From 8e8dac825d484032dc021e8698fe65f427ae8dae Mon Sep 17 00:00:00 2001 From: Balaji Ganesan Date: Tue, 21 Jul 2026 21:28:47 -0700 Subject: [PATCH 01/29] build(bazel): add cloud-tasks maven closure and grpc-java to the root hub MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Prepares the root nv_third_party_deps hub for the incoming cloud-tasks Java service (src/control-plane-services/cloud-tasks): - Add the 36 third-party coordinates cloud-tasks needs that were not already in the hub. All resolve from public Maven Central; the four BOMs it uses (spring-boot 4.0.7, spring-cloud 2025.1.2, testcontainers 2.0.5, shedlock 7.7.0) already match, so no version reconciliation was required. - Add gRPC-Java codegen support (rules_proto_grpc / rules_proto_grpc_java 5.8.0 plus the protoc-gen-grpc-java native plugin binaries) — the first Java gRPC consumer in the monorepo. - Re-pin //:maven_install.json. Note: pulling the grpc deps bumped the resolved rules_python and aspect_bazel_lib transitive versions above their direct pins (warnings only); those direct pins can be bumped separately. Co-authored-by: Balaji Ganesan Co-Authored-By: Claude Opus 4.8 --- MODULE.bazel | 116 ++- MODULE.bazel.lock | 81 ++- maven_install.json | 1689 +++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 1869 insertions(+), 17 deletions(-) diff --git a/MODULE.bazel b/MODULE.bazel index 31322b8bc..4231093ec 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -163,6 +163,77 @@ bazel_dep(name = "rules_java", version = "9.3.0") bazel_dep(name = "rules_jvm_external", version = "7.0") bazel_dep(name = "contrib_rules_jvm", version = "0.33.0") +# gRPC-Java codegen. rules_proto_grpc_java drives the protoc-gen-grpc-java +# plugin (fetched as native binaries below) to generate Java gRPC stubs for +# Java services that expose or consume gRPC. protobuf/com_google_protobuf and +# rules_java are already declared above. +bazel_dep(name = "rules_proto_grpc", version = "5.8.0") +bazel_dep(name = "rules_proto_grpc_java", version = "5.8.0") + +# The gRPC generator is a native executable, not a Java dependency. Keep it +# outside the shared Maven hub so fetch_sources applies only to Java artifacts. +GRPC_VERSION = "1.63.0" + +http_file = use_repo_rule( + "@bazel_tools//tools/build_defs/repo:http.bzl", + "http_file", +) + +http_file( + name = "grpc_java_plugin_linux_aarch_64", + downloaded_file_path = "protoc-gen-grpc-java.exe", + executable = True, + sha256 = "471427565ad82b3caac5e19dba2d15fb75b81042503ea32357630312d1f074b4", + urls = [ + "https://maven-central.storage-download.googleapis.com/maven2/io/grpc/protoc-gen-grpc-java/%s/protoc-gen-grpc-java-%s-linux-aarch_64.exe" % (GRPC_VERSION, GRPC_VERSION), + "https://repo.maven.apache.org/maven2/io/grpc/protoc-gen-grpc-java/%s/protoc-gen-grpc-java-%s-linux-aarch_64.exe" % (GRPC_VERSION, GRPC_VERSION), + ], +) + +http_file( + name = "grpc_java_plugin_linux_x86_64", + downloaded_file_path = "protoc-gen-grpc-java.exe", + executable = True, + sha256 = "0e3e8db80ba1fbddeed97ea3220b52cfaa95764ff8bf00716df7322883ce47e8", + urls = [ + "https://maven-central.storage-download.googleapis.com/maven2/io/grpc/protoc-gen-grpc-java/%s/protoc-gen-grpc-java-%s-linux-x86_64.exe" % (GRPC_VERSION, GRPC_VERSION), + "https://repo.maven.apache.org/maven2/io/grpc/protoc-gen-grpc-java/%s/protoc-gen-grpc-java-%s-linux-x86_64.exe" % (GRPC_VERSION, GRPC_VERSION), + ], +) + +http_file( + name = "grpc_java_plugin_osx_aarch_64", + downloaded_file_path = "protoc-gen-grpc-java.exe", + executable = True, + sha256 = "28290117a2ee9ea60f50f94273ab139dc2b3be4b8f2a557bef7e6efefee5b363", + urls = [ + "https://maven-central.storage-download.googleapis.com/maven2/io/grpc/protoc-gen-grpc-java/%s/protoc-gen-grpc-java-%s-osx-aarch_64.exe" % (GRPC_VERSION, GRPC_VERSION), + "https://repo.maven.apache.org/maven2/io/grpc/protoc-gen-grpc-java/%s/protoc-gen-grpc-java-%s-osx-aarch_64.exe" % (GRPC_VERSION, GRPC_VERSION), + ], +) + +http_file( + name = "grpc_java_plugin_osx_x86_64", + downloaded_file_path = "protoc-gen-grpc-java.exe", + executable = True, + sha256 = "28290117a2ee9ea60f50f94273ab139dc2b3be4b8f2a557bef7e6efefee5b363", + urls = [ + "https://maven-central.storage-download.googleapis.com/maven2/io/grpc/protoc-gen-grpc-java/%s/protoc-gen-grpc-java-%s-osx-x86_64.exe" % (GRPC_VERSION, GRPC_VERSION), + "https://repo.maven.apache.org/maven2/io/grpc/protoc-gen-grpc-java/%s/protoc-gen-grpc-java-%s-osx-x86_64.exe" % (GRPC_VERSION, GRPC_VERSION), + ], +) + +http_file( + name = "grpc_java_plugin_windows_x86_64", + downloaded_file_path = "protoc-gen-grpc-java.exe", + executable = True, + sha256 = "c3e9aaefd825a6ea9a252e153e0998d7ef36a7b27c2156867a98c71edf9c18a1", + urls = [ + "https://maven-central.storage-download.googleapis.com/maven2/io/grpc/protoc-gen-grpc-java/%s/protoc-gen-grpc-java-%s-windows-x86_64.exe" % (GRPC_VERSION, GRPC_VERSION), + "https://repo.maven.apache.org/maven2/io/grpc/protoc-gen-grpc-java/%s/protoc-gen-grpc-java-%s-windows-x86_64.exe" % (GRPC_VERSION, GRPC_VERSION), + ], +) + maven = use_extension("@rules_jvm_external//:extensions.bzl", "maven") maven.install( name = "nv_third_party_deps", @@ -224,6 +295,46 @@ maven.install( "org.junit.jupiter:junit-jupiter-engine", "org.junit.platform:junit-platform-launcher", "org.junit.platform:junit-platform-reporting", + # cloud-tasks service closure. Version-less coordinates are managed by + # the BOMs above (spring-boot 4.0.7 / spring-cloud 2025.1.2 / + # testcontainers 2.0.5 / shedlock 7.7.0). Explicit versions match the + # cloud-tasks standalone module; io.grpc pins track GRPC_VERSION. + "com.bucket4j:bucket4j_jdk17-core:8.19.0", + "com.github.ben-manes.caffeine:caffeine", + "com.google.protobuf:protobuf-java:4.33.4", + "com.google.protobuf:protobuf-java-util:4.33.4", + "io.grpc:grpc-api:%s" % GRPC_VERSION, + "io.grpc:grpc-protobuf:%s" % GRPC_VERSION, + "io.grpc:grpc-stub:%s" % GRPC_VERSION, + "io.micrometer:micrometer-registry-prometheus", + "io.projectreactor.netty:reactor-netty-core", + "io.projectreactor.netty:reactor-netty-http", + "javax.annotation:javax.annotation-api:1.3.2", + "net.devh:grpc-server-spring-boot-starter:3.1.0.RELEASE", + "net.javacrumbs.shedlock:shedlock-provider-cassandra", + "net.javacrumbs.shedlock:shedlock-spring", + "org.assertj:assertj-core", + "org.awaitility:awaitility", + "org.junit.jupiter:junit-jupiter-params", + "org.mockito:mockito-core", + "org.mockito:mockito-junit-jupiter", + "org.ow2.asm:asm:9.9", + "org.ow2.asm:asm-commons:9.9", + "org.ow2.asm:asm-tree:9.9", + "org.springframework:spring-context-support", + "org.springframework:spring-webflux", + "org.springframework.boot:spring-boot-actuator", + "org.springframework.boot:spring-boot-loader", + "org.springframework.boot:spring-boot-micrometer-metrics", + "org.springframework.boot:spring-boot-micrometer-tracing", + "org.springframework.boot:spring-boot-opentelemetry", + "org.springframework.boot:spring-boot-starter-aspectj", + "org.springframework.boot:spring-boot-starter-security", + "org.springframework.boot:spring-boot-starter-webmvc", + "org.springframework.cloud:spring-cloud-starter-kubernetes-client-config", + "org.springframework.retry:spring-retry", + "org.testcontainers:testcontainers", + "org.testcontainers:testcontainers-localstack", ], boms = [ "net.javacrumbs.shedlock:shedlock-bom:7.7.0", @@ -233,7 +344,10 @@ maven.install( ], fail_on_missing_checksum = True, fetch_sources = True, - known_contributing_modules = ["protobuf"], + known_contributing_modules = [ + "protobuf", + "rules_proto_grpc_java", + ], lock_file = "//:maven_install.json", repositories = [ # Public Central mirrors only. This is the public GitHub mirror; its diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index d2ebf15e3..25d1aea46 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -23,11 +23,13 @@ "https://bcr.bazel.build/modules/apple_support/1.15.1/MODULE.bazel": "a0556fefca0b1bb2de8567b8827518f94db6a6e7e7d632b4c48dc5f865bc7c85", "https://bcr.bazel.build/modules/apple_support/1.21.0/MODULE.bazel": "ac1824ed5edf17dee2fdd4927ada30c9f8c3b520be1b5fd02a5da15bc10bff3e", "https://bcr.bazel.build/modules/apple_support/1.21.1/MODULE.bazel": "5809fa3efab15d1f3c3c635af6974044bac8a4919c62238cce06acee8a8c11f1", + "https://bcr.bazel.build/modules/apple_support/1.23.0/MODULE.bazel": "317d47e3f65b580e7fb4221c160797fda48e32f07d2dfff63d754ef2316dcd25", "https://bcr.bazel.build/modules/apple_support/1.24.2/MODULE.bazel": "0e62471818affb9f0b26f128831d5c40b074d32e6dda5a0d3852847215a41ca4", "https://bcr.bazel.build/modules/apple_support/1.24.2/source.json": "2c22c9827093250406c5568da6c54e6fdf0ef06238def3d99c71b12feb057a8d", "https://bcr.bazel.build/modules/aspect_bazel_lib/2.14.0/MODULE.bazel": "2b31ffcc9bdc8295b2167e07a757dbbc9ac8906e7028e5170a3708cecaac119f", "https://bcr.bazel.build/modules/aspect_bazel_lib/2.19.3/MODULE.bazel": "253d739ba126f62a5767d832765b12b59e9f8d2bc88cc1572f4a73e46eb298ca", - "https://bcr.bazel.build/modules/aspect_bazel_lib/2.19.3/source.json": "ffab9254c65ba945f8369297ad97ca0dec213d3adc6e07877e23a48624a8b456", + "https://bcr.bazel.build/modules/aspect_bazel_lib/2.21.2/MODULE.bazel": "276347663a25b0d5bd6cad869252bea3e160c4d980e764b15f3bae7f80b30624", + "https://bcr.bazel.build/modules/aspect_bazel_lib/2.21.2/source.json": "f42051fa42629f0e59b7ac2adf0a55749144b11f1efcd8c697f0ee247181e526", "https://bcr.bazel.build/modules/aspect_bazel_lib/2.7.2/MODULE.bazel": "780d1a6522b28f5edb7ea09630748720721dfe27690d65a2d33aa7509de77e07", "https://bcr.bazel.build/modules/aspect_bazel_lib/2.8.1/MODULE.bazel": "812d2dd42f65dca362152101fbec418029cc8fd34cbad1a2fde905383d705838", "https://bcr.bazel.build/modules/bazel_features/1.1.0/MODULE.bazel": "cfd42ff3b815a5f39554d97182657f8c4b9719568eb7fded2b9135f084bf760b", @@ -46,6 +48,7 @@ "https://bcr.bazel.build/modules/bazel_features/1.28.0/MODULE.bazel": "4b4200e6cbf8fa335b2c3f43e1d6ef3e240319c33d43d60cc0fbd4b87ece299d", "https://bcr.bazel.build/modules/bazel_features/1.3.0/MODULE.bazel": "cdcafe83ec318cda34e02948e81d790aab8df7a929cec6f6969f13a489ccecd9", "https://bcr.bazel.build/modules/bazel_features/1.30.0/MODULE.bazel": "a14b62d05969a293b80257e72e597c2da7f717e1e69fa8b339703ed6731bec87", + "https://bcr.bazel.build/modules/bazel_features/1.32.0/MODULE.bazel": "095d67022a58cb20f7e20e1aefecfa65257a222c18a938e2914fd257b5f1ccdc", "https://bcr.bazel.build/modules/bazel_features/1.33.0/MODULE.bazel": "8b8dc9d2a4c88609409c3191165bccec0e4cb044cd7a72ccbe826583303459f6", "https://bcr.bazel.build/modules/bazel_features/1.36.0/MODULE.bazel": "596cb62090b039caf1cad1d52a8bc35cf188ca9a4e279a828005e7ee49a1bec3", "https://bcr.bazel.build/modules/bazel_features/1.4.1/MODULE.bazel": "e45b6bb2350aff3e442ae1111c555e27eac1d915e77775f6fdc4b351b758b5d7", @@ -80,6 +83,8 @@ "https://bcr.bazel.build/modules/buildozer/8.5.1/source.json": "e3386e6ff4529f2442800dee47ad28d3e6487f36a1f75ae39ae56c70f0cd2fbd", "https://bcr.bazel.build/modules/contrib_rules_jvm/0.33.0/MODULE.bazel": "1aba514585748372ee392484b2645f0bbcb13ad4271d5b7cace018280f15bae1", "https://bcr.bazel.build/modules/contrib_rules_jvm/0.33.0/source.json": "e52d62ce2a2b8a513d6afe9178acc06a4349c9b0b4c0934d59085ed9df4b4de0", + "https://bcr.bazel.build/modules/gawk/5.3.2.bcr.1/MODULE.bazel": "cdf8cbe5ee750db04b78878c9633cc76e80dcf4416cbe982ac3a9222f80713c8", + "https://bcr.bazel.build/modules/gawk/5.3.2.bcr.1/source.json": "fa7b512dfcb5eafd90ce3959cf42a2a6fe96144ebbb4b3b3928054895f2afac2", "https://bcr.bazel.build/modules/gazelle/0.32.0/MODULE.bazel": "b499f58a5d0d3537f3cf5b76d8ada18242f64ec474d8391247438bf04f58c7b8", "https://bcr.bazel.build/modules/gazelle/0.33.0/MODULE.bazel": "a13a0f279b462b784fb8dd52a4074526c4a2afe70e114c7d09066097a46b3350", "https://bcr.bazel.build/modules/gazelle/0.34.0/MODULE.bazel": "abdd8ce4d70978933209db92e436deb3a8b737859e9354fb5fd11fb5c2004c8a", @@ -173,6 +178,7 @@ "https://bcr.bazel.build/modules/rules_cc/0.2.14/MODULE.bazel": "353c99ed148887ee89c54a17d4100ae7e7e436593d104b668476019023b58df8", "https://bcr.bazel.build/modules/rules_cc/0.2.17/MODULE.bazel": "1849602c86cb60da8613d2de887f9566a6d354a6df6d7009f9d04a14402f9a84", "https://bcr.bazel.build/modules/rules_cc/0.2.17/source.json": "3832f45d145354049137c0090df04629d9c2b5493dc5c2bf46f1834040133a07", + "https://bcr.bazel.build/modules/rules_cc/0.2.4/MODULE.bazel": "1ff1223dfd24f3ecf8f028446d4a27608aa43c3f41e346d22838a4223980b8cc", "https://bcr.bazel.build/modules/rules_cc/0.2.8/MODULE.bazel": "f1df20f0bf22c28192a794f29b501ee2018fa37a3862a1a2132ae2940a23a642", "https://bcr.bazel.build/modules/rules_foreign_cc/0.9.0/MODULE.bazel": "c9e8c682bf75b0e7c704166d79b599f93b72cfca5ad7477df596947891feeef6", "https://bcr.bazel.build/modules/rules_fuzzing/0.5.2/MODULE.bazel": "40c97d1144356f52905566c55811f13b299453a14ac7769dfba2ac38192337a8", @@ -188,12 +194,15 @@ "https://bcr.bazel.build/modules/rules_go/0.60.0/source.json": "1e21368c5e0c3013a110bd79a8fcff8ca46b5bcb2b561713a7273cbfcff7c464", "https://bcr.bazel.build/modules/rules_java/4.0.0/MODULE.bazel": "5a78a7ae82cd1a33cef56dc578c7d2a46ed0dca12643ee45edbb8417899e6f74", "https://bcr.bazel.build/modules/rules_java/5.3.5/MODULE.bazel": "a4ec4f2db570171e3e5eb753276ee4b389bae16b96207e9d3230895c99644b86", + "https://bcr.bazel.build/modules/rules_java/6.0.0/MODULE.bazel": "8a43b7df601a7ec1af61d79345c17b31ea1fedc6711fd4abfd013ea612978e39", "https://bcr.bazel.build/modules/rules_java/6.3.0/MODULE.bazel": "a97c7678c19f236a956ad260d59c86e10a463badb7eb2eda787490f4c969b963", + "https://bcr.bazel.build/modules/rules_java/6.4.0/MODULE.bazel": "e986a9fe25aeaa84ac17ca093ef13a4637f6107375f64667a15999f77db6c8f6", "https://bcr.bazel.build/modules/rules_java/6.5.2/MODULE.bazel": "1d440d262d0e08453fa0c4d8f699ba81609ed0e9a9a0f02cd10b3e7942e61e31", "https://bcr.bazel.build/modules/rules_java/7.1.0/MODULE.bazel": "30d9135a2b6561c761bd67bd4990da591e6bdc128790ce3e7afd6a3558b2fb64", "https://bcr.bazel.build/modules/rules_java/7.10.0/MODULE.bazel": "530c3beb3067e870561739f1144329a21c851ff771cd752a49e06e3dc9c2e71a", "https://bcr.bazel.build/modules/rules_java/7.12.2/MODULE.bazel": "579c505165ee757a4280ef83cda0150eea193eed3bef50b1004ba88b99da6de6", "https://bcr.bazel.build/modules/rules_java/7.2.0/MODULE.bazel": "06c0334c9be61e6cef2c8c84a7800cef502063269a5af25ceb100b192453d4ab", + "https://bcr.bazel.build/modules/rules_java/7.3.2/MODULE.bazel": "50dece891cfdf1741ea230d001aa9c14398062f2b7c066470accace78e412bc2", "https://bcr.bazel.build/modules/rules_java/7.4.0/MODULE.bazel": "a592852f8a3dd539e82ee6542013bf2cadfc4c6946be8941e189d224500a8934", "https://bcr.bazel.build/modules/rules_java/7.6.1/MODULE.bazel": "2f14b7e8a1aa2f67ae92bc69d1ec0fa8d9f827c4e17ff5e5f02e91caa3b2d0fe", "https://bcr.bazel.build/modules/rules_java/8.13.0/MODULE.bazel": "0444ebf737d144cf2bb2ccb368e7f1cce735264285f2a3711785827c1686625e", @@ -210,14 +219,18 @@ "https://bcr.bazel.build/modules/rules_jvm_external/4.4.2/MODULE.bazel": "a56b85e418c83eb1839819f0b515c431010160383306d13ec21959ac412d2fe7", "https://bcr.bazel.build/modules/rules_jvm_external/5.1/MODULE.bazel": "33f6f999e03183f7d088c9be518a63467dfd0be94a11d0055fe2d210f89aa909", "https://bcr.bazel.build/modules/rules_jvm_external/5.2/MODULE.bazel": "d9351ba35217ad0de03816ef3ed63f89d411349353077348a45348b096615036", + "https://bcr.bazel.build/modules/rules_jvm_external/5.3/MODULE.bazel": "bf93870767689637164657731849fb887ad086739bd5d360d90007a581d5527d", + "https://bcr.bazel.build/modules/rules_jvm_external/6.1/MODULE.bazel": "75b5fec090dbd46cf9b7d8ea08cf84a0472d92ba3585b476f44c326eda8059c4", "https://bcr.bazel.build/modules/rules_jvm_external/6.10/MODULE.bazel": "33e636ca6bc9ee0fa090a38aa33c631ded2d8cf6fead4124181d1b35dc474f7c", "https://bcr.bazel.build/modules/rules_jvm_external/6.2/MODULE.bazel": "36a6e52487a855f33cb960724eb56547fa87e2c98a0474c3acad94339d7f8e99", "https://bcr.bazel.build/modules/rules_jvm_external/6.3/MODULE.bazel": "c998e060b85f71e00de5ec552019347c8bca255062c990ac02d051bb80a38df0", "https://bcr.bazel.build/modules/rules_jvm_external/6.6/MODULE.bazel": "153042249c7060536dc95b6bb9f9bb8063b8a0b0cb7acdb381bddbc2374aed55", "https://bcr.bazel.build/modules/rules_jvm_external/6.7/MODULE.bazel": "e717beabc4d091ecb2c803c2d341b88590e9116b8bf7947915eeb33aab4f96dd", + "https://bcr.bazel.build/modules/rules_jvm_external/6.8/MODULE.bazel": "b5afe861e867e4c8e5b88e401cb7955bd35924258f97b1862cc966cbcf4f1a62", "https://bcr.bazel.build/modules/rules_jvm_external/6.9/MODULE.bazel": "07c5db05527db7744a54fcffd653e1550d40e0540207a7f7e6d0a4de5bef8274", "https://bcr.bazel.build/modules/rules_jvm_external/7.0/MODULE.bazel": "421482bdbcf05709f933c96b867a599deb517f2804ceb3e74511880610cfbf71", "https://bcr.bazel.build/modules/rules_jvm_external/7.0/source.json": "714cd003eadf5be5c83268311fe8e951db39f802babeaddc536b3560dc8f6faf", + "https://bcr.bazel.build/modules/rules_kotlin/1.9.0/MODULE.bazel": "ef85697305025e5a61f395d4eaede272a5393cee479ace6686dba707de804d59", "https://bcr.bazel.build/modules/rules_kotlin/1.9.5/MODULE.bazel": "043a16a572f610558ec2030db3ff0c9938574e7dd9f58bded1bb07c0192ef025", "https://bcr.bazel.build/modules/rules_kotlin/1.9.6/MODULE.bazel": "d269a01a18ee74d0335450b10f62c9ed81f2321d7958a2934e44272fe82dcef3", "https://bcr.bazel.build/modules/rules_kotlin/2.1.3/MODULE.bazel": "ce7def6d576aa8d3a9c6d10e13b4d157296229674371f67dbf788dae0afae3d5", @@ -241,6 +254,10 @@ "https://bcr.bazel.build/modules/rules_proto/7.0.2/MODULE.bazel": "bf81793bd6d2ad89a37a40693e56c61b0ee30f7a7fdbaf3eabbf5f39de47dea2", "https://bcr.bazel.build/modules/rules_proto/7.1.0/MODULE.bazel": "002d62d9108f75bb807cd56245d45648f38275cb3a99dcd45dfb864c5d74cb96", "https://bcr.bazel.build/modules/rules_proto/7.1.0/source.json": "39f89066c12c24097854e8f57ab8558929f9c8d474d34b2c00ac04630ad8940e", + "https://bcr.bazel.build/modules/rules_proto_grpc/5.8.0/MODULE.bazel": "38e2acb9aa480a04c780fa4b11bfaae0fa16e05f85f6d8fc32e044bad683ed86", + "https://bcr.bazel.build/modules/rules_proto_grpc/5.8.0/source.json": "142d5c5dd650d0f817936835738daa7df2256dfb33c247163b600ab28cba31d1", + "https://bcr.bazel.build/modules/rules_proto_grpc_java/5.8.0/MODULE.bazel": "0e24d1d4716b017afa6c85649bee47144066310057fbce7bdb5661aecd525571", + "https://bcr.bazel.build/modules/rules_proto_grpc_java/5.8.0/source.json": "965a546920ecf67e8cbb9e060f35d7f87a6fcd4319db0cf47cbc66c30327b1ee", "https://bcr.bazel.build/modules/rules_python/0.10.2/MODULE.bazel": "cc82bc96f2997baa545ab3ce73f196d040ffb8756fd2d66125a530031cd90e5f", "https://bcr.bazel.build/modules/rules_python/0.23.1/MODULE.bazel": "49ffccf0511cb8414de28321f5fcf2a31312b47c40cc21577144b7447f2bf300", "https://bcr.bazel.build/modules/rules_python/0.25.0/MODULE.bazel": "72f1506841c920a1afec76975b35312410eea3aa7b63267436bfb1dd91d2d382", @@ -258,9 +275,12 @@ "https://bcr.bazel.build/modules/rules_python/1.7.0/source.json": "028a084b65dcf8f4dc4f82f8778dbe65df133f234b316828a82e060d81bdce32", "https://bcr.bazel.build/modules/rules_robolectric/4.14.1.2/MODULE.bazel": "d44fec647d0aeb67b9f3b980cf68ba634976f3ae7ccd6c07d790b59b87a4f251", "https://bcr.bazel.build/modules/rules_robolectric/4.14.1.2/source.json": "37c10335f2361c337c5c1f34ed36d2da70534c23088062b33a8bdaab68aa9dea", + "https://bcr.bazel.build/modules/rules_rust/0.66.0/MODULE.bazel": "86ef763a582f4739a27029bdcc6c562258ed0ea6f8d58294b049e215ceb251b3", + "https://bcr.bazel.build/modules/rules_rust/0.66.0/source.json": "5c2252a61ccc19b4e420c7c06429c8f51d8edd7b743dcb4b60571e7d40b5aa57", "https://bcr.bazel.build/modules/rules_shell/0.1.2/MODULE.bazel": "66e4ca3ce084b04af0b9ff05ff14cab4e5df7503973818bb91cbc6cda08d32fc", "https://bcr.bazel.build/modules/rules_shell/0.2.0/MODULE.bazel": "fda8a652ab3c7d8fee214de05e7a9916d8b28082234e8d2c0094505c5268ed3c", "https://bcr.bazel.build/modules/rules_shell/0.3.0/MODULE.bazel": "de4402cd12f4cc8fda2354fce179fdb068c0b9ca1ec2d2b17b3e21b24c1a937b", + "https://bcr.bazel.build/modules/rules_shell/0.4.0/MODULE.bazel": "0f8f11bb3cd11755f0b48c1de0bbcf62b4b34421023aa41a2fc74ef68d9584f0", "https://bcr.bazel.build/modules/rules_shell/0.4.1/MODULE.bazel": "00e501db01bbf4e3e1dd1595959092c2fadf2087b2852d3f553b5370f5633592", "https://bcr.bazel.build/modules/rules_shell/0.6.1/MODULE.bazel": "72e76b0eea4e81611ef5452aa82b3da34caca0c8b7b5c0c9584338aa93bae26b", "https://bcr.bazel.build/modules/rules_shell/0.8.0/MODULE.bazel": "f6a89f1d6a669a26f28fe814503857055d76306b79cfc11d12399af08d0b80ae", @@ -273,17 +293,21 @@ "https://bcr.bazel.build/modules/stardoc/0.5.1/MODULE.bazel": "1a05d92974d0c122f5ccf09291442580317cdd859f07a8655f1db9a60374f9f8", "https://bcr.bazel.build/modules/stardoc/0.5.3/MODULE.bazel": "c7f6948dae6999bf0db32c1858ae345f112cacf98f174c7a8bb707e41b974f1c", "https://bcr.bazel.build/modules/stardoc/0.5.4/MODULE.bazel": "6569966df04610b8520957cb8e97cf2e9faac2c0309657c537ab51c16c18a2a4", + "https://bcr.bazel.build/modules/stardoc/0.5.6/MODULE.bazel": "c43dabc564990eeab55e25ed61c07a1aadafe9ece96a4efabb3f8bf9063b71ef", "https://bcr.bazel.build/modules/stardoc/0.6.2/MODULE.bazel": "7060193196395f5dd668eda046ccbeacebfd98efc77fed418dbe2b82ffaa39fd", "https://bcr.bazel.build/modules/stardoc/0.7.0/MODULE.bazel": "05e3d6d30c099b6770e97da986c53bd31844d7f13d41412480ea265ac9e8079c", + "https://bcr.bazel.build/modules/stardoc/0.7.1/MODULE.bazel": "3548faea4ee5dda5580f9af150e79d0f6aea934fc60c1cc50f4efdd9420759e7", "https://bcr.bazel.build/modules/stardoc/0.7.2/MODULE.bazel": "fc152419aa2ea0f51c29583fab1e8c99ddefd5b3778421845606ee628629e0e5", "https://bcr.bazel.build/modules/stardoc/0.7.2/source.json": "58b029e5e901d6802967754adf0a9056747e8176f017cfe3607c0851f4d42216", "https://bcr.bazel.build/modules/swift_argument_parser/1.3.1.1/MODULE.bazel": "5e463fbfba7b1701d957555ed45097d7f984211330106ccd1352c6e0af0dcf91", "https://bcr.bazel.build/modules/swift_argument_parser/1.3.1.2/MODULE.bazel": "75aab2373a4bbe2a1260b9bf2a1ebbdbf872d3bd36f80bff058dccd82e89422f", "https://bcr.bazel.build/modules/swift_argument_parser/1.3.1.2/source.json": "5fba48bbe0ba48761f9e9f75f92876cafb5d07c0ce059cc7a8027416de94a05b", "https://bcr.bazel.build/modules/tar.bzl/0.2.1/MODULE.bazel": "52d1c00a80a8cc67acbd01649e83d8dd6a9dc426a6c0b754a04fe8c219c76468", - "https://bcr.bazel.build/modules/tar.bzl/0.2.1/source.json": "600ac6ff61744667a439e7b814ae59c1f29632c3984fccf8000c64c9db8d7bb6", + "https://bcr.bazel.build/modules/tar.bzl/0.5.1/MODULE.bazel": "7c2eb3dcfc53b0f3d6f9acdfd911ca803eaf92aadf54f8ca6e4c1f3aee288351", + "https://bcr.bazel.build/modules/tar.bzl/0.5.1/source.json": "deed3094f7cc779ed1d37a68403847b0e38d9dd9d931e03cb90825f3368b515f", "https://bcr.bazel.build/modules/toml.bzl/0.3.0/MODULE.bazel": "5016e5dd1ad2200e119a4b28b2b3935e276c4b480f2fe3e952bea7eeba88f578", "https://bcr.bazel.build/modules/toml.bzl/0.3.0/source.json": "0cf7c878c419b37ddb55f3dd93dd7c0c409bd7c4efacb3da504e0748780b2fa9", + "https://bcr.bazel.build/modules/toolchains_protoc/0.5.0/MODULE.bazel": "e649dcd74790d8b186517588c827a777dfa67acfc4cbd733721c4be143ea107f", "https://bcr.bazel.build/modules/toolchains_protoc/0.6.1/MODULE.bazel": "377cbb438118f413c3361a1dd363da8a42077018473fcdc71a19c203aaf94b17", "https://bcr.bazel.build/modules/toolchains_protoc/0.6.1/source.json": "b14b0b38c8309691bee7a0ab46113678b8675e04e8999294c58e68b036b8dbff", "https://bcr.bazel.build/modules/upb/0.0.0-20220923-a547704/MODULE.bazel": "7298990c00040a0e2f121f6c32544bab27d4452f80d9ce51349b1a28f3005c43", @@ -350,7 +374,7 @@ }, "@@rules_oci+//oci:extensions.bzl%oci": { "general": { - "bzlTransitiveDigest": "qGzrjxshR+J4OqW/IYdHPjWbclbeUFswL6msJ9ALGOg=", + "bzlTransitiveDigest": "IPpbSHX7+8yLBfvZyia9qXU/WRxkP+dWAO8m5+BsBY8=", "usagesDigest": "OlwIdJhTnYJJAA+ezJIG6rT/iRycvHf0Yuf0EPuhO7c=", "recordedInputs": [ "REPO_MAPPING:aspect_bazel_lib+,bazel_tools bazel_tools", @@ -772,6 +796,57 @@ } } } + }, + "@@tar.bzl+//tar:extensions.bzl%toolchains": { + "general": { + "bzlTransitiveDigest": "/2afh6fPjq/rcyE/jztQDK3ierehmFFngfvmqyRv72M=", + "usagesDigest": "maF8qsAIqeH1ey8pxP0gNZbvJt34kLZvTFeQ0ntrJVA=", + "recordedInputs": [], + "generatedRepoSpecs": { + "bsd_tar_toolchains": { + "repoRuleId": "@@tar.bzl+//tar/toolchain:toolchain.bzl%tar_toolchains_repo", + "attributes": { + "user_repository_name": "bsd_tar_toolchains" + } + }, + "bsd_tar_toolchains_darwin_amd64": { + "repoRuleId": "@@tar.bzl+//tar/toolchain:platforms.bzl%bsdtar_binary_repo", + "attributes": { + "platform": "darwin_amd64" + } + }, + "bsd_tar_toolchains_darwin_arm64": { + "repoRuleId": "@@tar.bzl+//tar/toolchain:platforms.bzl%bsdtar_binary_repo", + "attributes": { + "platform": "darwin_arm64" + } + }, + "bsd_tar_toolchains_linux_amd64": { + "repoRuleId": "@@tar.bzl+//tar/toolchain:platforms.bzl%bsdtar_binary_repo", + "attributes": { + "platform": "linux_amd64" + } + }, + "bsd_tar_toolchains_linux_arm64": { + "repoRuleId": "@@tar.bzl+//tar/toolchain:platforms.bzl%bsdtar_binary_repo", + "attributes": { + "platform": "linux_arm64" + } + }, + "bsd_tar_toolchains_windows_amd64": { + "repoRuleId": "@@tar.bzl+//tar/toolchain:platforms.bzl%bsdtar_binary_repo", + "attributes": { + "platform": "windows_amd64" + } + }, + "bsd_tar_toolchains_windows_arm64": { + "repoRuleId": "@@tar.bzl+//tar/toolchain:platforms.bzl%bsdtar_binary_repo", + "attributes": { + "platform": "windows_arm64" + } + } + } + } } }, "facts": { diff --git a/maven_install.json b/maven_install.json index 01d08969d..ebfae1f7c 100755 --- a/maven_install.json +++ b/maven_install.json @@ -2,41 +2,70 @@ "__AUTOGENERATED_FILE_DO_NOT_MODIFY_THIS_FILE_MANUALLY": "THERE_IS_NO_DATA_ONLY_ZUUL", "__INPUT_ARTIFACTS_HASH": { "at.yawk.lz4:lz4-java": 1725015399, + "com.bucket4j:bucket4j_jdk17-core": -1409600715, + "com.github.ben-manes.caffeine:caffeine": 1100418982, "com.github.ben-manes.caffeine:guava": 1054685015, "com.github.java-json-tools:json-patch": -1031005245, + "com.google.protobuf:protobuf-java": 1906581597, + "com.google.protobuf:protobuf-java-util": -1626074784, "commons-codec:commons-codec": -1269462382, "io.cloudevents:cloudevents-core": -2103567774, "io.cloudevents:cloudevents-json-jackson": -1197487309, + "io.grpc:grpc-api": 811923177, + "io.grpc:grpc-protobuf": 1083049616, + "io.grpc:grpc-stub": 1416868173, + "io.micrometer:micrometer-registry-prometheus": 1865600799, "io.micrometer:micrometer-tracing-bridge-otel": -754588172, "io.nats:jnats": 572014237, "io.opentelemetry:opentelemetry-exporter-otlp": -12806658, "io.opentelemetry:opentelemetry-sdk-testing": -32635354, + "io.projectreactor.netty:reactor-netty-core": -2096527644, + "io.projectreactor.netty:reactor-netty-http": 131695323, "jakarta.servlet:jakarta.servlet-api": 2120044853, + "javax.annotation:javax.annotation-api": 1286517389, + "net.devh:grpc-server-spring-boot-starter": -1304967214, "net.javacrumbs.shedlock:shedlock-bom": -1406345450, + "net.javacrumbs.shedlock:shedlock-provider-cassandra": -1200872, + "net.javacrumbs.shedlock:shedlock-spring": -326290089, "org.apache.cassandra:java-driver-metrics-micrometer": -465267397, "org.apache.commons:commons-lang3": -278168457, + "org.assertj:assertj-core": 1863574844, + "org.awaitility:awaitility": -1630939750, "org.bouncycastle:bcprov-jdk18on": -1405390253, "org.jacoco:org.jacoco.agent": -2069397525, "org.jacoco:org.jacoco.cli": -1856875155, "org.junit.jupiter:junit-jupiter-api": 194920406, "org.junit.jupiter:junit-jupiter-engine": -1886863302, + "org.junit.jupiter:junit-jupiter-params": 1082310006, "org.junit.platform:junit-platform-console-standalone": -1481831078, "org.junit.platform:junit-platform-launcher": -354104948, "org.junit.platform:junit-platform-reporting": 1896713402, + "org.mockito:mockito-core": -554630660, + "org.mockito:mockito-junit-jupiter": -1104541639, + "org.ow2.asm:asm": -221905796, "org.ow2.asm:asm-analysis": -1027574299, + "org.ow2.asm:asm-commons": 1525995351, + "org.ow2.asm:asm-tree": -242459737, "org.ow2.asm:asm-util": -307204853, "org.projectlombok:lombok": -2073039513, "org.springdoc:springdoc-openapi-starter-webflux-api": 1102747448, "org.springdoc:springdoc-openapi-starter-webmvc-api": 655186513, + "org.springframework.boot:spring-boot-actuator": 763411999, "org.springframework.boot:spring-boot-dependencies": 70164638, + "org.springframework.boot:spring-boot-loader": 1745496505, + "org.springframework.boot:spring-boot-micrometer-metrics": -782059807, + "org.springframework.boot:spring-boot-micrometer-tracing": -2099172128, "org.springframework.boot:spring-boot-micrometer-tracing-opentelemetry": 238152322, + "org.springframework.boot:spring-boot-opentelemetry": -396622647, "org.springframework.boot:spring-boot-restclient": 525086533, "org.springframework.boot:spring-boot-starter": 1358725161, "org.springframework.boot:spring-boot-starter-actuator": -1082017891, "org.springframework.boot:spring-boot-starter-actuator-test": 536870722, + "org.springframework.boot:spring-boot-starter-aspectj": -1960483986, "org.springframework.boot:spring-boot-starter-data-cassandra": 699136521, "org.springframework.boot:spring-boot-starter-data-cassandra-test": -667262890, "org.springframework.boot:spring-boot-starter-jackson": -1899095121, + "org.springframework.boot:spring-boot-starter-security": 1168390884, "org.springframework.boot:spring-boot-starter-security-oauth2-client": -1248590284, "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server": 185843737, "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server-test": -1173625786, @@ -45,16 +74,23 @@ "org.springframework.boot:spring-boot-starter-web": -1905796688, "org.springframework.boot:spring-boot-starter-webflux": 1788530073, "org.springframework.boot:spring-boot-starter-webflux-test": 5326534, + "org.springframework.boot:spring-boot-starter-webmvc": 338400426, "org.springframework.boot:spring-boot-starter-webmvc-test": -2111356331, "org.springframework.boot:spring-boot-webclient": -1835278023, "org.springframework.cloud:spring-cloud-commons": -673836000, "org.springframework.cloud:spring-cloud-context": -1724959431, "org.springframework.cloud:spring-cloud-dependencies": 46341733, "org.springframework.cloud:spring-cloud-starter-bootstrap": -213001704, + "org.springframework.cloud:spring-cloud-starter-kubernetes-client-config": -2108580045, + "org.springframework.retry:spring-retry": -815156811, "org.springframework.security:spring-security-test": 1317137564, + "org.springframework:spring-context-support": 43813702, + "org.springframework:spring-webflux": 11421498, + "org.testcontainers:testcontainers": -258185670, "org.testcontainers:testcontainers-bom": 483223872, "org.testcontainers:testcontainers-cassandra": -1027104267, "org.testcontainers:testcontainers-junit-jupiter": -918230293, + "org.testcontainers:testcontainers-localstack": 1146768038, "org.wiremock:wiremock-standalone": -1242936487, "repositories": -1624298853, "software.amazon.awssdk:regions": -1274787064, @@ -71,6 +107,10 @@ "ch.qos.logback:logback-classic:jar:sources": -390128445, "ch.qos.logback:logback-core": -1554021729, "ch.qos.logback:logback-core:jar:sources": 77538609, + "com.bucket4j:bucket4j-core": -332288989, + "com.bucket4j:bucket4j-core:jar:sources": -559201191, + "com.bucket4j:bucket4j_jdk17-core": -1244833112, + "com.bucket4j:bucket4j_jdk17-core:jar:sources": -2075602285, "com.datastax.cassandra:cassandra-driver-core": -681774303, "com.datastax.cassandra:cassandra-driver-core:jar:sources": -2045236197, "com.datastax.oss:native-protocol": 447263174, @@ -97,13 +137,13 @@ "com.github.docker-java:docker-java-transport-zerodep": -1848983763, "com.github.docker-java:docker-java-transport-zerodep:jar:sources": 1882881505, "com.github.docker-java:docker-java-transport:jar:sources": 864522470, - "com.github.java-json-tools:btf": -1747700664, + "com.github.java-json-tools:btf": 204024567, "com.github.java-json-tools:btf:jar:sources": 1539011915, - "com.github.java-json-tools:jackson-coreutils": 2047023685, + "com.github.java-json-tools:jackson-coreutils": 1585779168, "com.github.java-json-tools:jackson-coreutils:jar:sources": 323093438, - "com.github.java-json-tools:json-patch": -399792119, + "com.github.java-json-tools:json-patch": 388171991, "com.github.java-json-tools:json-patch:jar:sources": -1320375757, - "com.github.java-json-tools:msg-simple": 986302814, + "com.github.java-json-tools:msg-simple": -285204120, "com.github.java-json-tools:msg-simple:jar:sources": 1013495835, "com.github.jnr:jffi": 1952487985, "com.github.jnr:jffi:jar:native": 1426144838, @@ -118,7 +158,14 @@ "com.github.jnr:jnr-x86asm:jar:sources": -1784079536, "com.github.stephenc.jcip:jcip-annotations": -121928928, "com.github.stephenc.jcip:jcip-annotations:jar:sources": -2051941468, - "com.google.code.findbugs:jsr305": 1838181273, + "com.google.android:annotations": 769933135, + "com.google.android:annotations:jar:sources": 215169100, + "com.google.api.grpc:proto-google-common-protos": -1208329413, + "com.google.api.grpc:proto-google-common-protos:jar:sources": 944916609, + "com.google.code.findbugs:jsr305": -1038659426, + "com.google.code.findbugs:jsr305:jar:sources": -1300148931, + "com.google.code.gson:gson": 328405842, + "com.google.code.gson:gson:jar:sources": -329485452, "com.google.errorprone:error_prone_annotations": -1266099896, "com.google.errorprone:error_prone_annotations:jar:sources": 936701586, "com.google.guava:failureaccess": -56291903, @@ -128,6 +175,10 @@ "com.google.guava:listenablefuture": 1588902908, "com.google.j2objc:j2objc-annotations": -2074422376, "com.google.j2objc:j2objc-annotations:jar:sources": -597974451, + "com.google.protobuf:protobuf-java": 1139989641, + "com.google.protobuf:protobuf-java-util": 404866093, + "com.google.protobuf:protobuf-java-util:jar:sources": 1216176261, + "com.google.protobuf:protobuf-java:jar:sources": -718827633, "com.jayway.jsonpath:json-path": 626712679, "com.jayway.jsonpath:json-path:jar:sources": -343427302, "com.nimbusds:content-type": -444977683, @@ -138,10 +189,16 @@ "com.nimbusds:nimbus-jose-jwt:jar:sources": 24935039, "com.nimbusds:oauth2-oidc-sdk": -498816278, "com.nimbusds:oauth2-oidc-sdk:jar:sources": 1276926642, + "com.squareup.okhttp3:logging-interceptor": -2002563184, + "com.squareup.okhttp3:logging-interceptor:jar:sources": 524942179, + "com.squareup.okhttp3:okhttp": -2047906849, "com.squareup.okhttp3:okhttp-jvm": -314031254, "com.squareup.okhttp3:okhttp-jvm:jar:sources": 447067750, + "com.squareup.okhttp3:okhttp:jar:sources": -967779406, + "com.squareup.okio:okio": -11775483, "com.squareup.okio:okio-jvm": -391120506, "com.squareup.okio:okio-jvm:jar:sources": 1375453359, + "com.squareup.okio:okio:jar:sources": -1339925226, "com.typesafe:config": 96906638, "com.typesafe:config:jar:sources": -892423283, "com.vaadin.external.google:android-json": -1531950165, @@ -160,6 +217,38 @@ "io.cloudevents:cloudevents-json-jackson:jar:sources": -166751855, "io.dropwizard.metrics:metrics-core": 1029463962, "io.dropwizard.metrics:metrics-core:jar:sources": 1607397396, + "io.grpc:grpc-api": 716151037, + "io.grpc:grpc-api:jar:sources": 234601049, + "io.grpc:grpc-context": 721938541, + "io.grpc:grpc-context:jar:sources": 1478851124, + "io.grpc:grpc-core": -1513972768, + "io.grpc:grpc-core:jar:sources": -232667389, + "io.grpc:grpc-inprocess": 353730710, + "io.grpc:grpc-inprocess:jar:sources": -676994554, + "io.grpc:grpc-netty-shaded": 1759851352, + "io.grpc:grpc-netty-shaded:jar:sources": 1478851124, + "io.grpc:grpc-protobuf": -549393834, + "io.grpc:grpc-protobuf-lite": -1967256086, + "io.grpc:grpc-protobuf-lite:jar:sources": -1659538303, + "io.grpc:grpc-protobuf:jar:sources": -1849103116, + "io.grpc:grpc-services": 1483710115, + "io.grpc:grpc-services:jar:sources": 2062893709, + "io.grpc:grpc-stub": -1391817309, + "io.grpc:grpc-stub:jar:sources": -1596678046, + "io.grpc:grpc-util": 188637273, + "io.grpc:grpc-util:jar:sources": -2003766127, + "io.gsonfire:gson-fire": -1955577022, + "io.gsonfire:gson-fire:jar:sources": -237239617, + "io.kubernetes:client-java": -1721476940, + "io.kubernetes:client-java-api": 1944060710, + "io.kubernetes:client-java-api-fluent": 889139695, + "io.kubernetes:client-java-api-fluent:jar:sources": -1413457658, + "io.kubernetes:client-java-api:jar:sources": -1450077171, + "io.kubernetes:client-java-extended": 693015729, + "io.kubernetes:client-java-extended:jar:sources": -483537505, + "io.kubernetes:client-java-proto": -533144525, + "io.kubernetes:client-java-proto:jar:sources": 396874650, + "io.kubernetes:client-java:jar:sources": -1422160339, "io.micrometer:context-propagation": -1130727419, "io.micrometer:context-propagation:jar:sources": -1135393170, "io.micrometer:micrometer-commons": 326693391, @@ -172,6 +261,8 @@ "io.micrometer:micrometer-observation-test": -1818068529, "io.micrometer:micrometer-observation-test:jar:sources": 117373145, "io.micrometer:micrometer-observation:jar:sources": 1279306785, + "io.micrometer:micrometer-registry-prometheus": -104964751, + "io.micrometer:micrometer-registry-prometheus:jar:sources": 769452823, "io.micrometer:micrometer-tracing": -109714346, "io.micrometer:micrometer-tracing-bridge-otel": 975863312, "io.micrometer:micrometer-tracing-bridge-otel:jar:sources": 1300289348, @@ -256,6 +347,8 @@ "io.opentelemetry:opentelemetry-sdk-trace": 2083919234, "io.opentelemetry:opentelemetry-sdk-trace:jar:sources": 818630467, "io.opentelemetry:opentelemetry-sdk:jar:sources": -1478160490, + "io.perfmark:perfmark-api": 2140534246, + "io.perfmark:perfmark-api:jar:sources": 1660808382, "io.projectreactor.netty:reactor-netty-core": -1310988391, "io.projectreactor.netty:reactor-netty-core:jar:sources": 160926198, "io.projectreactor.netty:reactor-netty-http": -1289714469, @@ -264,12 +357,26 @@ "io.projectreactor:reactor-core:jar:sources": -717353230, "io.projectreactor:reactor-test": 947112823, "io.projectreactor:reactor-test:jar:sources": 383025302, + "io.prometheus:prometheus-metrics-config": 2090275681, + "io.prometheus:prometheus-metrics-config:jar:sources": -594166944, + "io.prometheus:prometheus-metrics-core": 786050810, + "io.prometheus:prometheus-metrics-core:jar:sources": 832360457, + "io.prometheus:prometheus-metrics-exposition-formats": 968068623, + "io.prometheus:prometheus-metrics-exposition-formats:jar:sources": -438412972, + "io.prometheus:prometheus-metrics-exposition-textformats": 620169553, + "io.prometheus:prometheus-metrics-exposition-textformats:jar:sources": 1866131456, + "io.prometheus:prometheus-metrics-model": -1472396605, + "io.prometheus:prometheus-metrics-model:jar:sources": 2095315251, + "io.prometheus:prometheus-metrics-tracer-common": -1148816462, + "io.prometheus:prometheus-metrics-tracer-common:jar:sources": 2121978274, "io.swagger.core.v3:swagger-annotations-jakarta": -842428034, "io.swagger.core.v3:swagger-annotations-jakarta:jar:sources": 133934665, "io.swagger.core.v3:swagger-core-jakarta": -439612282, "io.swagger.core.v3:swagger-core-jakarta:jar:sources": 449241668, "io.swagger.core.v3:swagger-models-jakarta": -1439553498, "io.swagger.core.v3:swagger-models-jakarta:jar:sources": 2092063988, + "io.swagger:swagger-annotations": 1839493157, + "io.swagger:swagger-annotations:jar:sources": 686356574, "jakarta.activation:jakarta.activation-api": -1560267684, "jakarta.activation:jakarta.activation-api:jar:sources": 759160467, "jakarta.annotation:jakarta.annotation-api": -1904975463, @@ -280,12 +387,24 @@ "jakarta.validation:jakarta.validation-api:jar:sources": -131796339, "jakarta.xml.bind:jakarta.xml.bind-api": 1157993223, "jakarta.xml.bind:jakarta.xml.bind-api:jar:sources": -945798747, + "javax.annotation:javax.annotation-api": 193132517, + "javax.annotation:javax.annotation-api:jar:sources": -1766532873, "net.bytebuddy:byte-buddy": 383637760, "net.bytebuddy:byte-buddy-agent": -1380713096, "net.bytebuddy:byte-buddy-agent:jar:sources": 564051985, "net.bytebuddy:byte-buddy:jar:sources": -1360611642, + "net.devh:grpc-common-spring-boot": 868090547, + "net.devh:grpc-common-spring-boot:jar:sources": 1655513026, + "net.devh:grpc-server-spring-boot-starter": 1078456931, + "net.devh:grpc-server-spring-boot-starter:jar:sources": 1954333860, "net.java.dev.jna:jna": -1951542637, "net.java.dev.jna:jna:jar:sources": -545183654, + "net.javacrumbs.shedlock:shedlock-core": 672475327, + "net.javacrumbs.shedlock:shedlock-core:jar:sources": 69227555, + "net.javacrumbs.shedlock:shedlock-provider-cassandra": -460637299, + "net.javacrumbs.shedlock:shedlock-provider-cassandra:jar:sources": 1860167, + "net.javacrumbs.shedlock:shedlock-spring": 2008414309, + "net.javacrumbs.shedlock:shedlock-spring:jar:sources": 875349683, "net.minidev:accessors-smart": -325667575, "net.minidev:accessors-smart:jar:sources": -124254155, "net.minidev:json-smart": 1673421716, @@ -298,6 +417,8 @@ "org.apache.cassandra:java-driver-metrics-micrometer:jar:sources": -2019023443, "org.apache.cassandra:java-driver-query-builder": 303143232, "org.apache.cassandra:java-driver-query-builder:jar:sources": -1665027563, + "org.apache.commons:commons-collections4": -321403372, + "org.apache.commons:commons-collections4:jar:sources": -620214302, "org.apache.commons:commons-compress": -134181577, "org.apache.commons:commons-compress:jar:sources": -1845261624, "org.apache.commons:commons-lang3": 759645435, @@ -314,14 +435,24 @@ "org.apache.tomcat.embed:tomcat-embed-websocket:jar:sources": -1809736441, "org.apiguardian:apiguardian-api": -1579303244, "org.apiguardian:apiguardian-api:jar:sources": 768152577, + "org.aspectj:aspectjweaver": -278059941, + "org.aspectj:aspectjweaver:jar:sources": 2235676, "org.assertj:assertj-core": -536770136, "org.assertj:assertj-core:jar:sources": -1826278818, "org.awaitility:awaitility": 755971515, "org.awaitility:awaitility:jar:sources": -1322650242, + "org.bitbucket.b_c:jose4j": 1319068658, + "org.bitbucket.b_c:jose4j:jar:sources": 969109778, + "org.bouncycastle:bcpkix-jdk18on": 755215182, + "org.bouncycastle:bcpkix-jdk18on:jar:sources": -167831728, "org.bouncycastle:bcprov-jdk18on": -709136978, "org.bouncycastle:bcprov-jdk18on:jar:sources": 106463766, "org.bouncycastle:bcprov-lts8on": 973431866, "org.bouncycastle:bcprov-lts8on:jar:sources": -196135755, + "org.bouncycastle:bcutil-jdk18on": 686883151, + "org.bouncycastle:bcutil-jdk18on:jar:sources": 1665148152, + "org.codehaus.mojo:animal-sniffer-annotations": -1054702037, + "org.codehaus.mojo:animal-sniffer-annotations:jar:sources": -248345982, "org.hamcrest:hamcrest": 1116842741, "org.hamcrest:hamcrest:jar:sources": -996443755, "org.hdrhistogram:HdrHistogram": 1379183334, @@ -339,6 +470,10 @@ "org.jboss.logging:jboss-logging": -2136063667, "org.jboss.logging:jboss-logging:jar:sources": 2066441551, "org.jetbrains.kotlin:kotlin-stdlib": -570435334, + "org.jetbrains.kotlin:kotlin-stdlib-jdk7": -1527302391, + "org.jetbrains.kotlin:kotlin-stdlib-jdk7:jar:sources": 197696244, + "org.jetbrains.kotlin:kotlin-stdlib-jdk8": 1920837701, + "org.jetbrains.kotlin:kotlin-stdlib-jdk8:jar:sources": -680289057, "org.jetbrains.kotlin:kotlin-stdlib:jar:sources": 1404576391, "org.jetbrains:annotations": 643765179, "org.jetbrains:annotations:jar:sources": 1009912224, @@ -427,6 +562,8 @@ "org.springframework.boot:spring-boot-http-converter:jar:sources": 678862764, "org.springframework.boot:spring-boot-jackson": -886310726, "org.springframework.boot:spring-boot-jackson:jar:sources": -928970153, + "org.springframework.boot:spring-boot-loader": 1516185416, + "org.springframework.boot:spring-boot-loader:jar:sources": 499181734, "org.springframework.boot:spring-boot-micrometer-metrics": -971815116, "org.springframework.boot:spring-boot-micrometer-metrics-test": 1059861465, "org.springframework.boot:spring-boot-micrometer-metrics-test:jar:sources": 539702709, @@ -466,6 +603,8 @@ "org.springframework.boot:spring-boot-starter-actuator-test": 910069034, "org.springframework.boot:spring-boot-starter-actuator-test:jar:sources": 314973026, "org.springframework.boot:spring-boot-starter-actuator:jar:sources": -2079433447, + "org.springframework.boot:spring-boot-starter-aspectj": 740892542, + "org.springframework.boot:spring-boot-starter-aspectj:jar:sources": 1957689077, "org.springframework.boot:spring-boot-starter-data-cassandra": -1305411192, "org.springframework.boot:spring-boot-starter-data-cassandra-test": 1049224325, "org.springframework.boot:spring-boot-starter-data-cassandra-test:jar:sources": 464889083, @@ -538,13 +677,22 @@ "org.springframework.cloud:spring-cloud-commons:jar:sources": 1320616004, "org.springframework.cloud:spring-cloud-context": 1118197933, "org.springframework.cloud:spring-cloud-context:jar:sources": -1413797918, + "org.springframework.cloud:spring-cloud-kubernetes-client-autoconfig": -256822388, + "org.springframework.cloud:spring-cloud-kubernetes-client-autoconfig:jar:sources": 758022911, + "org.springframework.cloud:spring-cloud-kubernetes-client-config": 954066893, + "org.springframework.cloud:spring-cloud-kubernetes-client-config:jar:sources": -251471561, + "org.springframework.cloud:spring-cloud-kubernetes-commons": -500725348, + "org.springframework.cloud:spring-cloud-kubernetes-commons:jar:sources": -325491963, "org.springframework.cloud:spring-cloud-starter": -1812063683, "org.springframework.cloud:spring-cloud-starter-bootstrap": -1263482746, "org.springframework.cloud:spring-cloud-starter-bootstrap:jar:sources": 1965832056, + "org.springframework.cloud:spring-cloud-starter-kubernetes-client-config": -251169345, "org.springframework.data:spring-data-cassandra": -1548120966, "org.springframework.data:spring-data-cassandra:jar:sources": -1628107854, "org.springframework.data:spring-data-commons": 1312199320, "org.springframework.data:spring-data-commons:jar:sources": 544548950, + "org.springframework.retry:spring-retry": -2038056656, + "org.springframework.retry:spring-retry:jar:sources": -870799349, "org.springframework.security:spring-security-config": 2001744589, "org.springframework.security:spring-security-config:jar:sources": -756968726, "org.springframework.security:spring-security-core": -1251894794, @@ -568,6 +716,8 @@ "org.springframework:spring-beans": -698130853, "org.springframework:spring-beans:jar:sources": -2147408778, "org.springframework:spring-context": -846077202, + "org.springframework:spring-context-support": 427709038, + "org.springframework:spring-context-support:jar:sources": -410245914, "org.springframework:spring-context:jar:sources": -1263444176, "org.springframework:spring-core": -253727183, "org.springframework:spring-core:jar:sources": -173347576, @@ -590,6 +740,8 @@ "org.testcontainers:testcontainers-database-commons:jar:sources": 315333060, "org.testcontainers:testcontainers-junit-jupiter": -1827576744, "org.testcontainers:testcontainers-junit-jupiter:jar:sources": 975697823, + "org.testcontainers:testcontainers-localstack": 744979553, + "org.testcontainers:testcontainers-localstack:jar:sources": 311852137, "org.testcontainers:testcontainers:jar:sources": 76092129, "org.wiremock:wiremock-standalone": -1817681233, "org.wiremock:wiremock-standalone:jar:sources": 695361099, @@ -674,6 +826,20 @@ }, "version": "1.5.34" }, + "com.bucket4j:bucket4j-core": { + "shasums": { + "jar": "c274208e4961855e8e341bcb74434af8771ce98a494aec48997028efeb4909f2", + "sources": "fb9270f4aef9d0688e12f9b83553fe2bc1fa0c15bd98894579c3f19b489ef4dc" + }, + "version": "8.10.1" + }, + "com.bucket4j:bucket4j_jdk17-core": { + "shasums": { + "jar": "603885663799e203f7e17394315fdbdc584fe021643614d8a34b49b53e618c74", + "sources": "e68a40186a9ef6f80e05db48ac76d7beca94b8d5bd635fb22aeab784ad16a520" + }, + "version": "8.19.0" + }, "com.datastax.cassandra:cassandra-driver-core": { "shasums": { "jar": "09c4d54009e942e3afb8755c5fd51abac8ba721e407b61dcb22f435d1a33c1a1", @@ -836,11 +1002,33 @@ }, "version": "1.0-1" }, + "com.google.android:annotations": { + "shasums": { + "jar": "ba734e1e84c09d615af6a09d33034b4f0442f8772dec120efb376d86a565ae15", + "sources": "e9b667aa958df78ea1ad115f7bbac18a5869c3128b1d5043feb360b0cfce9d40" + }, + "version": "4.1.1.4" + }, + "com.google.api.grpc:proto-google-common-protos": { + "shasums": { + "jar": "ee9c751f06b112e92b37f75e4f73a17d03ef2c3302c6e8d986adbcc721b63cb0", + "sources": "fe7831089c20c097ef540b61ff90d12cfe0fbc57c2bbe21a3e8fa96bb0085d99" + }, + "version": "2.29.0" + }, "com.google.code.findbugs:jsr305": { "shasums": { - "jar": "1e7f53fa5b8b5c807e986ba335665da03f18d660802d8bf061823089d1bee468" + "jar": "766ad2a0783f2687962c8ad74ceecc38a28b9f72a2d085ee438b7813e928d0c7", + "sources": "1c9e85e272d0708c6a591dc74828c71603053b48cc75ae83cce56912a2aa063b" }, - "version": "2.0.1" + "version": "3.0.2" + }, + "com.google.code.gson:gson": { + "shasums": { + "jar": "dd0ce1b55a3ed2080cb70f9c655850cda86c206862310009dcb5e5c95265a5e0", + "sources": "058974b69cb7b0a04712278e11870e84ee8cd8fb5f551bd8401e72ba6638bfef" + }, + "version": "2.13.2" }, "com.google.errorprone:error_prone_annotations": { "shasums": { @@ -876,6 +1064,20 @@ }, "version": "3.1" }, + "com.google.protobuf:protobuf-java": { + "shasums": { + "jar": "3ca892fd6ea8b37d01bb6917dbc0bf2637548b756753f65a28d4f1d4d982347f", + "sources": "ed30fe6a51c7c15a6f123448304c97185f2039f2aeca9d5e3b4f53de3a4c813c" + }, + "version": "4.33.4" + }, + "com.google.protobuf:protobuf-java-util": { + "shasums": { + "jar": "6f02f04c5ca088e74b68dbbaf118f1ffa9d587958e637f893e0f8a1899a61342", + "sources": "4bf8ae758fdaae56220796e651cf5fbc3f7ce99bdc42b7048c2604f757592f8a" + }, + "version": "4.33.4" + }, "com.jayway.jsonpath:json-path": { "shasums": { "jar": "890daa95dd3892d34d9fabc27cd5153656e6f369358625c88f4dc7b79cbd6c5a", @@ -911,6 +1113,20 @@ }, "version": "11.26.1" }, + "com.squareup.okhttp3:logging-interceptor": { + "shasums": { + "jar": "f3e8d5f0903c250c2b55d2f47fcfe008e80634385da8385161c7a63aaed0c74c", + "sources": "967335783f8af3fca7819f9f343f753243f2877c5480099e2084fe493af7da82" + }, + "version": "4.12.0" + }, + "com.squareup.okhttp3:okhttp": { + "shasums": { + "jar": "b1050081b14bb7a3a7e55a4d3ef01b5dcfabc453b4573a4fc019767191d5f4e0", + "sources": "d91a769a4140e542cddbac4e67fcf279299614e8bfd53bd23b85e60c2861341c" + }, + "version": "4.12.0" + }, "com.squareup.okhttp3:okhttp-jvm": { "shasums": { "jar": "9632c08567dbb21c569b13d793107834c8580d44e4eea74b2eae0722f0506179", @@ -918,6 +1134,13 @@ }, "version": "5.2.1" }, + "com.squareup.okio:okio": { + "shasums": { + "jar": "8e63292e5c53bb93c4a6b0c213e79f15990fed250c1340f1c343880e1c9c39b5", + "sources": "64d5b6667f064511dd93100173f735b2d5052a1c926858f4b6a05b84e825ef94" + }, + "version": "3.6.0" + }, "com.squareup.okio:okio-jvm": { "shasums": { "jar": "31f48e6463ec587d6d262d042c91da00659c983b6ad20d5982bf31e85222693c", @@ -988,6 +1211,118 @@ }, "version": "3.2.2" }, + "io.grpc:grpc-api": { + "shasums": { + "jar": "21d747911e1e5931004f1b058417f3c3f72f1fbf8aea16f5fc6af7a3f0caf35a", + "sources": "7ff367383a7e67241d72404f584a73d47d8f0a6b4c0bdf8aca4170f6475e58a3" + }, + "version": "1.63.0" + }, + "io.grpc:grpc-context": { + "shasums": { + "jar": "d7f50185bb858131d02314de23ea3cc797131ed98b215e845429f45a81dd5fed", + "sources": "a9032f8d2f795247bef60b45ee5fc3eb4693c705c05818cc12e9ed1deba440d4" + }, + "version": "1.63.0" + }, + "io.grpc:grpc-core": { + "shasums": { + "jar": "246e4e583cc11c70ed15cc8f988eff8e76fed5c06426e8310d51c4da6f5cc81b", + "sources": "6d2f37cebce94495593d736e118d6df8ff05b877e2ebc2b5e472c140a5fa5559" + }, + "version": "1.63.0" + }, + "io.grpc:grpc-inprocess": { + "shasums": { + "jar": "5386e23de85651bf868c3565bfa4f1af1bb9c888d8de5ae4350e010064041336", + "sources": "55a86f1a031e1c7dfe4bae6b6350ff561003e0395ca2c3af5114a3aab8afaa22" + }, + "version": "1.63.0" + }, + "io.grpc:grpc-netty-shaded": { + "shasums": { + "jar": "4d170c599e47214f35c8955cda3edd7cdb8171229b45795d4d61eb43dfa76402", + "sources": "a9032f8d2f795247bef60b45ee5fc3eb4693c705c05818cc12e9ed1deba440d4" + }, + "version": "1.63.0" + }, + "io.grpc:grpc-protobuf": { + "shasums": { + "jar": "260e0abaf8ac72fc71deec9f88d2beeb163e6d19494bbabe45676a4b4ce87087", + "sources": "e44785571580c4bfc25582a739f66acacf4af030bb6d58d8459532d4570225a6" + }, + "version": "1.63.0" + }, + "io.grpc:grpc-protobuf-lite": { + "shasums": { + "jar": "5e7f36c03600c7cfa8e10d2d0321f0ba8c32d74cd044873f44b026704f355fb7", + "sources": "0464b0b77b4360c0f9916477859abbbf22457a9d18c343743635e7247c2af684" + }, + "version": "1.63.0" + }, + "io.grpc:grpc-services": { + "shasums": { + "jar": "5258358c47d5afb1dc8fd6bc869c93b02bce686c156f5e0a1aab5d39b1d8e0a5", + "sources": "d265c23748ecd5c15142978d38798e8db4a2cd146cf7fe6f8cb535f202219561" + }, + "version": "1.63.0" + }, + "io.grpc:grpc-stub": { + "shasums": { + "jar": "a92fc7c7f1ac9d580c5e3df5825b977c842f442874794663b78db22b27d649e0", + "sources": "77cf1024d4612bf7ec085ff330456eb49cdbaa93e21559396f07b063ea289238" + }, + "version": "1.63.0" + }, + "io.grpc:grpc-util": { + "shasums": { + "jar": "b15006f22e76a6631dfb137a6930aaf9e0cb3a797499ec42394d79641fb770ee", + "sources": "969b6a21c1689ad8d71e4f557ccd76c9c3f422c037fe0e5c1e9c9b3f6eeb45d6" + }, + "version": "1.63.0" + }, + "io.gsonfire:gson-fire": { + "shasums": { + "jar": "73f56642ef43381efda085befb1e6cb51ce906af426d8db19632d396a5bb7a91", + "sources": "40d8500f33c7309515782d5381593a9d6c42699fc3fe38df0055ec4e08055f59" + }, + "version": "1.9.0" + }, + "io.kubernetes:client-java": { + "shasums": { + "jar": "8facf414f052bd39176703f0a5e923e3ed945fa736eb4a00cc685e633eaeb286", + "sources": "f4982edc9570241d940971b6f9a93a60976596584feba462e94c58263b234abe" + }, + "version": "24.0.0" + }, + "io.kubernetes:client-java-api": { + "shasums": { + "jar": "580bf0c6c7ab498cb53d16d975ee6fab8183e90c8993f39a9e739e100bb432d3", + "sources": "0248c50909280447729c9ab996abf41b96bcf54e1d7c9567b49dcddfae78fa67" + }, + "version": "24.0.0" + }, + "io.kubernetes:client-java-api-fluent": { + "shasums": { + "jar": "abd85f46b6a8d81032e25129dcc04a04e3efe414057255b91593e1a08aff0be5", + "sources": "febf43923730c43335aecb9bf8e16618cf9d6d35fef6acbd3b11579cf4e6cf75" + }, + "version": "24.0.0" + }, + "io.kubernetes:client-java-extended": { + "shasums": { + "jar": "5c7089ef93a08714f6b63142579cf7a9f7c2bde62bdf530174351ba390002281", + "sources": "127e271c85091a8a4f563cea1a7a4e16051b3db77b0b824ae1e51a2aada57787" + }, + "version": "24.0.0" + }, + "io.kubernetes:client-java-proto": { + "shasums": { + "jar": "ffe88472b1bac61e08fa19e8a3af53f5a4ee314913f77313f0a1beff7ca228b1", + "sources": "b954e41c5b45105699d1ee179f4e6fb6b0c707a9f3fe52a418989070194232d2" + }, + "version": "24.0.0" + }, "io.micrometer:context-propagation": { "shasums": { "jar": "5b69e2100640879ccf4b20673ced86de560b8e217b55542f85a53d3563b72aaa", @@ -1030,6 +1365,13 @@ }, "version": "1.16.6" }, + "io.micrometer:micrometer-registry-prometheus": { + "shasums": { + "jar": "0e9c7a32dffea3745f2ebff41a4cfeddc5269ca0fd6d98d6e3bafc7b5e35375d", + "sources": "76668b6182ad39e92ddc48ee7815d32cd84ceea4c6751ee13f076a86a37c8136" + }, + "version": "1.16.6" + }, "io.micrometer:micrometer-tracing": { "shasums": { "jar": "b335096393e4d070dfda4fb30808f8488d31d43811b93b2d7496703c5f1315ef", @@ -1314,6 +1656,13 @@ }, "version": "1.55.0" }, + "io.perfmark:perfmark-api": { + "shasums": { + "jar": "b7d23e93a34537ce332708269a0d1404788a5b5e1949e82f5535fce51b3ea95b", + "sources": "7379e0fef0c32d69f3ebae8f271f426fc808613f1cfbc29e680757f348ba8aa4" + }, + "version": "0.26.0" + }, "io.projectreactor.netty:reactor-netty-core": { "shasums": { "jar": "b8aaddd6025af42c2d810a76dc5b9a7717f0fde84beb93d6d4a778dac25fc287", @@ -1342,6 +1691,48 @@ }, "version": "3.8.6" }, + "io.prometheus:prometheus-metrics-config": { + "shasums": { + "jar": "3da2d5f0123af9e313bcf26f04c1248afeacd1b0d5c3a35f220034604ac0ec47", + "sources": "b926a8a6802d8f1ea9800f9e88cb4b2ff8511b6fb63786ad51d778a5f22bd059" + }, + "version": "1.4.3" + }, + "io.prometheus:prometheus-metrics-core": { + "shasums": { + "jar": "7ecd546d5238e3d3f5f312f580eaaab10cb05d147597978ab90b78080cc58255", + "sources": "48721aa5dd183e912fe82f2c19ebd980a11ed56c9a8296d23fd4011051ec8d96" + }, + "version": "1.4.3" + }, + "io.prometheus:prometheus-metrics-exposition-formats": { + "shasums": { + "jar": "502ad6b37c44b1a6311f6070a18fc921ffa2e26abb43eaaaf7626aa1b97984b6", + "sources": "4bc087c844d7dd22799e5466bcd47c7e0feda0a6fbc084c26aaa843af5cee6e9" + }, + "version": "1.4.3" + }, + "io.prometheus:prometheus-metrics-exposition-textformats": { + "shasums": { + "jar": "4aeee30d937ae5baf34ca9daced0f84400ec0f034e7beaa8331d9c519d84e3d7", + "sources": "a4b5c7b615f221b4fd6dc46a877c9c5b5151a86f03789c21f2d708407d1a9bc3" + }, + "version": "1.4.3" + }, + "io.prometheus:prometheus-metrics-model": { + "shasums": { + "jar": "bc3f1825014a14006626086ea779b62893e647e71d1eab075c0bb65057c245f8", + "sources": "61abe1dd37b1f8caea95ba193e5d85dc4b37861017731524ca155bfb57936cfe" + }, + "version": "1.4.3" + }, + "io.prometheus:prometheus-metrics-tracer-common": { + "shasums": { + "jar": "b816aaf84e45d591e5f66c5b94c7a789dedf2d705e5bf3eec2ae8730f76c68cd", + "sources": "797e6e276ccf7d874248b4d779b705ce0a400fe02b54443a04758b393de3f66e" + }, + "version": "1.4.3" + }, "io.swagger.core.v3:swagger-annotations-jakarta": { "shasums": { "jar": "9b30b319f1c31993e6128d22e12652be9a688589e30c67819ed84e95b96e7f88", @@ -1363,6 +1754,13 @@ }, "version": "2.2.47" }, + "io.swagger:swagger-annotations": { + "shasums": { + "jar": "c832295d639aa54139404b7406fb2f8fbf1da8c57219df3395de475503464297", + "sources": "7b2de9dc92520bd12e30987ee491191131e719d30e3bbe8a536f18e80ca14df3" + }, + "version": "1.6.16" + }, "jakarta.activation:jakarta.activation-api": { "shasums": { "jar": "c9db52100ce6c8aac95cc39075f95720d2e561b11f8051b81c121ad4effd7004", @@ -1398,6 +1796,13 @@ }, "version": "4.0.5" }, + "javax.annotation:javax.annotation-api": { + "shasums": { + "jar": "e04ba5195bcd555dc95650f7cc614d151e4bcd52d29a10b8aa2197f3ab89ab9b", + "sources": "128971e52e0d84a66e3b6e049dab8ad7b2c58b7e1ad37fa2debd3d40c2947b95" + }, + "version": "1.3.2" + }, "net.bytebuddy:byte-buddy": { "shasums": { "jar": "2b5ddc8c1f4234bdb7cb45338a8e10a13e0e3ca473e91d5d821d681127ea8ba1", @@ -1412,6 +1817,20 @@ }, "version": "1.17.8" }, + "net.devh:grpc-common-spring-boot": { + "shasums": { + "jar": "951fd28aa9dce0cfc5be8ff9eba6d7dc616b2998e920a7b6acc05e11f4064f94", + "sources": "157991de7c495e40c1b18f8ef274e5ff1e2c0393b75642e7308457b866b3096a" + }, + "version": "3.1.0.RELEASE" + }, + "net.devh:grpc-server-spring-boot-starter": { + "shasums": { + "jar": "289b7b45fe511d14f54801745ac3de7602bf7d7eef0fb75890bef7fbedb94ec4", + "sources": "e0ddd0872ffbbc48c322ba617035bafd0f5bc656e91eec0bda876d3f07d9f3f1" + }, + "version": "3.1.0.RELEASE" + }, "net.java.dev.jna:jna": { "shasums": { "jar": "260c4b1e22b1db9e110ee441c4f13ce115f841fa48c41d78750986214b395557", @@ -1419,6 +1838,27 @@ }, "version": "5.18.1" }, + "net.javacrumbs.shedlock:shedlock-core": { + "shasums": { + "jar": "b2ca6f358b5dcbadc641a7c5ef6217b8c5f91bc2b49e89d715fdd5443cc48166", + "sources": "81a2914ff05c94d86b54d78fa59f79216df1db8e980d5d5a910559f6da3bb9e1" + }, + "version": "7.7.0" + }, + "net.javacrumbs.shedlock:shedlock-provider-cassandra": { + "shasums": { + "jar": "e8a5db022350461384618f4ebaf978dbc2894becb208d7c053ae0125dd31a7eb", + "sources": "2e6e6fdcbc77faffaa22b16850ae4b50f7693439b59fc146c0ec9f510c012eb5" + }, + "version": "7.7.0" + }, + "net.javacrumbs.shedlock:shedlock-spring": { + "shasums": { + "jar": "a71fa9d539b10140b5aaea5a4a0e58f219b396195b6bc7148c8adf65425cbce1", + "sources": "bb61469b2f50396b4ab6ccb2a30ecb3d394ca0d0c986f43086de2beaafeac67e" + }, + "version": "7.7.0" + }, "net.minidev:accessors-smart": { "shasums": { "jar": "222c9f547bb20a99fc486403a398352d1306fb671b38abd7ecab6401df170e61", @@ -1461,6 +1901,13 @@ }, "version": "4.19.3" }, + "org.apache.commons:commons-collections4": { + "shasums": { + "jar": "00f93263c267be201b8ae521b44a7137271b16688435340bf629db1bac0a5845", + "sources": "75f1bef9447cce189743f7d52f63a669bd796ae19ca863e1f22db1d5b6b504a6" + }, + "version": "4.5.0" + }, "org.apache.commons:commons-compress": { "shasums": { "jar": "e1522945218456f3649a39bc4afd70ce4bd466221519dba7d378f2141a4642ca", @@ -1517,6 +1964,13 @@ }, "version": "1.1.2" }, + "org.aspectj:aspectjweaver": { + "shasums": { + "jar": "4fe86fdc18faea571f29129c70eaad5d121363504a06d7907be88f6c60ba3116", + "sources": "06fbde6ef3a83791e70965432b5f1891e493e21cdbc37307c54575ee86752595" + }, + "version": "1.9.25.1" + }, "org.assertj:assertj-core": { "shasums": { "jar": "c4a445426c3c2861666863b842cc4ec7bbb1c4226fefd370b6d2fe83d6c4ff0f", @@ -1531,6 +1985,20 @@ }, "version": "4.3.0" }, + "org.bitbucket.b_c:jose4j": { + "shasums": { + "jar": "7314af50cde9c99e8eaf43eee617a23edcc6bb43036221064355094999d837ef", + "sources": "958be1837b507d3a1f1187257072b4c1e1d031c3a0c610d3c02ac69aabfac6a5" + }, + "version": "0.9.6" + }, + "org.bouncycastle:bcpkix-jdk18on": { + "shasums": { + "jar": "4f4ba6a92617ea19dc183f0fa5db492eee426fdde2a0a2d6c94777ffd1af6413", + "sources": "601ec2beb4749f0be65e296811b6e63de567f90d124f26887875bb722fd87e71" + }, + "version": "1.80" + }, "org.bouncycastle:bcprov-jdk18on": { "shasums": { "jar": "64d6c5a6121fcd927152dd182cbed39afe0fda641a970d9bcc0c9cb1858b2731", @@ -1545,6 +2013,20 @@ }, "version": "2.73.8" }, + "org.bouncycastle:bcutil-jdk18on": { + "shasums": { + "jar": "bc78d32d7ffb141ee27e4fb77df04259d842c899e7e8eaf912f990d7253bd3b4", + "sources": "f1e43055e8287cde556a7741bf16b7fd7896b8f572ab91e0cadb337e710b015f" + }, + "version": "1.80.2" + }, + "org.codehaus.mojo:animal-sniffer-annotations": { + "shasums": { + "jar": "9ffe526bf43a6348e9d8b33b9cd6f580a7f5eed0cf055913007eda263de974d0", + "sources": "4878fcc6808dbc88085a4622db670e703867754bc4bc40312c52bf3a3510d019" + }, + "version": "1.23" + }, "org.hamcrest:hamcrest": { "shasums": { "jar": "5d66b6a4a680755cb6ed7cb104fa7835ef644667586ff0737adeb977c39ecdbc", @@ -1608,6 +2090,20 @@ }, "version": "2.2.21" }, + "org.jetbrains.kotlin:kotlin-stdlib-jdk7": { + "shasums": { + "jar": "b785922f11e6d91a6dd1d75cb0aef1ce37b83f8de0e3a2139139dfb823bb8a2c", + "sources": "2534c8908432e06de73177509903d405b55f423dd4c2f747e16b92a2162611e6" + }, + "version": "2.2.21" + }, + "org.jetbrains.kotlin:kotlin-stdlib-jdk8": { + "shasums": { + "jar": "c62275c50ee591ca2f82c7ba42696b791600c25844f47e84bd9460302a0d5238", + "sources": "3cb6895054a0985bba591c165503fe4dd63a215af53263b67a071ccdc242bf6e" + }, + "version": "2.2.21" + }, "org.jetbrains:annotations": { "shasums": { "jar": "195fb0da046d55bb042e91543484cf1da68b02bb7afbfe031f229e45ac84b3f2", @@ -1916,6 +2412,13 @@ }, "version": "4.0.7" }, + "org.springframework.boot:spring-boot-loader": { + "shasums": { + "jar": "bb1cd5fee23e03eec3fb5fdaff59c56d1db3829afe5f59381904764df76fb1a8", + "sources": "539b6b3e0fde31a126ee1bc885840874aae9275f28c8c7d4c30e1c15ed85b221" + }, + "version": "4.0.7" + }, "org.springframework.boot:spring-boot-micrometer-metrics": { "shasums": { "jar": "1cd20b112104d244fdc96b44b3a8193e0916686a819a6be93127c1c7eefc1c9d", @@ -2056,6 +2559,13 @@ }, "version": "4.0.7" }, + "org.springframework.boot:spring-boot-starter-aspectj": { + "shasums": { + "jar": "5521390213e6f2a0a3ef0d78eed35094868f840888823f9508e175dab10e7306", + "sources": "5521390213e6f2a0a3ef0d78eed35094868f840888823f9508e175dab10e7306" + }, + "version": "4.0.7" + }, "org.springframework.boot:spring-boot-starter-data-cassandra": { "shasums": { "jar": "32abc561b414e781bc1998e1a6cd1167f3eff2247e6bb2b1b08a347bb3054acb", @@ -2301,6 +2811,27 @@ }, "version": "5.0.2" }, + "org.springframework.cloud:spring-cloud-kubernetes-client-autoconfig": { + "shasums": { + "jar": "3ccfe0d3f130c7e2ddede783c416a331e935c5818df7ad6a0369c646641cd596", + "sources": "15ba3dfaf88146e82232510b8a02bdb1c0e6982efe5a0e00a5bbaacd40f7321f" + }, + "version": "5.0.2" + }, + "org.springframework.cloud:spring-cloud-kubernetes-client-config": { + "shasums": { + "jar": "3891c4930a4c214e316a6f1624a596c4007f759b3465cc1fa3cb1fc7edba2614", + "sources": "abf13b94b56188d1df40c9f080c3771c77c1252350a4d6b674887fa1466076e5" + }, + "version": "5.0.2" + }, + "org.springframework.cloud:spring-cloud-kubernetes-commons": { + "shasums": { + "jar": "34a0c7e9a1036e03faa0d75655f7e82eade86f6fc3b4ae2273e434b5798bd8f5", + "sources": "bec63622fa749d090a711f9a24b0c0561f70a8ee5853db7c1bf727990c373817" + }, + "version": "5.0.2" + }, "org.springframework.cloud:spring-cloud-starter": { "shasums": { "jar": "7568b8ced4069bc055af52b5455b206092401a44dcbd4f89d6fa00f89df1cc18" @@ -2314,6 +2845,12 @@ }, "version": "5.0.2" }, + "org.springframework.cloud:spring-cloud-starter-kubernetes-client-config": { + "shasums": { + "jar": "f0b4f8adf2dbac198147d18e1890e5ebd5f41d8de4db68ae5eca930e946c1efe" + }, + "version": "5.0.2" + }, "org.springframework.data:spring-data-cassandra": { "shasums": { "jar": "d9e4f2656df238d5561d02d0521036f52518b91d0ef840fd8f25d113b4325610", @@ -2328,6 +2865,13 @@ }, "version": "4.0.6" }, + "org.springframework.retry:spring-retry": { + "shasums": { + "jar": "213785750007f90b067ba43036cbffdad2890f6bb98917e199f6b049cf810040", + "sources": "672447ec8df39cf31fcd8b9fdd209ae65776fb06c17e1e6fd13e30943963947b" + }, + "version": "2.0.13" + }, "org.springframework.security:spring-security-config": { "shasums": { "jar": "7aeafd876d48d8b5660356953ed7a607d2d09e8f2b9844acba3fcbc32beb63cc", @@ -2412,6 +2956,13 @@ }, "version": "7.0.8" }, + "org.springframework:spring-context-support": { + "shasums": { + "jar": "9ab80715682c47ad66a1a2c0e9ab2be9ec3d828276f281597f12c5208147b92e", + "sources": "22d3e1ee4d52ede6b31cd6fd27d65d4bdd0b2709fcc14af92ec287286ae8abf3" + }, + "version": "7.0.8" + }, "org.springframework:spring-core": { "shasums": { "jar": "726ba2a5130833644bdf267a55ff26e1f52e8dcc9aa1ffa06904ca9c14619f25", @@ -2489,6 +3040,13 @@ }, "version": "2.0.5" }, + "org.testcontainers:testcontainers-localstack": { + "shasums": { + "jar": "2fa0f4271a69112ece3841bb26b251962280e39f2e6b2daa7a4aa9128a54485d", + "sources": "b37477b207c29a395c8d0428a6131954aa3495ba2cf5a8db40c9f57c1e8cfa8d" + }, + "version": "2.0.5" + }, "org.wiremock:wiremock-standalone": { "shasums": { "jar": "d097b19bd483c5038479b13a5c71e9faf8f2f5106584f0c120a7770ab0bdb367", @@ -2654,14 +3212,19 @@ "conflict_resolution": { "com.github.jnr:jnr-ffi:2.2.11": "com.github.jnr:jnr-ffi:2.1.7", "com.github.jnr:jnr-posix:3.0.44": "com.github.jnr:jnr-posix:3.1.15", - "com.google.code.findbugs:jsr305:3.0.2": "com.google.code.findbugs:jsr305:2.0.1", + "com.google.code.findbugs:jsr305:2.0.1": "com.google.code.findbugs:jsr305:3.0.2", + "com.google.errorprone:error_prone_annotations:2.18.0": "com.google.errorprone:error_prone_annotations:2.49.0", + "com.google.errorprone:error_prone_annotations:2.23.0": "com.google.errorprone:error_prone_annotations:2.49.0", + "com.google.errorprone:error_prone_annotations:2.41.0": "com.google.errorprone:error_prone_annotations:2.49.0", "com.google.errorprone:error_prone_annotations:2.47.0": "com.google.errorprone:error_prone_annotations:2.49.0", "com.google.guava:guava:19.0": "com.google.guava:guava:33.6.0-jre", - "org.jetbrains:annotations:13.0": "org.jetbrains:annotations:17.0.0", - "org.ow2.asm:asm-commons:5.0.3": "org.ow2.asm:asm-commons:9.9", - "org.ow2.asm:asm-tree:5.0.3": "org.ow2.asm:asm-tree:9.9", - "org.ow2.asm:asm:5.0.3": "org.ow2.asm:asm:9.9", - "org.ow2.asm:asm:9.7.1": "org.ow2.asm:asm:9.9" + "com.google.guava:guava:32.1.3-android": "com.google.guava:guava:33.6.0-jre", + "com.google.guava:guava:32.1.3-jre": "com.google.guava:guava:33.6.0-jre", + "com.google.j2objc:j2objc-annotations:2.8": "com.google.j2objc:j2objc-annotations:3.1", + "com.squareup.okio:okio-jvm:3.6.0": "com.squareup.okio:okio-jvm:3.16.1", + "commons-io:commons-io:2.19.0": "commons-io:commons-io:2.20.0", + "org.apache.commons:commons-compress:1.27.1": "org.apache.commons:commons-compress:1.28.0", + "org.jetbrains:annotations:13.0": "org.jetbrains:annotations:17.0.0" }, "dependencies": { "ch.qos.logback:logback-classic": [ @@ -2739,6 +3302,12 @@ "com.github.jnr:jnr-constants", "com.github.jnr:jnr-ffi" ], + "com.google.api.grpc:proto-google-common-protos": [ + "com.google.protobuf:protobuf-java" + ], + "com.google.code.gson:gson": [ + "com.google.errorprone:error_prone_annotations" + ], "com.google.guava:guava": [ "com.google.errorprone:error_prone_annotations", "com.google.guava:failureaccess", @@ -2746,6 +3315,12 @@ "com.google.j2objc:j2objc-annotations", "org.jspecify:jspecify" ], + "com.google.protobuf:protobuf-java-util": [ + "com.google.code.findbugs:jsr305", + "com.google.code.gson:gson", + "com.google.errorprone:error_prone_annotations", + "com.google.protobuf:protobuf-java" + ], "com.jayway.jsonpath:json-path": [ "net.minidev:json-smart", "org.slf4j:slf4j-api" @@ -2757,10 +3332,21 @@ "com.nimbusds:nimbus-jose-jwt", "net.minidev:json-smart" ], + "com.squareup.okhttp3:logging-interceptor": [ + "com.squareup.okhttp3:okhttp", + "org.jetbrains.kotlin:kotlin-stdlib-jdk8" + ], + "com.squareup.okhttp3:okhttp": [ + "com.squareup.okio:okio", + "org.jetbrains.kotlin:kotlin-stdlib-jdk8" + ], "com.squareup.okhttp3:okhttp-jvm": [ "com.squareup.okio:okio-jvm", "org.jetbrains.kotlin:kotlin-stdlib" ], + "com.squareup.okio:okio": [ + "com.squareup.okio:okio-jvm" + ], "com.squareup.okio:okio-jvm": [ "org.jetbrains.kotlin:kotlin-stdlib" ], @@ -2775,6 +3361,116 @@ "io.dropwizard.metrics:metrics-core": [ "org.slf4j:slf4j-api" ], + "io.grpc:grpc-api": [ + "com.google.code.findbugs:jsr305", + "com.google.errorprone:error_prone_annotations", + "com.google.guava:guava" + ], + "io.grpc:grpc-context": [ + "io.grpc:grpc-api" + ], + "io.grpc:grpc-core": [ + "com.google.android:annotations", + "com.google.code.gson:gson", + "com.google.errorprone:error_prone_annotations", + "com.google.guava:guava", + "io.grpc:grpc-api", + "io.grpc:grpc-context", + "io.perfmark:perfmark-api", + "org.codehaus.mojo:animal-sniffer-annotations" + ], + "io.grpc:grpc-inprocess": [ + "com.google.guava:guava", + "io.grpc:grpc-api", + "io.grpc:grpc-core" + ], + "io.grpc:grpc-netty-shaded": [ + "com.google.errorprone:error_prone_annotations", + "com.google.guava:guava", + "io.grpc:grpc-api", + "io.grpc:grpc-core", + "io.grpc:grpc-util", + "io.perfmark:perfmark-api" + ], + "io.grpc:grpc-protobuf": [ + "com.google.api.grpc:proto-google-common-protos", + "com.google.code.findbugs:jsr305", + "com.google.guava:guava", + "com.google.protobuf:protobuf-java", + "io.grpc:grpc-api", + "io.grpc:grpc-protobuf-lite" + ], + "io.grpc:grpc-protobuf-lite": [ + "com.google.code.findbugs:jsr305", + "com.google.guava:guava", + "io.grpc:grpc-api" + ], + "io.grpc:grpc-services": [ + "com.google.code.gson:gson", + "com.google.errorprone:error_prone_annotations", + "com.google.guava:guava", + "com.google.j2objc:j2objc-annotations", + "com.google.protobuf:protobuf-java-util", + "io.grpc:grpc-core", + "io.grpc:grpc-protobuf", + "io.grpc:grpc-stub", + "io.grpc:grpc-util" + ], + "io.grpc:grpc-stub": [ + "com.google.errorprone:error_prone_annotations", + "com.google.guava:guava", + "io.grpc:grpc-api" + ], + "io.grpc:grpc-util": [ + "com.google.guava:guava", + "io.grpc:grpc-api", + "io.grpc:grpc-core", + "org.codehaus.mojo:animal-sniffer-annotations" + ], + "io.gsonfire:gson-fire": [ + "com.google.code.gson:gson" + ], + "io.kubernetes:client-java": [ + "com.google.protobuf:protobuf-java", + "commons-codec:commons-codec", + "commons-io:commons-io", + "io.kubernetes:client-java-api", + "io.kubernetes:client-java-proto", + "org.apache.commons:commons-collections4", + "org.apache.commons:commons-compress", + "org.apache.commons:commons-lang3", + "org.bitbucket.b_c:jose4j", + "org.bouncycastle:bcpkix-jdk18on", + "org.slf4j:slf4j-api", + "org.yaml:snakeyaml" + ], + "io.kubernetes:client-java-api": [ + "com.fasterxml.jackson.core:jackson-databind", + "com.google.code.findbugs:jsr305", + "com.google.code.gson:gson", + "com.squareup.okhttp3:logging-interceptor", + "com.squareup.okhttp3:okhttp", + "io.gsonfire:gson-fire", + "io.swagger:swagger-annotations", + "jakarta.annotation:jakarta.annotation-api", + "javax.annotation:javax.annotation-api", + "org.apache.commons:commons-lang3" + ], + "io.kubernetes:client-java-api-fluent": [ + "io.kubernetes:client-java-api" + ], + "io.kubernetes:client-java-extended": [ + "com.bucket4j:bucket4j-core", + "com.github.ben-manes.caffeine:caffeine", + "io.kubernetes:client-java", + "io.kubernetes:client-java-api", + "io.kubernetes:client-java-api-fluent", + "io.kubernetes:client-java-proto", + "org.apache.commons:commons-lang3" + ], + "io.kubernetes:client-java-proto": [ + "com.google.protobuf:protobuf-java" + ], "io.micrometer:context-propagation": [ "org.jspecify:jspecify" ], @@ -2805,6 +3501,13 @@ "org.junit.jupiter:junit-jupiter", "org.mockito:mockito-core" ], + "io.micrometer:micrometer-registry-prometheus": [ + "io.micrometer:micrometer-core", + "io.prometheus:prometheus-metrics-core", + "io.prometheus:prometheus-metrics-exposition-formats", + "io.prometheus:prometheus-metrics-tracer-common", + "org.jspecify:jspecify" + ], "io.micrometer:micrometer-tracing": [ "aopalliance:aopalliance", "io.micrometer:context-propagation", @@ -3047,6 +3750,20 @@ "io.projectreactor:reactor-core", "org.jspecify:jspecify" ], + "io.prometheus:prometheus-metrics-core": [ + "io.prometheus:prometheus-metrics-config", + "io.prometheus:prometheus-metrics-model" + ], + "io.prometheus:prometheus-metrics-exposition-formats": [ + "io.prometheus:prometheus-metrics-exposition-textformats" + ], + "io.prometheus:prometheus-metrics-exposition-textformats": [ + "io.prometheus:prometheus-metrics-config", + "io.prometheus:prometheus-metrics-model" + ], + "io.prometheus:prometheus-metrics-model": [ + "io.prometheus:prometheus-metrics-config" + ], "io.swagger.core.v3:swagger-core-jakarta": [ "com.fasterxml.jackson.core:jackson-annotations", "com.fasterxml.jackson.core:jackson-databind", @@ -3066,6 +3783,32 @@ "jakarta.xml.bind:jakarta.xml.bind-api": [ "jakarta.activation:jakarta.activation-api" ], + "net.devh:grpc-common-spring-boot": [ + "io.grpc:grpc-core", + "org.springframework.boot:spring-boot-starter" + ], + "net.devh:grpc-server-spring-boot-starter": [ + "io.grpc:grpc-api", + "io.grpc:grpc-inprocess", + "io.grpc:grpc-netty-shaded", + "io.grpc:grpc-protobuf", + "io.grpc:grpc-services", + "io.grpc:grpc-stub", + "net.devh:grpc-common-spring-boot", + "org.springframework.boot:spring-boot-starter" + ], + "net.javacrumbs.shedlock:shedlock-core": [ + "org.slf4j:slf4j-api" + ], + "net.javacrumbs.shedlock:shedlock-provider-cassandra": [ + "net.javacrumbs.shedlock:shedlock-core", + "org.apache.cassandra:java-driver-core", + "org.apache.cassandra:java-driver-query-builder" + ], + "net.javacrumbs.shedlock:shedlock-spring": [ + "net.javacrumbs.shedlock:shedlock-core", + "org.springframework:spring-context" + ], "net.minidev:accessors-smart": [ "org.ow2.asm:asm" ], @@ -3109,6 +3852,15 @@ "org.awaitility:awaitility": [ "org.hamcrest:hamcrest" ], + "org.bitbucket.b_c:jose4j": [ + "org.slf4j:slf4j-api" + ], + "org.bouncycastle:bcpkix-jdk18on": [ + "org.bouncycastle:bcutil-jdk18on" + ], + "org.bouncycastle:bcutil-jdk18on": [ + "org.bouncycastle:bcprov-jdk18on" + ], "org.hibernate.validator:hibernate-validator": [ "com.fasterxml:classmate", "jakarta.validation:jakarta.validation-api", @@ -3130,6 +3882,13 @@ "org.jetbrains.kotlin:kotlin-stdlib": [ "org.jetbrains:annotations" ], + "org.jetbrains.kotlin:kotlin-stdlib-jdk7": [ + "org.jetbrains.kotlin:kotlin-stdlib" + ], + "org.jetbrains.kotlin:kotlin-stdlib-jdk8": [ + "org.jetbrains.kotlin:kotlin-stdlib", + "org.jetbrains.kotlin:kotlin-stdlib-jdk7" + ], "org.junit.jupiter:junit-jupiter": [ "org.junit.jupiter:junit-jupiter-api", "org.junit.jupiter:junit-jupiter-engine", @@ -3381,6 +4140,11 @@ "org.springframework.boot:spring-boot-starter-micrometer-metrics-test", "org.springframework.boot:spring-boot-starter-test" ], + "org.springframework.boot:spring-boot-starter-aspectj": [ + "org.aspectj:aspectjweaver", + "org.springframework.boot:spring-boot-starter", + "org.springframework:spring-aop" + ], "org.springframework.boot:spring-boot-starter-data-cassandra": [ "org.springframework.boot:spring-boot-cassandra", "org.springframework.boot:spring-boot-data-cassandra", @@ -3575,6 +4339,26 @@ "org.springframework.cloud:spring-cloud-context": [ "org.springframework.security:spring-security-crypto" ], + "org.springframework.cloud:spring-cloud-kubernetes-client-autoconfig": [ + "io.kubernetes:client-java", + "io.kubernetes:client-java-extended", + "org.springframework.boot:spring-boot-autoconfigure", + "org.springframework.cloud:spring-cloud-kubernetes-commons" + ], + "org.springframework.cloud:spring-cloud-kubernetes-client-config": [ + "io.kubernetes:client-java", + "io.kubernetes:client-java-extended", + "org.springframework.boot:spring-boot-autoconfigure", + "org.springframework.cloud:spring-cloud-kubernetes-client-autoconfig", + "org.springframework.cloud:spring-cloud-kubernetes-commons", + "org.springframework.cloud:spring-cloud-starter" + ], + "org.springframework.cloud:spring-cloud-kubernetes-commons": [ + "jakarta.annotation:jakarta.annotation-api", + "org.springframework.boot:spring-boot-autoconfigure", + "org.springframework.cloud:spring-cloud-commons", + "org.springframework.cloud:spring-cloud-context" + ], "org.springframework.cloud:spring-cloud-starter": [ "org.bouncycastle:bcprov-jdk18on", "org.springframework.boot:spring-boot-starter", @@ -3584,6 +4368,9 @@ "org.springframework.cloud:spring-cloud-starter-bootstrap": [ "org.springframework.cloud:spring-cloud-starter" ], + "org.springframework.cloud:spring-cloud-starter-kubernetes-client-config": [ + "org.springframework.cloud:spring-cloud-kubernetes-client-config" + ], "org.springframework.data:spring-data-cassandra": [ "org.apache.cassandra:java-driver-core", "org.apache.cassandra:java-driver-query-builder", @@ -3669,6 +4456,11 @@ "org.springframework:spring-core", "org.springframework:spring-expression" ], + "org.springframework:spring-context-support": [ + "org.springframework:spring-beans", + "org.springframework:spring-context", + "org.springframework:spring-core" + ], "org.springframework:spring-core": [ "commons-logging:commons-logging", "org.jspecify:jspecify" @@ -3719,6 +4511,9 @@ "org.testcontainers:testcontainers-junit-jupiter": [ "org.testcontainers:testcontainers" ], + "org.testcontainers:testcontainers-localstack": [ + "org.testcontainers:testcontainers" + ], "org.xmlunit:xmlunit-core": [ "jakarta.xml.bind:jakarta.xml.bind-api" ], @@ -3905,6 +4700,52 @@ "ch.qos.logback.core.testUtil", "ch.qos.logback.core.util" ], + "com.bucket4j:bucket4j-core": [ + "io.github.bucket4j", + "io.github.bucket4j.distributed", + "io.github.bucket4j.distributed.expiration", + "io.github.bucket4j.distributed.jdbc", + "io.github.bucket4j.distributed.proxy", + "io.github.bucket4j.distributed.proxy.generic.compare_and_swap", + "io.github.bucket4j.distributed.proxy.generic.pessimistic_locking", + "io.github.bucket4j.distributed.proxy.generic.select_for_update", + "io.github.bucket4j.distributed.proxy.optimization", + "io.github.bucket4j.distributed.proxy.optimization.batch", + "io.github.bucket4j.distributed.proxy.optimization.delay", + "io.github.bucket4j.distributed.proxy.optimization.manual", + "io.github.bucket4j.distributed.proxy.optimization.predictive", + "io.github.bucket4j.distributed.proxy.optimization.skiponzero", + "io.github.bucket4j.distributed.remote", + "io.github.bucket4j.distributed.remote.commands", + "io.github.bucket4j.distributed.serialization", + "io.github.bucket4j.distributed.versioning", + "io.github.bucket4j.local", + "io.github.bucket4j.util", + "io.github.bucket4j.util.concurrent.batch" + ], + "com.bucket4j:bucket4j_jdk17-core": [ + "io.github.bucket4j", + "io.github.bucket4j.distributed", + "io.github.bucket4j.distributed.expiration", + "io.github.bucket4j.distributed.jdbc", + "io.github.bucket4j.distributed.proxy", + "io.github.bucket4j.distributed.proxy.generic.compare_and_swap", + "io.github.bucket4j.distributed.proxy.generic.pessimistic_locking", + "io.github.bucket4j.distributed.proxy.generic.select_for_update", + "io.github.bucket4j.distributed.proxy.optimization", + "io.github.bucket4j.distributed.proxy.optimization.batch", + "io.github.bucket4j.distributed.proxy.optimization.delay", + "io.github.bucket4j.distributed.proxy.optimization.manual", + "io.github.bucket4j.distributed.proxy.optimization.predictive", + "io.github.bucket4j.distributed.proxy.optimization.skiponzero", + "io.github.bucket4j.distributed.remote", + "io.github.bucket4j.distributed.remote.commands", + "io.github.bucket4j.distributed.serialization", + "io.github.bucket4j.distributed.versioning", + "io.github.bucket4j.local", + "io.github.bucket4j.util", + "io.github.bucket4j.util.concurrent.batch" + ], "com.datastax.cassandra:cassandra-driver-core": [ "com.datastax.driver.core", "com.datastax.driver.core.exceptions", @@ -4180,11 +5021,37 @@ "com.github.stephenc.jcip:jcip-annotations": [ "net.jcip.annotations" ], + "com.google.android:annotations": [ + "android.annotation" + ], + "com.google.api.grpc:proto-google-common-protos": [ + "com.google.api", + "com.google.cloud", + "com.google.cloud.audit", + "com.google.cloud.location", + "com.google.geo.type", + "com.google.logging.type", + "com.google.longrunning", + "com.google.rpc", + "com.google.rpc.context", + "com.google.type" + ], "com.google.code.findbugs:jsr305": [ "javax.annotation", "javax.annotation.concurrent", "javax.annotation.meta" ], + "com.google.code.gson:gson": [ + "com.google.gson", + "com.google.gson.annotations", + "com.google.gson.internal", + "com.google.gson.internal.bind", + "com.google.gson.internal.bind.util", + "com.google.gson.internal.reflect", + "com.google.gson.internal.sql", + "com.google.gson.reflect", + "com.google.gson.stream" + ], "com.google.errorprone:error_prone_annotations": [ "com.google.errorprone.annotations", "com.google.errorprone.annotations.concurrent" @@ -4215,6 +5082,13 @@ "com.google.j2objc:j2objc-annotations": [ "com.google.j2objc.annotations" ], + "com.google.protobuf:protobuf-java": [ + "com.google.protobuf", + "com.google.protobuf.compiler" + ], + "com.google.protobuf:protobuf-java-util": [ + "com.google.protobuf.util" + ], "com.jayway.jsonpath:json-path": [ "com.jayway.jsonpath", "com.jayway.jsonpath.internal", @@ -4323,6 +5197,28 @@ "com.nimbusds.openid.connect.sdk.validators", "com.nimbusds.secevent.sdk.claims" ], + "com.squareup.okhttp3:logging-interceptor": [ + "okhttp3.logging" + ], + "com.squareup.okhttp3:okhttp": [ + "okhttp3", + "okhttp3.internal", + "okhttp3.internal.authenticator", + "okhttp3.internal.cache", + "okhttp3.internal.cache2", + "okhttp3.internal.concurrent", + "okhttp3.internal.connection", + "okhttp3.internal.http", + "okhttp3.internal.http1", + "okhttp3.internal.http2", + "okhttp3.internal.io", + "okhttp3.internal.platform", + "okhttp3.internal.platform.android", + "okhttp3.internal.proxy", + "okhttp3.internal.publicsuffix", + "okhttp3.internal.tls", + "okhttp3.internal.ws" + ], "com.squareup.okhttp3:okhttp-jvm": [ "okhttp3", "okhttp3.internal", @@ -4413,6 +5309,174 @@ "io.dropwizard.metrics:metrics-core": [ "com.codahale.metrics" ], + "io.grpc:grpc-api": [ + "io.grpc" + ], + "io.grpc:grpc-core": [ + "io.grpc.internal" + ], + "io.grpc:grpc-inprocess": [ + "io.grpc.inprocess" + ], + "io.grpc:grpc-netty-shaded": [ + "io.grpc.netty.shaded.io.grpc.netty", + "io.grpc.netty.shaded.io.netty.bootstrap", + "io.grpc.netty.shaded.io.netty.buffer", + "io.grpc.netty.shaded.io.netty.buffer.search", + "io.grpc.netty.shaded.io.netty.channel", + "io.grpc.netty.shaded.io.netty.channel.embedded", + "io.grpc.netty.shaded.io.netty.channel.epoll", + "io.grpc.netty.shaded.io.netty.channel.group", + "io.grpc.netty.shaded.io.netty.channel.internal", + "io.grpc.netty.shaded.io.netty.channel.local", + "io.grpc.netty.shaded.io.netty.channel.nio", + "io.grpc.netty.shaded.io.netty.channel.oio", + "io.grpc.netty.shaded.io.netty.channel.pool", + "io.grpc.netty.shaded.io.netty.channel.socket", + "io.grpc.netty.shaded.io.netty.channel.socket.nio", + "io.grpc.netty.shaded.io.netty.channel.socket.oio", + "io.grpc.netty.shaded.io.netty.channel.unix", + "io.grpc.netty.shaded.io.netty.handler.address", + "io.grpc.netty.shaded.io.netty.handler.codec", + "io.grpc.netty.shaded.io.netty.handler.codec.base64", + "io.grpc.netty.shaded.io.netty.handler.codec.bytes", + "io.grpc.netty.shaded.io.netty.handler.codec.compression", + "io.grpc.netty.shaded.io.netty.handler.codec.http", + "io.grpc.netty.shaded.io.netty.handler.codec.http.cookie", + "io.grpc.netty.shaded.io.netty.handler.codec.http.cors", + "io.grpc.netty.shaded.io.netty.handler.codec.http.multipart", + "io.grpc.netty.shaded.io.netty.handler.codec.http.websocketx", + "io.grpc.netty.shaded.io.netty.handler.codec.http.websocketx.extensions", + "io.grpc.netty.shaded.io.netty.handler.codec.http.websocketx.extensions.compression", + "io.grpc.netty.shaded.io.netty.handler.codec.http2", + "io.grpc.netty.shaded.io.netty.handler.codec.json", + "io.grpc.netty.shaded.io.netty.handler.codec.marshalling", + "io.grpc.netty.shaded.io.netty.handler.codec.protobuf", + "io.grpc.netty.shaded.io.netty.handler.codec.rtsp", + "io.grpc.netty.shaded.io.netty.handler.codec.serialization", + "io.grpc.netty.shaded.io.netty.handler.codec.socks", + "io.grpc.netty.shaded.io.netty.handler.codec.socksx", + "io.grpc.netty.shaded.io.netty.handler.codec.socksx.v4", + "io.grpc.netty.shaded.io.netty.handler.codec.socksx.v5", + "io.grpc.netty.shaded.io.netty.handler.codec.spdy", + "io.grpc.netty.shaded.io.netty.handler.codec.string", + "io.grpc.netty.shaded.io.netty.handler.codec.xml", + "io.grpc.netty.shaded.io.netty.handler.flow", + "io.grpc.netty.shaded.io.netty.handler.flush", + "io.grpc.netty.shaded.io.netty.handler.ipfilter", + "io.grpc.netty.shaded.io.netty.handler.logging", + "io.grpc.netty.shaded.io.netty.handler.pcap", + "io.grpc.netty.shaded.io.netty.handler.proxy", + "io.grpc.netty.shaded.io.netty.handler.ssl", + "io.grpc.netty.shaded.io.netty.handler.ssl.ocsp", + "io.grpc.netty.shaded.io.netty.handler.ssl.util", + "io.grpc.netty.shaded.io.netty.handler.stream", + "io.grpc.netty.shaded.io.netty.handler.timeout", + "io.grpc.netty.shaded.io.netty.handler.traffic", + "io.grpc.netty.shaded.io.netty.internal.tcnative", + "io.grpc.netty.shaded.io.netty.resolver", + "io.grpc.netty.shaded.io.netty.util", + "io.grpc.netty.shaded.io.netty.util.collection", + "io.grpc.netty.shaded.io.netty.util.concurrent", + "io.grpc.netty.shaded.io.netty.util.internal", + "io.grpc.netty.shaded.io.netty.util.internal.logging", + "io.grpc.netty.shaded.io.netty.util.internal.shaded.org.jctools.queues", + "io.grpc.netty.shaded.io.netty.util.internal.shaded.org.jctools.queues.atomic", + "io.grpc.netty.shaded.io.netty.util.internal.shaded.org.jctools.util", + "io.grpc.netty.shaded.io.netty.util.internal.svm" + ], + "io.grpc:grpc-protobuf": [ + "io.grpc.protobuf" + ], + "io.grpc:grpc-protobuf-lite": [ + "io.grpc.protobuf.lite" + ], + "io.grpc:grpc-services": [ + "io.grpc.binarylog.v1", + "io.grpc.channelz.v1", + "io.grpc.health.v1", + "io.grpc.protobuf.services", + "io.grpc.protobuf.services.internal", + "io.grpc.reflection.v1alpha", + "io.grpc.services" + ], + "io.grpc:grpc-stub": [ + "io.grpc.stub", + "io.grpc.stub.annotations" + ], + "io.grpc:grpc-util": [ + "io.grpc.util" + ], + "io.gsonfire:gson-fire": [ + "io.gsonfire", + "io.gsonfire.annotations", + "io.gsonfire.builders", + "io.gsonfire.gson", + "io.gsonfire.postprocessors", + "io.gsonfire.postprocessors.methodinvoker", + "io.gsonfire.util", + "io.gsonfire.util.reflection" + ], + "io.kubernetes:client-java": [ + "io.kubernetes.client", + "io.kubernetes.client.apimachinery", + "io.kubernetes.client.informer", + "io.kubernetes.client.informer.cache", + "io.kubernetes.client.informer.exception", + "io.kubernetes.client.informer.impl", + "io.kubernetes.client.monitoring", + "io.kubernetes.client.persister", + "io.kubernetes.client.simplified", + "io.kubernetes.client.util", + "io.kubernetes.client.util.annotations", + "io.kubernetes.client.util.authenticators", + "io.kubernetes.client.util.conversion", + "io.kubernetes.client.util.credentials", + "io.kubernetes.client.util.exception", + "io.kubernetes.client.util.generic", + "io.kubernetes.client.util.generic.dynamic", + "io.kubernetes.client.util.generic.options", + "io.kubernetes.client.util.labels", + "io.kubernetes.client.util.okhttp", + "io.kubernetes.client.util.taints", + "io.kubernetes.client.util.version", + "io.kubernetes.client.util.wait" + ], + "io.kubernetes:client-java-api": [ + "io.kubernetes.client.common", + "io.kubernetes.client.custom", + "io.kubernetes.client.gson", + "io.kubernetes.client.openapi", + "io.kubernetes.client.openapi.apis", + "io.kubernetes.client.openapi.auth", + "io.kubernetes.client.openapi.models" + ], + "io.kubernetes:client-java-api-fluent": [ + "io.kubernetes.client.fluent", + "io.kubernetes.client.openapi.models" + ], + "io.kubernetes:client-java-extended": [ + "io.kubernetes.client.extended.controller", + "io.kubernetes.client.extended.controller.builder", + "io.kubernetes.client.extended.controller.reconciler", + "io.kubernetes.client.extended.event", + "io.kubernetes.client.extended.event.legacy", + "io.kubernetes.client.extended.event.v1", + "io.kubernetes.client.extended.kubectl", + "io.kubernetes.client.extended.kubectl.exception", + "io.kubernetes.client.extended.kubectl.util.deployment", + "io.kubernetes.client.extended.leaderelection", + "io.kubernetes.client.extended.leaderelection.resourcelock", + "io.kubernetes.client.extended.network", + "io.kubernetes.client.extended.network.exception", + "io.kubernetes.client.extended.pager", + "io.kubernetes.client.extended.wait", + "io.kubernetes.client.extended.workqueue", + "io.kubernetes.client.extended.workqueue.ratelimiter" + ], + "io.kubernetes:client-java-proto": [ + "io.kubernetes.client.proto" + ], "io.micrometer:context-propagation": [ "io.micrometer.context", "io.micrometer.context.integration" @@ -4489,6 +5553,9 @@ "io.micrometer:micrometer-observation-test": [ "io.micrometer.observation.tck" ], + "io.micrometer:micrometer-registry-prometheus": [ + "io.micrometer.prometheusmetrics" + ], "io.micrometer:micrometer-tracing": [ "io.micrometer.tracing", "io.micrometer.tracing.annotation", @@ -4746,6 +5813,9 @@ "io.opentelemetry.sdk.trace.internal", "io.opentelemetry.sdk.trace.samplers" ], + "io.perfmark:perfmark-api": [ + "io.perfmark" + ], "io.projectreactor.netty:reactor-netty-core": [ "reactor.netty", "reactor.netty.channel", @@ -4794,6 +5864,31 @@ "reactor.test.subscriber", "reactor.test.util" ], + "io.prometheus:prometheus-metrics-config": [ + "io.prometheus.metrics.config" + ], + "io.prometheus:prometheus-metrics-core": [ + "io.prometheus.metrics.core.datapoints", + "io.prometheus.metrics.core.exemplars", + "io.prometheus.metrics.core.metrics", + "io.prometheus.metrics.core.util" + ], + "io.prometheus:prometheus-metrics-exposition-formats": [ + "io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_33_0", + "io.prometheus.metrics.expositionformats.internal", + "io.prometheus.metrics.shaded.com_google_protobuf_4_33_0", + "io.prometheus.metrics.shaded.com_google_protobuf_4_33_0.compiler" + ], + "io.prometheus:prometheus-metrics-exposition-textformats": [ + "io.prometheus.metrics.expositionformats" + ], + "io.prometheus:prometheus-metrics-model": [ + "io.prometheus.metrics.model.registry", + "io.prometheus.metrics.model.snapshots" + ], + "io.prometheus:prometheus-metrics-tracer-common": [ + "io.prometheus.metrics.tracer.common" + ], "io.swagger.core.v3:swagger-annotations-jakarta": [ "io.swagger.v3.oas.annotations", "io.swagger.v3.oas.annotations.callbacks", @@ -4832,6 +5927,9 @@ "io.swagger.v3.oas.models.servers", "io.swagger.v3.oas.models.tags" ], + "io.swagger:swagger-annotations": [ + "io.swagger.annotations" + ], "jakarta.activation:jakarta.activation-api": [ "jakarta.activation", "jakarta.activation.spi" @@ -4866,6 +5964,11 @@ "jakarta.xml.bind.helpers", "jakarta.xml.bind.util" ], + "javax.annotation:javax.annotation-api": [ + "javax.annotation", + "javax.annotation.security", + "javax.annotation.sql" + ], "net.bytebuddy:byte-buddy": [ "net.bytebuddy", "net.bytebuddy.agent.builder", @@ -4911,12 +6014,48 @@ "net.bytebuddy.agent", "net.bytebuddy.agent.utility.nullability" ], + "net.devh:grpc-common-spring-boot": [ + "net.devh.boot.grpc.common.autoconfigure", + "net.devh.boot.grpc.common.codec", + "net.devh.boot.grpc.common.security", + "net.devh.boot.grpc.common.util" + ], + "net.devh:grpc-server-spring-boot-starter": [ + "net.devh.boot.grpc.server.advice", + "net.devh.boot.grpc.server.autoconfigure", + "net.devh.boot.grpc.server.condition", + "net.devh.boot.grpc.server.config", + "net.devh.boot.grpc.server.error", + "net.devh.boot.grpc.server.event", + "net.devh.boot.grpc.server.interceptor", + "net.devh.boot.grpc.server.metrics", + "net.devh.boot.grpc.server.nameresolver", + "net.devh.boot.grpc.server.scope", + "net.devh.boot.grpc.server.security.authentication", + "net.devh.boot.grpc.server.security.check", + "net.devh.boot.grpc.server.security.interceptors", + "net.devh.boot.grpc.server.serverfactory", + "net.devh.boot.grpc.server.service" + ], "net.java.dev.jna:jna": [ "com.sun.jna", "com.sun.jna.internal", "com.sun.jna.ptr", "com.sun.jna.win32" ], + "net.javacrumbs.shedlock:shedlock-core": [ + "net.javacrumbs.shedlock.core", + "net.javacrumbs.shedlock.support", + "net.javacrumbs.shedlock.util" + ], + "net.javacrumbs.shedlock:shedlock-provider-cassandra": [ + "net.javacrumbs.shedlock.provider.cassandra" + ], + "net.javacrumbs.shedlock:shedlock-spring": [ + "net.javacrumbs.shedlock.spring", + "net.javacrumbs.shedlock.spring.annotation", + "net.javacrumbs.shedlock.spring.aop" + ], "net.minidev:accessors-smart": [ "net.minidev.asm", "net.minidev.asm.ex" @@ -5103,6 +6242,28 @@ "com.datastax.oss.driver.internal.querybuilder.truncate", "com.datastax.oss.driver.internal.querybuilder.update" ], + "org.apache.commons:commons-collections4": [ + "org.apache.commons.collections4", + "org.apache.commons.collections4.bag", + "org.apache.commons.collections4.bidimap", + "org.apache.commons.collections4.bloomfilter", + "org.apache.commons.collections4.collection", + "org.apache.commons.collections4.comparators", + "org.apache.commons.collections4.functors", + "org.apache.commons.collections4.iterators", + "org.apache.commons.collections4.keyvalue", + "org.apache.commons.collections4.list", + "org.apache.commons.collections4.map", + "org.apache.commons.collections4.multimap", + "org.apache.commons.collections4.multiset", + "org.apache.commons.collections4.properties", + "org.apache.commons.collections4.queue", + "org.apache.commons.collections4.sequence", + "org.apache.commons.collections4.set", + "org.apache.commons.collections4.splitmap", + "org.apache.commons.collections4.trie", + "org.apache.commons.collections4.trie.analyzer" + ], "org.apache.commons:commons-compress": [ "org.apache.commons.compress", "org.apache.commons.compress.archivers", @@ -5274,6 +6435,45 @@ "org.apiguardian:apiguardian-api": [ "org.apiguardian.api" ], + "org.aspectj:aspectjweaver": [ + "aj.org.objectweb.asm", + "aj.org.objectweb.asm.commons", + "aj.org.objectweb.asm.signature", + "org.aspectj.apache.bcel", + "org.aspectj.apache.bcel.classfile", + "org.aspectj.apache.bcel.classfile.annotation", + "org.aspectj.apache.bcel.generic", + "org.aspectj.apache.bcel.util", + "org.aspectj.asm", + "org.aspectj.asm.internal", + "org.aspectj.bridge", + "org.aspectj.bridge.context", + "org.aspectj.internal.lang.annotation", + "org.aspectj.internal.lang.reflect", + "org.aspectj.lang", + "org.aspectj.lang.annotation", + "org.aspectj.lang.annotation.control", + "org.aspectj.lang.internal.lang", + "org.aspectj.lang.reflect", + "org.aspectj.runtime", + "org.aspectj.runtime.internal", + "org.aspectj.runtime.internal.cflowstack", + "org.aspectj.runtime.reflect", + "org.aspectj.util", + "org.aspectj.weaver", + "org.aspectj.weaver.ast", + "org.aspectj.weaver.bcel", + "org.aspectj.weaver.bcel.asm", + "org.aspectj.weaver.internal.tools", + "org.aspectj.weaver.loadtime", + "org.aspectj.weaver.loadtime.definition", + "org.aspectj.weaver.ltw", + "org.aspectj.weaver.model", + "org.aspectj.weaver.patterns", + "org.aspectj.weaver.reflect", + "org.aspectj.weaver.tools", + "org.aspectj.weaver.tools.cache" + ], "org.assertj:assertj-core": [ "org.assertj.core.annotation", "org.assertj.core.annotations", @@ -5315,6 +6515,82 @@ "org.awaitility.reflect.exception", "org.awaitility.spi" ], + "org.bitbucket.b_c:jose4j": [ + "org.jose4j.base64url", + "org.jose4j.base64url.internal.apache.commons.codec.binary", + "org.jose4j.http", + "org.jose4j.jca", + "org.jose4j.json", + "org.jose4j.json.internal.json_simple", + "org.jose4j.json.internal.json_simple.parser", + "org.jose4j.jwa", + "org.jose4j.jwe", + "org.jose4j.jwe.kdf", + "org.jose4j.jwk", + "org.jose4j.jws", + "org.jose4j.jwt", + "org.jose4j.jwt.consumer", + "org.jose4j.jwx", + "org.jose4j.keys", + "org.jose4j.keys.resolvers", + "org.jose4j.lang", + "org.jose4j.mac", + "org.jose4j.zip" + ], + "org.bouncycastle:bcpkix-jdk18on": [ + "org.bouncycastle.cert", + "org.bouncycastle.cert.bc", + "org.bouncycastle.cert.cmp", + "org.bouncycastle.cert.crmf", + "org.bouncycastle.cert.crmf.bc", + "org.bouncycastle.cert.crmf.jcajce", + "org.bouncycastle.cert.dane", + "org.bouncycastle.cert.dane.fetcher", + "org.bouncycastle.cert.jcajce", + "org.bouncycastle.cert.ocsp", + "org.bouncycastle.cert.ocsp.jcajce", + "org.bouncycastle.cert.path", + "org.bouncycastle.cert.path.validations", + "org.bouncycastle.cert.selector", + "org.bouncycastle.cert.selector.jcajce", + "org.bouncycastle.cmc", + "org.bouncycastle.cms", + "org.bouncycastle.cms.bc", + "org.bouncycastle.cms.jcajce", + "org.bouncycastle.dvcs", + "org.bouncycastle.eac", + "org.bouncycastle.eac.jcajce", + "org.bouncycastle.eac.operator", + "org.bouncycastle.eac.operator.jcajce", + "org.bouncycastle.est", + "org.bouncycastle.est.jcajce", + "org.bouncycastle.its", + "org.bouncycastle.its.bc", + "org.bouncycastle.its.jcajce", + "org.bouncycastle.its.operator", + "org.bouncycastle.mime", + "org.bouncycastle.mime.encoding", + "org.bouncycastle.mime.smime", + "org.bouncycastle.mozilla", + "org.bouncycastle.mozilla.jcajce", + "org.bouncycastle.openssl", + "org.bouncycastle.openssl.bc", + "org.bouncycastle.openssl.jcajce", + "org.bouncycastle.operator", + "org.bouncycastle.operator.bc", + "org.bouncycastle.operator.jcajce", + "org.bouncycastle.pkcs", + "org.bouncycastle.pkcs.bc", + "org.bouncycastle.pkcs.jcajce", + "org.bouncycastle.pkix", + "org.bouncycastle.pkix.jcajce", + "org.bouncycastle.pkix.util", + "org.bouncycastle.pkix.util.filter", + "org.bouncycastle.tsp", + "org.bouncycastle.tsp.cms", + "org.bouncycastle.tsp.ers", + "org.bouncycastle.voms" + ], "org.bouncycastle:bcprov-jdk18on": [ "org.bouncycastle", "org.bouncycastle.asn1", @@ -5657,6 +6933,58 @@ "org.bouncycastle.util.io.pem", "org.bouncycastle.util.test" ], + "org.bouncycastle:bcutil-jdk18on": [ + "org.bouncycastle.asn1.bsi", + "org.bouncycastle.asn1.cmc", + "org.bouncycastle.asn1.cmp", + "org.bouncycastle.asn1.cms", + "org.bouncycastle.asn1.cms.ecc", + "org.bouncycastle.asn1.crmf", + "org.bouncycastle.asn1.cryptlib", + "org.bouncycastle.asn1.dvcs", + "org.bouncycastle.asn1.eac", + "org.bouncycastle.asn1.edec", + "org.bouncycastle.asn1.esf", + "org.bouncycastle.asn1.ess", + "org.bouncycastle.asn1.est", + "org.bouncycastle.asn1.gnu", + "org.bouncycastle.asn1.iana", + "org.bouncycastle.asn1.icao", + "org.bouncycastle.asn1.isara", + "org.bouncycastle.asn1.isismtt", + "org.bouncycastle.asn1.isismtt.ocsp", + "org.bouncycastle.asn1.isismtt.x509", + "org.bouncycastle.asn1.iso", + "org.bouncycastle.asn1.kisa", + "org.bouncycastle.asn1.microsoft", + "org.bouncycastle.asn1.misc", + "org.bouncycastle.asn1.mozilla", + "org.bouncycastle.asn1.nsri", + "org.bouncycastle.asn1.ntt", + "org.bouncycastle.asn1.oiw", + "org.bouncycastle.asn1.rosstandart", + "org.bouncycastle.asn1.smime", + "org.bouncycastle.asn1.tsp", + "org.bouncycastle.oer", + "org.bouncycastle.oer.its", + "org.bouncycastle.oer.its.etsi102941", + "org.bouncycastle.oer.its.etsi102941.basetypes", + "org.bouncycastle.oer.its.etsi103097", + "org.bouncycastle.oer.its.etsi103097.extension", + "org.bouncycastle.oer.its.ieee1609dot2", + "org.bouncycastle.oer.its.ieee1609dot2.basetypes", + "org.bouncycastle.oer.its.ieee1609dot2dot1", + "org.bouncycastle.oer.its.template.etsi102941", + "org.bouncycastle.oer.its.template.etsi102941.basetypes", + "org.bouncycastle.oer.its.template.etsi103097", + "org.bouncycastle.oer.its.template.etsi103097.extension", + "org.bouncycastle.oer.its.template.ieee1609dot2", + "org.bouncycastle.oer.its.template.ieee1609dot2.basetypes", + "org.bouncycastle.oer.its.template.ieee1609dot2dot1" + ], + "org.codehaus.mojo:animal-sniffer-annotations": [ + "org.codehaus.mojo.animal_sniffer" + ], "org.hamcrest:hamcrest": [ "org.hamcrest", "org.hamcrest.beans", @@ -6440,6 +7768,19 @@ "org.springframework.boot.jackson", "org.springframework.boot.jackson.autoconfigure" ], + "org.springframework.boot:spring-boot-loader": [ + "org.springframework.boot.loader.jar", + "org.springframework.boot.loader.jarmode", + "org.springframework.boot.loader.launch", + "org.springframework.boot.loader.log", + "org.springframework.boot.loader.net.protocol", + "org.springframework.boot.loader.net.protocol.jar", + "org.springframework.boot.loader.net.protocol.nested", + "org.springframework.boot.loader.net.util", + "org.springframework.boot.loader.nio.file", + "org.springframework.boot.loader.ref", + "org.springframework.boot.loader.zip" + ], "org.springframework.boot:spring-boot-micrometer-metrics": [ "org.springframework.boot.micrometer.metrics", "org.springframework.boot.micrometer.metrics.actuate.endpoint", @@ -6698,6 +8039,28 @@ "org.springframework.cloud.util", "org.springframework.cloud.util.random" ], + "org.springframework.cloud:spring-cloud-kubernetes-client-autoconfig": [ + "org.springframework.cloud.kubernetes.client" + ], + "org.springframework.cloud:spring-cloud-kubernetes-client-config": [ + "org.springframework.cloud.kubernetes.client.config", + "org.springframework.cloud.kubernetes.client.config.reload" + ], + "org.springframework.cloud:spring-cloud-kubernetes-commons": [ + "org.springframework.cloud.kubernetes.commons", + "org.springframework.cloud.kubernetes.commons.autoconfig", + "org.springframework.cloud.kubernetes.commons.config", + "org.springframework.cloud.kubernetes.commons.config.reload", + "org.springframework.cloud.kubernetes.commons.config.reload.condition", + "org.springframework.cloud.kubernetes.commons.configdata", + "org.springframework.cloud.kubernetes.commons.discovery", + "org.springframework.cloud.kubernetes.commons.discovery.conditionals", + "org.springframework.cloud.kubernetes.commons.leader", + "org.springframework.cloud.kubernetes.commons.leader.election", + "org.springframework.cloud.kubernetes.commons.leader.election.events", + "org.springframework.cloud.kubernetes.commons.loadbalancer", + "org.springframework.cloud.kubernetes.commons.profile" + ], "org.springframework.cloud:spring-cloud-starter-bootstrap": [ "org.springframework.cloud.bootstrap.marker" ], @@ -6777,6 +8140,20 @@ "org.springframework.data.web.config", "org.springframework.data.web.querydsl" ], + "org.springframework.retry:spring-retry": [ + "org.springframework.classify", + "org.springframework.classify.annotation", + "org.springframework.classify.util", + "org.springframework.retry", + "org.springframework.retry.annotation", + "org.springframework.retry.backoff", + "org.springframework.retry.context", + "org.springframework.retry.interceptor", + "org.springframework.retry.listener", + "org.springframework.retry.policy", + "org.springframework.retry.stats", + "org.springframework.retry.support" + ], "org.springframework.security:spring-security-config": [ "org.springframework.security.config", "org.springframework.security.config.annotation", @@ -7108,6 +8485,17 @@ "org.springframework.validation.method", "org.springframework.validation.support" ], + "org.springframework:spring-context-support": [ + "org.springframework.cache.caffeine", + "org.springframework.cache.jcache", + "org.springframework.cache.jcache.config", + "org.springframework.cache.jcache.interceptor", + "org.springframework.cache.transaction", + "org.springframework.mail", + "org.springframework.mail.javamail", + "org.springframework.scheduling.quartz", + "org.springframework.ui.freemarker" + ], "org.springframework:spring-core": [ "org.springframework.aot", "org.springframework.aot.generate", @@ -7830,6 +9218,10 @@ "org.testcontainers:testcontainers-junit-jupiter": [ "org.testcontainers.junit.jupiter" ], + "org.testcontainers:testcontainers-localstack": [ + "org.testcontainers.containers.localstack", + "org.testcontainers.localstack" + ], "org.wiremock:wiremock-standalone": [ "com.github.tomakehurst.wiremock", "com.github.tomakehurst.wiremock.admin", @@ -8507,6 +9899,10 @@ "ch.qos.logback:logback-classic:jar:sources", "ch.qos.logback:logback-core", "ch.qos.logback:logback-core:jar:sources", + "com.bucket4j:bucket4j-core", + "com.bucket4j:bucket4j-core:jar:sources", + "com.bucket4j:bucket4j_jdk17-core", + "com.bucket4j:bucket4j_jdk17-core:jar:sources", "com.datastax.cassandra:cassandra-driver-core", "com.datastax.cassandra:cassandra-driver-core:jar:sources", "com.datastax.oss:native-protocol", @@ -8554,7 +9950,14 @@ "com.github.jnr:jnr-x86asm:jar:sources", "com.github.stephenc.jcip:jcip-annotations", "com.github.stephenc.jcip:jcip-annotations:jar:sources", + "com.google.android:annotations", + "com.google.android:annotations:jar:sources", + "com.google.api.grpc:proto-google-common-protos", + "com.google.api.grpc:proto-google-common-protos:jar:sources", "com.google.code.findbugs:jsr305", + "com.google.code.findbugs:jsr305:jar:sources", + "com.google.code.gson:gson", + "com.google.code.gson:gson:jar:sources", "com.google.errorprone:error_prone_annotations", "com.google.errorprone:error_prone_annotations:jar:sources", "com.google.guava:failureaccess", @@ -8564,6 +9967,10 @@ "com.google.guava:listenablefuture", "com.google.j2objc:j2objc-annotations", "com.google.j2objc:j2objc-annotations:jar:sources", + "com.google.protobuf:protobuf-java", + "com.google.protobuf:protobuf-java-util", + "com.google.protobuf:protobuf-java-util:jar:sources", + "com.google.protobuf:protobuf-java:jar:sources", "com.jayway.jsonpath:json-path", "com.jayway.jsonpath:json-path:jar:sources", "com.nimbusds:content-type", @@ -8574,10 +9981,16 @@ "com.nimbusds:nimbus-jose-jwt:jar:sources", "com.nimbusds:oauth2-oidc-sdk", "com.nimbusds:oauth2-oidc-sdk:jar:sources", + "com.squareup.okhttp3:logging-interceptor", + "com.squareup.okhttp3:logging-interceptor:jar:sources", + "com.squareup.okhttp3:okhttp", "com.squareup.okhttp3:okhttp-jvm", "com.squareup.okhttp3:okhttp-jvm:jar:sources", + "com.squareup.okhttp3:okhttp:jar:sources", + "com.squareup.okio:okio", "com.squareup.okio:okio-jvm", "com.squareup.okio:okio-jvm:jar:sources", + "com.squareup.okio:okio:jar:sources", "com.typesafe:config", "com.typesafe:config:jar:sources", "com.vaadin.external.google:android-json", @@ -8596,6 +10009,38 @@ "io.cloudevents:cloudevents-json-jackson:jar:sources", "io.dropwizard.metrics:metrics-core", "io.dropwizard.metrics:metrics-core:jar:sources", + "io.grpc:grpc-api", + "io.grpc:grpc-api:jar:sources", + "io.grpc:grpc-context", + "io.grpc:grpc-context:jar:sources", + "io.grpc:grpc-core", + "io.grpc:grpc-core:jar:sources", + "io.grpc:grpc-inprocess", + "io.grpc:grpc-inprocess:jar:sources", + "io.grpc:grpc-netty-shaded", + "io.grpc:grpc-netty-shaded:jar:sources", + "io.grpc:grpc-protobuf", + "io.grpc:grpc-protobuf-lite", + "io.grpc:grpc-protobuf-lite:jar:sources", + "io.grpc:grpc-protobuf:jar:sources", + "io.grpc:grpc-services", + "io.grpc:grpc-services:jar:sources", + "io.grpc:grpc-stub", + "io.grpc:grpc-stub:jar:sources", + "io.grpc:grpc-util", + "io.grpc:grpc-util:jar:sources", + "io.gsonfire:gson-fire", + "io.gsonfire:gson-fire:jar:sources", + "io.kubernetes:client-java", + "io.kubernetes:client-java-api", + "io.kubernetes:client-java-api-fluent", + "io.kubernetes:client-java-api-fluent:jar:sources", + "io.kubernetes:client-java-api:jar:sources", + "io.kubernetes:client-java-extended", + "io.kubernetes:client-java-extended:jar:sources", + "io.kubernetes:client-java-proto", + "io.kubernetes:client-java-proto:jar:sources", + "io.kubernetes:client-java:jar:sources", "io.micrometer:context-propagation", "io.micrometer:context-propagation:jar:sources", "io.micrometer:micrometer-commons", @@ -8608,6 +10053,8 @@ "io.micrometer:micrometer-observation-test", "io.micrometer:micrometer-observation-test:jar:sources", "io.micrometer:micrometer-observation:jar:sources", + "io.micrometer:micrometer-registry-prometheus", + "io.micrometer:micrometer-registry-prometheus:jar:sources", "io.micrometer:micrometer-tracing", "io.micrometer:micrometer-tracing-bridge-otel", "io.micrometer:micrometer-tracing-bridge-otel:jar:sources", @@ -8692,6 +10139,8 @@ "io.opentelemetry:opentelemetry-sdk-trace", "io.opentelemetry:opentelemetry-sdk-trace:jar:sources", "io.opentelemetry:opentelemetry-sdk:jar:sources", + "io.perfmark:perfmark-api", + "io.perfmark:perfmark-api:jar:sources", "io.projectreactor.netty:reactor-netty-core", "io.projectreactor.netty:reactor-netty-core:jar:sources", "io.projectreactor.netty:reactor-netty-http", @@ -8700,12 +10149,26 @@ "io.projectreactor:reactor-core:jar:sources", "io.projectreactor:reactor-test", "io.projectreactor:reactor-test:jar:sources", + "io.prometheus:prometheus-metrics-config", + "io.prometheus:prometheus-metrics-config:jar:sources", + "io.prometheus:prometheus-metrics-core", + "io.prometheus:prometheus-metrics-core:jar:sources", + "io.prometheus:prometheus-metrics-exposition-formats", + "io.prometheus:prometheus-metrics-exposition-formats:jar:sources", + "io.prometheus:prometheus-metrics-exposition-textformats", + "io.prometheus:prometheus-metrics-exposition-textformats:jar:sources", + "io.prometheus:prometheus-metrics-model", + "io.prometheus:prometheus-metrics-model:jar:sources", + "io.prometheus:prometheus-metrics-tracer-common", + "io.prometheus:prometheus-metrics-tracer-common:jar:sources", "io.swagger.core.v3:swagger-annotations-jakarta", "io.swagger.core.v3:swagger-annotations-jakarta:jar:sources", "io.swagger.core.v3:swagger-core-jakarta", "io.swagger.core.v3:swagger-core-jakarta:jar:sources", "io.swagger.core.v3:swagger-models-jakarta", "io.swagger.core.v3:swagger-models-jakarta:jar:sources", + "io.swagger:swagger-annotations", + "io.swagger:swagger-annotations:jar:sources", "jakarta.activation:jakarta.activation-api", "jakarta.activation:jakarta.activation-api:jar:sources", "jakarta.annotation:jakarta.annotation-api", @@ -8716,12 +10179,24 @@ "jakarta.validation:jakarta.validation-api:jar:sources", "jakarta.xml.bind:jakarta.xml.bind-api", "jakarta.xml.bind:jakarta.xml.bind-api:jar:sources", + "javax.annotation:javax.annotation-api", + "javax.annotation:javax.annotation-api:jar:sources", "net.bytebuddy:byte-buddy", "net.bytebuddy:byte-buddy-agent", "net.bytebuddy:byte-buddy-agent:jar:sources", "net.bytebuddy:byte-buddy:jar:sources", + "net.devh:grpc-common-spring-boot", + "net.devh:grpc-common-spring-boot:jar:sources", + "net.devh:grpc-server-spring-boot-starter", + "net.devh:grpc-server-spring-boot-starter:jar:sources", "net.java.dev.jna:jna", "net.java.dev.jna:jna:jar:sources", + "net.javacrumbs.shedlock:shedlock-core", + "net.javacrumbs.shedlock:shedlock-core:jar:sources", + "net.javacrumbs.shedlock:shedlock-provider-cassandra", + "net.javacrumbs.shedlock:shedlock-provider-cassandra:jar:sources", + "net.javacrumbs.shedlock:shedlock-spring", + "net.javacrumbs.shedlock:shedlock-spring:jar:sources", "net.minidev:accessors-smart", "net.minidev:accessors-smart:jar:sources", "net.minidev:json-smart", @@ -8734,6 +10209,8 @@ "org.apache.cassandra:java-driver-metrics-micrometer:jar:sources", "org.apache.cassandra:java-driver-query-builder", "org.apache.cassandra:java-driver-query-builder:jar:sources", + "org.apache.commons:commons-collections4", + "org.apache.commons:commons-collections4:jar:sources", "org.apache.commons:commons-compress", "org.apache.commons:commons-compress:jar:sources", "org.apache.commons:commons-lang3", @@ -8750,14 +10227,24 @@ "org.apache.tomcat.embed:tomcat-embed-websocket:jar:sources", "org.apiguardian:apiguardian-api", "org.apiguardian:apiguardian-api:jar:sources", + "org.aspectj:aspectjweaver", + "org.aspectj:aspectjweaver:jar:sources", "org.assertj:assertj-core", "org.assertj:assertj-core:jar:sources", "org.awaitility:awaitility", "org.awaitility:awaitility:jar:sources", + "org.bitbucket.b_c:jose4j", + "org.bitbucket.b_c:jose4j:jar:sources", + "org.bouncycastle:bcpkix-jdk18on", + "org.bouncycastle:bcpkix-jdk18on:jar:sources", "org.bouncycastle:bcprov-jdk18on", "org.bouncycastle:bcprov-jdk18on:jar:sources", "org.bouncycastle:bcprov-lts8on", "org.bouncycastle:bcprov-lts8on:jar:sources", + "org.bouncycastle:bcutil-jdk18on", + "org.bouncycastle:bcutil-jdk18on:jar:sources", + "org.codehaus.mojo:animal-sniffer-annotations", + "org.codehaus.mojo:animal-sniffer-annotations:jar:sources", "org.hamcrest:hamcrest", "org.hamcrest:hamcrest:jar:sources", "org.hdrhistogram:HdrHistogram", @@ -8775,6 +10262,10 @@ "org.jboss.logging:jboss-logging", "org.jboss.logging:jboss-logging:jar:sources", "org.jetbrains.kotlin:kotlin-stdlib", + "org.jetbrains.kotlin:kotlin-stdlib-jdk7", + "org.jetbrains.kotlin:kotlin-stdlib-jdk7:jar:sources", + "org.jetbrains.kotlin:kotlin-stdlib-jdk8", + "org.jetbrains.kotlin:kotlin-stdlib-jdk8:jar:sources", "org.jetbrains.kotlin:kotlin-stdlib:jar:sources", "org.jetbrains:annotations", "org.jetbrains:annotations:jar:sources", @@ -8863,6 +10354,8 @@ "org.springframework.boot:spring-boot-http-converter:jar:sources", "org.springframework.boot:spring-boot-jackson", "org.springframework.boot:spring-boot-jackson:jar:sources", + "org.springframework.boot:spring-boot-loader", + "org.springframework.boot:spring-boot-loader:jar:sources", "org.springframework.boot:spring-boot-micrometer-metrics", "org.springframework.boot:spring-boot-micrometer-metrics-test", "org.springframework.boot:spring-boot-micrometer-metrics-test:jar:sources", @@ -8902,6 +10395,8 @@ "org.springframework.boot:spring-boot-starter-actuator-test", "org.springframework.boot:spring-boot-starter-actuator-test:jar:sources", "org.springframework.boot:spring-boot-starter-actuator:jar:sources", + "org.springframework.boot:spring-boot-starter-aspectj", + "org.springframework.boot:spring-boot-starter-aspectj:jar:sources", "org.springframework.boot:spring-boot-starter-data-cassandra", "org.springframework.boot:spring-boot-starter-data-cassandra-test", "org.springframework.boot:spring-boot-starter-data-cassandra-test:jar:sources", @@ -8974,13 +10469,22 @@ "org.springframework.cloud:spring-cloud-commons:jar:sources", "org.springframework.cloud:spring-cloud-context", "org.springframework.cloud:spring-cloud-context:jar:sources", + "org.springframework.cloud:spring-cloud-kubernetes-client-autoconfig", + "org.springframework.cloud:spring-cloud-kubernetes-client-autoconfig:jar:sources", + "org.springframework.cloud:spring-cloud-kubernetes-client-config", + "org.springframework.cloud:spring-cloud-kubernetes-client-config:jar:sources", + "org.springframework.cloud:spring-cloud-kubernetes-commons", + "org.springframework.cloud:spring-cloud-kubernetes-commons:jar:sources", "org.springframework.cloud:spring-cloud-starter", "org.springframework.cloud:spring-cloud-starter-bootstrap", "org.springframework.cloud:spring-cloud-starter-bootstrap:jar:sources", + "org.springframework.cloud:spring-cloud-starter-kubernetes-client-config", "org.springframework.data:spring-data-cassandra", "org.springframework.data:spring-data-cassandra:jar:sources", "org.springframework.data:spring-data-commons", "org.springframework.data:spring-data-commons:jar:sources", + "org.springframework.retry:spring-retry", + "org.springframework.retry:spring-retry:jar:sources", "org.springframework.security:spring-security-config", "org.springframework.security:spring-security-config:jar:sources", "org.springframework.security:spring-security-core", @@ -9004,6 +10508,8 @@ "org.springframework:spring-beans", "org.springframework:spring-beans:jar:sources", "org.springframework:spring-context", + "org.springframework:spring-context-support", + "org.springframework:spring-context-support:jar:sources", "org.springframework:spring-context:jar:sources", "org.springframework:spring-core", "org.springframework:spring-core:jar:sources", @@ -9026,6 +10532,8 @@ "org.testcontainers:testcontainers-database-commons:jar:sources", "org.testcontainers:testcontainers-junit-jupiter", "org.testcontainers:testcontainers-junit-jupiter:jar:sources", + "org.testcontainers:testcontainers-localstack", + "org.testcontainers:testcontainers-localstack:jar:sources", "org.testcontainers:testcontainers:jar:sources", "org.wiremock:wiremock-standalone", "org.wiremock:wiremock-standalone:jar:sources", @@ -9085,6 +10593,10 @@ "ch.qos.logback:logback-classic:jar:sources", "ch.qos.logback:logback-core", "ch.qos.logback:logback-core:jar:sources", + "com.bucket4j:bucket4j-core", + "com.bucket4j:bucket4j-core:jar:sources", + "com.bucket4j:bucket4j_jdk17-core", + "com.bucket4j:bucket4j_jdk17-core:jar:sources", "com.datastax.cassandra:cassandra-driver-core", "com.datastax.cassandra:cassandra-driver-core:jar:sources", "com.datastax.oss:native-protocol", @@ -9132,7 +10644,14 @@ "com.github.jnr:jnr-x86asm:jar:sources", "com.github.stephenc.jcip:jcip-annotations", "com.github.stephenc.jcip:jcip-annotations:jar:sources", + "com.google.android:annotations", + "com.google.android:annotations:jar:sources", + "com.google.api.grpc:proto-google-common-protos", + "com.google.api.grpc:proto-google-common-protos:jar:sources", "com.google.code.findbugs:jsr305", + "com.google.code.findbugs:jsr305:jar:sources", + "com.google.code.gson:gson", + "com.google.code.gson:gson:jar:sources", "com.google.errorprone:error_prone_annotations", "com.google.errorprone:error_prone_annotations:jar:sources", "com.google.guava:failureaccess", @@ -9142,6 +10661,10 @@ "com.google.guava:listenablefuture", "com.google.j2objc:j2objc-annotations", "com.google.j2objc:j2objc-annotations:jar:sources", + "com.google.protobuf:protobuf-java", + "com.google.protobuf:protobuf-java-util", + "com.google.protobuf:protobuf-java-util:jar:sources", + "com.google.protobuf:protobuf-java:jar:sources", "com.jayway.jsonpath:json-path", "com.jayway.jsonpath:json-path:jar:sources", "com.nimbusds:content-type", @@ -9152,10 +10675,16 @@ "com.nimbusds:nimbus-jose-jwt:jar:sources", "com.nimbusds:oauth2-oidc-sdk", "com.nimbusds:oauth2-oidc-sdk:jar:sources", + "com.squareup.okhttp3:logging-interceptor", + "com.squareup.okhttp3:logging-interceptor:jar:sources", + "com.squareup.okhttp3:okhttp", "com.squareup.okhttp3:okhttp-jvm", "com.squareup.okhttp3:okhttp-jvm:jar:sources", + "com.squareup.okhttp3:okhttp:jar:sources", + "com.squareup.okio:okio", "com.squareup.okio:okio-jvm", "com.squareup.okio:okio-jvm:jar:sources", + "com.squareup.okio:okio:jar:sources", "com.typesafe:config", "com.typesafe:config:jar:sources", "com.vaadin.external.google:android-json", @@ -9174,6 +10703,38 @@ "io.cloudevents:cloudevents-json-jackson:jar:sources", "io.dropwizard.metrics:metrics-core", "io.dropwizard.metrics:metrics-core:jar:sources", + "io.grpc:grpc-api", + "io.grpc:grpc-api:jar:sources", + "io.grpc:grpc-context", + "io.grpc:grpc-context:jar:sources", + "io.grpc:grpc-core", + "io.grpc:grpc-core:jar:sources", + "io.grpc:grpc-inprocess", + "io.grpc:grpc-inprocess:jar:sources", + "io.grpc:grpc-netty-shaded", + "io.grpc:grpc-netty-shaded:jar:sources", + "io.grpc:grpc-protobuf", + "io.grpc:grpc-protobuf-lite", + "io.grpc:grpc-protobuf-lite:jar:sources", + "io.grpc:grpc-protobuf:jar:sources", + "io.grpc:grpc-services", + "io.grpc:grpc-services:jar:sources", + "io.grpc:grpc-stub", + "io.grpc:grpc-stub:jar:sources", + "io.grpc:grpc-util", + "io.grpc:grpc-util:jar:sources", + "io.gsonfire:gson-fire", + "io.gsonfire:gson-fire:jar:sources", + "io.kubernetes:client-java", + "io.kubernetes:client-java-api", + "io.kubernetes:client-java-api-fluent", + "io.kubernetes:client-java-api-fluent:jar:sources", + "io.kubernetes:client-java-api:jar:sources", + "io.kubernetes:client-java-extended", + "io.kubernetes:client-java-extended:jar:sources", + "io.kubernetes:client-java-proto", + "io.kubernetes:client-java-proto:jar:sources", + "io.kubernetes:client-java:jar:sources", "io.micrometer:context-propagation", "io.micrometer:context-propagation:jar:sources", "io.micrometer:micrometer-commons", @@ -9186,6 +10747,8 @@ "io.micrometer:micrometer-observation-test", "io.micrometer:micrometer-observation-test:jar:sources", "io.micrometer:micrometer-observation:jar:sources", + "io.micrometer:micrometer-registry-prometheus", + "io.micrometer:micrometer-registry-prometheus:jar:sources", "io.micrometer:micrometer-tracing", "io.micrometer:micrometer-tracing-bridge-otel", "io.micrometer:micrometer-tracing-bridge-otel:jar:sources", @@ -9270,6 +10833,8 @@ "io.opentelemetry:opentelemetry-sdk-trace", "io.opentelemetry:opentelemetry-sdk-trace:jar:sources", "io.opentelemetry:opentelemetry-sdk:jar:sources", + "io.perfmark:perfmark-api", + "io.perfmark:perfmark-api:jar:sources", "io.projectreactor.netty:reactor-netty-core", "io.projectreactor.netty:reactor-netty-core:jar:sources", "io.projectreactor.netty:reactor-netty-http", @@ -9278,12 +10843,26 @@ "io.projectreactor:reactor-core:jar:sources", "io.projectreactor:reactor-test", "io.projectreactor:reactor-test:jar:sources", + "io.prometheus:prometheus-metrics-config", + "io.prometheus:prometheus-metrics-config:jar:sources", + "io.prometheus:prometheus-metrics-core", + "io.prometheus:prometheus-metrics-core:jar:sources", + "io.prometheus:prometheus-metrics-exposition-formats", + "io.prometheus:prometheus-metrics-exposition-formats:jar:sources", + "io.prometheus:prometheus-metrics-exposition-textformats", + "io.prometheus:prometheus-metrics-exposition-textformats:jar:sources", + "io.prometheus:prometheus-metrics-model", + "io.prometheus:prometheus-metrics-model:jar:sources", + "io.prometheus:prometheus-metrics-tracer-common", + "io.prometheus:prometheus-metrics-tracer-common:jar:sources", "io.swagger.core.v3:swagger-annotations-jakarta", "io.swagger.core.v3:swagger-annotations-jakarta:jar:sources", "io.swagger.core.v3:swagger-core-jakarta", "io.swagger.core.v3:swagger-core-jakarta:jar:sources", "io.swagger.core.v3:swagger-models-jakarta", "io.swagger.core.v3:swagger-models-jakarta:jar:sources", + "io.swagger:swagger-annotations", + "io.swagger:swagger-annotations:jar:sources", "jakarta.activation:jakarta.activation-api", "jakarta.activation:jakarta.activation-api:jar:sources", "jakarta.annotation:jakarta.annotation-api", @@ -9294,12 +10873,24 @@ "jakarta.validation:jakarta.validation-api:jar:sources", "jakarta.xml.bind:jakarta.xml.bind-api", "jakarta.xml.bind:jakarta.xml.bind-api:jar:sources", + "javax.annotation:javax.annotation-api", + "javax.annotation:javax.annotation-api:jar:sources", "net.bytebuddy:byte-buddy", "net.bytebuddy:byte-buddy-agent", "net.bytebuddy:byte-buddy-agent:jar:sources", "net.bytebuddy:byte-buddy:jar:sources", + "net.devh:grpc-common-spring-boot", + "net.devh:grpc-common-spring-boot:jar:sources", + "net.devh:grpc-server-spring-boot-starter", + "net.devh:grpc-server-spring-boot-starter:jar:sources", "net.java.dev.jna:jna", "net.java.dev.jna:jna:jar:sources", + "net.javacrumbs.shedlock:shedlock-core", + "net.javacrumbs.shedlock:shedlock-core:jar:sources", + "net.javacrumbs.shedlock:shedlock-provider-cassandra", + "net.javacrumbs.shedlock:shedlock-provider-cassandra:jar:sources", + "net.javacrumbs.shedlock:shedlock-spring", + "net.javacrumbs.shedlock:shedlock-spring:jar:sources", "net.minidev:accessors-smart", "net.minidev:accessors-smart:jar:sources", "net.minidev:json-smart", @@ -9312,6 +10903,8 @@ "org.apache.cassandra:java-driver-metrics-micrometer:jar:sources", "org.apache.cassandra:java-driver-query-builder", "org.apache.cassandra:java-driver-query-builder:jar:sources", + "org.apache.commons:commons-collections4", + "org.apache.commons:commons-collections4:jar:sources", "org.apache.commons:commons-compress", "org.apache.commons:commons-compress:jar:sources", "org.apache.commons:commons-lang3", @@ -9328,14 +10921,24 @@ "org.apache.tomcat.embed:tomcat-embed-websocket:jar:sources", "org.apiguardian:apiguardian-api", "org.apiguardian:apiguardian-api:jar:sources", + "org.aspectj:aspectjweaver", + "org.aspectj:aspectjweaver:jar:sources", "org.assertj:assertj-core", "org.assertj:assertj-core:jar:sources", "org.awaitility:awaitility", "org.awaitility:awaitility:jar:sources", + "org.bitbucket.b_c:jose4j", + "org.bitbucket.b_c:jose4j:jar:sources", + "org.bouncycastle:bcpkix-jdk18on", + "org.bouncycastle:bcpkix-jdk18on:jar:sources", "org.bouncycastle:bcprov-jdk18on", "org.bouncycastle:bcprov-jdk18on:jar:sources", "org.bouncycastle:bcprov-lts8on", "org.bouncycastle:bcprov-lts8on:jar:sources", + "org.bouncycastle:bcutil-jdk18on", + "org.bouncycastle:bcutil-jdk18on:jar:sources", + "org.codehaus.mojo:animal-sniffer-annotations", + "org.codehaus.mojo:animal-sniffer-annotations:jar:sources", "org.hamcrest:hamcrest", "org.hamcrest:hamcrest:jar:sources", "org.hdrhistogram:HdrHistogram", @@ -9353,6 +10956,10 @@ "org.jboss.logging:jboss-logging", "org.jboss.logging:jboss-logging:jar:sources", "org.jetbrains.kotlin:kotlin-stdlib", + "org.jetbrains.kotlin:kotlin-stdlib-jdk7", + "org.jetbrains.kotlin:kotlin-stdlib-jdk7:jar:sources", + "org.jetbrains.kotlin:kotlin-stdlib-jdk8", + "org.jetbrains.kotlin:kotlin-stdlib-jdk8:jar:sources", "org.jetbrains.kotlin:kotlin-stdlib:jar:sources", "org.jetbrains:annotations", "org.jetbrains:annotations:jar:sources", @@ -9441,6 +11048,8 @@ "org.springframework.boot:spring-boot-http-converter:jar:sources", "org.springframework.boot:spring-boot-jackson", "org.springframework.boot:spring-boot-jackson:jar:sources", + "org.springframework.boot:spring-boot-loader", + "org.springframework.boot:spring-boot-loader:jar:sources", "org.springframework.boot:spring-boot-micrometer-metrics", "org.springframework.boot:spring-boot-micrometer-metrics-test", "org.springframework.boot:spring-boot-micrometer-metrics-test:jar:sources", @@ -9480,6 +11089,8 @@ "org.springframework.boot:spring-boot-starter-actuator-test", "org.springframework.boot:spring-boot-starter-actuator-test:jar:sources", "org.springframework.boot:spring-boot-starter-actuator:jar:sources", + "org.springframework.boot:spring-boot-starter-aspectj", + "org.springframework.boot:spring-boot-starter-aspectj:jar:sources", "org.springframework.boot:spring-boot-starter-data-cassandra", "org.springframework.boot:spring-boot-starter-data-cassandra-test", "org.springframework.boot:spring-boot-starter-data-cassandra-test:jar:sources", @@ -9552,13 +11163,22 @@ "org.springframework.cloud:spring-cloud-commons:jar:sources", "org.springframework.cloud:spring-cloud-context", "org.springframework.cloud:spring-cloud-context:jar:sources", + "org.springframework.cloud:spring-cloud-kubernetes-client-autoconfig", + "org.springframework.cloud:spring-cloud-kubernetes-client-autoconfig:jar:sources", + "org.springframework.cloud:spring-cloud-kubernetes-client-config", + "org.springframework.cloud:spring-cloud-kubernetes-client-config:jar:sources", + "org.springframework.cloud:spring-cloud-kubernetes-commons", + "org.springframework.cloud:spring-cloud-kubernetes-commons:jar:sources", "org.springframework.cloud:spring-cloud-starter", "org.springframework.cloud:spring-cloud-starter-bootstrap", "org.springframework.cloud:spring-cloud-starter-bootstrap:jar:sources", + "org.springframework.cloud:spring-cloud-starter-kubernetes-client-config", "org.springframework.data:spring-data-cassandra", "org.springframework.data:spring-data-cassandra:jar:sources", "org.springframework.data:spring-data-commons", "org.springframework.data:spring-data-commons:jar:sources", + "org.springframework.retry:spring-retry", + "org.springframework.retry:spring-retry:jar:sources", "org.springframework.security:spring-security-config", "org.springframework.security:spring-security-config:jar:sources", "org.springframework.security:spring-security-core", @@ -9582,6 +11202,8 @@ "org.springframework:spring-beans", "org.springframework:spring-beans:jar:sources", "org.springframework:spring-context", + "org.springframework:spring-context-support", + "org.springframework:spring-context-support:jar:sources", "org.springframework:spring-context:jar:sources", "org.springframework:spring-core", "org.springframework:spring-core:jar:sources", @@ -9604,6 +11226,8 @@ "org.testcontainers:testcontainers-database-commons:jar:sources", "org.testcontainers:testcontainers-junit-jupiter", "org.testcontainers:testcontainers-junit-jupiter:jar:sources", + "org.testcontainers:testcontainers-localstack", + "org.testcontainers:testcontainers-localstack:jar:sources", "org.testcontainers:testcontainers:jar:sources", "org.wiremock:wiremock-standalone", "org.wiremock:wiremock-standalone:jar:sources", @@ -9690,6 +11314,40 @@ "io.cloudevents.jackson.JsonFormat" ] }, + "io.grpc:grpc-core": { + "io.grpc.LoadBalancerProvider": [ + "io.grpc.internal.PickFirstLoadBalancerProvider" + ], + "io.grpc.NameResolverProvider": [ + "io.grpc.internal.DnsNameResolverProvider" + ] + }, + "io.grpc:grpc-netty-shaded": { + "io.grpc.ManagedChannelProvider": [ + "io.grpc.netty.shaded.io.grpc.netty.NettyChannelProvider", + "io.grpc.netty.shaded.io.grpc.netty.UdsNettyChannelProvider" + ], + "io.grpc.NameResolverProvider": [ + "io.grpc.netty.shaded.io.grpc.netty.UdsNameResolverProvider" + ], + "io.grpc.ServerProvider": [ + "io.grpc.netty.shaded.io.grpc.netty.NettyServerProvider" + ], + "reactor.blockhound.integration.BlockHoundIntegration": [ + "io.grpc.netty.shaded.io.netty.util.internal.Hidden$NettyBlockHoundIntegration" + ] + }, + "io.grpc:grpc-services": { + "io.grpc.LoadBalancerProvider": [ + "io.grpc.protobuf.services.internal.HealthCheckingRoundRobinLoadBalancerProvider" + ] + }, + "io.grpc:grpc-util": { + "io.grpc.LoadBalancerProvider": [ + "io.grpc.util.OutlierDetectionLoadBalancerProvider", + "io.grpc.util.SecretRoundRobinLoadBalancerProvider$Provider" + ] + }, "io.micrometer:micrometer-observation": { "io.micrometer.context.ThreadLocalAccessor": [ "io.micrometer.observation.contextpropagation.ObservationThreadLocalAccessor" @@ -10031,6 +11689,11 @@ "org.springframework.boot.logging.log4j2.SpringBootPropertySource" ] }, + "org.springframework.boot:spring-boot-loader": { + "java.nio.file.spi.FileSystemProvider": [ + "org.springframework.boot.loader.nio.file.NestedFileSystemProvider" + ] + }, "org.springframework.boot:spring-boot-micrometer-tracing-opentelemetry": { "org.junit.platform.launcher.TestExecutionListener": [ "org.springframework.boot.micrometer.tracing.opentelemetry.autoconfigure.OpenTelemetryEventPublisherBeansTestExecutionListener" From 6ab9b1239bcaa63a13fe0ffd2064860687cb9a11 Mon Sep 17 00:00:00 2001 From: Balaji Ganesan Date: Tue, 21 Jul 2026 22:09:27 -0700 Subject: [PATCH 02/29] build(bazel): regenerate nv-boot NOTICE after the cloud-tasks re-pin Adding cloud-tasks's grpc-java closure to the shared nv_third_party_deps hub pulled com.google.code.findbugs:jsr305 up from 2.0.1 to 3.0.2, which is a transitive dependency inside nv-boot-parent's own NOTICE closure. Regenerated nv-boot-parent/NOTICE (generate_notice.py --update-metadata --write) so notice_check_test matches the re-pinned lock. One version-string line changed. Co-authored-by: Balaji Ganesan Co-Authored-By: Claude Opus 4.8 --- src/libraries/java/nv-boot-parent/NOTICE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/java/nv-boot-parent/NOTICE b/src/libraries/java/nv-boot-parent/NOTICE index ca15f90d3..400531af2 100644 --- a/src/libraries/java/nv-boot-parent/NOTICE +++ b/src/libraries/java/nv-boot-parent/NOTICE @@ -23,7 +23,7 @@ Lists of 208 third-party dependencies. (Eclipse Public License - v 2.0) (GNU General Public License Version 2) (GNU Lesser General Public License Version 2.1) jnr-posix (com.github.jnr:jnr-posix:3.1.15 - http://nexus.sonatype.org/oss-repository-hosting.html) (MIT License) jnr-x86asm (com.github.jnr:jnr-x86asm:1.0.2 - http://github.com/jnr/jnr-x86asm) (Apache License, Version 2.0) JCIP Annotations under Apache License (com.github.stephenc.jcip:jcip-annotations:1.0-1 - http://stephenc.github.com/jcip-annotations) - (The Apache Software License, Version 2.0) FindBugs-jsr305 (com.google.code.findbugs:jsr305:2.0.1 - http://findbugs.sourceforge.net/) + (The Apache Software License, Version 2.0) FindBugs-jsr305 (com.google.code.findbugs:jsr305:3.0.2 - http://findbugs.sourceforge.net/) (Apache 2.0) error-prone annotations (com.google.errorprone:error_prone_annotations:2.49.0 - https://errorprone.info) (Apache License, Version 2.0) Guava InternalFutureFailureAccess and InternalFutures (com.google.guava:failureaccess:1.0.3 - https://github.com/google/guava) (Apache License, Version 2.0) Guava: Google Core Libraries for Java (com.google.guava:guava:33.6.0-jre - https://github.com/google/guava) From 8e5f5012a3ee19f3c2aa40701a4c6ce3be4d4432 Mon Sep 17 00:00:00 2001 From: Balaji Ganesan Date: Wed, 22 Jul 2026 07:20:11 -0700 Subject: [PATCH 03/29] feat(cloud-tasks): add the Java cloud-tasks service under Bazel Relocate nvct-core + nvct-service to src/control-plane-services/cloud-tasks and build them with the monorepo-native //rules/java pattern (nvcf_java_library + nvcf_spring_boot_image + java_junit5_test), the same as examples/java-spring-boot-service. No rules_spring, no custom java/spring macros, no root-module change beyond the step-1 maven closure. nvct-core and nvct-service (:image_index) build green; nv-boot is consumed as in-tree source targets with no API drift. - gRPC-Java codegen retained via the subtree's proto.bzl; lombok wired through the subtree's own java_plugin. - CI: cloud-tasks is a root-workspace member (like nv-boot-parent), so it is covered by the root matrix row via ROOT_GLOBS rather than a nested-module row. - OSS hygiene: settings.xml (internal URM credential wiring) and the GitLab mirror .oss-allowlist are dropped from the public tree; urm.nvidia.com in pom.xml and stg.nvcr.io in test fixtures match content already public in the monorepo. local_env carries only dummy test fixtures. Follow-up: cloud-tasks NOTICE auto-verification was coupled to the rules_spring fat-jar layout and is removed with the macro swap; regenerating it for the exploded classpath needs the shared nv-boot generate_notice.py to support that layout (tracked separately). Co-authored-by: Balaji Ganesan Co-Authored-By: Claude Opus 4.8 --- .bazelignore | 7 +- .github/workflows/bazel.yml | 2 +- .../cloud-tasks/BUILD.bazel | 35 + src/control-plane-services/cloud-tasks/NOTICE | 260 ++ .../local_env/cassandra/cassandra.yaml | 1424 ++++++++++ .../local_env/cassandra/entrypoint.sh | 24 + .../local_env/cassandra/keystore.node0 | Bin 0 -> 2244 bytes .../cassandra/schema/0001_initial_schema.cql | 125 + .../local_env/cassandra/truststore.node0 | Bin 0 -> 955 bytes .../local_env/docker-compose.test.yml | 38 + .../cloud-tasks/local_env/docker-compose.yml | 38 + .../cloud-tasks/local_env/vault/secrets.json | 27 + .../cloud-tasks/lombok.config | 18 + .../cloud-tasks/nvct-core/BUILD.bazel | 257 ++ .../cloud-tasks/nvct-core/local_env | 1 + .../cloud-tasks/nvct-core/pom.xml | 343 +++ .../AuthManagerResolverConfiguration.java | 136 + .../configuration/ClockConfiguration.java | 32 + .../DistributedLockConfiguration.java | 49 + .../nvct/configuration/GrpcConfiguration.java | 92 + .../configuration/JacksonConfiguration.java | 50 + .../MethodSecurityConfiguration.java | 26 + .../configuration/MetricsConfiguration.java | 36 + .../configuration/NotaryJwtConfiguration.java | 44 + .../ObservationConfiguration.java | 31 + .../OpenApiDocConfiguration.java | 124 + .../OutboundHttpResourcesConfiguration.java | 74 + .../configuration/RegistryConfiguration.java | 36 + .../configuration/SecurityConfiguration.java | 62 + .../ExceptionTracingExceptionHandler.java | 132 + .../ValidationAwareExceptionHandler.java | 156 ++ .../filters/ExceptionHandlerFilter.java | 55 + .../AccountRateLimiterProperties.java | 81 + .../ratelimit/TaskRateLimiterProperties.java | 83 + .../FixedBearerExchangeFilterFunction.java | 39 + .../StaticClientAuthConfiguration.java | 89 + .../nvidia/nvct/grpc/GrpcSkywayService.java | 148 ++ .../nvidia/nvct/grpc/GrpcWorkerService.java | 331 +++ .../grpc/ResultMetadataStreamObserver.java | 242 ++ ...uthHeaderPassthroughServerHttpRequest.java | 47 + .../nvct/grpc/auth/SecurityExpression.java | 36 + .../event/EventsByTaskRepository.java | 41 + .../event/entity/EventByTaskEntity.java | 61 + .../event/entity/EventByTaskKey.java | 49 + .../result/ResultsByTaskRepository.java | 41 + .../result/entity/ResultByTaskEntity.java | 66 + .../result/entity/ResultByTaskKey.java | 49 + .../persistence/task/TasksRepository.java | 43 + .../persistence/task/entity/ArtifactUdt.java | 26 + .../persistence/task/entity/GpuSpecUdt.java | 80 + .../persistence/task/entity/HealthUdt.java | 67 + .../persistence/task/entity/ModelUdt.java | 44 + .../persistence/task/entity/ResourceUdt.java | 44 + .../task/entity/ResultHandlingStrategy.java | 48 + .../persistence/task/entity/TaskEntity.java | 184 ++ .../persistence/task/entity/TaskStatus.java | 54 + .../task/entity/TelemetriesUdt.java | 44 + .../nvct/rest/event/EventController.java | 87 + .../nvidia/nvct/rest/event/EventFacade.java | 48 + .../rest/event/XAccountEventController.java | 89 + .../nvidia/nvct/rest/event/dto/EventDto.java | 42 + .../rest/event/dto/ListEventsResponse.java | 35 + .../misc/XAccountMiscEndpointsController.java | 242 ++ .../nvct/rest/misc/dto/GpuPlacementDto.java | 59 + .../nvct/rest/misc/dto/GpuUsageDto.java | 39 + .../rest/misc/dto/ListGpuUsageResponse.java | 29 + .../nvct/rest/result/ResultController.java | 87 + .../nvidia/nvct/rest/result/ResultFacade.java | 49 + .../rest/result/XAccountResultController.java | 88 + .../rest/result/dto/ListResultsResponse.java | 35 + .../nvct/rest/result/dto/ResultDto.java | 46 + .../secret/SecretManagementController.java | 86 + .../rest/secret/SecretManagementFacade.java | 162 ++ .../XAccountSecretManagementController.java | 90 + .../rest/secret/dto/UpdateSecretsRequest.java | 31 + .../rest/task/TaskManagementController.java | 204 ++ .../nvct/rest/task/TaskManagementFacade.java | 142 + .../XAccountTaskManagementController.java | 218 ++ .../nvct/rest/task/dto/ArtifactDto.java | 50 + .../nvct/rest/task/dto/BasicTaskDto.java | 35 + .../rest/task/dto/BulkTaskDetailsRequest.java | 34 + .../dto/ContainerEnvironmentEntryDto.java | 49 + .../nvct/rest/task/dto/CreateTaskRequest.java | 171 ++ .../rest/task/dto/GpuSpecificationDto.java | 51 + .../nvidia/nvct/rest/task/dto/HealthDto.java | 38 + .../task/dto/HelmValidationPolicyDto.java | 57 + .../nvct/rest/task/dto/InstanceDto.java | 70 + .../nvct/rest/task/dto/InstanceStateEnum.java | 50 + .../rest/task/dto/InstanceUsageTypeEnum.java | 38 + .../dto/ListBasicTaskDetailsResponse.java | 32 + .../nvct/rest/task/dto/ListTasksResponse.java | 35 + .../task/dto/ResultHandlingStrategyEnum.java | 49 + .../nvidia/nvct/rest/task/dto/SecretDto.java | 92 + .../nvidia/nvct/rest/task/dto/TaskDto.java | 134 + .../nvct/rest/task/dto/TaskResponse.java | 29 + .../nvct/rest/task/dto/TaskStatusEnum.java | 55 + .../task/dto/ValidationPolicyNameEnum.java | 39 + .../nvct/service/account/AccountService.java | 179 ++ .../nvct/service/account/dto/AccountDto.java | 53 + .../account/dto/RegistryCredentialDto.java | 68 + .../apikeys/ApiKeyValidationResult.java | 124 + .../nvct/service/apikeys/ApiKeysClient.java | 156 ++ .../nvct/service/apikeys/ApiKeysService.java | 121 + .../apikeys/dto/ApiKeyValidationRequest.java | 36 + .../apikeys/dto/ApiKeyValidationResponse.java | 36 + .../nvct/service/client/ClientService.java | 49 + .../nvct/service/client/dto/ClientDto.java | 35 + .../nvidia/nvct/service/ess/EssClient.java | 212 ++ .../nvidia/nvct/service/ess/EssService.java | 69 + .../nvct/service/ess/EssStubService.java | 105 + .../nvct/service/event/EventService.java | 215 ++ .../nvidia/nvct/service/icms/IcmsClient.java | 530 ++++ .../service/icms/IcmsClusterGroupClient.java | 247 ++ .../nvidia/nvct/service/icms/IcmsService.java | 118 + .../nvct/service/icms/IcmsStubService.java | 384 +++ .../service/instance/InstanceService.java | 139 + .../metrics/TaskErrorMetricsService.java | 70 + .../metrics/TaskMetricsExpirationPolicy.java | 47 + .../metrics/TaskRunningMetricsService.java | 143 + .../metrics/TaskSuccessMetricsService.java | 67 + .../nvct/service/ngc/NgcRegistryClient.java | 160 ++ .../service/ngc/NgcRegistryStubService.java | 65 + .../service/ngc/dto/CreateModelRequest.java | 33 + .../nvidia/nvct/service/nvcf/NvcfClient.java | 171 ++ .../nvct/service/nvcf/NvcfStubService.java | 47 + .../service/ratelimit/BucketRateLimiter.java | 98 + .../service/ratelimit/RateLimiterService.java | 60 + .../RegistryArtifactMapperService.java | 53 + .../registry/RegistryArtifactService.java | 247 ++ .../RegistryArtifactValidationService.java | 226 ++ .../registry/RegistryCredentialService.java | 360 +++ .../registry/RegistryTaskMapperService.java | 50 + .../registry/dto/DockerConfigJsonAuthDto.java | 28 + .../registry/dto/DockerConfigJsonDto.java | 29 + .../service/registry/dto/K8sSecretsDto.java | 29 + .../nvct/service/result/ResultService.java | 191 ++ .../nvct/service/reval/RevalClient.java | 183 ++ .../nvct/service/reval/RevalStubService.java | 62 + .../scheduler/CleanTerminalTasksRoutine.java | 184 ++ .../scheduler/CommonRoutineService.java | 181 ++ .../MonitorLaunchedTasksRoutine.java | 233 ++ .../scheduler/MonitorQueuedTasksRoutine.java | 296 +++ .../MonitorWorkerHeartbeatRoutine.java | 261 ++ .../scheduler/ScheduledRoutineService.java | 125 + .../secret/SecretManagementService.java | 44 + .../task/GpuSpecificationMapperService.java | 85 + .../HelmValidationPolicyMapperService.java | 57 + .../nvct/service/task/TaskAuditService.java | 153 ++ .../service/task/TaskManagementService.java | 635 +++++ .../nvct/service/task/TaskMapperService.java | 355 +++ .../nvct/service/task/TaskPredicateUtils.java | 42 + .../nvidia/nvct/service/task/TaskService.java | 340 +++ .../service/telemetry/TelemetryService.java | 97 + .../service/telemetry/dto/TelemetriesDto.java | 38 + .../service/telemetry/dto/TelemetryDto.java | 52 + .../telemetry/dto/TelemetryProtocolEnum.java | 48 + .../telemetry/dto/TelemetryProviderEnum.java | 56 + .../telemetry/dto/TelemetryTypeEnum.java | 51 + .../nvct/service/token/GrpcAuthService.java | 53 + .../nvct/service/token/TokenService.java | 86 + .../token/WorkerAssertionValidator.java | 154 ++ .../client/NotaryAudiencesConfiguration.java | 31 + .../service/token/client/NotaryClient.java | 188 ++ .../token/client/NotaryStubService.java | 56 + .../com/nvidia/nvct/util/NvctConstants.java | 166 ++ .../nvct/util/NvctOAuth2ClientUtils.java | 371 +++ .../java/com/nvidia/nvct/util/NvctUtils.java | 103 + .../nvidia/nvct/util/ProtoMappingUtils.java | 36 + .../nvct-core/src/main/proto/nvct.proto | 169 ++ .../nvct/IntegrationTestConfiguration.java | 396 +++ .../java/com/nvidia/nvct/NvctTestApp.java | 31 + .../ActuatorTracingIntegrationTest.java | 123 + .../ActuatorTracingTestConfiguration.java | 52 + .../nvct/actuator/MetricsIntegrationTest.java | 150 ++ .../ValidationAwareExceptionHandlerTest.java | 123 + .../nvct/grpc/GrpcSkywayServiceTest.java | 461 ++++ ...orkerRefreshSecretAssertionsTokenTest.java | 247 ++ .../nvct/grpc/GrpcWorkerServiceTest.java | 817 ++++++ .../TestResultMetadataStreamObserver.java | 69 + .../com/nvidia/nvct/grpc/TestTaskService.java | 216 ++ .../event/EventsByTaskRepositoryTest.java | 126 + .../result/ResultsByTaskRepositoryTest.java | 128 + .../persistence/task/TasksRepositoryTest.java | 326 +++ .../nvct/rest/event/EventControllerTest.java | 444 ++++ .../nvct/rest/event/TestEventService.java | 48 + .../event/XAccountEventControllerTest.java | 394 +++ .../nvct/rest/misc/MiscEndpointsTest.java | 115 + .../rest/result/ResultControllerTest.java | 478 ++++ .../nvct/rest/result/TestResultService.java | 50 + .../result/XAccountResultControllerTest.java | 427 +++ .../SecretManagementControllerTest.java | 482 ++++ ...AccountSecretManagementControllerTest.java | 407 +++ .../nvidia/nvct/rest/task/FilterTaskTest.java | 348 +++ .../task/HelmChartBasedTaskCreationTest.java | 444 ++++ .../task/ListTasksWithBasicDetailsTest.java | 181 ++ .../task/TaskCreationWithAcrRegistryTest.java | 282 ++ ...skCreationWithArtifactoryRegistryTest.java | 282 ++ ...TaskCreationWithDockerHubRegistryTest.java | 284 ++ .../task/TaskCreationWithEcrRegistryTest.java | 319 +++ .../TaskCreationWithHarborRegistryTest.java | 275 ++ ...askCreationWithVolcengineRegistryTest.java | 263 ++ ...reationWithoutRegistryCredentialsTest.java | 260 ++ .../task/TaskManagementControllerTest.java | 2335 +++++++++++++++++ .../TaskWithHelmValidationPolicyTest.java | 411 +++ .../rest/task/TaskWithTelemetriesTest.java | 398 +++ .../rest/task/TaskWithUserSecretsTest.java | 578 ++++ .../rest/task/XAccountFilterTaskTest.java | 350 +++ ...XAccountListTasksWithBasicDetailsTest.java | 173 ++ .../XAccountMiscEndpointsControllerTest.java | 271 ++ .../XAccountTaskManagementControllerTest.java | 1877 +++++++++++++ ...countTaskWithHelmValidationPolicyTest.java | 379 +++ .../task/XAccountTaskWithTelemetriesTest.java | 403 +++ .../task/XAccountTaskWithUserSecretsTest.java | 571 ++++ .../service/account/AccountServiceTest.java | 197 ++ .../apikeys/ApiKeyValidationResultTest.java | 70 + .../service/apikeys/ApiKeysClientTest.java | 89 + .../service/client/ClientServiceTest.java | 117 + .../nvct/service/ess/EssServiceTest.java | 295 +++ .../icms/IcmsClusterGroupClientTest.java | 220 ++ .../nvct/service/icms/IcmsServiceTest.java | 487 ++++ .../service/instance/InstanceServiceTest.java | 120 + .../service/ngc/NgcRegistryClientTest.java | 193 ++ .../ratelimit/RateLimiterServiceTest.java | 371 +++ .../registry/RegistryArtifactServiceTest.java | 149 ++ ...RegistryArtifactValidationServiceTest.java | 444 ++++ .../reval/RevalClientIntegrationTest.java | 229 ++ .../service/reval/RevalSerializationTest.java | 89 + .../CleanTerminalTasksRoutineTest.java | 223 ++ .../MonitorLaunchedTasksRoutineTest.java | 222 ++ .../MonitorQueuedTasksRoutineTest.java | 279 ++ .../MonitorWorkerHeartbeatRoutineTest.java | 284 ++ .../token/WorkerAssertionValidatorTest.java | 143 + .../nvct/util/EssResponseTransformer.java | 142 + .../nvct/util/ManagedHttpResourcesTest.java | 107 + .../nvidia/nvct/util/MockApiKeysServer.java | 97 + .../com/nvidia/nvct/util/MockEssServer.java | 96 + .../com/nvidia/nvct/util/MockIcmsServer.java | 478 ++++ .../nvidia/nvct/util/MockNotaryServer.java | 83 + .../com/nvidia/nvct/util/MockNvcfServer.java | 170 ++ .../com/nvidia/nvct/util/MockRevalServer.java | 92 + .../NotaryServiceResponseTransformer.java | 230 ++ .../com/nvidia/nvct/util/TestConstants.java | 478 ++++ .../nvidia/nvct/util/TestRegistryService.java | 244 ++ .../java/com/nvidia/nvct/util/TestUtil.java | 194 ++ .../src/test/resources/application-test.yaml | 350 +++ .../src/test/resources/bootstrap-test.yaml | 30 + .../src/test/resources/docker-java.properties | 16 + .../cluster-groups/complete-response.json | 87 + .../missing-gfn-cluster-group-response.json | 37 + .../missing-gfn-gpus-response.json | 52 + .../missing-t10-gpu-response.json | 65 + ...ng-t10-instance-type-default-response.json | 64 + .../missing-t10-instance-types-response.json | 57 + .../icms/clusters/complete-response.json | 1146 ++++++++ .../fixtures/icms/raw-healthy-instance.json | 25 + .../icms/raw-no-capacity-instance.json | 31 + .../fixtures/icms/raw-unhealthy-instance.json | 29 + .../fixtures/nvcf/account-response.json | 151 ++ .../account-with-telemetries-response.json | 79 + ...without-registry-credentials-response.json | 10 + .../fixtures/nvcf/client-response.json | 7 + .../nvct-core/src/test/resources/load-test.js | 57 + .../cloud-tasks/nvct-service/BUILD.bazel | 102 + .../cloud-tasks/nvct-service/local_env | 1 + .../cloud-tasks/nvct-service/pom.xml | 113 + .../src/main/java/com/nvidia/nvct/App.java | 34 + .../src/main/resources/application-local.yaml | 61 + .../src/main/resources/application-ncp.yaml | 146 ++ .../src/main/resources/application.yaml | 342 +++ .../src/main/resources/bootstrap-local.yaml | 19 + .../src/main/resources/bootstrap-ncp.yaml | 21 + .../src/main/resources/bootstrap.yaml | 44 + .../nvct/NvctServiceIntegrationTest.java | 68 + .../src/test/resources/application-test.yaml | 222 ++ .../src/test/resources/bootstrap-test.yaml | 21 + .../cloud-tasks/pom.xml | 107 + .../cloud-tasks/tools/bazel/BUILD.bazel | 40 + .../tools/bazel/jacoco_test_runner.sh | 77 + .../tools/bazel/notice_metadata.json | 1878 +++++++++++++ .../cloud-tasks/tools/bazel/proto.bzl | 27 + .../cloud-tasks/tools/bazel/runfiles.bzl | 26 + .../tools/bazel/workspace_status.sh | 20 + 282 files changed, 47914 insertions(+), 2 deletions(-) create mode 100644 src/control-plane-services/cloud-tasks/BUILD.bazel create mode 100644 src/control-plane-services/cloud-tasks/NOTICE create mode 100644 src/control-plane-services/cloud-tasks/local_env/cassandra/cassandra.yaml create mode 100755 src/control-plane-services/cloud-tasks/local_env/cassandra/entrypoint.sh create mode 100644 src/control-plane-services/cloud-tasks/local_env/cassandra/keystore.node0 create mode 100644 src/control-plane-services/cloud-tasks/local_env/cassandra/schema/0001_initial_schema.cql create mode 100644 src/control-plane-services/cloud-tasks/local_env/cassandra/truststore.node0 create mode 100644 src/control-plane-services/cloud-tasks/local_env/docker-compose.test.yml create mode 100644 src/control-plane-services/cloud-tasks/local_env/docker-compose.yml create mode 100644 src/control-plane-services/cloud-tasks/local_env/vault/secrets.json create mode 100644 src/control-plane-services/cloud-tasks/lombok.config create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/BUILD.bazel create mode 120000 src/control-plane-services/cloud-tasks/nvct-core/local_env create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/pom.xml create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/AuthManagerResolverConfiguration.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/ClockConfiguration.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/DistributedLockConfiguration.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/GrpcConfiguration.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/JacksonConfiguration.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/MethodSecurityConfiguration.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/MetricsConfiguration.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/NotaryJwtConfiguration.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/ObservationConfiguration.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/OpenApiDocConfiguration.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/OutboundHttpResourcesConfiguration.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/RegistryConfiguration.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/SecurityConfiguration.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/exceptions/ExceptionTracingExceptionHandler.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/exceptions/ValidationAwareExceptionHandler.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/filters/ExceptionHandlerFilter.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/ratelimit/AccountRateLimiterProperties.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/ratelimit/TaskRateLimiterProperties.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/staticclientauth/FixedBearerExchangeFilterFunction.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/staticclientauth/StaticClientAuthConfiguration.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/grpc/GrpcSkywayService.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/grpc/GrpcWorkerService.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/grpc/ResultMetadataStreamObserver.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/grpc/auth/AuthHeaderPassthroughServerHttpRequest.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/grpc/auth/SecurityExpression.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/persistence/event/EventsByTaskRepository.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/persistence/event/entity/EventByTaskEntity.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/persistence/event/entity/EventByTaskKey.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/persistence/result/ResultsByTaskRepository.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/persistence/result/entity/ResultByTaskEntity.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/persistence/result/entity/ResultByTaskKey.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/persistence/task/TasksRepository.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/persistence/task/entity/ArtifactUdt.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/persistence/task/entity/GpuSpecUdt.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/persistence/task/entity/HealthUdt.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/persistence/task/entity/ModelUdt.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/persistence/task/entity/ResourceUdt.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/persistence/task/entity/ResultHandlingStrategy.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/persistence/task/entity/TaskEntity.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/persistence/task/entity/TaskStatus.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/persistence/task/entity/TelemetriesUdt.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/event/EventController.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/event/EventFacade.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/event/XAccountEventController.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/event/dto/EventDto.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/event/dto/ListEventsResponse.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/misc/XAccountMiscEndpointsController.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/misc/dto/GpuPlacementDto.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/misc/dto/GpuUsageDto.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/misc/dto/ListGpuUsageResponse.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/result/ResultController.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/result/ResultFacade.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/result/XAccountResultController.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/result/dto/ListResultsResponse.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/result/dto/ResultDto.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/secret/SecretManagementController.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/secret/SecretManagementFacade.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/secret/XAccountSecretManagementController.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/secret/dto/UpdateSecretsRequest.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/TaskManagementController.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/TaskManagementFacade.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/XAccountTaskManagementController.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/ArtifactDto.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/BasicTaskDto.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/BulkTaskDetailsRequest.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/ContainerEnvironmentEntryDto.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/CreateTaskRequest.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/GpuSpecificationDto.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/HealthDto.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/HelmValidationPolicyDto.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/InstanceDto.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/InstanceStateEnum.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/InstanceUsageTypeEnum.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/ListBasicTaskDetailsResponse.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/ListTasksResponse.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/ResultHandlingStrategyEnum.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/SecretDto.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/TaskDto.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/TaskResponse.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/TaskStatusEnum.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/ValidationPolicyNameEnum.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/account/AccountService.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/account/dto/AccountDto.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/account/dto/RegistryCredentialDto.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/apikeys/ApiKeyValidationResult.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/apikeys/ApiKeysClient.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/apikeys/ApiKeysService.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/apikeys/dto/ApiKeyValidationRequest.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/apikeys/dto/ApiKeyValidationResponse.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/client/ClientService.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/client/dto/ClientDto.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/ess/EssClient.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/ess/EssService.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/ess/EssStubService.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/event/EventService.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/icms/IcmsClient.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/icms/IcmsClusterGroupClient.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/icms/IcmsService.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/icms/IcmsStubService.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/instance/InstanceService.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/metrics/TaskErrorMetricsService.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/metrics/TaskMetricsExpirationPolicy.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/metrics/TaskRunningMetricsService.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/metrics/TaskSuccessMetricsService.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/ngc/NgcRegistryClient.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/ngc/NgcRegistryStubService.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/ngc/dto/CreateModelRequest.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/nvcf/NvcfClient.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/nvcf/NvcfStubService.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/ratelimit/BucketRateLimiter.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/ratelimit/RateLimiterService.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/registry/RegistryArtifactMapperService.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/registry/RegistryArtifactService.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/registry/RegistryArtifactValidationService.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/registry/RegistryCredentialService.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/registry/RegistryTaskMapperService.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/registry/dto/DockerConfigJsonAuthDto.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/registry/dto/DockerConfigJsonDto.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/registry/dto/K8sSecretsDto.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/result/ResultService.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/reval/RevalClient.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/reval/RevalStubService.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/scheduler/CleanTerminalTasksRoutine.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/scheduler/CommonRoutineService.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/scheduler/MonitorLaunchedTasksRoutine.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/scheduler/MonitorQueuedTasksRoutine.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/scheduler/MonitorWorkerHeartbeatRoutine.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/scheduler/ScheduledRoutineService.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/secret/SecretManagementService.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/task/GpuSpecificationMapperService.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/task/HelmValidationPolicyMapperService.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/task/TaskAuditService.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/task/TaskManagementService.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/task/TaskMapperService.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/task/TaskPredicateUtils.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/task/TaskService.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/telemetry/TelemetryService.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/telemetry/dto/TelemetriesDto.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/telemetry/dto/TelemetryDto.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/telemetry/dto/TelemetryProtocolEnum.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/telemetry/dto/TelemetryProviderEnum.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/telemetry/dto/TelemetryTypeEnum.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/token/GrpcAuthService.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/token/TokenService.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/token/WorkerAssertionValidator.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/token/client/NotaryAudiencesConfiguration.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/token/client/NotaryClient.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/token/client/NotaryStubService.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/util/NvctConstants.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/util/NvctOAuth2ClientUtils.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/util/NvctUtils.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/util/ProtoMappingUtils.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/main/proto/nvct.proto create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/IntegrationTestConfiguration.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/NvctTestApp.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/actuator/ActuatorTracingIntegrationTest.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/actuator/ActuatorTracingTestConfiguration.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/actuator/MetricsIntegrationTest.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/configuration/exceptions/ValidationAwareExceptionHandlerTest.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/grpc/GrpcSkywayServiceTest.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/grpc/GrpcWorkerRefreshSecretAssertionsTokenTest.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/grpc/GrpcWorkerServiceTest.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/grpc/TestResultMetadataStreamObserver.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/grpc/TestTaskService.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/persistence/event/EventsByTaskRepositoryTest.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/persistence/result/ResultsByTaskRepositoryTest.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/persistence/task/TasksRepositoryTest.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/event/EventControllerTest.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/event/TestEventService.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/event/XAccountEventControllerTest.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/misc/MiscEndpointsTest.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/result/ResultControllerTest.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/result/TestResultService.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/result/XAccountResultControllerTest.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/secret/SecretManagementControllerTest.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/secret/XAccountSecretManagementControllerTest.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/FilterTaskTest.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/HelmChartBasedTaskCreationTest.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/ListTasksWithBasicDetailsTest.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/TaskCreationWithAcrRegistryTest.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/TaskCreationWithArtifactoryRegistryTest.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/TaskCreationWithDockerHubRegistryTest.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/TaskCreationWithEcrRegistryTest.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/TaskCreationWithHarborRegistryTest.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/TaskCreationWithVolcengineRegistryTest.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/TaskCreationWithoutRegistryCredentialsTest.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/TaskManagementControllerTest.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/TaskWithHelmValidationPolicyTest.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/TaskWithTelemetriesTest.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/TaskWithUserSecretsTest.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/XAccountFilterTaskTest.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/XAccountListTasksWithBasicDetailsTest.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/XAccountMiscEndpointsControllerTest.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/XAccountTaskManagementControllerTest.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/XAccountTaskWithHelmValidationPolicyTest.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/XAccountTaskWithTelemetriesTest.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/XAccountTaskWithUserSecretsTest.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/service/account/AccountServiceTest.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/service/apikeys/ApiKeyValidationResultTest.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/service/apikeys/ApiKeysClientTest.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/service/client/ClientServiceTest.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/service/ess/EssServiceTest.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/service/icms/IcmsClusterGroupClientTest.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/service/icms/IcmsServiceTest.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/service/instance/InstanceServiceTest.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/service/ngc/NgcRegistryClientTest.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/service/ratelimit/RateLimiterServiceTest.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/service/registry/RegistryArtifactServiceTest.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/service/registry/RegistryArtifactValidationServiceTest.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/service/reval/RevalClientIntegrationTest.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/service/reval/RevalSerializationTest.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/service/scheduler/CleanTerminalTasksRoutineTest.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/service/scheduler/MonitorLaunchedTasksRoutineTest.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/service/scheduler/MonitorQueuedTasksRoutineTest.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/service/scheduler/MonitorWorkerHeartbeatRoutineTest.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/service/token/WorkerAssertionValidatorTest.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/util/EssResponseTransformer.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/util/ManagedHttpResourcesTest.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/util/MockApiKeysServer.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/util/MockEssServer.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/util/MockIcmsServer.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/util/MockNotaryServer.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/util/MockNvcfServer.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/util/MockRevalServer.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/util/NotaryServiceResponseTransformer.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/util/TestConstants.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/util/TestRegistryService.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/util/TestUtil.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/resources/application-test.yaml create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/resources/bootstrap-test.yaml create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/resources/docker-java.properties create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/resources/fixtures/icms/cluster-groups/complete-response.json create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/resources/fixtures/icms/cluster-groups/missing-gfn-cluster-group-response.json create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/resources/fixtures/icms/cluster-groups/missing-gfn-gpus-response.json create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/resources/fixtures/icms/cluster-groups/missing-t10-gpu-response.json create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/resources/fixtures/icms/cluster-groups/missing-t10-instance-type-default-response.json create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/resources/fixtures/icms/cluster-groups/missing-t10-instance-types-response.json create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/resources/fixtures/icms/clusters/complete-response.json create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/resources/fixtures/icms/raw-healthy-instance.json create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/resources/fixtures/icms/raw-no-capacity-instance.json create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/resources/fixtures/icms/raw-unhealthy-instance.json create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/resources/fixtures/nvcf/account-response.json create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/resources/fixtures/nvcf/account-with-telemetries-response.json create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/resources/fixtures/nvcf/account-without-registry-credentials-response.json create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/resources/fixtures/nvcf/client-response.json create mode 100644 src/control-plane-services/cloud-tasks/nvct-core/src/test/resources/load-test.js create mode 100644 src/control-plane-services/cloud-tasks/nvct-service/BUILD.bazel create mode 120000 src/control-plane-services/cloud-tasks/nvct-service/local_env create mode 100644 src/control-plane-services/cloud-tasks/nvct-service/pom.xml create mode 100644 src/control-plane-services/cloud-tasks/nvct-service/src/main/java/com/nvidia/nvct/App.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-service/src/main/resources/application-local.yaml create mode 100644 src/control-plane-services/cloud-tasks/nvct-service/src/main/resources/application-ncp.yaml create mode 100644 src/control-plane-services/cloud-tasks/nvct-service/src/main/resources/application.yaml create mode 100644 src/control-plane-services/cloud-tasks/nvct-service/src/main/resources/bootstrap-local.yaml create mode 100644 src/control-plane-services/cloud-tasks/nvct-service/src/main/resources/bootstrap-ncp.yaml create mode 100644 src/control-plane-services/cloud-tasks/nvct-service/src/main/resources/bootstrap.yaml create mode 100644 src/control-plane-services/cloud-tasks/nvct-service/src/test/java/com/nvidia/nvct/NvctServiceIntegrationTest.java create mode 100644 src/control-plane-services/cloud-tasks/nvct-service/src/test/resources/application-test.yaml create mode 100644 src/control-plane-services/cloud-tasks/nvct-service/src/test/resources/bootstrap-test.yaml create mode 100644 src/control-plane-services/cloud-tasks/pom.xml create mode 100644 src/control-plane-services/cloud-tasks/tools/bazel/BUILD.bazel create mode 100755 src/control-plane-services/cloud-tasks/tools/bazel/jacoco_test_runner.sh create mode 100644 src/control-plane-services/cloud-tasks/tools/bazel/notice_metadata.json create mode 100644 src/control-plane-services/cloud-tasks/tools/bazel/proto.bzl create mode 100644 src/control-plane-services/cloud-tasks/tools/bazel/runfiles.bzl create mode 100755 src/control-plane-services/cloud-tasks/tools/bazel/workspace_status.sh diff --git a/.bazelignore b/.bazelignore index ce2ac9fd9..b566f9400 100644 --- a/.bazelignore +++ b/.bazelignore @@ -28,7 +28,12 @@ # with our bzlmod setup. Re-enable per-subtree as Phase B brings each subtree # native. src/compute-plane-services -src/control-plane-services +# src/control-plane-services is carved out per-subtree: cloud-tasks is native +# (Phase B) and must stay loadable, while these siblings still carry nested +# MODULE.bazel / WORKSPACE-style BUILD files that conflict with bzlmod. +src/control-plane-services/function-autoscaler +src/control-plane-services/helm-reval +src/control-plane-services/nats-auth-callout src/invocation-plane-services src/libraries/python # stargate rolled back to authoritative_source: upstream in !413; its diff --git a/.github/workflows/bazel.yml b/.github/workflows/bazel.yml index 440aae2ad..9d9dccedf 100644 --- a/.github/workflows/bazel.yml +++ b/.github/workflows/bazel.yml @@ -117,7 +117,7 @@ jobs: helm-reval|src/control-plane-services/helm-reval|false' # Paths that affect the root-module workspace build (native # root subtrees, Go and Java, plus the shared Bazel scaffold). - ROOT_GLOBS=(MODULE.bazel .bazelrc .bazelversion BUILD.bazel rules/ platforms/ tools/ ci/ src/clis/ src/libraries/ .github/bazel-root-test-quarantine.txt) + ROOT_GLOBS=(MODULE.bazel .bazelrc .bazelversion BUILD.bazel rules/ platforms/ tools/ ci/ src/clis/ src/libraries/ src/control-plane-services/cloud-tasks/ .github/bazel-root-test-quarantine.txt) run_all=false changed="" diff --git a/src/control-plane-services/cloud-tasks/BUILD.bazel b/src/control-plane-services/cloud-tasks/BUILD.bazel new file mode 100644 index 000000000..a8c3b41d5 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/BUILD.bazel @@ -0,0 +1,35 @@ +load("//src/control-plane-services/cloud-tasks/tools/bazel:runfiles.bzl", "nvct_workspace_runfiles") + +package(default_visibility = ["//visibility:public"]) + +exports_files([ + "NOTICE", +]) + +filegroup( + name = "integration_local_env_files", + srcs = [ + "local_env/docker-compose.test.yml", + ] + glob([ + "local_env/cassandra/**", + "local_env/vault/**", + ]), +) + +nvct_workspace_runfiles( + name = "integration_local_env", + srcs = [":integration_local_env_files"], + # After the umbrella relocation the runfiles short_path carries the subtree + # prefix; strip it so integration tests still resolve local_env/... relative + # to the runfiles root (test config references local_env/vault/secrets.json). + strip_prefix = "src/control-plane-services/cloud-tasks/", +) + +# NOTE: THIRD_PARTY_NOTICE generation (the former notice genrule, generate +# binary, and tools/bazel notice check) read the Spring fat jar +# (nvct-service app jar, BOOT-INF/lib/external/... layout). Converging onto +# //rules/java's exploded-classpath image removes that fat jar, so the fat-jar +# NOTICE mechanism no longer has an input. Reworking NOTICE generation for the +# exploded classpath is tracked as follow-up; it needs a change to the shared +# nv-boot generate_notice.py, which is out of scope for this build-wiring +# convergence. diff --git a/src/control-plane-services/cloud-tasks/NOTICE b/src/control-plane-services/cloud-tasks/NOTICE new file mode 100644 index 000000000..4989aae6f --- /dev/null +++ b/src/control-plane-services/cloud-tasks/NOTICE @@ -0,0 +1,260 @@ + +Lists of 258 third-party dependencies. + (Apache License, Version 2.0) LZ4 Java Compression (at.yawk.lz4:lz4-java:1.10.3 - https://github.com/yawkat/lz4-java) + (EPL-2.0) (LGPL-2.1-only) Logback Classic Module (ch.qos.logback:logback-classic:1.5.34 - http://logback.qos.ch) + (EPL-2.0) (LGPL-2.1-only) Logback Core Module (ch.qos.logback:logback-core:1.5.34 - http://logback.qos.ch) + (The Apache Software License, Version 2.0) bucket4j-core (com.bucket4j:bucket4j-core:8.10.1 - http://github.com/bucket4j/bucket4j/bucket4j-core) + (The Apache Software License, Version 2.0) bucket4j_jdk17-core (com.bucket4j:bucket4j_jdk17-core:8.19.0 - http://github.com/bucket4j/bucket4j/bucket4j_jdk17-core) + (Apache 2) An implementation of the Apache Cassandra® native protocol (com.datastax.oss:native-protocol:1.5.2 - https://github.com/datastax/native-protocol) + (The Apache Software License, Version 2.0) Jackson-annotations (com.fasterxml.jackson.core:jackson-annotations:2.21 - https://github.com/FasterXML/jackson) + (The Apache Software License, Version 2.0) Jackson-core (com.fasterxml.jackson.core:jackson-core:2.21.4 - https://github.com/FasterXML/jackson-core) + (The Apache Software License, Version 2.0) jackson-databind (com.fasterxml.jackson.core:jackson-databind:2.21.4 - https://github.com/FasterXML/jackson) + (The Apache Software License, Version 2.0) Jackson-dataformat-YAML (com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.21.4 - https://github.com/FasterXML/jackson-dataformats-text) + (The Apache Software License, Version 2.0) Jackson datatype: JSR310 (com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.21.4 - https://github.com/FasterXML/jackson-modules-java8) + (Apache License, Version 2.0) ClassMate (com.fasterxml:classmate:1.7.3 - https://github.com/FasterXML/java-classmate) + (Apache License, Version 2.0) Caffeine cache (com.github.ben-manes.caffeine:caffeine:3.2.4 - https://github.com/ben-manes/caffeine) + (Apache License, Version 2.0) Caffeine cache (com.github.ben-manes.caffeine:guava:3.2.4 - https://github.com/ben-manes/caffeine) + (Lesser General Public License, version 3 or greater) (Apache Software License, version 2.0) btf (com.github.java-json-tools:btf:1.3 - https://github.com/java-json-tools/btf) + (Lesser General Public License, version 3 or greater) (Apache Software License, version 2.0) jackson-coreutils (com.github.java-json-tools:jackson-coreutils:2.0 - https://github.com/java-json-tools/jackson-coreutils) + (Lesser General Public License, version 3 or greater) (Apache Software License, version 2.0) json-patch (com.github.java-json-tools:json-patch:1.13 - https://github.com/java-json-tools/json-patch) + (Lesser General Public License, version 3 or greater) (Apache Software License, version 2.0) msg-simple (com.github.java-json-tools:msg-simple:1.2 - https://github.com/java-json-tools/msg-simple) + (The Apache Software License, Version 2.0) jffi (com.github.jnr:jffi:1.2.16 - http://github.com/jnr/jffi) + (The Apache Software License, Version 2.0) jnr-constants (com.github.jnr:jnr-constants:0.10.3 - http://github.com/jnr/jnr-constants) + (The Apache Software License, Version 2.0) jnr-ffi (com.github.jnr:jnr-ffi:2.1.7 - http://github.com/jnr/jnr-ffi) + (Eclipse Public License - v 2.0) (GNU General Public License Version 2) (GNU Lesser General Public License Version 2.1) jnr-posix (com.github.jnr:jnr-posix:3.1.15 - http://nexus.sonatype.org/oss-repository-hosting.html) + (MIT License) jnr-x86asm (com.github.jnr:jnr-x86asm:1.0.2 - http://github.com/jnr/jnr-x86asm) + (Apache License, Version 2.0) JCIP Annotations under Apache License (com.github.stephenc.jcip:jcip-annotations:1.0-1 - http://stephenc.github.com/jcip-annotations) + (Apache 2.0) Google Android Annotations Library (com.google.android:annotations:4.1.1.4 - http://source.android.com/) + (Apache-2.0) proto-google-common-protos (com.google.api.grpc:proto-google-common-protos:2.29.0 - https://github.com/googleapis/sdk-platform-java) + (The Apache Software License, Version 2.0) FindBugs-jsr305 (com.google.code.findbugs:jsr305:3.0.2 - http://findbugs.sourceforge.net/) + (Apache-2.0) Gson (com.google.code.gson:gson:2.13.2 - https://github.com/google/gson) + (Apache 2.0) error-prone annotations (com.google.errorprone:error_prone_annotations:2.49.0 - https://errorprone.info) + (Apache License, Version 2.0) Guava InternalFutureFailureAccess and InternalFutures (com.google.guava:failureaccess:1.0.3 - https://github.com/google/guava) + (Apache License, Version 2.0) Guava: Google Core Libraries for Java (com.google.guava:guava:33.6.0-jre - https://github.com/google/guava) + (The Apache Software License, Version 2.0) Guava ListenableFuture only (com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava - https://github.com/google/guava) + (Apache License, Version 2.0) J2ObjC Annotations (com.google.j2objc:j2objc-annotations:3.1 - https://github.com/google/j2objc/) + (BSD-3-Clause) Protocol Buffers [Core] (com.google.protobuf:protobuf-java:4.33.4 - https://developers.google.com/protocol-buffers/) + (BSD-3-Clause) Protocol Buffers [Util] (com.google.protobuf:protobuf-java-util:4.33.4 - https://developers.google.com/protocol-buffers/) + (The Apache Software License, Version 2.0) Nimbus Content Type (com.nimbusds:content-type:2.3 - https://bitbucket.org/connect2id/nimbus-content-type) + (The Apache Software License, Version 2.0) Nimbus LangTag (com.nimbusds:lang-tag:1.7 - https://bitbucket.org/connect2id/nimbus-language-tags) + (The Apache Software License, Version 2.0) Nimbus JOSE+JWT (com.nimbusds:nimbus-jose-jwt:10.4 - https://bitbucket.org/connect2id/nimbus-jose-jwt) + (Apache License, version 2.0) OAuth 2.0 SDK with OpenID Connect extensions (com.nimbusds:oauth2-oidc-sdk:11.26.1 - https://bitbucket.org/connect2id/oauth-2.0-sdk-with-openid-connect-extensions) + (The Apache Software License, Version 2.0) okhttp-logging-interceptor (com.squareup.okhttp3:logging-interceptor:4.12.0 - https://square.github.io/okhttp/) + (The Apache Software License, Version 2.0) okhttp (com.squareup.okhttp3:okhttp:4.12.0 - https://square.github.io/okhttp/) + (The Apache Software License, Version 2.0) okio (com.squareup.okio:okio:3.6.0 - https://github.com/square/okio/) + (The Apache Software License, Version 2.0) okio (com.squareup.okio:okio-jvm:3.16.1 - https://github.com/square/okio/) + (Apache-2.0) config (com.typesafe:config:1.4.1 - https://github.com/lightbend/config) + (Apache-2.0) Apache Commons Codec (commons-codec:commons-codec:1.19.0 - https://commons.apache.org/proper/commons-codec/) + (Apache-2.0) Apache Commons IO (commons-io:commons-io:2.20.0 - https://commons.apache.org/proper/commons-io/) + (Apache-2.0) Apache Commons Logging (commons-logging:commons-logging:1.3.6 - https://commons.apache.org/proper/commons-logging/) + (Apache License 2.0) Metrics Core (io.dropwizard.metrics:metrics-core:4.1.18 - https://metrics.dropwizard.io) + (Apache 2.0) io.grpc:grpc-api (io.grpc:grpc-api:1.63.0 - https://github.com/grpc/grpc-java) + (Apache 2.0) io.grpc:grpc-context (io.grpc:grpc-context:1.63.0 - https://github.com/grpc/grpc-java) + (Apache 2.0) io.grpc:grpc-core (io.grpc:grpc-core:1.63.0 - https://github.com/grpc/grpc-java) + (Apache 2.0) io.grpc:grpc-inprocess (io.grpc:grpc-inprocess:1.63.0 - https://github.com/grpc/grpc-java) + (Apache 2.0) io.grpc:grpc-netty-shaded (io.grpc:grpc-netty-shaded:1.63.0 - https://github.com/grpc/grpc-java) + (Apache 2.0) io.grpc:grpc-protobuf (io.grpc:grpc-protobuf:1.63.0 - https://github.com/grpc/grpc-java) + (Apache 2.0) io.grpc:grpc-protobuf-lite (io.grpc:grpc-protobuf-lite:1.63.0 - https://github.com/grpc/grpc-java) + (Apache 2.0) io.grpc:grpc-services (io.grpc:grpc-services:1.63.0 - https://github.com/grpc/grpc-java) + (Apache 2.0) io.grpc:grpc-stub (io.grpc:grpc-stub:1.63.0 - https://github.com/grpc/grpc-java) + (Apache 2.0) io.grpc:grpc-util (io.grpc:grpc-util:1.63.0 - https://github.com/grpc/grpc-java) + (Apache-2.0) Gson on Fire! (io.gsonfire:gson-fire:1.9.0 - http://gsonfire.io) + (The Apache Software License, Version 2.0) client-java (io.kubernetes:client-java:24.0.0 - https://github.com/kubernetes-client/java) + (The Apache Software License, Version 2.0) client-java-api (io.kubernetes:client-java-api:24.0.0 - https://github.com/kubernetes-client/java) + (The Apache Software License, Version 2.0) client-java-fluent (io.kubernetes:client-java-api-fluent:24.0.0 - https://github.com/kubernetes-client/java) + (The Apache Software License, Version 2.0) client-java-extended (io.kubernetes:client-java-extended:24.0.0 - https://github.com/kubernetes-client/java) + (The Apache Software License, Version 2.0) client-java-proto (io.kubernetes:client-java-proto:24.0.0 - https://github.com/kubernetes-client/java) + (The Apache Software License, Version 2.0) context-propagation (io.micrometer:context-propagation:1.2.1 - https://github.com/micrometer-metrics/context-propagation) + (The Apache Software License, Version 2.0) micrometer-commons (io.micrometer:micrometer-commons:1.16.6 - https://github.com/micrometer-metrics/micrometer) + (The Apache Software License, Version 2.0) micrometer-core (io.micrometer:micrometer-core:1.16.6 - https://github.com/micrometer-metrics/micrometer) + (The Apache Software License, Version 2.0) micrometer-jakarta9 (io.micrometer:micrometer-jakarta9:1.16.6 - https://github.com/micrometer-metrics/micrometer) + (The Apache Software License, Version 2.0) micrometer-observation (io.micrometer:micrometer-observation:1.16.6 - https://github.com/micrometer-metrics/micrometer) + (The Apache Software License, Version 2.0) micrometer-registry-prometheus (io.micrometer:micrometer-registry-prometheus:1.16.6 - https://github.com/micrometer-metrics/micrometer) + (The Apache Software License, Version 2.0) micrometer-tracing (io.micrometer:micrometer-tracing:1.6.6 - https://github.com/micrometer-metrics/tracing) + (The Apache Software License, Version 2.0) micrometer-tracing-bridge-otel (io.micrometer:micrometer-tracing-bridge-otel:1.6.6 - https://github.com/micrometer-metrics/tracing) + (Apache License, Version 2.0) Netty/Buffer (io.netty:netty-buffer:4.2.15.Final - https://netty.io/) + (Apache License, Version 2.0) Netty/Codec/Base (io.netty:netty-codec-base:4.2.15.Final - https://netty.io/) + (Apache License, Version 2.0) Netty/Codec/Classes/Quic (io.netty:netty-codec-classes-quic:4.2.15.Final - https://netty.io/) + (Apache License, Version 2.0) Netty/Codec/Compression (io.netty:netty-codec-compression:4.2.15.Final - https://netty.io/) + (Apache License, Version 2.0) Netty/Codec/DNS (io.netty:netty-codec-dns:4.2.15.Final - https://netty.io/) + (Apache License, Version 2.0) Netty/Codec/HTTP (io.netty:netty-codec-http:4.2.15.Final - https://netty.io/) + (Apache License, Version 2.0) Netty/Codec/HTTP2 (io.netty:netty-codec-http2:4.2.15.Final - https://netty.io/) + (Apache License, Version 2.0) Netty/Codec/Http3 (io.netty:netty-codec-http3:4.2.15.Final - https://netty.io/netty-codec-http3/) + (Apache License, Version 2.0) Netty/Codec/Native/Quic (io.netty:netty-codec-native-quic:4.2.15.Final - https://netty.io/) + (Apache License, Version 2.0) Netty/Codec/Socks (io.netty:netty-codec-socks:4.2.15.Final - https://netty.io/) + (Apache License, Version 2.0) Netty/Common (io.netty:netty-common:4.2.15.Final - https://netty.io/) + (Apache License, Version 2.0) Netty/Handler (io.netty:netty-handler:4.2.15.Final - https://netty.io/) + (Apache License, Version 2.0) Netty/Handler/Proxy (io.netty:netty-handler-proxy:4.2.15.Final - https://netty.io/) + (Apache License, Version 2.0) Netty/Resolver (io.netty:netty-resolver:4.2.15.Final - https://netty.io/) + (Apache License, Version 2.0) Netty/Resolver/DNS (io.netty:netty-resolver-dns:4.2.15.Final - https://netty.io/) + (Apache License, Version 2.0) Netty/Resolver/DNS/Classes/MacOS (io.netty:netty-resolver-dns-classes-macos:4.2.15.Final - https://netty.io/) + (Apache License, Version 2.0) Netty/Resolver/DNS/Native/MacOS (io.netty:netty-resolver-dns-native-macos:4.2.15.Final - https://netty.io/) + (Apache License, Version 2.0) Netty/Transport (io.netty:netty-transport:4.2.15.Final - https://netty.io/) + (Apache License, Version 2.0) Netty/Transport/Classes/Epoll (io.netty:netty-transport-classes-epoll:4.2.15.Final - https://netty.io/) + (Apache License, Version 2.0) Netty/Transport/Native/Epoll (io.netty:netty-transport-native-epoll:4.2.15.Final - https://netty.io/) + (Apache License, Version 2.0) Netty/Transport/Native/Unix/Common (io.netty:netty-transport-native-unix-common:4.2.15.Final - https://netty.io/) + (The Apache License, Version 2.0) OpenTelemetry Semantic Conventions Java (io.opentelemetry.semconv:opentelemetry-semconv:1.37.0 - https://github.com/open-telemetry/semantic-conventions-java) + (The Apache License, Version 2.0) OpenTelemetry Java (io.opentelemetry:opentelemetry-api:1.55.0 - https://github.com/open-telemetry/opentelemetry-java) + (The Apache License, Version 2.0) OpenTelemetry Java (io.opentelemetry:opentelemetry-common:1.55.0 - https://github.com/open-telemetry/opentelemetry-java) + (The Apache License, Version 2.0) OpenTelemetry Java (io.opentelemetry:opentelemetry-context:1.55.0 - https://github.com/open-telemetry/opentelemetry-java) + (The Apache License, Version 2.0) OpenTelemetry Java (io.opentelemetry:opentelemetry-extension-trace-propagators:1.55.0 - https://github.com/open-telemetry/opentelemetry-java) + (The Apache License, Version 2.0) OpenTelemetry Java (io.opentelemetry:opentelemetry-sdk:1.55.0 - https://github.com/open-telemetry/opentelemetry-java) + (The Apache License, Version 2.0) OpenTelemetry Java (io.opentelemetry:opentelemetry-sdk-common:1.55.0 - https://github.com/open-telemetry/opentelemetry-java) + (The Apache License, Version 2.0) OpenTelemetry Java (io.opentelemetry:opentelemetry-sdk-logs:1.55.0 - https://github.com/open-telemetry/opentelemetry-java) + (The Apache License, Version 2.0) OpenTelemetry Java (io.opentelemetry:opentelemetry-sdk-metrics:1.55.0 - https://github.com/open-telemetry/opentelemetry-java) + (The Apache License, Version 2.0) OpenTelemetry Java (io.opentelemetry:opentelemetry-sdk-trace:1.55.0 - https://github.com/open-telemetry/opentelemetry-java) + (Apache 2.0) perfmark:perfmark-api (io.perfmark:perfmark-api:0.26.0 - https://github.com/perfmark/perfmark) + (The Apache Software License, Version 2.0) Core functionality for the Reactor Netty library (io.projectreactor.netty:reactor-netty-core:1.3.6 - https://github.com/reactor/reactor-netty) + (The Apache Software License, Version 2.0) HTTP functionality for the Reactor Netty library (io.projectreactor.netty:reactor-netty-http:1.3.6 - https://github.com/reactor/reactor-netty) + (Apache License, Version 2.0) Non-Blocking Reactive Foundation for the JVM (io.projectreactor:reactor-core:3.8.6 - https://github.com/reactor/reactor-core) + (The Apache Software License, Version 2.0) Prometheus Metrics Config (io.prometheus:prometheus-metrics-config:1.4.3 - http://github.com/prometheus/client_java) + (The Apache Software License, Version 2.0) Prometheus Metrics Core (io.prometheus:prometheus-metrics-core:1.4.3 - http://github.com/prometheus/client_java) + (The Apache Software License, Version 2.0) Prometheus Metrics Exposition Formats (io.prometheus:prometheus-metrics-exposition-formats:1.4.3 - http://github.com/prometheus/client_java) + (The Apache Software License, Version 2.0) Prometheus Metrics Exposition Text Formats (io.prometheus:prometheus-metrics-exposition-textformats:1.4.3 - http://github.com/prometheus/client_java) + (The Apache Software License, Version 2.0) Prometheus Metrics Model (io.prometheus:prometheus-metrics-model:1.4.3 - http://github.com/prometheus/client_java) + (The Apache Software License, Version 2.0) Prometheus Metrics Tracer Common (io.prometheus:prometheus-metrics-tracer-common:1.4.3 - http://github.com/prometheus/client_java) + (Apache License 2.0) swagger-annotations-jakarta (io.swagger.core.v3:swagger-annotations-jakarta:2.2.47 - https://github.com/swagger-api/swagger-core) + (Apache License 2.0) swagger-core-jakarta (io.swagger.core.v3:swagger-core-jakarta:2.2.47 - https://github.com/swagger-api/swagger-core) + (Apache License 2.0) swagger-models-jakarta (io.swagger.core.v3:swagger-models-jakarta:2.2.47 - https://github.com/swagger-api/swagger-core) + (Apache License 2.0) swagger-annotations (io.swagger:swagger-annotations:1.6.16 - https://github.com/swagger-api/swagger-core) + (EDL 1.0) Jakarta Activation API (jakarta.activation:jakarta.activation-api:2.1.4 - https://github.com/jakartaee/jaf-api) + (EPL 2.0) (GPL2 w/ CPE) Jakarta Annotations API (jakarta.annotation:jakarta.annotation-api:3.0.0 - https://projects.eclipse.org/projects/ee4j.ca) + (EPL 2.0) (GPL2 w/ CPE) Jakarta Servlet (jakarta.servlet:jakarta.servlet-api:6.1.0 - https://projects.eclipse.org/projects/ee4j.servlet) + (Apache License 2.0) Jakarta Validation API (jakarta.validation:jakarta.validation-api:3.1.1 - https://beanvalidation.org) + (Eclipse Distribution License - v 1.0) Jakarta XML Binding API (jakarta.xml.bind:jakarta.xml.bind-api:4.0.5 - https://github.com/jakartaee/jaxb-api) + (CDDL + GPLv2 with classpath exception) javax.annotation API (javax.annotation:javax.annotation-api:1.3.2 - http://jcp.org/en/jsr/detail?id=250) + (Apache 2.0) gRPC Spring Boot Starter (net.devh:grpc-common-spring-boot:3.1.0.RELEASE - https://github.com/yidongnan/grpc-spring-boot-starter) + (Apache 2.0) gRPC Spring Boot Starter (net.devh:grpc-server-spring-boot-starter:3.1.0.RELEASE - https://github.com/yidongnan/grpc-spring-boot-starter) + (The Apache Software License, Version 2.0) net.javacrumbs.shedlock:shedlock-core (net.javacrumbs.shedlock:shedlock-core:7.7.0 - http://nexus.sonatype.org/oss-repository-hosting.html) + (The Apache Software License, Version 2.0) net.javacrumbs.shedlock:shedlock-provider-cassandra (net.javacrumbs.shedlock:shedlock-provider-cassandra:7.7.0 - http://nexus.sonatype.org/oss-repository-hosting.html) + (The Apache Software License, Version 2.0) net.javacrumbs.shedlock:shedlock-spring (net.javacrumbs.shedlock:shedlock-spring:7.7.0 - http://nexus.sonatype.org/oss-repository-hosting.html) + (The Apache Software License, Version 2.0) ASM based accessors helper used by json-smart (net.minidev:accessors-smart:2.6.0 - https://urielch.github.io/) + (The Apache Software License, Version 2.0) JSON Small and Fast Parser (net.minidev:json-smart:2.6.0 - https://urielch.github.io/) + (Apache 2) Apache Cassandra Java Driver - core (org.apache.cassandra:java-driver-core:4.19.3 - https://github.com/datastax/java-driver) + (Apache 2) Apache Cassandra Java Driver - guava shaded dep (org.apache.cassandra:java-driver-guava-shaded:4.19.3 - https://github.com/datastax/java-driver) + (Apache 2) Apache Cassandra Java Driver - Metrics - Micrometer (org.apache.cassandra:java-driver-metrics-micrometer:4.19.3 - https://github.com/datastax/java-driver) + (Apache 2) Apache Cassandra Java Driver - query builder (org.apache.cassandra:java-driver-query-builder:4.19.3 - https://github.com/datastax/java-driver) + (Apache-2.0) Apache Commons Collections (org.apache.commons:commons-collections4:4.5.0 - https://commons.apache.org/proper/commons-collections/) + (Apache-2.0) Apache Commons Compress (org.apache.commons:commons-compress:1.28.0 - https://commons.apache.org/proper/commons-compress/) + (Apache-2.0) Apache Commons Lang (org.apache.commons:commons-lang3:3.20.0 - https://commons.apache.org/proper/commons-lang/) + (Apache-2.0) Apache Log4j API (org.apache.logging.log4j:log4j-api:2.25.4 - https://logging.apache.org/log4j/2.x/) + (Apache-2.0) Log4j API to SLF4J Adapter (org.apache.logging.log4j:log4j-to-slf4j:2.25.4 - https://logging.apache.org/log4j/2.x/) + (Apache License, Version 2.0) tomcat-embed-core (org.apache.tomcat.embed:tomcat-embed-core:11.0.22 - https://tomcat.apache.org/) + (Apache License, Version 2.0) tomcat-embed-el (org.apache.tomcat.embed:tomcat-embed-el:11.0.22 - https://tomcat.apache.org/) + (Apache License, Version 2.0) tomcat-embed-websocket (org.apache.tomcat.embed:tomcat-embed-websocket:11.0.22 - https://tomcat.apache.org/) + (Eclipse Public License - v 2.0) AspectJ Weaver (org.aspectj:aspectjweaver:1.9.25.1 - https://www.eclipse.org/aspectj/) + (The Apache Software License, Version 2.0) jose4j (org.bitbucket.b_c:jose4j:0.9.6 - https://bitbucket.org/b_c/jose4j/) + (Bouncy Castle Licence) Bouncy Castle PKIX, CMS, EAC, TSP, PKCS, OCSP, CMP, and CRMF APIs (org.bouncycastle:bcpkix-jdk18on:1.80 - https://www.bouncycastle.org/download/bouncy-castle-java/) + (Bouncy Castle Licence) Bouncy Castle Provider (org.bouncycastle:bcprov-jdk18on:1.84 - https://www.bouncycastle.org/download/bouncy-castle-java/) + (Bouncy Castle Licence) Bouncy Castle ASN.1 Extension and Utility APIs (org.bouncycastle:bcutil-jdk18on:1.80.2 - https://www.bouncycastle.org/download/bouncy-castle-java/) + (MIT license) Animal Sniffer Annotations (org.codehaus.mojo:animal-sniffer-annotations:1.23 - https://www.mojohaus.org/animal-sniffer) + (Public Domain, per Creative Commons CC0) (BSD-2-Clause) HdrHistogram (org.hdrhistogram:HdrHistogram:2.2.2 - http://hdrhistogram.github.io/HdrHistogram/) + (Apache License 2.0) Hibernate Validator Engine (org.hibernate.validator:hibernate-validator:9.0.1.Final - https://hibernate.org/validator) + (Apache License 2.0) JBoss Logging 3 (org.jboss.logging:jboss-logging:3.6.3.Final - https://www.jboss.org) + (Apache-2.0) Kotlin Stdlib (org.jetbrains.kotlin:kotlin-stdlib:2.2.21 - https://kotlinlang.org/) + (Apache-2.0) Kotlin Stdlib Jdk7 (org.jetbrains.kotlin:kotlin-stdlib-jdk7:2.2.21 - https://kotlinlang.org/) + (Apache-2.0) Kotlin Stdlib Jdk8 (org.jetbrains.kotlin:kotlin-stdlib-jdk8:2.2.21 - https://kotlinlang.org/) + (The Apache Software License, Version 2.0) JetBrains Java Annotations (org.jetbrains:annotations:17.0.0 - https://github.com/JetBrains/java-annotations) + (The Apache License, Version 2.0) JSpecify annotations (org.jspecify:jspecify:1.0.0 - http://jspecify.org/) + (Public Domain, per Creative Commons CC0) LatencyUtils (org.latencyutils:LatencyUtils:2.0.3 - http://latencyutils.github.io/LatencyUtils/) + (BSD-3-Clause) asm (org.ow2.asm:asm:9.9 - http://asm.ow2.io/) + (BSD-3-Clause) asm-analysis (org.ow2.asm:asm-analysis:9.9 - http://asm.ow2.io/) + (BSD-3-Clause) asm-commons (org.ow2.asm:asm-commons:9.9 - http://asm.ow2.io/) + (BSD-3-Clause) asm-tree (org.ow2.asm:asm-tree:9.9 - http://asm.ow2.io/) + (BSD-3-Clause) asm-util (org.ow2.asm:asm-util:9.9 - http://asm.ow2.io/) + (MIT-0) reactive-streams (org.reactivestreams:reactive-streams:1.0.4 - http://www.reactive-streams.org/) + (MIT) JUL to SLF4J bridge (org.slf4j:jul-to-slf4j:2.0.18 - http://www.slf4j.org) + (MIT) SLF4J API Module (org.slf4j:slf4j-api:2.0.18 - http://www.slf4j.org) + (The Apache License, Version 2.0) springdoc-openapi-starter-common (org.springdoc:springdoc-openapi-starter-common:3.0.3 - https://springdoc.org/) + (The Apache License, Version 2.0) springdoc-openapi-starter-webmvc-api (org.springdoc:springdoc-openapi-starter-webmvc-api:3.0.3 - https://springdoc.org/) + (Apache License, Version 2.0) spring-boot (org.springframework.boot:spring-boot:4.0.7 - https://spring.io/projects/spring-boot) + (Apache License, Version 2.0) spring-boot-actuator (org.springframework.boot:spring-boot-actuator:4.0.7 - https://spring.io/projects/spring-boot) + (Apache License, Version 2.0) spring-boot-actuator-autoconfigure (org.springframework.boot:spring-boot-actuator-autoconfigure:4.0.7 - https://spring.io/projects/spring-boot) + (Apache License, Version 2.0) spring-boot-autoconfigure (org.springframework.boot:spring-boot-autoconfigure:4.0.7 - https://spring.io/projects/spring-boot) + (Apache License, Version 2.0) spring-boot-cassandra (org.springframework.boot:spring-boot-cassandra:4.0.7 - https://spring.io/projects/spring-boot) + (Apache License, Version 2.0) spring-boot-data-cassandra (org.springframework.boot:spring-boot-data-cassandra:4.0.7 - https://spring.io/projects/spring-boot) + (Apache License, Version 2.0) spring-boot-data-commons (org.springframework.boot:spring-boot-data-commons:4.0.7 - https://spring.io/projects/spring-boot) + (Apache License, Version 2.0) spring-boot-health (org.springframework.boot:spring-boot-health:4.0.7 - https://spring.io/projects/spring-boot) + (Apache License, Version 2.0) spring-boot-http-client (org.springframework.boot:spring-boot-http-client:4.0.7 - https://spring.io/projects/spring-boot) + (Apache License, Version 2.0) spring-boot-http-codec (org.springframework.boot:spring-boot-http-codec:4.0.7 - https://spring.io/projects/spring-boot) + (Apache License, Version 2.0) spring-boot-http-converter (org.springframework.boot:spring-boot-http-converter:4.0.7 - https://spring.io/projects/spring-boot) + (Apache License, Version 2.0) spring-boot-jackson (org.springframework.boot:spring-boot-jackson:4.0.7 - https://spring.io/projects/spring-boot) + (Apache License, Version 2.0) spring-boot-micrometer-metrics (org.springframework.boot:spring-boot-micrometer-metrics:4.0.7 - https://spring.io/projects/spring-boot) + (Apache License, Version 2.0) spring-boot-micrometer-observation (org.springframework.boot:spring-boot-micrometer-observation:4.0.7 - https://spring.io/projects/spring-boot) + (Apache License, Version 2.0) spring-boot-micrometer-tracing (org.springframework.boot:spring-boot-micrometer-tracing:4.0.7 - https://spring.io/projects/spring-boot) + (Apache License, Version 2.0) spring-boot-micrometer-tracing-opentelemetry (org.springframework.boot:spring-boot-micrometer-tracing-opentelemetry:4.0.7 - https://spring.io/projects/spring-boot) + (Apache License, Version 2.0) spring-boot-opentelemetry (org.springframework.boot:spring-boot-opentelemetry:4.0.7 - https://spring.io/projects/spring-boot) + (Apache License, Version 2.0) spring-boot-persistence (org.springframework.boot:spring-boot-persistence:4.0.7 - https://spring.io/projects/spring-boot) + (Apache License, Version 2.0) spring-boot-security (org.springframework.boot:spring-boot-security:4.0.7 - https://spring.io/projects/spring-boot) + (Apache License, Version 2.0) spring-boot-security-oauth2-client (org.springframework.boot:spring-boot-security-oauth2-client:4.0.7 - https://spring.io/projects/spring-boot) + (Apache License, Version 2.0) spring-boot-security-oauth2-resource-server (org.springframework.boot:spring-boot-security-oauth2-resource-server:4.0.7 - https://spring.io/projects/spring-boot) + (Apache License, Version 2.0) spring-boot-servlet (org.springframework.boot:spring-boot-servlet:4.0.7 - https://spring.io/projects/spring-boot) + (Apache License, Version 2.0) spring-boot-starter (org.springframework.boot:spring-boot-starter:4.0.7 - https://spring.io/projects/spring-boot) + (Apache License, Version 2.0) spring-boot-starter-actuator (org.springframework.boot:spring-boot-starter-actuator:4.0.7 - https://spring.io/projects/spring-boot) + (Apache License, Version 2.0) spring-boot-starter-aspectj (org.springframework.boot:spring-boot-starter-aspectj:4.0.7 - https://spring.io/projects/spring-boot) + (Apache License, Version 2.0) spring-boot-starter-data-cassandra (org.springframework.boot:spring-boot-starter-data-cassandra:4.0.7 - https://spring.io/projects/spring-boot) + (Apache License, Version 2.0) spring-boot-starter-jackson (org.springframework.boot:spring-boot-starter-jackson:4.0.7 - https://spring.io/projects/spring-boot) + (Apache License, Version 2.0) spring-boot-starter-logging (org.springframework.boot:spring-boot-starter-logging:4.0.7 - https://spring.io/projects/spring-boot) + (Apache License, Version 2.0) spring-boot-starter-micrometer-metrics (org.springframework.boot:spring-boot-starter-micrometer-metrics:4.0.7 - https://spring.io/projects/spring-boot) + (Apache License, Version 2.0) spring-boot-starter-security (org.springframework.boot:spring-boot-starter-security:4.0.7 - https://spring.io/projects/spring-boot) + (Apache License, Version 2.0) spring-boot-starter-security-oauth2-client (org.springframework.boot:spring-boot-starter-security-oauth2-client:4.0.7 - https://spring.io/projects/spring-boot) + (Apache License, Version 2.0) spring-boot-starter-security-oauth2-resource-server (org.springframework.boot:spring-boot-starter-security-oauth2-resource-server:4.0.7 - https://spring.io/projects/spring-boot) + (Apache License, Version 2.0) spring-boot-starter-tomcat (org.springframework.boot:spring-boot-starter-tomcat:4.0.7 - https://spring.io/projects/spring-boot) + (Apache License, Version 2.0) spring-boot-starter-tomcat-runtime (org.springframework.boot:spring-boot-starter-tomcat-runtime:4.0.7 - https://spring.io/projects/spring-boot) + (Apache License, Version 2.0) spring-boot-starter-validation (org.springframework.boot:spring-boot-starter-validation:4.0.7 - https://spring.io/projects/spring-boot) + (Apache License, Version 2.0) spring-boot-starter-webmvc (org.springframework.boot:spring-boot-starter-webmvc:4.0.7 - https://spring.io/projects/spring-boot) + (Apache License, Version 2.0) spring-boot-tomcat (org.springframework.boot:spring-boot-tomcat:4.0.7 - https://spring.io/projects/spring-boot) + (Apache License, Version 2.0) spring-boot-validation (org.springframework.boot:spring-boot-validation:4.0.7 - https://spring.io/projects/spring-boot) + (Apache License, Version 2.0) spring-boot-web-server (org.springframework.boot:spring-boot-web-server:4.0.7 - https://spring.io/projects/spring-boot) + (Apache License, Version 2.0) spring-boot-webclient (org.springframework.boot:spring-boot-webclient:4.0.7 - https://spring.io/projects/spring-boot) + (Apache License, Version 2.0) spring-boot-webmvc (org.springframework.boot:spring-boot-webmvc:4.0.7 - https://spring.io/projects/spring-boot) + (Apache License, Version 2.0) Spring Cloud Commons (org.springframework.cloud:spring-cloud-commons:5.0.2 - https://projects.spring.io/spring-cloud/spring-cloud-commons/) + (Apache License, Version 2.0) Spring Cloud Context (org.springframework.cloud:spring-cloud-context:5.0.2 - https://projects.spring.io/spring-cloud/spring-cloud-context/) + (Apache License, Version 2.0) spring-cloud-kubernetes-client-autoconfig (org.springframework.cloud:spring-cloud-kubernetes-client-autoconfig:5.0.2 - https://cloud.spring.io/spring-cloud-kubernetes-client-autoconfig) + (Apache License, Version 2.0) spring-cloud-kubernetes-client-config (org.springframework.cloud:spring-cloud-kubernetes-client-config:5.0.2 - https://cloud.spring.io/spring-cloud-kubernetes-client-config) + (Apache License, Version 2.0) spring-cloud-kubernetes-commons (org.springframework.cloud:spring-cloud-kubernetes-commons:5.0.2 - https://cloud.spring.io/spring-cloud-kubernetes-commons) + (Apache License, Version 2.0) spring-cloud-starter (org.springframework.cloud:spring-cloud-starter:5.0.2 - https://projects.spring.io/spring-cloud) + (Apache License, Version 2.0) spring-cloud-starter-bootstrap (org.springframework.cloud:spring-cloud-starter-bootstrap:5.0.2 - https://projects.spring.io/spring-cloud) + (Apache License, Version 2.0) Spring Cloud Kubernetes :: Kubernetes Native Starter :: Config (org.springframework.cloud:spring-cloud-starter-kubernetes-client-config:5.0.2 - https://cloud.spring.io/spring-cloud-starter-kubernetes-client-config) + (Apache License, Version 2.0) Spring Data for Apache Cassandra Core (org.springframework.data:spring-data-cassandra:5.0.6 - https://projects.spring.io/spring-data-cassandra/) + (Apache License, Version 2.0) Spring Data Core (org.springframework.data:spring-data-commons:4.0.6 - https://spring.io/projects/spring-data) + (Apache 2.0) Spring Retry (org.springframework.retry:spring-retry:2.0.13 - https://github.com/spring-projects/spring-retry) + (Apache License, Version 2.0) spring-security-config (org.springframework.security:spring-security-config:7.0.6 - https://spring.io/projects/spring-security) + (Apache License, Version 2.0) spring-security-core (org.springframework.security:spring-security-core:7.0.6 - https://spring.io/projects/spring-security) + (Apache License, Version 2.0) spring-security-crypto (org.springframework.security:spring-security-crypto:7.0.6 - https://spring.io/projects/spring-security) + (Apache License, Version 2.0) spring-security-oauth2-client (org.springframework.security:spring-security-oauth2-client:7.0.6 - https://spring.io/projects/spring-security) + (Apache License, Version 2.0) spring-security-oauth2-core (org.springframework.security:spring-security-oauth2-core:7.0.6 - https://spring.io/projects/spring-security) + (Apache License, Version 2.0) spring-security-oauth2-jose (org.springframework.security:spring-security-oauth2-jose:7.0.6 - https://spring.io/projects/spring-security) + (Apache License, Version 2.0) spring-security-oauth2-resource-server (org.springframework.security:spring-security-oauth2-resource-server:7.0.6 - https://spring.io/projects/spring-security) + (Apache License, Version 2.0) spring-security-web (org.springframework.security:spring-security-web:7.0.6 - https://spring.io/projects/spring-security) + (Apache License, Version 2.0) Spring AOP (org.springframework:spring-aop:7.0.8 - https://github.com/spring-projects/spring-framework) + (Apache License, Version 2.0) Spring Beans (org.springframework:spring-beans:7.0.8 - https://github.com/spring-projects/spring-framework) + (Apache License, Version 2.0) Spring Context (org.springframework:spring-context:7.0.8 - https://github.com/spring-projects/spring-framework) + (Apache License, Version 2.0) Spring Context Support (org.springframework:spring-context-support:7.0.8 - https://github.com/spring-projects/spring-framework) + (Apache License, Version 2.0) Spring Core (org.springframework:spring-core:7.0.8 - https://github.com/spring-projects/spring-framework) + (Apache License, Version 2.0) Spring Expression Language (SpEL) (org.springframework:spring-expression:7.0.8 - https://github.com/spring-projects/spring-framework) + (Apache License, Version 2.0) Spring Transaction (org.springframework:spring-tx:7.0.8 - https://github.com/spring-projects/spring-framework) + (Apache License, Version 2.0) Spring Web (org.springframework:spring-web:7.0.8 - https://github.com/spring-projects/spring-framework) + (Apache License, Version 2.0) Spring WebFlux (org.springframework:spring-webflux:7.0.8 - https://github.com/spring-projects/spring-framework) + (Apache License, Version 2.0) Spring Web MVC (org.springframework:spring-webmvc:7.0.8 - https://github.com/spring-projects/spring-framework) + (Apache License, Version 2.0) SnakeYAML (org.yaml:snakeyaml:2.5 - https://bitbucket.org/snakeyaml/snakeyaml) + (Apache License, Version 2.0) AWS Java SDK :: Annotations (software.amazon.awssdk:annotations:2.40.1 - https://aws.amazon.com/sdkforjava) + (Apache License, Version 2.0) AWS Java SDK :: Checksums (software.amazon.awssdk:checksums:2.40.1 - https://aws.amazon.com/sdkforjava) + (Apache License, Version 2.0) AWS Java SDK :: Checksums SPI (software.amazon.awssdk:checksums-spi:2.40.1 - https://aws.amazon.com/sdkforjava) + (Apache License, Version 2.0) AWS Java SDK :: Endpoints SPI (software.amazon.awssdk:endpoints-spi:2.40.1 - https://aws.amazon.com/sdkforjava) + (Apache License, Version 2.0) AWS Java SDK :: HTTP Auth AWS (software.amazon.awssdk:http-auth-aws:2.40.1 - https://aws.amazon.com/sdkforjava) + (Apache License, Version 2.0) AWS Java SDK :: HTTP Auth SPI (software.amazon.awssdk:http-auth-spi:2.40.1 - https://aws.amazon.com/sdkforjava) + (Apache License, Version 2.0) AWS Java SDK :: HTTP Client Interface (software.amazon.awssdk:http-client-spi:2.40.1 - https://aws.amazon.com/sdkforjava) + (Apache License, Version 2.0) AWS Java SDK :: Identity SPI (software.amazon.awssdk:identity-spi:2.40.1 - https://aws.amazon.com/sdkforjava) + (Apache License, Version 2.0) AWS Java SDK :: Core :: Protocols :: Json Utils (software.amazon.awssdk:json-utils:2.40.1 - https://aws.amazon.com/sdkforjava) + (Apache License, Version 2.0) AWS Java SDK :: Metrics SPI (software.amazon.awssdk:metrics-spi:2.40.1 - https://aws.amazon.com/sdkforjava) + (Apache License, Version 2.0) AWS Java SDK :: Profiles (software.amazon.awssdk:profiles:2.40.1 - https://aws.amazon.com/sdkforjava) + (Apache License, Version 2.0) AWS Java SDK :: Regions (software.amazon.awssdk:regions:2.40.1 - https://aws.amazon.com/sdkforjava) + (Apache License, Version 2.0) AWS Java SDK :: Retries (software.amazon.awssdk:retries:2.40.1 - https://aws.amazon.com/sdkforjava) + (Apache License, Version 2.0) AWS Java SDK :: Retries API (software.amazon.awssdk:retries-spi:2.40.1 - https://aws.amazon.com/sdkforjava) + (Apache License, Version 2.0) AWS Java SDK :: SDK Core (software.amazon.awssdk:sdk-core:2.40.1 - https://aws.amazon.com/sdkforjava) + (Apache License, Version 2.0) AWS Java SDK :: Third Party :: Jackson-core (software.amazon.awssdk:third-party-jackson-core:2.40.1 - https://aws.amazon.com/sdkforjava) + (Apache License, Version 2.0) AWS Java SDK :: Utilities (software.amazon.awssdk:utils:2.40.1 - https://aws.amazon.com/sdkforjava) + (The Apache Software License, Version 2.0) Jackson-core (tools.jackson.core:jackson-core:3.1.4 - https://github.com/FasterXML/jackson-core) + (The Apache Software License, Version 2.0) jackson-databind (tools.jackson.core:jackson-databind:3.1.4 - https://github.com/FasterXML/jackson) + (The Apache Software License, Version 2.0) Jackson module: Blackbird (tools.jackson.module:jackson-module-blackbird:3.1.4 - https://github.com/FasterXML/jackson-modules-base) diff --git a/src/control-plane-services/cloud-tasks/local_env/cassandra/cassandra.yaml b/src/control-plane-services/cloud-tasks/local_env/cassandra/cassandra.yaml new file mode 100644 index 000000000..7e5c60f7b --- /dev/null +++ b/src/control-plane-services/cloud-tasks/local_env/cassandra/cassandra.yaml @@ -0,0 +1,1424 @@ +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +# +# 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. +# Cassandra storage config YAML + +# NOTE: +# See https://cassandra.apache.org/doc/latest/configuration/ for +# full explanations of configuration directives +# /NOTE + +# The name of the cluster. This is mainly used to prevent machines in +# one logical cluster from joining another. +cluster_name: 'Test Cluster' + +# This defines the number of tokens randomly assigned to this node on the ring +# The more tokens, relative to other nodes, the larger the proportion of data +# that this node will store. You probably want all nodes to have the same number +# of tokens assuming they have equal hardware capability. +# +# If you leave this unspecified, Cassandra will use the default of 1 token for legacy compatibility, +# and will use the initial_token as described below. +# +# Specifying initial_token will override this setting on the node's initial start, +# on subsequent starts, this setting will apply even if initial token is set. +# +num_tokens: 256 + +# Triggers automatic allocation of num_tokens tokens for this node. The allocation +# algorithm attempts to choose tokens in a way that optimizes replicated load over +# the nodes in the datacenter for the replica factor. +# +# The load assigned to each node will be close to proportional to its number of +# vnodes. +# +# Only supported with the Murmur3Partitioner. + +# Replica factor is determined via the replication strategy used by the specified +# keyspace. +# allocate_tokens_for_keyspace: KEYSPACE + +# Replica factor is explicitly set, regardless of keyspace or datacenter. +# This is the replica factor within the datacenter, like NTS. +# allocate_tokens_for_local_replication_factor: 3 + +# initial_token allows you to specify tokens manually. While you can use it with +# vnodes (num_tokens > 1, above) -- in which case you should provide a +# comma-separated list -- it's primarily used when adding nodes to legacy clusters +# that do not have vnodes enabled. +# initial_token: + +# May either be "true" or "false" to enable globally +hinted_handoff_enabled: true + +# When hinted_handoff_enabled is true, a black list of data centers that will not +# perform hinted handoff +# hinted_handoff_disabled_datacenters: +# - DC1 +# - DC2 + +# this defines the maximum amount of time a dead host will have hints +# generated. After it has been dead this long, new hints for it will not be +# created until it has been seen alive and gone down again. +max_hint_window_in_ms: 10800000 # 3 hours + +# Maximum throttle in KBs per second, per delivery thread. This will be +# reduced proportionally to the number of nodes in the cluster. (If there +# are two nodes in the cluster, each delivery thread will use the maximum +# rate; if there are three, each will throttle to half of the maximum, +# since we expect two nodes to be delivering hints simultaneously.) +hinted_handoff_throttle_in_kb: 1024 + +# Number of threads with which to deliver hints; +# Consider increasing this number when you have multi-dc deployments, since +# cross-dc handoff tends to be slower +max_hints_delivery_threads: 2 + +# Directory where Cassandra should store hints. +# If not set, the default directory is $CASSANDRA_HOME/data/hints. +# hints_directory: /var/lib/cassandra/hints + +# How often hints should be flushed from the internal buffers to disk. +# Will *not* trigger fsync. +hints_flush_period_in_ms: 10000 + +# Maximum size for a single hints file, in megabytes. +max_hints_file_size_in_mb: 128 + +# Compression to apply to the hint files. If omitted, hints files +# will be written uncompressed. LZ4, Snappy, and Deflate compressors +# are supported. +#hints_compression: +# - class_name: LZ4Compressor +# parameters: +# - + +# Maximum throttle in KBs per second, total. This will be +# reduced proportionally to the number of nodes in the cluster. +batchlog_replay_throttle_in_kb: 1024 + +# Authentication backend, implementing IAuthenticator; used to identify users +# Out of the box, Cassandra provides org.apache.cassandra.auth.{AllowAllAuthenticator, +# PasswordAuthenticator}. +# +# - AllowAllAuthenticator performs no checks - set it to disable authentication. +# - PasswordAuthenticator relies on username/password pairs to authenticate +# users. It keeps usernames and hashed passwords in system_auth.roles table. +# Please increase system_auth keyspace replication factor if you use this authenticator. +# If using PasswordAuthenticator, CassandraRoleManager must also be used (see below) +authenticator: PasswordAuthenticator + +# Authorization backend, implementing IAuthorizer; used to limit access/provide permissions +# Out of the box, Cassandra provides org.apache.cassandra.auth.{AllowAllAuthorizer, +# CassandraAuthorizer}. +# +# - AllowAllAuthorizer allows any action to any user - set it to disable authorization. +# - CassandraAuthorizer stores permissions in system_auth.role_permissions table. Please +# increase system_auth keyspace replication factor if you use this authorizer. +authorizer: AllowAllAuthorizer + +# Part of the Authentication & Authorization backend, implementing IRoleManager; used +# to maintain grants and memberships between roles. +# Out of the box, Cassandra provides org.apache.cassandra.auth.CassandraRoleManager, +# which stores role information in the system_auth keyspace. Most functions of the +# IRoleManager require an authenticated login, so unless the configured IAuthenticator +# actually implements authentication, most of this functionality will be unavailable. +# +# - CassandraRoleManager stores role data in the system_auth keyspace. Please +# increase system_auth keyspace replication factor if you use this role manager. +role_manager: CassandraRoleManager + +# Network authorization backend, implementing INetworkAuthorizer; used to restrict user +# access to certain DCs +# Out of the box, Cassandra provides org.apache.cassandra.auth.{AllowAllNetworkAuthorizer, +# CassandraNetworkAuthorizer}. +# +# - AllowAllNetworkAuthorizer allows access to any DC to any user - set it to disable authorization. +# - CassandraNetworkAuthorizer stores permissions in system_auth.network_permissions table. Please +# increase system_auth keyspace replication factor if you use this authorizer. +network_authorizer: AllowAllNetworkAuthorizer + +# Validity period for roles cache (fetching granted roles can be an expensive +# operation depending on the role manager, CassandraRoleManager is one example) +# Granted roles are cached for authenticated sessions in AuthenticatedUser and +# after the period specified here, become eligible for (async) reload. +# Defaults to 2000, set to 0 to disable caching entirely. +# Will be disabled automatically for AllowAllAuthenticator. +roles_validity_in_ms: 2000 + +# Refresh interval for roles cache (if enabled). +# After this interval, cache entries become eligible for refresh. Upon next +# access, an async reload is scheduled and the old value returned until it +# completes. If roles_validity_in_ms is non-zero, then this must be +# also. +# Defaults to the same value as roles_validity_in_ms. +# roles_update_interval_in_ms: 2000 + +# Validity period for permissions cache (fetching permissions can be an +# expensive operation depending on the authorizer, CassandraAuthorizer is +# one example). Defaults to 2000, set to 0 to disable. +# Will be disabled automatically for AllowAllAuthorizer. +permissions_validity_in_ms: 2000 + +# Refresh interval for permissions cache (if enabled). +# After this interval, cache entries become eligible for refresh. Upon next +# access, an async reload is scheduled and the old value returned until it +# completes. If permissions_validity_in_ms is non-zero, then this must be +# also. +# Defaults to the same value as permissions_validity_in_ms. +# permissions_update_interval_in_ms: 2000 + +# Validity period for credentials cache. This cache is tightly coupled to +# the provided PasswordAuthenticator implementation of IAuthenticator. If +# another IAuthenticator implementation is configured, this cache will not +# be automatically used and so the following settings will have no effect. +# Please note, credentials are cached in their encrypted form, so while +# activating this cache may reduce the number of queries made to the +# underlying table, it may not bring a significant reduction in the +# latency of individual authentication attempts. +# Defaults to 2000, set to 0 to disable credentials caching. +credentials_validity_in_ms: 2000 + +# Refresh interval for credentials cache (if enabled). +# After this interval, cache entries become eligible for refresh. Upon next +# access, an async reload is scheduled and the old value returned until it +# completes. If credentials_validity_in_ms is non-zero, then this must be +# also. +# Defaults to the same value as credentials_validity_in_ms. +# credentials_update_interval_in_ms: 2000 + +# The partitioner is responsible for distributing groups of rows (by +# partition key) across nodes in the cluster. The partitioner can NOT be +# changed without reloading all data. If you are adding nodes or upgrading, +# you should set this to the same partitioner that you are currently using. +# +# The default partitioner is the Murmur3Partitioner. Older partitioners +# such as the RandomPartitioner, ByteOrderedPartitioner, and +# OrderPreservingPartitioner have been included for backward compatibility only. +# For new clusters, you should NOT change this value. +# +partitioner: org.apache.cassandra.dht.Murmur3Partitioner + +# Directories where Cassandra should store data on disk. If multiple +# directories are specified, Cassandra will spread data evenly across +# them by partitioning the token ranges. +# If not set, the default directory is $CASSANDRA_HOME/data/data. +# data_file_directories: +# - /var/lib/cassandra/data + +# commit log. when running on magnetic HDD, this should be a +# separate spindle than the data directories. +# If not set, the default directory is $CASSANDRA_HOME/data/commitlog. +# commitlog_directory: /var/lib/cassandra/commitlog + +# Enable / disable CDC functionality on a per-node basis. This modifies the logic used +# for write path allocation rejection (standard: never reject. cdc: reject Mutation +# containing a CDC-enabled table if at space limit in cdc_raw_directory). +cdc_enabled: false + +# CommitLogSegments are moved to this directory on flush if cdc_enabled: true and the +# segment contains mutations for a CDC-enabled table. This should be placed on a +# separate spindle than the data directories. If not set, the default directory is +# $CASSANDRA_HOME/data/cdc_raw. +# cdc_raw_directory: /var/lib/cassandra/cdc_raw + +# Policy for data disk failures: +# +# die +# shut down gossip and client transports and kill the JVM for any fs errors or +# single-sstable errors, so the node can be replaced. +# +# stop_paranoid +# shut down gossip and client transports even for single-sstable errors, +# kill the JVM for errors during startup. +# +# stop +# shut down gossip and client transports, leaving the node effectively dead, but +# can still be inspected via JMX, kill the JVM for errors during startup. +# +# best_effort +# stop using the failed disk and respond to requests based on +# remaining available sstables. This means you WILL see obsolete +# data at CL.ONE! +# +# ignore +# ignore fatal errors and let requests fail, as in pre-1.2 Cassandra +disk_failure_policy: stop + +# Policy for commit disk failures: +# +# die +# shut down the node and kill the JVM, so the node can be replaced. +# +# stop +# shut down the node, leaving the node effectively dead, but +# can still be inspected via JMX. +# +# stop_commit +# shutdown the commit log, letting writes collect but +# continuing to service reads, as in pre-2.0.5 Cassandra +# +# ignore +# ignore fatal errors and let the batches fail +commit_failure_policy: stop + +# Maximum size of the native protocol prepared statement cache +# +# Valid values are either "auto" (omitting the value) or a value greater 0. +# +# Note that specifying a too large value will result in long running GCs and possbily +# out-of-memory errors. Keep the value at a small fraction of the heap. +# +# If you constantly see "prepared statements discarded in the last minute because +# cache limit reached" messages, the first step is to investigate the root cause +# of these messages and check whether prepared statements are used correctly - +# i.e. use bind markers for variable parts. +# +# Do only change the default value, if you really have more prepared statements than +# fit in the cache. In most cases it is not neccessary to change this value. +# Constantly re-preparing statements is a performance penalty. +# +# Default value ("auto") is 1/256th of the heap or 10MB, whichever is greater +prepared_statements_cache_size_mb: + +# Maximum size of the key cache in memory. +# +# Each key cache hit saves 1 seek and each row cache hit saves 2 seeks at the +# minimum, sometimes more. The key cache is fairly tiny for the amount of +# time it saves, so it's worthwhile to use it at large numbers. +# The row cache saves even more time, but must contain the entire row, +# so it is extremely space-intensive. It's best to only use the +# row cache if you have hot rows or static rows. +# +# NOTE: if you reduce the size, you may not get you hottest keys loaded on startup. +# +# Default value is empty to make it "auto" (min(5% of Heap (in MB), 100MB)). Set to 0 to disable key cache. +key_cache_size_in_mb: + +# Duration in seconds after which Cassandra should +# save the key cache. Caches are saved to saved_caches_directory as +# specified in this configuration file. +# +# Saved caches greatly improve cold-start speeds, and is relatively cheap in +# terms of I/O for the key cache. Row cache saving is much more expensive and +# has limited use. +# +# Default is 14400 or 4 hours. +key_cache_save_period: 14400 + +# Number of keys from the key cache to save +# Disabled by default, meaning all keys are going to be saved +# key_cache_keys_to_save: 100 + +# Row cache implementation class name. Available implementations: +# +# org.apache.cassandra.cache.OHCProvider +# Fully off-heap row cache implementation (default). +# +# org.apache.cassandra.cache.SerializingCacheProvider +# This is the row cache implementation availabile +# in previous releases of Cassandra. +# row_cache_class_name: org.apache.cassandra.cache.OHCProvider + +# Maximum size of the row cache in memory. +# Please note that OHC cache implementation requires some additional off-heap memory to manage +# the map structures and some in-flight memory during operations before/after cache entries can be +# accounted against the cache capacity. This overhead is usually small compared to the whole capacity. +# Do not specify more memory that the system can afford in the worst usual situation and leave some +# headroom for OS block level cache. Do never allow your system to swap. +# +# Default value is 0, to disable row caching. +row_cache_size_in_mb: 0 + +# Duration in seconds after which Cassandra should save the row cache. +# Caches are saved to saved_caches_directory as specified in this configuration file. +# +# Saved caches greatly improve cold-start speeds, and is relatively cheap in +# terms of I/O for the key cache. Row cache saving is much more expensive and +# has limited use. +# +# Default is 0 to disable saving the row cache. +row_cache_save_period: 0 + +# Number of keys from the row cache to save. +# Specify 0 (which is the default), meaning all keys are going to be saved +# row_cache_keys_to_save: 100 + +# Maximum size of the counter cache in memory. +# +# Counter cache helps to reduce counter locks' contention for hot counter cells. +# In case of RF = 1 a counter cache hit will cause Cassandra to skip the read before +# write entirely. With RF > 1 a counter cache hit will still help to reduce the duration +# of the lock hold, helping with hot counter cell updates, but will not allow skipping +# the read entirely. Only the local (clock, count) tuple of a counter cell is kept +# in memory, not the whole counter, so it's relatively cheap. +# +# NOTE: if you reduce the size, you may not get you hottest keys loaded on startup. +# +# Default value is empty to make it "auto" (min(2.5% of Heap (in MB), 50MB)). Set to 0 to disable counter cache. +# NOTE: if you perform counter deletes and rely on low gcgs, you should disable the counter cache. +counter_cache_size_in_mb: + +# Duration in seconds after which Cassandra should +# save the counter cache (keys only). Caches are saved to saved_caches_directory as +# specified in this configuration file. +# +# Default is 7200 or 2 hours. +counter_cache_save_period: 7200 + +# Number of keys from the counter cache to save +# Disabled by default, meaning all keys are going to be saved +# counter_cache_keys_to_save: 100 + +# saved caches +# If not set, the default directory is $CASSANDRA_HOME/data/saved_caches. +# saved_caches_directory: /var/lib/cassandra/saved_caches + +# commitlog_sync may be either "periodic", "group", or "batch." +# +# When in batch mode, Cassandra won't ack writes until the commit log +# has been flushed to disk. Each incoming write will trigger the flush task. +# commitlog_sync_batch_window_in_ms is a deprecated value. Previously it had +# almost no value, and is being removed. +# +# commitlog_sync_batch_window_in_ms: 2 +# +# group mode is similar to batch mode, where Cassandra will not ack writes +# until the commit log has been flushed to disk. The difference is group +# mode will wait up to commitlog_sync_group_window_in_ms between flushes. +# +# commitlog_sync_group_window_in_ms: 1000 +# +# the default option is "periodic" where writes may be acked immediately +# and the CommitLog is simply synced every commitlog_sync_period_in_ms +# milliseconds. +commitlog_sync: periodic +commitlog_sync_period_in_ms: 10000 + +# When in periodic commitlog mode, the number of milliseconds to block writes +# while waiting for a slow disk flush to complete. +# periodic_commitlog_sync_lag_block_in_ms: + +# The size of the individual commitlog file segments. A commitlog +# segment may be archived, deleted, or recycled once all the data +# in it (potentially from each columnfamily in the system) has been +# flushed to sstables. +# +# The default size is 32, which is almost always fine, but if you are +# archiving commitlog segments (see commitlog_archiving.properties), +# then you probably want a finer granularity of archiving; 8 or 16 MB +# is reasonable. +# Max mutation size is also configurable via max_mutation_size_in_kb setting in +# cassandra.yaml. The default is half the size commitlog_segment_size_in_mb * 1024. +# This should be positive and less than 2048. +# +# NOTE: If max_mutation_size_in_kb is set explicitly then commitlog_segment_size_in_mb must +# be set to at least twice the size of max_mutation_size_in_kb / 1024 +# +commitlog_segment_size_in_mb: 32 + +# Compression to apply to the commit log. If omitted, the commit log +# will be written uncompressed. LZ4, Snappy, and Deflate compressors +# are supported. +# commitlog_compression: +# - class_name: LZ4Compressor +# parameters: +# - + +# Compression to apply to SSTables as they flush for compressed tables. +# Note that tables without compression enabled do not respect this flag. +# +# As high ratio compressors like LZ4HC, Zstd, and Deflate can potentially +# block flushes for too long, the default is to flush with a known fast +# compressor in those cases. Options are: +# +# none : Flush without compressing blocks but while still doing checksums. +# fast : Flush with a fast compressor. If the table is already using a +# fast compressor that compressor is used. +# table: Always flush with the same compressor that the table uses. This +# was the pre 4.0 behavior. +# +# flush_compression: fast + +# any class that implements the SeedProvider interface and has a +# constructor that takes a Map of parameters will do. +seed_provider: + # Addresses of hosts that are deemed contact points. + # Cassandra nodes use this list of hosts to find each other and learn + # the topology of the ring. You must change this if you are running + # multiple nodes! + - class_name: org.apache.cassandra.locator.SimpleSeedProvider + parameters: + # seeds is actually a comma-delimited list of addresses. + # Ex: ",," + - seeds: "localhost" + +# For workloads with more data than can fit in memory, Cassandra's +# bottleneck will be reads that need to fetch data from +# disk. "concurrent_reads" should be set to (16 * number_of_drives) in +# order to allow the operations to enqueue low enough in the stack +# that the OS and drives can reorder them. Same applies to +# "concurrent_counter_writes", since counter writes read the current +# values before incrementing and writing them back. +# +# On the other hand, since writes are almost never IO bound, the ideal +# number of "concurrent_writes" is dependent on the number of cores in +# your system; (8 * number_of_cores) is a good rule of thumb. +concurrent_reads: 32 +concurrent_writes: 32 +concurrent_counter_writes: 32 + +# For materialized view writes, as there is a read involved, so this should +# be limited by the less of concurrent reads or concurrent writes. +concurrent_materialized_view_writes: 32 + +# Maximum memory to use for inter-node and client-server networking buffers. +# +# Defaults to the smaller of 1/16 of heap or 128MB. This pool is allocated off-heap, +# so is in addition to the memory allocated for heap. The cache also has on-heap +# overhead which is roughly 128 bytes per chunk (i.e. 0.2% of the reserved size +# if the default 64k chunk size is used). +# Memory is only allocated when needed. +# networking_cache_size_in_mb: 128 + +# Enable the sstable chunk cache. The chunk cache will store recently accessed +# sections of the sstable in-memory as uncompressed buffers. +# file_cache_enabled: false + +# Maximum memory to use for sstable chunk cache and buffer pooling. +# 32MB of this are reserved for pooling buffers, the rest is used for chunk cache +# that holds uncompressed sstable chunks. +# Defaults to the smaller of 1/4 of heap or 512MB. This pool is allocated off-heap, +# so is in addition to the memory allocated for heap. The cache also has on-heap +# overhead which is roughly 128 bytes per chunk (i.e. 0.2% of the reserved size +# if the default 64k chunk size is used). +# Memory is only allocated when needed. +# file_cache_size_in_mb: 512 + +# Flag indicating whether to allocate on or off heap when the sstable buffer +# pool is exhausted, that is when it has exceeded the maximum memory +# file_cache_size_in_mb, beyond which it will not cache buffers but allocate on request. + +# buffer_pool_use_heap_if_exhausted: true + +# The strategy for optimizing disk read +# Possible values are: +# ssd (for solid state disks, the default) +# spinning (for spinning disks) +# disk_optimization_strategy: ssd + +# Total permitted memory to use for memtables. Cassandra will stop +# accepting writes when the limit is exceeded until a flush completes, +# and will trigger a flush based on memtable_cleanup_threshold +# If omitted, Cassandra will set both to 1/4 the size of the heap. +# memtable_heap_space_in_mb: 2048 +# memtable_offheap_space_in_mb: 2048 + +# memtable_cleanup_threshold is deprecated. The default calculation +# is the only reasonable choice. See the comments on memtable_flush_writers +# for more information. +# +# Ratio of occupied non-flushing memtable size to total permitted size +# that will trigger a flush of the largest memtable. Larger mct will +# mean larger flushes and hence less compaction, but also less concurrent +# flush activity which can make it difficult to keep your disks fed +# under heavy write load. +# +# memtable_cleanup_threshold defaults to 1 / (memtable_flush_writers + 1) +# memtable_cleanup_threshold: 0.11 + +# Specify the way Cassandra allocates and manages memtable memory. +# Options are: +# +# heap_buffers +# on heap nio buffers +# +# offheap_buffers +# off heap (direct) nio buffers +# +# offheap_objects +# off heap objects +memtable_allocation_type: heap_buffers + +# Limit memory usage for Merkle tree calculations during repairs. The default +# is 1/16th of the available heap. The main tradeoff is that smaller trees +# have less resolution, which can lead to over-streaming data. If you see heap +# pressure during repairs, consider lowering this, but you cannot go below +# one megabyte. If you see lots of over-streaming, consider raising +# this or using subrange repair. +# +# For more details see https://issues.apache.org/jira/browse/CASSANDRA-14096. +# +# repair_session_space_in_mb: + +# Total space to use for commit logs on disk. +# +# If space gets above this value, Cassandra will flush every dirty CF +# in the oldest segment and remove it. So a small total commitlog space +# will tend to cause more flush activity on less-active columnfamilies. +# +# The default value is the smaller of 8192, and 1/4 of the total space +# of the commitlog volume. +# +# commitlog_total_space_in_mb: 8192 + +# This sets the number of memtable flush writer threads per disk +# as well as the total number of memtables that can be flushed concurrently. +# These are generally a combination of compute and IO bound. +# +# Memtable flushing is more CPU efficient than memtable ingest and a single thread +# can keep up with the ingest rate of a whole server on a single fast disk +# until it temporarily becomes IO bound under contention typically with compaction. +# At that point you need multiple flush threads. At some point in the future +# it may become CPU bound all the time. +# +# You can tell if flushing is falling behind using the MemtablePool.BlockedOnAllocation +# metric which should be 0, but will be non-zero if threads are blocked waiting on flushing +# to free memory. +# +# memtable_flush_writers defaults to two for a single data directory. +# This means that two memtables can be flushed concurrently to the single data directory. +# If you have multiple data directories the default is one memtable flushing at a time +# but the flush will use a thread per data directory so you will get two or more writers. +# +# Two is generally enough to flush on a fast disk [array] mounted as a single data directory. +# Adding more flush writers will result in smaller more frequent flushes that introduce more +# compaction overhead. +# +# There is a direct tradeoff between number of memtables that can be flushed concurrently +# and flush size and frequency. More is not better you just need enough flush writers +# to never stall waiting for flushing to free memory. +# +#memtable_flush_writers: 2 + +# Total space to use for change-data-capture logs on disk. +# +# If space gets above this value, Cassandra will throw WriteTimeoutException +# on Mutations including tables with CDC enabled. A CDCCompactor is responsible +# for parsing the raw CDC logs and deleting them when parsing is completed. +# +# The default value is the min of 4096 mb and 1/8th of the total space +# of the drive where cdc_raw_directory resides. +# cdc_total_space_in_mb: 4096 + +# When we hit our cdc_raw limit and the CDCCompactor is either running behind +# or experiencing backpressure, we check at the following interval to see if any +# new space for cdc-tracked tables has been made available. Default to 250ms +# cdc_free_space_check_interval_ms: 250 + +# A fixed memory pool size in MB for for SSTable index summaries. If left +# empty, this will default to 5% of the heap size. If the memory usage of +# all index summaries exceeds this limit, SSTables with low read rates will +# shrink their index summaries in order to meet this limit. However, this +# is a best-effort process. In extreme conditions Cassandra may need to use +# more than this amount of memory. +index_summary_capacity_in_mb: + +# How frequently index summaries should be resampled. This is done +# periodically to redistribute memory from the fixed-size pool to sstables +# proportional their recent read rates. Setting to -1 will disable this +# process, leaving existing index summaries at their current sampling level. +index_summary_resize_interval_in_minutes: 60 + +# Whether to, when doing sequential writing, fsync() at intervals in +# order to force the operating system to flush the dirty +# buffers. Enable this to avoid sudden dirty buffer flushing from +# impacting read latencies. Almost always a good idea on SSDs; not +# necessarily on platters. +trickle_fsync: false +trickle_fsync_interval_in_kb: 10240 + +# TCP port, for commands and data +# For security reasons, you should not expose this port to the internet. Firewall it if needed. +storage_port: 7000 + +# SSL port, for legacy encrypted communication. This property is unused unless enabled in +# server_encryption_options (see below). As of cassandra 4.0, this property is deprecated +# as a single port can be used for either/both secure and insecure connections. +# For security reasons, you should not expose this port to the internet. Firewall it if needed. +ssl_storage_port: 7001 + +# Address or interface to bind to and tell other Cassandra nodes to connect to. +# You _must_ change this if you want multiple nodes to be able to communicate! +# +# Set listen_address OR listen_interface, not both. +# +# Leaving it blank leaves it up to InetAddress.getLocalHost(). This +# will always do the Right Thing _if_ the node is properly configured +# (hostname, name resolution, etc), and the Right Thing is to use the +# address associated with the hostname (it might not be). If unresolvable +# it will fall back to InetAddress.getLoopbackAddress(), which is wrong for production systems. +# +# Setting listen_address to 0.0.0.0 is always wrong. +# +listen_address: localhost + +# Set listen_address OR listen_interface, not both. Interfaces must correspond +# to a single address, IP aliasing is not supported. +# listen_interface: eth0 + +# If you choose to specify the interface by name and the interface has an ipv4 and an ipv6 address +# you can specify which should be chosen using listen_interface_prefer_ipv6. If false the first ipv4 +# address will be used. If true the first ipv6 address will be used. Defaults to false preferring +# ipv4. If there is only one address it will be selected regardless of ipv4/ipv6. +# listen_interface_prefer_ipv6: false + +# Address to broadcast to other Cassandra nodes +# Leaving this blank will set it to the same value as listen_address +broadcast_address: localhost + +# When using multiple physical network interfaces, set this +# to true to listen on broadcast_address in addition to +# the listen_address, allowing nodes to communicate in both +# interfaces. +# Ignore this property if the network configuration automatically +# routes between the public and private networks such as EC2. +# listen_on_broadcast_address: false + +# Internode authentication backend, implementing IInternodeAuthenticator; +# used to allow/disallow connections from peer nodes. +# internode_authenticator: org.apache.cassandra.auth.AllowAllInternodeAuthenticator + +# Whether to start the native transport server. +# The address on which the native transport is bound is defined by rpc_address. +start_native_transport: true +# port for the CQL native transport to listen for clients on +# For security reasons, you should not expose this port to the internet. Firewall it if needed. +native_transport_port: 9042 +# Enabling native transport encryption in client_encryption_options allows you to either use +# encryption for the standard port or to use a dedicated, additional port along with the unencrypted +# standard native_transport_port. +# Enabling client encryption and keeping native_transport_port_ssl disabled will use encryption +# for native_transport_port. Setting native_transport_port_ssl to a different value +# from native_transport_port will use encryption for native_transport_port_ssl while +# keeping native_transport_port unencrypted. +# native_transport_port_ssl: 9142 +# The maximum threads for handling requests (note that idle threads are stopped +# after 30 seconds so there is not corresponding minimum setting). +# native_transport_max_threads: 128 +# +# The maximum size of allowed frame. Frame (requests) larger than this will +# be rejected as invalid. The default is 256MB. If you're changing this parameter, +# you may want to adjust max_value_size_in_mb accordingly. This should be positive and less than 2048. +# native_transport_max_frame_size_in_mb: 256 + +# If checksumming is enabled as a protocol option, denotes the size of the chunks into which frame +# are bodies will be broken and checksummed. +# native_transport_frame_block_size_in_kb: 32 + +# The maximum number of concurrent client connections. +# The default is -1, which means unlimited. +# native_transport_max_concurrent_connections: -1 + +# The maximum number of concurrent client connections per source ip. +# The default is -1, which means unlimited. +# native_transport_max_concurrent_connections_per_ip: -1 + +# Controls whether Cassandra honors older, yet currently supported, protocol versions. +# The default is true, which means all supported protocols will be honored. +native_transport_allow_older_protocols: true + +# Controls when idle client connections are closed. Idle connections are ones that had neither reads +# nor writes for a time period. +# +# Clients may implement heartbeats by sending OPTIONS native protocol message after a timeout, which +# will reset idle timeout timer on the server side. To close idle client connections, corresponding +# values for heartbeat intervals have to be set on the client side. +# +# Idle connection timeouts are disabled by default. +# native_transport_idle_timeout_in_ms: 60000 + +# The address or interface to bind the native transport server to. +# +# Set rpc_address OR rpc_interface, not both. +# +# Leaving rpc_address blank has the same effect as on listen_address +# (i.e. it will be based on the configured hostname of the node). +# +# Note that unlike listen_address, you can specify 0.0.0.0, but you must also +# set broadcast_rpc_address to a value other than 0.0.0.0. +# +# For security reasons, you should not expose this port to the internet. Firewall it if needed. +rpc_address: 0.0.0.0 + +# Set rpc_address OR rpc_interface, not both. Interfaces must correspond +# to a single address, IP aliasing is not supported. +# rpc_interface: eth1 + +# If you choose to specify the interface by name and the interface has an ipv4 and an ipv6 address +# you can specify which should be chosen using rpc_interface_prefer_ipv6. If false the first ipv4 +# address will be used. If true the first ipv6 address will be used. Defaults to false preferring +# ipv4. If there is only one address it will be selected regardless of ipv4/ipv6. +# rpc_interface_prefer_ipv6: false + +# RPC address to broadcast to drivers and other Cassandra nodes. This cannot +# be set to 0.0.0.0. If left blank, this will be set to the value of +# rpc_address. If rpc_address is set to 0.0.0.0, broadcast_rpc_address must +# be set. +broadcast_rpc_address: localhost + +# enable or disable keepalive on rpc/native connections +rpc_keepalive: true + +# Uncomment to set socket buffer size for internode communication +# Note that when setting this, the buffer size is limited by net.core.wmem_max +# and when not setting it it is defined by net.ipv4.tcp_wmem +# See also: +# /proc/sys/net/core/wmem_max +# /proc/sys/net/core/rmem_max +# /proc/sys/net/ipv4/tcp_wmem +# /proc/sys/net/ipv4/tcp_wmem +# and 'man tcp' +# internode_send_buff_size_in_bytes: + +# Uncomment to set socket buffer size for internode communication +# Note that when setting this, the buffer size is limited by net.core.wmem_max +# and when not setting it it is defined by net.ipv4.tcp_wmem +# internode_recv_buff_size_in_bytes: + +# Set to true to have Cassandra create a hard link to each sstable +# flushed or streamed locally in a backups/ subdirectory of the +# keyspace data. Removing these links is the operator's +# responsibility. +incremental_backups: false + +# Whether or not to take a snapshot before each compaction. Be +# careful using this option, since Cassandra won't clean up the +# snapshots for you. Mostly useful if you're paranoid when there +# is a data format change. +snapshot_before_compaction: false + +# Whether or not a snapshot is taken of the data before keyspace truncation +# or dropping of column families. The STRONGLY advised default of true +# should be used to provide data safety. If you set this flag to false, you will +# lose data on truncation or drop. +auto_snapshot: true + +# Granularity of the collation index of rows within a partition. +# Increase if your rows are large, or if you have a very large +# number of rows per partition. The competing goals are these: +# +# - a smaller granularity means more index entries are generated +# and looking up rows withing the partition by collation column +# is faster +# - but, Cassandra will keep the collation index in memory for hot +# rows (as part of the key cache), so a larger granularity means +# you can cache more hot rows +column_index_size_in_kb: 64 + +# Per sstable indexed key cache entries (the collation index in memory +# mentioned above) exceeding this size will not be held on heap. +# This means that only partition information is held on heap and the +# index entries are read from disk. +# +# Note that this size refers to the size of the +# serialized index information and not the size of the partition. +column_index_cache_size_in_kb: 2 + +# Number of simultaneous compactions to allow, NOT including +# validation "compactions" for anti-entropy repair. Simultaneous +# compactions can help preserve read performance in a mixed read/write +# workload, by mitigating the tendency of small sstables to accumulate +# during a single long running compactions. The default is usually +# fine and if you experience problems with compaction running too +# slowly or too fast, you should look at +# compaction_throughput_mb_per_sec first. +# +# concurrent_compactors defaults to the smaller of (number of disks, +# number of cores), with a minimum of 2 and a maximum of 8. +# +# If your data directories are backed by SSD, you should increase this +# to the number of cores. +#concurrent_compactors: 1 + +# Number of simultaneous repair validations to allow. If not set or set to +# a value less than 1, it defaults to the value of concurrent_compactors. +# To set a value greeater than concurrent_compactors at startup, the system +# property cassandra.allow_unlimited_concurrent_validations must be set to +# true. To dynamically resize to a value > concurrent_compactors on a running +# node, first call the bypassConcurrentValidatorsLimit method on the +# org.apache.cassandra.db:type=StorageService mbean +# concurrent_validations: 0 + +# Number of simultaneous materialized view builder tasks to allow. +concurrent_materialized_view_builders: 1 + +# Throttles compaction to the given total throughput across the entire +# system. The faster you insert data, the faster you need to compact in +# order to keep the sstable count down, but in general, setting this to +# 16 to 32 times the rate you are inserting data is more than sufficient. +# Setting this to 0 disables throttling. Note that this accounts for all types +# of compaction, including validation compaction (building Merkle trees +# for repairs). +compaction_throughput_mb_per_sec: 64 + +# When compacting, the replacement sstable(s) can be opened before they +# are completely written, and used in place of the prior sstables for +# any range that has been written. This helps to smoothly transfer reads +# between the sstables, reducing page cache churn and keeping hot rows hot +sstable_preemptive_open_interval_in_mb: 50 + +# When enabled, permits Cassandra to zero-copy stream entire eligible +# SSTables between nodes, including every component. +# This speeds up the network transfer significantly subject to +# throttling specified by stream_throughput_outbound_megabits_per_sec. +# Enabling this will reduce the GC pressure on sending and receiving node. +# When unset, the default is enabled. While this feature tries to keep the +# disks balanced, it cannot guarantee it. This feature will be automatically +# disabled if internode encryption is enabled. Currently this can be used with +# Leveled Compaction. Once CASSANDRA-14586 is fixed other compaction strategies +# will benefit as well when used in combination with CASSANDRA-6696. +# stream_entire_sstables: true + +# Throttles all outbound streaming file transfers on this node to the +# given total throughput in Mbps. This is necessary because Cassandra does +# mostly sequential IO when streaming data during bootstrap or repair, which +# can lead to saturating the network connection and degrading rpc performance. +# When unset, the default is 200 Mbps or 25 MB/s. +# stream_throughput_outbound_megabits_per_sec: 200 + +# Throttles all streaming file transfer between the datacenters, +# this setting allows users to throttle inter dc stream throughput in addition +# to throttling all network stream traffic as configured with +# stream_throughput_outbound_megabits_per_sec +# When unset, the default is 200 Mbps or 25 MB/s +# inter_dc_stream_throughput_outbound_megabits_per_sec: 200 + +# How long the coordinator should wait for read operations to complete. +# Lowest acceptable value is 10 ms. +read_request_timeout_in_ms: 5000 +# How long the coordinator should wait for seq or index scans to complete. +# Lowest acceptable value is 10 ms. +range_request_timeout_in_ms: 10000 +# How long the coordinator should wait for writes to complete. +# Lowest acceptable value is 10 ms. +write_request_timeout_in_ms: 2000 +# How long the coordinator should wait for counter writes to complete. +# Lowest acceptable value is 10 ms. +counter_write_request_timeout_in_ms: 5000 +# How long a coordinator should continue to retry a CAS operation +# that contends with other proposals for the same row. +# Lowest acceptable value is 10 ms. +cas_contention_timeout_in_ms: 1000 +# How long the coordinator should wait for truncates to complete +# (This can be much longer, because unless auto_snapshot is disabled +# we need to flush first so we can snapshot before removing the data.) +# Lowest acceptable value is 10 ms. +truncate_request_timeout_in_ms: 60000 +# The default timeout for other, miscellaneous operations. +# Lowest acceptable value is 10 ms. +request_timeout_in_ms: 10000 + +# Defensive settings for protecting Cassandra from true network partitions. +# See (CASSANDRA-14358) for details. +# +# The amount of time to wait for internode tcp connections to establish. +# internode_tcp_connect_timeout_in_ms = 2000 +# +# The amount of time unacknowledged data is allowed on a connection before we throw out the connection +# Note this is only supported on Linux + epoll, and it appears to behave oddly above a setting of 30000 +# (it takes much longer than 30s) as of Linux 4.12. If you want something that high set this to 0 +# which picks up the OS default and configure the net.ipv4.tcp_retries2 sysctl to be ~8. +# internode_tcp_user_timeout_in_ms = 30000 + +# The maximum continuous period a connection may be unwritable in application space +# internode_application_timeout_in_ms = 30000 + +# Global, per-endpoint and per-connection limits imposed on messages queued for delivery to other nodes +# and waiting to be processed on arrival from other nodes in the cluster. These limits are applied to the on-wire +# size of the message being sent or received. +# +# The basic per-link limit is consumed in isolation before any endpoint or global limit is imposed. +# Each node-pair has three links: urgent, small and large. So any given node may have a maximum of +# N*3*(internode_application_send_queue_capacity_in_bytes+internode_application_receive_queue_capacity_in_bytes) +# messages queued without any coordination between them although in practice, with token-aware routing, only RF*tokens +# nodes should need to communicate with significant bandwidth. +# +# The per-endpoint limit is imposed on all messages exceeding the per-link limit, simultaneously with the global limit, +# on all links to or from a single node in the cluster. +# The global limit is imposed on all messages exceeding the per-link limit, simultaneously with the per-endpoint limit, +# on all links to or from any node in the cluster. +# +# internode_application_send_queue_capacity_in_bytes: 4194304 #4MiB +# internode_application_send_queue_reserve_endpoint_capacity_in_bytes: 134217728 #128MiB +# internode_application_send_queue_reserve_global_capacity_in_bytes: 536870912 #512MiB +# internode_application_receive_queue_capacity_in_bytes: 4194304 #4MiB +# internode_application_receive_queue_reserve_endpoint_capacity_in_bytes: 134217728 #128MiB +# internode_application_receive_queue_reserve_global_capacity_in_bytes: 536870912 #512MiB + + +# How long before a node logs slow queries. Select queries that take longer than +# this timeout to execute, will generate an aggregated log message, so that slow queries +# can be identified. Set this value to zero to disable slow query logging. +slow_query_log_timeout_in_ms: 500 + +# Enable operation timeout information exchange between nodes to accurately +# measure request timeouts. If disabled, replicas will assume that requests +# were forwarded to them instantly by the coordinator, which means that +# under overload conditions we will waste that much extra time processing +# already-timed-out requests. +# +# Warning: It is generally assumed that users have setup NTP on their clusters, and that clocks are modestly in sync, +# since this is a requirement for general correctness of last write wins. +#cross_node_timeout: true + +# Set keep-alive period for streaming +# This node will send a keep-alive message periodically with this period. +# If the node does not receive a keep-alive message from the peer for +# 2 keep-alive cycles the stream session times out and fail +# Default value is 300s (5 minutes), which means stalled stream +# times out in 10 minutes by default +# streaming_keep_alive_period_in_secs: 300 + +# Limit number of connections per host for streaming +# Increase this when you notice that joins are CPU-bound rather that network +# bound (for example a few nodes with big files). +# streaming_connections_per_host: 1 + + +# phi value that must be reached for a host to be marked down. +# most users should never need to adjust this. +# phi_convict_threshold: 8 + +# endpoint_snitch -- Set this to a class that implements +# IEndpointSnitch. The snitch has two functions: +# +# - it teaches Cassandra enough about your network topology to route +# requests efficiently +# - it allows Cassandra to spread replicas around your cluster to avoid +# correlated failures. It does this by grouping machines into +# "datacenters" and "racks." Cassandra will do its best not to have +# more than one replica on the same "rack" (which may not actually +# be a physical location) +# +# CASSANDRA WILL NOT ALLOW YOU TO SWITCH TO AN INCOMPATIBLE SNITCH +# ONCE DATA IS INSERTED INTO THE CLUSTER. This would cause data loss. +# This means that if you start with the default SimpleSnitch, which +# locates every node on "rack1" in "datacenter1", your only options +# if you need to add another datacenter are GossipingPropertyFileSnitch +# (and the older PFS). From there, if you want to migrate to an +# incompatible snitch like Ec2Snitch you can do it by adding new nodes +# under Ec2Snitch (which will locate them in a new "datacenter") and +# decommissioning the old ones. +# +# Out of the box, Cassandra provides: +# +# SimpleSnitch: +# Treats Strategy order as proximity. This can improve cache +# locality when disabling read repair. Only appropriate for +# single-datacenter deployments. +# +# GossipingPropertyFileSnitch +# This should be your go-to snitch for production use. The rack +# and datacenter for the local node are defined in +# cassandra-rackdc.properties and propagated to other nodes via +# gossip. If cassandra-topology.properties exists, it is used as a +# fallback, allowing migration from the PropertyFileSnitch. +# +# PropertyFileSnitch: +# Proximity is determined by rack and data center, which are +# explicitly configured in cassandra-topology.properties. +# +# Ec2Snitch: +# Appropriate for EC2 deployments in a single Region. Loads Region +# and Availability Zone information from the EC2 API. The Region is +# treated as the datacenter, and the Availability Zone as the rack. +# Only private IPs are used, so this will not work across multiple +# Regions. +# +# Ec2MultiRegionSnitch: +# Uses public IPs as broadcast_address to allow cross-region +# connectivity. (Thus, you should set seed addresses to the public +# IP as well.) You will need to open the storage_port or +# ssl_storage_port on the public IP firewall. (For intra-Region +# traffic, Cassandra will switch to the private IP after +# establishing a connection.) +# +# RackInferringSnitch: +# Proximity is determined by rack and data center, which are +# assumed to correspond to the 3rd and 2nd octet of each node's IP +# address, respectively. Unless this happens to match your +# deployment conventions, this is best used as an example of +# writing a custom Snitch class and is provided in that spirit. +# +# You can use a custom Snitch by setting this to the full class name +# of the snitch, which will be assumed to be on your classpath. +endpoint_snitch: SimpleSnitch + +# controls how often to perform the more expensive part of host score +# calculation +dynamic_snitch_update_interval_in_ms: 100 +# controls how often to reset all host scores, allowing a bad host to +# possibly recover +dynamic_snitch_reset_interval_in_ms: 600000 +# if set greater than zero, this will allow +# 'pinning' of replicas to hosts in order to increase cache capacity. +# The badness threshold will control how much worse the pinned host has to be +# before the dynamic snitch will prefer other replicas over it. This is +# expressed as a double which represents a percentage. Thus, a value of +# 0.2 means Cassandra would continue to prefer the static snitch values +# until the pinned host was 20% worse than the fastest. +dynamic_snitch_badness_threshold: 0.1 + +# Configure server-to-server internode encryption +# +# JVM and netty defaults for supported SSL socket protocols and cipher suites can +# be replaced using custom encryption options. This is not recommended +# unless you have policies in place that dictate certain settings, or +# need to disable vulnerable ciphers or protocols in case the JVM cannot +# be updated. +# +# FIPS compliant settings can be configured at JVM level and should not +# involve changing encryption settings here: +# https://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/FIPS.html +# +# **NOTE** this default configuration is an insecure configuration. If you need to +# enable server-to-server encryption generate server keystores (and truststores for mutual +# authentication) per: +# http://download.oracle.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html#CreateKeystore +# Then perform the following configuration changes: +# +# Step 1: Set internode_encryption= and explicitly set optional=true. Restart all nodes +# +# Step 2: Set optional=false (or remove it) and if you generated truststores and want to use mutual +# auth set require_client_auth=true. Restart all nodes +server_encryption_options: + # On outbound connections, determine which type of peers to securely connect to. + # The available options are : + # none : Do not encrypt outgoing connections + # dc : Encrypt connections to peers in other datacenters but not within datacenters + # rack : Encrypt connections to peers in other racks but not within racks + # all : Always use encrypted connections + internode_encryption: none + # When set to true, encrypted and unencrypted connections are allowed on the storage_port + # This should _only be true_ while in unencrypted or transitional operation + # optional defaults to true if internode_encryption is none + # optional: true + # If enabled, will open up an encrypted listening socket on ssl_storage_port. Should only be used + # during upgrade to 4.0; otherwise, set to false. + enable_legacy_ssl_storage_port: false + # Set to a valid keystore if internode_encryption is dc, rack or all + keystore: conf/.keystore + keystore_password: cassandra + # Verify peer server certificates + require_client_auth: false + # Set to a valid trustore if require_client_auth is true + truststore: conf/.truststore + truststore_password: cassandra + # Verify that the host name in the certificate matches the connected host + require_endpoint_verification: false + # More advanced defaults: + # protocol: TLS + # store_type: JKS + # cipher_suites: [ + # TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + # TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, + # TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_RSA_WITH_AES_128_GCM_SHA256, TLS_RSA_WITH_AES_128_CBC_SHA, + # TLS_RSA_WITH_AES_256_CBC_SHA + # ] + +# Configure client-to-server encryption. +# +# **NOTE** this default configuration is an insecure configuration. If you need to +# enable client-to-server encryption generate server keystores (and truststores for mutual +# authentication) per: +# http://download.oracle.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html#CreateKeystore +# Then perform the following configuration changes: +# +# Step 1: Set enabled=true and explicitly set optional=true. Restart all nodes +# +# Step 2: Set optional=false (or remove it) and if you generated truststores and want to use mutual +# auth set require_client_auth=true. Restart all nodes +client_encryption_options: + # Enable client-to-server encryption + enabled: true + # When set to true, encrypted and unencrypted connections are allowed on the native_transport_port + # This should _only be true_ while in unencrypted or transitional operation + # optional defaults to true when enabled is false, and false when enabled is true. + optional: true + # Set keystore and keystore_password to valid keystores if enabled is true + keystore: /etc/cassandra/keystore.node0 + keystore_password: 123456 + # Verify client certificates + require_client_auth: true + # Set trustore and truststore_password if require_client_auth is true + truststore: /etc/cassandra/truststore.node0 + truststore_password: 123456 + # More advanced defaults: + protocol: TLS + algorithm: SunX509 + store_type: JKS + cipher_suites: [ TLS_RSA_WITH_AES_256_CBC_SHA ] + +# internode_compression controls whether traffic between nodes is +# compressed. +# Can be: +# +# all +# all traffic is compressed +# +# dc +# traffic between different datacenters is compressed +# +# none +# nothing is compressed. +internode_compression: dc + +# Enable or disable tcp_nodelay for inter-dc communication. +# Disabling it will result in larger (but fewer) network packets being sent, +# reducing overhead from the TCP protocol itself, at the cost of increasing +# latency if you block for cross-datacenter responses. +inter_dc_tcp_nodelay: false + +# TTL for different trace types used during logging of the repair process. +tracetype_query_ttl: 86400 +tracetype_repair_ttl: 604800 + +# If unset, all GC Pauses greater than gc_log_threshold_in_ms will log at +# INFO level +# UDFs (user defined functions) are disabled by default. +# As of Cassandra 3.0 there is a sandbox in place that should prevent execution of evil code. +enable_user_defined_functions: false + +# Enables scripted UDFs (JavaScript UDFs). +# Java UDFs are always enabled, if enable_user_defined_functions is true. +# Enable this option to be able to use UDFs with "language javascript" or any custom JSR-223 provider. +# This option has no effect, if enable_user_defined_functions is false. +enable_scripted_user_defined_functions: false + +# The default Windows kernel timer and scheduling resolution is 15.6ms for power conservation. +# Lowering this value on Windows can provide much tighter latency and better throughput, however +# some virtualized environments may see a negative performance impact from changing this setting +# below their system default. The sysinternals 'clockres' tool can confirm your system's default +# setting. +windows_timer_interval: 1 + + +# Enables encrypting data at-rest (on disk). Different key providers can be plugged in, but the default reads from +# a JCE-style keystore. A single keystore can hold multiple keys, but the one referenced by +# the "key_alias" is the only key that will be used for encrypt opertaions; previously used keys +# can still (and should!) be in the keystore and will be used on decrypt operations +# (to handle the case of key rotation). +# +# It is strongly recommended to download and install Java Cryptography Extension (JCE) +# Unlimited Strength Jurisdiction Policy Files for your version of the JDK. +# (current link: http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html) +# +# Currently, only the following file types are supported for transparent data encryption, although +# more are coming in future cassandra releases: commitlog, hints +transparent_data_encryption_options: + enabled: false + chunk_length_kb: 64 + cipher: AES/CBC/PKCS5Padding + key_alias: testing:1 + # CBC IV length for AES needs to be 16 bytes (which is also the default size) + # iv_length: 16 + key_provider: + - class_name: org.apache.cassandra.security.JKSKeyProvider + parameters: + - keystore: conf/.keystore + keystore_password: cassandra + store_type: JCEKS + key_password: cassandra + + +##################### +# SAFETY THRESHOLDS # +##################### + +# When executing a scan, within or across a partition, we need to keep the +# tombstones seen in memory so we can return them to the coordinator, which +# will use them to make sure other replicas also know about the deleted rows. +# With workloads that generate a lot of tombstones, this can cause performance +# problems and even exaust the server heap. +# (http://www.datastax.com/dev/blog/cassandra-anti-patterns-queues-and-queue-like-datasets) +# Adjust the thresholds here if you understand the dangers and want to +# scan more tombstones anyway. These thresholds may also be adjusted at runtime +# using the StorageService mbean. +tombstone_warn_threshold: 1000 +tombstone_failure_threshold: 100000 + +# Filtering and secondary index queries at read consistency levels above ONE/LOCAL_ONE use a +# mechanism called replica filtering protection to ensure that results from stale replicas do +# not violate consistency. (See CASSANDRA-8272 and CASSANDRA-15907 for more details.) This +# mechanism materializes replica results by partition on-heap at the coordinator. The more possibly +# stale results returned by the replicas, the more rows materialized during the query. +replica_filtering_protection: + # These thresholds exist to limit the damage severely out-of-date replicas can cause during these + # queries. They limit the number of rows from all replicas individual index and filtering queries + # can materialize on-heap to return correct results at the desired read consistency level. + # + # "cached_replica_rows_warn_threshold" is the per-query threshold at which a warning will be logged. + # "cached_replica_rows_fail_threshold" is the per-query threshold at which the query will fail. + # + # These thresholds may also be adjusted at runtime using the StorageService mbean. + # + # If the failure threshold is breached, it is likely that either the current page/fetch size + # is too large or one or more replicas is severely out-of-sync and in need of repair. + cached_rows_warn_threshold: 2000 + cached_rows_fail_threshold: 32000 + +# Log WARN on any multiple-partition batch size exceeding this value. 5kb per batch by default. +# Caution should be taken on increasing the size of this threshold as it can lead to node instability. +batch_size_warn_threshold_in_kb: 5 + +# Fail any multiple-partition batch exceeding this value. 50kb (10x warn threshold) by default. +batch_size_fail_threshold_in_kb: 50 + +# Log WARN on any batches not of type LOGGED than span across more partitions than this limit +unlogged_batch_across_partitions_warn_threshold: 10 + +# Log a warning when compacting partitions larger than this value +compaction_large_partition_warning_threshold_mb: 100 + +# GC Pauses greater than 200 ms will be logged at INFO level +# This threshold can be adjusted to minimize logging if necessary +# gc_log_threshold_in_ms: 200 + +# GC Pauses greater than gc_warn_threshold_in_ms will be logged at WARN level +# Adjust the threshold based on your application throughput requirement. Setting to 0 +# will deactivate the feature. +# gc_warn_threshold_in_ms: 1000 + +# Maximum size of any value in SSTables. Safety measure to detect SSTable corruption +# early. Any value size larger than this threshold will result into marking an SSTable +# as corrupted. This should be positive and less than 2048. +# max_value_size_in_mb: 256 + +# Coalescing Strategies # +# Coalescing multiples messages turns out to significantly boost message processing throughput (think doubling or more). +# On bare metal, the floor for packet processing throughput is high enough that many applications won't notice, but in +# virtualized environments, the point at which an application can be bound by network packet processing can be +# surprisingly low compared to the throughput of task processing that is possible inside a VM. It's not that bare metal +# doesn't benefit from coalescing messages, it's that the number of packets a bare metal network interface can process +# is sufficient for many applications such that no load starvation is experienced even without coalescing. +# There are other benefits to coalescing network messages that are harder to isolate with a simple metric like messages +# per second. By coalescing multiple tasks together, a network thread can process multiple messages for the cost of one +# trip to read from a socket, and all the task submission work can be done at the same time reducing context switching +# and increasing cache friendliness of network message processing. +# See CASSANDRA-8692 for details. + +# Strategy to use for coalescing messages in OutboundTcpConnection. +# Can be fixed, movingaverage, timehorizon, disabled (default). +# You can also specify a subclass of CoalescingStrategies.CoalescingStrategy by name. +# otc_coalescing_strategy: DISABLED + +# How many microseconds to wait for coalescing. For fixed strategy this is the amount of time after the first +# message is received before it will be sent with any accompanying messages. For moving average this is the +# maximum amount of time that will be waited as well as the interval at which messages must arrive on average +# for coalescing to be enabled. +# otc_coalescing_window_us: 200 + +# Do not try to coalesce messages if we already got that many messages. This should be more than 2 and less than 128. +# otc_coalescing_enough_coalesced_messages: 8 + +# How many milliseconds to wait between two expiration runs on the backlog (queue) of the OutboundTcpConnection. +# Expiration is done if messages are piling up in the backlog. Droppable messages are expired to free the memory +# taken by expired messages. The interval should be between 0 and 1000, and in most installations the default value +# will be appropriate. A smaller value could potentially expire messages slightly sooner at the expense of more CPU +# time and queue contention while iterating the backlog of messages. +# An interval of 0 disables any wait time, which is the behavior of former Cassandra versions. +# +# otc_backlog_expiration_interval_ms: 200 + +# Track a metric per keyspace indicating whether replication achieved the ideal consistency +# level for writes without timing out. This is different from the consistency level requested by +# each write which may be lower in order to facilitate availability. +# ideal_consistency_level: EACH_QUORUM + +# Automatically upgrade sstables after upgrade - if there is no ordinary compaction to do, the +# oldest non-upgraded sstable will get upgraded to the latest version +# automatic_sstable_upgrade: false +# Limit the number of concurrent sstable upgrades +# max_concurrent_automatic_sstable_upgrades: 1 + +# Audit logging - Logs every incoming CQL command request, authentication to a node. See the docs +# on audit_logging for full details about the various configuration options. +audit_logging_options: + enabled: false + logger: + - class_name: BinAuditLogger + # audit_logs_dir: + # included_keyspaces: + # excluded_keyspaces: system, system_schema, system_virtual_schema + # included_categories: + # excluded_categories: + # included_users: + # excluded_users: + # roll_cycle: HOURLY + # block: true + # max_queue_weight: 268435456 # 256 MiB + # max_log_size: 17179869184 # 16 GiB + ## archive command is "/path/to/script.sh %path" where %path is replaced with the file being rolled: + # archive_command: + # max_archive_retries: 10 + + + # default options for full query logging - these can be overridden from command line when executing + # nodetool enablefullquerylog + #full_query_logging_options: + # log_dir: + # roll_cycle: HOURLY + # block: true + # max_queue_weight: 268435456 # 256 MiB + # max_log_size: 17179869184 # 16 GiB + ## archive command is "/path/to/script.sh %path" where %path is replaced with the file being rolled: + # archive_command: + # max_archive_retries: 10 + +# validate tombstones on reads and compaction +# can be either "disabled", "warn" or "exception" +# corrupted_tombstone_strategy: disabled + +# Diagnostic Events # +# If enabled, diagnostic events can be helpful for troubleshooting operational issues. Emitted events contain details +# on internal state and temporal relationships across events, accessible by clients via JMX. +diagnostic_events_enabled: false + +# Use native transport TCP message coalescing. If on upgrade to 4.0 you found your throughput decreasing, and in +# particular you run an old kernel or have very fewer client connections, this option might be worth evaluating. +#native_transport_flush_in_batches_legacy: false + +# Enable tracking of repaired state of data during reads and comparison between replicas +# Mismatches between the repaired sets of replicas can be characterized as either confirmed +# or unconfirmed. In this context, unconfirmed indicates that the presence of pending repair +# sessions, unrepaired partition tombstones, or some other condition means that the disparity +# cannot be considered conclusive. Confirmed mismatches should be a trigger for investigation +# as they may be indicative of corruption or data loss. +# There are separate flags for range vs partition reads as single partition reads are only tracked +# when CL > 1 and a digest mismatch occurs. Currently, range queries don't use digests so if +# enabled for range reads, all range reads will include repaired data tracking. As this adds +# some overhead, operators may wish to disable it whilst still enabling it for partition reads +repaired_data_tracking_for_range_reads_enabled: false +repaired_data_tracking_for_partition_reads_enabled: false +# If false, only confirmed mismatches will be reported. If true, a separate metric for unconfirmed +# mismatches will also be recorded. This is to avoid potential signal:noise issues are unconfirmed +# mismatches are less actionable than confirmed ones. +report_unconfirmed_repaired_data_mismatches: false + +######################### +# EXPERIMENTAL FEATURES # +######################### + +# Enables materialized view creation on this node. +# Materialized views are considered experimental and are not recommended for production use. +enable_materialized_views: false + +# Enables SASI index creation on this node. +# SASI indexes are considered experimental and are not recommended for production use. +enable_sasi_indexes: false + +# Enables creation of transiently replicated keyspaces on this node. +# Transient replication is experimental and is not recommended for production use. +enable_transient_replication: false diff --git a/src/control-plane-services/cloud-tasks/local_env/cassandra/entrypoint.sh b/src/control-plane-services/cloud-tasks/local_env/cassandra/entrypoint.sh new file mode 100755 index 000000000..445d01a1d --- /dev/null +++ b/src/control-plane-services/cloud-tasks/local_env/cassandra/entrypoint.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +# +# 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. +cd /docker-entrypoint-initdb.d || exit 1 +while ! cqlsh -e 'describe cluster' -u cassandra -p cassandra >/dev/null 2>&1; do sleep 6; done +echo "Cassandra cluster ready: executing cql scripts found in docker-entrypoint-initdb.d" +for f in $(find . -type f -name "*.cql" -print | sort); do + echo "running $f" + cqlsh -f "$f" -u cassandra -p cassandra + echo "$f executed" +done +echo "Cassandra init scripts executed" diff --git a/src/control-plane-services/cloud-tasks/local_env/cassandra/keystore.node0 b/src/control-plane-services/cloud-tasks/local_env/cassandra/keystore.node0 new file mode 100644 index 0000000000000000000000000000000000000000..d71c880ef7b124566e4b6e5383f1cd1e6a0fff89 GIT binary patch literal 2244 zcmchYS5Om(8imtnp(+Fgq!$5ElhB(qAxN(xD@{70VFN5EMIk7?NQsa{N@xN`niN44 zkbsm+@1b4=%$EL3XH!Z}o*{J8+yH}s*C4>WR_-6T;;0s{7*w5~hQB~|-I5sCCp6f~Z77{7r zMazE##c4)cvGF=2O&0NLT^|*Oz33Rf4VUPkK;=igrXk=>LydbT7EA*;mD#S*m{VO& zm)yF6J#D)OX~=NWa<)SKInbL+CE`4bZHQ3MRTbYRIqyx++XB^1QLZ4x^_DbusUGan zR9d|BWrI*l4C*6P?Q04h)7+auC2xOUFe(dPxQ1~(QcHhUY0dG0m%HQo7ZuOM;=1W4 z{=4qcxWUZc9B2Z|#Qks_Oqfqq@nsPNQ+QI5@bnorGfnwQ;44ZpN*) zl5o&>uw`p=s?T_X)<^20$Q(`2<&$)}Mnud)8MPEy&uM#<^<}EoPN+yAMlNgG_kLdf zRibI@{9W7BR(<^j@1O^R@!y2Uo$}vTZyk=!O0l+ZQTfIE-swM?Lk5nSSV_3Nt$CNs zge@rp`|O22svk7?N1t}IH?@EjX@s~-?6kyAy@yo$lbR3%6u$e*PbO7A!Ej&Srar8< zvp6CJ7iI3Zw`sHPjhRrmLlm9YE|!bUT66LF92n)-R#+2%S5=2WPsxiV-U8-zvF)LF zK2%@uT(X^gUoh-;tq$JHOOvr$9q=2@FCi)H6AuP1dU+J+t=k}YV}|c}uFO!>>8~>U z$)j#~%Masd!a)c%k3|q|BCwX8bqP=S7D?%B+}UUOAWA83A|?cq#v%&l{i1~U%(gYR z;}xw$QzGRa+B7?=PmH$;lUbX$22{kpU`^R*wNc}{x?ZaHd7s94?p!jl?q(WZd_28@ zp#`xY(rejl@Yj+^3QfTY5j|Qc{PsFI(-l%Ykuq&E=cK+%iQ`j3o3BfHdql_uEu|h$ zlu8}=B)h$e@CUZHm!G)GkKn^oP%HsSB4Z5*3pJM~ksY#^T8gE)wBsqH8}zVH z@BEu{D>>)NJC8)@?GDX`o^Xu2os=5=M;p6hd>)m+-FG+^NsbanQXb_++nH8GbQzi? z&O2P>Db9XKT}10S1*A65lRMcERkyhuPi5sed#Mb1k&OfL#os zha+b6^(-Sc;YUA8o_oAf6<9ebcDPFaJb;k;(`K}PU~@MiS1Z#kT+%I|*wwiuE313k z!g(R{KxNt%R{ZYSg}mq6(x`EQMBY#ii&?BpE%bf0at&h?JoKe;>ycWK!duQ0i89<%LU&hLY1GB>Uhj?BBb1=bAEH9RL7F!m;4Ta4hIv z0T=`Xfgo3iN!oBuW;Xd)=h=WH>-_7G-X7JIZmIv^DNU&8tmVfl$b ze+yFQh z2nAt*KtTE36t(w0*^vT48IZ$tTFi1IB?LEVNlL}6vEra=ESO04IYqy(%q&{GCNWnD zzUTUtjW?CjGHnJdomHKLm~VFU5s!x|?Wz&4Ym`x6Um$U5xX((=2d?Kfn(w+%hAZS3 zWRtsK5><4RReR?)I@}(#km{n&aU&|G@F<(+P=oi57Gw+Tu6pr}Lxo&Y!zW_fZ66}4 zhYAo8T6JAHw14%|xWgw5-)JQx)JgWVYu(|wH_@?#30njeCwgpN_wWjM`HgG9hM+7# zO3oQdrD?8449h}?Q0TIQ^Me`&tA32c*LHp`w02*i_=9rk8&6MF!_ktIjS0KCL!z)D z2n+-Oi^SogaN)C#2y;RBA$(M;q|bV}z8R;FJ=*H!*M*rdEJq%m8f*&b+jnFKF{2^`f@7sA%A6snxwk)0v@bV-aTiQ!wKP^yY{W~u7~x(J=+Zu& zDBMrW%rTA6+F@k%K*G(^bf)n27_+f1u$ZLbKhfArRRJ`WFh2Q=teokdkBB_8 zJAg4q>E2V94{JOhZW9X)KUs13m8!het<`y7_g(1~GEcv|FqPcE=d|qjjOk{(N3Wmy z+^p%^pg%h#ZbX@HCWONI8(Pfrhknj|7KKWmT4S98A4j=XoLDS>^lY{pfMM|Kyf(l% PwxT#e=ixo6%B;Tt!4>C3 literal 0 HcmV?d00001 diff --git a/src/control-plane-services/cloud-tasks/local_env/cassandra/schema/0001_initial_schema.cql b/src/control-plane-services/cloud-tasks/local_env/cassandra/schema/0001_initial_schema.cql new file mode 100644 index 000000000..54bfb10f6 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/local_env/cassandra/schema/0001_initial_schema.cql @@ -0,0 +1,125 @@ +-- SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +-- SPDX-License-Identifier: Apache-2.0 +-- +-- 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. +DROP KEYSPACE IF EXISTS nvct; + +CREATE KEYSPACE IF NOT EXISTS nvct WITH REPLICATION = {'class' : 'SimpleStrategy', 'replication_factor' : 1 }; + +USE nvct; + +// UDT for model. +CREATE TYPE IF NOT EXISTS model_udt ( + name TEXT, + version TEXT, + url TEXT +); + +// UDT for resource +CREATE TYPE IF NOT EXISTS resource_udt ( + name TEXT, + version TEXT, + url TEXT +); + +CREATE TYPE IF NOT EXISTS gpu_spec_udt( + instance_type TEXT, + gpu TEXT, + backend TEXT, + configuration TEXT, + clusters FROZEN>, + regions FROZEN>, + attributes FROZEN>, + max_request_concurrency INT, + helm_validation_policy TEXT +); + +CREATE TYPE IF NOT EXISTS health_udt ( + sis_request_id UUID, + gpu TEXT, + backend TEXT, + instance_type TEXT, + error TEXT +); + +CREATE TYPE IF NOT EXISTS telemetries_udt +( + logs_telemetry_id UUID, + metrics_telemetry_id UUID, + traces_telemetry_id UUID, +); + +CREATE TABLE IF NOT EXISTS tasks_v2 +( + nca_id TEXT, + task_id UUID, + name TEXT, + description TEXT, + tags FROZEN>, + container_image TEXT, + container_args TEXT, + container_environment TEXT, + models FROZEN>, + resources FROZEN>, + gpu_spec gpu_spec_udt, + max_runtime_duration DURATION, + max_queued_duration DURATION, + terminal_grace_period_duration DURATION, + result_handling_strategy TEXT, + helm_chart TEXT, + results_location TEXT, + status TEXT, + telemetries FROZEN, + health TEXT, + health_info FROZEN, + percent_complete INT, + last_updated_at TIMESTAMP, + last_heartbeat_at TIMESTAMP, + created_at TIMESTAMP, + has_secrets BOOLEAN, + PRIMARY KEY ((task_id)) +); + +CREATE CUSTOM INDEX IF NOT EXISTS tasks_v2_by_nca_id_sai_idx ON tasks_v2 (nca_id) USING 'StorageAttachedIndex'; + +CREATE TABLE IF NOT EXISTS events_by_task +( + task_id UUID, + event_id UUID, + nca_id TEXT, + message TEXT, + created_at TIMESTAMP, + PRIMARY KEY ((task_id), event_id) +); + +CREATE TABLE IF NOT EXISTS results_by_task +( + task_id UUID, + result_id UUID, + nca_id TEXT, + name TEXT, + metadata TEXT, + created_at TIMESTAMP, + PRIMARY KEY ((task_id), result_id) +); + +// Table for managing distributed locks for scheduled background threads. +// Primary key must be 'name', +CREATE TABLE IF NOT EXISTS lock +( + name TEXT, + lockUntil TIMESTAMP, + lockedAt TIMESTAMP, + lockedBy TEXT, + PRIMARY KEY ((name)) +); diff --git a/src/control-plane-services/cloud-tasks/local_env/cassandra/truststore.node0 b/src/control-plane-services/cloud-tasks/local_env/cassandra/truststore.node0 new file mode 100644 index 0000000000000000000000000000000000000000..09e1130e4c630f92e157d2de6cd001c394d64d8b GIT binary patch literal 955 zcmezO_TO6u1_mY|W(3o$dHE@+20&h!^8T%l8CWCqObsj<7?^7fnwTpMnwSz7Ff%bS zF|laR?zT1HW#iOp^Jx3d%gD&h%3zRVC}6bQhKm>|i1Qj57#bNE85*0K8d^q4@EZYnhK2?fPysr-r-@MsIY1a$8JL?G`56qF z7`d357#SH>M)z9mNS|ISSv-m5=fp3~PqrT^n|j@UVPD}3j;UN0?1i=5ca1Y2v$5L< zdo}CM$`Cwj>hap7e{#?{|5)=FX*QR`r)U4Zur6eS;qr~9?vE!JP3@n0$b{`jyx^-{ z(FsQ`uF|@%(Q`~xY5hOg;fujmUJb* z)=y5&pZ1LJT+l32rG-5+F7$n|eqM7?gX@BO-ijYW=dGNdXa4V69+DaN0_vdU`S0-jg2FAsT2J!~7z%(Mu$0Eieax0+wkmKBpNq;Mo4{X(X zDa%?I_YFA^fvE}@h>Q%W4`!K_St + + + 4.0.0 + + + com.nvidia.nvct + cloud-tasks + 0.0.1-SNAPSHOT + + + nvct-core + NVCT Core + jar + + NVIDIA Cloud Tasks Core Library — Shared library containing core business logic shared by + both open-source/self-hosted and managed environments. + + + + + + 8.19.0 + 1.3.2 + 1.7.1 + + + 3.1.0.RELEASE + 3.25.6 + 0.6.1 + 1.63.0 + + + + + + org.springframework.boot + spring-boot-starter-webmvc + + + org.springframework.boot + spring-boot-starter-jackson + + + + org.springframework + spring-webflux + + + org.springframework + spring-context-support + + + org.springframework.boot + spring-boot-starter-validation + + + org.springframework.boot + spring-boot-starter-security + + + org.springframework.boot + spring-boot-starter-aspectj + + + org.springframework.boot + spring-boot-starter-security-oauth2-client + + + org.springframework.boot + spring-boot-starter-security-oauth2-resource-server + + + + + io.micrometer + micrometer-registry-prometheus + + + org.springdoc + springdoc-openapi-starter-webmvc-api + + + net.devh + grpc-server-spring-boot-starter + ${spring-boot.grpc.version} + + + guava + com.google.guava + + + + + org.springframework.cloud + spring-cloud-starter-kubernetes-client-config + + + + + + com.bucket4j + bucket4j-core + + + + + + org.springframework.retry + spring-retry + + + + + com.nvidia.boot + nv-boot-starter-registries + + + com.nvidia.boot + nv-boot-starter-exceptions + + + com.nvidia.boot + nv-boot-starter-core + + + com.nvidia.boot + nv-boot-starter-audit + + + com.nvidia.boot + nv-boot-starter-reloadable-properties + + + com.nvidia.boot + nv-boot-starter-cassandra + + + com.nvidia.boot + nv-boot-starter-observability + + + + + io.projectreactor.netty + reactor-netty-http + + + org.apache.cassandra + java-driver-metrics-micrometer + + + tools.jackson.module + jackson-module-blackbird + + + + com.github.ben-manes.caffeine + caffeine + + + + + + com.github.ben-manes.caffeine + guava + + + net.javacrumbs.shedlock + shedlock-provider-cassandra + + + net.javacrumbs.shedlock + shedlock-spring + + + + + + com.bucket4j + bucket4j_jdk17-core + ${bucket4j.version} + + + + javax.annotation + javax.annotation-api + ${javax-annotation-api.version} + + + + + org.springframework.boot + spring-boot-starter-webmvc-test + test + + + org.springframework.boot + spring-boot-restclient + test + + + org.springframework.boot + spring-boot-starter-data-cassandra-test + test + + + org.junit.jupiter + junit-jupiter-api + test + + + org.assertj + assertj-core + test + + + org.testcontainers + testcontainers + test + + + org.testcontainers + testcontainers-cassandra + test + + + org.testcontainers + testcontainers-localstack + test + + + org.wiremock + wiremock-standalone + test + + + com.nvidia.boot + nv-boot-mock-servers-test + test + + + io.opentelemetry + opentelemetry-sdk-testing + test + + + + + + + kr.motd.maven + os-maven-plugin + ${os-maven-plugin.version} + + + + + + + org.apache.maven.plugins + maven-resources-plugin + + + copy-integration-local-env + process-test-resources + + copy-resources + + + ${project.build.testOutputDirectory}/local_env + + + ${project.basedir}/local_env + + docker-compose.test.yml + cassandra/** + + + + + + + + + + + org.apache.maven.plugins + maven-jar-plugin + + + + test-jar + + + + + + org.xolstice.maven.plugins + protobuf-maven-plugin + ${protobuf-maven-plugin.version} + + grpc-java + + com.google.protobuf:protoc:${protobuf.version}:exe:${os.detected.classifier} + + + io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier} + + + + + + compile + compile-custom + + + + + + + diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/AuthManagerResolverConfiguration.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/AuthManagerResolverConfiguration.java new file mode 100644 index 000000000..ad9170efd --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/AuthManagerResolverConfiguration.java @@ -0,0 +1,136 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.configuration; + +import static org.springframework.security.oauth2.core.OAuth2AccessToken.TokenType.BEARER; +import static org.springframework.security.oauth2.core.OAuth2TokenIntrospectionClaimNames.EXP; +import static org.springframework.security.oauth2.core.OAuth2TokenIntrospectionClaimNames.IAT; + +import com.nvidia.nvct.service.apikeys.ApiKeysService; +import jakarta.servlet.http.HttpServletRequest; +import java.time.Instant; +import java.util.Collections; +import java.util.Map; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.HttpHeaders; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.AuthenticationManagerResolver; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.oauth2.core.OAuth2AccessToken; +import org.springframework.security.oauth2.jose.jws.SignatureAlgorithm; +import org.springframework.security.oauth2.jwt.JwtDecoder; +import org.springframework.security.oauth2.jwt.JwtValidators; +import org.springframework.security.oauth2.jwt.NimbusJwtDecoder; +import org.springframework.security.oauth2.server.resource.authentication.BearerTokenAuthentication; +import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationConverter; +import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationProvider; +import org.springframework.security.oauth2.server.resource.authentication.JwtIssuerAuthenticationManagerResolver; +import org.springframework.security.oauth2.server.resource.authentication.OpaqueTokenAuthenticationProvider; +import org.springframework.security.oauth2.server.resource.introspection.OpaqueTokenAuthenticationConverter; +import org.springframework.security.oauth2.server.resource.introspection.OpaqueTokenIntrospector; +import org.springframework.util.CollectionUtils; + +@Configuration(proxyBeanMethods = false) +public class AuthManagerResolverConfiguration { + + private final ApiKeysService apiKeysService; + private final String issuerUri; + private final String jwkSetUri; + private final SignatureAlgorithm jwsAlgorithm; + + + public AuthManagerResolverConfiguration( + ApiKeysService apiKeysService, + @Value("${spring.security.oauth2.resourceserver.jwt.jws-algorithms}") String jwsAlgorithm, + @Value("${spring.security.oauth2.resourceserver.jwt.issuer-uri}") String issuerUri, + @Value("${spring.security.oauth2.resourceserver.jwt.jwk-set-uri}") String jwkSetUri) { + this.apiKeysService = apiKeysService; + this.issuerUri = issuerUri; + this.jwkSetUri = jwkSetUri; + this.jwsAlgorithm = SignatureAlgorithm.valueOf(jwsAlgorithm); // Fail-fast if invalid. + } + + @Bean + AuthenticationManagerResolver authenticationManagerResolver() { + var jwtResolver = jwtResolver(); + return request -> { + var authorization = request.getHeader(HttpHeaders.AUTHORIZATION); + if (authorization != null && authorization.startsWith("Bearer nvapi-")) { + return apiKeyAuthenticationManager(); + } + return jwtResolver.resolve(request); + }; + } + + private AuthenticationManager apiKeyAuthenticationManager() { + var provider = new OpaqueTokenAuthenticationProvider(apiKeyIntrospector()); + provider.setAuthenticationConverter(apiKeyConverter()); + return provider::authenticate; + } + + private OpaqueTokenIntrospector apiKeyIntrospector() { + return token -> apiKeysService.resolveNCAIdFromApiKey(token).getOAuth2Principal(); + } + + private static OpaqueTokenAuthenticationConverter apiKeyConverter() { + return (introspectedToken, authenticatedPrincipal) -> { + Instant iat = authenticatedPrincipal.getAttribute(IAT); + Instant exp = authenticatedPrincipal.getAttribute(EXP); + var accessToken = new OAuth2AccessToken(BEARER, introspectedToken, iat, exp); + return new BearerTokenAuthentication(authenticatedPrincipal, accessToken, + authenticatedPrincipal.getAuthorities()); + }; + } + + private JwtIssuerAuthenticationManagerResolver jwtResolver() { + var managers = Map.of(issuerUri, jwtAuthenticationManager()); + return new JwtIssuerAuthenticationManagerResolver(managers::get); + } + + private AuthenticationManager jwtAuthenticationManager() { + var provider = new JwtAuthenticationProvider(jwtDecoder()); + provider.setJwtAuthenticationConverter(jwtAuthenticationConverter()); + return provider::authenticate; + } + + private JwtDecoder jwtDecoder() { + var decoder = NimbusJwtDecoder + .withJwkSetUri(jwkSetUri) + .jwsAlgorithm(jwsAlgorithm) + .build(); + decoder.setJwtValidator(JwtValidators.createDefaultWithIssuer(issuerUri)); + return decoder; + } + + private JwtAuthenticationConverter jwtAuthenticationConverter() { + var converter = new JwtAuthenticationConverter(); + converter.setJwtGrantedAuthoritiesConverter(jwt -> { + var scopes = jwt.getClaimAsStringList("scopes"); + if (CollectionUtils.isEmpty(scopes)) { + return Collections.emptyList(); + } + return scopes.stream() + .map(SimpleGrantedAuthority::new) + .map(GrantedAuthority.class::cast) + .toList(); + }); + return converter; + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/ClockConfiguration.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/ClockConfiguration.java new file mode 100644 index 000000000..63d25fdf4 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/ClockConfiguration.java @@ -0,0 +1,32 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.configuration; + +import java.time.Clock; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Slf4j +@Configuration +public class ClockConfiguration { + + @Bean + public Clock clock() { + return Clock.systemUTC(); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/DistributedLockConfiguration.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/DistributedLockConfiguration.java new file mode 100644 index 000000000..1f5ddde64 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/DistributedLockConfiguration.java @@ -0,0 +1,49 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.configuration; + +import com.datastax.oss.driver.api.core.ConsistencyLevel; +import com.datastax.oss.driver.api.core.CqlSession; +import com.datastax.oss.driver.api.core.DefaultConsistencyLevel; +import net.javacrumbs.shedlock.core.LockProvider; +import net.javacrumbs.shedlock.provider.cassandra.CassandraLockProvider; +import net.javacrumbs.shedlock.spring.annotation.EnableSchedulerLock; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +@EnableSchedulerLock(defaultLockAtMostFor = "60s") +public class DistributedLockConfiguration { + + @Bean + public LockProvider lockProvider( + CqlSession cqlSession, + // Higher quorum for cross region locks + @Value("${nvct.scheduled-routines.lock-consistency:EACH_QUORUM}") + DefaultConsistencyLevel consistencyLevel) { + return new CassandraLockProvider( + CassandraLockProvider.Configuration.builder() + .withCqlSession(cqlSession) + .withTableName("lock") + // higher quorum for cross region locks + .withConsistencyLevel(consistencyLevel) + .withSerialConsistencyLevel(ConsistencyLevel.SERIAL) + .build()); + } + +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/GrpcConfiguration.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/GrpcConfiguration.java new file mode 100644 index 000000000..849eb56c3 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/GrpcConfiguration.java @@ -0,0 +1,92 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.configuration; + +import com.nvidia.boot.exceptions.ForbiddenException; +import com.nvidia.boot.exceptions.UnauthorizedException; +import io.grpc.Status; +import io.grpc.Status.Code; +import io.grpc.netty.shaded.io.grpc.netty.NettyServerBuilder; +import net.devh.boot.grpc.server.advice.GrpcAdvice; +import net.devh.boot.grpc.server.advice.GrpcExceptionHandler; +import net.devh.boot.grpc.server.security.authentication.BearerAuthenticationReader; +import net.devh.boot.grpc.server.security.authentication.GrpcAuthenticationReader; +import net.devh.boot.grpc.server.security.interceptors.DefaultAuthenticatingServerInterceptor; +import net.devh.boot.grpc.server.security.interceptors.ExceptionTranslatingServerInterceptor; +import net.devh.boot.grpc.server.serverfactory.GrpcServerConfigurer; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.access.AccessDeniedException; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.oauth2.server.resource.authentication.BearerTokenAuthenticationToken; +import org.springframework.web.ErrorResponseException; + +@Configuration(proxyBeanMethods = false) +@GrpcAdvice +public class GrpcConfiguration { + + @Bean + public GrpcAuthenticationReader authenticationReader() { + return new BearerAuthenticationReader(BearerTokenAuthenticationToken::new); + } + + @Bean + public ExceptionTranslatingServerInterceptor exceptionTranslatingServerInterceptor() { + return new ExceptionTranslatingServerInterceptor(); + } + + @Bean + public DefaultAuthenticatingServerInterceptor authenticatingServerInterceptor( + final GrpcAuthenticationReader authenticationReader) { + // pass-through auth manager, since we need to auth in a non-blocking context + return new DefaultAuthenticatingServerInterceptor(authentication -> authentication, + authenticationReader); + } + + @Bean + public GrpcServerConfigurer keepAliveServerConfigurer() { + return serverBuilder -> { + if (serverBuilder instanceof NettyServerBuilder sb) { + sb.permitKeepAliveWithoutCalls(true); + } + }; + } + + @GrpcExceptionHandler + public Status handleErrorResponseException(ErrorResponseException e) { + var code = switch (e.getStatusCode().value()) { + case 400 -> Code.INTERNAL; + case 401 -> Code.UNAUTHENTICATED; + case 403 -> Code.PERMISSION_DENIED; + case 404 -> Code.NOT_FOUND; + case 429, 502, 503, 504 -> Code.UNAVAILABLE; + default -> Code.UNKNOWN; + }; + return Status.fromCode(code).withDescription(e.getBody().getDetail()).withCause(e); + } + + @GrpcExceptionHandler + public Status handleException(AccessDeniedException e) { + return handleErrorResponseException(new ForbiddenException(e.getMessage(), e.getCause())); + } + + @GrpcExceptionHandler + public Status handleException(AuthenticationException e) { + return handleErrorResponseException( + new UnauthorizedException(e.getMessage(), e.getCause())); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/JacksonConfiguration.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/JacksonConfiguration.java new file mode 100644 index 000000000..27a0dbdcb --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/JacksonConfiguration.java @@ -0,0 +1,50 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.configuration; + +import com.fasterxml.jackson.annotation.JsonInclude; +import tools.jackson.core.StreamWriteFeature; +import tools.jackson.databind.DeserializationFeature; +import tools.jackson.databind.MapperFeature; +import tools.jackson.databind.cfg.EnumFeature; +import tools.jackson.databind.json.JsonMapper; +import tools.jackson.module.blackbird.BlackbirdModule; +import lombok.extern.slf4j.Slf4j; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.http.ProblemDetail; +import org.springframework.http.converter.json.ProblemDetailJacksonMixin; + +@Slf4j +@Configuration +public class JacksonConfiguration { + + @Bean + @Primary + public JsonMapper jsonMapper() { + return JsonMapper.builder() + .addModule(new BlackbirdModule()) + .addMixIn(ProblemDetail.class, ProblemDetailJacksonMixin.class) + .changeDefaultPropertyInclusion(v -> v.withValueInclusion(JsonInclude.Include.NON_NULL)) + .enable(StreamWriteFeature.STRICT_DUPLICATE_DETECTION) + .enable(MapperFeature.ACCEPT_CASE_INSENSITIVE_ENUMS) + .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) + .enable(EnumFeature.READ_UNKNOWN_ENUM_VALUES_USING_DEFAULT_VALUE) + .build(); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/MethodSecurityConfiguration.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/MethodSecurityConfiguration.java new file mode 100644 index 000000000..40ad42590 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/MethodSecurityConfiguration.java @@ -0,0 +1,26 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.configuration; + +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; + +@Configuration +@EnableMethodSecurity +public class MethodSecurityConfiguration { + // empty to inherit defaults +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/MetricsConfiguration.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/MetricsConfiguration.java new file mode 100644 index 000000000..77c8fffad --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/MetricsConfiguration.java @@ -0,0 +1,36 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.configuration; + +import io.micrometer.core.instrument.MeterRegistry; +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.micrometer.metrics.autoconfigure.MeterRegistryCustomizer; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +@Slf4j +public class MetricsConfiguration { + @Bean + MeterRegistryCustomizer nvctMeterRegistryCustomizer() { + return registry -> registry.config() + .onMeterAdded(meter -> log.debug("meter added: {}", meter.getId())) + .onMeterRemoved(meter -> log.debug("meter removed: {}", meter.getId())) + .onMeterRegistrationFailed((id, reason) -> log.error( + "meter registration failed, id:{} reason:{}", id, reason)); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/NotaryJwtConfiguration.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/NotaryJwtConfiguration.java new file mode 100644 index 000000000..b2e790e56 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/NotaryJwtConfiguration.java @@ -0,0 +1,44 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.configuration; + +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.oauth2.core.OAuth2TokenValidatorResult; +import org.springframework.security.oauth2.jose.jws.SignatureAlgorithm; +import org.springframework.security.oauth2.jwt.JwtDecoder; +import org.springframework.security.oauth2.jwt.NimbusJwtDecoder; + +@Configuration(proxyBeanMethods = false) +public class NotaryJwtConfiguration { + + @Bean + @Qualifier("notaryJwtDecoder") + public JwtDecoder notaryJwtDecoder(@Value("${nvct.notary.jwt.jwk-set-uri}") String jwkSetUri) { + var decoder = NimbusJwtDecoder + .withJwkSetUri(jwkSetUri) + .jwsAlgorithm(SignatureAlgorithm.ES256) + .build(); + // Notary worker assertion tokens intentionally do not carry exp. We still need + // signature verification here, while temporal checks are handled separately in a + // different validator. + decoder.setJwtValidator(token -> OAuth2TokenValidatorResult.success()); + return decoder; + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/ObservationConfiguration.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/ObservationConfiguration.java new file mode 100644 index 000000000..86772735a --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/ObservationConfiguration.java @@ -0,0 +1,31 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.configuration; + +import io.micrometer.observation.ObservationRegistry; +import io.micrometer.observation.aop.ObservedAspect; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration(proxyBeanMethods = false) +public class ObservationConfiguration { + + @Bean + public ObservedAspect observedAspect(ObservationRegistry observationRegistry) { + return new ObservedAspect(observationRegistry); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/OpenApiDocConfiguration.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/OpenApiDocConfiguration.java new file mode 100644 index 000000000..72960e9c1 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/OpenApiDocConfiguration.java @@ -0,0 +1,124 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.configuration; + +import com.nvidia.nvct.rest.event.XAccountEventController; +import com.nvidia.nvct.rest.result.XAccountResultController; +import com.nvidia.nvct.rest.secret.XAccountSecretManagementController; +import com.nvidia.nvct.rest.task.XAccountTaskManagementController; +import io.swagger.v3.oas.models.OpenAPI; +import io.swagger.v3.oas.models.info.Contact; +import io.swagger.v3.oas.models.info.Info; +import jakarta.annotation.PostConstruct; +import java.util.List; +import org.apache.commons.lang3.StringUtils; +import org.springdoc.core.customizers.OpenApiCustomizer; +import org.springdoc.core.customizers.OperationCustomizer; +import org.springdoc.core.utils.SpringDocUtils; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class OpenApiDocConfiguration { + + private final boolean excludeSuperAdminApis; + + public OpenApiDocConfiguration( + @Value("${nvct.openapi.exclude.super-admin-apis:true}") boolean excludeSuperAdminApis) { + this.excludeSuperAdminApis = excludeSuperAdminApis; + } + + @PostConstruct + public void postConstruct() { + // In general, we do NOT want details of our NVIDIA Super Admin endpoints to be exposed + // via our OpenAPI Specs generated from the /v3/openapi endpoint. However, we still want + // the ability to generate OpenAPI Specs that contain details for all(Super Admin and + // Account Admin) the endpoints to help our SRE and UI teams. So, we cannot just + // use the @Hidden annotation in our cross-account controllers and exclude the docs for + // Super Admin endpoints the OpenAPI Specs. We are planning on automating the process of + // generating OpenAPI Specs from within a dedicated job in the CI pipeline. Once a MR is + // merged and a new tag is ready, the job will generate OpenAPI Specs containing just + // the Account Admin endpoints by doing this: + // + // $ cd local_env; docker-compose up; cd .. + // $ java -Dspring.profiles.active=local -jar target/app.jar + // $ curl localhost:8080/v3/openapi > nvct-openapi.json + // + // Then, the job will terminate the app and generate uber OpenAPI Specs that will contain + // details of both NVIDIA Super Admin and Account Admin endpoints like this: + // + // $ java -Dspring.profiles.active=local \ + // -Dnvct.openapi.exclude.super-admin-apis=false -jar target/app.jar + // $ curl localhost:8080/v3/openapi > full-nvct-openapi.json + // + // Once the job generates the two JSON files, it will shutdown the docker containers, + // terminate the app, and automatically update the gitlab repo containing OpenAPI Specs + // with the newly generated JSON files. + if (excludeSuperAdminApis) { + var superAdminControllers = List.of(XAccountEventController.class, + XAccountResultController.class, + XAccountTaskManagementController.class, + XAccountSecretManagementController.class) + .toArray(new Class[0]); + SpringDocUtils.getConfig().addHiddenRestControllers(superAdminControllers); + } + } + + // Using Cloud Tasks as title instead of spring.application.name property. We cannot change + // the value of spring.application.name property easily at this point. + @SuppressWarnings("unused") + @Bean + public OpenAPI customOpenAPI( + @Value("${spring.application.version}") String version) { + var title = "Cloud Tasks"; + return new OpenAPI() + .info(new Info().title(title) + .version(version) + .contact(new Contact().name("NVIDIA").url("https://www.nvidia.com/")) + .termsOfService("https://www.nvidia.com/en-us/legal_info")); + + } + + @SuppressWarnings("unused") + @Bean + public OperationCustomizer operationCustomizer() { + // Replace '\n' introduced due to Java multi-line strings in the description + // field of @Operation annotation. + return (operation, handlerMethod) -> { + var description = operation.getDescription(); + if (StringUtils.isNotBlank(description)) { + operation.setDescription(description.replace("\n", " ")); + } + return operation; + }; + } + + @SuppressWarnings("unused") + @Bean + public OpenApiCustomizer openApiCustomizer() { + // Replace '\n' introduced due to Java multi-line strings in the description + // field of @Tag annotation. + return openApi -> openApi.getTags().forEach(tag -> { + var description = tag.getDescription(); + if (StringUtils.isNotBlank(description)) { + tag.setDescription(description.replace("\n", " ")); + } + }); + } + +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/OutboundHttpResourcesConfiguration.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/OutboundHttpResourcesConfiguration.java new file mode 100644 index 000000000..de258d5e0 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/OutboundHttpResourcesConfiguration.java @@ -0,0 +1,74 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.configuration; + +import com.nvidia.nvct.service.ess.EssClient; +import com.nvidia.nvct.service.icms.IcmsClient; +import com.nvidia.nvct.service.ngc.NgcRegistryClient; +import com.nvidia.nvct.service.nvcf.NvcfClient; +import com.nvidia.nvct.service.reval.RevalClient; +import com.nvidia.nvct.service.token.client.NotaryClient; +import com.nvidia.nvct.util.NvctOAuth2ClientUtils; +import com.nvidia.nvct.util.NvctOAuth2ClientUtils.ManagedHttpResources; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * Creates singleton {@link ManagedHttpResources} beans for each outbound client. + * These pools survive {@link org.springframework.cloud.context.config.annotation.RefreshScope + * @RefreshScope} refreshes — only the {@code WebClient} is rebuilt when config changes. + * Spring disposes them on application shutdown via {@code destroyMethod = "close"}. + */ +@Configuration +class OutboundHttpResourcesConfiguration { + + @Bean(destroyMethod = "close") + ManagedHttpResources essHttpResources() { + return NvctOAuth2ClientUtils + .getClientHttpConnectorManaged(EssClient.CLIENT_REGISTRATION_ID); + } + + @Bean(destroyMethod = "close") + ManagedHttpResources ngcRegistryHttpResources() { + return NvctOAuth2ClientUtils + .getClientHttpConnectorManaged(NgcRegistryClient.CLIENT_REGISTRATION_ID); + } + + @Bean(destroyMethod = "close") + ManagedHttpResources nvcfHttpResources() { + return NvctOAuth2ClientUtils + .getClientHttpConnectorManaged(NvcfClient.CLIENT_REGISTRATION_ID); + } + + @Bean(destroyMethod = "close") + ManagedHttpResources revalHttpResources() { + return NvctOAuth2ClientUtils + .getClientHttpConnectorManaged(RevalClient.CLIENT_REGISTRATION_ID); + } + + @Bean(destroyMethod = "close") + ManagedHttpResources icmsHttpResources() { + return NvctOAuth2ClientUtils + .getClientHttpConnectorManaged(IcmsClient.CLIENT_REGISTRATION_ID); + } + + @Bean(destroyMethod = "close") + ManagedHttpResources notaryHttpResources() { + return NvctOAuth2ClientUtils + .getClientHttpConnectorManaged(NotaryClient.CLIENT_REGISTRATION_ID); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/RegistryConfiguration.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/RegistryConfiguration.java new file mode 100644 index 000000000..76b4f68b1 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/RegistryConfiguration.java @@ -0,0 +1,36 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.configuration; + +import com.nvidia.boot.registries.configurations.RegistryConfigPathProvider; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * Registry configuration for NVCT. Uses {@code proxyBeanMethods = false} to avoid early + * singleton creation that triggers ConfigurationClassPostProcessor warnings. Safe here + * because the {@code @Bean} method does not call other {@code @Bean} methods on this class. + */ +@Configuration(proxyBeanMethods = false) +public class RegistryConfiguration { + private static final String REGISTRY_CONFIG_PATH = "nvct.registries"; + + @Bean + public RegistryConfigPathProvider registryConfigPathProvider() { + return () -> REGISTRY_CONFIG_PATH; + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/SecurityConfiguration.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/SecurityConfiguration.java new file mode 100644 index 000000000..cd4a509b5 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/SecurityConfiguration.java @@ -0,0 +1,62 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.configuration; + +import static org.springframework.security.config.http.SessionCreationPolicy.STATELESS; + +import com.nvidia.nvct.configuration.filters.ExceptionHandlerFilter; +import jakarta.servlet.http.HttpServletRequest; +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.authentication.AuthenticationManagerResolver; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.authentication.logout.LogoutFilter; + +@Configuration +@RequiredArgsConstructor +@EnableWebSecurity +public class SecurityConfiguration { + + @Bean + public SecurityFilterChain filterChain( + HttpSecurity http, + AuthenticationManagerResolver authenticationManagerResolver, + ExceptionHandlerFilter exceptionHandlerFilter) { + http + .csrf(csrf -> csrf.disable()) + .sessionManagement(session -> session.sessionCreationPolicy(STATELESS)) + // Reuse the ValidationAwareExceptionHandler to handle the exception inside + // the filters,especially for the custom authentication resolver exceptions. + .addFilterBefore(exceptionHandlerFilter, LogoutFilter.class) + // Enable JWT and api-key security + .oauth2ResourceServer(configurer -> configurer + .authenticationManagerResolver(authenticationManagerResolver)) + .authorizeHttpRequests( + request -> request + .requestMatchers("/health").permitAll() + .requestMatchers("/v3/openapi").permitAll() + // management port is not exposed via load balancer. Readiness + // and liveness probes, metrics, prometheus etc. are accessible + // via management port. + .requestMatchers("/actuator/**").permitAll() + .anyRequest().authenticated()); + return http.build(); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/exceptions/ExceptionTracingExceptionHandler.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/exceptions/ExceptionTracingExceptionHandler.java new file mode 100644 index 000000000..af5073ad6 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/exceptions/ExceptionTracingExceptionHandler.java @@ -0,0 +1,132 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.configuration.exceptions; + +import com.nvidia.boot.exceptions.BadRequestException; +import com.nvidia.boot.exceptions.ConflictException; +import com.nvidia.boot.exceptions.ForbiddenException; +import com.nvidia.boot.exceptions.NotFoundException; +import com.nvidia.boot.exceptions.TooManyRequestsException; +import com.nvidia.boot.exceptions.UnauthorizedException; +import com.nvidia.boot.exceptions.handlers.BootMvcExceptionHandler; +import com.nvidia.nvct.util.NvctUtils; +import io.micrometer.tracing.Tracer; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.context.request.WebRequest; +import org.springframework.web.reactive.function.client.WebClientResponseException; + +public class ExceptionTracingExceptionHandler extends BootMvcExceptionHandler { + + @Autowired + private Tracer tracer; + + @Override + protected void recordException(Exception ex) { + NvctUtils.recordExceptionUsingCurrentSpan(tracer, ex); + } + + @ExceptionHandler(WebClientResponseException.BadRequest.class) + protected ResponseEntity handleException( + WebClientResponseException.BadRequest ex, + WebRequest request) throws Exception { + return super.handleException( + new BadRequestException(ex.getMessage(), ex.getCause()), request); + } + + @ExceptionHandler(WebClientResponseException.Unauthorized.class) + protected ResponseEntity handleException( + WebClientResponseException.Unauthorized ex, + WebRequest request) throws Exception { + return super.handleException( + new UnauthorizedException(ex.getMessage(), ex.getCause()), request); + } + + @ExceptionHandler(WebClientResponseException.Forbidden.class) + protected ResponseEntity handleException( + WebClientResponseException.Forbidden ex, + WebRequest request) throws Exception { + return super.handleException( + new ForbiddenException(ex.getMessage(), ex.getCause()), request); + } + + @ExceptionHandler(WebClientResponseException.NotFound.class) + protected ResponseEntity handleException( + WebClientResponseException.NotFound ex, + WebRequest request) throws Exception { + return super.handleException( + new NotFoundException(ex.getMessage(), ex.getCause()), request); + } + + @ExceptionHandler(WebClientResponseException.Conflict.class) + protected ResponseEntity handleException( + WebClientResponseException.Conflict ex, + WebRequest request) throws Exception { + return super.handleException( + new ConflictException(ex.getMessage(), ex.getCause()), request); + } + + @ExceptionHandler(WebClientResponseException.TooManyRequests.class) + protected ResponseEntity handleException( + WebClientResponseException.TooManyRequests ex, + WebRequest request) throws Exception { + return super.handleException( + new TooManyRequestsException(ex.getMessage(), ex.getCause()), request); + } + + @ExceptionHandler(WebClientResponseException.MethodNotAllowed.class) + protected ResponseEntity handleException( + WebClientResponseException.MethodNotAllowed ex, + WebRequest request) throws Exception { + return super.handleException( + new BadRequestException(ex.getMessage(), ex.getCause()), request); + } + + @ExceptionHandler(WebClientResponseException.NotAcceptable.class) + protected ResponseEntity handleException( + WebClientResponseException.NotAcceptable ex, + WebRequest request) throws Exception { + return super.handleException( + new BadRequestException(ex.getMessage(), ex.getCause()), request); + } + + @ExceptionHandler(WebClientResponseException.Gone.class) + protected ResponseEntity handleException( + WebClientResponseException.Gone ex, + WebRequest request) throws Exception { + return super.handleException( + new BadRequestException(ex.getMessage(), ex.getCause()), request); + } + + @ExceptionHandler(WebClientResponseException.UnsupportedMediaType.class) + protected ResponseEntity handleException( + WebClientResponseException.UnsupportedMediaType ex, + WebRequest request) throws Exception { + return super.handleException( + new BadRequestException(ex.getMessage(), ex.getCause()), request); + } + + @ExceptionHandler(WebClientResponseException.UnprocessableContent.class) + protected ResponseEntity handleException( + WebClientResponseException.UnprocessableContent ex, + WebRequest request) throws Exception { + return super.handleException( + new BadRequestException(ex.getMessage(), ex.getCause()), request); + } + +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/exceptions/ValidationAwareExceptionHandler.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/exceptions/ValidationAwareExceptionHandler.java new file mode 100644 index 000000000..1a69886b4 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/exceptions/ValidationAwareExceptionHandler.java @@ -0,0 +1,156 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.configuration.exceptions; + +import tools.jackson.databind.JsonNode; +import com.nvidia.boot.exceptions.BootResponseException; +import jakarta.annotation.Nonnull; +import java.util.List; +import org.springframework.context.MessageSourceResolvable; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatusCode; +import org.springframework.http.ProblemDetail; +import org.springframework.http.ResponseEntity; +import org.jspecify.annotations.Nullable; +import org.springframework.util.ObjectUtils; +import org.springframework.validation.FieldError; +import org.springframework.web.bind.MethodArgumentNotValidException; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.context.request.WebRequest; +import org.springframework.web.method.annotation.HandlerMethodValidationException; + +@Configuration +@ControllerAdvice +public class ValidationAwareExceptionHandler extends ExceptionTracingExceptionHandler { + + private static final int MAX_REJECTED_VALUE_LOG_CHARS = 256; + + private static String toCleanMessage(HandlerMethodValidationException ex) { + StringBuilder sb = new StringBuilder("Validation failed with "); + appendError(sb, ex.getAllErrors()); + return sb.toString(); + } + + private static void appendError( + StringBuilder sb, List errors) { + for (MessageSourceResolvable error : errors) { + sb.append('['); + if (error instanceof FieldError fieldError) { + sb.append("Field error in object '") + .append(fieldError.getObjectName()) + .append("' on field '") + .append(fieldError.getField()) + .append("': rejected value [") + .append(truncateRejectedValueForLog(fieldError.getRejectedValue())) + .append("]; ") + .append(fieldError.getDefaultMessage()); + } else { + sb.append(error); + } + sb.append("] "); + } + sb.deleteCharAt(sb.length() - 1); + } + + /** + * Keeps validation problem responses and framework DEBUG logs bounded when rejected values are + * very large (e.g. secret value length integration tests). + */ + @Override + protected ResponseEntity handleMethodArgumentNotValid( + MethodArgumentNotValidException ex, + HttpHeaders headers, + HttpStatusCode status, + WebRequest request) { + var problemDetail = + ProblemDetail.forStatusAndDetail(status, buildMethodArgumentNotValidDetail(ex)); + return handleExceptionInternal(ex, problemDetail, headers, status, request); + } + + private static String buildMethodArgumentNotValidDetail(MethodArgumentNotValidException ex) { + var errors = ex.getBindingResult().getFieldErrors(); + if (errors.isEmpty()) { + return "Validation failed"; + } + StringBuilder sb = new StringBuilder("Validation failed: "); + for (FieldError fe : errors) { + sb.append("[object=") + .append(fe.getObjectName()) + .append(", field=") + .append(fe.getField()) + .append(", rejected=") + .append(truncateRejectedValueForLog(fe.getRejectedValue())) + .append(", message=") + .append(fe.getDefaultMessage()) + .append("] "); + } + return sb.toString().trim(); + } + + private static String truncateRejectedValueForLog(@Nullable Object rejected) { + if (rejected == null) { + return "null"; + } + String raw; + if (rejected instanceof JsonNode node) { + if (node.isString()) { + raw = node.asString(); + } else { + raw = node.toString(); + } + } else if (rejected instanceof CharSequence seq) { + raw = seq.toString(); + } else { + raw = ObjectUtils.nullSafeConciseToString(rejected); + } + if (raw.length() <= MAX_REJECTED_VALUE_LOG_CHARS) { + return raw; + } + return raw.substring(0, MAX_REJECTED_VALUE_LOG_CHARS) + + "... (truncated for log/response, total length " + + raw.length() + + " chars)"; + } + + @Override + protected ResponseEntity handleHandlerMethodValidationException( + @Nonnull HandlerMethodValidationException ex, @Nonnull HttpHeaders headers, + @Nonnull HttpStatusCode status, @Nonnull WebRequest request) { + var problemDetail = ProblemDetail.forStatusAndDetail(status, toCleanMessage(ex)); + return super.handleExceptionInternal(ex, problemDetail, headers, status, request); + } + + @Nonnull + @Override + protected ResponseEntity handleExceptionInternal( + @Nonnull Exception ex, + Object body, + HttpHeaders headers, + @Nonnull HttpStatusCode status, + @Nonnull WebRequest request) { + Object problemBody = body instanceof ProblemDetail ? body : resolveBody(ex, status); + return super.handleExceptionInternal(ex, problemBody, headers, status, request); + } + + private static ProblemDetail resolveBody(Exception ex, HttpStatusCode status) { + if (ex instanceof BootResponseException bre) { + return bre.getBody(); + } + return ProblemDetail.forStatusAndDetail(status, ex.getMessage()); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/filters/ExceptionHandlerFilter.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/filters/ExceptionHandlerFilter.java new file mode 100644 index 000000000..7ebfd8887 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/filters/ExceptionHandlerFilter.java @@ -0,0 +1,55 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.configuration.filters; + +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.validation.constraints.NotNull; +import java.io.IOException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Component; +import org.springframework.web.filter.OncePerRequestFilter; +import org.springframework.web.servlet.HandlerExceptionResolver; + +@Component +public class ExceptionHandlerFilter extends OncePerRequestFilter { + + @Autowired + @Qualifier("handlerExceptionResolver") + private HandlerExceptionResolver resolver; + + @Override + protected void doFilterInternal( + @NotNull HttpServletRequest request, + @NotNull HttpServletResponse response, + @NotNull FilterChain filterChain + ) throws ServletException, IOException { + try { + filterChain.doFilter(request, response); + } catch (Exception e) { + // When the exception resolver doesn't handle the exception from filter, we + // will throw the exception and let it act as default spring boot behavior. + // If we don't add this, that will make 200 status code for those unhandled exceptions. + if (resolver.resolveException(request, response, null, e) == null) { + throw e; + } + } + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/ratelimit/AccountRateLimiterProperties.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/ratelimit/AccountRateLimiterProperties.java new file mode 100644 index 000000000..0eb79bbf5 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/ratelimit/AccountRateLimiterProperties.java @@ -0,0 +1,81 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.configuration.ratelimit; + +import jakarta.annotation.PostConstruct; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Data; +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.cloud.context.config.annotation.RefreshScope; +import org.springframework.context.annotation.Configuration; +import org.springframework.util.CollectionUtils; + +@Slf4j +@Data +@Configuration +@RefreshScope +@ConfigurationProperties(prefix = "nvct.rate-limiters.account-rate-limiter") +public class AccountRateLimiterProperties { + + private static final String MESG_INVALID_OVERRIDES_ENTRY = + "Invalid or duplicate account entry in the account-rate-limiter's overrides config"; + + private long allowedInvocationsPerSecond = 100; + private List overrides; + + @Setter(AccessLevel.NONE) + private Map overridesMap = Collections.emptyMap(); + + @Setter(AccessLevel.NONE) + private AccountRateCappingProperties defaultRateCappingProperties; + + @Data + @Builder + public static class AccountRateCappingProperties { + private String ncaId; + private long allowedInvocationsPerSecond; + } + + @PostConstruct + void postConstruct() { + if (!CollectionUtils.isEmpty(overrides)) { + this.overridesMap = overrides.stream() + .filter(props -> StringUtils.isNotBlank(props.getNcaId())) + .collect(Collectors.toMap(AccountRateCappingProperties::getNcaId, + Function.identity())); + + if (overridesMap.size() != overrides.size()) { + log.warn(MESG_INVALID_OVERRIDES_ENTRY); + } + } + + this.defaultRateCappingProperties = + AccountRateCappingProperties.builder() + .ncaId("*") + .allowedInvocationsPerSecond(allowedInvocationsPerSecond) + .build(); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/ratelimit/TaskRateLimiterProperties.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/ratelimit/TaskRateLimiterProperties.java new file mode 100644 index 000000000..138722ad1 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/ratelimit/TaskRateLimiterProperties.java @@ -0,0 +1,83 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.configuration.ratelimit; + +import com.nvidia.nvct.util.NvctConstants; +import jakarta.annotation.PostConstruct; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import java.util.function.Function; +import java.util.stream.Collectors; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Data; +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.cloud.context.config.annotation.RefreshScope; +import org.springframework.context.annotation.Configuration; +import org.springframework.util.CollectionUtils; + +@Slf4j +@Data +@Configuration +@RefreshScope +@ConfigurationProperties(prefix = "nvct.rate-limiters.task-rate-limiter") +public class TaskRateLimiterProperties { + + private static final String MESG_INVALID_OVERRIDES_ENTRY = + "Invalid or duplicate entry in the task-rate-limiter's overrides config"; + + private long allowedInvocationsPerSecond = 100; + private List overrides; + + // Only contains override entries that have taskId. + @Setter(AccessLevel.NONE) + private Map taskOverridesMap = Collections.emptyMap(); + + @Setter(AccessLevel.NONE) + private TaskRateCappingProperties defaultRateCappingProperties; + + @Builder + @Data + public static class TaskRateCappingProperties { + private UUID taskId; + private long allowedInvocationsPerSecond; + } + + @PostConstruct + void postConstruct() { + if (!CollectionUtils.isEmpty(overrides)) { + this.taskOverridesMap = overrides.stream() + .filter(props -> props.getTaskId() != null) + .collect(Collectors.toMap( + TaskRateCappingProperties::getTaskId, Function.identity())); + + if (taskOverridesMap.size() != overrides.size()) { + log.warn(MESG_INVALID_OVERRIDES_ENTRY); + } + } + + this.defaultRateCappingProperties = + TaskRateCappingProperties.builder() + .taskId(NvctConstants.UUID_WILDCARD) + .allowedInvocationsPerSecond(allowedInvocationsPerSecond) + .build(); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/staticclientauth/FixedBearerExchangeFilterFunction.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/staticclientauth/FixedBearerExchangeFilterFunction.java new file mode 100644 index 000000000..2b00a074d --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/staticclientauth/FixedBearerExchangeFilterFunction.java @@ -0,0 +1,39 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.configuration.staticclientauth; + +import jakarta.annotation.Nonnull; +import java.util.function.Supplier; +import org.springframework.web.reactive.function.client.ClientRequest; +import org.springframework.web.reactive.function.client.ClientResponse; +import org.springframework.web.reactive.function.client.ExchangeFilterFunction; +import org.springframework.web.reactive.function.client.ExchangeFunction; +import reactor.core.publisher.Mono; + + +public record FixedBearerExchangeFilterFunction(Supplier tokenSupplier) implements + ExchangeFilterFunction { + + @Nonnull + @Override + public Mono filter(@Nonnull ClientRequest request, ExchangeFunction next) { + return next.exchange(ClientRequest.from(request) + .headers(headers -> headers.setBearerAuth(tokenSupplier.get())) + .build()); + + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/staticclientauth/StaticClientAuthConfiguration.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/staticclientauth/StaticClientAuthConfiguration.java new file mode 100644 index 000000000..0a81eae03 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/staticclientauth/StaticClientAuthConfiguration.java @@ -0,0 +1,89 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.configuration.staticclientauth; + + +import lombok.Data; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.cloud.context.config.annotation.RefreshScope; +import org.springframework.context.annotation.Configuration; + +@AutoConfiguration +public class StaticClientAuthConfiguration { + + @Data + @RefreshScope + @Configuration + @ConditionalOnProperty("nvct.notary.static.token") + @ConfigurationProperties("nvct.notary.static") + public static class StaticClientNotaryProperties { + + private String token; + } + + @Data + @RefreshScope + @Configuration + @ConditionalOnProperty("nvct.nvcf.static.token") + @ConfigurationProperties("nvct.nvcf.static") + public static class StaticClientNvcfProperties { + + private String token; + } + + @Data + @RefreshScope + @Configuration + @ConditionalOnProperty("nvct.reval.static.token") + @ConfigurationProperties("nvct.reval.static") + public static class StaticClientRevalProperties { + + private String token; + } + + @Data + @RefreshScope + @Configuration + @ConditionalOnProperty("nvct.icms.static.token") + @ConfigurationProperties("nvct.icms.static") + public static class StaticClientIcmsProperties { + + private String token; + } + + @Data + @RefreshScope + @Configuration + @ConditionalOnProperty("nvct.ess.static.token") + @ConfigurationProperties("nvct.ess.static") + public static class StaticClientEssProperties { + + private String token; + } + + @Data + @RefreshScope + @Configuration + @ConditionalOnProperty("nvct.api-keys.static.token") + @ConfigurationProperties("nvct.api-keys.static") + public static class StaticClientApiKeysProperties { + + private String token; + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/grpc/GrpcSkywayService.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/grpc/GrpcSkywayService.java new file mode 100644 index 000000000..70f3f9c7c --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/grpc/GrpcSkywayService.java @@ -0,0 +1,148 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.grpc; + + +import static com.nvidia.nvct.util.NvctConstants.SCOPE_LAUNCH_TASK; +import static com.nvidia.nvct.util.NvctConstants.SCOPE_LIST_TASKS; + +import com.nvidia.boot.exceptions.ForbiddenException; +import com.nvidia.boot.exceptions.NotFoundException; +import com.nvidia.boot.exceptions.UnauthorizedException; +import com.nvidia.nvct.proto.SkywayAuthRequest; +import com.nvidia.nvct.proto.SkywayAuthResponse; +import com.nvidia.nvct.proto.SkywayGrpc; +import com.nvidia.nvct.service.account.AccountService; +import com.nvidia.nvct.service.instance.InstanceService; +import com.nvidia.nvct.service.task.TaskService; +import com.nvidia.nvct.service.token.GrpcAuthService; +import io.grpc.stub.StreamObserver; +import java.util.UUID; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import net.devh.boot.grpc.server.service.GrpcService; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.oauth2.server.resource.authentication.BearerTokenAuthenticationToken; + +@Slf4j +@GrpcService +@RequiredArgsConstructor +public class GrpcSkywayService extends SkywayGrpc.SkywayImplBase { + private final GrpcAuthService grpcAuthService; + private final AccountService accountService; + private final InstanceService instanceService; + private final TaskService taskService; + + private static final String MESG_INVALID_NCA_ID = "Permission denied for the task ID: %s"; + private static final String MESG_NO_ACTIVE_INSTANCE = "No active instances for the task ID: %s"; + private static final String SKYWAY_AUTH_SCOPE = "skyway:auth"; + + @Override + public void authGetLogs( + SkywayAuthRequest request, + StreamObserver responseObserver) { + validateAuth(); + var authentication = validateClientAuth(request, SCOPE_LIST_TASKS); + var authResponse = buildAuthResponse(request, authentication); + responseObserver.onNext(authResponse); + responseObserver.onCompleted(); + } + + + @Override + public void authExecuteCommand( + SkywayAuthRequest request, + StreamObserver responseObserver) { + validateAuth(); + var authentication = validateClientAuth(request, SCOPE_LAUNCH_TASK); + var authResponse = buildAuthResponse(request, authentication); + responseObserver.onNext(authResponse); + responseObserver.onCompleted(); + } + + @Override + public void authListInstances( + SkywayAuthRequest request, + StreamObserver responseObserver) { + validateAuth(); + var authentication = validateClientAuth(request, SCOPE_LIST_TASKS); + var authResponse = buildAuthResponse(request, authentication); + responseObserver.onNext(authResponse); + responseObserver.onCompleted(); + } + + private void validateAuth() { + var authentication = SecurityContextHolder.getContext().getAuthentication(); + if (!(authentication instanceof BearerTokenAuthenticationToken bearer)) { + throw new UnauthorizedException("Unauthorized"); + } + + grpcAuthService.validateBearer(bearer, SKYWAY_AUTH_SCOPE); + } + + private Authentication validateClientAuth( + SkywayAuthRequest clientInvokeRequest, + String targetScope) { + var bearer = new BearerTokenAuthenticationToken( + clientInvokeRequest.getClientAuthorizationToken()); + + // check if super admin invocation + if (clientInvokeRequest.hasTargetNcaId()) { + return grpcAuthService.validateBearer(bearer, "admin:" + targetScope); + } + return grpcAuthService.validateBearer(bearer, targetScope); + } + + private SkywayAuthResponse buildAuthResponse( + SkywayAuthRequest request, Authentication authentication) { + var ncaId = request.hasTargetNcaId() ? request.getTargetNcaId() + : accountService.getNcaId(authentication); + var authResponseBuilder = SkywayAuthResponse.newBuilder() + .setTaskId(request.getTaskId()) + .setClientNcaId(ncaId) + .setClientAuthSubject(authentication.getName()); + + try { + var taskId = UUID.fromString(request.getTaskId()); + var taskEntity = taskService.fetchTask(taskId); + if (!taskEntity.getNcaId().equals(ncaId)) { + var errMsg = MESG_INVALID_NCA_ID.formatted(taskId); + log.error(errMsg); + throw new ForbiddenException(errMsg); + } + + var instances = instanceService + .getInstances(taskEntity) + .orElseThrow( + () -> new NotFoundException(MESG_NO_ACTIVE_INSTANCE.formatted(taskId))) + .stream() + .map(instance -> SkywayAuthResponse.Instance.newBuilder() + .setInstanceId(instance.getInstanceId()) + .setLocation(instance.getLocation()) + .setState(instance.getInstanceState() == null ? "UNKNOWN" : + instance.getInstanceState().toString()) + .build()) + .toList(); + authResponseBuilder.addAllInstances(instances); + } catch (NotFoundException e) { + log.error(e.getMessage(), e); + throw new ForbiddenException(e.getMessage()); + } + return authResponseBuilder.build(); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/grpc/GrpcWorkerService.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/grpc/GrpcWorkerService.java new file mode 100644 index 000000000..bd5da1678 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/grpc/GrpcWorkerService.java @@ -0,0 +1,331 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.grpc; + +import static com.nvidia.nvct.persistence.task.entity.TaskStatus.ERRORED; +import static com.nvidia.nvct.persistence.task.entity.TaskStatus.EXCEEDED_MAX_RUNTIME_DURATION; +import static com.nvidia.nvct.persistence.task.entity.TaskStatus.LAUNCHED; +import static com.nvidia.nvct.persistence.task.entity.TaskStatus.QUEUED; +import static com.nvidia.nvct.persistence.task.entity.TaskStatus.RUNNING; +import static com.nvidia.nvct.proto.ExecutionStatus.TASK_CONTAINER_INITIALIZING; +import static com.nvidia.nvct.proto.ExecutionStatus.WORKER_TERMINATED; +import static com.nvidia.nvct.service.event.EventService.STATUS_CHANGE_EVENT_MESSAGE; +import static com.nvidia.nvct.service.event.EventService.STATUS_CHANGE_EVENT_MESSAGE_WITH_ERROR; +import static com.nvidia.nvct.util.NvctConstants.SPAN_TAG_TASK_ID; +import static com.nvidia.nvct.util.NvctConstants.TERMINAL_TASK_STATUSES; +import static com.nvidia.nvct.util.ProtoMappingUtils.toTimestamp; + +import tools.jackson.databind.json.JsonMapper; +import com.nvidia.boot.registries.service.registry.dto.ArtifactTypeEnum; +import com.nvidia.nvct.proto.ArtifactsRequest; +import com.nvidia.nvct.proto.ArtifactsResponse; +import com.nvidia.nvct.proto.ArtifactsResponse.ArtifactResponse; +import com.nvidia.nvct.proto.ConnectRequest; +import com.nvidia.nvct.proto.ConnectResponse; +import com.nvidia.nvct.proto.ExecutionStatus; +import com.nvidia.nvct.proto.HeartbeatRequest; +import com.nvidia.nvct.proto.HeartbeatResponse; +import com.nvidia.nvct.proto.RefreshTokenRequest; +import com.nvidia.nvct.proto.RefreshTokenResponse; +import com.nvidia.nvct.proto.ResultMetadataRequest; +import com.nvidia.nvct.proto.ResultMetadataResponse; +import com.nvidia.nvct.proto.SecretCredentialsRequest; +import com.nvidia.nvct.proto.SecretCredentialsResponse; +import com.nvidia.nvct.proto.WorkerGrpc; +import com.nvidia.nvct.service.account.AccountService; +import com.nvidia.nvct.service.event.EventService; +import com.nvidia.nvct.service.metrics.TaskErrorMetricsService; +import com.nvidia.nvct.service.metrics.TaskRunningMetricsService; +import com.nvidia.nvct.service.metrics.TaskSuccessMetricsService; +import com.nvidia.nvct.service.registry.RegistryArtifactService; +import com.nvidia.nvct.service.result.ResultService; +import com.nvidia.nvct.service.icms.IcmsService; +import com.nvidia.nvct.service.task.TaskService; +import com.nvidia.nvct.service.token.TokenService; +import com.nvidia.nvct.util.NvctUtils; +import io.grpc.stub.StreamObserver; +import io.micrometer.tracing.Tracer; +import java.time.Duration; +import java.time.Instant; +import java.util.ArrayList; +import java.util.Map; +import java.util.Objects; +import java.util.UUID; +import lombok.extern.slf4j.Slf4j; +import net.devh.boot.grpc.server.service.GrpcService; +import org.springframework.beans.factory.annotation.Value; + +@Slf4j +@GrpcService +public class GrpcWorkerService extends WorkerGrpc.WorkerImplBase { + + private static final String MESG_START_GRPC_ENDPOINT = + "Task id '{}': Starting call to gRPC endpoint '{}'"; + private static final String MESG_END_GRPC_ENDPOINT = + "Task id '{}': Completed call to gRPC endpoint '{}'"; + private static final String MESG_TASK_INFO = + "Task id '{}': {}"; + private static final String MESG_RECEIVING_HEARTBEAT_AFTER_TERMINAL_STATUS = + "Task id '{}': Receiving heartbeat after Task has reached terminal status '{}'"; + private static final String MESG_NOT_SUPPORTED_ARTIFACT_TYPE = + "Task id '%s': Received unsupported artifact type '%s'"; + private static final String MESG_TASK_CONTAINER_INITIALIZING = + "Task id '%s': Task Container initializing"; + private static final String MESG_WORKER_TERMINATED = + "Task id '%s': Worker terminated due to SIGTERM from the control plane"; + + private static final Duration VALIDITY = Duration.ofHours(3); + + private final String awsRegion; + private final TokenService tokenService; + private final IcmsService icmsService; + private final AccountService accountService; + private final RegistryArtifactService artifactService; + private final EventService eventService; + private final TaskService taskService; + private final ResultService resultService; + private final JsonMapper jsonMapper; + private final TaskRunningMetricsService taskRunningMetricsService; + private final TaskSuccessMetricsService taskSuccessMetricsService; + private final TaskErrorMetricsService taskErrorMetricsService; + private final Tracer tracer; + + public GrpcWorkerService( + TokenService tokenService, + IcmsService icmsService, + AccountService accountService, + RegistryArtifactService artifactService, + EventService eventService, + TaskService taskService, + ResultService resultService, + JsonMapper jsonMapper, + TaskRunningMetricsService taskRunningMetricsService, + TaskSuccessMetricsService taskSuccessMetricsService, + TaskErrorMetricsService taskErrorMetricsService, + Tracer tracer, + @Value("${nvct.aws.region}") String awsRegion) { + this.tokenService = tokenService; + this.icmsService = icmsService; + this.accountService = accountService; + this.artifactService = artifactService; + this.eventService = eventService; + this.taskService = taskService; + this.resultService = resultService; + this.awsRegion = awsRegion; + this.taskRunningMetricsService = taskRunningMetricsService; + this.taskSuccessMetricsService = taskSuccessMetricsService; + this.taskErrorMetricsService = taskErrorMetricsService; + this.tracer = tracer; + this.jsonMapper = jsonMapper; + } + + @Override + public void connect(ConnectRequest request, StreamObserver responseObserver) { + var taskId = UUID.fromString(request.getTaskId()); + log.info(MESG_START_GRPC_ENDPOINT, taskId, "connect"); + + var taskEntity = taskService.fetchTask(taskId); + var ncaId = taskEntity.getNcaId(); + + tokenService.validateWorkerAccessAssertion(ncaId, taskId); + NvctUtils.addTagsToCurrentSpan(tracer, Map.of(SPAN_TAG_TASK_ID, request.getTaskId())); + + if (taskEntity.getStatus() == QUEUED) { + taskService.updateTask(taskId, LAUNCHED); + var mesg = STATUS_CHANGE_EVENT_MESSAGE.formatted(QUEUED, LAUNCHED); + log.info(MESG_TASK_INFO, taskId, mesg); + eventService.insertEvent(ncaId, taskId, mesg); + } + responseObserver.onNext(ConnectResponse.newBuilder() + .setConnectedRegion(awsRegion).build()); + responseObserver.onCompleted(); + log.info(MESG_END_GRPC_ENDPOINT, taskId, "connect"); + } + + @Override + public void sendHeartbeat( + HeartbeatRequest request, + StreamObserver responseObserver) { + var taskId = UUID.fromString(request.getTaskId()); + var uniqueStrForLogs = "sendHeartbeat-" + Instant.now().getEpochSecond(); + log.info(MESG_START_GRPC_ENDPOINT, taskId, uniqueStrForLogs); + + var taskEntity = taskService.fetchTask(taskId); + var ncaId = taskEntity.getNcaId(); + + tokenService.validateWorkerAccessAssertion(ncaId, taskId); + NvctUtils.addTagsToCurrentSpan(tracer, Map.of(SPAN_TAG_TASK_ID, request.getTaskId())); + + if (TERMINAL_TASK_STATUSES.contains(taskEntity.getStatus())) { + // Ignore heartbeat once the Task has already reached terminal status. + var status = taskEntity.getStatus(); + log.warn(MESG_RECEIVING_HEARTBEAT_AFTER_TERMINAL_STATUS, taskId, status); + } else { + if (request.hasErrorMessage()) { + // Map ExecutionStatus in proto to TaskStatus. + var status = request.getStatus() == ExecutionStatus.EXCEEDED_MAX_RUNTIME_DURATION ? + EXCEEDED_MAX_RUNTIME_DURATION : ERRORED; + var errorMessage = request.getErrorMessage(); + var mesg = STATUS_CHANGE_EVENT_MESSAGE_WITH_ERROR + .formatted(taskEntity.getStatus(), status, errorMessage); + log.info(MESG_TASK_INFO, taskId, mesg); + taskService.updateTask(taskId, status, + icmsService.getHealthDto(taskId, + request.getInstanceType(), + errorMessage)); + log.info(MESG_TASK_INFO, taskId, "Updated with terminal status " + status); + eventService.insertEvent(ncaId, taskId, mesg); + } else if (taskEntity.getStatus() == LAUNCHED) { + if (request.getStatus() == TASK_CONTAINER_INITIALIZING) { + var mesg = MESG_TASK_CONTAINER_INITIALIZING.formatted(taskId); + log.info(mesg); + taskService.updateTask(taskId); // Update lastUpdatedAt timestamp + } else if (request.getStatus() == WORKER_TERMINATED) { + // If worker's control plane fails to pull the container image or helm chart, + // either due to bad registry credentials or incorrect URL in the Task + // definition, then NVCT/NEWT will first send the error information to ICMS and + // then send SIGTERM signal to the Utils Container. On receiving the SIGTERM + // signal, Utils Container will send a heartbeat with WORKER_TERMINATED + // ExecutionStatus to the NVCT API. NVCT API will just ignore such a heartbeat + // and NOT update the Task's lastUpdatedAt timestamp so that the async + // MonitorLaunchedTaskRoutine can get the health information from ICMS during + // the next iteration. This way, the user can see the actual error message that + // the control plane received when pulling the container image or helm chart. + var mesg = MESG_WORKER_TERMINATED.formatted(taskId); + log.info(mesg); + } else { + var mesg = STATUS_CHANGE_EVENT_MESSAGE.formatted(LAUNCHED, RUNNING); + log.info(MESG_TASK_INFO, taskId, mesg); + taskService.updateTask(taskId, RUNNING, Instant.now()); + eventService.insertEvent(ncaId, taskId, mesg); + var accountName = accountService.getAccountName(ncaId); + taskRunningMetricsService.recordRunningTask(ncaId, accountName); + } + } else if (taskEntity.getStatus() == RUNNING) { + log.info(MESG_TASK_INFO, taskId, "Received heartbeat"); + taskService.updateTask(taskId, Instant.now()); + } + } + responseObserver.onNext(HeartbeatResponse.newBuilder() + .setTaskId(taskId.toString()) + .setExecutionStatus(taskEntity.getStatus().toString()) + .build()); + responseObserver.onCompleted(); + log.info(MESG_END_GRPC_ENDPOINT, taskId, uniqueStrForLogs); + } + + @Override + public void getArtifacts( + ArtifactsRequest request, + StreamObserver responseObserver) { + var taskId = UUID.fromString(request.getTaskId()); + log.info(MESG_START_GRPC_ENDPOINT, taskId, "getArtifacts"); + + var ncaId = taskService.fetchTask(taskId).getNcaId(); + tokenService.validateWorkerAccessAssertion(ncaId, taskId); + NvctUtils.addTagsToCurrentSpan(tracer, Map.of(SPAN_TAG_TASK_ID, request.getTaskId())); + + var artifacts = artifactService.getPresignedUrls(ncaId, taskId); + var artifactResponse = new ArrayList(); + for (var artifact : artifacts) { + var files = new ArrayList(); + for (var file : artifact.files()) { + files.add(ArtifactResponse.ArtifactFile.newBuilder() + .setPath(Objects.requireNonNullElse(file.path(), "")) + .setUrl(file.url()) + .build()); + } + var kind = switch (artifact.artifactType()) { + case ArtifactTypeEnum.MODEL -> ArtifactResponse.ArtifactKindEnum.MODEL; + case ArtifactTypeEnum.RESOURCE -> ArtifactResponse.ArtifactKindEnum.RESOURCE; + default -> { + var errorMsg = MESG_NOT_SUPPORTED_ARTIFACT_TYPE.formatted(taskId, + artifact.artifactType()); + log.error(errorMsg); + throw new IllegalStateException(errorMsg); + } + }; + artifactResponse.add(ArtifactResponse.newBuilder() + .setKind(kind) + .setName(artifact.name()) + .setVersion(artifact.version()) + .addAllFiles(files) + .build()); + } + var response = ArtifactsResponse.newBuilder() + .addAllArtifacts(artifactResponse) + .build(); + responseObserver.onNext(response); + responseObserver.onCompleted(); + log.info(MESG_END_GRPC_ENDPOINT, taskId, "getArtifacts"); + } + + @Override + public StreamObserver sendResultMetadata( + StreamObserver responseObserver) { + return new ResultMetadataStreamObserver(responseObserver, + taskService, + tokenService, + eventService, + resultService, + icmsService, + taskSuccessMetricsService, + taskErrorMetricsService, + jsonMapper, + tracer); + } + + @Override + public void refreshToken( + RefreshTokenRequest request, + StreamObserver responseObserver) { + var taskId = UUID.fromString(request.getTaskId()); + log.info(MESG_START_GRPC_ENDPOINT, taskId, "refreshToken"); + + var ncaId = taskService.fetchTask(taskId).getNcaId(); + tokenService.validateWorkerAccessAssertion(ncaId, taskId); + NvctUtils.addTagsToCurrentSpan(tracer, Map.of(SPAN_TAG_TASK_ID, request.getTaskId())); + + var newToken = tokenService.issueWorkerAccessAssertion(ncaId, taskId); + var response = RefreshTokenResponse.newBuilder().setToken(newToken).build(); + responseObserver.onNext(response); + responseObserver.onCompleted(); + log.info(MESG_END_GRPC_ENDPOINT, taskId, "refreshToken"); + } + + @Override + public void requestSecretCredentials( + SecretCredentialsRequest request, + StreamObserver responseObserver) { + var taskId = UUID.fromString(request.getTaskId()); + log.info(MESG_START_GRPC_ENDPOINT, taskId, "requestSecretCredentials"); + + var task = taskService.fetchTask(taskId); + var ncaId = task.getNcaId(); + tokenService.validateWorkerAccessAssertion(ncaId, taskId); + NvctUtils.addTagsToCurrentSpan(tracer, Map.of(SPAN_TAG_TASK_ID, request.getTaskId())); + + var assertionToken = tokenService.issueSecretsAssertion(task); + var response = SecretCredentialsResponse.newBuilder() + .setSecretCredentialsToken(assertionToken) + .setExpiration(toTimestamp(Instant.now().plus(VALIDITY))).build(); + responseObserver.onNext(response); + responseObserver.onCompleted(); + log.info(MESG_END_GRPC_ENDPOINT, taskId, "requestSecretCredentials"); + } + +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/grpc/ResultMetadataStreamObserver.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/grpc/ResultMetadataStreamObserver.java new file mode 100644 index 000000000..4344f1c0b --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/grpc/ResultMetadataStreamObserver.java @@ -0,0 +1,242 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.grpc; + +import static com.nvidia.nvct.persistence.task.entity.TaskStatus.COMPLETED; +import static com.nvidia.nvct.persistence.task.entity.TaskStatus.ERRORED; +import static com.nvidia.nvct.persistence.task.entity.TaskStatus.EXCEEDED_MAX_RUNTIME_DURATION; +import static com.nvidia.nvct.persistence.task.entity.TaskStatus.RUNNING; +import static com.nvidia.nvct.service.event.EventService.STATUS_CHANGE_EVENT_MESSAGE; +import static com.nvidia.nvct.service.event.EventService.STATUS_CHANGE_EVENT_MESSAGE_WITH_ERROR; +import static com.nvidia.nvct.util.NvctConstants.SPAN_TAG_TASK_ID; +import static com.nvidia.nvct.util.NvctConstants.TERMINAL_TASK_STATUSES; + +import tools.jackson.core.JacksonException; +import tools.jackson.databind.json.JsonMapper; +import tools.jackson.databind.node.ObjectNode; +import com.google.protobuf.ByteString; +import com.nvidia.nvct.persistence.task.entity.TaskStatus; +import com.nvidia.nvct.proto.ResultMetadataRequest; +import com.nvidia.nvct.proto.ResultMetadataResponse; +import com.nvidia.nvct.rest.task.dto.HealthDto; +import com.nvidia.nvct.service.event.EventService; +import com.nvidia.nvct.service.metrics.TaskErrorMetricsService; +import com.nvidia.nvct.service.metrics.TaskSuccessMetricsService; +import com.nvidia.nvct.service.result.ResultService; +import com.nvidia.nvct.service.icms.IcmsService; +import com.nvidia.nvct.service.task.TaskService; +import com.nvidia.nvct.service.token.TokenService; +import com.nvidia.nvct.util.NvctUtils; +import io.grpc.stub.StreamObserver; +import io.micrometer.tracing.Tracer; +import java.time.Instant; +import java.util.Map; +import java.util.Optional; +import java.util.UUID; +import lombok.NonNull; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; + +@Slf4j +public class ResultMetadataStreamObserver implements StreamObserver { + private static final String MESG_TASK_ERROR = + "Task id '%s': Worker error '%s', status '%s', details '%s'"; + private static final String MESG_INVALID_STATUS = + "Task id '%s': Invalid ExecutionStatus %s"; + private static final String MESG_INVALID_METADATA = + "Task id '%s': Invalid ResultMetadata %s"; + + private static final String MESG_TASK_INFO = + "Task id '{}': {}"; + private static final String MESG_START_GRPC_ENDPOINT = + "Task id '{}': Starting call to gRPC endpoint 'SendResultMetadata' with ExecutionStatus '{}'"; + private static final String MESG_END_GRPC_ENDPOINT = + "Task id '{}': Completed gRPC call 'SendResultMetadata'"; + private static final String MESG_RECEIVING_RESULT_AFTER_TERMINAL_STATUS = + "Task id '{}': Receiving result metadata after Task has reached terminal status '{}'"; + private static final String MESG_LOG_PERCENT_COMPLETE = + "Task id '{}': '{}' percent complete"; + private static final String MESG_ERROR_IN_SEND_RESULT_METADATA = + "Encountered error in sendResultMetadata"; + + private final StreamObserver responseObserver; + private final TaskService taskService; + private final TokenService tokenService; + private final EventService eventService; + private final ResultService resultService; + private final IcmsService icmsService; + private final JsonMapper jsonMapper; + private final TaskSuccessMetricsService taskSuccessMetricsService; + private final TaskErrorMetricsService taskErrorMetricsService; + private final Tracer tracer; + + private UUID taskId; + private TaskStatus executionStatus; + + public ResultMetadataStreamObserver( + StreamObserver responseObserver, + TaskService taskService, + TokenService tokenService, + EventService eventService, + ResultService resultService, + IcmsService icmsService, + TaskSuccessMetricsService taskSuccessMetricsService, + TaskErrorMetricsService taskErrorMetricsService, + JsonMapper jsonMapper, + Tracer tracer) { + this.responseObserver = responseObserver; + this.taskService = taskService; + this.tokenService = tokenService; + this.eventService = eventService; + this.resultService = resultService; + this.icmsService = icmsService; + this.taskSuccessMetricsService = taskSuccessMetricsService; + this.taskErrorMetricsService = taskErrorMetricsService; + this.jsonMapper = jsonMapper; + this.tracer = tracer; + } + + @Override + public void onNext(ResultMetadataRequest request) { + this.taskId = UUID.fromString(request.getTaskId()); + log.info(MESG_START_GRPC_ENDPOINT, taskId, request.getStatus().name()); + var taskEntity = taskService.fetchTask(taskId); + this.executionStatus = taskEntity.getStatus(); + // Ignore result metadata if the Task has reached terminal status. + if (TERMINAL_TASK_STATUSES.contains(taskEntity.getStatus())) { + log.warn(MESG_RECEIVING_RESULT_AFTER_TERMINAL_STATUS, taskId, taskEntity.getStatus()); + log.info(MESG_END_GRPC_ENDPOINT, taskId); + return; + } + + var ncaId = taskEntity.getNcaId(); + tokenService.validateWorkerAccessAssertion(ncaId, taskId); + NvctUtils.addTagsToCurrentSpan(tracer, Map.of(SPAN_TAG_TASK_ID, request.getTaskId())); + + Optional percentComplete = request.hasPercentComplete() ? + Optional.of(request.getPercentComplete()) : Optional.empty(); + var errorMessage = StringUtils.EMPTY; + + var status = switch (request.getStatus()) { + case IN_PROGRESS -> { + log.debug(MESG_LOG_PERCENT_COMPLETE, taskId, percentComplete); + validateResultMetadata(taskId, request.getMetadata().getBody()); + var metaData = includePercentCompleteInMetadata(request); + taskSuccessMetricsService.recordTaskSuccess(ncaId); // Record for every result. + resultService.insertResult(taskEntity, request.getResultName(), metaData); + yield RUNNING; + } + case ERRORED -> { + var errorDetail = errorDetail(taskId, request); + taskService.updateTask(taskId, ERRORED, errorDetail); + taskErrorMetricsService.recordTaskError(ncaId); + errorMessage = request.getErrorDetails().getDetail(); + yield ERRORED; + } + case EXCEEDED_MAX_RUNTIME_DURATION -> { + var errorDetail = errorDetail(taskId, request); + taskService.updateTask(taskId, EXCEEDED_MAX_RUNTIME_DURATION, errorDetail); + taskErrorMetricsService.recordTaskError(ncaId); + errorMessage = request.getErrorDetails().getDetail(); + yield EXCEEDED_MAX_RUNTIME_DURATION; + } + case COMPLETED -> { + validateResultMetadata(taskId, request.getMetadata().getBody()); + var metaData = includePercentCompleteInMetadata(request); + resultService.insertResult(taskEntity, request.getResultName(), metaData); + taskSuccessMetricsService.recordTaskSuccess(ncaId); // Record when completed. + icmsService.terminateInstanceByTaskId(ncaId, taskId); + yield COMPLETED; + } + default -> { + var mesg = MESG_INVALID_STATUS.formatted(taskId, request.getStatus()); + log.error(mesg); + throw new IllegalArgumentException(mesg); + } + }; + + taskService.updateTask(taskId, status, Instant.now(), percentComplete); + if (taskEntity.getStatus() != status) { + var mesg = StringUtils.isBlank(errorMessage) ? + STATUS_CHANGE_EVENT_MESSAGE.formatted(taskEntity.getStatus(), status) : + STATUS_CHANGE_EVENT_MESSAGE_WITH_ERROR + .formatted(taskEntity.getStatus(), status, errorMessage); + log.info(MESG_TASK_INFO, taskId, mesg); + eventService.insertEvent(ncaId, taskId, mesg); + } + log.info(MESG_END_GRPC_ENDPOINT, taskId); + } + + @Override + public void onError(Throwable throwable) { + log.error(MESG_ERROR_IN_SEND_RESULT_METADATA, throwable); + responseObserver.onError(throwable); + } + + @Override + public void onCompleted() { + responseObserver.onNext(ResultMetadataResponse.newBuilder() + .setExecutionStatus(executionStatus.toString()) + .setTaskId(taskId.toString()) + .build()); + responseObserver.onCompleted(); + } + + private void validateResultMetadata(@NonNull UUID taskId, ByteString body) { + var metadata = body.toStringUtf8(); + + if (StringUtils.isBlank(metadata)) { + return; + } + + try { + jsonMapper.readValue(metadata, ObjectNode.class); + } catch (JacksonException e) { + var mesg = MESG_INVALID_METADATA.formatted(taskId, metadata); + log.error(mesg); + throw new IllegalArgumentException(mesg, e); + } + } + + @SneakyThrows + private String includePercentCompleteInMetadata(@NonNull ResultMetadataRequest request) { + var rawJson = request.getMetadata().getBody().toStringUtf8(); + if (request.hasPercentComplete()) { + // Utils Container can marshall a "null" value as result metadata. It gets + // deserialized as NullNode and cause ClassCastException when it is cast as + // ObjectNode. + var objectNode = StringUtils.isBlank(rawJson) || rawJson.equals("null") ? + jsonMapper.createObjectNode() : (ObjectNode) jsonMapper.readTree(rawJson); + objectNode.put("percentComplete", request.getPercentComplete()); + return jsonMapper.writeValueAsString(objectNode); + } + return rawJson; + } + + private HealthDto errorDetail( + UUID taskId, + ResultMetadataRequest request) { + var errorDetails = request.getErrorDetails(); + var mesg = MESG_TASK_ERROR.formatted(taskId, + errorDetails.getType(), + errorDetails.getStatus(), + errorDetails.getDetail()); + return icmsService.getHealthDto(taskId, request.getInstanceType(), mesg); + } + +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/grpc/auth/AuthHeaderPassthroughServerHttpRequest.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/grpc/auth/AuthHeaderPassthroughServerHttpRequest.java new file mode 100644 index 000000000..46170543e --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/grpc/auth/AuthHeaderPassthroughServerHttpRequest.java @@ -0,0 +1,47 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.grpc.auth; + +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletRequestWrapper; +import java.lang.reflect.Proxy; +import org.springframework.http.HttpHeaders; +import org.springframework.security.oauth2.server.resource.authentication.BearerTokenAuthenticationToken; + +public class AuthHeaderPassthroughServerHttpRequest extends HttpServletRequestWrapper { + + private static final HttpServletRequest UNSUPPORTED_REQUEST = (HttpServletRequest) Proxy.newProxyInstance( + AuthHeaderPassthroughServerHttpRequest.class.getClassLoader(), + new Class[]{HttpServletRequest.class}, (proxy, method, args) -> { + throw new UnsupportedOperationException(method + " is not supported"); + }); + + private final BearerTokenAuthenticationToken authentication; + + public AuthHeaderPassthroughServerHttpRequest(BearerTokenAuthenticationToken authentication) { + super(UNSUPPORTED_REQUEST); + this.authentication = authentication; + } + + @Override + public String getHeader(String name) { + if (HttpHeaders.AUTHORIZATION.equalsIgnoreCase(name)) { // Header names are case-insensitive + return "Bearer " + this.authentication.getToken(); + } + return null; + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/grpc/auth/SecurityExpression.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/grpc/auth/SecurityExpression.java new file mode 100644 index 000000000..2b7eecae3 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/grpc/auth/SecurityExpression.java @@ -0,0 +1,36 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.grpc.auth; + +import org.springframework.security.access.expression.SecurityExpressionRoot; +import org.springframework.security.core.Authentication; + +public class SecurityExpression extends SecurityExpressionRoot { + + public SecurityExpression(Authentication authentication) { + if (authentication == null) { + throw new IllegalArgumentException("authentication cannot be null"); + } + + super(() -> authentication, null); + + if (!authentication.isAuthenticated()) { + throw new IllegalStateException( + "security expression only usable with authenticated principals"); + } + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/persistence/event/EventsByTaskRepository.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/persistence/event/EventsByTaskRepository.java new file mode 100644 index 000000000..b3630a755 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/persistence/event/EventsByTaskRepository.java @@ -0,0 +1,41 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.persistence.event; + +import com.nvidia.nvct.persistence.event.entity.EventByTaskEntity; +import com.nvidia.nvct.persistence.event.entity.EventByTaskKey; +import java.util.Optional; +import java.util.UUID; +import java.util.stream.Stream; +import org.springframework.data.cassandra.repository.CassandraRepository; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Slice; +import org.springframework.stereotype.Repository; + +@Repository +public interface EventsByTaskRepository + extends CassandraRepository { + + Optional getByKeyTaskIdAndKeyEventId(UUID taskId, UUID eventId); + + Stream findByKeyTaskId(UUID taskId); + + Slice findByKeyTaskId(UUID taskId, Pageable pageable); + + void deleteByKeyTaskId(UUID taskId); + +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/persistence/event/entity/EventByTaskEntity.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/persistence/event/entity/EventByTaskEntity.java new file mode 100644 index 000000000..8c14b7759 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/persistence/event/entity/EventByTaskEntity.java @@ -0,0 +1,61 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.persistence.event.entity; + +import java.time.Instant; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.NonNull; +import org.springframework.data.annotation.PersistenceCreator; +import org.springframework.data.cassandra.core.mapping.Column; +import org.springframework.data.cassandra.core.mapping.PrimaryKey; +import org.springframework.data.cassandra.core.mapping.Table; + +@Builder(toBuilder = true) +@Data +@NoArgsConstructor +@AllArgsConstructor(onConstructor_ = @PersistenceCreator) +@Table(EventByTaskEntity.TABLE_NAME) +public class EventByTaskEntity { + + public static final String TABLE_NAME = "events_by_task"; + + public static final String COLUMN_TASK_ID = "task_id"; + public static final String COLUMN_EVENT_ID = "event_id"; + public static final String COLUMN_NCA_ID = "nca_id"; + public static final String COLUMN_MESSAGE = "message"; + public static final String COLUMN_CREATED_AT = "created_at"; + + @NonNull + @PrimaryKey + private EventByTaskKey key; + + @NonNull + @Column(COLUMN_NCA_ID) + private String ncaId; + + @NonNull + @Column(COLUMN_MESSAGE) + private String message; + + @Column(COLUMN_CREATED_AT) + @Builder.Default + private Instant createdAt = Instant.now(); + +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/persistence/event/entity/EventByTaskKey.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/persistence/event/entity/EventByTaskKey.java new file mode 100644 index 000000000..1d7f9bb55 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/persistence/event/entity/EventByTaskKey.java @@ -0,0 +1,49 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.persistence.event.entity; + + +import static com.nvidia.nvct.persistence.event.entity.EventByTaskEntity.COLUMN_EVENT_ID; +import static com.nvidia.nvct.persistence.event.entity.EventByTaskEntity.COLUMN_TASK_ID; + +import java.io.Serializable; +import java.util.UUID; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.NonNull; +import org.springframework.data.cassandra.core.cql.PrimaryKeyType; +import org.springframework.data.cassandra.core.mapping.PrimaryKeyClass; +import org.springframework.data.cassandra.core.mapping.PrimaryKeyColumn; + +@Builder(toBuilder = true) +@Data +@NoArgsConstructor +@AllArgsConstructor +@PrimaryKeyClass +public class EventByTaskKey implements Serializable { + + @NonNull + @PrimaryKeyColumn(name = COLUMN_TASK_ID, ordinal = 0, type = PrimaryKeyType.PARTITIONED) + private UUID taskId; + + @NonNull + @PrimaryKeyColumn(name = COLUMN_EVENT_ID, ordinal = 1, type = PrimaryKeyType.CLUSTERED) + private UUID eventId; + +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/persistence/result/ResultsByTaskRepository.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/persistence/result/ResultsByTaskRepository.java new file mode 100644 index 000000000..e770e77cc --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/persistence/result/ResultsByTaskRepository.java @@ -0,0 +1,41 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.persistence.result; + +import com.nvidia.nvct.persistence.result.entity.ResultByTaskEntity; +import com.nvidia.nvct.persistence.result.entity.ResultByTaskKey; +import java.util.Optional; +import java.util.UUID; +import java.util.stream.Stream; +import org.springframework.data.cassandra.repository.CassandraRepository; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Slice; +import org.springframework.stereotype.Repository; + +@Repository +public interface ResultsByTaskRepository + extends CassandraRepository { + + Optional getByKeyTaskIdAndKeyResultId(UUID taskId, UUID resultId); + + Stream findByKeyTaskId(UUID taskId); + + Slice findByKeyTaskId(UUID taskId, Pageable pageable); + + void deleteByKeyTaskId(UUID taskId); + +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/persistence/result/entity/ResultByTaskEntity.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/persistence/result/entity/ResultByTaskEntity.java new file mode 100644 index 000000000..3b9151510 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/persistence/result/entity/ResultByTaskEntity.java @@ -0,0 +1,66 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.persistence.result.entity; + +import java.time.Instant; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.NonNull; +import org.springframework.data.annotation.PersistenceCreator; +import org.springframework.data.cassandra.core.mapping.Column; +import org.springframework.data.cassandra.core.mapping.PrimaryKey; +import org.springframework.data.cassandra.core.mapping.Table; + +@Builder(toBuilder = true) +@Data +@NoArgsConstructor +@AllArgsConstructor(onConstructor_ = @PersistenceCreator) +@Table(ResultByTaskEntity.TABLE_NAME) +public class ResultByTaskEntity { + + public static final String TABLE_NAME = "results_by_task"; + + public static final String COLUMN_TASK_ID = "task_id"; + public static final String COLUMN_RESULT_ID = "result_id"; + public static final String COLUMN_NCA_ID = "nca_id"; + public static final String COLUMN_NAME = "name"; + public static final String COLUMN_METADATA = "metadata"; + public static final String COLUMN_CREATED_AT = "created_at"; + + @NonNull + @PrimaryKey + private ResultByTaskKey key; + + @NonNull + @Column(COLUMN_NCA_ID) + private String ncaId; + + @NonNull + @Column(COLUMN_NAME) + private String name; + + @NonNull + @Column(COLUMN_METADATA) + private String metadata; + + @Column(COLUMN_CREATED_AT) + @Builder.Default + private Instant createdAt = Instant.now(); + +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/persistence/result/entity/ResultByTaskKey.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/persistence/result/entity/ResultByTaskKey.java new file mode 100644 index 000000000..b6c821c97 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/persistence/result/entity/ResultByTaskKey.java @@ -0,0 +1,49 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.persistence.result.entity; + + +import static com.nvidia.nvct.persistence.result.entity.ResultByTaskEntity.COLUMN_RESULT_ID; +import static com.nvidia.nvct.persistence.result.entity.ResultByTaskEntity.COLUMN_TASK_ID; + +import java.io.Serializable; +import java.util.UUID; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.NonNull; +import org.springframework.data.cassandra.core.cql.PrimaryKeyType; +import org.springframework.data.cassandra.core.mapping.PrimaryKeyClass; +import org.springframework.data.cassandra.core.mapping.PrimaryKeyColumn; + +@Builder(toBuilder = true) +@Data +@NoArgsConstructor +@AllArgsConstructor +@PrimaryKeyClass +public class ResultByTaskKey implements Serializable { + + @NonNull + @PrimaryKeyColumn(name = COLUMN_TASK_ID, ordinal = 0, type = PrimaryKeyType.PARTITIONED) + private UUID taskId; + + @NonNull + @PrimaryKeyColumn(name = COLUMN_RESULT_ID, ordinal = 1, type = PrimaryKeyType.CLUSTERED) + private UUID resultId; + +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/persistence/task/TasksRepository.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/persistence/task/TasksRepository.java new file mode 100644 index 000000000..17da3184b --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/persistence/task/TasksRepository.java @@ -0,0 +1,43 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.persistence.task; + +import com.nvidia.nvct.persistence.task.entity.TaskEntity; +import java.util.Optional; +import java.util.UUID; +import java.util.stream.Stream; +import org.springframework.data.cassandra.repository.CassandraRepository; +import org.springframework.data.cassandra.repository.Query; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Slice; +import org.springframework.data.repository.query.Param; +import org.springframework.stereotype.Repository; + +@Repository +public interface TasksRepository extends CassandraRepository { + + Optional getByTaskId(UUID taskId); + + Slice findByNcaId(String ncaId, Pageable pageable); + + Slice findAllBy(Pageable pageable); + + Stream findByNcaId(String ncaId); + + @Query("SELECT COUNT(*) FROM tasks_v2 WHERE nca_id=:ncaId") + long countByNcaId(@Param("ncaId") String ncaId); +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/persistence/task/entity/ArtifactUdt.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/persistence/task/entity/ArtifactUdt.java new file mode 100644 index 000000000..1cd94879e --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/persistence/task/entity/ArtifactUdt.java @@ -0,0 +1,26 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.persistence.task.entity; + +public interface ArtifactUdt { + String getName(); + + String getVersion(); + + String getUrl(); + +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/persistence/task/entity/GpuSpecUdt.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/persistence/task/entity/GpuSpecUdt.java new file mode 100644 index 000000000..cc5f79572 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/persistence/task/entity/GpuSpecUdt.java @@ -0,0 +1,80 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.persistence.task.entity; + +import jakarta.annotation.Nullable; +import java.util.Set; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.NonNull; +import org.springframework.data.annotation.PersistenceCreator; +import org.springframework.data.cassandra.core.mapping.Column; +import org.springframework.data.cassandra.core.mapping.UserDefinedType; + +@Data +@Builder +@AllArgsConstructor(onConstructor_ = @PersistenceCreator) +@NoArgsConstructor +@UserDefinedType(GpuSpecUdt.USER_DEFINED_TYPE_NAME) +public class GpuSpecUdt { + + public static final String USER_DEFINED_TYPE_NAME = "gpu_spec_udt"; + + @NonNull + @Column("instance_type") + private String instanceType; + + @NonNull + @Column("gpu") + private String gpu; + + @Nullable + @Column("backend") + private String backend; + + @Nullable + @Column("max_request_concurrency") + private Integer maxRequestConcurrency; + + @Nullable + @Column("configuration") + private String configuration; + + @Nullable + @Column("clusters") + private Set clusters; + + @Nullable + @Column("regions") + private Set regions; + + @Nullable + @Column("attributes") + private Set attributes; + + /** + * Serialized {@link com.nvidia.nvct.rest.task.dto.HelmValidationPolicyDto} JSON. + * Null for tasks created before helm validation policy support was added. + */ + @Nullable + @Column("helm_validation_policy") + private String helmValidationPolicy; + +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/persistence/task/entity/HealthUdt.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/persistence/task/entity/HealthUdt.java new file mode 100644 index 000000000..45e15ddc7 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/persistence/task/entity/HealthUdt.java @@ -0,0 +1,67 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.persistence.task.entity; + +import jakarta.annotation.Nonnull; +import jakarta.validation.constraints.NotBlank; +import java.util.UUID; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.springframework.data.annotation.PersistenceCreator; +import org.springframework.data.cassandra.core.mapping.Column; +import org.springframework.data.cassandra.core.mapping.UserDefinedType; + +@Data +@Builder +@AllArgsConstructor(onConstructor_ = @PersistenceCreator) +@NoArgsConstructor +@UserDefinedType(HealthUdt.USER_DEFINED_TYPE_NAME) +public class HealthUdt { + public static final String USER_DEFINED_TYPE_NAME = "health_udt"; + + @Nonnull + @Column("sis_request_id") + private UUID legacyIcmsRequestId; + + @NotBlank + @Column("gpu") + private String gpu; + + @NotBlank + @Column("backend") + private String backend; + + @NotBlank + @Column("instance_type") + private String instanceType; + + @NotBlank + @Column("error") + private String error; + + @Override + public String toString() { + return "ICMS request-id " + legacyIcmsRequestId + "; " + + "GPU " + gpu + "; " + + "Instance Type " + instanceType + "; " + + "Backend " + backend + "; " + + "Error " + error; + + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/persistence/task/entity/ModelUdt.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/persistence/task/entity/ModelUdt.java new file mode 100644 index 000000000..4d0d79383 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/persistence/task/entity/ModelUdt.java @@ -0,0 +1,44 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.persistence.task.entity; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.springframework.data.annotation.PersistenceCreator; +import org.springframework.data.cassandra.core.mapping.Column; +import org.springframework.data.cassandra.core.mapping.UserDefinedType; + +@Data +@Builder +@AllArgsConstructor(onConstructor_ = @PersistenceCreator) +@NoArgsConstructor +@UserDefinedType(ModelUdt.USER_DEFINED_TYPE_NAME) +public class ModelUdt implements ArtifactUdt { + public static final String USER_DEFINED_TYPE_NAME = "model_udt"; + + @Column("name") + private String name; + + @Column("version") + private String version; + + @Column("url") + private String url; + +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/persistence/task/entity/ResourceUdt.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/persistence/task/entity/ResourceUdt.java new file mode 100644 index 000000000..46290a8f4 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/persistence/task/entity/ResourceUdt.java @@ -0,0 +1,44 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.persistence.task.entity; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.springframework.data.annotation.PersistenceCreator; +import org.springframework.data.cassandra.core.mapping.Column; +import org.springframework.data.cassandra.core.mapping.UserDefinedType; + +@Data +@Builder +@AllArgsConstructor(onConstructor_ = @PersistenceCreator) +@NoArgsConstructor +@UserDefinedType(ResourceUdt.USER_DEFINED_TYPE_NAME) +public class ResourceUdt implements ArtifactUdt { + public static final String USER_DEFINED_TYPE_NAME = "resource_udt"; + + @Column("name") + private String name; + + @Column("version") + private String version; + + @Column("url") + private String url; + +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/persistence/task/entity/ResultHandlingStrategy.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/persistence/task/entity/ResultHandlingStrategy.java new file mode 100644 index 000000000..99f3ccbd1 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/persistence/task/entity/ResultHandlingStrategy.java @@ -0,0 +1,48 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.persistence.task.entity; + +import static java.lang.String.format; + +import java.util.EnumSet; +import lombok.NonNull; + +public enum ResultHandlingStrategy { + + UPLOAD("UPLOAD"), + NONE("NONE"); + + private final String name; + + ResultHandlingStrategy(String name) { + this.name = name; + } + + @Override + public String toString() { + return this.name; + } + + public static ResultHandlingStrategy fromText(@NonNull String val) { + return EnumSet.allOf(ResultHandlingStrategy.class) + .stream() + .filter(e -> e.name.equalsIgnoreCase(val)) + .findFirst() + .orElseThrow(() -> new IllegalStateException(format("Unsupported enum %s.", val))); + } + +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/persistence/task/entity/TaskEntity.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/persistence/task/entity/TaskEntity.java new file mode 100644 index 000000000..98cd3ff49 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/persistence/task/entity/TaskEntity.java @@ -0,0 +1,184 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.persistence.task.entity; + +import jakarta.annotation.Nullable; +import java.time.Duration; +import java.time.Instant; +import java.util.Objects; +import java.util.Set; +import java.util.UUID; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.NonNull; +import org.springframework.data.annotation.PersistenceCreator; +import org.springframework.data.cassandra.core.mapping.CassandraType; +import org.springframework.data.cassandra.core.mapping.Column; +import org.springframework.data.cassandra.core.mapping.PrimaryKey; +import org.springframework.data.cassandra.core.mapping.Table; + +@Builder(toBuilder = true) +@Data +@NoArgsConstructor +@AllArgsConstructor(onConstructor_ = @PersistenceCreator) +@Table(TaskEntity.TABLE_NAME) +public class TaskEntity { + public static final String TABLE_NAME = "tasks_v2"; + + public static final String COLUMN_TASK_ID = "task_id"; + public static final String COLUMN_NCA_ID = "nca_id"; + public static final String COLUMN_NAME = "name"; + public static final String COLUMN_STATUS = "status"; + public static final String COLUMN_HEALTH = "health"; + public static final String COLUMN_HEALTH_INFO = "health_info"; + public static final String COLUMN_PERCENT_COMPLETE = "percent_complete"; + public static final String COLUMN_LAST_HEARTBEAT_AT = "last_heartbeat_at"; + public static final String COLUMN_LAST_UPDATED_AT = "last_updated_at"; + public static final String COLUMN_CREATED_AT = "created_at"; + public static final String COLUMN_CONTAINER_IMAGE = "container_image"; + public static final String COLUMN_CONTAINER_ARGS = "container_args"; + public static final String COLUMN_CONTAINER_ENVIRONMENT = "container_environment"; + public static final String COLUMN_MODELS = "models"; + public static final String COLUMN_RESOURCES = "resources"; + public static final String COLUMN_DESCRIPTION = "description"; + public static final String COLUMN_TAGS = "tags"; + public static final String COLUMN_MAX_RUNTIME_DURATION = "max_runtime_duration"; + public static final String COLUMN_MAX_QUEUED_DURATION = "max_queued_duration"; + public static final String COLUMN_TERMINAL_GRACE_PERIOD_DURATION = + "terminal_grace_period_duration"; + public static final String COLUMN_RESULT_HANDLING_STRATEGY = "result_handling_strategy"; + public static final String COLUMN_RESULTS_LOCATION = "results_location"; + public static final String COLUMN_HELM_CHART = "helm_chart"; + public static final String COLUMN_TELEMETRIES = "telemetries"; + public static final String COLUMN_GPU_SPEC = "gpu_spec"; + public static final String COLUMN_HAS_SECRETS = "has_secrets"; + + @NonNull + @PrimaryKey(COLUMN_TASK_ID) + private UUID taskId; + + @NonNull + @Column(COLUMN_NCA_ID) + private String ncaId; + + @NonNull + @Column(COLUMN_NAME) + private String name; + + @Nullable + @Column(COLUMN_DESCRIPTION) + private String description; + + @Nullable + @Column(COLUMN_TAGS) + private Set tags; + + @Nullable + @Column(COLUMN_CONTAINER_IMAGE) + private String containerImage; + + @Nullable + @Column(COLUMN_CONTAINER_ARGS) + private String containerArgs; + + @Nullable + @Column(COLUMN_CONTAINER_ENVIRONMENT) + private String containerEnvironment; + + @Nullable + @Column(COLUMN_MODELS) + private Set models; + + @Nullable + @Column(COLUMN_RESOURCES) + private Set resources; + + @NonNull + @Column(COLUMN_GPU_SPEC) + private GpuSpecUdt gpuSpec; + + @Nullable + @Column(COLUMN_MAX_RUNTIME_DURATION) + @CassandraType(type = CassandraType.Name.DURATION) + private Duration maxRuntimeDuration; + + @NonNull + @Column(COLUMN_MAX_QUEUED_DURATION) + @CassandraType(type = CassandraType.Name.DURATION) + private Duration maxQueuedDuration; + + @NonNull + @Column(COLUMN_TERMINAL_GRACE_PERIOD_DURATION) + @CassandraType(type = CassandraType.Name.DURATION) + private Duration terminalGracePeriodDuration; + + @Column(COLUMN_RESULT_HANDLING_STRATEGY) + @Builder.Default + private ResultHandlingStrategy resultHandlingStrategy = ResultHandlingStrategy.UPLOAD; + + @Nullable + @Column(COLUMN_HELM_CHART) + private String helmChart; + + @Nullable + @Column(COLUMN_RESULTS_LOCATION) + private String resultsLocation; + + @NonNull + @Column(COLUMN_STATUS) + private TaskStatus status; + + @Nullable + @Column(COLUMN_TELEMETRIES) + private TelemetriesUdt telemetries; + + @Nullable + @Column(COLUMN_HEALTH) + private String health; + + @Nullable + @Column(COLUMN_HEALTH_INFO) + private HealthUdt legacyHealthInfo; + + @Nullable + @Column(COLUMN_PERCENT_COMPLETE) + private Integer percentComplete; + + @Nullable + @Column(COLUMN_LAST_HEARTBEAT_AT) + private Instant lastHeartbeatAt; + + @Nullable + @Column(COLUMN_LAST_UPDATED_AT) + private Instant lastUpdatedAt; + + @Column(COLUMN_CREATED_AT) + @Builder.Default + private Instant createdAt = Instant.now(); + + @Column(COLUMN_HAS_SECRETS) + @Builder.Default + private Boolean hasSecrets = Boolean.FALSE; + + // Custom getter for natural method name (Lombok generates isHasSecrets by default) + public boolean hasSecrets() { + return Objects.requireNonNullElse(hasSecrets, false); + } + +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/persistence/task/entity/TaskStatus.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/persistence/task/entity/TaskStatus.java new file mode 100644 index 000000000..4bd0a27b8 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/persistence/task/entity/TaskStatus.java @@ -0,0 +1,54 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.persistence.task.entity; + +import static java.lang.String.format; + +import java.util.EnumSet; +import lombok.NonNull; + +public enum TaskStatus { + + QUEUED("QUEUED"), + LAUNCHED("LAUNCHED"), + RUNNING("RUNNING"), + ERRORED("ERRORED"), + CANCELED("CANCELED"), + EXCEEDED_MAX_RUNTIME_DURATION("EXCEEDED_MAX_RUNTIME_DURATION"), + EXCEEDED_MAX_QUEUED_DURATION("EXCEEDED_MAX_QUEUED_DURATION"), + COMPLETED("COMPLETED"); + + private final String name; + + TaskStatus(String name) { + this.name = name; + } + + @Override + public String toString() { + return this.name; + } + + public static TaskStatus fromText(@NonNull String val) { + return EnumSet.allOf(TaskStatus.class) + .stream() + .filter(e -> e.name.equalsIgnoreCase(val)) + .findFirst() + .orElseThrow(() -> new IllegalStateException(format("Unsupported enum %s.", val))); + } + +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/persistence/task/entity/TelemetriesUdt.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/persistence/task/entity/TelemetriesUdt.java new file mode 100644 index 000000000..1c8234e5d --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/persistence/task/entity/TelemetriesUdt.java @@ -0,0 +1,44 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.persistence.task.entity; + +import java.util.UUID; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.springframework.data.annotation.PersistenceCreator; +import org.springframework.data.cassandra.core.mapping.Column; +import org.springframework.data.cassandra.core.mapping.UserDefinedType; + +@Data +@AllArgsConstructor(onConstructor_ = @PersistenceCreator) +@NoArgsConstructor +@Builder(toBuilder = true) +@UserDefinedType(TelemetriesUdt.USER_DEFINED_TYPE_NAME) +public class TelemetriesUdt { + public static final String USER_DEFINED_TYPE_NAME = "telemetries_udt"; + + @Column("logs_telemetry_id") + private UUID logsTelemetryId; + + @Column("metrics_telemetry_id") + private UUID metricsTelemetryId; + + @Column("traces_telemetry_id") + private UUID tracesTelemetryId; +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/event/EventController.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/event/EventController.java new file mode 100644 index 000000000..e56314789 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/event/EventController.java @@ -0,0 +1,87 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.rest.event; + +import static com.nvidia.nvct.util.NvctConstants.DEFAULT_PAGINATION_LIMIT; +import static com.nvidia.nvct.util.NvctConstants.SPAN_TAG_NCA_ID; +import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; + +import com.nvidia.nvct.rest.event.dto.ListEventsResponse; +import com.nvidia.nvct.service.account.AccountService; +import com.nvidia.nvct.service.ratelimit.RateLimiterService; +import com.nvidia.nvct.util.NvctUtils; +import io.micrometer.tracing.Tracer; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.constraints.Positive; +import java.util.Map; +import java.util.UUID; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.security.core.Authentication; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@Slf4j +@RestController +@RequiredArgsConstructor +@RequestMapping(produces = APPLICATION_JSON_VALUE) +@Tag(name = "Task Events", + description = """ + Defines Task Event endpoints. All tne endpoints defined in this API require + a bearer token appropriate scope in the HTTP Authorization header. + """ +) +public class EventController { + + private final AccountService accountService; + private final RateLimiterService rateLimiterService; + private final EventFacade eventFacade; + private final Tracer tracer; + + @GetMapping("/v1/nvct/tasks/{taskId}/events") + @Operation( + summary = "Get Events", + description = """ + Gets events associated with the specified task in the authenticated + NVIDIA Cloud Account. Requires a bearer token with 'list_events' scope + in the HTTP Authorization header. + """ + ) + @PreAuthorize("hasAnyAuthority('list_events', 'apikey:list_events')") + public ListEventsResponse getTaskEvents( + @Parameter(description = "Number of events to return in the response") + @RequestParam(required = false, defaultValue = DEFAULT_PAGINATION_LIMIT) + @Positive int limit, + @Parameter(description = "Beginning of the pagination slice") + @RequestParam(required = false) String cursor, + @Parameter(description = "Task id", required = true) + @PathVariable("taskId") UUID taskId, + Authentication authentication) { + var ncaId = accountService.getNcaId(authentication); + NvctUtils.addTagsToCurrentSpan(tracer, Map.of(SPAN_TAG_NCA_ID, ncaId)); + + rateLimiterService.verifyLimits(ncaId, taskId); + return eventFacade.getEvents(ncaId, taskId, limit, cursor, authentication); + } + +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/event/EventFacade.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/event/EventFacade.java new file mode 100644 index 000000000..2fbf8b31f --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/event/EventFacade.java @@ -0,0 +1,48 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.rest.event; + +import static com.nvidia.nvct.service.task.TaskPredicateUtils.taskAccessMatch; + +import com.nvidia.nvct.rest.event.dto.ListEventsResponse; +import com.nvidia.nvct.service.event.EventService; +import java.util.Optional; +import java.util.UUID; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.security.core.Authentication; +import org.springframework.stereotype.Service; + +@Slf4j +@Service +@RequiredArgsConstructor +public class EventFacade { + + private final EventService eventService; + + public ListEventsResponse getEvents(String ncaId, + UUID taskId, + int limit, + String cursor, + Authentication authentication) { + var sliceContext = eventService.fetchEvents(ncaId, taskId, limit, cursor, + taskEntity -> taskAccessMatch(authentication, Optional.of(taskId))); + return new ListEventsResponse(sliceContext.events(), + sliceContext.limit(), + sliceContext.cursor()); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/event/XAccountEventController.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/event/XAccountEventController.java new file mode 100644 index 000000000..78fea4c18 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/event/XAccountEventController.java @@ -0,0 +1,89 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.rest.event; + +import static com.nvidia.nvct.util.NvctConstants.DEFAULT_PAGINATION_LIMIT; +import static com.nvidia.nvct.util.NvctConstants.SPAN_TAG_NCA_ID; +import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; + +import com.nvidia.nvct.rest.event.dto.ListEventsResponse; +import com.nvidia.nvct.service.account.AccountService; +import com.nvidia.nvct.util.NvctUtils; +import io.micrometer.tracing.Tracer; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.constraints.Positive; +import java.util.Map; +import java.util.UUID; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.security.core.Authentication; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@Slf4j +@RestController +@RequiredArgsConstructor +@RequestMapping(produces = APPLICATION_JSON_VALUE) +@Tag(name = "Cross-Account Event Support for NVIDIA Super Admins", + description = """ + Defines Event endpoints for NVIDIA Super Admins to work across accounts. All the + endpoints defined in this API require a bearer token with an appropriate + admin scope in the HTTP Authorization header. + """ +) +public class XAccountEventController { + + private static final String NCA_ID_DESCRIPTION = "NVIDIA Cloud Account(NCA) Id"; + + private final AccountService accountService; + private final EventFacade eventFacade; + private final Tracer tracer; + + @GetMapping("/v1/nvct/accounts/{ncaId}/tasks/{taskId}/events") + @Operation( + summary = "Get Events", + description = """ + Gets events associated with the specified task in the authenticated + NVIDIA Cloud Account. Requires a bearer token with 'admin:list_events' + scope in the HTTP Authorization header. + """ + ) + @PreAuthorize("hasAuthority('admin:list_events')") + public ListEventsResponse getTaskEvents( + @Parameter(description = "Number of events to return in the response") + @RequestParam(required = false, defaultValue = DEFAULT_PAGINATION_LIMIT) + @Positive int limit, + @Parameter(description = "Beginning of the pagination slice") + @RequestParam(required = false) String cursor, + @Parameter(description = NCA_ID_DESCRIPTION, required = true) + @PathVariable String ncaId, + @Parameter(description = "Task id", required = true) + @PathVariable("taskId") UUID taskId, + Authentication authentication) { + NvctUtils.addTagsToCurrentSpan(tracer, Map.of(SPAN_TAG_NCA_ID, ncaId)); + accountService.assertAccountExistsOrThrow(ncaId); + accountService.assertAccountIdFromPathMatches(ncaId, authentication); + return eventFacade.getEvents(ncaId, taskId, limit, cursor, authentication); + } + +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/event/dto/EventDto.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/event/dto/EventDto.java new file mode 100644 index 000000000..1ace4241d --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/event/dto/EventDto.java @@ -0,0 +1,42 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.rest.event.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import java.time.Instant; +import java.util.UUID; +import lombok.Builder; + +@Builder(toBuilder = true) +@Schema(description = "Data Transfer Object(DTO) representing a Task Event") +public record EventDto( + @Schema(description = "Event id") + @NotNull UUID eventId, + + @Schema(description = "Task id") + @NotNull UUID taskId, + + @Schema(description = "NVIDIA Cloud Account Id") + @NotNull String ncaId, + + @Schema(description = "Event message") + @NotNull String message, + + @Schema(description = "Event creation timestamp") + @NotNull Instant createdAt) { +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/event/dto/ListEventsResponse.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/event/dto/ListEventsResponse.java new file mode 100644 index 000000000..e12828c53 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/event/dto/ListEventsResponse.java @@ -0,0 +1,35 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.rest.event.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import java.util.List; +import lombok.Builder; + +@Builder +@Schema(description = "Response body containing list of task events") +public record ListEventsResponse( + @Schema(description = "List of events") + @NotNull List events, + + @Schema(description = "Pagination limit - Not included in the response for the last slice") + Integer limit, + + @Schema(description = "Pagination cursor - Not included in the response for the last slice") + String cursor) { +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/misc/XAccountMiscEndpointsController.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/misc/XAccountMiscEndpointsController.java new file mode 100644 index 000000000..ac37a8309 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/misc/XAccountMiscEndpointsController.java @@ -0,0 +1,242 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.rest.misc; + +import static com.nvidia.nvct.util.NvctConstants.SPAN_TAG_NCA_ID; +import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; + +import com.nvidia.nvct.persistence.task.entity.GpuSpecUdt; +import com.nvidia.nvct.persistence.task.entity.TaskEntity; +import com.nvidia.nvct.persistence.task.entity.TaskStatus; +import com.nvidia.nvct.rest.misc.dto.GpuPlacementDto; +import com.nvidia.nvct.rest.misc.dto.GpuUsageDto; +import com.nvidia.nvct.rest.misc.dto.ListGpuUsageResponse; +import com.nvidia.nvct.rest.task.dto.InstanceUsageTypeEnum; +import com.nvidia.nvct.service.account.AccountService; +import com.nvidia.nvct.service.icms.IcmsClient; +import com.nvidia.nvct.service.icms.IcmsStubService; +import com.nvidia.nvct.service.task.TaskService; +import com.nvidia.nvct.util.NvctUtils; +import io.micrometer.tracing.Tracer; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import java.util.ArrayList; +import java.util.Collections; +import java.util.EnumSet; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.security.core.Authentication; +import org.springframework.util.CollectionUtils; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@Slf4j +@RestController +@RequiredArgsConstructor +@RequestMapping(produces = APPLICATION_JSON_VALUE) +@Tag(name = "Cross-Account Miscellaneous API for NVIDIA Super Admins", + description = """ + Defines miscellaneous endpoints for smooth service operation by NVIDIA Super + Admins such as SREs.""") +public class XAccountMiscEndpointsController { + + private static final String NCA_ID_DESCRIPTION = "NVIDIA Cloud Account Id"; + private static final EnumSet QUEUED_OR_LAUNCHED_OR_RUNNING = + EnumSet.of(TaskStatus.RUNNING, TaskStatus.QUEUED, TaskStatus.LAUNCHED); + private final AccountService accountService; + private final TaskService taskService; + private final IcmsClient icmsClient; + private final Tracer tracer; + + @GetMapping(value = "/v1/nvct/accounts/{ncaId}/usage/gpus") + @Operation( + summary = "GPU Max Usage", + description = """ + Provides the current max usage of GPUs in the specified NVIDIA Cloud Account + based on currently deployed tasks. Requires a bearer token with + 'admin:launch_task' scope in the HTTP Authorization header. + """ + ) + @PreAuthorize("hasAuthority('admin:launch_task')") + public ListGpuUsageResponse getGpuUsage( + @Parameter(description = NCA_ID_DESCRIPTION, required = true) + @PathVariable String ncaId, + Authentication authentication) { + NvctUtils.addTagsToCurrentSpan(tracer, Map.of(SPAN_TAG_NCA_ID, ncaId)); + accountService.assertAccountExistsOrThrow(ncaId); + accountService.assertAccountIdFromPathMatches(ncaId, authentication); + var gpuToSpec = new HashMap(); + var gpuToCount = new HashMap(); + // usage per cluster + var gpuToClusterCount = new HashMap(); + // clusters where the gpu could be deployed + var gpuToClustersFiltered = new HashMap>(); + + var tasks = taskService.fetchTasksByAccount(ncaId) + .filter(task -> QUEUED_OR_LAUNCHED_OR_RUNNING.contains(task.getStatus())) + .collect(Collectors.toSet()); + var gpuToClusters = toGpuClusterMapping( + icmsClient.getClusters( + ncaId, getInstanceTypeUsage(tasks))); + + tasks.stream() + .map(TaskEntity::getGpuSpec) + .forEach(spec -> { + var instanceKey = spec.getGpu() + "/" + spec.getInstanceType(); + gpuToSpec.put(instanceKey, spec); + // we know there is only one instance per spec + gpuToCount.put(instanceKey, gpuToCount.getOrDefault(instanceKey, 0) + 1); + + var clusterResponses = + gpuToClusters.computeIfAbsent(instanceKey, k -> new HashSet<>()); + + Stream clusterResponseStream = + clusterResponses.stream(); + if (StringUtils.isNotBlank(spec.getBackend())) { + clusterResponseStream = clusterResponseStream.filter( + cluster -> spec.getBackend() + .equalsIgnoreCase( + convertGfnClusterGroupName( + cluster.getClusterGroupName()))); + } + if (!CollectionUtils.isEmpty(spec.getClusters())) { + clusterResponseStream = clusterResponseStream.filter( + cluster -> spec.getClusters() + .contains(cluster.getClusterName())); + } + if (!CollectionUtils.isEmpty(spec.getRegions())) { + clusterResponseStream = clusterResponseStream.filter( + cluster -> spec.getRegions().contains(cluster.getRegion())); + } + + clusterResponseStream.forEach(cluster -> { + var clusterKey = instanceKey + "/" + cluster.getClusterId(); + gpuToClusterCount.put(clusterKey, gpuToClusterCount.getOrDefault(clusterKey, 0) + 1); + gpuToClustersFiltered + .computeIfAbsent(instanceKey, k -> new HashSet<>()) + .add(cluster); + }); + }); + + // Build resulting dto + var gpus = new ArrayList(); + gpuToCount.keySet() + .forEach(instanceKey -> { + var gpu = gpuToSpec.get(instanceKey).getGpu(); + var instanceType = gpuToSpec.get(instanceKey).getInstanceType(); + var specCount = gpuToCount.get(instanceKey); + var clusters = gpuToClustersFiltered.computeIfAbsent( + instanceKey, k -> Collections.emptySet()); + var placements = new ArrayList(); + for (IcmsStubService.ClusterResponse cluster : clusters) { + var clusterKey = instanceKey + "/" + cluster.getClusterId(); + if (gpuToClusterCount.containsKey(clusterKey)) { + placements.add(toGpuPlacementDto( + cluster, gpuToClusterCount.get(clusterKey), + gpuToClusterCount.get(clusterKey))); + } + } + gpus.add(GpuUsageDto.builder() + .gpu(gpu) + .instanceType(instanceType) + .currentMaxUsage(specCount) + .currentMinUsage(specCount) + .placements(placements) + .build()); + }); + + return new ListGpuUsageResponse(gpus); + } + + /** + * Converts a ICMS Clusters response to a mapping: + * key: [gpu/instanceType] + * value: A Unique set of all clusters where this gpu/instance type is available for ncaId + * + * Filter out all clusters with status != READY + * @param clustersResponse icms /clusters response + * @return mapping + */ + private static Map> toGpuClusterMapping( + List clustersResponse) { + Map> result = new HashMap<>(); + clustersResponse + .stream() + .filter(clusterResponse -> + clusterResponse.getStatus().equalsIgnoreCase("READY")) + .forEach(clusterResponse -> + clusterResponse.getGpus().forEach(gpu -> { + var gpuName = gpu.getName(); + gpu.getInstanceTypes().forEach(instanceType -> { + var instanceTypeName = instanceType.getName(); + var key = gpuName + "/" + instanceTypeName; + Set setOfLocations = + result.computeIfAbsent(key, k -> new HashSet<>()); + setOfLocations.add(clusterResponse); + }); + + })); + return result; + } + + private static GpuPlacementDto toGpuPlacementDto( + IcmsStubService.ClusterResponse cluster, Integer currentMaxUsage, + Integer currentMinUsage) { + return GpuPlacementDto.builder() + .clusterId(cluster.getClusterId()) + .cluster(cluster.getClusterName()) + .clusterGroupId(cluster.getClusterGroupId()) + .clusterGroup(cluster.getClusterGroupName()) + .cloudProvider(cluster.getCloudProvider()) + .region(cluster.getRegion()) + .currentMaxUsage(currentMaxUsage) + .currentMinUsage(currentMinUsage) + .build(); + } + + // Due to different flows at ICMS for NVCA and GFN, in /cluster response GFN cluster group + // name is always GFN_REGION_TARGETING. We need to convert it to expected backend name GFN. + private static String convertGfnClusterGroupName(String clusterGroupName) { + if ("GFN_REGION_TARGETING".equalsIgnoreCase(clusterGroupName)) { + return "GFN"; + } + return clusterGroupName; + } + + // Determines if all the Tasks in the list are either strictly container-based or whether + // some are helm-based and some are container-based. + private static InstanceUsageTypeEnum getInstanceTypeUsage( + Set entities) { + if (entities.stream() + .noneMatch(entity -> StringUtils.isBlank(entity.getContainerImage()))) { + return InstanceUsageTypeEnum.CONTAINER; + } + return InstanceUsageTypeEnum.DEFAULT; + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/misc/dto/GpuPlacementDto.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/misc/dto/GpuPlacementDto.java new file mode 100644 index 000000000..21f89c63b --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/misc/dto/GpuPlacementDto.java @@ -0,0 +1,59 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.rest.misc.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.PositiveOrZero; +import lombok.Builder; + +@Builder +@Schema(description = "Data Transfer Object(DTO) representing GPU location, i.e. " + + "cluster, cluster group, region") +public record GpuPlacementDto( + @Schema(description = "Unique cluster id. Note: cluster name may not be unique.") + @NotBlank + String clusterId, + + @Schema(description = "Cluster name") + @NotBlank + String cluster, + + @Schema(description = "Unique cluster group id.") + @NotBlank + String clusterGroupId, + + @Schema(description = "Cluster group name") + @NotBlank + String clusterGroup, + + @Schema(description = "Cluster provider") + @NotBlank + String cloudProvider, + + @Schema(description = "Cluster region where gpu is located") + @NotBlank + String region, + + @Schema(description = "Max usage of gpu in this cluster") + @PositiveOrZero + int currentMaxUsage, + + @Schema(description = "Min usage of gpu in this cluster") + @PositiveOrZero + int currentMinUsage) { +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/misc/dto/GpuUsageDto.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/misc/dto/GpuUsageDto.java new file mode 100644 index 000000000..905f4fc2d --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/misc/dto/GpuUsageDto.java @@ -0,0 +1,39 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.rest.misc.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.PositiveOrZero; +import java.util.List; +import lombok.Builder; + +@Builder +@Schema(description = "Data Transfer Object(DTO) representing GPU usage") +public record GpuUsageDto( + @Schema(description = "GPU name") + @NotBlank String gpu, + @Schema(description = "GPU instance type") + @NotBlank String instanceType, + @Schema(description = "Max usage based on currently deployed Tasks") + @PositiveOrZero int currentMaxUsage, + @Schema(description = "Min usage based on currently deployed Tasks") + @PositiveOrZero int currentMinUsage, + @Schema(description = "GPU placement list") + @NotNull List placements) { +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/misc/dto/ListGpuUsageResponse.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/misc/dto/ListGpuUsageResponse.java new file mode 100644 index 000000000..a9c8a1a16 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/misc/dto/ListGpuUsageResponse.java @@ -0,0 +1,29 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.rest.misc.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import java.util.List; +import lombok.Builder; + +@Builder +@Schema(description = "Response body containing current usage of GPUs in an account") +public record ListGpuUsageResponse( + @Schema(description = "List of DTOs with GPU usage information") + @NotNull List gpus) { +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/result/ResultController.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/result/ResultController.java new file mode 100644 index 000000000..ba817b37a --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/result/ResultController.java @@ -0,0 +1,87 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.rest.result; + +import static com.nvidia.nvct.util.NvctConstants.DEFAULT_PAGINATION_LIMIT; +import static com.nvidia.nvct.util.NvctConstants.SPAN_TAG_NCA_ID; +import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; + +import com.nvidia.nvct.rest.result.dto.ListResultsResponse; +import com.nvidia.nvct.service.account.AccountService; +import com.nvidia.nvct.service.ratelimit.RateLimiterService; +import com.nvidia.nvct.util.NvctUtils; +import io.micrometer.tracing.Tracer; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.constraints.Positive; +import java.util.Map; +import java.util.UUID; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.security.core.Authentication; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@Slf4j +@RestController +@RequiredArgsConstructor +@RequestMapping(produces = APPLICATION_JSON_VALUE) +@Tag(name = "Task Results", + description = """ + Defines Task Result endpoints. All the endpoints defined in this API require + a bearer token with appropriate scope in the HTTP Authorization + header. + """ +) +public class ResultController { + + private final AccountService accountService; + private final RateLimiterService rateLimiterService; + private final ResultFacade resultFacade; + private final Tracer tracer; + + @GetMapping("/v1/nvct/tasks/{taskId}/results") + @Operation( + summary = "Get Results", + description = """ + Gets results associated with the specified task in the authenticated + NVIDIA Cloud Account. Requires a bearer token with 'list_results' scope + in the HTTP Authorization header. + """ + ) + @PreAuthorize("hasAnyAuthority('list_results', 'apikey:list_results')") + public ListResultsResponse getTaskResults( + @Parameter(description = "Number of results to return in the response") + @RequestParam(required = false, defaultValue = DEFAULT_PAGINATION_LIMIT) + @Positive int limit, + @Parameter(description = "Beginning of the pagination slice") + @RequestParam(required = false) String cursor, + @Parameter(description = "Task id", required = true) + @PathVariable("taskId") UUID taskId, + Authentication authentication) { + var ncaId = accountService.getNcaId(authentication); + NvctUtils.addTagsToCurrentSpan(tracer, Map.of(SPAN_TAG_NCA_ID, ncaId)); + rateLimiterService.verifyLimits(ncaId, taskId); + return resultFacade.getResults(ncaId, taskId, limit, cursor, authentication); + } + +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/result/ResultFacade.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/result/ResultFacade.java new file mode 100644 index 000000000..8d95e4a1e --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/result/ResultFacade.java @@ -0,0 +1,49 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.rest.result; + +import static com.nvidia.nvct.service.task.TaskPredicateUtils.taskAccessMatch; + +import com.nvidia.nvct.rest.result.dto.ListResultsResponse; +import com.nvidia.nvct.service.result.ResultService; +import java.util.Optional; +import java.util.UUID; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.security.core.Authentication; +import org.springframework.stereotype.Service; + +@Slf4j +@Service +@RequiredArgsConstructor +public class ResultFacade { + + private final ResultService resultService; + + public ListResultsResponse getResults(String ncaId, + UUID taskId, + int limit, + String cursor, + Authentication authentication) { + var sliceContext = resultService.fetchResults(ncaId, taskId, limit, cursor, + taskEntity -> taskAccessMatch(authentication, Optional.of(taskEntity.getTaskId()))); + return new ListResultsResponse(sliceContext.results(), + sliceContext.limit(), + sliceContext.cursor()); + } + +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/result/XAccountResultController.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/result/XAccountResultController.java new file mode 100644 index 000000000..4645e3d12 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/result/XAccountResultController.java @@ -0,0 +1,88 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.rest.result; + +import static com.nvidia.nvct.util.NvctConstants.DEFAULT_PAGINATION_LIMIT; +import static com.nvidia.nvct.util.NvctConstants.SPAN_TAG_NCA_ID; +import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; + +import com.nvidia.nvct.rest.result.dto.ListResultsResponse; +import com.nvidia.nvct.service.account.AccountService; +import com.nvidia.nvct.util.NvctUtils; +import io.micrometer.tracing.Tracer; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.constraints.Positive; +import java.util.Map; +import java.util.UUID; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.security.core.Authentication; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@Slf4j +@RestController +@RequiredArgsConstructor +@RequestMapping(produces = APPLICATION_JSON_VALUE) +@Tag(name = "Cross-Account Result Support for NVIDIA Super Admins", + description = """ + Defines Result endpoints for NVIDIA Super Admins to work across accounts. All the + endpoints defined in this API require a bearer token with an appropriate + admin scope in the HTTP Authorization header. + """ +) +public class XAccountResultController { + + private static final String NCA_ID_DESCRIPTION = "NVIDIA Cloud Account(NCA) Id"; + + private final AccountService accountService; + private final ResultFacade resultFacade; + private final Tracer tracer; + + @GetMapping("/v1/nvct/accounts/{ncaId}/tasks/{taskId}/results") + @Operation( + summary = "Get Results", + description = """ + Gets results associated with the specified task in the authenticated + NVIDIA Cloud Account. Requires a bearer token with 'admin:list_results' + scope in the HTTP Authorization header. + """ + ) + @PreAuthorize("hasAuthority('admin:list_results')") + public ListResultsResponse getTaskResults( + @Parameter(description = "Number of results to return in the response") + @RequestParam(required = false, defaultValue = DEFAULT_PAGINATION_LIMIT) + @Positive int limit, + @Parameter(description = "Beginning of the pagination slice") + @RequestParam(required = false) String cursor, + @Parameter(description = NCA_ID_DESCRIPTION, required = true) + @PathVariable String ncaId, + @PathVariable @Parameter(description = "Task id", required = true) UUID taskId, + Authentication authentication) { + NvctUtils.addTagsToCurrentSpan(tracer, Map.of(SPAN_TAG_NCA_ID, ncaId)); + accountService.assertAccountExistsOrThrow(ncaId); + accountService.assertAccountIdFromPathMatches(ncaId, authentication); + return resultFacade.getResults(ncaId, taskId, limit, cursor, authentication); + } + +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/result/dto/ListResultsResponse.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/result/dto/ListResultsResponse.java new file mode 100644 index 000000000..e9e50915d --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/result/dto/ListResultsResponse.java @@ -0,0 +1,35 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.rest.result.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import java.util.List; +import lombok.Builder; + +@Builder +@Schema(description = "Response body containing list of task results") +public record ListResultsResponse( + @Schema(description = "List of results") + @NotNull List results, + + @Schema(description = "Pagination limit - Not included in the response for the last slice") + Integer limit, + + @Schema(description = "Pagination cursor - Not included in the response for the last slice") + String cursor) { +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/result/dto/ResultDto.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/result/dto/ResultDto.java new file mode 100644 index 000000000..17d5d1ad3 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/result/dto/ResultDto.java @@ -0,0 +1,46 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.rest.result.dto; + +import tools.jackson.databind.node.ObjectNode; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import java.time.Instant; +import java.util.UUID; +import lombok.Builder; + +@Builder(toBuilder = true) +@Schema(description = "Data Transfer Object(DTO) representing a Result") +public record ResultDto( + @Schema(description = "Result id") + @NotNull UUID resultId, + + @Schema(description = "Task id") + @NotNull UUID taskId, + + @Schema(description = "NVIDIA Cloud Account Id") + @NotNull String ncaId, + + @Schema(description = "Result name") + @NotNull String name, + + @Schema(description = "Result metadata") + @NotNull ObjectNode metadata, + + @Schema(description = "Result creation timestamp") + @NotNull Instant createdAt) { +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/secret/SecretManagementController.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/secret/SecretManagementController.java new file mode 100644 index 000000000..c9650e12f --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/secret/SecretManagementController.java @@ -0,0 +1,86 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.rest.secret; + +import static com.nvidia.nvct.util.NvctConstants.SPAN_TAG_NCA_ID; +import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; + +import com.nvidia.nvct.rest.secret.dto.UpdateSecretsRequest; +import com.nvidia.nvct.service.account.AccountService; +import com.nvidia.nvct.service.ratelimit.RateLimiterService; +import com.nvidia.nvct.util.NvctUtils; +import io.micrometer.tracing.Tracer; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import java.util.Map; +import java.util.UUID; +import lombok.NonNull; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.security.core.Authentication; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@Slf4j +@RestController +@RequiredArgsConstructor +@RequestMapping(value = "/v1/nvct/secrets", produces = APPLICATION_JSON_VALUE) +@Tag(name = "User Secret Management", + description = """ + Defines User Secret Management endpoints for Account Admins. All the endpoints + defined in this API require a bearer token with appropriate scope in the + HTTP Authorization header. + """ +) +public class SecretManagementController { + + private final SecretManagementFacade secretManagementFacade; + private final AccountService accountService; + private final RateLimiterService rateLimiterService; + private final Tracer tracer; + + @PutMapping(value = "tasks/{taskId}", + consumes = APPLICATION_JSON_VALUE) + @Operation( + summary = "Update user secrets for a task", + description = """ + Updates secrets for the specified task id. This endpoint requires a + bearer token 'update_secrets' scope in the HTTP Authorization header. + """, + responses = @ApiResponse(responseCode = "204") + ) + @PreAuthorize("hasAnyAuthority('update_secrets', 'apikey:update_secrets')") + public ResponseEntity updateSecrets( + @Parameter(description = "Task id", required = true) + @NotNull @PathVariable UUID taskId, + @Valid @NonNull @RequestBody UpdateSecretsRequest request, + Authentication authentication) { + var ncaId = accountService.getNcaId(authentication); + NvctUtils.addTagsToCurrentSpan(tracer, Map.of(SPAN_TAG_NCA_ID, ncaId)); + rateLimiterService.verifyLimits(ncaId, taskId); + return secretManagementFacade.updateSecrets(ncaId, taskId, request.secrets(), authentication); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/secret/SecretManagementFacade.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/secret/SecretManagementFacade.java new file mode 100644 index 000000000..1c21909d6 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/secret/SecretManagementFacade.java @@ -0,0 +1,162 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.rest.secret; + +import static com.nvidia.nvct.persistence.task.entity.ResultHandlingStrategy.UPLOAD; +import static com.nvidia.nvct.service.secret.SecretManagementService.getNgcApiKey; +import static com.nvidia.nvct.service.secret.SecretManagementService.hasDupeSecrets; +import static com.nvidia.nvct.service.task.TaskPredicateUtils.taskAccessMatch; +import static com.nvidia.nvct.util.NvctConstants.TERMINAL_TASK_STATUSES; + +import com.nvidia.boot.exceptions.BadRequestException; +import com.nvidia.boot.exceptions.ForbiddenException; +import com.nvidia.boot.exceptions.NotFoundException; +import com.nvidia.nvct.persistence.task.entity.TaskEntity; +import com.nvidia.nvct.rest.task.dto.SecretDto; +import com.nvidia.nvct.service.account.AccountService; +import com.nvidia.nvct.service.ess.EssService; +import com.nvidia.nvct.service.ngc.NgcRegistryClient; +import com.nvidia.nvct.service.task.TaskService; +import java.util.HashSet; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.UUID; +import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.http.ResponseEntity; +import org.springframework.security.core.Authentication; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; + +@Slf4j +@Service +@RequiredArgsConstructor +public class SecretManagementFacade { + + private static final String MESG_MISSING_SECRETS = + "Task id '%s': Missing secrets in the payload"; + private static final String MESG_DUPLICATE_SECRETS = + "Task id '%s': Duplicate secrets keys in the payload"; + private static final String MESG_INVALID_OPERATION = + "Task id '%s': Cannot update secrets for a Task that does not have any secrets"; + private static final String MESG_TERMINAL_TASK_SECRETS = + "Task id '%s': Cannot update secrets for a Task with terminal status '%s'"; + private static final String MESG_TASK_NOT_IN_ACCOUNT = + "Task id '%s': Not found in account '%s'"; + private static final String MESG_FORBIDDEN_TO_UPDATE_SECRETS = + "Task '%s': Forbidden to update secrets"; + + private final EssService essService; + private final NgcRegistryClient ngcRegistryClient; + private final TaskService taskService; + private final AccountService accountService; + + public ResponseEntity updateSecrets( + String ncaId, + UUID taskId, + Set secrets, + Authentication authentication) { + if (CollectionUtils.isEmpty(secrets)) { + var mesg = MESG_MISSING_SECRETS.formatted(taskId); + log.error(mesg); + throw new BadRequestException(mesg); + } + // Confirm that the account exists. + accountService.lookupAccountUsingNcaIdOrThrow(ncaId); + + var taskEntity = taskService.fetchTask(taskId); + + if (!taskAccessMatch(authentication, Optional.of(taskId))) { + var mesg = MESG_FORBIDDEN_TO_UPDATE_SECRETS.formatted(taskId); + log.error(mesg); + throw new ForbiddenException(mesg); + } + + // If a Task does not have any secrets, then we do not allow secrets to be updated. + if (!taskEntity.hasSecrets()) { + var mesg = MESG_INVALID_OPERATION.formatted(taskId); + log.error(mesg); + throw new BadRequestException(mesg); + } + + // Confirm Task belongs to the specified ncaId/account. + if (!taskEntity.getNcaId().equals(ncaId)) { + var mesg = MESG_TASK_NOT_IN_ACCOUNT.formatted(taskId, ncaId); + log.error(mesg); + throw new NotFoundException(mesg); + } + + // Cannot update secrets for a Task with terminal status. + var status = taskEntity.getStatus(); + if (TERMINAL_TASK_STATUSES.contains(status)) { + var mesg = MESG_TERMINAL_TASK_SECRETS.formatted(taskId, status); + log.error(mesg); + throw new BadRequestException(mesg); + } + + validateSecrets(taskEntity, secrets); + + var existingSecrets = essService.getSecrets(taskId) + .orElseGet(Set::of) + .stream() + .collect(Collectors.toMap(SecretDto::name, Function.identity())); + + // Get the existing secrets first and then merge them with the new secrets + // Preferring new secrets values if the secret name is the same. + var newSecrets = secrets.stream() + .collect(Collectors.toMap(SecretDto::name, Function.identity())); + var mergedSecrets = Stream.concat(existingSecrets.entrySet().stream(), + newSecrets.entrySet().stream()) + .collect(Collectors.toMap( + Map.Entry::getKey, + Map.Entry::getValue, + (oldValue, newValue) -> newValue)); + essService.saveSecrets(taskId, new HashSet<>(mergedSecrets.values())); + return ResponseEntity.noContent().build(); // Status 204. + } + + private void validateSecrets( + TaskEntity taskEntity, + Set secrets) { + var taskId = taskEntity.getTaskId(); + if (hasDupeSecrets(secrets)) { + var mesg = MESG_DUPLICATE_SECRETS.formatted(taskId); + log.error(mesg); + throw new BadRequestException(mesg); + } + + // If a new NGC_API_KEY is being provided when updating secrets, then make sure that + // it can be used to upload results/checkpoints at the specified resultsLocation by + // creating and deleting a dummy/empty model. If successful, then the new NGC_API_KEY + // is valid. Otherwise, we respond with a 400. + var ngcApiKey = getNgcApiKey(secrets); + if (ngcApiKey.isPresent()) { + var resultsLocation = taskEntity.getResultsLocation(); + var resultHandlingStrategy = taskEntity.getResultHandlingStrategy(); + + if (resultHandlingStrategy == UPLOAD && StringUtils.isNotBlank(resultsLocation)) { + // If resultHandlingStrategy is UPLOAD, then resultsLocation will not be blank. + ngcRegistryClient.validate(ngcApiKey.get(), resultsLocation); + } + } + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/secret/XAccountSecretManagementController.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/secret/XAccountSecretManagementController.java new file mode 100644 index 000000000..55f3d349f --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/secret/XAccountSecretManagementController.java @@ -0,0 +1,90 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.rest.secret; + +import static com.nvidia.nvct.util.NvctConstants.SPAN_TAG_NCA_ID; +import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; + +import com.nvidia.nvct.rest.secret.dto.UpdateSecretsRequest; +import com.nvidia.nvct.service.ratelimit.RateLimiterService; +import com.nvidia.nvct.util.NvctUtils; +import io.micrometer.tracing.Tracer; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import java.util.Map; +import java.util.UUID; +import lombok.NonNull; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.security.core.Authentication; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@Slf4j +@RestController +@RequiredArgsConstructor +@RequestMapping(value = "/v1/nvct/accounts/{ncaId}/secrets/", produces = APPLICATION_JSON_VALUE) +@Tag(name = "Cross-Account User Secret Management for NVIDIA Super Admins", + description = """ + Defines User Secret Management endpoints for NVIDIA Super Admins to work across + accounts. All the endpoints defined in this API require a bearer token + with appropriate admin scopes in the HTTP Authorization header.""" +) + +public class XAccountSecretManagementController { + + private static final String NCA_ID_DESCRIPTION = "NVIDIA Cloud Account Id"; + + private final SecretManagementFacade secretManagementFacade; + private final RateLimiterService rateLimiterService; + private final com.nvidia.nvct.service.account.AccountService accountService; + private final Tracer tracer; + + @PutMapping(value = "tasks/{taskId}", + consumes = APPLICATION_JSON_VALUE) + @Operation( + summary = "Update user secrets for a task", + description = """ + Updates secrets for the specified task id. This endpoint requires a bearer + token with 'admin:update_secrets' scope in the HTTP Authorization header. + """, + responses = @ApiResponse(responseCode = "204") + ) + @PreAuthorize("hasAuthority('admin:update_secrets')") + public ResponseEntity updateSecrets( + @Parameter(description = NCA_ID_DESCRIPTION, required = true) + @PathVariable String ncaId, + @Parameter(description = "Task id", required = true) + @NotNull @PathVariable UUID taskId, + @Valid @NonNull @RequestBody UpdateSecretsRequest request, + Authentication authentication) { + NvctUtils.addTagsToCurrentSpan(tracer, Map.of(SPAN_TAG_NCA_ID, ncaId)); + accountService.assertAccountExistsOrThrow(ncaId); + accountService.assertAccountIdFromPathMatches(ncaId, authentication); + rateLimiterService.verifyLimits(ncaId, taskId); + return secretManagementFacade.updateSecrets(ncaId, taskId, request.secrets(), authentication); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/secret/dto/UpdateSecretsRequest.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/secret/dto/UpdateSecretsRequest.java new file mode 100644 index 000000000..647bb531a --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/secret/dto/UpdateSecretsRequest.java @@ -0,0 +1,31 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.rest.secret.dto; + +import com.nvidia.nvct.rest.task.dto.SecretDto; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import java.util.Set; +import lombok.Builder; + +@Builder +@Schema(description = "Request payload to update secrets") +public record UpdateSecretsRequest( + @Schema(description = "Secrets") + @NotNull @Valid Set secrets) { +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/TaskManagementController.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/TaskManagementController.java new file mode 100644 index 000000000..8ff345e7b --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/TaskManagementController.java @@ -0,0 +1,204 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.rest.task; + +import static com.nvidia.nvct.util.NvctConstants.DEFAULT_PAGINATION_LIMIT; +import static com.nvidia.nvct.util.NvctConstants.SPAN_TAG_NCA_ID; +import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; + +import com.nvidia.nvct.rest.task.dto.BulkTaskDetailsRequest; +import com.nvidia.nvct.rest.task.dto.CreateTaskRequest; +import com.nvidia.nvct.rest.task.dto.ListBasicTaskDetailsResponse; +import com.nvidia.nvct.rest.task.dto.ListTasksResponse; +import com.nvidia.nvct.rest.task.dto.TaskResponse; +import com.nvidia.nvct.rest.task.dto.TaskStatusEnum; +import com.nvidia.nvct.service.account.AccountService; +import com.nvidia.nvct.service.ratelimit.RateLimiterService; +import com.nvidia.nvct.util.NvctUtils; +import io.micrometer.tracing.Tracer; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Positive; +import java.util.Map; +import java.util.UUID; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.security.core.Authentication; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@Slf4j +@RestController +@RequiredArgsConstructor +@RequestMapping(produces = APPLICATION_JSON_VALUE) +@Tag(name = "Task Management", + description = """ + Defines Task Management endpoints. All tne endpoints defined in this API require + a bearer token with appropriate scope in the HTTP Authorization header. + """ +) +public class TaskManagementController { + + private final AccountService accountService; + private final RateLimiterService rateLimiterService; + private final TaskManagementFacade taskManagementFacade; + private final Tracer tracer; + + @PostMapping(value = "/v1/nvct/tasks", consumes = APPLICATION_JSON_VALUE) + @Operation( + summary = "Create and Launch Task", + description = """ + Creates and launches a new task within the authenticated NVIDIA Cloud Account. + Requires a bearer token with 'launch_task' scope in the HTTP Authorization + header. + """ + ) + @PreAuthorize("hasAnyAuthority('launch_task', 'apikey:launch_task')") + public TaskResponse createAndLaunchTask( + @Valid @NotNull @RequestBody CreateTaskRequest createRequest, + HttpServletRequest httpServletRequest, + Authentication authentication) { + var ncaId = accountService.getNcaId(authentication); + NvctUtils.addTagsToCurrentSpan(tracer, Map.of(SPAN_TAG_NCA_ID, ncaId)); + rateLimiterService.verifyLimits(ncaId); + return taskManagementFacade.createAndLaunchTask(ncaId, createRequest, + httpServletRequest, authentication); + } + + @PostMapping(value = "/v1/nvct/tasks/bulk", consumes = APPLICATION_JSON_VALUE) + @Operation( + summary = "List Basic Details of Specific Tasks", + description = """ + Lists basic details such as status, etc. of specified Task Ids. All the + Tasks should belong to the authenticated NVIDIA Cloud Account. Requires + a bearer token 'list_tasks' scopes in the HTTP Authorization header.""" + ) + @PreAuthorize("hasAnyAuthority('list_tasks', 'apikey:list_tasks')") + public ListBasicTaskDetailsResponse listBasicDetailsOfSpecificTasks( + @Valid @NotNull @RequestBody BulkTaskDetailsRequest listBasicTasksRequest, + Authentication authentication) { + var ncaId = accountService.getNcaId(authentication); + NvctUtils.addTagsToCurrentSpan(tracer, Map.of(SPAN_TAG_NCA_ID, ncaId)); + rateLimiterService.verifyLimits(ncaId); + return taskManagementFacade + .listBasicDetailsOfSpecificTasks(ncaId, listBasicTasksRequest, authentication); + } + + + @GetMapping("/v1/nvct/tasks") + @Operation( + summary = "List Tasks", + description = """ + Lists all the tasks associated with the authenticated NVIDIA Cloud Account. + Requires a bearer token with 'list_tasks' scopes in the HTTP Authorization + header.""" + ) + @PreAuthorize("hasAnyAuthority('list_tasks', 'apikey:list_tasks')") + public ListTasksResponse listTasks( + @Parameter(description = "Number of tasks to return in the response") + @RequestParam(required = false, defaultValue = DEFAULT_PAGINATION_LIMIT) + @Positive int limit, + @Parameter(description = "Task status") + @RequestParam(required = false) TaskStatusEnum status, + @Parameter(description = "Beginning of the pagination slice") + @RequestParam(required = false) String cursor, + Authentication authentication) { + var ncaId = accountService.getNcaId(authentication); + NvctUtils.addTagsToCurrentSpan(tracer, Map.of(SPAN_TAG_NCA_ID, ncaId)); + rateLimiterService.verifyLimits(ncaId); + return taskManagementFacade.listTasks(ncaId, authentication, limit, status, cursor); + } + + @GetMapping("/v1/nvct/tasks/{taskId}") + @Operation( + summary = "Get Task Details", + description = """ + Gets details of specified task in the authenticated NVIDIA Cloud Account. + Requires a bearer token with 'task_details' scope in the HTTP Authorization + header. + """ + ) + @PreAuthorize("hasAnyAuthority('task_details', 'apikey:task_details')") + public TaskResponse getTaskDetails( + @Parameter(description = "Task id", required = true) + @PathVariable("taskId") UUID taskId, + @Parameter(description = "Indicates whether to include secret names in the response") + @RequestParam(required = false, defaultValue = "true") boolean includeSecrets, + Authentication authentication) { + var ncaId = accountService.getNcaId(authentication); + NvctUtils.addTagsToCurrentSpan(tracer, Map.of(SPAN_TAG_NCA_ID, ncaId)); + rateLimiterService.verifyLimits(ncaId, taskId); + return taskManagementFacade.getTaskDetails(ncaId, taskId, authentication, includeSecrets); + } + + @PostMapping("/v1/nvct/tasks/{taskId}/cancel") + @Operation( + summary = "Cancel Task", + description = """ + Cancels the specified task in the authenticated NVIDIA Cloud Account. Requires + a bearer token with 'cancel_task' scope in the HTTP Authorization header. + """ + ) + @PreAuthorize("hasAnyAuthority('cancel_task', 'apikey:cancel_task')") + public TaskResponse cancelTask( + @Parameter(description = "Task id", required = true) + @PathVariable("taskId") UUID taskId, + HttpServletRequest httpServletRequest, + Authentication authentication) { + var ncaId = accountService.getNcaId(authentication); + NvctUtils.addTagsToCurrentSpan(tracer, Map.of(SPAN_TAG_NCA_ID, ncaId)); + rateLimiterService.verifyLimits(ncaId, taskId); + return taskManagementFacade.cancelTask(ncaId, taskId, + httpServletRequest, authentication); + } + + @DeleteMapping("/v1/nvct/tasks/{taskId}") + @Operation( + summary = "Delete Task", + description = """ + Deletes the specified task in the authenticated NVIDIA Cloud Account. Requires + a bearer token with 'delete_task' scope in the HTTP Authorization header. + """, + responses = @ApiResponse(responseCode = "204") + ) + @PreAuthorize("hasAnyAuthority('delete_task', 'apikey:delete_task')") + public ResponseEntity deleteTask( + @Parameter(description = "Task id", required = true) + @PathVariable("taskId") UUID taskId, + HttpServletRequest httpServletRequest, + Authentication authentication) { + var ncaId = accountService.getNcaId(authentication); + NvctUtils.addTagsToCurrentSpan(tracer, Map.of(SPAN_TAG_NCA_ID, ncaId)); + rateLimiterService.verifyLimits(ncaId, taskId); + return taskManagementFacade.deleteTask(ncaId, taskId, + httpServletRequest, authentication); + } + +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/TaskManagementFacade.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/TaskManagementFacade.java new file mode 100644 index 000000000..523ade16d --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/TaskManagementFacade.java @@ -0,0 +1,142 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.rest.task; + +import static com.nvidia.nvct.service.task.TaskPredicateUtils.taskAccessMatch; + +import com.nvidia.boot.audit.event.AuditEventPayload; +import com.nvidia.nvct.rest.task.dto.BulkTaskDetailsRequest; +import com.nvidia.nvct.rest.task.dto.CreateTaskRequest; +import com.nvidia.nvct.rest.task.dto.ListBasicTaskDetailsResponse; +import com.nvidia.nvct.rest.task.dto.ListTasksResponse; +import com.nvidia.nvct.rest.task.dto.TaskResponse; +import com.nvidia.nvct.rest.task.dto.TaskStatusEnum; +import com.nvidia.nvct.service.task.TaskAuditService; +import com.nvidia.nvct.service.task.TaskManagementService; +import com.nvidia.nvct.util.NvctUtils; +import jakarta.servlet.http.HttpServletRequest; +import java.util.Optional; +import java.util.UUID; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.ResponseEntity; +import org.springframework.security.core.Authentication; +import org.springframework.stereotype.Service; + +@Slf4j +@Service +@RequiredArgsConstructor +public class TaskManagementFacade { + + private final TaskAuditService taskAuditService; + private final TaskManagementService taskManagementService; + + public TaskResponse createAndLaunchTask( + String ncaId, + CreateTaskRequest request, + HttpServletRequest httpServletRequest, + Authentication authentication) { + var payloadBuilder = auditEventPayloadBuilder(httpServletRequest, authentication); + var dto = taskManagementService + .createAndLaunchTask(ncaId, + request, + () -> taskAccessMatch(authentication, Optional.empty()), + payloadBuilder); + return new TaskResponse(dto); + } + + public ListBasicTaskDetailsResponse listBasicDetailsOfSpecificTasks( + String ncaId, + BulkTaskDetailsRequest listBasicTasksRequest, + Authentication authentication) { + var taskIds = listBasicTasksRequest.taskIds(); + var dtos = taskIds.stream() + .map(taskId -> taskManagementService + .getBasicTaskDetails(ncaId, + taskId, + task -> taskAccessMatch(authentication, + Optional.of(task.getTaskId())))) + .toList(); + return new ListBasicTaskDetailsResponse(ncaId, dtos); + } + + public ListTasksResponse listTasks( + String ncaId, + Authentication authentication, + int limit, + TaskStatusEnum status, + String cursor) { + var sliceContext = taskManagementService + .listTasks(ncaId, + status, + limit, + cursor, + taskEntity -> taskAccessMatch(authentication, + Optional.of(taskEntity.getTaskId()))); + return new ListTasksResponse(sliceContext.tasks(), + sliceContext.limit(), + sliceContext.cursor()); + } + + public TaskResponse getTaskDetails(String ncaId, + UUID taskId, + Authentication authentication, + boolean includeSecrets) { + var dto = taskManagementService + .getTaskDetails(ncaId, + taskId, + includeSecrets, + taskEntity -> taskAccessMatch(authentication, + Optional.of(taskEntity.getTaskId()))); + return new TaskResponse(dto); + } + + public TaskResponse cancelTask(String ncaId, + UUID taskId, + HttpServletRequest httpServletRequest, + Authentication authentication) { + var payloadBuilder = auditEventPayloadBuilder(httpServletRequest, authentication); + var dto = taskManagementService + .cancelTask(ncaId, + taskId, + taskEntity -> taskAccessMatch(authentication, + Optional.of(taskEntity.getTaskId())), + payloadBuilder); + return new TaskResponse(dto); + } + + public ResponseEntity deleteTask(String ncaId, + UUID taskId, + HttpServletRequest httpServletRequest, + Authentication authentication) { + var payloadBuilder = auditEventPayloadBuilder(httpServletRequest, authentication); + taskManagementService + .deleteTask(ncaId, + taskId, + taskEntity -> taskAccessMatch(authentication, + Optional.of(taskEntity.getTaskId())), + payloadBuilder); + return ResponseEntity.noContent().build(); // Status 204. + } + + private AuditEventPayload.Builder auditEventPayloadBuilder( + HttpServletRequest httpServletRequest, + Authentication authentication) { + var customProperties = NvctUtils.getCustomProperties(httpServletRequest); + return taskAuditService.auditEventPayloadBuilder(authentication, customProperties); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/XAccountTaskManagementController.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/XAccountTaskManagementController.java new file mode 100644 index 000000000..88ee16f0d --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/XAccountTaskManagementController.java @@ -0,0 +1,218 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.rest.task; + +import static com.nvidia.nvct.util.NvctConstants.DEFAULT_PAGINATION_LIMIT; +import static com.nvidia.nvct.util.NvctConstants.SPAN_TAG_NCA_ID; +import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; + +import com.nvidia.nvct.rest.task.dto.BulkTaskDetailsRequest; +import com.nvidia.nvct.rest.task.dto.CreateTaskRequest; +import com.nvidia.nvct.rest.task.dto.ListBasicTaskDetailsResponse; +import com.nvidia.nvct.rest.task.dto.ListTasksResponse; +import com.nvidia.nvct.rest.task.dto.TaskResponse; +import com.nvidia.nvct.rest.task.dto.TaskStatusEnum; +import com.nvidia.nvct.service.account.AccountService; +import com.nvidia.nvct.util.NvctUtils; +import io.micrometer.tracing.Tracer; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Positive; +import java.util.Map; +import java.util.UUID; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.security.core.Authentication; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +@Slf4j +@RestController +@RequiredArgsConstructor +@RequestMapping(produces = APPLICATION_JSON_VALUE) +@Tag(name = "Cross-Account Task Management for NVIDIA Super Admins", + description = """ + Defines Task Management endpoints for NVIDIA Super Admins to work across accounts. + All tne endpoints defined in this API require a bearer token with an appropriate + admin scope in the HTTP Authorization header. + """ +) +public class XAccountTaskManagementController { + + private static final String NCA_ID_DESCRIPTION = "NVIDIA Cloud Account(NCA) Id"; + + private final AccountService accountService; + private final TaskManagementFacade taskManagementFacade; + private final Tracer tracer; + + @PostMapping(value = "/v1/nvct/accounts/{ncaId}/tasks", consumes = APPLICATION_JSON_VALUE) + @Operation( + summary = "Create and Launch Task", + description = """ + Creates and launches a new task within the authenticated NVIDIA Cloud Account. + Requires a bearer token with 'admin:launch_task' scope in the HTTP + Authorization header. + """ + ) + @PreAuthorize("hasAuthority('admin:launch_task')") + public TaskResponse createAndLaunchTask( + @Parameter(description = NCA_ID_DESCRIPTION, required = true) + @PathVariable String ncaId, + @Valid @NotNull @RequestBody CreateTaskRequest createRequest, + HttpServletRequest httpServletRequest, + Authentication authentication) { + NvctUtils.addTagsToCurrentSpan(tracer, Map.of(SPAN_TAG_NCA_ID, ncaId)); + accountService.assertAccountExistsOrThrow(ncaId); + accountService.assertAccountIdFromPathMatches(ncaId, authentication); + return taskManagementFacade.createAndLaunchTask(ncaId, createRequest, + httpServletRequest, authentication); + } + + @PostMapping(value = "/v1/nvct/accounts/{ncaId}/tasks/bulk", + consumes = APPLICATION_JSON_VALUE) + @Operation( + summary = "List Basic Details of Specific Tasks", + description = """ + Lists basic details such as status, etc. of specified Task Ids. All the + Tasks should belong to the authenticated NVIDIA Cloud Account. Requires a + bearer token with 'admin:list_tasks' scopes in the HTTP Authorization header. + """ + ) + @PreAuthorize("hasAuthority('admin:list_tasks')") + public ListBasicTaskDetailsResponse listBasicDetailsOfSpecificTasks( + @Parameter(description = NCA_ID_DESCRIPTION, required = true) + @PathVariable String ncaId, + @Valid @NotNull @RequestBody BulkTaskDetailsRequest listBasicTasksRequest, + Authentication authentication) { + NvctUtils.addTagsToCurrentSpan(tracer, Map.of(SPAN_TAG_NCA_ID, ncaId)); + accountService.assertAccountExistsOrThrow(ncaId); + accountService.assertAccountIdFromPathMatches(ncaId, authentication); + return taskManagementFacade + .listBasicDetailsOfSpecificTasks(ncaId, listBasicTasksRequest, authentication); + } + + @GetMapping("/v1/nvct/accounts/{ncaId}/tasks") + @Operation( + summary = "List Tasks", + description = """ + Lists all the tasks associated with the authenticated NVIDIA Cloud Account. + Requires a bearer token 'admin:list_tasks' scopes in the HTTP Authorization + header.""" + ) + @PreAuthorize("hasAuthority('admin:list_tasks')") + public ListTasksResponse listTasks( + @Parameter(description = NCA_ID_DESCRIPTION, required = true) + @PathVariable String ncaId, + @Parameter(description = "Number of tasks to return in the response") + @RequestParam(required = false, defaultValue = DEFAULT_PAGINATION_LIMIT) + @Positive int limit, + @Parameter(description = "Task status") + @RequestParam(required = false) TaskStatusEnum status, + @Parameter(description = "Beginning of the pagination slice") + @RequestParam(required = false) String cursor, + Authentication authentication) { + NvctUtils.addTagsToCurrentSpan(tracer, Map.of(SPAN_TAG_NCA_ID, ncaId)); + accountService.assertAccountExistsOrThrow(ncaId); + accountService.assertAccountIdFromPathMatches(ncaId, authentication); + return taskManagementFacade.listTasks(ncaId, authentication, limit, status, cursor); + } + + @GetMapping("/v1/nvct/accounts/{ncaId}/tasks/{taskId}") + @Operation( + summary = "Get Task Details", + description = """ + Gets details of specified task in the authenticated NVIDIA Cloud Account. + Requires a bearer token with 'admin:task_details' scope in the HTTP + Authorization header. + """ + ) + @PreAuthorize("hasAuthority('admin:task_details')") + public TaskResponse getTaskDetails( + @Parameter(description = NCA_ID_DESCRIPTION, required = true) + @PathVariable String ncaId, + @Parameter(description = "Task id", required = true) + @PathVariable("taskId") UUID taskId, + @Parameter(description = "Indicates whether to include secret names in the response") + @RequestParam(required = false, defaultValue = "true") boolean includeSecrets, + Authentication authentication) { + NvctUtils.addTagsToCurrentSpan(tracer, Map.of(SPAN_TAG_NCA_ID, ncaId)); + accountService.assertAccountExistsOrThrow(ncaId); + accountService.assertAccountIdFromPathMatches(ncaId, authentication); + return taskManagementFacade.getTaskDetails(ncaId, taskId, authentication, includeSecrets); + } + + @PostMapping("/v1/nvct/accounts/{ncaId}/tasks/{taskId}/cancel") + @Operation( + summary = "Cancel Task", + description = """ + Cancels the specified task in the authenticated NVIDIA Cloud Account. Requires + a bearer token with 'admin:cancel_task' scope in the HTTP Authorization header. + """ + ) + @PreAuthorize("hasAuthority('admin:cancel_task')") + public TaskResponse cancelTask( + @Parameter(description = NCA_ID_DESCRIPTION, required = true) + @PathVariable String ncaId, + @Parameter(description = "Task id", required = true) + @PathVariable("taskId") UUID taskId, + HttpServletRequest httpServletRequest, + Authentication authentication) { + NvctUtils.addTagsToCurrentSpan(tracer, Map.of(SPAN_TAG_NCA_ID, ncaId)); + accountService.assertAccountExistsOrThrow(ncaId); + accountService.assertAccountIdFromPathMatches(ncaId, authentication); + return taskManagementFacade.cancelTask(ncaId, taskId, + httpServletRequest, authentication); + } + + @DeleteMapping("/v1/nvct/accounts/{ncaId}/tasks/{taskId}") + @Operation( + summary = "Delete Task", + description = """ + Deletes the specified task in the authenticated NVIDIA Cloud Account. Requires + a bearer token with 'admin:delete_task' scope in the HTTP Authorization header. + """, + responses = @ApiResponse(responseCode = "204") + ) + @PreAuthorize("hasAuthority('admin:delete_task')") + public ResponseEntity deleteTask( + @Parameter(description = NCA_ID_DESCRIPTION, required = true) + @PathVariable String ncaId, + @Parameter(description = "Task id", required = true) + @PathVariable("taskId") UUID taskId, + HttpServletRequest httpServletRequest, + Authentication authentication) { + NvctUtils.addTagsToCurrentSpan(tracer, Map.of(SPAN_TAG_NCA_ID, ncaId)); + accountService.assertAccountExistsOrThrow(ncaId); + accountService.assertAccountIdFromPathMatches(ncaId, authentication); + return taskManagementFacade.deleteTask(ncaId, taskId, + httpServletRequest, authentication); + } + +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/ArtifactDto.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/ArtifactDto.java new file mode 100644 index 000000000..792a15702 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/ArtifactDto.java @@ -0,0 +1,50 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.rest.task.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import java.net.URI; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.NonNull; + +@Builder +@Data +@NoArgsConstructor +@AllArgsConstructor +@Schema(description = "Data Transfer Object(DTO) representing an artifact") +public class ArtifactDto { + + @Schema(description = "Artifact name") + @NotBlank + @NonNull + private String name; + + @Schema(description = "Artifact version") + @NotBlank + @NonNull + private String version; + + @Schema(description = "Artifact URI") + @NotNull + @NonNull + private URI uri; +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/BasicTaskDto.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/BasicTaskDto.java new file mode 100644 index 000000000..0848dda9a --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/BasicTaskDto.java @@ -0,0 +1,35 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.rest.task.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import java.util.UUID; +import lombok.Builder; + +@Builder(toBuilder = true) +@Schema(description = "Data Transfer Object(DTO) representing a Task with fewer details") +public record BasicTaskDto( + @Schema(description = "Unique Task id") + @NotNull UUID id, + + @Schema(description = "Task name") + @NotNull String name, + + @Schema(description = "Task status") + @NotNull TaskStatusEnum status) { +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/BulkTaskDetailsRequest.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/BulkTaskDetailsRequest.java new file mode 100644 index 000000000..9b99616c9 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/BulkTaskDetailsRequest.java @@ -0,0 +1,34 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.rest.task.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotEmpty; +import java.util.Set; +import java.util.UUID; +import lombok.Builder; +import lombok.NonNull; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@Builder(toBuilder = true) +@Schema(description = "Request payload to fetch details such as status about specific Tasks") +public record BulkTaskDetailsRequest( + @Schema(description = "Task Ids") + @NonNull @NotEmpty @Valid Set taskIds) { +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/ContainerEnvironmentEntryDto.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/ContainerEnvironmentEntryDto.java new file mode 100644 index 000000000..96be173d6 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/ContainerEnvironmentEntryDto.java @@ -0,0 +1,49 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.rest.task.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Pattern; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.NonNull; + +@Builder +@Data +@NoArgsConstructor +@AllArgsConstructor +@Schema(description = "Data Transfer Object(DTO) representing a container environment entry") +public class ContainerEnvironmentEntryDto { + private static final String KEY_REGEX = "^[a-z0-9A-Z][a-z0-9A-Z\\_]*$"; + + + @Schema(description = "Container environment key") + @Pattern(regexp = KEY_REGEX, + message = "Invalid environment key: Must conform to regex " + KEY_REGEX) + @NotBlank + @NonNull + private String key; + + @Schema(description = "Container environment value") + @NotBlank + @NonNull + private String value; + +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/CreateTaskRequest.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/CreateTaskRequest.java new file mode 100644 index 000000000..2cba2b36e --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/CreateTaskRequest.java @@ -0,0 +1,171 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.rest.task.dto; + +import static com.nvidia.nvct.util.NvctConstants.MAX_DESCRIPTION_LENGTH; +import static com.nvidia.nvct.util.NvctConstants.MAX_TAGS_COUNT; +import static com.nvidia.nvct.util.NvctConstants.MAX_TAG_LENGTH; +import static com.nvidia.nvct.util.NvctConstants.NAME_REGEX; +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import com.nvidia.nvct.service.telemetry.dto.TelemetriesDto; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.annotation.Nullable; +import jakarta.validation.Constraint; +import jakarta.validation.ConstraintValidator; +import jakarta.validation.ConstraintValidatorContext; +import jakarta.validation.Payload; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Pattern; +import jakarta.validation.constraints.Size; +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; +import java.net.URI; +import java.time.Duration; +import java.util.List; +import java.util.Set; +import lombok.Builder; +import lombok.NonNull; +import lombok.extern.slf4j.Slf4j; +import org.hibernate.validator.constraints.Length; + +@Slf4j +@Builder(toBuilder = true) +@Schema(description = "Request payload to create a Task") +public record CreateTaskRequest( + @Schema(description = "Task name must start with lowercase/uppercase/digit and can " + + "only contain lowercase, uppercase, digit, hyphen, and underscore characters.") + @Pattern(regexp = NAME_REGEX, + message = "Invalid task name: Must conform to regex " + NAME_REGEX) + @Size(min = 1, max = 128, message = "Invalid task name: must be 1 - 128 characters long") + @NonNull @NotBlank String name, + + @Schema(description = "GPU, instance-type, and backend details for launching a Task.") + @NotNull @Valid GpuSpecificationDto gpuSpecification, + + @Schema(description = "Task container image") + @Nullable URI containerImage, + + @Schema(description = "Args to be passed when launching the container.") + @Nullable String containerArgs, + + @Schema(description = "Environment settings for launching the container.") + @Nullable List<@Valid ContainerEnvironmentEntryDto> containerEnvironment, + + @Schema(description = "Optional set of models") + @Nullable Set<@Valid ArtifactDto> models, + + @Schema(description = "Optional set of resources") + @Nullable Set<@Valid ArtifactDto> resources, + + @Schema(description = "Optional set of tags") + @Nullable @Valid + @Size(max = MAX_TAGS_COUNT, message = "Maximum number of tags of " + MAX_TAGS_COUNT + + " is exceeded.") + Set<@Length(max = MAX_TAG_LENGTH, message = "Maximum tag length of " + MAX_TAG_LENGTH + + " is exceeded.") + @Pattern(regexp = "[a-zA-Z0-9\\-_:=]+") String> tags, + + @Schema(description = "Optional Task description") + @Nullable + @Length(max = MAX_DESCRIPTION_LENGTH, message = "Maximum description length of " + + MAX_DESCRIPTION_LENGTH + " is exceeded.") + String description, + + @Schema(description = "Optional max duration for which the Task should run. " + + "Must be specified when launching Task on 'GFN'. Must be less than PT8H when " + + "launching Task on 'GFN'.", + type = "string", + format = "duration", + example = "PT12H30M") + @Nullable Duration maxRuntimeDuration, + + @Schema(description = "Optional max duration for which the Task should be queued.", + defaultValue = "PT72H", + type = "string", + format = "duration", + example = "PT4H30M45S") + @Nullable Duration maxQueuedDuration, + + @Schema(description = "Optional grace period after which the Task should be terminated.", + defaultValue = "PT1H", + type = "string", + format = "duration", + example = "PT1H30M20S") + @Nullable Duration terminationGracePeriodDuration, + + @Schema(description = "Optional Task result handling strategy", + defaultValue = "UPLOAD") + @Nullable ResultHandlingStrategyEnum resultHandlingStrategy, + + @Schema(description = "Optional result path in NGC Model Registry for the generated " + + "results. Must be specified when resultHandlingStrategy is UPLOAD and the " + + "format should be -- //.") + @Nullable String resultsLocation, + + @Schema(description = "Optional Helm Chart") + @Nullable URI helmChart, + + @Schema(description = "Optional telemetry configuration for logs, metrics, and traces.") + @Nullable @ValidTelemetries TelemetriesDto telemetries, + + @Schema(description = "Optional set of secrets. If resultHandlingStrategy is UPLOAD, " + + "then user must specify NGC_API_KEY secret with write-privileges for NVCT to " + + "upload results/checkpoints to the NGC Private Registry at a path specified " + + "using resultPath property.") + @Nullable Set<@Valid SecretDto> secrets) { + + @Documented + @Target(FIELD) + @Retention(RUNTIME) + @Constraint(validatedBy = TelemetriesValidator.class) + @interface ValidTelemetries { + String message() default "Invalid request: Issues with the telemetries"; + + Class[] groups() default {}; + + Class[] payload() default {}; + } + + private static class TelemetriesValidator + implements ConstraintValidator { + private static final String MESG_INVALID_TELEMETRY_REQUEST = + "Invalid request: telemetries object must have at least one UUID specified."; + + @Override + public boolean isValid( + TelemetriesDto telemetries, + ConstraintValidatorContext constraintValidatorContext) { + if (telemetries == null) { + return true; + } + + if (telemetries.logsTelemetryId() == null && + telemetries.metricsTelemetryId() == null && + telemetries.tracesTelemetryId() == null) { + log.error(MESG_INVALID_TELEMETRY_REQUEST); + return false; + } + return true; + } + } + +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/GpuSpecificationDto.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/GpuSpecificationDto.java new file mode 100644 index 000000000..3c4d211e8 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/GpuSpecificationDto.java @@ -0,0 +1,51 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.rest.task.dto; + +import tools.jackson.databind.node.ObjectNode; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.annotation.Nullable; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotBlank; +import java.util.Set; +import lombok.Builder; + +@Builder +@Schema(description = "Data Transfer Object(DTO) representing GPU specification for a Task.") +public record GpuSpecificationDto( + @Schema(description = "GPU name from the cluster") + @NotBlank String gpu, + + @Schema(description = "Backend/CSP where the GPU powered instance will be launched") + @Nullable String backend, + + @Schema(description = """ + Specific clusters within instance or worker node powered by the selected + instance-type to launch the Task. + """) + @Nullable Set clusters, + + @Schema(description = "Instance type, based on GPU, assigned to a Worker") + @NotBlank String instanceType, + + @Schema(description = "Optional configuration field typically used with Helm Charts " + + "to substitute placeholders in values.yaml") + @Nullable ObjectNode configuration, + + @Schema(description = "Helm validation policy cluster attributes") + @Nullable @Valid HelmValidationPolicyDto helmValidationPolicy) { +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/HealthDto.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/HealthDto.java new file mode 100644 index 000000000..2ea2a7659 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/HealthDto.java @@ -0,0 +1,38 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.rest.task.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.annotation.Nullable; +import jakarta.validation.constraints.NotBlank; +import lombok.Builder; + +@Builder +@Schema(description = "Data Transfer Object(DTO) representing instance health") +public record HealthDto( + @Schema(description = "GPU Type as per SDD") + @NotBlank String gpu, + + @Schema(description = "Backend/CSP where the GPU powered instance will be launched") + @NotBlank String backend, + + @Schema(description = "Instance type") + @Nullable String instanceType, + + @Schema(description = "Deployment error") + @NotBlank String error) { +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/HelmValidationPolicyDto.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/HelmValidationPolicyDto.java new file mode 100644 index 000000000..c22f8c1d7 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/HelmValidationPolicyDto.java @@ -0,0 +1,57 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.rest.task.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.annotation.Nullable; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import java.util.List; +import lombok.Builder; + +@Builder +@Schema(description = "Data Transfer Object(DTO) representing Helm validation policy") +public record HelmValidationPolicyDto ( + @Schema(description = "Helm validation policy name.") + @NotNull + ValidationPolicyNameEnum name, + + @Schema(description = """ + An API Group in Kubernetes is a collection of related functionality. + When present, must contain at least one entry; each entry must be a valid + KubernetesType (group, version, kind). + """) + @Valid @Nullable @Size(min = 1) + List<@NotNull KubernetesType> extraKubernetesTypes) { + + @Builder + public record KubernetesType( + @Schema(description = "Name of API Group") + @NotBlank + String group, + + @Schema(description = "Version of API Group") + @NotBlank + String version, + + @Schema(description = "API Group resource or Kind") + @NotBlank + String kind) { + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/InstanceDto.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/InstanceDto.java new file mode 100644 index 000000000..f15e5014d --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/InstanceDto.java @@ -0,0 +1,70 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.rest.task.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import java.time.Instant; +import java.util.UUID; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.NonNull; + +@Builder +@Data +@NoArgsConstructor +@AllArgsConstructor +@Schema(description = "Data Transfer Object(DTO) representing an instance") +public class InstanceDto { + + @Schema(description = "Unique id of the instance") + private String instanceId; + + @Schema(description = "Task executing on the instance") + private UUID taskId; + + @Schema(description = "GPU instance-type powering the instance") + private String instanceType; + + @Schema(description = "Instance state") + private InstanceStateEnum instanceState; + + @Schema(description = "ICMS request-id used to launch this instance") + private UUID icmsRequestId; + + @Schema(description = "NVIDIA Cloud Account Id that owns the Task running on the instance") + private String ncaId; + + @Schema(description = "GPU name powering the instance") + private String gpu; + + @Schema(description = "Backend where the instance is running") + private String backend; + + @Schema(description = "Location such as zone name or region where the instance is running") + private String location; + + @Schema(description = "Instance creation timestamp") + private Instant instanceCreatedAt; + + @Schema(description = "Instance's last updated timestamp") + private Instant instanceUpdatedAt; + +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/InstanceStateEnum.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/InstanceStateEnum.java new file mode 100644 index 000000000..08196c167 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/InstanceStateEnum.java @@ -0,0 +1,50 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.rest.task.dto; + +import static java.lang.String.format; + +import java.util.EnumSet; + +public enum InstanceStateEnum { + ACTIVE("ACTIVE"), + STARTING("STARTING"), + RUNNING("RUNNING"), + TERMINATED("TERMINATED"), + PREEMPTED("PREEMPTED"), + DELETED("DELETED"); + + private final String name; + + InstanceStateEnum(String name) { + this.name = name; + } + + @Override + public String toString() { + return this.name; + } + + public static InstanceStateEnum fromText(String val) { + return EnumSet.allOf(InstanceStateEnum.class) + .stream() + .filter(e -> e.name.equalsIgnoreCase(val)) + .findFirst() + .orElseThrow(() -> new IllegalStateException(format("Unsupported enum %s.", val))); + } + +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/InstanceUsageTypeEnum.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/InstanceUsageTypeEnum.java new file mode 100644 index 000000000..a3601380f --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/InstanceUsageTypeEnum.java @@ -0,0 +1,38 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.rest.task.dto; + + +// Used to validate the instance-types on which the Task will be launched. This enum +// is used as value for instanceTypeUsage=CONTAINER|DEFAULT query parameter with +// ICMS endpoint. For container-based Tasks, instanceTypeUsage=CONTAINER is used. For +// helm-based Tasks, instanceTypeUsage=DEFAULT is used. +public enum InstanceUsageTypeEnum { + CONTAINER("CONTAINER"), + DEFAULT("DEFAULT"); + + private final String value; + + InstanceUsageTypeEnum(String value) { + this.value = value; + } + + @Override + public String toString() { + return value; + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/ListBasicTaskDetailsResponse.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/ListBasicTaskDetailsResponse.java new file mode 100644 index 000000000..0d4304a29 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/ListBasicTaskDetailsResponse.java @@ -0,0 +1,32 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.rest.task.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import java.util.List; +import lombok.Builder; + +@Builder +@Schema(description = "Response body containing details such as status for list of specific tasks") +public record ListBasicTaskDetailsResponse( + @Schema(description = "NVIDIA Cloud Account id of the tasks with concise response") + @NotBlank String ncaId, + @Schema(description = "List of tasks with few basic properties included in the response") + @NotNull List tasks) { +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/ListTasksResponse.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/ListTasksResponse.java new file mode 100644 index 000000000..5e5189398 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/ListTasksResponse.java @@ -0,0 +1,35 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.rest.task.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import java.util.List; +import lombok.Builder; + +@Builder +@Schema(description = "Response body containing list of tasks") +public record ListTasksResponse ( + @Schema(description = "List of tasks") + @NotNull List tasks, + + @Schema(description = "Pagination limit - Not included in the response for the last slice") + Integer limit, + + @Schema(description = "Pagination cursor - Not included in the response for the last slice") + String cursor) { +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/ResultHandlingStrategyEnum.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/ResultHandlingStrategyEnum.java new file mode 100644 index 000000000..b92339361 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/ResultHandlingStrategyEnum.java @@ -0,0 +1,49 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.rest.task.dto; + +import static java.lang.String.format; + +import java.util.EnumSet; +import lombok.NonNull; + +public enum ResultHandlingStrategyEnum { + + UPLOAD("UPLOAD"), + NONE("NONE"); + + private final String name; + + ResultHandlingStrategyEnum(String name) { + this.name = name; + } + + @Override + public String toString() { + return this.name; + } + + public static ResultHandlingStrategyEnum fromText(@NonNull String val) { + return EnumSet.allOf(ResultHandlingStrategyEnum.class) + .stream() + .filter(e -> e.name.equalsIgnoreCase(val)) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException(format("Unsupported enum '%s'", + val))); + } + +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/SecretDto.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/SecretDto.java new file mode 100644 index 000000000..47a4709ca --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/SecretDto.java @@ -0,0 +1,92 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.rest.task.dto; + +import static com.nvidia.nvct.util.NvctConstants.MAX_SECRET_NAME_LENGTH; +import static com.nvidia.nvct.util.NvctConstants.MAX_SECRET_VALUE_LENGTH; +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import tools.jackson.databind.JsonNode; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.Constraint; +import jakarta.validation.ConstraintValidator; +import jakarta.validation.ConstraintValidatorContext; +import jakarta.validation.Payload; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Pattern; +import jakarta.validation.constraints.Size; +import java.lang.annotation.Documented; +import java.lang.annotation.Retention; +import java.lang.annotation.Target; +import lombok.Builder; +import lombok.NonNull; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@Builder +@Schema(description = "Data Transfer Object(DTO) representing secret name/value pair") +public record SecretDto( + @Schema(description = "Secret name") + @Pattern(regexp = SECRET_NAME_REGEX, + message = "Invalid secret name: Must conform to regex " + SECRET_NAME_REGEX) + @Size(min = 1, max = MAX_SECRET_NAME_LENGTH, + message = "Invalid secret name: must be 1 - " + MAX_SECRET_NAME_LENGTH + " chars long") + @NonNull @NotBlank String name, + + @Schema(description = "Secret value must be 1 - " + MAX_SECRET_VALUE_LENGTH + " chars long") + @NonNull @ValidSecretValueLength JsonNode value) { + + private static final String MESG_INVALID_SECRET_VALUE = + "Invalid secret value specified"; + private static final String MESG_INVALID_SECRET_VALUE_LENGTH = + "Secret value's length must be 1 - " + MAX_SECRET_VALUE_LENGTH + " chars long"; + + private static final String SECRET_NAME_REGEX = "^[a-z0-9A-Z][a-z0-9A-Z\\_\\.\\-]*$"; + + @Documented + @Target(FIELD) + @Retention(RUNTIME) + @Constraint(validatedBy = SecretValueLengthValidator.class) + @interface ValidSecretValueLength { + String message() default MESG_INVALID_SECRET_VALUE; + + Class[] groups() default {}; + + Class[] payload() default {}; + } + + private static class SecretValueLengthValidator + implements + ConstraintValidator { + + @Override + public boolean isValid( + JsonNode jsonNode, + ConstraintValidatorContext constraintValidatorContext) { + var value = jsonNode.isString() ? jsonNode.asString() : jsonNode.toString(); + var length = value != null ? value.trim().length() : 0; + if (length == 0 || length > MAX_SECRET_VALUE_LENGTH) { + log.error(MESG_INVALID_SECRET_VALUE_LENGTH); + return false; + } + + return true; + } + } + +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/TaskDto.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/TaskDto.java new file mode 100644 index 000000000..8b164ed86 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/TaskDto.java @@ -0,0 +1,134 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.rest.task.dto; + +import static com.fasterxml.jackson.annotation.JsonFormat.Shape.STRING; +import static com.nvidia.nvct.util.NvctConstants.MAX_TAGS_COUNT; +import static com.nvidia.nvct.util.NvctConstants.MAX_TAG_LENGTH; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.nvidia.nvct.service.telemetry.dto.TelemetriesDto; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.annotation.Nullable; +import jakarta.validation.constraints.NotNull; +import java.net.URI; +import java.time.Duration; +import java.time.Instant; +import java.util.List; +import java.util.Set; +import java.util.UUID; +import lombok.Builder; + +@Builder(toBuilder = true) +@Schema(description = "Data Transfer Object(DTO) representing a Task") +public record TaskDto( + @Schema(description = "Unique Task id") + @NotNull UUID id, + + @Schema(description = "NVIDIA Cloud Account Id") + @NotNull String ncaId, + + @Schema(description = "Task name") + @NotNull String name, + + @Schema(description = "Task status") + @NotNull TaskStatusEnum status, + + @Schema(description = "Task GPU Specification") + @NotNull GpuSpecificationDto gpuSpecification, + + @Schema(description = "Task container") + @NotNull URI containerImage, + + @Schema(description = "Args used to launch the container") + @Nullable String containerArgs, + + @Schema(description = "Environment settings used to launch the container") + @Nullable + List containerEnvironment, + + @Schema(description = "Set of models") + @Nullable + Set models, + + @Schema(description = "Set of resources") + @Nullable Set resources, + + @Schema(description = "Set of tags. Maximum allowed number of tags per " + + "Task is " + MAX_TAGS_COUNT + ". Maximum length of each tag is " + + MAX_TAG_LENGTH + " chars.") + @Nullable Set tags, + + @Schema(description = "Task description") + @Nullable String description, + + @Schema(description = "Results handling strategy") + @Nullable ResultHandlingStrategyEnum resultHandlingStrategy, + + @Schema(description = "Results location") + @Nullable String resultsLocation, + + @Schema(description = "Maximum runtime duration", + type = "string", + format = "duration", + example = "PT12H30M") + @JsonFormat(shape = STRING) + @Nullable Duration maxRuntimeDuration, + + @Schema(description = "Maximum queued duration", + defaultValue = "PT72H", + type = "string", + format = "duration", + example = "PT4H30M45S") + @JsonFormat(shape = STRING) + @NotNull Duration maxQueuedDuration, + + @Schema(description = "Termination grace period duration", + defaultValue = "PT1H", + type = "string", + format = "duration", + example = "PT1H30M20S") + @JsonFormat(shape = STRING) + @NotNull Duration terminationGracePeriodDuration, + + @Schema(description = "Optional Helm Chart") + @Nullable URI helmChart, + + @Schema(description = "Task health") + @Nullable HealthDto healthInfo, + + @Schema(description = "Task secret keys") + @Nullable Set secrets, + + @Schema(description = "Percentage complete") + @Nullable Integer percentComplete, + + @Schema(description = "Last heartbeat received timestamp") + @Nullable Instant lastHeartbeatAt, + + @Schema(description = "Last updated timestamp") + @Nullable Instant lastUpdatedAt, + + @Schema(description = "Optional telemetry configuration") + @Nullable TelemetriesDto telemetries, + + @Schema(description = "Task creation timestamp") + @NotNull Instant createdAt, + + @Schema(description = "List of instances") + @Nullable List instances) { +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/TaskResponse.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/TaskResponse.java new file mode 100644 index 000000000..7fc8d1402 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/TaskResponse.java @@ -0,0 +1,29 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.rest.task.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import lombok.Builder; + +@Builder +@Schema(description = "Response body with Task details") +public record TaskResponse( + @Schema(description = "Task details") + @NotNull TaskDto task) { + +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/TaskStatusEnum.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/TaskStatusEnum.java new file mode 100644 index 000000000..bdd57fdac --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/TaskStatusEnum.java @@ -0,0 +1,55 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.rest.task.dto; + +import static java.lang.String.format; + +import java.util.EnumSet; +import lombok.NonNull; + +public enum TaskStatusEnum { + + QUEUED("QUEUED"), + LAUNCHED("LAUNCHED"), + RUNNING("RUNNING"), + ERRORED("ERRORED"), + CANCELED("CANCELED"), + EXCEEDED_MAX_RUNTIME_DURATION("EXCEEDED_MAX_RUNTIME_DURATION"), + EXCEEDED_MAX_QUEUED_DURATION("EXCEEDED_MAX_QUEUED_DURATION"), + COMPLETED("COMPLETED"); + + private final String name; + + TaskStatusEnum(String name) { + this.name = name; + } + + @Override + public String toString() { + return this.name; + } + + public static TaskStatusEnum fromText(@NonNull String val) { + return EnumSet.allOf(TaskStatusEnum.class) + .stream() + .filter(e -> e.name.equalsIgnoreCase(val)) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException(format("Unsupported enum '%s'", + val))); + } + +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/ValidationPolicyNameEnum.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/ValidationPolicyNameEnum.java new file mode 100644 index 000000000..22366e318 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/ValidationPolicyNameEnum.java @@ -0,0 +1,39 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.rest.task.dto; + +import io.swagger.v3.oas.annotations.media.Schema; + +/** + * Validation Policy Names enumerator for Helm validation. + */ +@Schema(description = "Validation policy names for Helm validation") +public enum ValidationPolicyNameEnum { + DEFAULT("Default"), + UNRESTRICTED("Unrestricted"); + + private final String name; + + ValidationPolicyNameEnum(String name) { + this.name = name; + } + + @Override + public String toString() { + return name; + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/account/AccountService.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/account/AccountService.java new file mode 100644 index 000000000..9e4766101 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/account/AccountService.java @@ -0,0 +1,179 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.account; + +import static com.nvidia.nvct.service.apikeys.ApiKeyValidationResult.POLICY_RESULT_ATTRIBUTE; + +import com.google.common.annotations.VisibleForTesting; +import com.nvidia.boot.exceptions.ForbiddenException; +import com.nvidia.boot.exceptions.NotFoundException; +import com.nvidia.boot.exceptions.UnprocessableEntityException; +import com.nvidia.nvct.service.account.dto.AccountDto; +import com.nvidia.nvct.service.apikeys.ApiKeyValidationResult; +import com.nvidia.nvct.service.nvcf.NvcfClient; +import com.nvidia.nvct.service.telemetry.dto.TelemetryDto; +import java.util.Collections; +import java.util.Map; +import java.util.UUID; +import java.util.function.Function; +import java.util.stream.Collectors; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.security.core.Authentication; +import org.springframework.security.oauth2.core.DefaultOAuth2AuthenticatedPrincipal; +import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; +import org.springframework.web.reactive.function.client.WebClientResponseException; + +@Slf4j +@Service +@RequiredArgsConstructor +public class AccountService { + + private static final String MESG_UNSUPPORTED_AUTHENTICATION_TYPE = + "Unsupported Authentication class type '%s' or PolicyResult object was not found."; + private static final String MESG_BLANK_PARAMETER = "'%s' cannot be blank"; + private static final String MESG_ACCOUNT_NOT_FOUND = + "Account '%s': Does not exist"; + private static final String MESG_ACCOUNT_ID_MISMATCH = + "Account id mismatch. Expected: '%s', Got: '%s'"; + + private final NvcfClient nvcfClient; + + public String getNcaId(Authentication authentication) { + // JWT + if (authentication instanceof JwtAuthenticationToken) { + var clientId = authentication.getName(); + var dto = nvcfClient.getClient(clientId); + return dto.ncaId(); + } + + // Api-Key + if (authentication.getPrincipal() instanceof DefaultOAuth2AuthenticatedPrincipal principal + && principal.getAttributes() != null + && principal.getAttributes() + .get(POLICY_RESULT_ATTRIBUTE) instanceof ApiKeyValidationResult policyResult) { + return policyResult.ncaId(); + } + + throw new UnprocessableEntityException(MESG_UNSUPPORTED_AUTHENTICATION_TYPE + .formatted(authentication.getClass())); + } + + public AccountDto getAccount(String ncaId) { + if (StringUtils.isBlank(ncaId)) { + var mesg = MESG_BLANK_PARAMETER.formatted("ncaId"); + log.error(mesg); + throw new IllegalArgumentException(mesg); + } + + return nvcfClient.getAccount(ncaId); + } + + public String getAccountName(String ncaId) { + if (StringUtils.isBlank(ncaId)) { + var mesg = MESG_BLANK_PARAMETER.formatted("ncaId"); + log.error(mesg); + throw new IllegalArgumentException(mesg); + } + + var account = getAccount(ncaId); + return account.name(); + } + + public AccountDto lookupAccountUsingNcaIdOrThrow(String ncaId) { + try { + return getAccount(ncaId); + } catch (WebClientResponseException.NotFound ex) { + var mesg = MESG_ACCOUNT_NOT_FOUND.formatted(ncaId) + " - " + ex.getMessage(); + log.error(mesg); + throw new NotFoundException(mesg, ex); + } + } + + public Map getAccountTelemetryMap(String ncaId) { + var accountDto = getAccount(ncaId); + + if (CollectionUtils.isEmpty(accountDto.telemetries())) { + return Collections.emptyMap(); + } + + return accountDto.telemetries().stream() + .collect(Collectors.toMap(TelemetryDto::telemetryId, Function.identity())); + } + + public void invalidateCacheForSpecificAccount(String ncaId) { + nvcfClient.invalidateCacheForSpecificAccount(ncaId); + } + + public void assertAccountExistsOrThrow(String ncaId) { + if (StringUtils.isBlank(ncaId)) { + var mesg = MESG_BLANK_PARAMETER.formatted("ncaId"); + log.error(mesg); + throw new IllegalArgumentException(mesg); + } + + // Verify account exists by trying to fetch it from NVCF + try { + nvcfClient.getAccount(ncaId); + } catch (WebClientResponseException.NotFound ex) { + var mesg = MESG_ACCOUNT_NOT_FOUND.formatted(ncaId); + log.error(mesg); + throw new NotFoundException(mesg, ex); + } + } + + // Used only for super admin endpoints to ensure that the NCA Id specified in the path + // matches the corresponding property in the auth token. We do not allow api-keys with admin: + // scopes as api-keys are locked to the account and cannot be used across accounts. This is + // different from JWTs with admin: scopes which can be used across different accounts. The + // reason we chose to lock down api-keys to a specific account is because they are long-lived + // when compared to JWTs which are ephemeral and short-lived. + public void assertAccountIdFromPathMatches( + String ncaId, // Value of the path variable in super admin endpoints + Authentication authentication) { + // Api-key + if (authentication.getPrincipal() instanceof DefaultOAuth2AuthenticatedPrincipal principal + && principal.getAttributes() != null + && principal.getAttributes() + .get(POLICY_RESULT_ATTRIBUTE) instanceof ApiKeyValidationResult policyResult) { + // Check if the nca_id in the api-key matches the value from the path variable. + if (!policyResult.ncaId().equals(ncaId)) { + var mesg = MESG_ACCOUNT_ID_MISMATCH.formatted(policyResult.ncaId(), ncaId); + log.error(mesg); + throw new ForbiddenException(mesg); + } + return; + } + + // JWT: No-op + if (authentication instanceof JwtAuthenticationToken) { + // No need to further check for any match for JWTs for super admin endpoints. + return; + } + + throw new UnprocessableEntityException(MESG_UNSUPPORTED_AUTHENTICATION_TYPE + .formatted(authentication.getClass())); + } + + @VisibleForTesting + public void invalidateCache() { + nvcfClient.invalidateCache(); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/account/dto/AccountDto.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/account/dto/AccountDto.java new file mode 100644 index 000000000..537528f39 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/account/dto/AccountDto.java @@ -0,0 +1,53 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.account.dto; + +import com.nvidia.nvct.service.telemetry.dto.TelemetryDto; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.annotation.Nullable; +import jakarta.validation.constraints.NotNull; +import java.time.Instant; +import java.util.List; +import java.util.Set; +import lombok.Builder; + + +@Builder +@Schema(description = "Data Transfer Object(DTO) representing an account") +public record AccountDto( + + @Schema(description = "NVIDIA Cloud Account id") + @NotNull String ncaId, + + @Schema(description = "Client Ids associated with the NVIDIA Cloud Account") + @Nullable Set clientIds, + + @Schema(description = "Account/Org name") + @NotNull String name, + + @Schema(description = "Account Telemetry configurations") + @Nullable List telemetries, + + @Schema(description = "Registry credentials associated with the account") + @Nullable List registryCredentials, + + @Schema(description = "Maximum number of tasks allowed for Account") + @NotNull Integer maxTasksAllowed, + + @Schema(description = "Last time the account was updated.") + @Nullable Instant lastUpdatedAt) { +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/account/dto/RegistryCredentialDto.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/account/dto/RegistryCredentialDto.java new file mode 100644 index 000000000..ad99283ea --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/account/dto/RegistryCredentialDto.java @@ -0,0 +1,68 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.account.dto; + +import static com.nvidia.nvct.util.NvctConstants.HOSTNAME_REGEX; +import static com.nvidia.nvct.util.NvctConstants.MAX_HOSTNAME_LENGTH; +import static com.nvidia.nvct.util.NvctConstants.MAX_TAGS_COUNT; +import static com.nvidia.nvct.util.NvctConstants.MAX_TAG_LENGTH; +import static com.nvidia.nvct.util.NvctConstants.TAG_REGEX; + +import com.nvidia.boot.registries.service.registry.dto.ArtifactTypeEnum; +import com.nvidia.nvct.rest.task.dto.SecretDto; +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.annotation.Nullable; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Pattern; +import jakarta.validation.constraints.Size; +import java.util.Set; +import lombok.Builder; +import org.hibernate.validator.constraints.Length; + +@Builder(toBuilder = true) +@Schema(description = "DTO of a registry credential") +public record RegistryCredentialDto( + @Schema(description = "Registry hostname") + @Pattern(regexp = HOSTNAME_REGEX, + message = "Invalid hostname: Must conform to regex " + HOSTNAME_REGEX) + @Size(min = 1, max = MAX_HOSTNAME_LENGTH, + message = "Invalid hostname: Must be 1 - " + MAX_HOSTNAME_LENGTH + " chars long") + @NotBlank String registryHostname, + + @Schema(description = "Registry credential - secret value must be base64 encoded " + + "string in username:password format") + @NotNull SecretDto secret, + + @Schema(description = "Artifact types") + @NotNull @NotEmpty Set artifactTypes, + + @Nullable + @Schema(description = "Optional set of tags") + @Valid + @Size(max = MAX_TAGS_COUNT, + message = "Maximum number of tags of " + MAX_TAGS_COUNT + " is exceeded.") + Set<@Length(max = MAX_TAG_LENGTH, + message = "Maximum tag length of " + MAX_TAG_LENGTH + " is exceeded.") + @Pattern(regexp = TAG_REGEX) String> tags, + + @Nullable + @Schema(description = "Optional registry credential description") + String description) { +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/apikeys/ApiKeyValidationResult.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/apikeys/ApiKeyValidationResult.java new file mode 100644 index 000000000..4e989b1c0 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/apikeys/ApiKeyValidationResult.java @@ -0,0 +1,124 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.apikeys; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonSetter; +import com.fasterxml.jackson.annotation.Nulls; +import com.google.common.annotations.VisibleForTesting; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.UUID; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.oauth2.core.DefaultOAuth2AuthenticatedPrincipal; +import org.springframework.security.oauth2.core.OAuth2AuthenticatedPrincipal; +import org.springframework.util.StringUtils; + +/** + * Represents the result of API Key validation. + * + * @param allowed indicates whether the current request should be allowed to proceed + * @param ncaId NVIDIA Cloud Account(NCA) id + * @param ownerId for Service Keys, this parameter will be NCA Id; for Personal Keys, + * this parameter will be OIDC Id + * @param policy resource types and scopes + */ +public record ApiKeyValidationResult(@JsonProperty("allowed") boolean allowed, + @JsonProperty("ncaId") String ncaId, + @JsonProperty("ownerId") String ownerId, + @JsonProperty("policy") Policy policy) { + + public static final String TASK_ACCESS_ATTRIBUTE = "task_access"; + public static final String POLICY_RESULT_ATTRIBUTE = "policy_result"; + + public ApiKeyValidationResult( + boolean allowed, + String ncaId, + String ownerId, + Policy policy) { + this.allowed = allowed; + this.ncaId = ncaId; + this.ownerId = ownerId; + this.policy = policy; + } + + public record Resource(@JsonProperty("type") String type, @JsonProperty("id") String id) { + + } + + public record Policy( + @JsonProperty("resources") @JsonSetter(nulls = Nulls.AS_EMPTY) List resources, + @JsonProperty("scopes") @JsonSetter(nulls = Nulls.AS_EMPTY) List scopes, + @JsonProperty("product") String product) { + + } + + public boolean valid() { + return allowed && StringUtils.hasText(ncaId) && StringUtils.hasText(ownerId) && + policy != null; + } + + @JsonIgnore + public OAuth2AuthenticatedPrincipal getOAuth2Principal() { + Map resourcesAttribute = Map.of( + TASK_ACCESS_ATTRIBUTE, allAllowedTasks(policy.resources), + POLICY_RESULT_ATTRIBUTE, this); + var scopes = policy.scopes.stream() + .map(scope -> (GrantedAuthority) new SimpleGrantedAuthority("apikey:" + scope)) + .toList(); + return new DefaultOAuth2AuthenticatedPrincipal(ownerId, resourcesAttribute, scopes); + } + + public record ApiKeyTaskAccess(Set allowedTaskIds, + boolean privateTasksAllowed) { + + public boolean hasResourcesScopedForTask(UUID taskId) { + return allowedTaskIds.contains(taskId); + } + } + + @VisibleForTesting + static ApiKeyTaskAccess allAllowedTasks(List resources) { + Set allowedTaskIds = new HashSet<>(); + boolean privateTasksAllowed = false; + + for (var resource : resources) { + if ("account-tasks".equals(resource.type()) && "*".equals(resource.id())) { + privateTasksAllowed = true; + } + if (!"task".equals(resource.type())) { + continue; + } + var resourceId = resource.id(); + if (resourceId == null) { + continue; + } + + try { + var resourceTaskId = UUID.fromString(resourceId); + allowedTaskIds.add(resourceTaskId); + } catch (Exception e) { + // continue + } + } + return new ApiKeyTaskAccess(allowedTaskIds, privateTasksAllowed); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/apikeys/ApiKeysClient.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/apikeys/ApiKeysClient.java new file mode 100644 index 000000000..d7b1277c0 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/apikeys/ApiKeysClient.java @@ -0,0 +1,156 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.apikeys; + +import tools.jackson.databind.json.JsonMapper; +import com.nvidia.boot.exceptions.ForbiddenException; +import com.nvidia.boot.exceptions.UpstreamException; +import com.nvidia.nvct.configuration.staticclientauth.FixedBearerExchangeFilterFunction; +import com.nvidia.nvct.configuration.staticclientauth.StaticClientAuthConfiguration.StaticClientApiKeysProperties; +import com.nvidia.nvct.service.apikeys.dto.ApiKeyValidationRequest; +import com.nvidia.nvct.service.apikeys.dto.ApiKeyValidationResponse; +import java.time.Duration; +import java.util.Arrays; +import java.util.List; +import java.util.Optional; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.cloud.context.config.annotation.RefreshScope; +import org.springframework.http.HttpStatusCode; +import org.springframework.http.MediaType; +import org.springframework.security.oauth2.client.AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager; +import org.springframework.security.oauth2.client.InMemoryReactiveOAuth2AuthorizedClientService; +import org.springframework.security.oauth2.client.registration.ClientRegistration; +import org.springframework.security.oauth2.client.registration.InMemoryReactiveClientRegistrationRepository; +import org.springframework.security.oauth2.client.web.reactive.function.client.ServerOAuth2AuthorizedClientExchangeFilterFunction; +import org.springframework.security.oauth2.core.AuthorizationGrantType; +import org.springframework.stereotype.Service; +import org.springframework.web.reactive.function.client.ExchangeFilterFunction; +import org.springframework.web.reactive.function.client.WebClient; +import reactor.core.publisher.Mono; +import reactor.util.retry.Retry; +import reactor.util.retry.RetryBackoffSpec; + +@Service +@RefreshScope +@Slf4j +public class ApiKeysClient { + + private static final String CLIENT_REGISTRATION_ID = "api-keys"; + + private static final RetryBackoffSpec RETRY_SPEC = Retry.backoff(2, Duration.ofMillis(200)) + .jitter(0.75) + .doBeforeRetry(retrySignal -> log.info("before retrying call")) + .doAfterRetry(retrySignal -> log.info("after retrying call")) + // retry only on 500 upstream + .filter(UpstreamException.class::isInstance) + .onRetryExhaustedThrow((retryBackoffSpec, retrySignal) -> { + log.error("External Service failed to process after max retries"); + return new UpstreamException( + "Failed to get response from external system after retries."); + }); + + private final WebClient webClient; + private final JsonMapper jsonMapper; + private final String evaluationUri; + private final String requestPropertyName; + + // We could have used OAuth2AuthorizedClientManager and relied on Spring Security to + // pick up the configuration properties using ClientRegistrationRepository directly. However, + // the client-secret value held in the ClientRegistrationRepository does not get refreshed when + // client-secret is rotated. Addressing these issues requires introducing a refreshable + // ClientRegistrationRepository that wasn't clean. Instead, we will keep it simple and use + // the tried and tested approach of using @Value and @RefreshScope annotations and wire + // things up ourselves. + public ApiKeysClient( + @Value("${nvct.api-keys.base-url}") String baseUrl, + @Value("${nvct.api-keys.evaluation-uri:/v1/namespaces/nvct/evaluations/apikey.allow}") + String evaluationUri, + @Value("${nvct.api-keys.request-property-name:apiKey}") + String requestPropertyName, + @Value("${spring.security.oauth2.client.registration.api-keys.client-id}") String clientId, + @Value("${spring.security.oauth2.client.registration.api-keys.client-secret}") + String clientSecret, + @Value("${spring.security.oauth2.client.registration.api-keys.scope}") String scope, + @Value("${spring.security.oauth2.client.provider.api-keys.token-uri}") String tokenUri, + Optional staticClientApiKeysProperties, + WebClient.Builder webClientBuilder, // Prototype-scoped - Safe to mutate. + JsonMapper jsonMapper) { + this.evaluationUri = evaluationUri; + this.requestPropertyName = requestPropertyName; + this.jsonMapper = jsonMapper; + var authFilter = staticClientApiKeysProperties.map(properties -> (ExchangeFilterFunction) + new FixedBearerExchangeFilterFunction(properties::getToken)) + .orElseGet(() -> oauthFilter(clientId, clientSecret, scope, tokenUri)); + this.webClient = webClientBuilder + .baseUrl(baseUrl) + .filter(authFilter) + .build(); + } + + private static ServerOAuth2AuthorizedClientExchangeFilterFunction oauthFilter( + String clientId, String clientSecret, String scope, String tokenUri) { + var scopes = StringUtils.isBlank(scope) ? List.of() : + Arrays.stream(scope.split(",")).map(String::trim).toList(); + var clientRegistration = ClientRegistration.withRegistrationId(CLIENT_REGISTRATION_ID) + .authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS) + .clientId(clientId) + .clientSecret(clientSecret) + .scope(scopes) + .tokenUri(tokenUri) + .build(); + var clientRegistrationRepository = + new InMemoryReactiveClientRegistrationRepository(clientRegistration); + var authorizedClientService = + new InMemoryReactiveOAuth2AuthorizedClientService(clientRegistrationRepository); + var authorizedClientManager = + new AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager( + clientRegistrationRepository, authorizedClientService); + var filter = + new ServerOAuth2AuthorizedClientExchangeFilterFunction(authorizedClientManager); + filter.setDefaultClientRegistrationId(CLIENT_REGISTRATION_ID); + return filter; + } + + public ApiKeyValidationResult fetchApiKeyValidationResult(String apiKey) { + return webClient + .post() + .uri(evaluationUri) + .accept(MediaType.APPLICATION_JSON) + .bodyValue(ApiKeyValidationRequest.builder() + .jsonField(requestPropertyName, apiKey) + .build()) + .retrieve() + .onStatus(HttpStatusCode::is4xxClientError, response -> { + log.error("4xx error from ApiKeys Svc: {}", response.statusCode()); + return response.createException(); + }) + .onStatus(HttpStatusCode::is5xxServerError, response -> { + log.error("Error response code from ApiKeys Svc: {}", response.statusCode()); + return Mono.error(new UpstreamException("ApiKeys Service returned 5xx error")); + }) + .bodyToMono(ApiKeyValidationResponse.class) + .retryWhen(RETRY_SPEC) + .switchIfEmpty(Mono.error(() -> new UpstreamException("No response from ApiKeys Svc"))) + .map(apiKeysResponse -> jsonMapper.convertValue(apiKeysResponse.getResult(), + ApiKeyValidationResult.class)) + .filter(ApiKeyValidationResult::valid) + .switchIfEmpty(Mono.error(() -> new ForbiddenException("Authorization failed"))) + .block(); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/apikeys/ApiKeysService.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/apikeys/ApiKeysService.java new file mode 100644 index 000000000..91eed1af6 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/apikeys/ApiKeysService.java @@ -0,0 +1,121 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.apikeys; + +import static com.nvidia.nvct.service.apikeys.ApiKeyValidationResult.POLICY_RESULT_ATTRIBUTE; + +import com.github.benmanes.caffeine.cache.Cache; +import com.github.benmanes.caffeine.cache.Caffeine; +import com.github.benmanes.caffeine.cache.LoadingCache; +import com.github.benmanes.caffeine.cache.Scheduler; +import com.google.common.annotations.VisibleForTesting; +import com.nvidia.boot.exceptions.UpstreamException; +import com.nvidia.nvct.service.apikeys.ApiKeyValidationResult.ApiKeyTaskAccess; +import java.time.Duration; +import java.util.Optional; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.security.core.Authentication; +import org.springframework.security.oauth2.core.OAuth2AuthenticatedPrincipal; +import org.springframework.stereotype.Service; +import org.springframework.web.reactive.function.client.WebClientRequestException; + +@Slf4j +@Service +@RequiredArgsConstructor +public class ApiKeysService { + private static final String MESG_POLICY_RESULT_FROM_BACKUP_CACHE = + "Returning ApiKeyValidationResult from backup cache as ApiKeys is not reachable - '{}'"; + private static final String MESG_POLICY_RESULT_NOT_IN_BACKUP_CACHE = + "ApiKeys is not reachable and ApiKeyValidationResult is not in backup cache - '{}'"; + private static final String MESG_API_KEY_VALIDATION_RESULT = + "Api Key Validation Result: '{}'"; + + private final ApiKeysClient apiKeysClient; + private final LoadingCache apiKeysCache = Caffeine.newBuilder() + .maximumSize(512).expireAfterWrite(Duration.ofMinutes(1)) + .scheduler(Scheduler.systemScheduler()) + .build(this::fetchApiKeyValidationResult); + private final Cache apiKeysBackupCache = Caffeine.newBuilder() + .maximumSize(512).expireAfterWrite(Duration.ofMinutes(60)) + .scheduler(Scheduler.systemScheduler()) + .build(); + + private ApiKeyValidationResult fetchApiKeyValidationResult(String apiKey) { + try { + var result = apiKeysClient.fetchApiKeyValidationResult(apiKey); + log.debug(MESG_API_KEY_VALIDATION_RESULT, result); + apiKeysBackupCache.put(apiKey, result); + return result; + } catch (WebClientRequestException | UpstreamException ex) { + // WebClientRequestException is thrown when external service(such as Api Keys) is not + // reachable. NVCT should use the backup cache only when Api Keys is not reachable. For + // other exceptions, backup cache should not be used. + return fetchApiKeyValidationResultFromBackupCache(apiKey, ex); + } + } + + public ApiKeyValidationResult resolveNCAIdFromApiKey(String apiKey) { + return apiKeysCache.get(apiKey); + } + + @VisibleForTesting + public void invalidateCache() { + apiKeysCache.invalidateAll(); + apiKeysBackupCache.invalidateAll(); + } + + @VisibleForTesting + public void invalidatePrimaryCache() { + apiKeysCache.invalidateAll(); + } + + public static Optional isApiKeyAuth(Authentication authentication) { + if (!(authentication.getPrincipal() instanceof OAuth2AuthenticatedPrincipal principal)) { + return Optional.empty(); + } + if (principal.getAttribute( + ApiKeyValidationResult.TASK_ACCESS_ATTRIBUTE) instanceof ApiKeyTaskAccess access) { + return Optional.of(access); + } + return Optional.empty(); + } + + public Optional getApiKeyValidationResult( + Authentication authentication) { + if (!(authentication.getPrincipal() instanceof OAuth2AuthenticatedPrincipal principal)) { + return Optional.empty(); + } + if (principal.getAttribute( + POLICY_RESULT_ATTRIBUTE) instanceof ApiKeyValidationResult policyResult) { + return Optional.of(policyResult); + } + return Optional.empty(); + } + + private ApiKeyValidationResult fetchApiKeyValidationResultFromBackupCache( + String apiKey, + RuntimeException ex) { + var policyResult = apiKeysBackupCache.getIfPresent(apiKey); + if (policyResult == null) { + log.error(MESG_POLICY_RESULT_NOT_IN_BACKUP_CACHE, ex.getMessage()); + throw ex; + } + log.info(MESG_POLICY_RESULT_FROM_BACKUP_CACHE, ex.getMessage()); + return policyResult; + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/apikeys/dto/ApiKeyValidationRequest.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/apikeys/dto/ApiKeyValidationRequest.java new file mode 100644 index 000000000..5b325aff9 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/apikeys/dto/ApiKeyValidationRequest.java @@ -0,0 +1,36 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.apikeys.dto; + +import java.util.Map; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Singular; +import lombok.Value; +import lombok.extern.jackson.Jacksonized; + +@Value +@AllArgsConstructor(access = AccessLevel.PRIVATE) +@Jacksonized +@Builder +public class ApiKeyValidationRequest { + + @Singular("jsonField") + Map input; + +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/apikeys/dto/ApiKeyValidationResponse.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/apikeys/dto/ApiKeyValidationResponse.java new file mode 100644 index 000000000..e26833436 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/apikeys/dto/ApiKeyValidationResponse.java @@ -0,0 +1,36 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.apikeys.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class ApiKeyValidationResponse { + + private String namespace; + + @JsonProperty("rule_name") + private String ruleName; + + private Object result; + +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/client/ClientService.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/client/ClientService.java new file mode 100644 index 000000000..c45f615c0 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/client/ClientService.java @@ -0,0 +1,49 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.client; + +import com.google.common.annotations.VisibleForTesting; +import com.nvidia.nvct.service.client.dto.ClientDto; +import com.nvidia.nvct.service.nvcf.NvcfClient; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; + +@Slf4j +@Service +@RequiredArgsConstructor +public class ClientService { + private static final String MESG_BLANK_PARAMETER = "'%s' cannot be blank"; + + private final NvcfClient nvcfClient; + + public ClientDto getClient(String clientId) { + if (StringUtils.isBlank(clientId)) { + var mesg = MESG_BLANK_PARAMETER.formatted("clientId"); + log.error(mesg); + throw new IllegalArgumentException(mesg); + } + + return nvcfClient.getClient(clientId); + } + + @VisibleForTesting + public void invalidateCache() { + nvcfClient.invalidateCache(); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/client/dto/ClientDto.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/client/dto/ClientDto.java new file mode 100644 index 000000000..fd6135643 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/client/dto/ClientDto.java @@ -0,0 +1,35 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.client.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.annotation.Nullable; +import jakarta.validation.constraints.NotNull; +import lombok.Builder; + +@Builder +@Schema(description = "Data Transfer Object(DTO) representing a client") +public record ClientDto( + @Schema(description = "Client Id") + @Nullable String clientId, + + @Schema(description = "Associated NVIDIA Cloud Account id") + @NotNull String ncaId, + + @Schema(description = "Name of the associated NVIDIA Cloud Account") + @NotNull String name) { +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/ess/EssClient.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/ess/EssClient.java new file mode 100644 index 000000000..5c19472f7 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/ess/EssClient.java @@ -0,0 +1,212 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.ess; + +import static com.nvidia.nvct.util.NvctConstants.ESS_NAMESPACE; + +import tools.jackson.databind.JsonNode; +import com.nvidia.boot.exceptions.BadRequestException; +import com.nvidia.boot.exceptions.NotFoundException; +import com.nvidia.boot.exceptions.UpstreamException; +import com.nvidia.nvct.configuration.staticclientauth.FixedBearerExchangeFilterFunction; +import com.nvidia.nvct.configuration.staticclientauth.StaticClientAuthConfiguration.StaticClientEssProperties; +import com.nvidia.nvct.rest.task.dto.SecretDto; +import com.nvidia.nvct.service.ess.EssStubService.SaveSecretsRequest; +import com.nvidia.nvct.util.NvctOAuth2ClientUtils; +import com.nvidia.nvct.util.NvctOAuth2ClientUtils.ManagedHttpResources; +import jakarta.annotation.Nonnull; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.UUID; +import java.util.stream.Collectors; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.cloud.context.config.annotation.RefreshScope; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; +import org.springframework.web.reactive.function.client.ExchangeFilterFunction; +import org.springframework.web.reactive.function.client.WebClient; +import org.springframework.web.reactive.function.client.support.WebClientAdapter; +import org.springframework.web.service.invoker.HttpServiceProxyFactory; + +@Slf4j +@Service +@RefreshScope +public class EssClient { + + private static final String MESG_NO_SECRETS_TO_SAVE = + "Task '%s': No user secrets specified to save"; + private static final String MESG_MISSING_RESPONSE_BODY = + "Task '%s': ESS '%s' - Response body cannot be null"; + private static final String MESG_MISSING_FETCH_SECRETS_RESPONSE_BODY = + "Secret Path '%s': ESS '%s' - Response body cannot be null"; + private static final String MESG_ESS_DISABLED = "ESS interaction is disabled"; + + public static final String CLIENT_REGISTRATION_ID = "ess"; + private final EssStubService essStubService; + private final boolean enabled; + + // We could have used OAuth2AuthorizedClientManager and relied on Spring Security to + // pick up the configuration properties using ClientRegistrationRepository directly. However, + // the client-secret value held in the ClientRegistrationRepository does not get refreshed when + // client-secret is rotated. Addressing these issues requires introducing a refreshable + // ClientRegistrationRepository that wasn't clean. Instead, we will keep it simple and use + // the tried and tested approach of using @Value and @RefreshScope annotations and wire + // things up ourselves. + public EssClient( + WebClient.Builder webClientBuilder, // Prototype-scoped - Safe to mutate. + ManagedHttpResources essHttpResources, + @Value("${nvct.ess.base-url}") String baseUrl, + @Value("${nvct.ess.enabled:true}") boolean enabled, + @Value("${spring.security.oauth2.client.registration.ess.client-id}") String clientId, + @Value("${spring.security.oauth2.client.registration.ess.client-secret}") String clientSecret, + @Value("${spring.security.oauth2.client.registration.ess.scope}") String scope, + @Value("${spring.security.oauth2.client.provider.ess.token-uri}") String tokenUri, + Optional staticClientEssProperties) { + var authFilter = oauthFilter(staticClientEssProperties, webClientBuilder, + clientId, clientSecret, scope, tokenUri); + var webClient = webClientBuilder + .baseUrl(baseUrl) + .clientConnector(essHttpResources.connector()) + .filter(NvctOAuth2ClientUtils.getRetryableFilter(CLIENT_REGISTRATION_ID)) + .filter(authFilter) + .filter(NvctOAuth2ClientUtils.getResponseFilterProcessor("ESS")) + .build(); + var adapter = WebClientAdapter.create(webClient); + var factory = HttpServiceProxyFactory.builderFor(adapter).build(); + this.essStubService = factory.createClient(EssStubService.class); + this.enabled = enabled; + } + + private static ExchangeFilterFunction oauthFilter( + Optional staticClientEssProperties, + WebClient.Builder webClientBuilder, + String clientId, + String clientSecret, + String scope, + String tokenUri) { + return staticClientEssProperties + .map(p -> (ExchangeFilterFunction) + new FixedBearerExchangeFilterFunction(p::getToken)) + .orElseGet(() -> NvctOAuth2ClientUtils + .getOAuth2ExchangeFilter(webClientBuilder, CLIENT_REGISTRATION_ID, + tokenUri, clientId, clientSecret, scope)); + } + + @Nonnull + public UUID saveSecrets(UUID taskId, Set secrets) { + if (!enabled) { + log.debug(MESG_ESS_DISABLED); + return UUID.randomUUID(); + } + + if (CollectionUtils.isEmpty(secrets)) { + // Shouldn't have reached here if there are no secrets in the request payload. + var mesg = MESG_NO_SECRETS_TO_SAVE.formatted(taskId); + log.error(mesg); + throw new BadRequestException(mesg); + } + + var data = secrets.stream().collect(Collectors.toMap(SecretDto::name, SecretDto::value)); + var response = essStubService.saveSecrets(taskId.toString(), ESS_NAMESPACE, + new SaveSecretsRequest(data)); + return Optional.ofNullable(response) + .map(body -> body.getData().getVersion()) + .orElseThrow(() -> { + var mesg = MESG_MISSING_RESPONSE_BODY + .formatted(taskId, "Save Secrets"); + log.error(mesg); + return new UpstreamException(mesg); + }); + } + + public Optional> getSecretNames(UUID taskId) { + if (!enabled) { + log.debug(MESG_ESS_DISABLED); + return Optional.empty(); + } + + return fetchSecrets(taskId).map(Map::keySet); + } + + public void deleteSecrets(UUID taskId) { + if (!enabled) { + log.debug(MESG_ESS_DISABLED); + return; + } + + essStubService.deleteSecrets(taskId.toString(), ESS_NAMESPACE); + } + + public Optional> fetchSecrets(UUID taskId) { + if (!enabled) { + log.debug(MESG_ESS_DISABLED); + return Optional.empty(); + } + + try { + var response = essStubService.fetchSecrets(taskId.toString(), + "fetch_secret", + ESS_NAMESPACE); + return Optional.ofNullable(response) + .map(body -> Optional.ofNullable(body.getData().getData())) + .orElseThrow(() -> { + var mesg = MESG_MISSING_RESPONSE_BODY + .formatted(taskId, "Fetch Secrets"); + log.error(mesg); + return new UpstreamException(mesg); + }); + } catch (NotFoundException ex) { + return Optional.empty(); + } + } + + public void deleteSecretsPath(UUID taskId) { + if (!enabled) { + log.debug(MESG_ESS_DISABLED); + return; + } + essStubService.deleteSecretsPath(taskId.toString(), ESS_NAMESPACE); + } + + public Optional> fetchTelemetrySecret(String ncaId, UUID telemetryId) { + if (!enabled) { + log.debug(MESG_ESS_DISABLED); + return Optional.empty(); + } + + try { + var response = essStubService.fetchTelemetrySecret(ncaId, + telemetryId.toString(), + "fetch_secret", + ESS_NAMESPACE); + return Optional.ofNullable(response) + .map(body -> Optional.ofNullable(body.getData().getData())) + .orElseThrow(() -> { + var path = "accounts/%s/telemetries/%s".formatted(ncaId, telemetryId); + var mesg = MESG_MISSING_FETCH_SECRETS_RESPONSE_BODY + .formatted(path, "Fetch Secrets"); + log.error(mesg); + return new UpstreamException(mesg); + }); + } catch (NotFoundException ex) { + return Optional.empty(); + } + } + +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/ess/EssService.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/ess/EssService.java new file mode 100644 index 000000000..f1946b57f --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/ess/EssService.java @@ -0,0 +1,69 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.ess; + +import com.nvidia.nvct.rest.task.dto.SecretDto; +import java.util.Optional; +import java.util.Set; +import java.util.UUID; +import java.util.stream.Collectors; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +@Slf4j +public class EssService { + + private final EssClient essClient; + + public UUID saveSecrets(UUID taskId, Set secrets) { + return essClient.saveSecrets(taskId, secrets); + } + + public Optional> getSecretNames(UUID taskId) { + return essClient.getSecretNames(taskId); + } + + public Optional> getSecrets(UUID taskId) { + var secretDtos = essClient.fetchSecrets(taskId) + .map(secrets -> secrets.entrySet() + .stream() + .map(entry -> SecretDto.builder() + .name(entry.getKey()) + .value(entry.getValue()) + .build()) + .collect(Collectors.toSet())) + .orElse(null); + return Optional.ofNullable(secretDtos); + } + + public void deleteSecrets(UUID taskId) { + essClient.deleteSecrets(taskId); + } + + public void deleteSecretsPath(UUID taskId) { + essClient.deleteSecretsPath(taskId); + } + + public boolean telemetrySecretExist(String ncaId, UUID telemetryId) { + var existingSecrets = essClient.fetchTelemetrySecret(ncaId, telemetryId); + return existingSecrets.isPresent() && !existingSecrets.get().isEmpty(); + } + +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/ess/EssStubService.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/ess/EssStubService.java new file mode 100644 index 000000000..d901cbe4c --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/ess/EssStubService.java @@ -0,0 +1,105 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.ess; + +import com.fasterxml.jackson.annotation.JsonProperty; +import tools.jackson.databind.JsonNode; +import com.google.common.annotations.VisibleForTesting; +import java.time.Instant; +import java.util.Map; +import java.util.UUID; +import lombok.Builder; +import lombok.NonNull; +import lombok.Value; +import lombok.extern.jackson.Jacksonized; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.service.annotation.DeleteExchange; +import org.springframework.web.service.annotation.GetExchange; +import org.springframework.web.service.annotation.PutExchange; + +public interface EssStubService { + + @PutExchange("v1/tasks/{taskId}/secrets") + SaveSecretsResponse saveSecrets(@PathVariable String taskId, + @RequestHeader("X-ESS-NAMESPACE") String namespace, + @RequestBody SaveSecretsRequest payload); + + @GetExchange("v1/tasks/{taskId}/secrets") + FetchSecretsResponse fetchSecrets(@PathVariable String taskId, + @RequestParam("query_type") String queryType, + @RequestHeader("X-ESS-NAMESPACE") String namespace); + + @GetExchange("v1/accounts/{ncaId}/telemetries/{telemetryId}") + FetchSecretsResponse fetchTelemetrySecret(@PathVariable String ncaId, + @PathVariable String telemetryId, + @RequestParam("query_type") String queryType, + @RequestHeader("X-ESS-NAMESPACE") String namespace); + + @DeleteExchange("v1/tasks/{taskId}/secrets") + void deleteSecrets(@PathVariable String taskId, + @RequestHeader("X-ESS-NAMESPACE") String namespace); + + @DeleteExchange("v1/tasks/{taskId}") + void deleteSecretsPath(@PathVariable String taskId, + @RequestHeader("X-ESS-NAMESPACE") String namespace); + + + @Value + @Jacksonized + @Builder + class SaveSecretsRequest { + @NonNull + Map data; + } + + @Value + @Jacksonized + @Builder + class SaveSecretsResponse { + @NonNull + SaveSecretsData data; + + @Value + @Jacksonized + @Builder + public static class SaveSecretsData { + @JsonProperty("created_time") + Instant createdTime; + UUID version; + } + } + + @Value + @Jacksonized + @Builder + @VisibleForTesting + class FetchSecretsResponse { + @NonNull + FetchSecretData data; + + @Value + @Jacksonized + @Builder + public static class FetchSecretData { + @NonNull + Map data; // Object will be a Map when response is deserialized + } + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/event/EventService.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/event/EventService.java new file mode 100644 index 000000000..08eaa4e99 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/event/EventService.java @@ -0,0 +1,215 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.event; + +import static com.datastax.oss.driver.api.core.data.ByteUtils.fromHexString; +import static com.datastax.oss.driver.api.core.data.ByteUtils.toHexString; +import static com.nvidia.nvct.util.NvctConstants.DEFAULT_PAGINATION_LIMIT; +import static com.nvidia.nvct.util.NvctConstants.MESG_INVALID_CURSOR; +import static com.nvidia.nvct.util.NvctConstants.TERMINAL_TASK_STATUSES; + +import com.google.common.annotations.VisibleForTesting; +import com.nvidia.boot.exceptions.BadRequestException; +import com.nvidia.boot.exceptions.ForbiddenException; +import com.nvidia.nvct.persistence.event.EventsByTaskRepository; +import com.nvidia.nvct.persistence.event.entity.EventByTaskEntity; +import com.nvidia.nvct.persistence.event.entity.EventByTaskKey; +import com.nvidia.nvct.persistence.task.entity.TaskEntity; +import com.nvidia.nvct.persistence.task.entity.TaskStatus; +import com.nvidia.nvct.rest.event.dto.EventDto; +import com.nvidia.nvct.service.task.TaskService; +import java.time.Instant; +import java.util.Comparator; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.UUID; +import java.util.function.Predicate; +import java.util.regex.Pattern; +import lombok.Builder; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.data.cassandra.core.query.CassandraPageRequest; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Slice; +import org.springframework.stereotype.Service; + +@Slf4j +@Service +@RequiredArgsConstructor +public class EventService { + public static final String STATUS_CHANGE_EVENT_MESSAGE = + "Changing status from '%s' to '%s'"; + public static final String STATUS_CHANGE_EVENT_MESSAGE_WITH_ERROR = + "Changing status from '%s' to '%s' with error '%s'"; + + // Pattern to match status change event messages such as above. + private static final Pattern STATUS_CHANGE_PATTERN = + Pattern.compile("Changing status from '[^']*' to '([^']+)'"); + + private static final String MESG_CANNOT_BE_NULL = "Parameter '%s' cannot be null"; + private static final String MESG_BLANK_PARAMETER = "'%s' cannot be blank"; + + private static final String MESG_TASK_EVENT_OPERATION = + "Task id '{}': {}"; + private static final String MESG_FAILED_TO_PARSE_EVENT_MESSAGE = + "Task id '{}': Could not parse status '{}' from event message: {}"; + private static final String MESG_ERROR_RETRIEVING_TERMINAL_STATUS_FROM_EVENT = + "Task id '{}': Error retrieving terminal status from events: {}"; + private static final String MESG_FORBIDDEN_TO_LIST_EVENTS = + "Task '%s': Forbidden to list events"; + + private final EventsByTaskRepository eventsByTaskRepository; + private final TaskService taskService; + + @Builder + public record EventsSliceContext(List events, String cursor, Integer limit) { } + + public EventsSliceContext fetchEvents(String ncaId, UUID taskId, int limit, String cursor, + Predicate taskAccessMatch) { + var taskEntity = taskService.validateAccount(ncaId, taskId); + if (!taskAccessMatch.test(taskEntity)) { + var mesg = MESG_FORBIDDEN_TO_LIST_EVENTS.formatted(taskId); + log.error(mesg); + throw new ForbiddenException(mesg); + } + + Slice pagedResult; + try { + var byteBuffer = cursor == null ? null : fromHexString(cursor); + var pageable = PageRequest.of(0, limit); + var pageRequest = CassandraPageRequest.of(pageable, byteBuffer); + pagedResult = eventsByTaskRepository.findByKeyTaskId(taskId, pageRequest); + } catch (Exception e) { + var mesg = MESG_INVALID_CURSOR.formatted(cursor); + log.error(mesg); + throw new BadRequestException(mesg, e); + } + var dtos = pagedResult.getContent().stream() + .map(EventService::toEventDto) + .toList(); + var builder = EventsSliceContext.builder().events(dtos); + if (pagedResult.hasNext()) { + var pagingState = ((CassandraPageRequest) pagedResult.getPageable()).getPagingState(); + builder.cursor(toHexString(pagingState)); + builder.limit(limit); + } + log.debug(MESG_TASK_EVENT_OPERATION, taskId, "Fetched events"); + return builder.build(); + } + + @VisibleForTesting + public List fetchEvents(String ncaId, UUID taskId) { + var events = fetchEvents(ncaId, taskId, Integer.parseInt(DEFAULT_PAGINATION_LIMIT), null, + taskEntity -> true); + return events.events(); + } + + public boolean deleteEvents(String ncaId, UUID taskId) { + Objects.requireNonNull(taskId, () -> MESG_CANNOT_BE_NULL.formatted("taskId")); + if (StringUtils.isBlank(ncaId)) { + var mesg = MESG_BLANK_PARAMETER.formatted("ncaId"); + log.error(mesg); + throw new IllegalArgumentException(mesg); + } + + // If the Task was deleted but for some reason events were not deleted, then don't + // throw an exception and continue deleting events. + taskService.lookupTask(taskId).ifPresent(task -> taskService.validateAccount(ncaId, task)); + eventsByTaskRepository.deleteByKeyTaskId(taskId); + log.info(MESG_TASK_EVENT_OPERATION, taskId, "Deleted task events"); + return true; + } + + public EventByTaskEntity insertEvent(String ncaId, UUID taskId, String message) { + taskService.validateAccount(ncaId, taskId); + if (StringUtils.isBlank(message)) { + var mesg = MESG_BLANK_PARAMETER.formatted("message"); + log.error(mesg); + throw new IllegalArgumentException(mesg); + } + + var eventEntity = EventByTaskEntity.builder() + .key(EventByTaskKey.builder().taskId(taskId).eventId(UUID.randomUUID()).build()) + .createdAt(Instant.now()) + .ncaId(ncaId) + .message(message) + .build(); + eventEntity = eventsByTaskRepository.save(eventEntity); + log.info(MESG_TASK_EVENT_OPERATION, taskId, "Inserted event"); + return eventEntity; + } + + // Used by cleanup subroutine that executes periodically. There is no validation performed + // to match the NCA Id as there could be scenario where the Task entry is deleted but the + // events were not deleted. If the validation kicks in, then it will result in + // NotFoundException and we end up with partially cleaned Task. + public void cleanEvents(UUID taskId) { + Objects.requireNonNull(taskId, () -> MESG_CANNOT_BE_NULL.formatted("taskId")); + eventsByTaskRepository.deleteByKeyTaskId(taskId); + } + + // Retrieves task events and checks if the latest event contains a terminal status transition. + // Returns the terminal status if found, otherwise returns empty. + public Optional getTerminalStatusFromLatestEvent(UUID taskId) { + try { + // Fetch all events for this task and get the latest one by creation time. + var latestEventOpt = eventsByTaskRepository + .findByKeyTaskId(taskId) + .max(Comparator.comparing(EventByTaskEntity::getCreatedAt)); + + return latestEventOpt.flatMap(EventService::parseEventMessage); + } catch (Exception e) { + log.error(MESG_ERROR_RETRIEVING_TERMINAL_STATUS_FROM_EVENT, taskId, e.getMessage(), e); + return Optional.empty(); + } + } + + // ### TODO: Parse the event message to extract the target status. This is temporary. + // We should enhance the events_by_task table to have a separate field for the + // new/target status. + private static Optional parseEventMessage(EventByTaskEntity taskEvent) { + var message = taskEvent.getMessage(); + var taskId = taskEvent.getKey().getTaskId(); + + var matcher = STATUS_CHANGE_PATTERN.matcher(message); + if (matcher.find()) { + var rawStatus = matcher.group(1); + try { + var status = TaskStatus.fromText(rawStatus); + if (TERMINAL_TASK_STATUSES.contains(status)) { // Check if terminal status + return Optional.of(status); + } + } catch (IllegalStateException e) { + log.warn(MESG_FAILED_TO_PARSE_EVENT_MESSAGE, taskId, rawStatus, e.getMessage()); + } + } + + return Optional.empty(); + } + + private static EventDto toEventDto(EventByTaskEntity entity) { + return EventDto.builder() + .eventId(entity.getKey().getEventId()) + .taskId(entity.getKey().getTaskId()) + .ncaId(entity.getNcaId()) + .message(entity.getMessage()) + .createdAt(entity.getCreatedAt()) + .build(); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/icms/IcmsClient.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/icms/IcmsClient.java new file mode 100644 index 000000000..e259704ad --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/icms/IcmsClient.java @@ -0,0 +1,530 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.icms; + +import static com.nvidia.nvct.util.NvctConstants.DEFAULT_CONTAINER_ENV; +import static com.nvidia.nvct.util.NvctConstants.MAX_BUFFER_LIMIT; +import static org.apache.commons.lang3.StringUtils.EMPTY; +import static org.apache.commons.lang3.StringUtils.isBlank; +import static org.apache.commons.lang3.StringUtils.isNotBlank; + +import com.github.benmanes.caffeine.cache.Caffeine; +import com.github.benmanes.caffeine.cache.LoadingCache; +import com.github.benmanes.caffeine.cache.Scheduler; +import com.google.common.collect.Lists; +import com.nvidia.boot.exceptions.NotFoundException; +import com.nvidia.boot.exceptions.UpstreamException; +import com.nvidia.nvct.configuration.staticclientauth.FixedBearerExchangeFilterFunction; +import com.nvidia.nvct.configuration.staticclientauth.StaticClientAuthConfiguration.StaticClientIcmsProperties; +import com.nvidia.nvct.persistence.task.entity.GpuSpecUdt; +import com.nvidia.nvct.persistence.task.entity.TaskEntity; +import com.nvidia.nvct.rest.task.dto.InstanceUsageTypeEnum; +import com.nvidia.nvct.service.account.AccountService; +import com.nvidia.nvct.service.icms.IcmsStubService.DescribeInstancesResponse; +import com.nvidia.nvct.service.icms.IcmsStubService.DescribeInstancesResponse.Instance; +import com.nvidia.nvct.service.icms.IcmsStubService.GetInstancesResponse.InstanceRequest; +import com.nvidia.nvct.service.registry.RegistryArtifactValidationService; +import com.nvidia.nvct.service.registry.RegistryCredentialService; +import com.nvidia.nvct.service.telemetry.TelemetryService; +import com.nvidia.nvct.service.token.TokenService; +import com.nvidia.nvct.util.NvctOAuth2ClientUtils; +import com.nvidia.nvct.util.NvctOAuth2ClientUtils.ManagedHttpResources; +import jakarta.validation.constraints.NotNull; +import java.net.URI; +import java.nio.charset.StandardCharsets; +import java.time.Duration; +import java.util.Base64; +import java.util.Collection; +import java.util.Comparator; +import java.util.List; +import java.util.Optional; +import java.util.Set; +import java.util.UUID; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import lombok.NonNull; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.cloud.context.config.annotation.RefreshScope; +import org.springframework.cloud.context.scope.refresh.RefreshScopeRefreshedEvent; +import org.springframework.context.event.EventListener; +import org.springframework.data.util.Pair; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; +import org.springframework.web.reactive.function.client.ExchangeFilterFunction; +import org.springframework.web.reactive.function.client.WebClient; +import org.springframework.web.reactive.function.client.support.WebClientAdapter; +import org.springframework.web.service.invoker.HttpServiceProxyFactory; + +@Slf4j +@Service +@RefreshScope +public class IcmsClient { + + private static final String MESG_NO_REQUEST_ID_FROM_ICMS = + "Task id '%s': No request-id returned from ICMS"; + private static final String MESG_INSTANCE_TYPE_NOT_AVAILABLE = + "Task id '%s': Instance-type not available for Backend '%s' GPU '%s'"; + private static final String MESG_MISSING_DELETABLE_INSTANCES = + "Task id '{}': No deletable instances"; + private static final String MESG_MISSING_IDS_OF_EXTRA_INSTANCES = + "Task id '{}': No instance ids to delete from full list '{}'"; + private static final String MESG_DELETING_EXTRA_INSTANCES = + "Task id '{}': Deleting extra instances '{}' from full list '{}'"; + private static final String MESG_DELETED_EXTRA_INSTANCES = + "Task id '{}': Deleted extra instances '{}' from full list '{}'"; + private static final String MESG_INVALID_CACHE_HANDLE = + "Task id '%s': Empty cache handle."; + private static final String MSEG_INSTANCE_NOT_FOUND = "Instance id '%s' not found"; + private static final String MESG_ERROR_RESPONSE_STATUS = + "Upstream ICMS responded with status code '%d' - %s"; + private static final String MESG_FETCH_CLUSTERS = + "Account '{}': Fetching Clusters from ICMS for instance type '{}'"; + private static final String MESG_REMOTE_CONFIG_REFRESH = + "Remote config refresh observed: nvct.sidecars.init-container = {}"; + private static final String MESG_NO_ICMS_WORKLOAD = + "Account '{}': No ICMS workload found for taskId '{}', treating terminate as idempotent"; + + private static final int BATCH_SIZE = 32; + public static final String CLIENT_REGISTRATION_ID = "icms"; + + private final IcmsStubService icmsStubService; + private final String selfFqdn; + private final String globalFqdnGrpc; + private final URI tracingUrl; + private final AccountService accountService; + private final String tracingAccessToken; + private final String initContainer; + private final String otelContainer; + private final String utilsContainer; + private final String essAgentContainer; + private final String essFqdn; + private final String otelCollectorContainer; + private final TokenService tokenService; + private final TelemetryService telemetryService; + private final RegistryArtifactValidationService registryArtifactValidationService; + private final RegistryCredentialService registryCredentialService; + private final LoadingCache> clustersCache; + + private record IcmsCacheKey(String ncaId, InstanceUsageTypeEnum instanceTypeUsage) { + } + + // We could have used OAuth2AuthorizedClientManager and relied on Spring Security to + // pick up the configuration properties using ClientRegistrationRepository directly. However, + // the client-secret value held in the ClientRegistrationRepository does not get refreshed when + // client-secret is rotated. Addressing these issues requires introducing a refreshable + // ClientRegistrationRepository that wasn't clean. Instead, we will keep it simple and use + // the tried and tested approach of using @Value and @RefreshScope annotations and wire + // things up ourselves. + public IcmsClient( + @Value("${nvct.icms.base-url}") String baseUrl, + @Value("${nvct.sidecars.tracing-key}") String tracingAccessToken, + @Value("${nvct.sidecars.init-container}") String initContainer, + @Value("${nvct.sidecars.otel-container}") String otelContainer, + @Value("${nvct.sidecars.utils-container}") String utilsContainer, + @Value("${nvct.sidecars.ess-agent-container}") String essAgentContainer, + @Value("${nvct.ess.base-url}") String essFqdn, + @Value("${nvct.sidecars.otel-collector-container}") String otelCollectorContainer, + @Value("${nvct.fqdn}") String selfFqdn, + @Value("${nvct.global-fqdn-grpc}") String globalFqdnGrpc, + @Value("${spring.security.oauth2.client.registration.icms.client-id}") String clientId, + @Value("${spring.security.oauth2.client.registration.icms.client-secret}") + String clientSecret, + @Value("${spring.security.oauth2.client.registration.icms.scope}") String scope, + @Value("${spring.security.oauth2.client.provider.icms.token-uri}") String tokenUri, + @Value("${management.opentelemetry.tracing.export.otlp.endpoint}") String otlpTracingEndpoint, + AccountService accountService, + TokenService tokenService, + TelemetryService telemetryService, + RegistryArtifactValidationService registryArtifactValidationService, + RegistryCredentialService registryCredentialService, + Optional staticClientIcmsProperties, + WebClient.Builder webClientBuilder, // Prototype-scoped - Safe to mutate. + ManagedHttpResources icmsHttpResources) { + this.tracingAccessToken = tracingAccessToken; + this.initContainer = initContainer; + this.otelContainer = otelContainer; + this.utilsContainer = utilsContainer; + this.essAgentContainer = essAgentContainer; + this.essFqdn = essFqdn; + this.otelCollectorContainer = otelCollectorContainer; + this.selfFqdn = selfFqdn; + this.globalFqdnGrpc = globalFqdnGrpc; + this.accountService = accountService; + this.tokenService = tokenService; + this.telemetryService = telemetryService; + this.registryArtifactValidationService = registryArtifactValidationService; + this.registryCredentialService = registryCredentialService; + + var authFilter = oauthFilter(staticClientIcmsProperties, webClientBuilder, + clientId, clientSecret, scope, tokenUri); + var webClient = webClientBuilder + .baseUrl(baseUrl) + .codecs(configurer -> configurer.defaultCodecs().maxInMemorySize(MAX_BUFFER_LIMIT)) + .clientConnector(icmsHttpResources.connector()) + .filter(NvctOAuth2ClientUtils.getRetryableFilter(CLIENT_REGISTRATION_ID)) + .filter(authFilter) + .filter(NvctOAuth2ClientUtils.getResponseFilterProcessor("ICMS")) + .build(); + var adapter = WebClientAdapter.create(webClient); + var factory = HttpServiceProxyFactory.builderFor(adapter).build(); + this.icmsStubService = factory.createClient(IcmsStubService.class); + this.tracingUrl = URI.create(otlpTracingEndpoint); + this.clustersCache = Caffeine.newBuilder() + .maximumSize(64) + .expireAfterWrite(Duration.ofMinutes(15)) + .scheduler(Scheduler.systemScheduler()) + .build(this::fetchClusters); + } + + // Temporary verification hook for NVCF-10266 remote-config rollout (v2). + // Remove after sign-off — the actuator env source check is the durable contract. + @EventListener(RefreshScopeRefreshedEvent.class) + public void logRemoteConfigRefresh() { + log.info(MESG_REMOTE_CONFIG_REFRESH, initContainer); + } + + private static ExchangeFilterFunction oauthFilter( + Optional staticClientIcmsProperties, + WebClient.Builder webClientBuilder, + String clientId, + String clientSecret, + String scope, + String tokenUri) { + return staticClientIcmsProperties + .map(p -> (ExchangeFilterFunction) + new FixedBearerExchangeFilterFunction(p::getToken)) + .orElseGet(() -> NvctOAuth2ClientUtils + .getOAuth2ExchangeFilter(webClientBuilder, CLIENT_REGISTRATION_ID, + tokenUri, clientId, clientSecret, scope)); + } + + /** + * @param task the task that the instance being created will run + * @return list of ICMS request ids and count of instances associated with that request + */ + public UUID createInstance( + TaskEntity task, + GpuSpecUdt gpuSpec, + String artifactCacheHandle, + @NotNull Long artifactSize) { + if (StringUtils.isBlank(artifactCacheHandle)) { + var mesg = MESG_INVALID_CACHE_HANDLE.formatted(task.getTaskId()); + log.error(mesg); + throw new IllegalArgumentException(mesg); + } + var telemetries = base64EncodeTelemetryDetails(task); + var env = getEnvironment(task); + var policy = getHelmValidationPolicy(task); + return scheduleSingleInstanceType(task, + env, + gpuSpec, + artifactCacheHandle, + artifactSize, + telemetries, + policy); + } + + public List getInstancesByTaskId( + String ncaId, + UUID deploymentId) { + try { + var response = icmsStubService.terminateInstancesByTaskId( + ncaId, deploymentId, false, true, false); + if (response == null || response.getInstances() == null) { + return List.of(); + } + return response.getInstances(); + } catch (NotFoundException ex) { + return List.of(); + } + } + + // Includes terminated instances and instances whose acknowledgement has expired. + public List getAllInstancesByTaskId( + String ncaId, + UUID deploymentId) { + try { + var response = icmsStubService.terminateInstancesByTaskId( + ncaId, deploymentId, true, true, true); + if (response == null || response.getInstances() == null) { + return List.of(); + } + return response.getInstances(); + } catch (NotFoundException ex) { + return List.of(); + } + } + + public List getClusters( + String ncaId, InstanceUsageTypeEnum usageType) { + return clustersCache.get(new IcmsCacheKey(ncaId, usageType)); + } + + public void deleteInstances(List instanceIds) { + Lists.partition(instanceIds, BATCH_SIZE) + .stream() + .forEach(this::deleteInstancesUnBatched); + } + + public void deleteExtraInstances( + TaskEntity task, int extraInstancesToDelete, + List deletableInstances) { + var taskId = task.getTaskId(); + + if (CollectionUtils.isEmpty(deletableInstances)) { + log.warn(MESG_MISSING_DELETABLE_INSTANCES, taskId); + return; + } + + var allDeletableInstanceIds = deletableInstances.stream() + .filter(instance -> instance.getInstanceId() != null) + .map(InstanceRequest::getInstanceId) + .toList(); + + // Target oldest instances for deletion. All the instances will be in either "running" + // or "starting" state. + var targetInstanceIds = deletableInstances.stream() + .filter(instance -> instance.getInstanceId() != null) + .sorted(Comparator.comparing(InstanceRequest::getCreateTime)) + .limit(extraInstancesToDelete) + .map(InstanceRequest::getInstanceId) + .toList(); + if (CollectionUtils.isEmpty(targetInstanceIds)) { + log.warn(MESG_MISSING_IDS_OF_EXTRA_INSTANCES, taskId, + allDeletableInstanceIds); + return; + } + log.info(MESG_DELETING_EXTRA_INSTANCES, taskId, targetInstanceIds, + allDeletableInstanceIds); + deleteInstances(targetInstanceIds); + log.info(MESG_DELETED_EXTRA_INSTANCES, taskId, targetInstanceIds, + allDeletableInstanceIds); + } + + public void terminateInstanceByTaskId(String ncaId, UUID taskId) { + try { + icmsStubService.terminateInstancesByTaskId(ncaId, taskId); + } catch (NotFoundException ex) { + log.info(MESG_NO_ICMS_WORKLOAD, ncaId, taskId); + } + } + + public Instance getInstanceById(String instanceId) { + var response = icmsStubService.describeInstances(Set.of(instanceId)); + return Optional.ofNullable(response) + .map(DescribeInstancesResponse::getInstances) + .stream() + .flatMap(Collection::stream) + .filter(instance -> instance.getInstanceId().equals(instanceId)) + .findFirst() + .orElseThrow( + () -> new NotFoundException(MSEG_INSTANCE_NOT_FOUND.formatted(instanceId))); + } + + private List fetchClusters(IcmsCacheKey cacheKey) { + log.info(MESG_FETCH_CLUSTERS, cacheKey.ncaId(), cacheKey.instanceTypeUsage()); + return icmsStubService.getClusters(cacheKey.ncaId(), cacheKey.instanceTypeUsage()); + } + + private UUID scheduleSingleInstanceType( + TaskEntity task, + String env, + GpuSpecUdt gpuSpec, + String cacheHandle, + @NonNull Long cacheSize, + String telemetries, + String helmValidationPolicy) { + var taskId = task.getTaskId(); + var taskName = task.getName(); + var backend = gpuSpec.getBackend(); + var clusters = gpuSpec.getClusters(); + var ncaId = task.getNcaId(); + var gpu = gpuSpec.getGpu(); + var instanceType = gpuSpec.getInstanceType(); + if (isBlank(instanceType)) { + var mesg = MESG_INSTANCE_TYPE_NOT_AVAILABLE.formatted(taskId, backend, gpu); + log.error(mesg); + throw new IllegalArgumentException(mesg); + } + + var ownerNcaId = task.getNcaId(); + var maxRuntimeDuration = getMaxRuntimeDuration(task); + var maxQueuedDuration = task.getMaxQueuedDuration().toString(); + var terminationGracePeriodDuration = + task.getTerminalGracePeriodDuration().toString(); + var resultHandlingStrategy = task.getResultHandlingStrategy().toString(); + var instanceCount = 1; + var configuration = isNotBlank(task.getHelmChart()) ? getConfiguration(gpuSpec) : null; + var response = icmsStubService.createInstance(backend, + clusters, + gpu, + instanceType, + ncaId, + accountService.getAccountName(ncaId), + instanceCount, + getTaskContainer(task), + getHelmChart(task), + configuration, + env, + null, + cacheSize != 0, + cacheHandle, + cacheSize != 0 ? cacheSize : null, + ownerNcaId, + taskId, + taskName, + maxRuntimeDuration, + maxQueuedDuration, + terminationGracePeriodDuration, + resultHandlingStrategy, + telemetries, + // taskId will play as deploymentId and + // gpuSpecId + taskId, + taskId, + helmValidationPolicy); + return Optional.of(response) + .map(IcmsStubService.CreateInstancesResponse::getRequestId) + .orElseThrow(() -> new UpstreamException(MESG_NO_REQUEST_ID_FROM_ICMS + .formatted(taskId))); + } + + private String getEnvironment(TaskEntity task) { + var taskId = task.getTaskId(); + var ncaId = task.getNcaId(); + var nvctWorkerToken = tokenService.issueWorkerAccessAssertion(ncaId, taskId); + var containerArgs = task.getContainerArgs(); + var args = isNotBlank(containerArgs) ? containerArgs : StringUtils.EMPTY; + var containerEnv = task.getContainerEnvironment(); + var cenv = isNotBlank(containerEnv) ? containerEnv : DEFAULT_CONTAINER_ENV; + var terminalGracePeriodDuration = task.getTerminalGracePeriodDuration(); + var taskSecretsPresent = task.hasSecrets(); + var secretsAssertionToken = tokenService.issueSecretsAssertion(task); + var sidecarRegistryCredentialEncoded = registryCredentialService + .getBase64EncodedSidecarRegistryImagePullSecret(task); + var containerRegistryCredentialsEncoded = + validateAndGetContainerRegistryImagePullSecrets(task); + var helmRegistryCredentialsEncoded = + validateAndGetHelmRegistryImagePullSecrets(task); + var env = Stream.of( + Pair.of("NCA_ID", task.getNcaId()), + Pair.of("ACCOUNT_NAME", accountService.getAccountName(ncaId)), + Pair.of("NVCT_WORKER_TOKEN", nvctWorkerToken), + Pair.of("NVCT_FQDN", selfFqdn), + Pair.of("NVCT_FQDN_GRPC", globalFqdnGrpc), + Pair.of("INIT_CONTAINER", initContainer), + Pair.of("OTEL_CONTAINER", otelContainer), + Pair.of("UTILS_CONTAINER", utilsContainer), + Pair.of("ESS_AGENT_CONTAINER", essAgentContainer), + Pair.of("ESS_FQDN", essFqdn), + Pair.of("OTEL_EXPORTER_OTLP_ENDPOINT", tracingUrl.toString()), + Pair.of("TASK_TAGS", getTaskTags(task)), + Pair.of("TASK_ID", task.getTaskId()), + Pair.of("TASK_NAME", task.getName()), + Pair.of("TASK_CONTAINER", getTaskContainer(task)), + Pair.of("TASK_CONTAINER_ARGS", args), + Pair.of("TASK_CONTAINER_ENV", cenv), + Pair.of("TERMINATION_GRACE_PERIOD", terminalGracePeriodDuration), + Pair.of("RESULTS_LOCATION", getResultsLocation(task)), + Pair.of("TRACING_ACCESS_TOKEN", tracingAccessToken), + Pair.of("BYOO_OTEL_COLLECTOR_CONTAINER", otelCollectorContainer), + Pair.of("TASK_SECRETS_PRESENT", taskSecretsPresent), + Pair.of("CONTAINER_REGISTRIES_CREDENTIALS", containerRegistryCredentialsEncoded), + Pair.of("HELM_REGISTRIES_CREDENTIALS", helmRegistryCredentialsEncoded), + Pair.of("SECRETS_ASSERTION_TOKEN", secretsAssertionToken), + Pair.of("SIDECAR_REGISTRY_CREDENTIAL", sidecarRegistryCredentialEncoded)) + .map(pair -> pair.getFirst() + "=" + pair.getSecond()) + .collect(Collectors.joining("\n")); + return Base64.getEncoder().encodeToString(env.getBytes(StandardCharsets.UTF_8)); + } + + + private static String getTaskTags(TaskEntity task) { + var tags = task.getTags(); + if (tags == null || tags.isEmpty()) { + return ""; + } + return String.join(",", tags); + } + + private String getTaskContainer(TaskEntity task) { + var containerImage = task.getContainerImage(); + return isBlank(containerImage) ? EMPTY : containerImage; + } + + private String getHelmChart(TaskEntity task) { + var helmChart = task.getHelmChart(); + return isBlank(helmChart) ? EMPTY : helmChart; + } + + private String getConfiguration(GpuSpecUdt spec) { + var configuration = spec.getConfiguration(); + return isBlank(configuration) ? EMPTY : configuration; + } + + private String getResultsLocation(TaskEntity task) { + var resultsLocation = task.getResultsLocation(); + return isBlank(resultsLocation) ? EMPTY : resultsLocation; + } + + private String getMaxRuntimeDuration(TaskEntity task) { + var maxRuntimeDuration = task.getMaxRuntimeDuration(); + return (maxRuntimeDuration != null) ? maxRuntimeDuration.toString() : EMPTY; + } + + private void deleteInstancesUnBatched(List instanceIds) { + if (instanceIds.isEmpty()) { + return; + } + icmsStubService.deleteInstances(instanceIds); + } + + private String base64EncodeTelemetryDetails(TaskEntity entity) { + var telemetriesUdt = entity.getTelemetries(); + if (telemetriesUdt == null) { + return StringUtils.EMPTY; + } + + var ncaId = entity.getNcaId(); + return telemetryService.base64Encode(ncaId, telemetriesUdt); + } + + private String validateAndGetContainerRegistryImagePullSecrets(TaskEntity task) { + registryArtifactValidationService.validateContainerRegistryCredentialsExist(task); + return registryCredentialService + .getBase64EncodedContainerRegistryImagePullSecrets(task); + } + + private String validateAndGetHelmRegistryImagePullSecrets(TaskEntity task) { + registryArtifactValidationService.validateHelmRegistryCredentialsExist(task); + return registryCredentialService + .getBase64EncodedHelmRegistryImagePullSecrets(task); + } + + private static String getHelmValidationPolicy(TaskEntity task) { + if (task.getGpuSpec() != null) { + var policy = task.getGpuSpec().getHelmValidationPolicy(); + if (StringUtils.isNotBlank(policy)) { + return Base64.getEncoder().encodeToString(policy.getBytes(StandardCharsets.UTF_8)); + } + } + + return null; + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/icms/IcmsClusterGroupClient.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/icms/IcmsClusterGroupClient.java new file mode 100644 index 000000000..9cb1ca62e --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/icms/IcmsClusterGroupClient.java @@ -0,0 +1,247 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.icms; + +import static com.nvidia.nvct.util.NvctConstants.MAX_BUFFER_LIMIT; +import static org.apache.commons.lang3.StringUtils.isBlank; + +import com.github.benmanes.caffeine.cache.Caffeine; +import com.github.benmanes.caffeine.cache.LoadingCache; +import com.github.benmanes.caffeine.cache.Scheduler; +import com.google.common.annotations.VisibleForTesting; +import com.nvidia.boot.exceptions.BadRequestException; +import com.nvidia.boot.exceptions.UpstreamException; +import com.nvidia.nvct.configuration.staticclientauth.FixedBearerExchangeFilterFunction; +import com.nvidia.nvct.configuration.staticclientauth.StaticClientAuthConfiguration.StaticClientIcmsProperties; +import com.nvidia.nvct.rest.task.dto.InstanceUsageTypeEnum; +import com.nvidia.nvct.service.icms.IcmsStubService.ClusterGroupsResponse; +import com.nvidia.nvct.service.icms.IcmsStubService.ClusterGroupsResponse.ClusterGroup; +import com.nvidia.nvct.service.icms.IcmsStubService.ClusterGroupsResponse.ClusterGroup.Gpu; +import com.nvidia.nvct.service.icms.IcmsStubService.ClusterGroupsResponse.ClusterGroup.Gpu.InstanceType; +import com.nvidia.nvct.util.NvctOAuth2ClientUtils; +import com.nvidia.nvct.util.NvctOAuth2ClientUtils.ManagedHttpResources; +import java.time.Duration; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.cloud.context.config.annotation.RefreshScope; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; +import org.springframework.web.reactive.function.client.ExchangeFilterFunction; +import org.springframework.web.reactive.function.client.WebClient; +import org.springframework.web.reactive.function.client.support.WebClientAdapter; +import org.springframework.web.service.invoker.HttpServiceProxyFactory; + + +@Slf4j +@Service +@RefreshScope +public class IcmsClusterGroupClient { + + private static final String CLIENT_REGISTRATION_ID = "icms"; + + private static final String MESG_INVALID_GPU = + "Cluster Group '%s': Invalid GPU '%s' specified"; + private static final String MESG_INVALID_GET_INSTANCE_TYPE_ARGUMENT = + "Invalid argument specified for getting default instance type"; + private static final String MESG_INVALID_CLUSTER_GROUP = + "Invalid Backend or Cluster-Group '%s' specified"; + private static final String MESG_MISSING_GPUS = + "ClusterGroup '%s': Missing GPUs in ICMS response"; + private static final String MESG_MISSING_INSTANCE_TYPES = + "ClusterGroup '%s', GPU '%s': Missing instance-types in ICMS response"; + private static final String MESG_MISSING_DEFAULT_INSTANCE_TYPE = + "Cluster Group '%s', GPU '%s': Missing default instance-type"; + private static final String MESG_MISSING_CLUSTER_GROUPS = + "Account '%s': Missing cluster-groups in successful ICSM response"; + private static final String MESG_DEFAULT_INSTANCE_TYPE_DETAILS = + "ClusterGroup: '{}', GPU: '{}', Default InstanceType: '{}'"; + private static final String MESG_FETCH_CLUSTER_GROUPS = + "Account '{}': Fetching Cluster Groups from ICMS for instance type '{}'"; + private static final String MESG_BLANK_PARAMETER = "'%s' cannot be blank"; + + private final IcmsStubService icmsStubService; + private final LoadingCache> clusterGroupCache; + + private record IcmsCacheKey(String ncaId, InstanceUsageTypeEnum instanceTypeUsage) { + } + + // We could have used OAuth2AuthorizedClientManager and relied on Spring Security to + // pick up the configuration properties using ClientRegistrationRepository directly. However, + // the client-secret value held in the ClientRegistrationRepository does not get refreshed when + // client-secret is rotated. Addressing these issues requires introducing a refreshable + // ClientRegistrationRepository that wasn't clean. Instead, we will keep it simple and use + // the tried and tested approach of using @Value and @RefreshScope annotations and wire + // things up ourselves. + public IcmsClusterGroupClient( + WebClient.Builder webClientBuilder, // Prototype-scoped - Safe to mutate. + ManagedHttpResources icmsHttpResources, + @Value("${nvct.icms.base-url}") String baseUrl, + @Value("${spring.security.oauth2.client.registration.icms.client-id}") String clientId, + @Value("${spring.security.oauth2.client.registration.icms.client-secret}") String clientSecret, + @Value("${spring.security.oauth2.client.registration.icms.scope}") String scope, + @Value("${spring.security.oauth2.client.provider.icms.token-uri}") String tokenUri, + Optional staticClientIcmsProperties) { + + var authFilter = oauthFilter(staticClientIcmsProperties, webClientBuilder, + clientId, clientSecret, scope, tokenUri); + var webClient = webClientBuilder + .baseUrl(baseUrl) + .codecs(configurer -> configurer.defaultCodecs().maxInMemorySize(MAX_BUFFER_LIMIT)) + .clientConnector(icmsHttpResources.connector()) + .filter(NvctOAuth2ClientUtils.getRetryableFilter(CLIENT_REGISTRATION_ID)) + .filter(authFilter) + .filter(NvctOAuth2ClientUtils.getResponseFilterProcessor("ICMS")) + .build(); + var adapter = WebClientAdapter.create(webClient); + var factory = HttpServiceProxyFactory.builderFor(adapter).build(); + this.icmsStubService = factory.createClient(IcmsStubService.class); + this.clusterGroupCache = Caffeine.newBuilder() + .maximumSize(64) + .expireAfterWrite(Duration.ofMinutes(15)) + .scheduler(Scheduler.systemScheduler()) + .build(this::fetchClusterGroups); + } + + private static ExchangeFilterFunction oauthFilter( + Optional staticClientIcmsProperties, + WebClient.Builder webClientBuilder, + String clientId, + String clientSecret, + String scope, + String tokenUri) { + return staticClientIcmsProperties + .map(p -> (ExchangeFilterFunction) + new FixedBearerExchangeFilterFunction(p::getToken)) + .orElseGet(() -> NvctOAuth2ClientUtils + .getOAuth2ExchangeFilter(webClientBuilder, CLIENT_REGISTRATION_ID, + tokenUri, clientId, clientSecret, scope)); + } + + public String getDefaultInstanceType(String ncaId, InstanceUsageTypeEnum instanceUsage, + String clusterGroupName, String gpuName) { + if (isBlank(ncaId) || isBlank(clusterGroupName) || isBlank(gpuName)) { + log.error(MESG_INVALID_GET_INSTANCE_TYPE_ARGUMENT); + throw new IllegalArgumentException(MESG_INVALID_GET_INSTANCE_TYPE_ARGUMENT); + } + + var clusterGroups = getClusterGroups(ncaId, instanceUsage); + var targetClusterGroup = targetClusterGroup(ncaId, clusterGroupName, clusterGroups); + var targetGpu = targetGpu(clusterGroupName, gpuName, targetClusterGroup.getGpus()); + var defaultInstanceType = defaultInstanceType(clusterGroupName, gpuName, + targetGpu.getInstanceTypes()); + log.info(MESG_DEFAULT_INSTANCE_TYPE_DETAILS, + targetClusterGroup.getName(), targetGpu.getName(), defaultInstanceType.getName()); + return defaultInstanceType.getName(); // Return name -- not the value. + } + + @VisibleForTesting + public void clearClusterGroupCache() { + clusterGroupCache.invalidateAll(); + } + + public List getClusterGroups(String ncaId, InstanceUsageTypeEnum instanceUsage) { + if (StringUtils.isBlank(ncaId)) { + var mesg = MESG_BLANK_PARAMETER.formatted("ncaId"); + log.error(mesg); + throw new IllegalArgumentException(mesg); + } + + return clusterGroupCache.get(new IcmsCacheKey(ncaId, instanceUsage)); + } + + private List fetchClusterGroups(IcmsCacheKey cacheKey) { + log.info(MESG_FETCH_CLUSTER_GROUPS, cacheKey.ncaId(), cacheKey.instanceTypeUsage()); + var response = icmsStubService.getClusterGroups( + cacheKey.ncaId(), cacheKey.instanceTypeUsage()); + + verifyClusterGroupsResponse(cacheKey.ncaId(), response); + Objects.requireNonNull(response); + return response.getClusterGroups(); + } + + private static void verifyClusterGroupsResponse( + String ncaId, + ClusterGroupsResponse response) { + if ((response == null) || CollectionUtils.isEmpty(response.getClusterGroups())) { + var mesg = MESG_MISSING_CLUSTER_GROUPS.formatted(ncaId); + log.error(mesg); + throw new UpstreamException(mesg); + } + } + + private static ClusterGroup targetClusterGroup( + String ncaId, + String clusterGroupName, + List clusterGroups) { + if (CollectionUtils.isEmpty(clusterGroups)) { + var mesg = MESG_MISSING_CLUSTER_GROUPS.formatted(ncaId); + log.error(mesg); + throw new UpstreamException(mesg); + } + + return clusterGroups.stream() + .filter(cg -> cg.getName().equals(clusterGroupName)) + .findFirst() + .orElseThrow(() -> { + var mesg = MESG_INVALID_CLUSTER_GROUP.formatted(clusterGroupName); + log.error(mesg); + return new BadRequestException(mesg); + }); + } + + private static Gpu targetGpu(String clusterGroupName, String gpuName, List gpus) { + if (CollectionUtils.isEmpty(gpus)) { + var mesg = MESG_MISSING_GPUS.formatted(clusterGroupName); + log.error(mesg); + throw new UpstreamException(mesg); + } + + return gpus.stream() + .filter(gpu -> gpu.getName().equals(gpuName)) + .findFirst() + .orElseThrow(() -> { + var mesg = MESG_INVALID_GPU.formatted(clusterGroupName, gpuName); + log.error(mesg); + return new BadRequestException(mesg); + }); + } + + private static InstanceType defaultInstanceType( + String clusterGroupName, + String gpuName, + List instanceTypes) { + if (CollectionUtils.isEmpty(instanceTypes)) { + var mesg = MESG_MISSING_INSTANCE_TYPES.formatted(clusterGroupName, gpuName); + log.error(mesg); + throw new UpstreamException(mesg); + } + + return instanceTypes.stream() + .filter(InstanceType::isDefaultInstanceType) + .findFirst() + .orElseThrow(() -> { + var mesg = MESG_MISSING_DEFAULT_INSTANCE_TYPE + .formatted(clusterGroupName, gpuName); + log.error(mesg); + return new UpstreamException(mesg); + }); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/icms/IcmsService.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/icms/IcmsService.java new file mode 100644 index 000000000..f422ebe0c --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/icms/IcmsService.java @@ -0,0 +1,118 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.icms; + +import com.nvidia.nvct.persistence.task.entity.TaskEntity; +import com.nvidia.nvct.rest.task.dto.HealthDto; +import com.nvidia.nvct.service.registry.RegistryArtifactService; +import com.nvidia.nvct.service.task.TaskService; +import java.util.Objects; +import java.util.UUID; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +@Slf4j +@Service +public class IcmsService { + + private static final String MESG_BLANK_PARAMETER = "'%s' cannot be blank"; + private static final String MESG_CANNOT_BE_NULL = "Parameter '%s' cannot be null"; + private static final String MESG_INVALID_INSTANCE_TYPE = + "Task id '%s': Invalid instance-type '%s'"; + + private static final String MESG_REQUESTED_INSTANCE = + "Task id '{}', ICMS requestId '{}', GPU '{}': Requested '1' instance"; + private static final String MESG_TASK_ICMS_OPERATION = + "Task id '{}': {}"; + + private final IcmsClient icmsClient; + private final boolean allocatorEnabled; + private final RegistryArtifactService artifactService; + private final TaskService taskService; + + public IcmsService( + IcmsClient icmsClient, + @Value("${nvct.icms.allocator.enabled:true}") boolean allocatorEnabled, + RegistryArtifactService artifactService, + TaskService taskService) { + this.icmsClient = icmsClient; + this.allocatorEnabled = allocatorEnabled; + this.artifactService = artifactService; + this.taskService = taskService; + } + + public UUID scheduleInstance(TaskEntity task) { + if (!allocatorEnabled) { + return null; + } + Objects.requireNonNull(task, () -> MESG_CANNOT_BE_NULL.formatted("task")); + + var taskId = task.getTaskId(); + var gpuSpec = task.getGpuSpec(); + var gpu = gpuSpec.getGpu(); + var ncaId = task.getNcaId(); + var cacheSize = artifactService.getSize(ncaId, taskId); + var cacheHandle = artifactService.getCacheHandle(ncaId, taskId); + var requestId = icmsClient.createInstance(task, gpuSpec, cacheHandle, + cacheSize); + log.info(MESG_REQUESTED_INSTANCE, taskId, requestId, gpu); + return requestId; + } + + public boolean terminateInstanceByTaskId(String ncaId, UUID taskId) { + icmsClient.terminateInstanceByTaskId(ncaId, taskId); + log.info(MESG_TASK_ICMS_OPERATION, taskId, "Terminated ICMS instances by task id."); + return true; + } + + public HealthDto getHealthDto( + UUID taskId, + String instanceType, + String error) { + if (StringUtils.isBlank(instanceType)) { + var mesg = MESG_BLANK_PARAMETER.formatted("instanceType"); + log.error(mesg); + throw new IllegalArgumentException(mesg); + } + if (StringUtils.isBlank(error)) { + var mesg = MESG_BLANK_PARAMETER.formatted("error"); + log.error(mesg); + throw new IllegalArgumentException(mesg); + } + + var task = taskService.fetchTask(taskId); + var gpuSpec = task.getGpuSpec(); + if (!instanceType.equals(gpuSpec.getInstanceType())) { + // ### Temporarily return health info even if the passed in instanceType does + // not match the one in the Task definition. This is happening because NVCA is + // sending an incorrect instanceType to Utils Container. Till NVCA fixes + // the issue, NVCT API will just log a warning and NOT throw an exception if + // instanceType does not match. + var mesg = MESG_INVALID_INSTANCE_TYPE.formatted(taskId, instanceType); + log.warn(mesg); + } + + return HealthDto.builder() + .gpu(gpuSpec.getGpu()) + .instanceType(instanceType) + .backend(gpuSpec.getBackend()) + .error(error) + .build(); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/icms/IcmsStubService.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/icms/IcmsStubService.java new file mode 100644 index 000000000..70376b516 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/icms/IcmsStubService.java @@ -0,0 +1,384 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.icms; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import tools.jackson.databind.PropertyNamingStrategies; +import tools.jackson.databind.annotation.JsonNaming; +import com.nvidia.nvct.rest.task.dto.InstanceUsageTypeEnum; +import com.nvidia.nvct.service.icms.IcmsStubService.GetInstancesResponse.InstanceRequest.HealthInfo; +import com.nvidia.nvct.service.icms.IcmsStubService.GetInstancesResponse.InstanceRequest.InstanceState; +import com.nvidia.nvct.service.icms.IcmsStubService.GetInstancesResponse.InstanceRequest.Placement; +import jakarta.annotation.Nullable; +import java.net.URI; +import java.time.Instant; +import java.util.List; +import java.util.Set; +import java.util.UUID; +import lombok.Builder; +import lombok.RequiredArgsConstructor; +import lombok.Value; +import lombok.extern.jackson.Jacksonized; +import org.apache.commons.lang3.StringUtils; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.service.annotation.DeleteExchange; +import org.springframework.web.service.annotation.GetExchange; +import org.springframework.web.service.annotation.PostExchange; + +public interface IcmsStubService { + + @Value + @Jacksonized + @Builder + class CreateInstancesResponse { + UUID requestId; + } + + @PostExchange(value = "/v1/si?Action=RequestInstances", + accept = "application/json", + contentType = "application/x-www-form-urlencoded") + CreateInstancesResponse createInstance( + @RequestParam(value = "LaunchSpecification.Backend", required = false) + String backend, + @RequestParam(value = "LaunchSpecification.Clusters", required = false) + Set clusters, + @RequestParam("LaunchSpecification.Gpu") + String gpu, + @RequestParam("LaunchSpecification.InstanceType") + String instanceType, + @RequestParam("LaunchSpecification.NcaId") + String ncaId, + @RequestParam("TaskDetails.AccountName") + String accountName, + @RequestParam("InstanceCount") + int instanceCount, + @RequestParam("LaunchSpecification.ContainerImage") + String containerImage, + @RequestParam("LaunchSpecification.HelmChart") + String helmChart, + @RequestParam(value = "LaunchSpecification.Configuration", required = false) + String configuration, + @RequestParam("LaunchSpecification.Environment") + String environment, + @RequestParam(value = "LaunchSpecification.ArtifactUrl", required = false) + URI artifactUrl, + @RequestParam("LaunchSpecification.CacheArtifacts") + boolean cacheArtifacts, + @RequestParam("LaunchSpecification.CacheHandle") + String cacheHandle, + @RequestParam(value = "LaunchSpecification.CacheSize", required = false) + Long cacheSize, + @RequestParam("TaskDetails.OwnerNcaId") + String ownerNcaId, + @RequestParam("TaskDetails.TaskId") + UUID taskId, + @RequestParam("TaskDetails.TaskName") + String taskName, + @RequestParam("LaunchSpecification.MaxRuntimeDuration") + String maxRuntimeDuration, + @RequestParam("LaunchSpecification.MaxQueuedDuration") + String maxQueuedDuration, + @RequestParam("LaunchSpecification.TerminationGracePeriodDuration") + String terminationGracePeriodDuration, + @RequestParam("LaunchSpecification.ResultHandlingStrategy") + String resultHandlingStrategy, + @RequestParam("LaunchSpecification.Telemetries") + String telemetries, + @RequestParam("LaunchSpecification.DeploymentId") + UUID deploymentId, + @RequestParam("LaunchSpecification.GpuSpecificationId") + UUID gpuSpecificationId, + @RequestParam(value = "LaunchSpecification.HelmValidationPolicy", required = false) + String helmValidationPolicy); + + @Value + @Jacksonized + @Builder + @JsonNaming(PropertyNamingStrategies.UpperCamelCaseStrategy.class) + class GetInstancesResponse { + + List instanceRequests; + + @Value + @Jacksonized + @Builder + @JsonNaming(PropertyNamingStrategies.UpperCamelCaseStrategy.class) + public static class InstanceRequest { + + Instant createTime; + String instanceId; + LaunchSpecification launchSpecification; + String launchedAvailabilityZone; + UUID instanceRequestId; + State state; + Status status; + String instanceInterruptionBehavior; + String cloudProvider; + @Nullable + InstanceState instanceState; + @Nullable + HealthInfo healthInfo; + + @Value + @Jacksonized + @Builder + @JsonNaming(PropertyNamingStrategies.UpperCamelCaseStrategy.class) + public static class LaunchSpecification { + + String instanceType; + String gpu; + String containerImage; + Placement placement; + } + + @Value + @Jacksonized + @Builder + @JsonNaming(PropertyNamingStrategies.UpperCamelCaseStrategy.class) + public static class Placement { + + String availabilityZone; + } + + @Value + @Jacksonized + @Builder + @JsonNaming(PropertyNamingStrategies.UpperCamelCaseStrategy.class) + public static class Status { + + String code; + String message; + Instant updateTime; + } + + @RequiredArgsConstructor + public enum State { + OPEN, ACTIVE, CLOSED, CANCELED, FAILED; + + public boolean isActive() { + return this == ACTIVE; + } + + @JsonCreator + public static State fromString(String state) { + return StringUtils.isBlank(state) ? null : State.valueOf(state.toUpperCase()); + } + + } + + @Value + @Jacksonized + @Builder + @JsonNaming(PropertyNamingStrategies.UpperCamelCaseStrategy.class) + public static class InstanceState { + + int code; + String name; + + public boolean isStartingOrRunning() { + return "starting".equals(name) || "running".equals(name); + } + + public boolean isRunning() { + return "running".equals(name); + } + } + + @Value + @Jacksonized + @Builder + @JsonNaming(PropertyNamingStrategies.UpperCamelCaseStrategy.class) + public static class HealthInfo { + String errorLog; + } + } + } + + @DeleteExchange("/v1/si?Action=TerminateInstances") + GetInstancesResponse deleteInstances( + @RequestParam("InstanceId") List instanceIds); + + @DeleteExchange("/v1/si/accounts/{ncaId}/workloads/{workloadId}") + void terminateInstancesByTaskId( + @PathVariable("ncaId") String ncaId, + @PathVariable("workloadId") UUID taskId); + + @Value + @Jacksonized + @Builder + class ClusterGroupsResponse { + List clusterGroups; + + @Value + @Jacksonized + @Builder + public static class ClusterGroup { + UUID id; + String name; + String ncaId; + List authorizedNcaIds; + List gpus; + List clusters; + + @Value + @Jacksonized + @Builder + public static class Gpu { + String name; + List instanceTypes; + + @Value + @Jacksonized + @Builder + public static class InstanceType { + String name; + String description; + @JsonProperty("default") + boolean defaultInstanceType; + } + } + + @Value + @Jacksonized + @Builder + public static class Cluster { + String k8sVersion; + String id; + String name; + } + } + } + + @GetExchange("/v1/si/accounts/{ncaId}/clusterGroups") + ClusterGroupsResponse getClusterGroups( + @PathVariable("ncaId") String ncaId, + @RequestParam("instanceTypeUsage") InstanceUsageTypeEnum instanceUsage); + + @Value + @Jacksonized + @Builder + @JsonNaming(PropertyNamingStrategies.UpperCamelCaseStrategy.class) + class DescribeInstancesResponse { + + List instances; + + @Value + @Jacksonized + @Builder + @JsonNaming(PropertyNamingStrategies.UpperCamelCaseStrategy.class) + public static class Instance { + + String instanceId; + Set instanceIps; + } + } + + @GetExchange("/v1/si?Action=DescribeInstances") + DescribeInstancesResponse describeInstances(@RequestParam("InstanceId") Set instanceIds); + + @Value + @Jacksonized + @Builder + class InstanceTypeDetails { + String name; + String value; + String description; + int cpuCores; + String systemMemory; + String gpuMemory; + int gpuCount = 1; + Set clusters; + Set regions; + Set attributes; + String gpuName; + Boolean defaultable; + String cpuArch; + String os; + String driverVersion; + String storage; + } + + @Value + @Jacksonized + @Builder + class ClusterResponse { + String clusterName; + String clusterGroupName; + String ncaId; + Set authorizedNCAIds; + String cloudProvider; + String region; + Set gpus; + String clusterId; + String clusterGroupId; + String status; + + @Value + @Jacksonized + @Builder + public static class GpuV4 { + String name; + int capacity; + Set instanceTypes; + } + } + + @GetExchange( + "/v1/si/accounts/{ncaId}/clusters?includeAuthorizedClusters=true&includeGfnInAuthorizedClusters=true") + List getClusters( + @PathVariable("ncaId") String ncaId, + @RequestParam("instanceTypeUsage") InstanceUsageTypeEnum instanceUsage); + + @Value + @Jacksonized + @JsonNaming(PropertyNamingStrategies.UpperCamelCaseStrategy.class) + @Builder + class Instances { + List Instances; + } + + @Value + @Jacksonized + @JsonNaming(PropertyNamingStrategies.UpperCamelCaseStrategy.class) + @Builder + class Instance { + Instant createTime; + String imageId; + String containerImage; + String instanceId; + String cloudProvider; + String instanceType; + Placement placement; + InstanceState state; + HealthInfo healthInfo; + String launchRequestId; + Set instanceIps; + String capacityType; + UUID deploymentId; + UUID gpuSpecificationId; + } + + @GetExchange("/v1/si/accounts/{ncaId}/deployments/{deploymentId}/instances") + Instances terminateInstancesByTaskId( + @PathVariable("ncaId") String ncaId, + @PathVariable("deploymentId") UUID taskId, + @RequestParam("IncludeTerminated") boolean includeTerminated, + @RequestParam("UseConciseName") boolean useConciseName, + @RequestParam("ExpiredAckedInstances") boolean expiredAckedInstances); +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/instance/InstanceService.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/instance/InstanceService.java new file mode 100644 index 000000000..5c46cff36 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/instance/InstanceService.java @@ -0,0 +1,139 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.instance; + +import static com.nvidia.nvct.util.NvctConstants.TERMINAL_TASK_STATUSES; + +import com.nvidia.nvct.persistence.task.entity.TaskEntity; +import com.nvidia.nvct.rest.task.dto.InstanceDto; +import com.nvidia.nvct.rest.task.dto.InstanceStateEnum; +import com.nvidia.nvct.service.icms.IcmsClient; +import com.nvidia.nvct.service.icms.IcmsStubService.Instance; +import com.nvidia.nvct.service.icms.IcmsStubService.GetInstancesResponse.InstanceRequest.InstanceState; +import java.util.List; +import java.util.Optional; +import java.util.UUID; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; + +@Slf4j +@Service +@RequiredArgsConstructor +public class InstanceService { + + private static final String MESG_INSTANCE_BY_ACC_TASK_STATUS = + "{} instances for account '{}' and task '{}'"; + private static final String MESG_UNKNOWN_INSTANCE_STATE = + "ICMS Request Id '{}': Unknown InstanceState '{}'"; + private static final String MESG_NULL_INSTANCE_STATE = + "ICMS Request Id '{}': Null InstanceState"; + private static final String MESG_BLANK_INSTANCE_STATE_NAME = + "ICMS Request Id '{}': InstanceState name is blank"; + private static final String MESG_TERMINAL_STATUS_AND_INSTANCE_STATE = + "Task id '{}': Terminal status '{}' and Instance state '{}'"; + + private final IcmsClient icmsClient; + + public Optional> getInstances(TaskEntity taskEntity) { + return getInstancesByTaskId(taskEntity); + } + + public Optional> getInstancesByTaskId(TaskEntity taskEntity) { + var ncaId = taskEntity.getNcaId(); + var taskId = taskEntity.getTaskId(); + + log.debug(MESG_INSTANCE_BY_ACC_TASK_STATUS, "Retrieving", ncaId, taskId); + + var instances = icmsClient.getInstancesByTaskId(ncaId, taskId); + + log.debug(MESG_INSTANCE_BY_ACC_TASK_STATUS, "Retrieved", ncaId, taskId); + var instancesWithIds = instances.stream() + .filter(instance -> StringUtils.isNotBlank(instance.getInstanceId())) + .toList(); + if (instancesWithIds.isEmpty()) { + return Optional.empty(); + } + + return Optional.of(instancesWithIds.stream() + .map(instance -> InstanceDto.builder() + .instanceId(instance.getInstanceId()) + .taskId(taskId) + .instanceType(instance.getInstanceType()) + .instanceState(getInstanceState(instance, taskEntity)) + .icmsRequestId(UUID.fromString(instance.getLaunchRequestId())) + .ncaId(ncaId) + .gpu(taskEntity.getGpuSpec().getGpu()) + .backend(instance.getCloudProvider()) + .location(instance.getPlacement().getAvailabilityZone()) + .instanceCreatedAt(instance.getCreateTime()) + // TODO right now ICMS instance object does not have updatedAt. At the + // legacy flow we populated instanceUpdatedAt in DTO with a value when + // request was updated last time, not instance. ICMS should provide actual + // value related to instance, not to request. + .instanceUpdatedAt(instance.getCreateTime()) + .build()) + .toList()); + } + + private InstanceStateEnum getInstanceState( + Instance instance, + TaskEntity taskEntity) { + return getInstanceState( + instance.getState(), instance.getLaunchRequestId(), taskEntity); + } + + private InstanceStateEnum getInstanceState( + InstanceState instanceState, + Object icmsRequestId, + TaskEntity taskEntity) { + InstanceStateEnum state; + + if (instanceState == null) { + log.info(MESG_NULL_INSTANCE_STATE, icmsRequestId); + state = null; + } else { + var instanceStateName = instanceState.getName(); + if (StringUtils.isBlank(instanceStateName)) { + log.info(MESG_BLANK_INSTANCE_STATE_NAME, icmsRequestId); + state = null; + } else { + state = switch (instanceStateName.toUpperCase()) { + case "STARTING" -> InstanceStateEnum.STARTING; + case "RUNNING" -> InstanceStateEnum.RUNNING; + case "TERMINATED" -> InstanceStateEnum.TERMINATED; + default -> { + log.info(MESG_UNKNOWN_INSTANCE_STATE, icmsRequestId, instanceStateName); + yield null; + } + }; + } + } + + var status = taskEntity.getStatus(); + if (state != null && TERMINAL_TASK_STATUSES.contains(status)) { + // Return null as instance state when the Task has reached terminal status to + // avoid confusion in the response. Log the actual instance state. + log.info(MESG_TERMINAL_STATUS_AND_INSTANCE_STATE, + taskEntity.getTaskId(), status, state); + state = null; + } + return state; + } + +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/metrics/TaskErrorMetricsService.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/metrics/TaskErrorMetricsService.java new file mode 100644 index 000000000..f8bdc9045 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/metrics/TaskErrorMetricsService.java @@ -0,0 +1,70 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.metrics; + +import static com.nvidia.nvct.util.NvctConstants.METER_TASK_ERROR; +import static com.nvidia.nvct.util.NvctConstants.SPAN_TAG_NCA_ID; +import static com.nvidia.nvct.util.NvctConstants.TAG_ERROR_SOURCE; +import static com.nvidia.nvct.util.NvctConstants.TAG_NCA_ID; +import static java.time.Duration.ofMinutes; + +import com.github.benmanes.caffeine.cache.Caffeine; +import com.github.benmanes.caffeine.cache.LoadingCache; +import com.github.benmanes.caffeine.cache.Scheduler; +import com.nvidia.nvct.util.NvctUtils; +import io.micrometer.core.instrument.Counter; +import io.micrometer.core.instrument.Meter; +import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.observation.annotation.Observed; +import io.micrometer.tracing.Tracer; +import java.util.Map; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +@Service +@Slf4j +public class TaskErrorMetricsService { + + private static final String NVCT_API_ERROR_SOURCE = "nvct-api"; + + private final LoadingCache taskErrorCounters; + private final Tracer tracer; + + public TaskErrorMetricsService(MeterRegistry meterRegistry, Tracer tracer) { + this.tracer = tracer; + this.taskErrorCounters = Caffeine.newBuilder() + .expireAfter(new TaskMetricsExpirationPolicy(ofMinutes(45))) + .scheduler(Scheduler.systemScheduler()) + .evictionListener((key, counter, cause) -> { + if (counter instanceof Meter m) { + meterRegistry.remove(m); + } + }) + .build(ncaId -> Counter.builder(METER_TASK_ERROR) + .tag(TAG_NCA_ID, ncaId) + .tag(TAG_ERROR_SOURCE, NVCT_API_ERROR_SOURCE) + .register(meterRegistry)); + } + + // Invoked everytime a Task(belonging to the specified account) errors. + @Observed(name = "task.error", contextualName = "record-task-error") + public void recordTaskError(String ncaId) { + NvctUtils.addTagsToCurrentSpan(tracer, Map.of(SPAN_TAG_NCA_ID, ncaId)); + taskErrorCounters.get(ncaId).increment(); + } + +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/metrics/TaskMetricsExpirationPolicy.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/metrics/TaskMetricsExpirationPolicy.java new file mode 100644 index 000000000..4b25d3223 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/metrics/TaskMetricsExpirationPolicy.java @@ -0,0 +1,47 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.metrics; + +import com.github.benmanes.caffeine.cache.Expiry; +import io.micrometer.core.instrument.Meter; +import jakarta.validation.constraints.PositiveOrZero; +import java.time.Duration; +import lombok.NonNull; +import lombok.RequiredArgsConstructor; + +@RequiredArgsConstructor +public class TaskMetricsExpirationPolicy implements Expiry { + @NonNull + private final Duration timeToLive; + + @Override + public long expireAfterCreate(String key, Meter value, long currentTime) { + return timeToLive.toNanos(); + } + + @Override + public long expireAfterUpdate(String key, Meter value, long currentTime, + @PositiveOrZero long currentDuration) { + return currentDuration; + } + + @Override + public long expireAfterRead(String key, Meter value, long currentTime, + @PositiveOrZero long currentDuration) { + return currentDuration; + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/metrics/TaskRunningMetricsService.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/metrics/TaskRunningMetricsService.java new file mode 100644 index 000000000..f910b5acd --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/metrics/TaskRunningMetricsService.java @@ -0,0 +1,143 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.metrics; + +import static com.nvidia.nvct.util.NvctConstants.METER_TASK_RUNNING; +import static com.nvidia.nvct.util.NvctConstants.SPAN_TAG_ACCOUNT_NAME; +import static com.nvidia.nvct.util.NvctConstants.SPAN_TAG_NCA_ID; +import static com.nvidia.nvct.util.NvctConstants.TAG_NCA_ID; +import static com.nvidia.nvct.util.NvctConstants.TAG_ORG_NAME; +import static java.time.Duration.ofMinutes; + +import com.github.benmanes.caffeine.cache.Cache; +import com.github.benmanes.caffeine.cache.Caffeine; +import com.github.benmanes.caffeine.cache.Expiry; +import com.github.benmanes.caffeine.cache.LoadingCache; +import com.github.benmanes.caffeine.cache.Scheduler; +import com.nvidia.nvct.service.task.TaskService; +import com.nvidia.nvct.util.NvctUtils; +import io.micrometer.core.instrument.Gauge; +import io.micrometer.core.instrument.Meter; +import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.observation.annotation.Observed; +import io.micrometer.tracing.Tracer; +import jakarta.validation.constraints.PositiveOrZero; +import java.time.Duration; +import java.util.Map; +import lombok.Builder; +import lombok.NonNull; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +@Service +@Slf4j +public class TaskRunningMetricsService { + + private final TaskService taskService; + private final Tracer tracer; + + @Builder + public record TaskRunningKey(String ncaId, String accountName) { } + + private final Cache taskRunningValues = Caffeine.newBuilder() + .expireAfterAccess(ofMinutes(45)) + .scheduler(Scheduler.systemScheduler()) + .build(); + + private final LoadingCache taskRunningGauges; + + public TaskRunningMetricsService(MeterRegistry meterRegistry, TaskService taskService, Tracer tracer) { + this.taskService = taskService; + this.tracer = tracer; + this.taskRunningGauges = Caffeine.newBuilder() + .expireAfter(new TaskRunningExpirationPolicy(ofMinutes(45))) + .scheduler(Scheduler.systemScheduler()) + .evictionListener((key, gauge, cause) -> { + if (gauge instanceof Meter m) { + meterRegistry.remove(m); + } + }) + .build(key -> Gauge.builder(METER_TASK_RUNNING, + () -> taskRunningValues.getIfPresent(key)) + .tag(TAG_NCA_ID, key.ncaId()) + .tag(TAG_ORG_NAME, key.accountName()) + .register(meterRegistry)); + } + + /** + * Records count of tasks with RUNNING status for the specified account. + *

+ * Micrometer Gauge has async nature. On building the Gauge meter, we have to provide a + * lambda/supplier to return actual values to be recorded. We have a cache to store real + * values. The meter will get the value from the cache. We store the meter in another + * async loading cache. The meter is created on the first request to async loading cache. + * Therefore, we need to call meter cache on each invocation to make sure the metric is + * created/populated. + *

+ * @param ncaId NVIDIA Cloud Account id + * @param accountName Account name -- Can be NGC Org Name + */ + @Observed(name = "task.running", contextualName = "record-running-task") + public void recordRunningTask(String ncaId, String accountName) { + NvctUtils.addTagsToCurrentSpan(tracer, Map.of(SPAN_TAG_NCA_ID, ncaId, + SPAN_TAG_ACCOUNT_NAME, accountName)); + var taskRunningKey = new TaskRunningKey(ncaId, accountName); + updateValuesCacheWithTaskCountByNcaId(taskRunningKey); + taskRunningGauges.get(taskRunningKey); + } + + private void updateValuesCacheWithTaskCountByNcaId(TaskRunningKey key) { + var count = taskRunningValues.getIfPresent(key); + if (count == null) { + // Get the count from the DB if the cache doesn't have it. + count = taskService.countByNcaId(key.ncaId()); + taskRunningValues.put(key, count); + return; + } + count++; + taskRunningValues.put(key, count); + } + + @RequiredArgsConstructor + private static class TaskRunningExpirationPolicy + implements Expiry { + + @NonNull + private final Duration timeToLive; + + @Override + public long expireAfterCreate( + TaskRunningKey key, Gauge value, long currentTime) { + return timeToLive.toNanos(); + } + + @Override + public long expireAfterUpdate( + TaskRunningKey key, Gauge value, long currentTime, + @PositiveOrZero long currentDuration) { + return currentDuration; + } + + @Override + public long expireAfterRead( + TaskRunningKey key, Gauge value, long currentTime, + @PositiveOrZero long currentDuration) { + return currentDuration; + } + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/metrics/TaskSuccessMetricsService.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/metrics/TaskSuccessMetricsService.java new file mode 100644 index 000000000..01f4654d0 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/metrics/TaskSuccessMetricsService.java @@ -0,0 +1,67 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.metrics; + +import static com.nvidia.nvct.util.NvctConstants.METER_TASK_SUCCESS; +import static com.nvidia.nvct.util.NvctConstants.SPAN_TAG_NCA_ID; +import static com.nvidia.nvct.util.NvctConstants.TAG_NCA_ID; +import static java.time.Duration.ofMinutes; + +import com.github.benmanes.caffeine.cache.Caffeine; +import com.github.benmanes.caffeine.cache.LoadingCache; +import com.github.benmanes.caffeine.cache.Scheduler; +import com.nvidia.nvct.util.NvctUtils; +import io.micrometer.core.instrument.Counter; +import io.micrometer.core.instrument.Meter; +import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.observation.annotation.Observed; +import io.micrometer.tracing.Tracer; +import java.util.Map; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +@Service +@Slf4j +public class TaskSuccessMetricsService { + + private final LoadingCache taskSuccessGauges; + private final Tracer tracer; + + public TaskSuccessMetricsService(MeterRegistry meterRegistry, Tracer tracer) { + this.tracer = tracer; + this.taskSuccessGauges = Caffeine.newBuilder() + .expireAfter(new TaskMetricsExpirationPolicy(ofMinutes(45))) + .scheduler(Scheduler.systemScheduler()) + .evictionListener((functionId, gauge, cause) -> { + if (gauge instanceof Meter m) { + meterRegistry.remove(m); + } + }) + .build(ncaId -> Counter.builder(METER_TASK_SUCCESS) + .tag(TAG_NCA_ID, ncaId) + .register(meterRegistry)); + } + + // Invoked everytime a Task(belonging to the specified account) generates a result/checkpoint + // and when completed. + @Observed(name = "task.success", contextualName = "record-task-success") + public void recordTaskSuccess(String ncaId) { + NvctUtils.addTagsToCurrentSpan(tracer, Map.of(SPAN_TAG_NCA_ID, ncaId)); + taskSuccessGauges.get(ncaId).increment(); + } + +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/ngc/NgcRegistryClient.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/ngc/NgcRegistryClient.java new file mode 100644 index 000000000..a6d751351 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/ngc/NgcRegistryClient.java @@ -0,0 +1,160 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.ngc; + +import tools.jackson.databind.JsonNode; +import com.nvidia.boot.exceptions.BadRequestException; +import com.nvidia.nvct.service.ngc.dto.CreateModelRequest; +import com.nvidia.nvct.util.NvctOAuth2ClientUtils; +import com.nvidia.nvct.util.NvctOAuth2ClientUtils.ManagedHttpResources; +import java.util.UUID; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.cloud.context.config.annotation.RefreshScope; +import org.springframework.stereotype.Service; +import org.springframework.web.reactive.function.client.WebClient; +import org.springframework.web.reactive.function.client.support.WebClientAdapter; +import org.springframework.web.service.invoker.HttpServiceProxyFactory; + +@Service +@RefreshScope +@Slf4j +public class NgcRegistryClient { + private static final String MESG_BLANK_PARAMETER = "'%s' cannot be blank"; + private static final String MESG_INVALID_RESULTS_LOCATION = + "Invalid request: resultsLocation '%s' should be either in 'orgName/modelName' or " + + "'orgName/teamName/modelName' format"; + private static final int NGC_MODEL_NAME_MAX_LENGTH = 64; + private static final String MESG_MODEL_NAME_TOO_LONG = + "Invalid request: model name '%s' in resultsLocation exceeds the maximum allowed " + + "length of " + NGC_MODEL_NAME_MAX_LENGTH + " characters"; + private static final String MESG_CREATED_AND_DELETED_MODEL = + "Successfully created and deleted model '{}' using the NGC_API_KEY"; + private static final String MESG_REGISTRY_RESPONSE_STATUS = + "Cannot create results/checkpoints using the specified secret NGC_API_KEY in the " + + "org/team specified in the 'resultsLocation' - NGC Registry response " + + "status code '%d' "; + + public static final String CLIENT_REGISTRATION_ID = "ngc-registry"; + private static final String BEARER_TOKEN = "Bearer %s"; + + private final NgcRegistryStubService ngcRegistryStubService; + + private record ModelDetails(String orgName, String teamName, String modelName) { } + + public NgcRegistryClient( + WebClient.Builder webClientBuilder, // Prototype-scoped - Safe to mutate. + ManagedHttpResources ngcRegistryHttpResources, + @Value("${nvct.registries.recognized.model.ngc.hostname}") String hostname) { + var baseUrl = hostname.toLowerCase().startsWith("http") + ? hostname : "https://" + hostname; // For tests. + var webClient = webClientBuilder + .baseUrl(baseUrl.replace("-ngc", "")) + .clientConnector(ngcRegistryHttpResources.connector()) + .filter(NvctOAuth2ClientUtils.getRetryableFilter(CLIENT_REGISTRATION_ID)) + .filter(NvctOAuth2ClientUtils.getResponseFilterProcessor("NGC")) + .build(); + var adapter = WebClientAdapter.create(webClient); + var factory = HttpServiceProxyFactory.builderFor(adapter).build(); + this.ngcRegistryStubService = factory.createClient(NgcRegistryStubService.class); + } + + // Validate the NGC_API_KEY by creating the model and then deleting the model specified in + // the resultsLocation under the specified org / team. + public void validate(JsonNode ngcApiKey, String resultsLocation) { + var value = ngcApiKey.isString() ? ngcApiKey.asString() : ngcApiKey.toString(); + if (StringUtils.isBlank(value)) { + var mesg = MESG_BLANK_PARAMETER.formatted("ngcApiKey"); + log.error(mesg); + throw new IllegalArgumentException(mesg); + } + + if (StringUtils.isBlank(resultsLocation)) { + var mesg = MESG_BLANK_PARAMETER.formatted("resultsLocation"); + log.error(mesg); + throw new IllegalArgumentException(mesg); + } + + var modelDetails = getModelDetails(resultsLocation); + var payload = CreateModelRequest.builder() + .name(modelDetails.modelName()) + .displayName(modelDetails.modelName()) + .precision(StringUtils.EMPTY) + .framework(StringUtils.EMPTY) + .build(); + var bearerToken = BEARER_TOKEN.formatted(value); + if (StringUtils.isBlank(modelDetails.teamName())) { + ngcRegistryStubService.createOrgModel(bearerToken, + modelDetails.orgName(), + payload); + ngcRegistryStubService.deleteOrgModel(bearerToken, modelDetails.orgName(), + modelDetails.modelName()); + } else { + ngcRegistryStubService.createTeamModel(bearerToken, + modelDetails.orgName(), + modelDetails.teamName(), + payload); + ngcRegistryStubService.deleteTeamModel(bearerToken, modelDetails.orgName(), + modelDetails.teamName(), + modelDetails.modelName()); + } + log.info(MESG_CREATED_AND_DELETED_MODEL, modelDetails.modelName()); + } + + private static ModelDetails getModelDetails(String resultsLocation) { + int slashCount = StringUtils.countMatches(resultsLocation, '/'); + if ((slashCount == 0) || (slashCount > 2)) { + var mesg = MESG_INVALID_RESULTS_LOCATION.formatted(resultsLocation); + log.error(mesg); + throw new BadRequestException(mesg); + } + + var orgName = resultsLocation.substring(0, resultsLocation.indexOf('/')); + String teamName = null; + var modelName = ""; + + if (slashCount == 1) { + modelName = resultsLocation.substring(orgName.length() + 1); + } else { + var index = resultsLocation.lastIndexOf('/'); + teamName = resultsLocation.substring(orgName.length() + 1, index); + modelName = resultsLocation.substring(index + 1); + } + + // Validate that model name doesn't exceed NGC's maximum limit + if (modelName.length() > NGC_MODEL_NAME_MAX_LENGTH) { + var mesg = MESG_MODEL_NAME_TOO_LONG.formatted(modelName); + log.error(mesg); + throw new BadRequestException(mesg); + } + + // Model name length can only be 64 characters. Since we are appending a full UUID, + // truncate the model name if needed to ensure the final name fits within the limit. + var uuid = UUID.randomUUID().toString(); + // Reserve space for dash and UUID + var maxModelNameLength = NGC_MODEL_NAME_MAX_LENGTH - uuid.length() - 1; + if (modelName.length() > maxModelNameLength) { + modelName = modelName.substring(0, maxModelNameLength); + } + + // Create a unique model name so that there is no conflict with existing ones when + // we try to create a new model to validate the NGC_API_KEY. This newly created model + // will be deleted immediately. + return new ModelDetails(orgName, teamName, modelName + "-" + uuid); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/ngc/NgcRegistryStubService.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/ngc/NgcRegistryStubService.java new file mode 100644 index 000000000..ca1d50652 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/ngc/NgcRegistryStubService.java @@ -0,0 +1,65 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.ngc; + +import static org.springframework.http.HttpHeaders.AUTHORIZATION; +import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; + +import com.nvidia.nvct.service.ngc.dto.CreateModelRequest; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.service.annotation.DeleteExchange; +import org.springframework.web.service.annotation.PostExchange; + +// Used to validate the NGC_API_KEY and the org/team names that are provided +// during Task creation so that we can fail fast. We don't care about the +// response from these endpoints. We just care about the response status code +// and the error message, if any. +// +// There is no interceptor involved in this case as NGC_API_KEY provided by +// the user during Task creation serves as the Bearer token. +public interface NgcRegistryStubService { + + @PostExchange(url = "/v2/org/{orgName}/models", contentType = APPLICATION_JSON_VALUE) + ResponseEntity createOrgModel( + @RequestHeader(name = AUTHORIZATION) String authorization, + @PathVariable String orgName, + @RequestBody CreateModelRequest payload); + + @PostExchange(url = "/v2/org/{orgName}/team/{teamName}/models", + contentType = APPLICATION_JSON_VALUE) + ResponseEntity createTeamModel( + @RequestHeader(name = AUTHORIZATION) String authorization, + @PathVariable String orgName, + @PathVariable String teamName, + @RequestBody CreateModelRequest payload); + + @DeleteExchange("/v2/org/{orgName}/models/{modelName}") + ResponseEntity deleteOrgModel( + @RequestHeader(name = AUTHORIZATION) String authorization, + @PathVariable String orgName, + @PathVariable String modelName); + + @DeleteExchange("/v2/org/{orgName}/team/{teamName}/models/{modelName}") + ResponseEntity deleteTeamModel( + @RequestHeader(name = AUTHORIZATION) String authorization, + @PathVariable String orgName, + @PathVariable String teamName, + @PathVariable String modelName); +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/ngc/dto/CreateModelRequest.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/ngc/dto/CreateModelRequest.java new file mode 100644 index 000000000..1d3042983 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/ngc/dto/CreateModelRequest.java @@ -0,0 +1,33 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.ngc.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotBlank; +import lombok.Builder; +import lombok.NonNull; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@Builder(toBuilder = true) +@Schema(description = "Request payload to create a model in NGC Model Registry") +public record CreateModelRequest( + @NonNull @NotBlank String name, + @NonNull @NotBlank String displayName, + @NonNull String precision, + @NonNull String framework) { +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/nvcf/NvcfClient.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/nvcf/NvcfClient.java new file mode 100644 index 000000000..5d3ba3386 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/nvcf/NvcfClient.java @@ -0,0 +1,171 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.nvcf; + +import static com.nvidia.nvct.util.NvctConstants.MAX_BUFFER_LIMIT; + +import com.github.benmanes.caffeine.cache.Caffeine; +import com.github.benmanes.caffeine.cache.LoadingCache; +import com.github.benmanes.caffeine.cache.Scheduler; +import com.nvidia.boot.exceptions.UnauthorizedException; +import com.nvidia.boot.exceptions.UpstreamException; +import com.nvidia.nvct.configuration.staticclientauth.FixedBearerExchangeFilterFunction; +import com.nvidia.nvct.configuration.staticclientauth.StaticClientAuthConfiguration.StaticClientNvcfProperties; +import com.nvidia.nvct.service.account.dto.AccountDto; +import com.nvidia.nvct.service.client.dto.ClientDto; +import com.nvidia.nvct.util.NvctOAuth2ClientUtils; +import com.nvidia.nvct.util.NvctOAuth2ClientUtils.ManagedHttpResources; +import java.time.Duration; +import java.util.Optional; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.cloud.context.config.annotation.RefreshScope; +import org.springframework.stereotype.Service; +import org.springframework.web.reactive.function.client.ExchangeFilterFunction; +import org.springframework.web.reactive.function.client.WebClient; +import org.springframework.web.reactive.function.client.support.WebClientAdapter; +import org.springframework.web.service.invoker.HttpServiceProxyFactory; + +@Service +@RefreshScope +@Slf4j +public class NvcfClient { + + private static final String MESG_BLANK_PARAMETER = "'%s' cannot be blank"; + public static final String CLIENT_REGISTRATION_ID = "nvcf"; + + private final NvcfStubService nvcfStubService; + private final LoadingCache cachedNvcfAccounts; + private final LoadingCache cachedNvcfClients; + + // We could have used OAuth2AuthorizedClientManager and relied on Spring Security to + // pick up the configuration properties using ClientRegistrationRepository directly. However, + // the client-secret value held in the ClientRegistrationRepository does not get refreshed when + // client-secret is rotated. Addressing these issues requires introducing a refreshable + // ClientRegistrationRepository that wasn't clean. Instead, we will keep it simple and use + // the tried and tested approach of using @Value and @RefreshScope annotations and wire + // things up ourselves. + public NvcfClient( + WebClient.Builder webClientBuilder, // Prototype-scoped - Safe to mutate. + ManagedHttpResources nvcfHttpResources, + @Value("${nvct.nvcf.base-url}") String baseUrl, + @Value("${spring.security.oauth2.client.registration.nvcf.client-id}") String clientId, + @Value("${spring.security.oauth2.client.registration.nvcf.client-secret}") String clientSecret, + @Value("${spring.security.oauth2.client.registration.nvcf.scope}") String scope, + @Value("${spring.security.oauth2.client.provider.nvcf.token-uri}") String tokenUri, + @Value("${nvct.nvcf.cache-ttl:PT15M}") Duration cacheTtl, + Optional staticClientNvcfProperties) { + this.cachedNvcfAccounts = Caffeine.newBuilder() + .maximumSize(512) + .scheduler(Scheduler.systemScheduler()) + .expireAfterWrite(cacheTtl) + .build(this::fetchAccount); + this.cachedNvcfClients = Caffeine.newBuilder() + .maximumSize(512) + .scheduler(Scheduler.systemScheduler()) + .expireAfterWrite(cacheTtl) + .build(this::fetchClient); + + var authFilter = oauthFilter(staticClientNvcfProperties, webClientBuilder, + clientId, clientSecret, scope, tokenUri); + var webClient = webClientBuilder + .baseUrl(baseUrl) + .codecs(configurer -> configurer.defaultCodecs().maxInMemorySize(MAX_BUFFER_LIMIT)) + .clientConnector(nvcfHttpResources.connector()) + .filter(NvctOAuth2ClientUtils.getRetryableFilter(CLIENT_REGISTRATION_ID)) + .filter(authFilter) + .filter(NvctOAuth2ClientUtils.getResponseFilterProcessor("NVCF")) + .build(); + var adapter = WebClientAdapter.create(webClient); + var factory = HttpServiceProxyFactory.builderFor(adapter).build(); + this.nvcfStubService = factory.createClient(NvcfStubService.class); + } + + private static ExchangeFilterFunction oauthFilter( + Optional staticClientNvcfProperties, + WebClient.Builder webClientBuilder, + String clientId, + String clientSecret, + String scope, + String tokenUri) { + return staticClientNvcfProperties + .map(p -> (ExchangeFilterFunction) + new FixedBearerExchangeFilterFunction(p::getToken)) + .orElseGet(() -> NvctOAuth2ClientUtils + .getOAuth2ExchangeFilter(webClientBuilder, CLIENT_REGISTRATION_ID, + tokenUri, clientId, clientSecret, scope)); + } + + public AccountDto getAccount(String ncaId) { + if (StringUtils.isBlank(ncaId)) { + var mesg = MESG_BLANK_PARAMETER.formatted("ncaId"); + log.error(mesg); + throw new IllegalArgumentException(mesg); + } + + return cachedNvcfAccounts.get(ncaId); + } + + public ClientDto getClient(String clientId) { + if (StringUtils.isBlank(clientId)) { + var mesg = MESG_BLANK_PARAMETER.formatted("clientId"); + log.error(mesg); + throw new IllegalArgumentException(mesg); + } + + return cachedNvcfClients.get(clientId); + } + + public void invalidateCache() { + cachedNvcfClients.invalidateAll(); + cachedNvcfAccounts.invalidateAll(); + } + + public void invalidateCacheForSpecificAccount(String ncaId) { + var account = cachedNvcfAccounts.get(ncaId); + if (account == null) { + return; + } + cachedNvcfAccounts.invalidate(ncaId); + } + + private AccountDto fetchAccount(String ncaId) { + var response = nvcfStubService.fetchAccount(ncaId); + if (response == null) { + throw new UpstreamException("No response from NVCF"); + } + var result = response.getAccount(); + if (result == null) { + throw new UnauthorizedException("Unknown NCA Id: " + ncaId); + } + return result; + } + + private ClientDto fetchClient(String clientId) { + var response = nvcfStubService.fetchClient(clientId); + if (response == null) { + throw new UpstreamException("No response from NVCF"); + } + var result = response.getClient(); + if (result == null) { + throw new UnauthorizedException("Unknown Client Id: " + clientId); + } + return result; + } + +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/nvcf/NvcfStubService.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/nvcf/NvcfStubService.java new file mode 100644 index 000000000..b816b1be2 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/nvcf/NvcfStubService.java @@ -0,0 +1,47 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.nvcf; + +import com.nvidia.nvct.service.account.dto.AccountDto; +import com.nvidia.nvct.service.client.dto.ClientDto; +import lombok.Builder; +import lombok.extern.jackson.Jacksonized; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.service.annotation.GetExchange; + +public interface NvcfStubService { + + @GetExchange("/v2/nvcf/accounts/{ncaId}") + NvcfAccountResponse fetchAccount(@PathVariable String ncaId); + + @GetExchange("/v2/nvcf/clients/{clientId}") + NvcfClientResponse fetchClient(@PathVariable String clientId); + + @lombok.Value + @Jacksonized + @Builder + class NvcfAccountResponse { + AccountDto account; + } + + @lombok.Value + @Jacksonized + @Builder + class NvcfClientResponse { + ClientDto client; + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/ratelimit/BucketRateLimiter.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/ratelimit/BucketRateLimiter.java new file mode 100644 index 000000000..a177a8210 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/ratelimit/BucketRateLimiter.java @@ -0,0 +1,98 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.ratelimit; + +import com.github.benmanes.caffeine.cache.Caffeine; +import com.github.benmanes.caffeine.cache.LoadingCache; +import com.github.benmanes.caffeine.cache.Scheduler; +import com.nvidia.boot.exceptions.TooManyRequestsException; +import io.github.bucket4j.Bandwidth; +import io.github.bucket4j.Bucket; +import io.github.bucket4j.ConsumptionProbe; +import java.time.Duration; +import java.util.Objects; +import java.util.UUID; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; + +@Slf4j +public class BucketRateLimiter { + + private static final String MESG_BLANK_PARAMETER = "'%s' cannot be blank"; + private static final String MSG_ACCOUNT_PREFIX = "Account '%s'"; + private static final String MSG_TASK_PREFIX = "Task id '%s'"; + private static final String MSG_TOO_MANY_REQUESTS = + "%s: Too many requests. Slow down."; + private static final String MSG_CONSUMED_TOKEN = + "{}: consumed-tokens '{}', remaining-tokens '{}'"; + private static final String MSG_NEW_BUCKET = + "{}: Creating a new bucket with bandwidth '{}' per second"; + private static final String MESG_CANNOT_BE_NULL = "Parameter '%s' cannot be null"; + + private final LoadingCache bucketMap; + + private record CacheKey(String id, long bandwidthPerSecond, String msgPrefix) { + + } + + BucketRateLimiter() { + bucketMap = Caffeine.newBuilder() + .maximumSize(10_000) + .expireAfterWrite(Duration.ofMinutes(10)) + .scheduler(Scheduler.systemScheduler()) + .recordStats() + .build(BucketRateLimiter::newBucket); + } + + public void accountLimit(String ncaId, long allowedInvocations) { + if (StringUtils.isBlank(ncaId)) { + var mesg = MESG_BLANK_PARAMETER.formatted("ncaId"); + log.error(mesg); + throw new IllegalArgumentException(mesg); + } + + verifyCall(ncaId, allowedInvocations, String.format(MSG_ACCOUNT_PREFIX, ncaId)); + } + + public void taskLimit(UUID taskId, long allowedInvocations) { + Objects.requireNonNull(taskId, () -> MESG_CANNOT_BE_NULL.formatted("taskId")); + verifyCall(taskId.toString(), allowedInvocations, + String.format(MSG_TASK_PREFIX, taskId)); + } + + private void verifyCall(String id, long bandwidthPerSecond, String msgPrefix) { + final Bucket bucket = bucketMap.get(new CacheKey(id, bandwidthPerSecond, msgPrefix)); + final ConsumptionProbe consumptionProbe = bucket.tryConsumeAndReturnRemaining(1); + final boolean consumed = consumptionProbe.isConsumed(); + log.debug(MSG_CONSUMED_TOKEN, msgPrefix, consumed, consumptionProbe.getRemainingTokens()); + if (!consumed) { + var msg = String.format(MSG_TOO_MANY_REQUESTS, msgPrefix); + log.error(msg); + throw new TooManyRequestsException(msg); + } + } + + private static Bucket newBucket(CacheKey key) { + log.debug(MSG_NEW_BUCKET, key.msgPrefix, key.bandwidthPerSecond); + return Bucket.builder() + .addLimit(Bandwidth.builder() + .capacity(key.bandwidthPerSecond) + .refillGreedy(key.bandwidthPerSecond, Duration.ofSeconds(1)) + .build()) + .build(); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/ratelimit/RateLimiterService.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/ratelimit/RateLimiterService.java new file mode 100644 index 000000000..896f5388f --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/ratelimit/RateLimiterService.java @@ -0,0 +1,60 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.ratelimit; + +import com.nvidia.nvct.configuration.ratelimit.AccountRateLimiterProperties; +import com.nvidia.nvct.configuration.ratelimit.TaskRateLimiterProperties; +import java.util.UUID; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +@Slf4j +@Service +public class RateLimiterService { + + private final AccountRateLimiterProperties accountProperties; + private final TaskRateLimiterProperties taskProperties; + private final BucketRateLimiter bucketRateLimiter; + + RateLimiterService(AccountRateLimiterProperties accountProperties, + TaskRateLimiterProperties taskProperties) { + this.accountProperties = accountProperties; + this.taskProperties = taskProperties; + bucketRateLimiter = new BucketRateLimiter(); + } + + public void verifyLimits(String ncaId, UUID taskId) { + verifyLimits(ncaId); + verifyLimits(taskId); + } + + public void verifyLimits(String ncaId) { + var defaultCappingProps = accountProperties.getDefaultRateCappingProperties(); + var rateCappingProps = accountProperties.getOverridesMap() + .getOrDefault(ncaId, defaultCappingProps); + var invocationsPerSecond = rateCappingProps.getAllowedInvocationsPerSecond(); + bucketRateLimiter.accountLimit(ncaId, invocationsPerSecond); + } + + public void verifyLimits(UUID taskId) { + var defaultCappingProps = taskProperties.getDefaultRateCappingProperties(); + var rateCappingProps = taskProperties.getTaskOverridesMap() + .getOrDefault(taskId, defaultCappingProps); + var invocationsPerSecond = rateCappingProps.getAllowedInvocationsPerSecond(); + bucketRateLimiter.taskLimit(taskId, invocationsPerSecond); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/registry/RegistryArtifactMapperService.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/registry/RegistryArtifactMapperService.java new file mode 100644 index 000000000..3a7bad5a0 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/registry/RegistryArtifactMapperService.java @@ -0,0 +1,53 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.registry; + +import com.nvidia.boot.registries.service.registry.dto.ArtifactDetails; +import com.nvidia.nvct.persistence.task.entity.ModelUdt; +import com.nvidia.nvct.persistence.task.entity.ResourceUdt; +import java.util.List; +import java.util.Set; +import lombok.AllArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@AllArgsConstructor +public class RegistryArtifactMapperService { + + public static ArtifactDetails toArtifactDetailsFromResourceUdt(ResourceUdt artifactUdt) { + return new ArtifactDetails(artifactUdt.getName(), artifactUdt.getVersion(), + artifactUdt.getUrl()); + } + + public static List toArtifactDetailsFromResourceUdts( + Set resourceUdts) { + return resourceUdts.stream() + .map(RegistryArtifactMapperService::toArtifactDetailsFromResourceUdt) + .toList(); + } + + public static ArtifactDetails toArtifactDetailsFromModelUdt(ModelUdt modelUdt) { + return new ArtifactDetails(modelUdt.getName(), modelUdt.getVersion(), + modelUdt.getUrl()); + } + + public static List toArtifactDetailsFromModelUdt(Set modelUdts) { + return modelUdts.stream() + .map(RegistryArtifactMapperService::toArtifactDetailsFromModelUdt) + .toList(); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/registry/RegistryArtifactService.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/registry/RegistryArtifactService.java new file mode 100644 index 000000000..f0566166b --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/registry/RegistryArtifactService.java @@ -0,0 +1,247 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.registry; + +import static com.nvidia.boot.registries.service.registry.dto.ArtifactTypeEnum.MODEL; +import static com.nvidia.boot.registries.service.registry.dto.ArtifactTypeEnum.RESOURCE; + +import com.github.benmanes.caffeine.cache.Caffeine; +import com.github.benmanes.caffeine.cache.LoadingCache; +import com.github.benmanes.caffeine.cache.Scheduler; +import com.google.common.annotations.VisibleForTesting; +import com.nvidia.boot.exceptions.BadRequestException; +import com.nvidia.boot.registries.service.registry.dto.Artifact; +import com.nvidia.boot.registries.service.registry.dto.ArtifactTypeEnum; +import com.nvidia.boot.registries.service.registry.model.ModelRegistryService; +import com.nvidia.boot.registries.service.registry.resource.ResourceRegistryService; +import com.nvidia.nvct.persistence.task.entity.ModelUdt; +import com.nvidia.nvct.persistence.task.entity.ResourceUdt; +import com.nvidia.nvct.persistence.task.entity.TaskEntity; +import com.nvidia.nvct.service.task.TaskService; +import java.time.Duration; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.Set; +import java.util.UUID; +import java.util.stream.Stream; +import lombok.AllArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.codec.digest.DigestUtils; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; + +@Slf4j +@Service +@AllArgsConstructor +public class RegistryArtifactService { + public static final Duration ICMS_MAX_REQUEST_DURATION = Duration.ofMinutes(32); + + private static final int CACHE_HANDLE_LENGTH = 32; + private static final String NO_ARTIFACT_TRIMMED_SHA256 = "e3b0c44298fc1c149afbf4c8996fb924"; + private static final List ARTIFACT_TYPES = List.of(MODEL, RESOURCE); + + private static final String MESG_COMMON_ERROR_PREFIX = + "Account '%s', Task '%s': "; + private static final String MESG_WRONG_IMPLEMENTATION_GET_ARTIFACTS_SIZE = + "Only resource or model registries support 'getArtifactSize' method. " + + "Input registry type is %s"; + private static final String MESG_WRONG_IMPLEMENTATION_FETCH_ARTIFACTS = + "Only resource or model registries support 'fetchArtifacts' method. " + + "Input registry type is %s"; + + private final RegistryCredentialService registryCredentialService; + private final ModelRegistryService modelRegistryService; + private final ResourceRegistryService resourceRegistryService; + private final RegistryArtifactValidationService registryArtifactValidationService; + private final TaskService taskService; + + public record ArtifactCacheKey(String ncaId, UUID taskId) { + } + + private final LoadingCache> artifactsPresignedUrlsCache = + Caffeine.newBuilder() + .maximumSize(512) + .scheduler(Scheduler.systemScheduler()) + .expireAfterWrite(ICMS_MAX_REQUEST_DURATION) + .build(this::fetchPresignedUrls); + + private final LoadingCache artifactsSizeCache = + Caffeine.newBuilder() + .maximumSize(512) + .scheduler(Scheduler.systemScheduler()) + .expireAfterWrite(ICMS_MAX_REQUEST_DURATION) + .build(this::fetchSize); + + private final LoadingCache artifactsCacheHandleCache = + Caffeine.newBuilder() + .maximumSize(512) + .scheduler(Scheduler.systemScheduler()) + .expireAfterWrite(ICMS_MAX_REQUEST_DURATION) + .build(this::generateCacheHandle); + + + public List getPresignedUrls(String ncaId, UUID taskId) { + return artifactsPresignedUrlsCache.get(new ArtifactCacheKey(ncaId, taskId)); + } + + public long getSize(String ncaId, UUID taskId) { + return artifactsSizeCache.get(new ArtifactCacheKey(ncaId, taskId)); + } + + public String getCacheHandle(String ncaId, UUID taskId) { + return artifactsCacheHandleCache.get(new ArtifactCacheKey(ncaId, taskId)); + } + + public void validateArtifacts(TaskEntity taskEntity) { + registryArtifactValidationService.validateArtifacts(taskEntity); + } + + @VisibleForTesting + public void invalidateCache() { + artifactsPresignedUrlsCache.invalidateAll(); + artifactsSizeCache.invalidateAll(); + artifactsCacheHandleCache.invalidateAll(); + } + + private String generateCacheHandle(ArtifactCacheKey cacheKey) { + var taskId = cacheKey.taskId; + Comparator modelUdtComparator = Comparator.comparing(ModelUdt::getUrl); + Comparator resourceUdtComparator = Comparator.comparing(ResourceUdt::getUrl); + var taskEntity = taskService.fetchTask(taskId); + var models = CollectionUtils.isEmpty(taskEntity.getModels()) + ? Set.of() : taskEntity.getModels(); + var resources = CollectionUtils.isEmpty(taskEntity.getResources()) + ? Set.of() : taskEntity.getResources(); + var hashes = Stream.concat(models.stream().sorted(modelUdtComparator), + resources.stream().sorted(resourceUdtComparator)) + .map(artifactUdt -> DigestUtils.sha256(artifactUdt.getUrl())) + .toList(); + if (hashes.isEmpty()) { + return NO_ARTIFACT_TRIMMED_SHA256; + } + var messageDigest = DigestUtils.getSha256Digest(); + for (var hash : hashes) { + messageDigest = DigestUtils.updateDigest(messageDigest, hash); + } + return DigestUtils.sha256Hex(messageDigest.digest()).substring(0, CACHE_HANDLE_LENGTH); + } + + private long getArtifactSize(TaskEntity taskEntity) { + return ARTIFACT_TYPES.stream() + .map(registryType -> fetchSize(taskEntity, registryType)) + .mapToLong(Long::longValue) + .sum(); + } + + private long fetchSize(ArtifactCacheKey cacheKey) { + var taskEntity = taskService.fetchTask(cacheKey.taskId); + return getArtifactSize(taskEntity); + } + + private long fetchSize(TaskEntity taskEntity, ArtifactTypeEnum registryType) { + var taskId = taskEntity.getTaskId(); + var ncaId = taskEntity.getNcaId(); + + try { + if (MODEL == registryType) { + if (CollectionUtils.isEmpty(taskEntity.getModels())) { + return 0L; + } + var secrets = + registryCredentialService.getModelRegistryCredentialsValue(taskEntity); + var models = RegistryArtifactMapperService.toArtifactDetailsFromModelUdt( + taskEntity.getModels()); + return modelRegistryService.fetchSize(models, secrets); + } else if (RESOURCE == registryType) { + if (CollectionUtils.isEmpty(taskEntity.getResources())) { + return 0L; + } + var secrets = + registryCredentialService.getResourceRegistryCredentialsValue(taskEntity); + var resources = RegistryArtifactMapperService.toArtifactDetailsFromResourceUdts( + taskEntity.getResources()); + return resourceRegistryService.fetchSize(resources, secrets); + } else { + var errMsg = + MESG_WRONG_IMPLEMENTATION_GET_ARTIFACTS_SIZE.formatted(registryType); + log.error(errMsg); + throw new IllegalStateException(errMsg); + } + } catch (IllegalStateException | IllegalArgumentException e) { + var enrichedErrorMsg = + MESG_COMMON_ERROR_PREFIX.formatted(ncaId, taskId) + e.getMessage(); + log.error(enrichedErrorMsg); + throw new BadRequestException(enrichedErrorMsg, e); + } catch (Exception e) { + var enrichedErrorMsg = + MESG_COMMON_ERROR_PREFIX.formatted(ncaId, taskId) + e.getMessage(); + log.error(enrichedErrorMsg); + throw e; + } + } + + private List fetchArtifacts(TaskEntity taskEntity) { + return ARTIFACT_TYPES.stream() + .flatMap(artifactType -> fetchArtifacts(taskEntity, artifactType).stream()) + .toList(); + } + + private List fetchArtifacts(TaskEntity taskEntity, ArtifactTypeEnum artifactType) { + var taskId = taskEntity.getTaskId(); + var ncaId = taskEntity.getNcaId(); + try { + if (MODEL == artifactType) { + if (CollectionUtils.isEmpty(taskEntity.getModels())) { + return Collections.emptyList(); + } + var secrets = + registryCredentialService.getModelRegistryCredentialsValue(taskEntity); + var models = RegistryArtifactMapperService.toArtifactDetailsFromModelUdt( + taskEntity.getModels()); + return modelRegistryService.fetchArtifact(models, secrets); + } else if (RESOURCE == artifactType) { + if (CollectionUtils.isEmpty(taskEntity.getResources())) { + return Collections.emptyList(); + } + var secrets = + registryCredentialService.getResourceRegistryCredentialsValue(taskEntity); + var resources = RegistryArtifactMapperService + .toArtifactDetailsFromResourceUdts(taskEntity.getResources()); + return resourceRegistryService.fetchArtifact(resources, secrets); + } else { + throw new IllegalStateException( + MESG_WRONG_IMPLEMENTATION_FETCH_ARTIFACTS.formatted(artifactType)); + } + } catch (IllegalStateException | IllegalArgumentException e) { + var enrichedErrorMsg = + MESG_COMMON_ERROR_PREFIX.formatted(ncaId, taskId) + e.getMessage(); + log.error(enrichedErrorMsg); + throw new BadRequestException(enrichedErrorMsg, e); + } catch (Exception e) { + var enrichedErrorMsg = + MESG_COMMON_ERROR_PREFIX.formatted(ncaId, taskId) + e.getMessage(); + log.error(enrichedErrorMsg); + throw e; + } + } + + private List fetchPresignedUrls(ArtifactCacheKey cacheKey) { + var taskEntity = taskService.fetchTask(cacheKey.taskId); + return fetchArtifacts(taskEntity); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/registry/RegistryArtifactValidationService.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/registry/RegistryArtifactValidationService.java new file mode 100644 index 000000000..c31ebdc62 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/registry/RegistryArtifactValidationService.java @@ -0,0 +1,226 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.registry; + +import static com.nvidia.boot.registries.service.registry.dto.ArtifactTypeEnum.CONTAINER; +import static com.nvidia.boot.registries.service.registry.dto.ArtifactTypeEnum.HELM; +import static com.nvidia.boot.registries.service.registry.dto.ArtifactTypeEnum.MODEL; +import static com.nvidia.boot.registries.service.registry.dto.ArtifactTypeEnum.RESOURCE; + +import com.nvidia.boot.exceptions.BadRequestException; +import com.nvidia.boot.exceptions.ForbiddenException; +import com.nvidia.boot.exceptions.NotFoundException; +import com.nvidia.boot.exceptions.TooManyRequestsException; +import com.nvidia.boot.exceptions.UnauthorizedException; +import com.nvidia.boot.registries.service.registry.RegistryValidationService; +import com.nvidia.boot.registries.service.registry.container.ContainerRegistryService; +import com.nvidia.boot.registries.service.registry.dto.ArtifactTypeEnum; +import com.nvidia.boot.registries.service.registry.helm.HelmRegistryService; +import com.nvidia.boot.registries.service.registry.model.ModelRegistryService; +import com.nvidia.boot.registries.service.registry.resource.ResourceRegistryService; +import com.nvidia.nvct.persistence.task.entity.TaskEntity; +import com.nvidia.nvct.service.account.dto.RegistryCredentialDto; +import java.util.EnumSet; +import java.util.List; +import java.util.Set; +import lombok.extern.slf4j.Slf4j; +import org.apache.logging.log4j.util.Strings; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.cloud.context.config.annotation.RefreshScope; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; + +@Slf4j +@RefreshScope +@Service +public class RegistryArtifactValidationService { + private static final String MESG_COMMON_ERROR_PREFIX = + "Account '%s', Task '%s': "; + private static final String MESG_WRONG_IMPLEMENTATION_VALIDATE_ARTIFACTS = + "Only container, helm, resource or model registry support 'validateArtifact'" + + " method. Input registry type is %s"; + private static final String MESG_ARTIFACT_INVALID = + "Task '%s': Invalid artifact provided"; + private static final String MESG_ARTIFACT_VALIDATION = + "Task '{}': {} artifacts"; + private static final String MESG_LOG_ARTIFACT_VALIDATION = + "Artifact validation is enabled but exception is not being thrown for " + + "invalid artifact so that Task creation can proceed"; + private static final String MESG_MISSING_REGISTRY_CREDENTIALS = + "Missing %s registry credential for hostname '%s'"; + + private final RegistryCredentialService registryCredentialService; + private final RegistryValidationService registryValidationService; + private final ModelRegistryService modelRegistryService; + private final ResourceRegistryService resourceRegistryService; + private final HelmRegistryService helmRegistryService; + private final ContainerRegistryService containerRegistryService; + private final String exceptionHandlingDuringArtifactValidation; + + public RegistryArtifactValidationService( + RegistryCredentialService registryCredentialService, + RegistryValidationService registryValidationService, + ModelRegistryService modelRegistryService, + ResourceRegistryService resourceRegistryService, + HelmRegistryService helmRegistryService, + ContainerRegistryService containerRegistryService, + @Value("${nvct.registries.artifact-validation.exception-handling:throw}") // throw, log + String exceptionHandlingDuringArtifactValidation) { + this.registryCredentialService = registryCredentialService; + this.registryValidationService = registryValidationService; + this.modelRegistryService = modelRegistryService; + this.resourceRegistryService = resourceRegistryService; + this.helmRegistryService = helmRegistryService; + this.containerRegistryService = containerRegistryService; + this.exceptionHandlingDuringArtifactValidation = exceptionHandlingDuringArtifactValidation; + } + + public void validateArtifacts(TaskEntity taskEntity) { + try { + log.info(MESG_ARTIFACT_VALIDATION, taskEntity.getTaskId(), "Validating"); + validateCredentialsExist(taskEntity); + validateArtifacts(taskEntity, EnumSet.of( + MODEL, + RESOURCE, + HELM, + CONTAINER)); + log.info(MESG_ARTIFACT_VALIDATION, taskEntity.getTaskId(), "Validated"); + } catch (BadRequestException | NotFoundException | UnauthorizedException | + ForbiddenException | TooManyRequestsException e) { + var taskId = taskEntity.getTaskId(); + var errMsg = MESG_ARTIFACT_INVALID.formatted(taskId); + log.error(errMsg, e); + if (exceptionHandlingDuringArtifactValidation.equals("throw")) { + throw e; + } else { + // Just log a warning and let the request continue so that function creation + // or deployment can proceed. + log.warn(MESG_LOG_ARTIFACT_VALIDATION); + } + } + } + + public void validateArtifacts(TaskEntity taskEntity, + Set artifactTypes) { + artifactTypes.forEach(artifactType -> validateArtifacts(taskEntity, artifactType)); + } + + private void validateArtifacts(TaskEntity taskEntity, ArtifactTypeEnum artifactType) { + var taskId = taskEntity.getTaskId(); + var ncaId = taskEntity.getNcaId(); + + try { + if (MODEL == artifactType) { + if (CollectionUtils.isEmpty(taskEntity.getModels())) { + return; + } + var secrets = registryCredentialService + .getModelRegistryCredentialsValue(taskEntity); + var modelArtifactDetails = RegistryArtifactMapperService + .toArtifactDetailsFromModelUdt(taskEntity.getModels()); + modelRegistryService.validateArtifacts(modelArtifactDetails, secrets); + } else if (RESOURCE == artifactType) { + if (CollectionUtils.isEmpty(taskEntity.getResources())) { + return; + } + var secrets = registryCredentialService + .getResourceRegistryCredentialsValue(taskEntity); + var resourceArtifactDetails = RegistryArtifactMapperService + .toArtifactDetailsFromResourceUdts(taskEntity.getResources()); + resourceRegistryService.validateArtifacts(resourceArtifactDetails, secrets); + } else if (HELM == artifactType) { + if (Strings.isBlank(taskEntity.getHelmChart())) { + return; + } + var secrets = registryCredentialService.getHelmRegistryCredentialsValue(taskEntity); + helmRegistryService.validateArtifact(taskEntity.getHelmChart(), secrets); + } else if (CONTAINER == artifactType) { + if (Strings.isBlank(taskEntity.getContainerImage())) { + return; + } + var secrets = registryCredentialService + .getContainerRegistryCredentialsValue(taskEntity); + containerRegistryService.validateArtifact(taskEntity.getContainerImage(), secrets); + } else { + var mesg = MESG_WRONG_IMPLEMENTATION_VALIDATE_ARTIFACTS.formatted(artifactType); + log.error(mesg); + throw new IllegalStateException(mesg); + } + } catch (IllegalStateException | IllegalArgumentException e) { + var commonPrefix = MESG_COMMON_ERROR_PREFIX.formatted(ncaId, taskId); + var enrichedErrorMsg = + e.getMessage() != null && e.getMessage().startsWith(commonPrefix) ? + e.getMessage() : commonPrefix + e.getMessage(); + log.error(enrichedErrorMsg); + throw new BadRequestException(enrichedErrorMsg, e); + } catch (Exception e) { + var commonPrefix = MESG_COMMON_ERROR_PREFIX.formatted(ncaId, taskId); + var enrichedErrorMsg = + e.getMessage() != null && e.getMessage().startsWith(commonPrefix) ? + e.getMessage() : commonPrefix + e.getMessage(); + log.error(enrichedErrorMsg); + throw e; + } + } + + public void validateContainerRegistryCredentialsExist(TaskEntity task) { + if (Strings.isBlank(task.getContainerImage())) return; + var creds = registryCredentialService.getContainerRegistryCredentials(task); + var hostname = registryCredentialService.getRegistryHostname(task.getContainerImage()); + validateCredentialsExist(CONTAINER, hostname, creds); + } + + public void validateHelmRegistryCredentialsExist(TaskEntity task) { + if (Strings.isBlank(task.getHelmChart())) return; + var creds = registryCredentialService.getHelmRegistryCredentials(task); + var hostname = registryCredentialService.getHelmRegistryHostname(task.getHelmChart()); + validateCredentialsExist(HELM, hostname, creds); + } + + private void validateCredentialsExist( + ArtifactTypeEnum artifactType, + String hostname, + List credentials) { + if (!registryValidationService.isArtifactValidationEnabled(artifactType, hostname)) { + return; + } + + // Gets here if artifact-validation is enabled. If there are registry creds for the + // hostname, then we don't have to throw IllegalStateException with missing registry + // credential message. + if (!CollectionUtils.isEmpty(credentials)) { + return; + } + var mesg = MESG_MISSING_REGISTRY_CREDENTIALS.formatted(artifactType, hostname); + log.error(mesg); + throw new IllegalStateException(mesg); + } + + private void validateCredentialsExist(TaskEntity taskEntity) { + try { + validateContainerRegistryCredentialsExist(taskEntity); + validateHelmRegistryCredentialsExist(taskEntity); + registryCredentialService.getModelRegistryCredentials(taskEntity); + registryCredentialService.getResourceRegistryCredentials(taskEntity); + } catch (Exception e) { + if (e instanceof BadRequestException badrequestexception) throw badrequestexception; + log.error(e.getMessage(), e); + throw new BadRequestException(e.getMessage(), e); + } + } + +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/registry/RegistryCredentialService.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/registry/RegistryCredentialService.java new file mode 100644 index 000000000..a1e485cca --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/registry/RegistryCredentialService.java @@ -0,0 +1,360 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.registry; + +import static com.nvidia.boot.registries.service.registry.dto.ArtifactTypeEnum.CONTAINER; + +import tools.jackson.core.JacksonException; +import tools.jackson.databind.json.JsonMapper; +import com.google.common.collect.Sets; +import com.nvidia.boot.registries.service.registry.RegistryMapperService; +import com.nvidia.boot.registries.service.registry.dto.ArtifactTypeEnum; +import com.nvidia.nvct.persistence.task.entity.TaskEntity; +import com.nvidia.nvct.service.account.AccountService; +import com.nvidia.nvct.service.account.dto.RegistryCredentialDto; +import com.nvidia.nvct.service.registry.dto.DockerConfigJsonAuthDto; +import com.nvidia.nvct.service.registry.dto.DockerConfigJsonDto; +import com.nvidia.nvct.service.registry.dto.K8sSecretsDto; +import java.net.URI; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import org.apache.logging.log4j.util.Strings; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; + +@Service +@Slf4j +public class RegistryCredentialService { + private static final String MESG_COMMON_ERROR_PREFIX = + "Account '%s', Task '%s': "; + private static final String MESG_MISSING_REGISTRY = + MESG_COMMON_ERROR_PREFIX + "Missing %s registry for hostname '%s'"; + private static final String MESG_FAIL_TO_ENCODE_SECRETS = + MESG_COMMON_ERROR_PREFIX + "Failed to encode secrets"; + private static final String MESG_INVALID_REGISTRY_URL = "Invalid registry URL: %s"; + + private final AccountService accountService; + private final RegistryMapperService registryMapperService; + private final RegistryTaskMapperService registryTaskMapperService; + private final JsonMapper jsonMapper; + private final String sidecarImagePullSecret; + private final String sidecarRegistryHostname; + + public RegistryCredentialService( + AccountService accountService, + RegistryMapperService registryMapperService, + RegistryTaskMapperService registryTaskMapperService, + JsonMapper jsonMapper, + @Value("${nvct.sidecars.image-pull-secret}") + String sidecarImagePullSecret, + @Value("${nvct.sidecars.hostname}") + String sidecarRegistryHostname) { + this.accountService = accountService; + this.registryTaskMapperService = registryTaskMapperService; + this.registryMapperService = registryMapperService; + this.jsonMapper = jsonMapper; + this.sidecarImagePullSecret = sidecarImagePullSecret; + this.sidecarRegistryHostname = sidecarRegistryHostname; + } + + public String getBase64EncodedSidecarRegistryImagePullSecret(TaskEntity taskEntity) { + var dockerConfigJsonDto = DockerConfigJsonDto.builder() + .auths(Map.of( + this.sidecarRegistryHostname, + DockerConfigJsonAuthDto.builder() + .auth(this.sidecarImagePullSecret) + .build() + )) + .build(); + return base64Encode(taskEntity, dockerConfigJsonDto); + } + + public List getRegistryCredentials(TaskEntity task, + String hostname, + ArtifactTypeEnum artifactTypeEnum) { + var account = accountService.getAccount(task.getNcaId()); + if (CollectionUtils.isEmpty(account.registryCredentials())) { + return Collections.emptyList(); + } + var normalizedHostname = registryMapperService.toNormalizedHostname(hostname); + return account.registryCredentials().stream() + .filter(rc -> rc.artifactTypes().contains(artifactTypeEnum) && + rc.registryHostname().equals(normalizedHostname)) + .toList(); + } + + private List getRegistryCredentials( + TaskEntity task, + Set artifactTypeEnums) { + var account = accountService.getAccount(task.getNcaId()); + if (CollectionUtils.isEmpty(account.registryCredentials())) { + return Collections.emptyList(); + } + return account.registryCredentials().stream() + .filter(regCred -> !Sets + .intersection(regCred.artifactTypes(), artifactTypeEnums) + .isEmpty()) + .toList(); + } + + public String getRegistryHostname(String artifactUrl) { + // WAR for using URI lib to parse url host, since image url won't include protocol prefix. + var normalizedArtifactUrl = + !artifactUrl.startsWith("http") ? "https://" + artifactUrl : artifactUrl; + return Optional.ofNullable(URI.create(normalizedArtifactUrl).getHost()) + .orElseThrow(() -> new IllegalStateException( + MESG_INVALID_REGISTRY_URL.formatted(artifactUrl))); + } + + public String getHelmRegistryHostname(String artifactUrl) { + var uri = URI.create(artifactUrl); + var scheme = uri.getScheme(); + + // Validate scheme - only allow http, https, oci + if (scheme == null || + !scheme.equals("http") && !scheme.equals("https") && !scheme.equals("oci")) { + throw new IllegalStateException( + MESG_INVALID_REGISTRY_URL.formatted(artifactUrl)); + } + + return Optional.ofNullable(uri.getHost()) + .orElseThrow(() -> new IllegalStateException( + MESG_INVALID_REGISTRY_URL.formatted(artifactUrl))); + } + + @SneakyThrows + public List getModelRegistriesHostnames(TaskEntity task) { + var models = task.getModels(); + if (CollectionUtils.isEmpty(models)) { + return Collections.emptyList(); + } + + return models.stream() + .map(model -> getRegistryHostname(model.getUrl())) + .toList(); + } + + @SneakyThrows + public List getResourceRegistriesHostnames(TaskEntity task) { + var resources = task.getResources(); + if (CollectionUtils.isEmpty(resources)) { + return Collections.emptyList(); + } + + return resources.stream() + .map(resource -> getRegistryHostname(resource.getUrl())) + .toList(); + } + + private K8sSecretsDto getRegistryImagePullSecrets( + List registryCredentials) { + K8sSecretsDto k8SSecretsDto = K8sSecretsDto.builder().k8sSecrets(new ArrayList<>()).build(); + registryCredentials.forEach(registry -> { + var hostname = registry.registryHostname(); + var secret = registry.secret().value().asString(); + var dockerConfigJsonRegistryCredentialDto = DockerConfigJsonAuthDto + .builder() + .auth(secret) + .build(); + k8SSecretsDto.k8sSecrets().add( + DockerConfigJsonDto.builder().auths( + Map.of(hostname, dockerConfigJsonRegistryCredentialDto)).build()); + }); + return k8SSecretsDto; + } + + public List getContainerRegistryCredentials(TaskEntity task) { + if (Strings.isNotBlank(task.getContainerImage())) { + var containerRegistryHostname = getRegistryHostname(task.getContainerImage()); + var registryCredentials = + getRegistryCredentials(task, containerRegistryHostname, CONTAINER); + // For Container-based task. Return container registry credentials whose hostname + // matches the hostname specified in the task definition. + return registryCredentials.stream() + .map(dto -> { + if (RegistryMapperService.isCanaryHostname(containerRegistryHostname)) { + return registryTaskMapperService + .toRegistryCredentialDtoWithCanaryHostname(dto); + } + return dto; + }) + .toList(); + } + // Helm-based task. Return all the container registry credentials associated with the + // account and duplicated NGC registry with canary alias hostname, since we don't know + // which registry hostname is in use by the helm chart. + return getRegistryCredentials(task, Set.of(CONTAINER)).stream() + .flatMap(registryTaskMapperService::expandRegistryCredentialWithCanaryHostname) + .toList(); + } + + public List getContainerRegistryCredentialsValue(TaskEntity taskEntity) { + return getContainerRegistryCredentials(taskEntity) + .stream().map(x -> x.secret().value().asString()) + .toList(); + } + + public K8sSecretsDto getContainerRegistryImagePullSecrets(TaskEntity task) { + var containerRegistryCredentials = getContainerRegistryCredentials(task); + return getRegistryImagePullSecrets(containerRegistryCredentials); + } + + public List getHelmRegistryCredentials(TaskEntity task) { + + if (Strings.isNotBlank(task.getHelmChart())) { + var helmRegistryHostname = getHelmRegistryHostname(task.getHelmChart()); + return getRegistryCredentials(task, helmRegistryHostname, + ArtifactTypeEnum.HELM).stream() + .map(dto -> { + if (RegistryMapperService.isCanaryHostname(helmRegistryHostname)) { + return registryTaskMapperService + .toRegistryCredentialDtoWithCanaryHostname(dto); + } + return dto; + }) + .toList(); + } + // Container-based function. + return Collections.emptyList(); + } + + public List getHelmRegistryCredentialsValue(TaskEntity taskEntity) { + return getHelmRegistryCredentials(taskEntity) + .stream().map(x -> x.secret().value().asString()) + .toList(); + } + + public K8sSecretsDto getHelmRegistryImagePullSecrets(TaskEntity task) { + var helmRegistryCredentials = getHelmRegistryCredentials(task); + return getRegistryImagePullSecrets(helmRegistryCredentials); + } + + public Map> getModelRegistryCredentials(TaskEntity task) { + var ncaId = task.getNcaId(); + var taskId = task.getTaskId(); + var normalizedModelRegistriesHostnames = getModelRegistriesHostnames(task); + if (normalizedModelRegistriesHostnames.isEmpty()) { + return Collections.emptyMap(); + } + var modelRegistryCredentials = normalizedModelRegistriesHostnames.stream() + .map(hostname -> { + var registryCredentials = + getRegistryCredentials(task, hostname, ArtifactTypeEnum.MODEL); + + if (CollectionUtils.isEmpty(registryCredentials)) { + var mesg = MESG_MISSING_REGISTRY.formatted(ncaId, taskId, + ArtifactTypeEnum.MODEL, + hostname); + log.error(mesg); + throw new IllegalStateException(mesg); + } + return registryCredentials; + }) + .flatMap(Collection::stream) + .toList(); + return modelRegistryCredentials.stream() + .flatMap(registryTaskMapperService::expandRegistryCredentialWithCanaryHostname) + .collect(Collectors.groupingBy(RegistryCredentialDto::registryHostname)); + } + + public Map> getModelRegistryCredentialsValue(TaskEntity taskEntity) { + return getModelRegistryCredentials(taskEntity).entrySet() + .stream() + .collect(Collectors.toMap( + Map.Entry::getKey, + x -> x.getValue().stream() + .map(registryCredentialDto -> + registryCredentialDto + .secret().value().asString()) + .toList())); + } + + public Map> getResourceRegistryCredentials( + TaskEntity task) { + var ncaId = task.getNcaId(); + var taskId = task.getTaskId(); + var normalizedResourceRegistriesHostnames = getResourceRegistriesHostnames(task); + if (normalizedResourceRegistriesHostnames.isEmpty()) { + return Collections.emptyMap(); + } + var resourceRegistryCredentials = normalizedResourceRegistriesHostnames.stream() + .map(hostname -> { + var registryCredentials = + getRegistryCredentials(task, hostname, ArtifactTypeEnum.RESOURCE); + + if (CollectionUtils.isEmpty(registryCredentials)) { + var mesg = MESG_MISSING_REGISTRY.formatted(ncaId, taskId, + ArtifactTypeEnum.RESOURCE, + hostname); + log.error(mesg); + throw new IllegalStateException(mesg); + } + return registryCredentials; + }) + .flatMap(Collection::stream) + .toList(); + return resourceRegistryCredentials.stream() + .flatMap(registryTaskMapperService::expandRegistryCredentialWithCanaryHostname) + .collect(Collectors.groupingBy(RegistryCredentialDto::registryHostname)); + } + + public Map> getResourceRegistryCredentialsValue( + TaskEntity taskEntity) { + return getResourceRegistryCredentials(taskEntity).entrySet() + .stream() + .collect(Collectors.toMap( + Map.Entry::getKey, + x -> x.getValue().stream() + .map(registryCredentialDto -> + registryCredentialDto + .secret().value().asString()) + .toList())); + } + + public String getBase64EncodedContainerRegistryImagePullSecrets(TaskEntity task) { + var k8SSecretsDto = getContainerRegistryImagePullSecrets(task); + return base64Encode(task, k8SSecretsDto); + } + + public String getBase64EncodedHelmRegistryImagePullSecrets(TaskEntity task) { + var k8SSecretsDto = getHelmRegistryImagePullSecrets(task); + return base64Encode(task, k8SSecretsDto); + } + + private String base64Encode(TaskEntity task, Object secrets) { + var taskId = task.getTaskId(); + var ncaId = task.getNcaId(); + + try { + var jsonString = jsonMapper.writeValueAsString(secrets); + return java.util.Base64.getEncoder().encodeToString(jsonString.getBytes()); + } catch (JacksonException e) { + var msg = MESG_FAIL_TO_ENCODE_SECRETS.formatted(ncaId, taskId); + log.error(msg); + throw new IllegalArgumentException(msg); + } + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/registry/RegistryTaskMapperService.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/registry/RegistryTaskMapperService.java new file mode 100644 index 000000000..cf1f52b04 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/registry/RegistryTaskMapperService.java @@ -0,0 +1,50 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.registry; + +import com.nvidia.boot.registries.service.registry.RegistryMapperService; +import com.nvidia.nvct.service.account.dto.RegistryCredentialDto; +import java.util.stream.Stream; +import lombok.AllArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@AllArgsConstructor +public class RegistryTaskMapperService { + private final RegistryMapperService registryMapperService; + + public Stream expandRegistryCredentialWithCanaryHostname( + RegistryCredentialDto registryCredentialDto) { + var originalHostname = registryCredentialDto.registryHostname(); + var canaryHostname = registryMapperService.toCanaryHostname(originalHostname); + + if (canaryHostname.equals(originalHostname)) { + return Stream.of(registryCredentialDto); + } + return Stream.of( + registryCredentialDto, + toRegistryCredentialDtoWithCanaryHostname(registryCredentialDto)); + } + + public RegistryCredentialDto toRegistryCredentialDtoWithCanaryHostname( + RegistryCredentialDto registryDetailsDto) { + return registryDetailsDto.toBuilder() + .registryHostname(registryMapperService + .toCanaryHostname(registryDetailsDto.registryHostname())) + .build(); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/registry/dto/DockerConfigJsonAuthDto.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/registry/dto/DockerConfigJsonAuthDto.java new file mode 100644 index 000000000..9e84c5d09 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/registry/dto/DockerConfigJsonAuthDto.java @@ -0,0 +1,28 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.registry.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotBlank; +import lombok.Builder; + +@Builder +@Schema(description = "dockerconfigjson registry auth object") +public record DockerConfigJsonAuthDto( + @Schema() + @NotBlank String auth) { +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/registry/dto/DockerConfigJsonDto.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/registry/dto/DockerConfigJsonDto.java new file mode 100644 index 000000000..fa0154817 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/registry/dto/DockerConfigJsonDto.java @@ -0,0 +1,29 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.registry.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import java.util.Map; +import lombok.Builder; + +@Builder +@Schema(description = "Object of dockerconfigjson") +public record DockerConfigJsonDto( + @Schema(description = "K8s secret in dockerconfigjson format") + @NotNull Map auths) { +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/registry/dto/K8sSecretsDto.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/registry/dto/K8sSecretsDto.java new file mode 100644 index 000000000..440ea4e2e --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/registry/dto/K8sSecretsDto.java @@ -0,0 +1,29 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.registry.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotNull; +import java.util.List; +import lombok.Builder; + +@Builder +@Schema(description = "Objects to create image-pull secrets using registry credentials") +public record K8sSecretsDto( + @Schema(description = "K8s secrets") + @NotNull List k8sSecrets) { +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/result/ResultService.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/result/ResultService.java new file mode 100644 index 000000000..19fc6922d --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/result/ResultService.java @@ -0,0 +1,191 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.result; + +import static com.datastax.oss.driver.api.core.data.ByteUtils.fromHexString; +import static com.datastax.oss.driver.api.core.data.ByteUtils.toHexString; +import static com.nvidia.nvct.util.NvctConstants.DEFAULT_PAGINATION_LIMIT; +import static com.nvidia.nvct.util.NvctConstants.MESG_INVALID_CURSOR; + +import tools.jackson.databind.json.JsonMapper; +import tools.jackson.databind.node.ObjectNode; +import com.google.common.annotations.VisibleForTesting; +import com.nvidia.boot.exceptions.BadRequestException; +import com.nvidia.boot.exceptions.ForbiddenException; +import com.nvidia.nvct.persistence.result.ResultsByTaskRepository; +import com.nvidia.nvct.persistence.result.entity.ResultByTaskEntity; +import com.nvidia.nvct.persistence.result.entity.ResultByTaskKey; +import com.nvidia.nvct.persistence.task.entity.ResultHandlingStrategy; +import com.nvidia.nvct.persistence.task.entity.TaskEntity; +import com.nvidia.nvct.rest.result.dto.ResultDto; +import com.nvidia.nvct.service.task.TaskService; +import java.time.Instant; +import java.util.List; +import java.util.Objects; +import java.util.UUID; +import java.util.function.Predicate; +import lombok.Builder; +import lombok.RequiredArgsConstructor; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.data.cassandra.core.query.CassandraPageRequest; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Slice; +import org.springframework.stereotype.Service; + +@Slf4j +@Service +@RequiredArgsConstructor +public class ResultService { + private static final String MESG_CANNOT_BE_NULL = "Parameter '%s' cannot be null"; + private static final String MESG_BLANK_PARAMETER = "'%s' cannot be blank"; + private static final String MESG_TASK_RESULT_OPERATION = + "Task id '{}': {}"; + private static final String MESG_TASK_RESULT_IGNORED = + "Task id '{}': Result ignored as resultHandlingStrategy is NONE"; + private static final String MESG_FORBIDDEN_TO_LIST_RESULTS = + "Task '%s': Forbidden to list results"; + + private final ResultsByTaskRepository resultsByTaskRepository; + private final TaskService taskService; + private final JsonMapper jsonMapper; + + @Builder + public record ResultsSliceContext(List results, String cursor, Integer limit) { } + + public ResultsSliceContext fetchResults(String ncaId, UUID taskId, int limit, String cursor, + Predicate taskAccessMatch) { + log.debug(MESG_TASK_RESULT_OPERATION, taskId, "Fetching results"); + var taskEntity = taskService.validateAccount(ncaId, taskId); + if (!taskAccessMatch.test(taskEntity)) { + var mesg = MESG_FORBIDDEN_TO_LIST_RESULTS.formatted(taskId); + log.error(mesg); + throw new ForbiddenException(mesg); + } + + Slice pagedResult; + try { + var byteBuffer = cursor == null ? null : fromHexString(cursor); + var pageable = PageRequest.of(0, limit); + var pageRequest = CassandraPageRequest.of(pageable, byteBuffer); + pagedResult = resultsByTaskRepository.findByKeyTaskId(taskId, pageRequest); + } catch (Exception e) { + var mesg = MESG_INVALID_CURSOR.formatted(cursor); + log.error(mesg); + throw new BadRequestException(mesg, e); + } + + var dtos = pagedResult.getContent().stream() + .map(this::toResultDto) + .toList(); + var builder = ResultsSliceContext.builder().results(dtos); + if (pagedResult.hasNext()) { + var pagingState = ((CassandraPageRequest) pagedResult.getPageable()).getPagingState(); + builder.cursor(toHexString(pagingState)); + builder.limit(limit); + } + + log.debug(MESG_TASK_RESULT_OPERATION, taskId, "Fetched results"); + return builder.build(); + } + + @VisibleForTesting + public List fetchResults(String ncaId, UUID taskId) { + var results = fetchResults(ncaId, taskId, Integer.parseInt(DEFAULT_PAGINATION_LIMIT), null, + taskEntity -> true); + return results.results(); + } + + public boolean deleteResults(String ncaId, UUID taskId) { + Objects.requireNonNull(taskId, () -> MESG_CANNOT_BE_NULL.formatted("taskId")); + if (StringUtils.isBlank(ncaId)) { + var mesg = MESG_BLANK_PARAMETER.formatted("ncaId"); + log.error(mesg); + throw new IllegalArgumentException(mesg); + } + + // If the Task was deleted but for some reason results were not deleted, then don't + // throw an exception and continue deleting results. + taskService.lookupTask(taskId).ifPresent(task -> taskService.validateAccount(ncaId, task)); + resultsByTaskRepository.deleteByKeyTaskId(taskId); + log.info(MESG_TASK_RESULT_OPERATION, taskId, "Deleted results"); + return true; + } + + public ResultByTaskEntity insertResult( + TaskEntity taskEntity, + String name, + String metadata) { + var ncaId = taskEntity.getNcaId(); + var taskId = taskEntity.getTaskId(); + taskService.validateAccount(ncaId, taskId); + if (taskEntity.getResultHandlingStrategy() == ResultHandlingStrategy.NONE) { + // If resultHandlingStrategy is NONE, we will ignore calls to insert an entry + // in the results_by_task table. This can happen when the Task Container + // updates progress file with just percentComplete set to 100 to indicate + // a graceful exit so that Utils Container can mark the Task as COMPLETED. + log.debug(MESG_TASK_RESULT_IGNORED, taskId); + return null; + } + + if (StringUtils.isBlank(name)) { + var mesg = MESG_BLANK_PARAMETER.formatted("name"); + log.error(mesg); + throw new IllegalArgumentException(mesg); + } + + if (StringUtils.isBlank(metadata)) { + var mesg = MESG_BLANK_PARAMETER.formatted("metadata"); + log.error(mesg); + throw new IllegalArgumentException(mesg); + } + + var resultEntity = ResultByTaskEntity.builder() + .key(ResultByTaskKey.builder().taskId(taskId).resultId(UUID.randomUUID()).build()) + .createdAt(Instant.now()) + .ncaId(ncaId) + .name(name) + .metadata(metadata) + .build(); + resultEntity = resultsByTaskRepository.save(resultEntity); + log.info(MESG_TASK_RESULT_OPERATION, taskId, "Inserted result"); + return resultEntity; + } + + // Used by cleanup subroutine that executes periodically. There is no validation performed + // to match the NCA Id as there could be scenario where the Task entry is deleted but the + // results were not deleted. If the validation kicks in, then it will result in + // NotFoundException and we end up with partially cleaned Task. + public void cleanResults(UUID taskId) { + Objects.requireNonNull(taskId, () -> MESG_CANNOT_BE_NULL.formatted("taskId")); + resultsByTaskRepository.deleteByKeyTaskId(taskId); + } + + @SneakyThrows + private ResultDto toResultDto(ResultByTaskEntity entity) { + return ResultDto.builder() + .resultId(entity.getKey().getResultId()) + .taskId(entity.getKey().getTaskId()) + .ncaId(entity.getNcaId()) + .name(entity.getName()) + .metadata(jsonMapper.readValue(entity.getMetadata(), ObjectNode.class)) + .createdAt(entity.getCreatedAt()) + .build(); + } + +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/reval/RevalClient.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/reval/RevalClient.java new file mode 100644 index 000000000..3d3d3895a --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/reval/RevalClient.java @@ -0,0 +1,183 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.reval; + +import com.nvidia.boot.exceptions.UpstreamException; +import com.nvidia.nvct.configuration.staticclientauth.FixedBearerExchangeFilterFunction; +import com.nvidia.nvct.configuration.staticclientauth.StaticClientAuthConfiguration.StaticClientRevalProperties; +import com.nvidia.nvct.persistence.task.entity.TaskEntity; +import com.nvidia.nvct.rest.task.dto.GpuSpecificationDto; +import com.nvidia.nvct.service.registry.RegistryArtifactValidationService; +import com.nvidia.nvct.service.registry.RegistryCredentialService; +import com.nvidia.nvct.service.registry.dto.K8sSecretsDto; +import com.nvidia.nvct.util.NvctOAuth2ClientUtils; +import com.nvidia.nvct.util.NvctOAuth2ClientUtils.ManagedHttpResources; +import java.util.Optional; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.cloud.context.config.annotation.RefreshScope; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; +import org.springframework.web.reactive.function.client.ExchangeFilterFunction; +import org.springframework.web.reactive.function.client.WebClient; +import org.springframework.web.reactive.function.client.support.WebClientAdapter; +import org.springframework.web.service.invoker.HttpServiceProxyFactory; +import tools.jackson.databind.json.JsonMapper; + + +@Slf4j +@Service +@RefreshScope +public class RevalClient { + private static final String MESG_REVAL_ERROR = + "Internal error during validation. Reval Status %s"; + private static final String MESG_REVAL_INTERNAL_ERRORS = "ReVal internal errors: {}"; + private static final String MESG_HELM_CHART_VALIDATION_ERRORS = + "Helm chart validation error(s) from NVCF ReVal service: %s"; + private static final String MESG_UNKNOWN_VALIDATION_ERROR = + "Helm chart validation failure. Unknown error."; + public static final String CLIENT_REGISTRATION_ID = "reval"; + + private final RevalStubService revalStubService; + private final boolean enabled; + private final RegistryArtifactValidationService registryArtifactValidationService; + private final RegistryCredentialService registryCredentialService; + private final JsonMapper jsonMapper; + + // We could have used OAuth2AuthorizedClientManager and relied on Spring Security to + // pick up the configuration properties using ClientRegistrationRepository directly. However, + // the client-secret value held in the ClientRegistrationRepository does not get refreshed when + // client-secret is rotated. Addressing these issues requires introducing a refreshable + // ClientRegistrationRepository that wasn't clean. Instead, we will keep it simple and use + // the tried and tested approach of using @Value and @RefreshScope annotations and wire + // things up ourselves. + public RevalClient( + @Value("${nvct.reval.base-url}") String baseUrl, + @Value("${nvct.reval.enabled:true}") boolean enabled, + @Value("${spring.security.oauth2.client.registration.reval.client-id}") String clientId, + @Value("${spring.security.oauth2.client.registration.reval.client-secret}") + String clientSecret, + @Value("${spring.security.oauth2.client.registration.reval.scope}") String scope, + @Value("${spring.security.oauth2.client.provider.reval.token-uri}") String tokenUri, + Optional staticClientRevalProperties, + RegistryArtifactValidationService registryArtifactValidationService, + RegistryCredentialService registryCredentialService, + ManagedHttpResources revalHttpResources, + WebClient.Builder webClientBuilder, // Prototype-scoped - Safe to mutate. + JsonMapper jsonMapper) { + var authFilter = oauthFilter(staticClientRevalProperties, webClientBuilder, + clientId, clientSecret, scope, tokenUri); + var webClient = webClientBuilder + .baseUrl(baseUrl) + .clientConnector(revalHttpResources.connector()) + .filter(NvctOAuth2ClientUtils.getRetryableFilter(CLIENT_REGISTRATION_ID)) + .filter(authFilter) + .build(); + var adapter = WebClientAdapter.create(webClient); + var factory = HttpServiceProxyFactory.builderFor(adapter).build(); + this.revalStubService = factory.createClient(RevalStubService.class); + + this.enabled = enabled; + this.registryArtifactValidationService = registryArtifactValidationService; + this.registryCredentialService = registryCredentialService; + this.jsonMapper = jsonMapper; + } + + private static ExchangeFilterFunction oauthFilter( + Optional staticClientRevalProperties, + WebClient.Builder webClientBuilder, + String clientId, + String clientSecret, + String scope, + String tokenUri) { + return staticClientRevalProperties + .map(p -> (ExchangeFilterFunction) + new FixedBearerExchangeFilterFunction(p::getToken)) + .orElseGet(() -> NvctOAuth2ClientUtils + .getOAuth2ExchangeFilter(webClientBuilder, CLIENT_REGISTRATION_ID, + tokenUri, clientId, clientSecret, scope)); + } + + public String validate( + String ncaId, + TaskEntity task, + GpuSpecificationDto gpuSpec) { + if (!enabled) { + return StringUtils.EMPTY; + } + var imageRegistryAuthConfig = validateAndGetContainerRegistryImagePullSecrets(task); + var helmRegistryAuthConfig = validateAndGetHelmRegistryImagePullSecrets(task); + + var request = RevalStubService.RevalValidateRequest + .builder() + .helmChart(task.getHelmChart()) + .instanceType(gpuSpec.instanceType()) + .gpu(gpuSpec.gpu()) + .configuration(gpuSpec.configuration()) + .imageRegistryAuthConfig(jsonMapper.valueToTree(imageRegistryAuthConfig)) + .helmRegistryAuthConfig(jsonMapper.valueToTree(helmRegistryAuthConfig)) + .build(); + var response = this.revalStubService.validate(request); + if (response.getStatusCode().is2xxSuccessful() && response.hasBody()) { + var body = response.getBody(); + assert body != null; // Shuts up Sonar as it doesn't recognize hasBody() check above. + + if (!CollectionUtils.isEmpty(body.getInternalErrors())) { + var internalErrors = String.join(", ", body.getInternalErrors()); + log.warn(MESG_REVAL_INTERNAL_ERRORS, internalErrors); + } + + if (body.isValid()) { + return StringUtils.EMPTY; + } + + String errors; + if (CollectionUtils.isEmpty(body.getValidationErrors())) { + errors = MESG_UNKNOWN_VALIDATION_ERROR; + } else { + errors = String.join(", ", body.getValidationErrors()); + } + + var msg = String.format(MESG_HELM_CHART_VALIDATION_ERRORS, errors); + log.error(msg); + return msg; + } + + var msg = String.format(MESG_REVAL_ERROR, response.getStatusCode()); + log.error(msg); + + if (response.getStatusCode().is4xxClientError()) { + // 4xx from Reval means that NVCT API is doing something wrong when invoking it. + // That's why we throw IllegalStateException. + throw new IllegalStateException(msg); + } + + throw new UpstreamException(msg); + } + + private K8sSecretsDto validateAndGetContainerRegistryImagePullSecrets(TaskEntity task) { + registryArtifactValidationService.validateContainerRegistryCredentialsExist(task); + return registryCredentialService.getContainerRegistryImagePullSecrets(task); + } + + private K8sSecretsDto validateAndGetHelmRegistryImagePullSecrets(TaskEntity task) { + registryArtifactValidationService.validateHelmRegistryCredentialsExist(task); + return registryCredentialService.getHelmRegistryImagePullSecrets(task); + } + +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/reval/RevalStubService.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/reval/RevalStubService.java new file mode 100644 index 000000000..67a7cee23 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/reval/RevalStubService.java @@ -0,0 +1,62 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.reval; + +import com.fasterxml.jackson.annotation.JsonInclude; +import tools.jackson.databind.node.ObjectNode; +import java.util.List; +import lombok.Builder; +import lombok.Value; +import lombok.extern.jackson.Jacksonized; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.service.annotation.PostExchange; + +public interface RevalStubService { + + @Value + @Jacksonized + @Builder + @JsonInclude(JsonInclude.Include.NON_NULL) + class RevalValidateRequest { + String helmChart; + + String instanceType; + + String gpu; + + ObjectNode configuration; + + ObjectNode imageRegistryAuthConfig; + + ObjectNode helmRegistryAuthConfig; + } + + @Value + @Jacksonized + @Builder + class RevalValidateResponse { + boolean valid; + + List validationErrors; + + List internalErrors; + } + + @PostExchange("/v1/validate") + ResponseEntity validate(@RequestBody RevalValidateRequest request); +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/scheduler/CleanTerminalTasksRoutine.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/scheduler/CleanTerminalTasksRoutine.java new file mode 100644 index 000000000..8155c7a5f --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/scheduler/CleanTerminalTasksRoutine.java @@ -0,0 +1,184 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.scheduler; + +import static com.nvidia.nvct.util.NvctConstants.BATCH_SIZE; +import static com.nvidia.nvct.util.NvctConstants.TERMINAL_TASK_STATUSES; + +import com.google.common.annotations.VisibleForTesting; +import com.nvidia.nvct.persistence.task.TasksRepository; +import com.nvidia.nvct.persistence.task.entity.TaskEntity; +import com.nvidia.nvct.service.ess.EssService; +import com.nvidia.nvct.service.event.EventService; +import com.nvidia.nvct.service.result.ResultService; +import com.nvidia.nvct.service.icms.IcmsService; +import com.nvidia.nvct.service.task.TaskService; +import java.time.Duration; +import java.time.Instant; +import java.util.concurrent.atomic.AtomicInteger; +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.cloud.context.config.annotation.RefreshScope; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Slice; +import org.springframework.stereotype.Service; + +@Slf4j +@Service +@RefreshScope +@ConditionalOnProperty(name = "nvct.scheduled-routines.enabled", + havingValue = "true", + matchIfMissing = true) +public class CleanTerminalTasksRoutine { + + private static final String MESG_TASK_CLEANING = + "Task id '{}', status '{}', last heartbeat at '{}': Cleaning related events, result" + + "metadata, ICMS requests, secrets, and definition"; + private static final String MESG_TASK_CLEANED = + "Task id '{}', status '{}', last heartbeat '{}': Completed cleaning"; + private static final String MESG_ERROR_PROCESSING_TASK_SLICE = + "Error processing Task slice: {}"; + private static final String MESG_FINISHED_ROUTINE = + "Finished CleanTerminalTasksRoutine in {} ms. Processed {} Tasks"; + private static final String MESG_STARTED_ROUTINE = + "Started CleanTerminalTasksRoutine"; + private static final String MESG_UNEXPECTED_EXCEPTION = + "Unexpected exception: {}"; + + private static final String CONFIG_TERMINAL_TASK_RETENTION_DURATION = + "nvct.scheduled-routines.clean-terminal-tasks-routine.retention-duration"; + private static final String CONFIG_ROUTINE_ENABLED = + "nvct.scheduled-routines.clean-terminal-tasks-routine.enabled"; + + private final IcmsService icmsService; + private final EventService eventService; + private final ResultService resultService; + private final TaskService taskService; + private final EssService essService; + private final Duration retentionDuration; + private final TasksRepository tasksRepository; + + // The setter can be used to enable/disable the routine during testing without + // restarting the context and incurring delays. + @VisibleForTesting + @Setter + private volatile boolean enabled; + + public CleanTerminalTasksRoutine( + EssService essService, + IcmsService icmsService, + EventService eventService, + ResultService resultService, + TaskService taskService, + TasksRepository tasksRepository, + @Value("${" + CONFIG_TERMINAL_TASK_RETENTION_DURATION + ":P7D}") + Duration retentionDuration, + @Value("${" + CONFIG_ROUTINE_ENABLED + ":true}") + boolean enabled) { + this.essService = essService; + this.icmsService = icmsService; + this.eventService = eventService; + this.resultService = resultService; + this.taskService = taskService; + this.tasksRepository = tasksRepository; + this.retentionDuration = retentionDuration; + this.enabled = enabled; + } + + public void run() { + if (!enabled) { + return; + } + + runUnchecked(); + } + + @VisibleForTesting + public void runUnchecked() { + var totalProcessed = 0; + var start = System.currentTimeMillis(); + + log.info(MESG_STARTED_ROUTINE); + + try { + var slice = tasksRepository.findAllBy(Pageable.ofSize(BATCH_SIZE).first()); + do { + totalProcessed += processSlice(slice); + if (!slice.hasNext()) { + break; + } + slice = tasksRepository.findAllBy(slice.nextPageable()); + } while (true); + } catch (Exception e) { + // Swallow and move on as async routines should process all the Tasks. + log.error(MESG_UNEXPECTED_EXCEPTION, e.getMessage(), e); + } + + log.info(MESG_FINISHED_ROUTINE, System.currentTimeMillis() - start, totalProcessed); + } + + private int processSlice(Slice slice) { + var processed = new AtomicInteger(0); + + slice.stream() + .filter(CleanTerminalTasksRoutine::hasTerminalStatus) + .filter(this::hasRetentionPeriodElapsed) + .forEach(taskEntity -> { + try { + cleanUpTask(taskEntity); + } catch (Exception ex) { + // Swallow exception, log, and continue. + log.error(MESG_ERROR_PROCESSING_TASK_SLICE, ex.getMessage(), ex); + } + processed.incrementAndGet(); + }); + return processed.get(); + } + + private static boolean hasTerminalStatus(TaskEntity taskEntity) { + return TERMINAL_TASK_STATUSES.contains(taskEntity.getStatus()); + } + + private boolean hasRetentionPeriodElapsed(TaskEntity taskEntity) { + var lastHeartbeat = taskEntity.getLastHeartbeatAt(); + var instant = lastHeartbeat; + + if (lastHeartbeat == null) { + // If lastHeartbeatAt is null, then fall back to lastUpdatedAt. If lastUpdatedAt + // is null, then use createdAt as the last option. + instant = taskEntity.getLastUpdatedAt() != null ? taskEntity.getLastUpdatedAt() : + taskEntity.getCreatedAt(); + } + return instant.isBefore(Instant.now().minus(retentionDuration)); + } + + private void cleanUpTask(TaskEntity taskEntity) { + var taskId = taskEntity.getTaskId(); + var status = taskEntity.getStatus(); + var lastHeartbeatAt = taskEntity.getLastHeartbeatAt(); + + log.info(MESG_TASK_CLEANING, taskId, status, lastHeartbeatAt); + eventService.cleanEvents(taskId); + resultService.cleanResults(taskId); + icmsService.terminateInstanceByTaskId(taskEntity.getNcaId(), taskId); + taskService.deleteTask(taskId); + essService.deleteSecretsPath(taskId); + log.info(MESG_TASK_CLEANED, taskId, status, lastHeartbeatAt); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/scheduler/CommonRoutineService.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/scheduler/CommonRoutineService.java new file mode 100644 index 000000000..03895cc56 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/scheduler/CommonRoutineService.java @@ -0,0 +1,181 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.scheduler; + +import static com.google.common.collect.ImmutableListMultimap.toImmutableListMultimap; +import static com.nvidia.nvct.service.icms.IcmsStubService.GetInstancesResponse.InstanceRequest; +import static com.nvidia.nvct.service.icms.IcmsStubService.GetInstancesResponse.InstanceRequest.State.CANCELED; +import static com.nvidia.nvct.service.icms.IcmsStubService.GetInstancesResponse.InstanceRequest.State.CLOSED; +import static com.nvidia.nvct.service.icms.IcmsStubService.GetInstancesResponse.InstanceRequest.State.FAILED; +import static org.apache.commons.lang3.StringUtils.isNotBlank; + +import com.google.common.collect.ImmutableListMultimap; +import com.nvidia.nvct.persistence.task.entity.GpuSpecUdt; +import com.nvidia.nvct.rest.task.dto.HealthDto; +import com.nvidia.nvct.service.icms.IcmsStubService.GetInstancesResponse.InstanceRequest.State; +import jakarta.validation.constraints.NotNull; +import java.util.Collection; +import java.util.Collections; +import java.util.EnumSet; +import java.util.List; +import java.util.Objects; +import java.util.Set; +import java.util.UUID; +import java.util.function.Function; +import java.util.stream.Collectors; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; + +@Slf4j +@Service +class CommonRoutineService { + + private static final String MESG_ICMS_REQUEST_INSTANCE_DETAILS = + "ICMS Request Id %s: Request State %s; Instance Id %s; Instance State %s; "; + private static final String MESG_HEALTH_INFO_UNAVAILABLE = + "Health info is not available"; + private static final String UNKNOWN = "UNKNOWN"; + + public static final Set TERMINAL_INSTANCE_STATES = + Collections.unmodifiableSet(EnumSet.of(CLOSED, CANCELED, FAILED)); + + public static ImmutableListMultimap mapInstancesByRequestId( + Collection instanceRequests) { + return instanceRequests.stream() + .collect(toImmutableListMultimap( + InstanceRequest::getInstanceRequestId, + Function.identity())); + } + + // Return true if there are no instances or all of the instances are in a terminal state. + public static boolean areAllInstancesInTerminalState( + Collection instanceRequests) { + return CollectionUtils.isEmpty(instanceRequests) + || instanceRequests.stream().map(InstanceRequest::getState) + .allMatch(TERMINAL_INSTANCE_STATES::contains); + } + + public static Set getHealthDtos( + List instanceRequestIds, + List instanceRequests) { + return instanceRequestIds.stream() + .map(instanceRequestId -> { + var instances = instanceRequests.stream() + .filter(instanceRequest -> instanceRequest.getInstanceRequestId() + .equals(instanceRequestId)) + .toList(); + var allWithErrors = instances.stream() + .allMatch(instance -> instance.getHealthInfo() != null && + isNotBlank(instance.getHealthInfo().getErrorLog())); + if (allWithErrors) { + return instances.stream().findAny() + .map(instance -> { + var healthInfo = instance.getHealthInfo(); + var launchSpec = instance.getLaunchSpecification(); + var error = healthInfo != null ? + healthInfo.getErrorLog() : "No health info"; + return getHealthDto(launchSpec.getGpu(), + launchSpec.getInstanceType(), + instance.getCloudProvider(), + error); + }) + .orElse(null); + } + return null; + }) + .filter(Objects::nonNull) + .collect(Collectors.toSet()); + } + + public static HealthDto getHealthDto( + String gpu, + String instanceType, + String backend, + String error) { + return HealthDto.builder() + .error(error) + .instanceType(instanceType) + .gpu(gpu) + .backend(backend) + .build(); + } + + public static HealthDto getHealthDto( + GpuSpecUdt gpuSpec, + String errorMessage) { + return CommonRoutineService.getHealthDto(gpuSpec.getGpu(), + gpuSpec.getInstanceType(), + gpuSpec.getBackend(), + errorMessage); + } + + public static String getErrorMessage(Set healthDtos) { + var builder = new StringBuilder(); + if (healthDtos.isEmpty()) { + return builder.append("No health information available").toString(); + } + + healthDtos.forEach(healthDto -> { + if (!builder.isEmpty()) { + builder.append("; "); + } + builder.append(healthDto.error()); + }); + return builder.toString(); + } + + // Collect health info of all the instances. + public static String getErrorMessage(Collection instanceRequests) { + if (CollectionUtils.isEmpty(instanceRequests)) { + return "No error logs available"; + } + + var healthInfos = instanceRequests.stream() + .map(CommonRoutineService::getHealthInfo) + .toList(); + return StringUtils.join(healthInfos, ";"); + } + + private static String getHealthInfo(InstanceRequest instanceRequest) { + var errorMessageBuilder = getErrorMessageStringBuilder(instanceRequest); + var healthInfo = instanceRequest.getHealthInfo(); + if ((healthInfo != null) && isNotBlank(healthInfo.getErrorLog())) { + errorMessageBuilder.append("Error Message - ").append(healthInfo.getErrorLog()); + } else { + errorMessageBuilder.append(MESG_HEALTH_INFO_UNAVAILABLE); + } + return errorMessageBuilder.toString(); + } + + @NotNull + private static StringBuilder getErrorMessageStringBuilder(InstanceRequest instanceRequest) { + var icmsRequesId = instanceRequest.getInstanceRequestId(); + var instanceId = isNotBlank(instanceRequest.getInstanceId()) ? + instanceRequest.getInstanceId() : UNKNOWN; + var requestState = instanceRequest.getState() != null ? + instanceRequest.getState() : UNKNOWN; + var instanceState = instanceRequest.getInstanceState() != null ? + instanceRequest.getInstanceState().getName() : UNKNOWN; + return new StringBuilder(MESG_ICMS_REQUEST_INSTANCE_DETAILS.formatted(icmsRequesId, + requestState, + instanceId, + instanceState)); + } + +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/scheduler/MonitorLaunchedTasksRoutine.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/scheduler/MonitorLaunchedTasksRoutine.java new file mode 100644 index 000000000..c077ce637 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/scheduler/MonitorLaunchedTasksRoutine.java @@ -0,0 +1,233 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.scheduler; + +import static com.nvidia.nvct.persistence.task.entity.TaskStatus.ERRORED; +import static com.nvidia.nvct.persistence.task.entity.TaskStatus.LAUNCHED; +import static com.nvidia.nvct.service.event.EventService.STATUS_CHANGE_EVENT_MESSAGE_WITH_ERROR; +import static com.nvidia.nvct.service.scheduler.CommonRoutineService.getHealthDto; +import static com.nvidia.nvct.util.NvctConstants.BATCH_SIZE; +import static com.nvidia.nvct.util.NvctConstants.SPAN_TAG_NCA_ID; +import static com.nvidia.nvct.util.NvctConstants.SPAN_TAG_TASK_ID; +import static java.util.stream.Collectors.joining; +import static org.apache.commons.lang3.StringUtils.isNotBlank; + +import com.google.common.annotations.VisibleForTesting; +import com.nvidia.nvct.persistence.task.TasksRepository; +import com.nvidia.nvct.persistence.task.entity.TaskEntity; +import com.nvidia.nvct.persistence.task.entity.TaskStatus; +import com.nvidia.nvct.service.event.EventService; +import com.nvidia.nvct.service.metrics.TaskErrorMetricsService; +import com.nvidia.nvct.service.icms.IcmsClient; +import com.nvidia.nvct.service.icms.IcmsStubService.Instance; +import com.nvidia.nvct.service.task.TaskService; +import com.nvidia.nvct.util.NvctUtils; +import io.micrometer.tracing.Tracer; +import java.time.Duration; +import java.time.Instant; +import java.util.List; +import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.cloud.context.config.annotation.RefreshScope; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Slice; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; + +@Slf4j +@Service +@RefreshScope +@ConditionalOnProperty(name = "nvct.scheduled-routines.enabled", + havingValue = "true", + matchIfMissing = true) +public class MonitorLaunchedTasksRoutine { + + private static final String MESG_NOT_UPDATED_RECENTLY = + "Task id '{}': Status LAUNCHED - last updated more than 5 minutes ago at '{}'"; + private static final String MESG_TASK_HEALTH = + "Task id '{}': {}"; + private static final String MESG_TASK_INFO = + "Task id '{}': {}"; + private static final String MESG_ERROR_PROCESSING_TASK_SLICE = + "Error processing Task slice: {}"; + private static final String MESG_FINISHED_ROUTINE = + "Finished MonitorLaunchedTasksRoutine in {} ms. Processed {} Tasks"; + private static final String MESG_STARTED_ROUTINE = + "Started MonitorLaunchedTasksRoutine"; + private static final String MESG_UNEXPECTED_EXCEPTION = + "Unexpected exception: {}"; + + private static final String MISSING_ICMS_INSTANCES = + "No corresponding ICMS instances found"; + private static final String NO_HEALTH_INFORMATION_AVAILABLE = + "No health information available"; + + // If the current time is greater than timestamp in the lastUpdatedAt field of a Task with + // LAUNCHED status by this duration, then the Task is transitioned to ERRORED status. + private static final Duration MAX_DURATION = Duration.ofMinutes(5); + + private final EventService eventService; + private final IcmsClient icmsClient; + private final TaskService taskService; + private final TaskErrorMetricsService taskErrorMetricsService; + private final TasksRepository tasksRepository; + private final Tracer tracer; + + // The setter can be used to enable/disable the routine during testing without + // restarting the context and incurring delays. + @VisibleForTesting + @Setter + private volatile boolean enabled; + + public MonitorLaunchedTasksRoutine( + EventService eventService, + IcmsClient icmsClient, + TaskService taskService, + TaskErrorMetricsService taskErrorMetricsService, + TasksRepository tasksRepository, + Tracer tracer, + @Value("${nvct.scheduled-routines.monitor-launched-tasks-routine.enabled:true}") + boolean enabled) { + this.eventService = eventService; + this.icmsClient = icmsClient; + this.taskService = taskService; + this.taskErrorMetricsService = taskErrorMetricsService; + this.tasksRepository = tasksRepository; + this.tracer = tracer; + this.enabled = enabled; + } + + public void run() { + if (!enabled) { + return; + } + + runUnchecked(Instant.now()); + } + + @VisibleForTesting + public void runUnchecked(Instant now) { + var totalProcessed = 0; + var start = System.currentTimeMillis(); + + log.info(MESG_STARTED_ROUTINE); + + try { + var slice = tasksRepository.findAllBy(Pageable.ofSize(BATCH_SIZE).first()); + do { + totalProcessed += processSlice(slice, now); + if (!slice.hasNext()) { + break; + } + slice = tasksRepository.findAllBy(slice.nextPageable()); + } while (true); + } catch (Exception e) { + // Swallow and move on as async routines should process all the Tasks. + log.error(MESG_UNEXPECTED_EXCEPTION, e.getMessage(), e); + } + + log.info(MESG_FINISHED_ROUTINE, System.currentTimeMillis() - start, totalProcessed); + } + + private int processSlice(Slice slice, Instant now) { + var processed = new AtomicInteger(0); + + slice.stream() + .filter(task -> task.getStatus() == LAUNCHED) + .forEach(taskEntity -> { + try { + processLaunchedTask(taskEntity, now); + } catch (Exception ex) { + // Swallow exception, log, and continue. + log.error(MESG_ERROR_PROCESSING_TASK_SLICE, ex.getMessage(), ex); + } + processed.incrementAndGet(); + }); + return processed.get(); + } + + private void processLaunchedTask(TaskEntity taskEntity, Instant now) { + var ncaId = taskEntity.getNcaId(); + var taskId = taskEntity.getTaskId(); + var lastUpdatedAt = taskEntity.getLastUpdatedAt(); + + NvctUtils.addTagsToChildSpan(tracer, + Map.of(SPAN_TAG_NCA_ID, ncaId, + SPAN_TAG_TASK_ID, taskId), + "process-launched-task"); + + if (lastUpdatedAt != null && + lastUpdatedAt.isBefore(now.minus(MAX_DURATION))) { + log.info(MESG_NOT_UPDATED_RECENTLY, taskId, lastUpdatedAt); + var instances = icmsClient.getAllInstancesByTaskId(ncaId, taskId); + if (CollectionUtils.isEmpty(instances)) { + transitionToErroredWhenNoIcmsRequestsFound(taskEntity); + return; + } + + transitionToErrored(taskEntity, getInstanceErrorMessage(instances)); + } + } + + private void transitionToErrored(TaskEntity taskEntity, String errorMessage) { + var ncaId = taskEntity.getNcaId(); + var taskId = taskEntity.getTaskId(); + log.info(MESG_TASK_HEALTH, taskId, errorMessage); + + taskService.updateTask(taskId, + TaskStatus.ERRORED, + getHealthDto(taskEntity.getGpuSpec(), errorMessage)); + taskErrorMetricsService.recordTaskError(ncaId); + var mesg = STATUS_CHANGE_EVENT_MESSAGE_WITH_ERROR + .formatted(LAUNCHED, ERRORED, errorMessage); + log.info(MESG_TASK_INFO, taskId, mesg); + eventService.insertEvent(ncaId, taskId, mesg); + } + + private static String getInstanceErrorMessage(List instances) { + var errorMessage = instances.stream() + .map(Instance::getHealthInfo) + .filter(healthInfo -> healthInfo != null && + isNotBlank(healthInfo.getErrorLog())) + .map(healthInfo -> healthInfo.getErrorLog()) + .collect(joining("; ")); + return isNotBlank(errorMessage) ? errorMessage : NO_HEALTH_INFORMATION_AVAILABLE; + } + + // Transitions the Task to ERRORED status when there are no corresponding ICMS Request Id(s). + // This should not happen. We saw this when ICMS was not hooked up to NVCT. So, keeping this + // for completeness. + private void transitionToErroredWhenNoIcmsRequestsFound(TaskEntity task) { + var gpuSpec = task.getGpuSpec(); + var taskId = task.getTaskId(); + var ncaId = task.getNcaId(); + var healthDto = getHealthDto(gpuSpec, MISSING_ICMS_INSTANCES); + log.info(MESG_TASK_HEALTH, taskId, MISSING_ICMS_INSTANCES); + + taskService.updateTask(taskId, TaskStatus.ERRORED, healthDto); + taskErrorMetricsService.recordTaskError(ncaId); + var mesg = STATUS_CHANGE_EVENT_MESSAGE_WITH_ERROR + .formatted(LAUNCHED, ERRORED, MISSING_ICMS_INSTANCES); + log.info(MESG_TASK_INFO, taskId, mesg); + eventService.insertEvent(ncaId, taskId, mesg); + } + +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/scheduler/MonitorQueuedTasksRoutine.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/scheduler/MonitorQueuedTasksRoutine.java new file mode 100644 index 000000000..51dd4b7ca --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/scheduler/MonitorQueuedTasksRoutine.java @@ -0,0 +1,296 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.scheduler; + +import static com.nvidia.nvct.persistence.task.entity.TaskStatus.ERRORED; +import static com.nvidia.nvct.persistence.task.entity.TaskStatus.EXCEEDED_MAX_QUEUED_DURATION; +import static com.nvidia.nvct.persistence.task.entity.TaskStatus.QUEUED; +import static com.nvidia.nvct.service.event.EventService.STATUS_CHANGE_EVENT_MESSAGE_WITH_ERROR; +import static com.nvidia.nvct.service.scheduler.CommonRoutineService.getHealthDto; +import static com.nvidia.nvct.util.NvctConstants.BATCH_SIZE; +import static com.nvidia.nvct.util.NvctConstants.SPAN_TAG_NCA_ID; +import static com.nvidia.nvct.util.NvctConstants.SPAN_TAG_TASK_ID; +import static java.util.stream.Collectors.joining; +import static org.apache.commons.lang3.StringUtils.isNotBlank; + +import com.google.common.annotations.VisibleForTesting; +import com.nvidia.nvct.persistence.task.TasksRepository; +import com.nvidia.nvct.persistence.task.entity.TaskEntity; +import com.nvidia.nvct.persistence.task.entity.TaskStatus; +import com.nvidia.nvct.service.event.EventService; +import com.nvidia.nvct.service.metrics.TaskErrorMetricsService; +import com.nvidia.nvct.service.icms.IcmsClient; +import com.nvidia.nvct.service.icms.IcmsStubService.Instance; +import com.nvidia.nvct.service.icms.IcmsStubService.GetInstancesResponse.InstanceRequest; +import com.nvidia.nvct.service.task.TaskService; +import com.nvidia.nvct.util.NvctUtils; +import io.micrometer.tracing.Tracer; +import java.time.Duration; +import java.time.Instant; +import java.util.List; +import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.cloud.context.config.annotation.RefreshScope; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Slice; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; + +@Slf4j +@Service +@RefreshScope +@ConditionalOnProperty(name = "nvct.scheduled-routines.enabled", + havingValue = "true", + matchIfMissing = true) +public class MonitorQueuedTasksRoutine { + + private static final String MESG_ICMS_REQUESTS_CAN_PRODUCE = + "Task id '{}': ICMS Requests can still produce instance so stays in QUEUED state"; + private static final String MESG_TASK_HEALTH = + "Task id '{}': {}"; + private static final String MESG_TASK_INFO = + "Task id '{}': {}"; + private static final String MESG_ERROR_PROCESSING_TASK_SLICE = + "Error processing Task slice: {}"; + private static final String MESG_FINISHED_ROUTINE = + "Finished MonitorQueuedTasksRoutine in {} ms. Processed {} Tasks"; + private static final String MESG_STARTED_ROUTINE = + "Started MonitorQueuedTasksRoutine"; + private static final String MESG_UNEXPECTED_EXCEPTION = + "Unexpected exception: {}"; + + private static final String MISSING_ICMS_REQUEST_IDS = + "No corresponding ICMS request-id(s) found"; + private static final String NO_HEALTH_INFORMATION_AVAILABLE = + "No health information available"; + + // Extra time given after maxQueuedDuration before transitioning the Task to + // EXCEEDED_MAX_QUEUED_DURATION status. Extra time is being given to avoid race with ICMS as + // it updates the health information that NVCT can then use to update its DB. This will help + // users to see the error message percolating from the Worker -> ICMS -> NVCT. + private static final Duration DELTA_DURATION = Duration.ofMinutes(3); + + private final EventService eventService; + private final IcmsClient icmsClient; + private final TaskService taskService; + private final TaskErrorMetricsService taskErrorMetricsService; + private final TasksRepository tasksRepository; + private final Tracer tracer; + + // The setter can be used to enable/disable the routine during testing without + // restarting the context and incurring delays. + @VisibleForTesting + @Setter + private volatile boolean enabled; + + public MonitorQueuedTasksRoutine( + EventService eventService, + IcmsClient icmsClient, + TaskService taskService, + TaskErrorMetricsService taskErrorMetricsService, + TasksRepository tasksRepository, + Tracer tracer, + @Value("${nvct.scheduled-routines.monitor-queued-tasks-routine.enabled:true}") + boolean enabled) { + this.eventService = eventService; + this.icmsClient = icmsClient; + this.taskService = taskService; + this.taskErrorMetricsService = taskErrorMetricsService; + this.tasksRepository = tasksRepository; + this.tracer = tracer; + this.enabled = enabled; + } + + public void run() { + if (!enabled) { + return; + } + + runUnchecked(); + } + + @VisibleForTesting + public void runUnchecked() { + var totalProcessed = 0; + var start = System.currentTimeMillis(); + + log.info(MESG_STARTED_ROUTINE); + + try { + var slice = tasksRepository.findAllBy(Pageable.ofSize(BATCH_SIZE).first()); + do { + totalProcessed += processSlice(slice); + if (!slice.hasNext()) { + break; + } + slice = tasksRepository.findAllBy(slice.nextPageable()); + } while (true); + } catch (Exception e) { + // Swallow and move on as async routines should process all the Tasks. + log.error(MESG_UNEXPECTED_EXCEPTION, e.getMessage(), e); + } + + log.info(MESG_FINISHED_ROUTINE, System.currentTimeMillis() - start, totalProcessed); + } + + private int processSlice(Slice slice) { + var processed = new AtomicInteger(0); + + slice.stream() + .filter(task -> task.getStatus() == QUEUED) + .forEach(taskEntity -> { + try { + processQueuedTask(taskEntity); + } catch (Exception ex) { + // Swallow exception, log, and continue. + log.error(MESG_ERROR_PROCESSING_TASK_SLICE, ex.getMessage(), ex); + } + processed.incrementAndGet(); + }); + return processed.get(); + } + + private void processQueuedTask(TaskEntity taskEntity) { + var ncaId = taskEntity.getNcaId(); + var taskId = taskEntity.getTaskId(); + var createdAt = taskEntity.getCreatedAt(); + + NvctUtils.addTagsToChildSpan(tracer, + Map.of(SPAN_TAG_NCA_ID, ncaId, + SPAN_TAG_TASK_ID, taskId), + "process-queued-task"); + + var instances = icmsClient.getAllInstancesByTaskId(ncaId, taskId); + + if (CollectionUtils.isEmpty(instances)) { + if (Instant.now().isAfter(createdAt.plus(Duration.ofMinutes(2)))) { + // If the Task is created more than two minutes ago and still there is no + // corresponding ICMS instances, then transition to ERRORED. + transitionToErroredWhenNoIcmsRequestsFound(taskEntity); + } + return; + } + + // Transition to EXCEEDED_MAX_QUEUED_DURATION if the Task has been in QUEUED status + // for more than the specified maxQueuedDuration. Use health info from ICMS if + // available. + var haveAllInstancesExceededMaxQueuedDuration = instances.stream() + .allMatch(instance -> hasExceededMaxQueuedDurationPlusDelta(instance, taskEntity)); + if (haveAllInstancesExceededMaxQueuedDuration) { + log.info("Task id '{}': Transition to EXCEEDED_MAX_QUEUED_DURATION", taskId); + transitionToExceededMaxQueuedDuration(taskEntity, instances); + return; + } + + // Transition to ERRORED if all the instances are in terminal state and has health info. + // This can happen in scenarios when there is no capacity or Task Container exited + // ungracefully during startup. These things can happen even before maxQueuedDuration + // has elapsed. + if (areAllInstancesInTerminalStateByTaskId(instances)) { + log.info("Task id '{}': Transition to ERRORED as all instances are in terminal state", + taskId); + transitionToErrored(taskEntity, instances); + return; + } + + // The ICMS still can produce active instances and maxQueuedDuration has not elapsed. + log.info(MESG_ICMS_REQUESTS_CAN_PRODUCE, taskId); + } + + // Transitions the Task to ERRORED status when there are no corresponding ICMS Request Id(s). + // This should not happen. We saw this when ICMS was not hooked up to NVCT. So, keeping this + // for completeness. + private void transitionToErroredWhenNoIcmsRequestsFound(TaskEntity taskEntity) { + var taskId = taskEntity.getTaskId(); + var ncaId = taskEntity.getNcaId(); + var gpuSpec = taskEntity.getGpuSpec(); + var healthDto = getHealthDto(gpuSpec, MISSING_ICMS_REQUEST_IDS); + log.info(MESG_TASK_HEALTH, taskId, MISSING_ICMS_REQUEST_IDS); + + taskService.updateTask(taskId, TaskStatus.ERRORED, healthDto); + taskErrorMetricsService.recordTaskError(ncaId); + var mesg = STATUS_CHANGE_EVENT_MESSAGE_WITH_ERROR + .formatted(QUEUED, ERRORED, MISSING_ICMS_REQUEST_IDS); + log.info(MESG_TASK_INFO, taskId, mesg); + eventService.insertEvent(ncaId, taskId, mesg); + } + + private void transitionToExceededMaxQueuedDuration( + TaskEntity taskEntity, + List instances) { + var taskId = taskEntity.getTaskId(); + var errorMessage = getInstanceErrorMessage(instances); + var healthDto = getHealthDto(taskEntity.getGpuSpec(), errorMessage); + log.info(MESG_TASK_HEALTH, taskId, healthDto.error()); + + var ncaId = taskEntity.getNcaId(); + taskService.updateTask(taskId, TaskStatus.EXCEEDED_MAX_QUEUED_DURATION, healthDto); + taskErrorMetricsService.recordTaskError(ncaId); + var mesg = STATUS_CHANGE_EVENT_MESSAGE_WITH_ERROR + .formatted(QUEUED, EXCEEDED_MAX_QUEUED_DURATION, errorMessage); + log.info(MESG_TASK_INFO, taskId, mesg); + eventService.insertEvent(ncaId, taskId, mesg); + } + + private void transitionToErrored( + TaskEntity taskEntity, + List instances) { + var ncaId = taskEntity.getNcaId(); + var taskId = taskEntity.getTaskId(); + var errorMessage = getInstanceErrorMessage(instances); + log.info(MESG_TASK_HEALTH, taskId, errorMessage); + + taskService.updateTask(taskId, + TaskStatus.ERRORED, + getHealthDto(taskEntity.getGpuSpec(), errorMessage)); + taskErrorMetricsService.recordTaskError(ncaId); + var mesg = STATUS_CHANGE_EVENT_MESSAGE_WITH_ERROR + .formatted(QUEUED, ERRORED, errorMessage); + log.info(MESG_TASK_INFO, taskId, mesg); + eventService.insertEvent(ncaId, taskId, mesg); + } + + private static boolean areAllInstancesInTerminalStateByTaskId(List instances) { + return instances.stream() + .map(Instance::getState) + .allMatch(state -> state != null && + "terminated".equalsIgnoreCase(state.getName())); + } + + private static String getInstanceErrorMessage(List instances) { + var errorMessage = instances.stream() + .map(Instance::getHealthInfo) + .filter(healthInfo -> healthInfo != null && + isNotBlank(healthInfo.getErrorLog())) + .map(InstanceRequest.HealthInfo::getErrorLog) + .collect(joining("; ")); + return isNotBlank(errorMessage) ? errorMessage : NO_HEALTH_INFORMATION_AVAILABLE; + } + + private static boolean hasExceededMaxQueuedDurationPlusDelta( + Instance instance, + TaskEntity taskEntity) { + var maxQueuedDuration = taskEntity.getMaxQueuedDuration(); + var createdAt = instance.getCreateTime(); + return Instant.now().minus(maxQueuedDuration.plus(DELTA_DURATION)).isAfter(createdAt); + } + +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/scheduler/MonitorWorkerHeartbeatRoutine.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/scheduler/MonitorWorkerHeartbeatRoutine.java new file mode 100644 index 000000000..d9a2ab314 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/scheduler/MonitorWorkerHeartbeatRoutine.java @@ -0,0 +1,261 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.scheduler; + +import static com.nvidia.nvct.persistence.task.entity.TaskStatus.ERRORED; +import static com.nvidia.nvct.persistence.task.entity.TaskStatus.RUNNING; +import static com.nvidia.nvct.service.event.EventService.STATUS_CHANGE_EVENT_MESSAGE_WITH_ERROR; +import static com.nvidia.nvct.service.scheduler.CommonRoutineService.getHealthDto; +import static com.nvidia.nvct.util.NvctConstants.BATCH_SIZE; +import static com.nvidia.nvct.util.NvctConstants.SPAN_TAG_NCA_ID; +import static com.nvidia.nvct.util.NvctConstants.SPAN_TAG_TASK_ID; +import static java.util.stream.Collectors.joining; +import static org.apache.commons.lang3.StringUtils.isNotBlank; + +import com.google.common.annotations.VisibleForTesting; +import com.nvidia.nvct.persistence.task.TasksRepository; +import com.nvidia.nvct.persistence.task.entity.TaskEntity; +import com.nvidia.nvct.persistence.task.entity.TaskStatus; +import com.nvidia.nvct.service.event.EventService; +import com.nvidia.nvct.service.metrics.TaskErrorMetricsService; +import com.nvidia.nvct.service.icms.IcmsClient; +import com.nvidia.nvct.service.icms.IcmsStubService.Instance; +import com.nvidia.nvct.service.task.TaskService; +import com.nvidia.nvct.util.NvctUtils; +import io.micrometer.tracing.Tracer; +import java.time.Duration; +import java.time.Instant; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.atomic.AtomicInteger; +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.cloud.context.config.annotation.RefreshScope; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Slice; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; + +@Slf4j +@Service +@RefreshScope +@ConditionalOnProperty(name = "nvct.scheduled-routines.enabled", + havingValue = "true", + matchIfMissing = true) +public class MonitorWorkerHeartbeatRoutine { + private static final String MESG_NO_HEARTBEAT_RECEIVED = + "Task id '{}': Status RUNNING; Last heartbeat received more than 4 minutes ago at '{}'"; + private static final String MESG_TASK_HEALTH = + "Task id '{}': {}"; + private static final String MESG_TASK_INFO = + "Task id '{}': {}"; + private static final String MESG_ERROR_PROCESSING_TASK_SLICE = + "Error processing Task slice: {}"; + private static final String MESG_FINISHED_ROUTINE = + "Finished MonitorWorkerHeartbeatRoutine in {} ms. Processed {} Tasks"; + private static final String MESG_STARTED_ROUTINE = + "Started MonitorWorkerHeartbeatRoutine"; + private static final String MESG_UNEXPECTED_EXCEPTION = + "Unexpected exception: {}"; + private static final String MESG_CHECKING_TASK_EVENTS = + "Task id '{}': Checking task events for terminal status"; + private static final String MESG_TERMINAL_STATUS_IN_LATEST_EVENT = + "Task id '{}': Updated with terminal status '{}' from the latest event"; + private static final String MESG_NO_TERMINAL_STATUS_IN_LATEST_EVENT = + "Task id '{}': No terminal status found in latest event"; + + private static final String MESG_MISSING_ICMS_REQUEST_IDS = + "Task id '%s': No corresponding ICMS request-id(s) found"; + private static final String MESG_ICMS_INSTANCE_DETAILS = + "ICMS Request Id %s: Instance Id %s; Instance State %s; %s"; + private static final String MESG_HEALTH_INFO_UNAVAILABLE = + "Health info is not available"; + private static final String UNKNOWN = "UNKNOWN"; + + // If the current time is greater than timestamp in the lastHeartbeatAt field of a Task with + // RUNNING status by this duration, then the Task is transitioned to ERRORED status. + private static final Duration MAX_DURATION = Duration.ofMinutes(4); + + private final EventService eventService; + private final TaskService taskService; + private final IcmsClient icmsClient; + private final TaskErrorMetricsService tasksErrorMetricsService; + private final TasksRepository tasksRepository; + private final Tracer tracer; + + // The setter can be used to enable/disable the routine during testing without + // restarting the context and incurring delays. + @VisibleForTesting + @Setter + private volatile boolean enabled; + + public MonitorWorkerHeartbeatRoutine( + EventService eventService, + TaskService taskService, + IcmsClient icmsClient, + TaskErrorMetricsService tasksErrorMetricsService, + TasksRepository tasksRepository, + Tracer tracer, + @Value("${nvct.scheduled-routines.monitor-worker-heartbeat-routine.enabled:true}") + boolean enabled) { + this.eventService = eventService; + this.taskService = taskService; + this.icmsClient = icmsClient; + this.tasksErrorMetricsService = tasksErrorMetricsService; + this.tasksRepository = tasksRepository; + this.tracer = tracer; + this.enabled = enabled; + } + + public void run() { + if (!enabled) { + return; + } + + runUnchecked(); + } + + @VisibleForTesting + public void runUnchecked() { + var totalProcessed = 0; + var start = System.currentTimeMillis(); + + log.info(MESG_STARTED_ROUTINE); + + try { + var slice = tasksRepository.findAllBy(Pageable.ofSize(BATCH_SIZE).first()); + do { + totalProcessed += processSlice(slice); + if (!slice.hasNext()) { + break; + } + slice = tasksRepository.findAllBy(slice.nextPageable()); + } while (true); + } catch (Exception e) { + // Swallow and move on as async routines should process all the Tasks. + log.error(MESG_UNEXPECTED_EXCEPTION, e.getMessage(), e); + } + + log.info(MESG_FINISHED_ROUTINE, System.currentTimeMillis() - start, totalProcessed); + } + + private int processSlice(Slice slice) { + var processed = new AtomicInteger(0); + + slice.stream() + .filter(this::hasNoRecentHeartbeatForRunningTask) + .forEach(taskEntity -> { + try { + processRunningTasksWithNoRecentHeartbeat(taskEntity); + } catch (Exception ex) { + // Swallow exception, log, and continue. + log.error(MESG_ERROR_PROCESSING_TASK_SLICE, ex.getMessage(), ex); + } + processed.incrementAndGet(); + }); + return processed.get(); + } + + private void processRunningTasksWithNoRecentHeartbeat(TaskEntity taskEntity) { + var ncaId = taskEntity.getNcaId(); + var taskId = taskEntity.getTaskId(); + var lastHeartbeatAt = taskEntity.getLastHeartbeatAt(); + + NvctUtils.addTagsToChildSpan(tracer, + Map.of(SPAN_TAG_NCA_ID, ncaId, + SPAN_TAG_TASK_ID, taskId), + "process-worker-heartbeat-task"); + + log.info(MESG_NO_HEARTBEAT_RECEIVED, taskId, lastHeartbeatAt); + var instances = icmsClient.getAllInstancesByTaskId(ncaId, taskId); + if (CollectionUtils.isEmpty(instances)) { + processTaskWithMissingIcmsInstances(taskId); + return; + } + + var errorMessage = getErrorMessage(instances); + transitionTaskToErrored(taskEntity, errorMessage); + } + + private void transitionTaskToErrored(TaskEntity taskEntity, String errorMessage) { + var ncaId = taskEntity.getNcaId(); + var taskId = taskEntity.getTaskId(); + var healthDto = getHealthDto(taskEntity.getGpuSpec(), errorMessage); + log.info(MESG_TASK_HEALTH, taskId, healthDto.error()); + + // There may be multiple ICMS Requests associated with a Task, but we must + // transition the Task to ERRORED state just once and also insert just one + // event. + taskService.updateTask(taskId, TaskStatus.ERRORED, healthDto); + tasksErrorMetricsService.recordTaskError(ncaId); + + var error = healthDto.error(); + var mesg = STATUS_CHANGE_EVENT_MESSAGE_WITH_ERROR.formatted(RUNNING, ERRORED, error); + log.info(MESG_TASK_INFO, taskId, mesg); + eventService.insertEvent(ncaId, taskId, mesg); + } + + private void processTaskWithMissingIcmsInstances(UUID taskId) { + var mesg = MESG_MISSING_ICMS_REQUEST_IDS.formatted(taskId); + log.info(mesg); + + // Check the latest Task event to see if there's a terminal status recorded. + log.info(MESG_CHECKING_TASK_EVENTS, taskId); + eventService.getTerminalStatusFromLatestEvent(taskId) + .ifPresentOrElse( + terminalStatus -> { + // Update Task with the terminal status found in the latest event. + // Note that we will not be inserting a new entry in events_by_tasks + // table for this as it was already done earlier. + taskService.updateTask(taskId, terminalStatus); + log.info(MESG_TERMINAL_STATUS_IN_LATEST_EVENT, + taskId, terminalStatus); + }, + () -> log.info(MESG_NO_TERMINAL_STATUS_IN_LATEST_EVENT, taskId)); + } + + private String getErrorMessage(List instances) { + return instances.stream() + .map(instance -> { + var requestId = isNotBlank(instance.getLaunchRequestId()) ? + instance.getLaunchRequestId() : UNKNOWN; + var instanceId = isNotBlank(instance.getInstanceId()) ? + instance.getInstanceId() : UNKNOWN; + var instanceState = instance.getState() != null ? + instance.getState().getName() : UNKNOWN; + var healthInfo = instance.getHealthInfo(); + var healthMessage = healthInfo != null && + isNotBlank(healthInfo.getErrorLog()) ? + "Error Message - " + healthInfo.getErrorLog() : + MESG_HEALTH_INFO_UNAVAILABLE; + return MESG_ICMS_INSTANCE_DETAILS.formatted( + requestId, instanceId, instanceState, healthMessage); + }) + .collect(joining("; ")); + } + + private boolean hasNoRecentHeartbeatForRunningTask(TaskEntity taskEntity) { + var lastHeartbeatAt = taskEntity.getLastHeartbeatAt(); + return taskEntity.getStatus() == RUNNING + && (lastHeartbeatAt == null || + lastHeartbeatAt.isBefore(Instant.now().minus(MAX_DURATION))); + } + +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/scheduler/ScheduledRoutineService.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/scheduler/ScheduledRoutineService.java new file mode 100644 index 000000000..bc5cc4237 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/scheduler/ScheduledRoutineService.java @@ -0,0 +1,125 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.scheduler; + +import io.micrometer.observation.annotation.Observed; +import jakarta.annotation.Nonnull; +import java.util.concurrent.CountDownLatch; +import lombok.extern.slf4j.Slf4j; +import net.javacrumbs.shedlock.core.LockAssert; +import net.javacrumbs.shedlock.spring.annotation.SchedulerLock; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.context.event.ApplicationReadyEvent; +import org.springframework.cloud.context.config.annotation.RefreshScope; +import org.springframework.context.ApplicationListener; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Service; + +@Slf4j +@Service +@RefreshScope +@ConditionalOnProperty(name = "nvct.scheduled-routines.enabled", + havingValue = "true", + matchIfMissing = true) +@EnableScheduling +public class ScheduledRoutineService implements ApplicationListener { + + private static final String CLEAN_TERMINAL_TASKS_ROUTINE = + "clean-terminal-tasks-routine"; + private static final String MONITOR_LAUNCHED_TASKS_ROUTINE = + "monitor-launched-tasks-routine"; + private static final String MONITOR_QUEUED_TASKS_ROUTINE = + "monitor-queued-tasks-routine"; + private static final String MONITOR_WORKER_HEARTBEAT_ROUTINE = + "monitor-worker-heartbeat-routine"; + private final CountDownLatch initialised; + private final MonitorQueuedTasksRoutine monitorQueuedTasksRoutine; + private final MonitorLaunchedTasksRoutine monitorLaunchedTasksRoutine; + private final CleanTerminalTasksRoutine cleanTerminalTasksRoutine; + private final MonitorWorkerHeartbeatRoutine monitorWorkerHeartbeatRoutine; + + public ScheduledRoutineService( + MonitorQueuedTasksRoutine monitorQueuedTasksRoutine, + MonitorLaunchedTasksRoutine monitorLaunchedTasksRoutine, + CleanTerminalTasksRoutine cleanTerminalTasksRoutine, + MonitorWorkerHeartbeatRoutine monitorWorkerHeartbeatRoutine) { + this.monitorQueuedTasksRoutine = monitorQueuedTasksRoutine; + this.monitorLaunchedTasksRoutine = monitorLaunchedTasksRoutine; + this.cleanTerminalTasksRoutine = cleanTerminalTasksRoutine; + this.monitorWorkerHeartbeatRoutine = monitorWorkerHeartbeatRoutine; + this.initialised = new CountDownLatch(1); + } + + @Override + public void onApplicationEvent(@Nonnull ApplicationReadyEvent event) { + initialised.countDown(); + } + + @SchedulerLock(name = MONITOR_QUEUED_TASKS_ROUTINE, + lockAtLeastFor = "PT5M", + lockAtMostFor = "PT5M") + @Scheduled(fixedDelayString = "PT5M") + @Observed(name = "monitor-queued-tasks") + void monitorQueuedTasks() throws InterruptedException { + initialised.await(); + LockAssert.assertLocked(); + log.debug("Begin Routine: " + MONITOR_QUEUED_TASKS_ROUTINE); + monitorQueuedTasksRoutine.run(); + log.debug("End Routine: " + MONITOR_QUEUED_TASKS_ROUTINE); + } + + @SchedulerLock(name = MONITOR_LAUNCHED_TASKS_ROUTINE, + lockAtLeastFor = "PT8M", + lockAtMostFor = "PT8M") + @Scheduled(fixedDelayString = "PT8M") + @Observed(name = "monitor-launched-tasks") + void monitorLaunchedTasks() throws InterruptedException { + initialised.await(); + LockAssert.assertLocked(); + log.debug("Begin Routine: " + MONITOR_LAUNCHED_TASKS_ROUTINE); + monitorLaunchedTasksRoutine.run(); + log.debug("End Routine: " + MONITOR_LAUNCHED_TASKS_ROUTINE); + } + + @SchedulerLock(name = CLEAN_TERMINAL_TASKS_ROUTINE, + lockAtLeastFor = "PT14M", + lockAtMostFor = "PT14M") + @Scheduled(fixedDelayString = "PT14M") + @Observed(name = "clean-up-terminal-tasks") + void cleanUpTerminalTasks() throws InterruptedException { + initialised.await(); + LockAssert.assertLocked(); + log.debug("Begin Routine: " + CLEAN_TERMINAL_TASKS_ROUTINE); + cleanTerminalTasksRoutine.run(); + log.debug("End Routine: " + CLEAN_TERMINAL_TASKS_ROUTINE); + } + + @SchedulerLock(name = MONITOR_WORKER_HEARTBEAT_ROUTINE, + lockAtLeastFor = "PT3M", + lockAtMostFor = "PT3M") + @Scheduled(fixedDelayString = "PT3M") + @Observed(name = "monitor-worker-heartbeat") + void monitorWorkerHeartbeat() throws InterruptedException { + initialised.await(); + LockAssert.assertLocked(); + log.debug("Begin Routine: " + MONITOR_WORKER_HEARTBEAT_ROUTINE); + monitorWorkerHeartbeatRoutine.run(); + log.debug("End Routine: " + MONITOR_WORKER_HEARTBEAT_ROUTINE); + } + +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/secret/SecretManagementService.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/secret/SecretManagementService.java new file mode 100644 index 000000000..6d04d4130 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/secret/SecretManagementService.java @@ -0,0 +1,44 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.secret; + +import static com.nvidia.nvct.util.NvctConstants.NGC_API_KEY; + +import tools.jackson.databind.JsonNode; +import com.nvidia.nvct.rest.task.dto.SecretDto; +import java.util.Optional; +import java.util.Set; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +@Slf4j +@Service +public class SecretManagementService { + + public static Optional getNgcApiKey(Set secrets) { + return secrets.stream() + .filter(secret -> secret.name().equalsIgnoreCase(NGC_API_KEY)) + .map(SecretDto::value) + .findFirst(); + } + + public static boolean hasDupeSecrets(Set secrets) { + var dedupedCount = (Long) secrets.stream().map(SecretDto::name).distinct().count(); + return dedupedCount != secrets.size(); + } + +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/task/GpuSpecificationMapperService.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/task/GpuSpecificationMapperService.java new file mode 100644 index 000000000..501ce3a10 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/task/GpuSpecificationMapperService.java @@ -0,0 +1,85 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.task; + +import static java.nio.charset.StandardCharsets.UTF_8; +import static org.apache.commons.lang3.StringUtils.isNotBlank; + +import tools.jackson.databind.json.JsonMapper; +import tools.jackson.databind.node.ObjectNode; +import com.nvidia.nvct.persistence.task.entity.GpuSpecUdt; +import com.nvidia.nvct.rest.task.dto.GpuSpecificationDto; +import java.util.Base64; +import lombok.RequiredArgsConstructor; +import lombok.SneakyThrows; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class GpuSpecificationMapperService { + + private final JsonMapper jsonMapper; + private final HelmValidationPolicyMapperService helmValidationPolicyMapperService; + + /** + * Convert DTO to {@link GpuSpecUdt}, including + * {@code helmValidationPolicy} serialized as JSON. + */ + public GpuSpecUdt toGpuSpecUdt(GpuSpecificationDto dto) { + var builder = GpuSpecUdt.builder() + .backend(dto.backend()) + .gpu(dto.gpu()) + .instanceType(dto.instanceType()) + .clusters(dto.clusters()) + .helmValidationPolicy( + helmValidationPolicyMapperService.toHelmValidationPolicyJson( + dto.helmValidationPolicy())); + + if (dto.configuration() != null) { + builder.configuration( + Base64.getEncoder().encodeToString( + dto.configuration().toString().getBytes(UTF_8))); + } + + return builder.build(); + } + + /** + * Convert {@link GpuSpecUdt} to DTO, including {@code helmValidationPolicy}. + */ + @SneakyThrows + public GpuSpecificationDto toGpuSpecificationDto(GpuSpecUdt udt) { + var builder = GpuSpecificationDto.builder() + .backend(udt.getBackend()) + .gpu(udt.getGpu()) + .instanceType(udt.getInstanceType()) + .clusters(udt.getClusters()) + .helmValidationPolicy( + helmValidationPolicyMapperService.toHelmValidationPolicyDto( + udt.getHelmValidationPolicy())); + + if (isNotBlank(udt.getConfiguration())) { + builder.configuration( + jsonMapper.readValue( + Base64.getDecoder().decode(udt.getConfiguration()), + ObjectNode.class)); + } + + return builder.build(); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/task/HelmValidationPolicyMapperService.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/task/HelmValidationPolicyMapperService.java new file mode 100644 index 000000000..765a0adb0 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/task/HelmValidationPolicyMapperService.java @@ -0,0 +1,57 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.task; + +import tools.jackson.databind.json.JsonMapper; +import com.nvidia.nvct.rest.task.dto.HelmValidationPolicyDto; +import lombok.RequiredArgsConstructor; +import lombok.SneakyThrows; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class HelmValidationPolicyMapperService { + + private final JsonMapper jsonMapper; + + /** + * Serialize {@link HelmValidationPolicyDto} to JSON for storage in the + * {@code helm_validation_policy} TEXT column. + */ + @SneakyThrows + public String toHelmValidationPolicyJson(HelmValidationPolicyDto dto) { + if (dto == null) { + return null; + } + return jsonMapper.writeValueAsString(dto); + } + + /** + * Deserialize JSON from the {@code helm_validation_policy} TEXT column back to + * {@link HelmValidationPolicyDto}. + */ + @SneakyThrows + public HelmValidationPolicyDto toHelmValidationPolicyDto(String json) { + if (StringUtils.isBlank(json)) { + return null; + } + return jsonMapper.readValue(json, HelmValidationPolicyDto.class); + } + +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/task/TaskAuditService.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/task/TaskAuditService.java new file mode 100644 index 000000000..3506bab55 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/task/TaskAuditService.java @@ -0,0 +1,153 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.task; + +import static com.nvidia.nvct.util.NvctConstants.GRP_TYPE_TASK_MANAGEMENT; +import static com.nvidia.nvct.util.NvctConstants.NCA_ID; +import static com.nvidia.nvct.util.NvctConstants.OPER_CANCEL_TASK; +import static com.nvidia.nvct.util.NvctConstants.OPER_CREATE_TASK; +import static com.nvidia.nvct.util.NvctConstants.OPER_DELETE_TASK; +import static com.nvidia.nvct.util.NvctConstants.OPER_UPDATE_TASK; +import static com.nvidia.nvct.util.NvctConstants.STATE_CANCELED; +import static com.nvidia.nvct.util.NvctConstants.STATE_CREATED; +import static com.nvidia.nvct.util.NvctConstants.STATE_DELETED; +import static com.nvidia.nvct.util.NvctConstants.STATE_UPDATED; +import static com.nvidia.nvct.util.NvctConstants.SUMMARY_CANCEL_TASK; +import static com.nvidia.nvct.util.NvctConstants.SUMMARY_CREATE_TASK; +import static com.nvidia.nvct.util.NvctConstants.SUMMARY_DELETE_TASK; +import static com.nvidia.nvct.util.NvctConstants.SUMMARY_UPDATE_TASK; +import static com.nvidia.nvct.util.NvctConstants.TASK_ID; +import static com.nvidia.nvct.util.NvctConstants.TASK_OBJECT_LOCATION; +import static com.nvidia.nvct.util.NvctConstants.TASK_STATUS; +import static java.lang.String.format; + +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.json.JsonMapper; +import com.nvidia.boot.audit.AuditService; +import com.nvidia.boot.audit.event.AuditEventPayload; +import com.nvidia.nvct.persistence.task.entity.TaskEntity; +import java.util.Map; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.security.core.Authentication; +import org.springframework.stereotype.Service; + +@Slf4j +@Service +@RequiredArgsConstructor +public class TaskAuditService { + private final AuditService auditService; + private final JsonMapper jsonMapper; + + public AuditEventPayload.Builder auditEventPayloadBuilder() { + return auditService.auditEventPayloadBuilder(); + } + + public AuditEventPayload.Builder auditEventPayloadBuilder( + Authentication authentication, + Map customProperties) { + return auditService.auditEventPayloadBuilder(authentication, customProperties); + } + + public void auditTaskCreate( + AuditEventPayload.Builder payloadBuilder, + TaskEntity taskEntity) { + var ncaId = taskEntity.getNcaId(); + var taskId = taskEntity.getTaskId(); + var status = taskEntity.getStatus(); + var summary = format(SUMMARY_CREATE_TASK, taskId, ncaId); + payloadBuilder.operation(OPER_CREATE_TASK) + .type(TaskEntity.class.getCanonicalName()) + .groupType(GRP_TYPE_TASK_MANAGEMENT) + .objectId(taskId.toString()) + .objectLocation(TASK_OBJECT_LOCATION) + .jsonBefore(jsonMapper.createObjectNode()) // empty + .jsonAfter(jsonMapper.valueToTree(taskEntity)) + .state(STATE_CREATED) + .summary(summary) + .custom(NCA_ID, ncaId) + .custom(TASK_ID, taskId) + .custom(TASK_STATUS, status); + auditService.audit(payloadBuilder); + } + + public void auditTaskUpdate( + AuditEventPayload.Builder payloadBuilder, + JsonNode taskJsonBefore, + TaskEntity taskEntity) { + var ncaId = taskEntity.getNcaId(); + var taskId = taskEntity.getTaskId(); + var status = taskEntity.getStatus(); + var summary = format(SUMMARY_UPDATE_TASK, taskId, status); + payloadBuilder.operation(OPER_UPDATE_TASK) + .type(TaskEntity.class.getCanonicalName()) + .groupType(GRP_TYPE_TASK_MANAGEMENT) + .objectId(taskId.toString()) + .objectLocation(TASK_OBJECT_LOCATION) + .jsonBefore(taskJsonBefore) + .jsonAfter(jsonMapper.valueToTree(taskEntity)) + .state(STATE_UPDATED) + .summary(summary) + .custom(NCA_ID, ncaId) + .custom(TASK_ID, taskId) + .custom(TASK_STATUS, status); + auditService.audit(payloadBuilder); + } + + public void auditTaskCancel( + AuditEventPayload.Builder payloadBuilder, + JsonNode taskJsonBefore, + TaskEntity taskEntity) { + var ncaId = taskEntity.getNcaId(); + var taskId = taskEntity.getTaskId(); + var status = taskEntity.getStatus(); + var summary = format(SUMMARY_CANCEL_TASK, taskId); + payloadBuilder.operation(OPER_CANCEL_TASK) + .type(TaskEntity.class.getCanonicalName()) + .groupType(GRP_TYPE_TASK_MANAGEMENT) + .objectId(taskId.toString()) + .objectLocation(TASK_OBJECT_LOCATION) + .jsonBefore(taskJsonBefore) + .jsonAfter(jsonMapper.valueToTree(taskEntity)) + .state(STATE_CANCELED) + .summary(summary) + .custom(NCA_ID, ncaId) + .custom(TASK_ID, taskId) + .custom(TASK_STATUS, status); + auditService.audit(payloadBuilder); + } + + public void auditTaskDelete( + AuditEventPayload.Builder payloadBuilder, + TaskEntity taskEntity) { + var ncaId = taskEntity.getNcaId(); + var taskId = taskEntity.getTaskId(); + var summary = format(SUMMARY_DELETE_TASK, taskId); + payloadBuilder.operation(OPER_DELETE_TASK) + .type(TaskEntity.class.getCanonicalName()) + .groupType(GRP_TYPE_TASK_MANAGEMENT) + .objectId(taskId.toString()) + .objectLocation(TASK_OBJECT_LOCATION) + .jsonBefore(jsonMapper.valueToTree(taskEntity)) + .jsonAfter(jsonMapper.createObjectNode()) // empty + .state(STATE_DELETED) + .summary(summary) + .custom(NCA_ID, ncaId) + .custom(TASK_ID, taskId); + auditService.audit(payloadBuilder); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/task/TaskManagementService.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/task/TaskManagementService.java new file mode 100644 index 000000000..bad0d6a84 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/task/TaskManagementService.java @@ -0,0 +1,635 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.task; + +import static com.nvidia.nvct.service.event.EventService.STATUS_CHANGE_EVENT_MESSAGE; +import static com.nvidia.nvct.service.secret.SecretManagementService.getNgcApiKey; +import static com.nvidia.nvct.service.secret.SecretManagementService.hasDupeSecrets; +import static com.nvidia.nvct.service.task.TaskMapperService.DEFAULT_TERMINATION_GRACE_PERIOD_DURATION; +import static com.nvidia.nvct.service.telemetry.dto.TelemetryTypeEnum.LOGS; +import static com.nvidia.nvct.service.telemetry.dto.TelemetryTypeEnum.METRICS; +import static com.nvidia.nvct.service.telemetry.dto.TelemetryTypeEnum.TRACES; +import static com.nvidia.nvct.util.NvctConstants.TERMINAL_TASK_STATUSES; +import static java.lang.String.format; + +import tools.jackson.databind.json.JsonMapper; +import com.nimbusds.oauth2.sdk.util.CollectionUtils; +import com.nimbusds.oauth2.sdk.util.MapUtils; +import com.nvidia.boot.audit.event.AuditEventPayload; +import com.nvidia.boot.exceptions.BadRequestException; +import com.nvidia.boot.exceptions.ForbiddenException; +import com.nvidia.nvct.persistence.task.entity.TaskEntity; +import com.nvidia.nvct.persistence.task.entity.TaskStatus; +import com.nvidia.nvct.rest.task.dto.BasicTaskDto; +import com.nvidia.nvct.rest.task.dto.CreateTaskRequest; +import com.nvidia.nvct.rest.task.dto.InstanceUsageTypeEnum; +import com.nvidia.nvct.rest.task.dto.ResultHandlingStrategyEnum; +import com.nvidia.nvct.rest.task.dto.SecretDto; +import com.nvidia.nvct.rest.task.dto.TaskDto; +import com.nvidia.nvct.rest.task.dto.TaskStatusEnum; +import com.nvidia.nvct.service.account.AccountService; +import com.nvidia.nvct.service.account.dto.AccountDto; +import com.nvidia.nvct.service.ess.EssService; +import com.nvidia.nvct.service.event.EventService; +import com.nvidia.nvct.service.icms.IcmsClusterGroupClient; +import com.nvidia.nvct.service.icms.IcmsService; +import com.nvidia.nvct.service.icms.IcmsStubService.ClusterGroupsResponse.ClusterGroup; +import com.nvidia.nvct.service.icms.IcmsStubService.ClusterGroupsResponse.ClusterGroup.Gpu; +import com.nvidia.nvct.service.instance.InstanceService; +import com.nvidia.nvct.service.ngc.NgcRegistryClient; +import com.nvidia.nvct.service.registry.RegistryArtifactService; +import com.nvidia.nvct.service.result.ResultService; +import com.nvidia.nvct.service.reval.RevalClient; +import com.nvidia.nvct.service.task.TaskService.TasksSliceContext; +import com.nvidia.nvct.service.telemetry.dto.TelemetryDto; +import com.nvidia.nvct.service.telemetry.dto.TelemetryTypeEnum; +import java.time.Duration; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import java.util.UUID; +import java.util.function.BooleanSupplier; +import java.util.function.Predicate; +import java.util.regex.Pattern; +import java.util.stream.Collectors; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; + +@Slf4j +@Service +@RequiredArgsConstructor +public class TaskManagementService { + + private static final Duration GFN_MAX_RUNTIME_DURATION = Duration.ofHours(8); + private static final Pattern RESULTS_LOCATION_PATTERN = + Pattern.compile("^[^/]+/([^/]+/)?[^/]+[a-zA-Z0-9\\-]*$"); + + private static final String MESG_CREATE_AND_LAUNCH_TASK = + "Account '{}': Creating and launching new task with name '{}'"; + private static final String MESG_ACCOUNT_OPERATION = + "Account '{}': {}"; + private static final String MESG_TASK_OPERATION = + "Task id '{}': {}"; + private static final String MESG_TASK_INFO = + "Task id '{}': {}"; + + private static final String MESG_BLANK_PARAMETER = + "'%s' cannot be blank"; + private static final String MESG_CANNOT_BE_NULL = + "Parameter '%s' cannot be null"; + private static final String MESG_INVALID_MAX_RUNTIME_DURATION = + "Invalid request: 'maxRuntimeDuration' cannot exceed PT8H for launching Task on 'GFN'"; + private static final String MESG_MISSING_MAX_RUNTIME_DURATION = + "Invalid request: 'maxRuntimeDuration' must be specified when launching Task on 'GFN'"; + private static final String MESG_INVALID_GRACE_PERIOD_DURATION = + "Invalid request: 'terminationGracePeriodDuration' cannot exceed 'maxRuntimeDuration'"; + private static final String MESG_DUPLICATE_SECRETS = + "Invalid request: Duplicate secrets keys in the payload"; + private static final String MESG_NO_NGC_API_KEY = + "Invalid request: Missing 'NGC_API_KEY' secret key in the payload"; + private static final String MESG_INVALID_CLUSTER_GROUP = + "Invalid request: Invalid Backend '%s' specified"; + private static final String MESG_GPUS_MISSING = + "Invalid request: GPUs missing for Backend '%s'"; + private static final String MESG_INVALID_GPU = + "Invalid request: Invalid GPU '%s' specified"; + private static final String MESG_INVALID_INSTANCE_TYPE = + "Invalid request: Invalid InstanceType '%s' specified"; + private static final String MESG_MISSING_RESULTS_LOCATION = + "Invalid request: Missing 'resultsLocation' property"; + private static final String MESG_INVALID_RESULTS_PATH = + "Invalid request: 'resultsLocation' should have format " + + "'/optional-team-name/'"; + private static final String MESG_MISSING_SECRETS = + "Invalid request: Missing secrets with default or UPLOAD 'resultHandlingStrategy'"; + private static final String MESG_INVALID_DURATION = + "Invalid request: '%s' cannot be of zero length"; + private static final String MESG_CANCEL_TERMINAL = + "Invalid request: Cannot cancel a Task with '%s' terminal status"; + private static final String MESG_MISSING_REQ_PROPS = + "Invalid request: One of the following properties 'containerImage' " + + "or 'helmChart' must be specified in the payload"; + private static final String MESG_ONE_OF_PROPS_CONSTRAINT_VIOLATION = + "Invalid request: Cannot specify both '%s' and '%s' properties in the payload"; + private static final String MESG_TELEMETRY_NOT_AVAILABLE = + "Invalid request: Telemetry '%s' not found in account '%s'"; + private static final String MESG_TELEMETRY_INVALID_TYPE = + "Invalid request: Telemetry '%s' - Invalid type '%s'"; + private static final String MESG_CONFIGURATION_NOT_EMPTY = + "Invalid request: Container-based Task should have empty " + + "configuration field in GPU specification"; + private static final String MESG_HELM_VALIDATION_POLICY_NOT_SUPPORTED = + "Invalid request: Container-based Task should have empty " + + "helmValidationPolicy field in GPU specification"; + private static final String MESG_MAX_ALLOWED_EXCEEDED = + "Account '%s': Reached or exceeded the limit for max number of in-flight Tasks '%d'"; + private static final String MESG_FORBIDDEN_TO_CREATE_TASK = + "Forbidden to create task"; + private static final String MESG_FORBIDDEN_TO_RETRIEVE_TASK = + "Insufficient resource access for task details"; + private static final String MESG_FORBIDDEN_TO_CANCEL_TASK = + "Insufficient resource access to cancel task"; + private static final String MESG_FORBIDDEN_TO_DELETE_TASK = + "Insufficient resource access to delete task"; + + private static final String PROP_CONTAINER_IMAGE = "containerImage"; + private static final String PROP_CONTAINER_ARGS = "containerArgs"; + private static final String PROP_CONTAINER_ENVIRONMENT = "containerEnvironment"; + private static final String PROP_HELM_CHART = "helmChart"; + + private final AccountService accountService; + private final EventService eventService; + private final ResultService resultService; + private final IcmsService icmsService; + private final IcmsClusterGroupClient icmsClusterGroupClient; + private final TaskAuditService taskAuditService; + private final TaskMapperService taskMapperService; + private final TaskService taskService; + private final EssService essService; + private final InstanceService instanceService; + private final NgcRegistryClient ngcRegistryClient; + private final JsonMapper jsonMapper; + private final RevalClient revalClient; + private final RegistryArtifactService registryArtifactService; + + @SuppressWarnings("checkstyle:VariableDeclarationUsageDistance") + public TaskDto createAndLaunchTask( + String ncaId, + CreateTaskRequest request, + BooleanSupplier taskAccessMatch, + AuditEventPayload.Builder payloadBuilder) { + log.info(MESG_CREATE_AND_LAUNCH_TASK, ncaId, request.name()); + if (!taskAccessMatch.getAsBoolean()) { + throw new ForbiddenException(MESG_FORBIDDEN_TO_CREATE_TASK); + } + var taskEntity = validateCreateTaskRequest(ncaId, request); + var taskId = taskEntity.getTaskId(); + + Optional> secretNames = Optional.empty(); + try { + if (!CollectionUtils.isEmpty(request.secrets())) { + secretNames = saveSecrets(request.secrets(), taskId); + taskEntity.setHasSecrets(true); + } + taskService.saveTask(taskEntity); + icmsService.scheduleInstance(taskEntity); + } catch (Exception ex) { + // Delete secrets from ESS and Task from the NVCT DB. + essService.deleteSecretsPath(taskId); + taskService.deleteTask(taskId); + log.error(ex.getMessage()); + throw ex; + } + + taskAuditService.auditTaskCreate(payloadBuilder, taskEntity); + log.info(MESG_TASK_OPERATION, taskId, "Created"); + return taskMapperService.toTaskDto(taskEntity, secretNames, Optional.empty()); + } + + public TasksSliceContext listTasks( + String ncaId, + TaskStatusEnum status, + int limit, + String cursor, + Predicate taskFilter) { + if (StringUtils.isBlank(ncaId)) { + var mesg = MESG_BLANK_PARAMETER.formatted("ncaId"); + log.error(mesg); + throw new IllegalArgumentException(mesg); + } + + accountService.lookupAccountUsingNcaIdOrThrow(ncaId); + + log.debug(MESG_ACCOUNT_OPERATION, ncaId, "Listing tasks"); + var sliceContext = taskService.fetchTasksByAccount(ncaId, limit, status, cursor, taskFilter); + log.debug(MESG_ACCOUNT_OPERATION, ncaId, "Listed tasks"); + + return sliceContext; + } + + public TaskDto getTaskDetails( + String ncaId, + UUID taskId, + boolean includeSecrets, + Predicate taskAccessMatch) { + log.debug(MESG_TASK_OPERATION, taskId, "Retrieving"); + var taskEntity = taskService.validateAccount(ncaId, taskId); + + var filteredTask = Optional.of(taskEntity) + .filter(taskAccessMatch) + .orElseThrow(() -> new ForbiddenException(MESG_FORBIDDEN_TO_RETRIEVE_TASK)); + var hasSecrets = filteredTask.hasSecrets(); + var secretsNames = includeSecrets && hasSecrets ? essService.getSecretNames(taskId) : + Optional.>empty(); + var instances = instanceService.getInstances(filteredTask); + var dto = taskMapperService.toTaskDto(filteredTask, secretsNames, instances); + log.debug(MESG_TASK_OPERATION, taskId, "Retrieved"); + return dto; + } + + public BasicTaskDto getBasicTaskDetails( + String ncaId, + UUID taskId, + Predicate taskAccessMatch) { + log.debug(MESG_TASK_OPERATION, taskId, "Retrieving"); + var taskEntity = taskService.validateAccount(ncaId, taskId); + + // Filter by predicate - if denied, throw ForbiddenException + var filteredTask = Optional.of(taskEntity) + .filter(taskAccessMatch) + .orElseThrow(() -> new ForbiddenException(MESG_FORBIDDEN_TO_RETRIEVE_TASK)); + + var dto = taskMapperService.toBasicTaskDto(filteredTask); + log.debug(MESG_TASK_OPERATION, taskId, "Retrieved"); + return dto; + } + + public TaskDto cancelTask( + String ncaId, + UUID taskId, + Predicate taskAccessMatch, + AuditEventPayload.Builder payloadBuilder) { + var taskEntity = taskService.validateAccount(ncaId, taskId); + if (!taskAccessMatch.test(taskEntity)) { + throw new ForbiddenException(MESG_FORBIDDEN_TO_CANCEL_TASK); + } + var status = taskEntity.getStatus(); + if (TERMINAL_TASK_STATUSES.contains(status)) { + var mesg = MESG_CANCEL_TERMINAL.formatted(status.name()); + log.error(mesg); + throw new BadRequestException(mesg); + } + + var jsonBefore = jsonMapper.valueToTree(taskEntity); + log.info(MESG_TASK_OPERATION, taskId, "Canceling"); + icmsService.terminateInstanceByTaskId(ncaId, taskId); + + taskEntity.setStatus(TaskStatus.CANCELED); + taskService.updateTask(taskEntity, false); // Don't audit - audited by cancelTask + + // Record the event for the change in the status. + var mesg = STATUS_CHANGE_EVENT_MESSAGE.formatted(status, taskEntity.getStatus()); + log.info(MESG_TASK_INFO, taskId, mesg); + eventService.insertEvent(ncaId, taskId, mesg); + + taskAuditService.auditTaskCancel(payloadBuilder, jsonBefore, taskEntity); + var dto = taskMapperService.toTaskDto(taskEntity, Optional.empty(), Optional.empty()); + log.info(MESG_TASK_OPERATION, taskId, "Canceled"); + return dto; + } + + public boolean deleteTask( + String ncaId, + UUID taskId, + Predicate taskAccessMatch, + AuditEventPayload.Builder payloadBuilder) { + var taskEntity = taskService.validateAccount(ncaId, taskId); + if (!taskAccessMatch.test(taskEntity)) { + log.error(MESG_FORBIDDEN_TO_DELETE_TASK); + throw new ForbiddenException(MESG_FORBIDDEN_TO_DELETE_TASK); + } + + log.info(MESG_TASK_OPERATION, taskId, "Deleting"); + eventService.deleteEvents(ncaId, taskId); + resultService.deleteResults(ncaId, taskId); + icmsService.terminateInstanceByTaskId(ncaId, taskId); + essService.deleteSecretsPath(taskId); + taskService.deleteTask(taskId); + + taskAuditService.auditTaskDelete(payloadBuilder, taskEntity); + log.info(MESG_TASK_OPERATION, taskId, "Deleted"); + return true; + } + + private Optional> saveSecrets(Set secrets, UUID taskId) { + if (CollectionUtils.isNotEmpty(secrets)) { + essService.saveSecrets(taskId, secrets); + return Optional.of(secrets.stream() + .map(SecretDto::name) + .collect(Collectors.toSet())); + } + return Optional.empty(); + } + + private TaskEntity validateCreateTaskRequest(String ncaId, CreateTaskRequest request) { + Objects.requireNonNull(request, () -> MESG_CANNOT_BE_NULL.formatted("request")); + if (StringUtils.isBlank(ncaId)) { + var mesg = MESG_BLANK_PARAMETER.formatted("ncaId"); + log.error(mesg); + throw new IllegalArgumentException(mesg); + } + + // Validate there is an account corresponding to the specified NCA Id. + var account = accountService.lookupAccountUsingNcaIdOrThrow(ncaId); + // validateLimitForMaxTasksAllowed(ncaId, account); // Limit not enforced for now. + validateDurations(request); + validateGpuSpecification(ncaId, request); + validateSecrets(request); + validateResultHandlingStrategy(request); + validateContainer(request); + validateTelemetries(ncaId, request); + + // Validate artifacts before validating the helm chart using Reval service. + var taskEntity = taskMapperService.toTaskEntity(ncaId, request); + registryArtifactService.validateArtifacts(taskEntity); + validateHelmChart(ncaId, request, taskEntity); + return taskEntity; + } + + // During load testing, this method seemed to be causing a bottleneck as we would fetch + // all the Tasks from the DB and filter them for each new Task that is being created. As + // the number of Tasks in an account increases, this method will start taking more and + // more time. Till we have a good solution, we will not call this method and not enforce + // the limit. + private void validateLimitForMaxTasksAllowed(String ncaId, AccountDto account) { + // A new Task is going to be created, check if total number of in-flight + // Tasks under the specified account is smaller than threshold. + var inFlightTaskCount = taskService.fetchTasksByAccount(ncaId) + .filter(task -> !TERMINAL_TASK_STATUSES.contains(task.getStatus())) + .count(); + if (inFlightTaskCount >= account.maxTasksAllowed()) { + var msg = format(MESG_MAX_ALLOWED_EXCEEDED, ncaId, account.maxTasksAllowed()); + log.error(msg); + throw new BadRequestException(msg); + } + } + + private static void validateDurations(CreateTaskRequest request) { + if ((request.maxRuntimeDuration() != null) && request.maxRuntimeDuration().isZero()) { + var mesg = MESG_INVALID_DURATION.formatted("maxRuntimeDuration"); + log.error(mesg); + throw new BadRequestException(mesg); + } + + if ((request.terminationGracePeriodDuration() != null) + && request.terminationGracePeriodDuration().isZero()) { + var mesg = MESG_INVALID_DURATION.formatted("terminationGracePeriodDuration"); + log.error(mesg); + throw new BadRequestException(mesg); + } + + if ((request.maxQueuedDuration() != null) && request.maxQueuedDuration().isZero()) { + var mesg = MESG_INVALID_DURATION.formatted("maxQueuedDuration"); + log.error(mesg); + throw new BadRequestException(mesg); + } + + var maxRuntimeDuration = request.maxRuntimeDuration(); + var terminationGracePeriodDuration = + Objects.requireNonNullElse(request.terminationGracePeriodDuration(), + DEFAULT_TERMINATION_GRACE_PERIOD_DURATION); + + if ((maxRuntimeDuration != null) + && maxRuntimeDuration.minus(terminationGracePeriodDuration).isNegative()) { + log.error(MESG_INVALID_GRACE_PERIOD_DURATION); + throw new BadRequestException(MESG_INVALID_GRACE_PERIOD_DURATION); + } + } + + private void validateGpuSpecification(String ncaId, CreateTaskRequest request) { + var spec = request.gpuSpecification(); + var maxRuntimeDuration = request.maxRuntimeDuration(); + List gpus; + var backend = spec.backend(); + var clusterGroups = icmsClusterGroupClient.getClusterGroups( + ncaId, getTaskContainerType(request)); + + if (StringUtils.isNotBlank(backend)) { + if (backend.equals("GFN")) { + if (maxRuntimeDuration == null) { + log.error(MESG_MISSING_MAX_RUNTIME_DURATION); + throw new BadRequestException(MESG_MISSING_MAX_RUNTIME_DURATION); + } + + if (GFN_MAX_RUNTIME_DURATION.minus(maxRuntimeDuration).isNegative()) { + log.error(MESG_INVALID_MAX_RUNTIME_DURATION); + throw new BadRequestException(MESG_INVALID_MAX_RUNTIME_DURATION); + } + } + + var clusterGroup = clusterGroups.stream() + .filter(cg -> cg.getName().equalsIgnoreCase(backend)) + .findAny() + .orElseThrow(() -> { + var mesg = MESG_INVALID_CLUSTER_GROUP.formatted(backend); + log.error(mesg); + return new BadRequestException(mesg); + }); + if (CollectionUtils.isEmpty(clusterGroup.getGpus())) { + var mesg = MESG_GPUS_MISSING.formatted(backend); + log.error(mesg); + throw new BadRequestException(mesg); + } + gpus = clusterGroup.getGpus().stream() + .filter(gpu -> gpu.getName().equalsIgnoreCase(spec.gpu())) + .toList(); + + } else { + gpus = clusterGroups.stream() + .map(ClusterGroup::getGpus) + .flatMap(Collection::stream) + .filter(gpu -> gpu.getName().equalsIgnoreCase(spec.gpu())) + .toList(); + } + + if (CollectionUtils.isEmpty(gpus)) { + var mesg = MESG_INVALID_GPU.formatted(spec.gpu()); + log.error(mesg); + throw new BadRequestException(mesg); + } + + var instanceType = spec.instanceType(); + if (StringUtils.isNotBlank(instanceType) + && gpus.stream() + .map(ClusterGroup.Gpu::getInstanceTypes) + .flatMap(Collection::stream) + .noneMatch(it -> it.getName().equalsIgnoreCase(instanceType))) { + var mesg = MESG_INVALID_INSTANCE_TYPE.formatted(spec.instanceType()); + log.error(mesg); + throw new BadRequestException(mesg); + } + } + + private void validateResultHandlingStrategy(CreateTaskRequest request) { + var secrets = request.secrets(); + var resultHandlingStrategy = request.resultHandlingStrategy(); + + if ((resultHandlingStrategy == null) + || resultHandlingStrategy == ResultHandlingStrategyEnum.UPLOAD) { + if (CollectionUtils.isEmpty(secrets)) { + log.error(MESG_MISSING_SECRETS); + throw new BadRequestException(MESG_MISSING_SECRETS); + } + + var optNgcApiKey = getNgcApiKey(secrets); + if (CollectionUtils.isEmpty(secrets) || optNgcApiKey.isEmpty()) { + log.error(MESG_NO_NGC_API_KEY); + throw new BadRequestException(MESG_NO_NGC_API_KEY); + } + + var resultsLocation = request.resultsLocation(); + if (StringUtils.isBlank(resultsLocation)) { + log.error(MESG_MISSING_RESULTS_LOCATION); + throw new BadRequestException(MESG_MISSING_RESULTS_LOCATION); + } + + if (!RESULTS_LOCATION_PATTERN.matcher(resultsLocation).matches()) { + log.error(MESG_INVALID_RESULTS_PATH); + throw new BadRequestException(MESG_INVALID_RESULTS_PATH); + } + + // Validate whether the specified NGC_API_KEY can be used to create results + // or checkpoint models at the specified resultsLocation. + var ngcApiKey = optNgcApiKey.get(); + ngcRegistryClient.validate(ngcApiKey, resultsLocation); + } + } + + private static void validateSecrets(CreateTaskRequest request) { + var secrets = request.secrets(); + if (CollectionUtils.isNotEmpty(secrets) && hasDupeSecrets(secrets)) { + log.error(MESG_DUPLICATE_SECRETS); + throw new BadRequestException(MESG_DUPLICATE_SECRETS); + } + } + + private void validateHelmChart( + String ncaId, + CreateTaskRequest request, + TaskEntity task) { + var helmChart = request.helmChart(); + + if (helmChart == null && request.containerImage() == null) { + log.error(MESG_MISSING_REQ_PROPS); + throw new BadRequestException(MESG_MISSING_REQ_PROPS); + } + + if (helmChart != null && request.containerImage() != null) { + var mesg = MESG_ONE_OF_PROPS_CONSTRAINT_VIOLATION + .formatted(PROP_CONTAINER_IMAGE, PROP_HELM_CHART); + log.error(mesg); + throw new BadRequestException(mesg); + } + + if (helmChart != null && StringUtils.isNotBlank(request.containerArgs())) { + var mesg = MESG_ONE_OF_PROPS_CONSTRAINT_VIOLATION + .formatted(PROP_CONTAINER_ARGS, PROP_HELM_CHART); + log.error(mesg); + throw new BadRequestException(mesg); + } + + if (helmChart != null && request.containerEnvironment() != null) { + var mesg = MESG_ONE_OF_PROPS_CONSTRAINT_VIOLATION + .formatted(PROP_CONTAINER_ENVIRONMENT, PROP_HELM_CHART); + log.error(mesg); + throw new BadRequestException(mesg); + } + + if (helmChart != null) { + var spec = request.gpuSpecification(); + var validationErrorMsg = revalClient.validate(ncaId, task, spec); + + if (StringUtils.isBlank(validationErrorMsg)) { + return; + } + + log.error(validationErrorMsg); + throw new BadRequestException(validationErrorMsg); + } + } + + // Container based Task should have empty configuration and helmValidationPolicy + // fields in gpuSpec. + private static void validateContainer(CreateTaskRequest request) { + var helmChart = request.helmChart(); + if (helmChart == null) { + var spec = request.gpuSpecification(); + if (spec.configuration() != null + && StringUtils.isNotBlank(spec.configuration().toString())) { + var mesg = MESG_CONFIGURATION_NOT_EMPTY; + log.error(mesg); + throw new BadRequestException(mesg); + } + if (spec.helmValidationPolicy() != null) { + var mesg = MESG_HELM_VALIDATION_POLICY_NOT_SUPPORTED; + log.error(mesg); + throw new BadRequestException(mesg); + } + } + } + + private void validateTelemetries(String ncaId, CreateTaskRequest request) { + var telemetriesDto = request.telemetries(); + if (telemetriesDto == null) { + return; + } + + // Invalidate cache for the specified account to fetch any new telemetries that may + // be defined before the Task is created. + accountService.invalidateCacheForSpecificAccount(ncaId); + var telemetryMap = accountService.getAccountTelemetryMap(ncaId); + + if (telemetriesDto.logsTelemetryId() != null) { + validateTelemetryType(ncaId, telemetryMap, telemetriesDto.logsTelemetryId(), LOGS); + } + + if (telemetriesDto.metricsTelemetryId() != null) { + validateTelemetryType(ncaId, telemetryMap, telemetriesDto.metricsTelemetryId(), METRICS); + } + + if (telemetriesDto.tracesTelemetryId() != null) { + validateTelemetryType(ncaId, telemetryMap, telemetriesDto.tracesTelemetryId(), TRACES); + } + } + + private static void validateTelemetryType( + String ncaId, + Map telemetryMap, + UUID telemetryId, + TelemetryTypeEnum expectedType) { + if (telemetryId == null) { + return; + } + + if (MapUtils.isEmpty(telemetryMap) || !telemetryMap.containsKey(telemetryId)) { + var mesg = MESG_TELEMETRY_NOT_AVAILABLE.formatted(telemetryId, ncaId); + log.error(mesg); + throw new BadRequestException(mesg); + } + + var telemetryDto = telemetryMap.get(telemetryId); + if (!telemetryDto.types().contains(expectedType)) { + var mesg = MESG_TELEMETRY_INVALID_TYPE.formatted(telemetryId, expectedType); + log.error(mesg); + throw new BadRequestException(mesg); + } + } + + // Determines if the instance-type can be used to specifically launch just a + // Container-based Task or any(Container / Helm) Task. + private static InstanceUsageTypeEnum getTaskContainerType(CreateTaskRequest request) { + if (Objects.nonNull(request.containerImage())) { + return InstanceUsageTypeEnum.CONTAINER; + } + return InstanceUsageTypeEnum.DEFAULT; + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/task/TaskMapperService.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/task/TaskMapperService.java new file mode 100644 index 000000000..e456b9826 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/task/TaskMapperService.java @@ -0,0 +1,355 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.task; + +import com.google.common.annotations.VisibleForTesting; +import com.nvidia.nvct.persistence.task.entity.HealthUdt; +import com.nvidia.nvct.persistence.task.entity.ModelUdt; +import com.nvidia.nvct.persistence.task.entity.ResourceUdt; +import com.nvidia.nvct.persistence.task.entity.ResultHandlingStrategy; +import com.nvidia.nvct.persistence.task.entity.TaskEntity; +import com.nvidia.nvct.persistence.task.entity.TaskStatus; +import com.nvidia.nvct.persistence.task.entity.TelemetriesUdt; +import com.nvidia.nvct.rest.task.dto.ArtifactDto; +import com.nvidia.nvct.rest.task.dto.BasicTaskDto; +import com.nvidia.nvct.rest.task.dto.ContainerEnvironmentEntryDto; +import com.nvidia.nvct.rest.task.dto.CreateTaskRequest; +import com.nvidia.nvct.rest.task.dto.HealthDto; +import com.nvidia.nvct.rest.task.dto.InstanceDto; +import com.nvidia.nvct.rest.task.dto.ResultHandlingStrategyEnum; +import com.nvidia.nvct.rest.task.dto.TaskDto; +import com.nvidia.nvct.rest.task.dto.TaskStatusEnum; +import com.nvidia.nvct.service.telemetry.dto.TelemetriesDto; +import java.net.URI; +import java.time.Duration; +import java.time.Instant; +import java.util.Base64; +import java.util.List; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import java.util.UUID; +import java.util.stream.Collectors; +import lombok.RequiredArgsConstructor; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; +import tools.jackson.core.JacksonException; +import tools.jackson.core.type.TypeReference; +import tools.jackson.databind.json.JsonMapper; + +@Slf4j +@Service +@RequiredArgsConstructor +public class TaskMapperService { + + public static final Duration DEFAULT_MAX_QUEUE_DURATION = Duration.parse("PT72H"); + public static final Duration DEFAULT_TERMINATION_GRACE_PERIOD_DURATION = Duration.parse("PT1H"); + private static final String MESG_DEFAULT_REGISTRY_MISSING = + "Default '%s' registry is missing"; + + private static final ListEnvTypeReference LIST_ENV_TYPE_REFERENCE = new ListEnvTypeReference(); + + private static class ListEnvTypeReference extends + TypeReference> { + } + + private final JsonMapper jsonMapper; + private final GpuSpecificationMapperService gpuSpecificationMapperService; + + + public TaskEntity toTaskEntity(String ncaId, CreateTaskRequest request) { + var models = getModelUdts(request.models()); + var resources = getResourceUdts(request.resources()); + var maxQueuedDuration = + Objects.requireNonNullElse(request.maxQueuedDuration(), DEFAULT_MAX_QUEUE_DURATION); + var terminationGracePeriodDuration = + Objects.requireNonNullElse(request.terminationGracePeriodDuration(), + DEFAULT_TERMINATION_GRACE_PERIOD_DURATION); + var resultStrategy = request.resultHandlingStrategy() == null ? + ResultHandlingStrategy.UPLOAD : + ResultHandlingStrategy.fromText(request.resultHandlingStrategy().toString()); + var serializedContainerEnvironment = + serializeContainerEnvironment(request.containerEnvironment()); + var taskId = UUID.randomUUID(); + var createdAt = Instant.now(); + var containerImage = Objects.nonNull(request.containerImage()) ? + request.containerImage().toString() : null; + var helmChart = Objects.nonNull(request.helmChart()) ? + request.helmChart().toString() : null; + return TaskEntity.builder() + .taskId(taskId) + .ncaId(ncaId) + .name(request.name()) + .status(TaskStatus.QUEUED) + .description(request.description()) + .tags(request.tags()) + .helmChart(helmChart) + .containerImage(containerImage) + .containerArgs(request.containerArgs()) + .containerEnvironment(serializedContainerEnvironment.orElse(null)) + .models(models.orElse(null)) + .resources(resources.orElse(null)) + .gpuSpec(gpuSpecificationMapperService.toGpuSpecUdt(request.gpuSpecification())) + .maxRuntimeDuration(request.maxRuntimeDuration()) + .maxQueuedDuration(maxQueuedDuration) + .terminalGracePeriodDuration(terminationGracePeriodDuration) + .resultHandlingStrategy(resultStrategy) + .resultsLocation(request.resultsLocation()) + .createdAt(createdAt) + .status(TaskStatus.QUEUED) + .telemetries(toTelemetriesUdt(request.telemetries()).orElse(null)) + .build(); + } + + public TaskDto toTaskDto(TaskEntity entity) { + return toTaskDto(entity, Optional.empty(), Optional.empty()); + } + + public TaskDto toTaskDto( + TaskEntity entity, + Optional> secrets, + Optional> instances) { + var resultHandlingStrategyRaw = entity.getResultHandlingStrategy().name(); + var deserializeContainerEnvironment = + deserializeContainerEnvironment(entity.getContainerEnvironment()); + var resultHandlingStrategy = ResultHandlingStrategyEnum.fromText(resultHandlingStrategyRaw); + var containerImage = StringUtils.isNotBlank(entity.getContainerImage()) ? + URI.create(entity.getContainerImage()) : null; + var helmChart = StringUtils.isNotBlank(entity.getHelmChart()) ? + URI.create(entity.getHelmChart()) : null; + var healthInfo = deserializeHealth(entity.getHealth()) + .or(() -> toHealthDto(entity.getLegacyHealthInfo())) + .orElse(null); + return TaskDto.builder() + .id(entity.getTaskId()) + .ncaId(entity.getNcaId()) + .name(entity.getName()) + .description(entity.getDescription()) + .tags(entity.getTags()) + .helmChart(helmChart) + .containerImage(containerImage) + .containerArgs(entity.getContainerArgs()) + .containerEnvironment(deserializeContainerEnvironment.orElse(null)) + .models(getModelDtos(entity.getModels()).orElse(null)) + .resources(getResourceDtos(entity.getResources()).orElse(null)) + .gpuSpecification( + gpuSpecificationMapperService.toGpuSpecificationDto(entity.getGpuSpec())) + .maxRuntimeDuration(entity.getMaxRuntimeDuration()) + .maxQueuedDuration(entity.getMaxQueuedDuration()) + .terminationGracePeriodDuration(entity.getTerminalGracePeriodDuration()) + .resultsLocation(entity.getResultsLocation()) + .resultHandlingStrategy(resultHandlingStrategy) + .percentComplete(entity.getPercentComplete()) + .status(toTaskStatusEnum(entity.getStatus())) + .healthInfo(healthInfo) + .lastHeartbeatAt(entity.getLastHeartbeatAt()) + .lastUpdatedAt(entity.getLastUpdatedAt()) + .createdAt(entity.getCreatedAt()) + .secrets(secrets.orElse(null)) + .instances(instances.orElse(null)) + .telemetries(toTelemetriesDto(entity.getTelemetries()).orElse(null)) + .build(); + } + + public BasicTaskDto toBasicTaskDto(TaskEntity taskEntity) { + return BasicTaskDto.builder() + .id(taskEntity.getTaskId()) + .name(taskEntity.getName()) + .status(toTaskStatusEnum(taskEntity.getStatus())) + .build(); + } + + @SneakyThrows + private Optional serializeContainerEnvironment( + List environment) { + if (Objects.isNull(environment) || environment.isEmpty()) { + return Optional.empty(); + } + + var json = jsonMapper.writeValueAsBytes(environment); + return Optional.of(Base64.getEncoder().encodeToString(json)); + } + + @SneakyThrows + private Optional> deserializeContainerEnvironment( + String env) { + if (StringUtils.isBlank(env)) { + return Optional.empty(); + } + + var json = Base64.getDecoder().decode(env); + return Optional.of(jsonMapper.readValue(json, LIST_ENV_TYPE_REFERENCE)); + } + + private Optional> getModelUdts(Set models) { + if (models == null) { + return Optional.empty(); + } + return Optional.of(models.stream() + .map(this::toModelUdt) + .collect(Collectors.toSet())); + } + + @VisibleForTesting + public Optional> getModelDtos(Set models) { + if (models == null) { + return Optional.empty(); + } + return Optional.of(models.stream() + .map(this::toArtifactDto) + .collect(Collectors.toSet())); + } + + private Optional> getResourceUdts(Set resources) { + if (resources == null) { + return Optional.empty(); + } + return Optional.of(resources.stream() + .map(this::toResourceUdt) + .collect(Collectors.toSet())); + } + + @VisibleForTesting + public Optional> getResourceDtos(Set resources) { + if (resources == null) { + return Optional.empty(); + } + return Optional.of(resources.stream() + .map(this::toArtifactDto) + .collect(Collectors.toSet())); + } + + private ModelUdt toModelUdt(ArtifactDto artifactDto) { + return ModelUdt.builder() + .name(artifactDto.getName()) + .version(artifactDto.getVersion()) + .url(artifactDto.getUri().toString()) + .build(); + } + + private ArtifactDto toArtifactDto(ModelUdt modelUdt) { + return ArtifactDto.builder() + .name(modelUdt.getName()) + .version(modelUdt.getVersion()) + .uri(URI.create(modelUdt.getUrl())) + .build(); + } + + private ArtifactDto toArtifactDto(ResourceUdt resourceUdt) { + return ArtifactDto.builder() + .name(resourceUdt.getName()) + .version(resourceUdt.getVersion()) + .uri(URI.create(resourceUdt.getUrl())) + .build(); + } + + private ResourceUdt toResourceUdt(ArtifactDto artifactDto) { + return ResourceUdt.builder() + .name(artifactDto.getName()) + .version(artifactDto.getVersion()) + .url(artifactDto.getUri().toString()) + .build(); + } + + @SneakyThrows + public Optional serializeHealth(HealthDto healthDto) { + if (healthDto == null) { + return Optional.empty(); + } + + return Optional.of(jsonMapper.writeValueAsString(healthDto)); + } + + @VisibleForTesting + public Optional deserializeHealth(String json) { + if (StringUtils.isBlank(json)) { + return Optional.empty(); + } + + try { + return Optional.of(jsonMapper.readValue(json, HealthDto.class)); + } catch (JacksonException e) { + log.error("Failed to deserialize task health: {}", e.getMessage(), e); + return Optional.empty(); + } + } + + public static Optional toHealthDto(HealthUdt udt) { + if (udt == null) { + return Optional.empty(); + } + + return Optional.of(HealthDto.builder() + .backend(udt.getBackend()) + .gpu(udt.getGpu()) + .instanceType(udt.getInstanceType()) + .error(udt.getError()) + .build()); + } + + private static Optional toTelemetriesUdt(TelemetriesDto telemetriesDto) { + if (telemetriesDto == null) { + return Optional.empty(); + } + + return Optional.of(TelemetriesUdt.builder() + .logsTelemetryId(telemetriesDto.logsTelemetryId()) + .metricsTelemetryId(telemetriesDto.metricsTelemetryId()) + .tracesTelemetryId(telemetriesDto.tracesTelemetryId()) + .build()); + } + + private static Optional toTelemetriesDto(TelemetriesUdt telemetriesUdt) { + if (telemetriesUdt == null) { + return Optional.empty(); + } + + return Optional.of(TelemetriesDto.builder() + .logsTelemetryId(telemetriesUdt.getLogsTelemetryId()) + .metricsTelemetryId(telemetriesUdt.getMetricsTelemetryId()) + .tracesTelemetryId(telemetriesUdt.getTracesTelemetryId()) + .build()); + } + + public static TaskStatus toTaskStatus(TaskStatusEnum taskStatusEnum) { + return switch (taskStatusEnum) { + case QUEUED -> TaskStatus.QUEUED; + case LAUNCHED -> TaskStatus.LAUNCHED; + case RUNNING -> TaskStatus.RUNNING; + case ERRORED -> TaskStatus.ERRORED; + case CANCELED -> TaskStatus.CANCELED; + case EXCEEDED_MAX_RUNTIME_DURATION -> TaskStatus.EXCEEDED_MAX_RUNTIME_DURATION; + case EXCEEDED_MAX_QUEUED_DURATION -> TaskStatus.EXCEEDED_MAX_QUEUED_DURATION; + case COMPLETED -> TaskStatus.COMPLETED; + }; + } + + private static TaskStatusEnum toTaskStatusEnum(TaskStatus taskStatus) { + return switch (taskStatus) { + case QUEUED -> TaskStatusEnum.QUEUED; + case LAUNCHED -> TaskStatusEnum.LAUNCHED; + case RUNNING -> TaskStatusEnum.RUNNING; + case ERRORED -> TaskStatusEnum.ERRORED; + case CANCELED -> TaskStatusEnum.CANCELED; + case EXCEEDED_MAX_RUNTIME_DURATION -> TaskStatusEnum.EXCEEDED_MAX_RUNTIME_DURATION; + case EXCEEDED_MAX_QUEUED_DURATION -> TaskStatusEnum.EXCEEDED_MAX_QUEUED_DURATION; + case COMPLETED -> TaskStatusEnum.COMPLETED; + }; + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/task/TaskPredicateUtils.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/task/TaskPredicateUtils.java new file mode 100644 index 000000000..0c625536a --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/task/TaskPredicateUtils.java @@ -0,0 +1,42 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.task; + +import static com.nvidia.nvct.service.apikeys.ApiKeysService.isApiKeyAuth; + +import java.util.Optional; +import java.util.UUID; +import lombok.experimental.UtilityClass; +import org.springframework.security.core.Authentication; + +@UtilityClass +public class TaskPredicateUtils { + + public static boolean taskAccessMatch( + Authentication authentication, + Optional optTaskId) { + return isApiKeyAuth(authentication).map(access -> { + if (access.privateTasksAllowed()) { + return true; + } + + return optTaskId + .map(access::hasResourcesScopedForTask) + .orElse(false); + }).orElseGet(() -> true); // JWT and others + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/task/TaskService.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/task/TaskService.java new file mode 100644 index 000000000..f3609b6e0 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/task/TaskService.java @@ -0,0 +1,340 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.task; + +import static com.datastax.oss.driver.api.core.data.ByteUtils.fromHexString; +import static com.datastax.oss.driver.api.core.data.ByteUtils.toHexString; +import static com.nvidia.nvct.service.task.TaskMapperService.toTaskStatus; +import static com.nvidia.nvct.util.NvctConstants.MESG_INVALID_CURSOR; +import static com.nvidia.nvct.util.NvctConstants.SPAN_TAG_NCA_ID; +import static com.nvidia.nvct.util.NvctConstants.SPAN_TAG_TASK_ID; +import static com.nvidia.nvct.util.NvctConstants.SPAN_TAG_TASK_STATUS; + +import tools.jackson.databind.json.JsonMapper; +import com.nvidia.boot.audit.event.AuditEventPayload; +import com.nvidia.boot.exceptions.BadRequestException; +import com.nvidia.boot.exceptions.NotFoundException; +import com.nvidia.nvct.persistence.task.TasksRepository; +import com.nvidia.nvct.persistence.task.entity.TaskEntity; +import com.nvidia.nvct.persistence.task.entity.TaskStatus; +import com.nvidia.nvct.rest.task.dto.HealthDto; +import com.nvidia.nvct.rest.task.dto.TaskDto; +import com.nvidia.nvct.rest.task.dto.TaskStatusEnum; +import com.nvidia.nvct.service.account.AccountService; +import com.nvidia.nvct.util.NvctUtils; +import io.micrometer.observation.annotation.Observed; +import io.micrometer.tracing.Tracer; +import jakarta.validation.constraints.NotNull; +import java.time.Instant; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.UUID; +import java.util.function.Predicate; +import java.util.stream.Stream; +import lombok.Builder; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.data.cassandra.core.query.CassandraPageRequest; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Slice; +import org.springframework.stereotype.Service; + +@Slf4j +@Service +@RequiredArgsConstructor +public class TaskService { + private static final String MESG_TASK_OPERATION = + "Task id '{}', status '{}': {}"; + private static final String MESG_TASK_NOT_FOUND = + "Task id '%s': Not found"; + private static final String MESG_TASK_NOT_IN_ACCOUNT = + "Task id '%s': Not found in account '%s'"; + private static final String MESG_BLANK_PARAMETER = "'%s' cannot be blank"; + private static final String MESG_CANNOT_BE_NULL = "Parameter '%s' cannot be null"; + + private final AccountService accountService; + private final TasksRepository tasksRepository; + private final TaskAuditService taskAuditService; + private final TaskMapperService taskMapperService; + private final JsonMapper jsonMapper; + private final Tracer tracer; + + public long countByNcaId(String ncaId) { + if (StringUtils.isBlank(ncaId)) { + var mesg = MESG_BLANK_PARAMETER.formatted("ncaId"); + log.error(mesg); + throw new IllegalArgumentException(mesg); + } + + return tasksRepository.countByNcaId(ncaId); + } + + public Optional lookupTask(UUID taskId) { + NvctUtils.addTagsToCurrentSpan(tracer, Map.of(SPAN_TAG_TASK_ID, taskId)); + return tasksRepository.getByTaskId(taskId); + } + + @NotNull + public TaskEntity fetchTask(UUID taskId) { + NvctUtils.addTagsToCurrentSpan(tracer, Map.of(SPAN_TAG_TASK_ID, taskId)); + return tasksRepository.getByTaskId(taskId) + .orElseThrow(() -> { + var mesg = MESG_TASK_NOT_FOUND.formatted(taskId); + log.error(mesg); + return new NotFoundException(mesg); + }); + } + + @Builder + public record TasksSliceContext(List tasks, String cursor, Integer limit) { + } + + public TasksSliceContext fetchTasksByAccount( + String ncaId, + int limit, + TaskStatusEnum status, + String cursor, + Predicate taskFilter) { + if (StringUtils.isBlank(ncaId)) { + var mesg = MESG_BLANK_PARAMETER.formatted("ncaId"); + log.error(mesg); + throw new IllegalArgumentException(mesg); + } + + Slice pagedResult; + try { + var byteBuffer = cursor == null ? null : fromHexString(cursor); + var pageable = PageRequest.of(0, limit); + var pageRequest = CassandraPageRequest.of(pageable, byteBuffer); + pagedResult = tasksRepository.findByNcaId(ncaId, pageRequest); + } catch (Exception e) { + var mesg = MESG_INVALID_CURSOR.formatted(cursor); + log.error(mesg); + throw new BadRequestException(mesg, e); + } + + var taskStatus = status == null ? null : toTaskStatus(status); + var dtos = pagedResult.getContent().stream() + .filter(task -> status == null || task.getStatus() == taskStatus) + .filter(taskFilter) + .map(taskMapperService::toTaskDto) + .toList(); + var builder = TasksSliceContext.builder().tasks(dtos); + if (pagedResult.hasNext()) { + var pagingState = ((CassandraPageRequest) pagedResult.getPageable()).getPagingState(); + builder.cursor(toHexString(pagingState)); + builder.limit(limit); + } + return builder.build(); + } + + public Stream fetchTasksByAccount(String ncaId) { + if (StringUtils.isBlank(ncaId)) { + var mesg = MESG_BLANK_PARAMETER.formatted("ncaId"); + log.error(mesg); + throw new IllegalArgumentException(mesg); + } + + return tasksRepository.findByNcaId(ncaId); + } + + @Observed(name = "task.save", contextualName = "save-task") + public TaskEntity saveTask(TaskEntity entity) { + var taskId = entity.getTaskId(); + + setSpanAttributes(entity); + tasksRepository.save(entity); + log.info(MESG_TASK_OPERATION, taskId, entity.getStatus(), "Saved task"); + return entity; + } + + @Observed(name = "task.delete", contextualName = "delete-task") + public void deleteTask(TaskEntity entity) { + var taskId = entity.getTaskId(); + setSpanAttributes(entity); + tasksRepository.delete(entity); + log.info(MESG_TASK_OPERATION, taskId, entity.getStatus(), "Deleted task"); + } + + public void deleteTask(UUID taskId) { + deleteTask(fetchTask(taskId)); + } + + @Observed(name = "task.update", contextualName = "update-task-by-id") + public TaskEntity updateTask(UUID taskId) { + Objects.requireNonNull(taskId, () -> MESG_CANNOT_BE_NULL.formatted("taskId")); + var taskEntity = fetchTask(taskId); + return updateTask(taskEntity); + } + + @Observed(name = "task.update", contextualName = "update-task") + public TaskEntity updateTask(TaskEntity entity) { + return updateTask(entity, true); + } + + @Observed(name = "task.update", contextualName = "update-task-with-audit") + public TaskEntity updateTask(TaskEntity entity, boolean shouldAudit) { + var jsonBefore = jsonMapper.valueToTree(entity); + + setSpanAttributes(entity); + entity.setLastUpdatedAt(Instant.now()); + entity = tasksRepository.insert(entity); + + final var finalEntity = entity; + var optPayloadBuilder = shouldAudit ? + Optional.of(taskAuditService.auditEventPayloadBuilder()) : + Optional.empty(); + optPayloadBuilder + .ifPresent(builder -> taskAuditService.auditTaskUpdate(builder, jsonBefore, + finalEntity)); + + var taskId = entity.getTaskId(); + var status = entity.getStatus(); + log.info(MESG_TASK_OPERATION, taskId, status, "Updated last_updated_at"); + return entity; + } + + @Observed(name = "task.update", contextualName = "update-task-status") + public TaskEntity updateTask(UUID taskId, TaskStatus status) { + var entity = fetchTask(taskId); + var jsonBefore = jsonMapper.valueToTree(entity); + + log.info(MESG_TASK_OPERATION, taskId, entity.getStatus(), "Updating status to " + status); + setSpanAttributes(entity); + entity.setStatus(status); + entity.setLastUpdatedAt(Instant.now()); + entity = tasksRepository.insert(entity); + + var payloadBuilder = taskAuditService.auditEventPayloadBuilder(); + taskAuditService.auditTaskUpdate(payloadBuilder, jsonBefore, entity); + log.info(MESG_TASK_OPERATION, taskId, entity.getStatus(), "Updated status"); + return entity; + } + + public TaskEntity updateTask(UUID taskId, TaskStatus status, Instant lastHeartbeatAt) { + return updateTask(taskId, status, lastHeartbeatAt, Optional.empty()); + } + + @Observed(name = "task.update", contextualName = "update-task-status-heartbeat") + public TaskEntity updateTask( + UUID taskId, + TaskStatus status, + Instant lastHeartbeatAt, + Optional percentComplete) { + var entity = fetchTask(taskId); + var payloadBuilder = taskAuditService.auditEventPayloadBuilder(); + var jsonBefore = jsonMapper.valueToTree(entity); + + setSpanAttributes(entity); + entity.setStatus(status); + entity.setLastHeartbeatAt(lastHeartbeatAt); + if (percentComplete.isPresent()) { + entity.setPercentComplete(percentComplete.get()); + } + entity.setLastUpdatedAt(Instant.now()); + entity = tasksRepository.insert(entity); + + taskAuditService.auditTaskUpdate(payloadBuilder, jsonBefore, entity); + log.info(MESG_TASK_OPERATION, + taskId, entity.getStatus(), + "Updated status, last_heartbeat_at, and maybe percent_complete"); + return entity; + } + + @Observed(name = "task.update", contextualName = "update-task-heartbeat") + public TaskEntity updateTask(UUID taskId, Instant lastHeartbeatAt) { + var entity = fetchTask(taskId); + var payloadBuilder = taskAuditService.auditEventPayloadBuilder(); + var jsonBefore = jsonMapper.valueToTree(entity); + + setSpanAttributes(entity); + entity.setLastHeartbeatAt(lastHeartbeatAt); + entity.setLastUpdatedAt(Instant.now()); + entity = tasksRepository.insert(entity); + + taskAuditService.auditTaskUpdate(payloadBuilder, jsonBefore, entity); + log.info(MESG_TASK_OPERATION, taskId, entity.getStatus(), "Updated last_heartbeat_at"); + return entity; + } + + @Observed(name = "task.update", contextualName = "update-task-status-health") + public TaskEntity updateTask(UUID taskId, TaskStatus status, HealthDto healthInfo) { + var entity = fetchTask(taskId); + var payloadBuilder = taskAuditService.auditEventPayloadBuilder(); + var jsonBefore = jsonMapper.valueToTree(entity); + + setSpanAttributes(entity); + entity.setStatus(status); + entity.setHealth(taskMapperService.serializeHealth(healthInfo).orElse(null)); + entity.setLastUpdatedAt(Instant.now()); + entity = tasksRepository.insert(entity); + + taskAuditService.auditTaskUpdate(payloadBuilder, jsonBefore, entity); + log.info(MESG_TASK_OPERATION, taskId, entity.getStatus(), "Updated status and health"); + return entity; + } + + public TaskEntity validateAccount(String ncaId, UUID taskId) { + Objects.requireNonNull(taskId, () -> MESG_CANNOT_BE_NULL.formatted("taskId")); + if (StringUtils.isBlank(ncaId)) { + var mesg = MESG_BLANK_PARAMETER.formatted("ncaId"); + log.error(mesg); + throw new IllegalArgumentException(mesg); + } + + // Validate account exists. + accountService.lookupAccountUsingNcaIdOrThrow(ncaId); + + // Ensure ncaId in Task definition matches the one that is passed in. + var taskEntity = fetchTask(taskId); + if (!taskEntity.getNcaId().equals(ncaId)) { + var mesg = MESG_TASK_NOT_IN_ACCOUNT.formatted(taskId, ncaId); + log.error(mesg); + throw new NotFoundException(mesg); + } + + return taskEntity; + } + + public void validateAccount(String ncaId, TaskEntity taskEntity) { + Objects.requireNonNull(taskEntity, () -> MESG_CANNOT_BE_NULL.formatted("taskEntity")); + if (StringUtils.isBlank(ncaId)) { + var mesg = MESG_BLANK_PARAMETER.formatted("ncaId"); + log.error(mesg); + throw new IllegalArgumentException(mesg); + } + + // Validate account exists. + accountService.lookupAccountUsingNcaIdOrThrow(ncaId); + + // Ensure ncaId in Task definition matches the one that is passed in. + if (!taskEntity.getNcaId().equals(ncaId)) { + var mesg = MESG_TASK_NOT_IN_ACCOUNT.formatted(taskEntity.getTaskId(), ncaId); + log.error(mesg); + throw new NotFoundException(mesg); + } + } + + private void setSpanAttributes(TaskEntity entity) { + NvctUtils.addTagsToCurrentSpan(tracer, Map.of(SPAN_TAG_NCA_ID, entity.getNcaId(), + SPAN_TAG_TASK_ID, entity.getTaskId(), + SPAN_TAG_TASK_STATUS, entity.getStatus())); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/telemetry/TelemetryService.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/telemetry/TelemetryService.java new file mode 100644 index 000000000..b49ac243d --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/telemetry/TelemetryService.java @@ -0,0 +1,97 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.telemetry; + +import tools.jackson.databind.json.JsonMapper; +import com.nvidia.boot.exceptions.BadRequestException; +import com.nvidia.nvct.persistence.task.entity.TelemetriesUdt; +import com.nvidia.nvct.service.account.AccountService; +import com.nvidia.nvct.service.telemetry.dto.TelemetryDto; +import java.nio.charset.StandardCharsets; +import java.util.Base64; +import java.util.Map; +import java.util.Optional; +import java.util.UUID; +import lombok.RequiredArgsConstructor; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; +import org.springframework.util.CollectionUtils; + +@Slf4j +@Service +@RequiredArgsConstructor +public class TelemetryService { + + private static final String MESG_TELEMETRY_NOT_AVAILABLE = + "Telemetry '%s': Not found in account '%s'"; + + private final AccountService accountService; + private final JsonMapper jsonMapper; + + public record Telemetries(TelemetryDto logsTelemetry, + TelemetryDto metricsTelemetry, + TelemetryDto tracesTelemetry) { } + + public record SerializeTelemetriesDto(Telemetries telemetries) { } + + @SneakyThrows + public String base64Encode(String ncaId, TelemetriesUdt telemetriesUdt) { + if (telemetriesUdt == null) { + return StringUtils.EMPTY; + } + + if (telemetriesUdt.getLogsTelemetryId() == null && + telemetriesUdt.getMetricsTelemetryId() == null && + telemetriesUdt.getTracesTelemetryId() == null) { + return StringUtils.EMPTY; + } + + // Serialized JSON should be as defined in section 4.2.5 of the SDD. + var telemetriesMap = accountService.getAccountTelemetryMap(ncaId); + var logsTelemetry = toTelemetryDto(ncaId, telemetriesMap, + telemetriesUdt.getLogsTelemetryId()); + var metricsTelemetry = toTelemetryDto(ncaId, telemetriesMap, + telemetriesUdt.getMetricsTelemetryId()); + var tracesTelemetry = toTelemetryDto(ncaId, telemetriesMap, + telemetriesUdt.getTracesTelemetryId()); + var telemetries = new Telemetries(logsTelemetry.orElse(null), + metricsTelemetry.orElse(null), + tracesTelemetry.orElse(null)); + var json = jsonMapper.writeValueAsString(new SerializeTelemetriesDto(telemetries)); + return Base64.getEncoder().encodeToString(json.getBytes(StandardCharsets.UTF_8)); + } + + private Optional toTelemetryDto( + String ncaId, + Map telemetryMap, + UUID telemetryId) { + if (telemetryId == null) { + return Optional.empty(); + } + + if (CollectionUtils.isEmpty(telemetryMap) || !telemetryMap.containsKey(telemetryId)) { + var mesg = MESG_TELEMETRY_NOT_AVAILABLE.formatted(telemetryId, ncaId); + log.error(mesg); + throw new BadRequestException(mesg); + } + + return Optional.of(telemetryMap.get(telemetryId)); + } + +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/telemetry/dto/TelemetriesDto.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/telemetry/dto/TelemetriesDto.java new file mode 100644 index 000000000..49de091b3 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/telemetry/dto/TelemetriesDto.java @@ -0,0 +1,38 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.telemetry.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.annotation.Nullable; +import java.util.UUID; +import lombok.Builder; + +@Builder +@Schema(description = "Telemetry configuration for logs, metrics, and traces.") +public record TelemetriesDto( + @Nullable + @Schema(description = "UUID representing the logs telemetry.") + UUID logsTelemetryId, + + @Nullable + @Schema(description = "UUID representing the metrics telemetry.") + UUID metricsTelemetryId, + + @Nullable + @Schema(description = "UUID representing the traces telemetry.") + UUID tracesTelemetryId) { +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/telemetry/dto/TelemetryDto.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/telemetry/dto/TelemetryDto.java new file mode 100644 index 000000000..7a4b4176d --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/telemetry/dto/TelemetryDto.java @@ -0,0 +1,52 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.telemetry.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; +import java.time.Instant; +import java.util.Set; +import java.util.UUID; +import lombok.Builder; + +@Builder +@Schema(description = "Data Transfer Object (DTO) for Telemetry configurations") +public record TelemetryDto( + + @Schema(description = "Unique telemetry ID") + @NotNull UUID telemetryId, + + @Schema(description = "Telemetry name") + @NotBlank String name, + + @Schema(description = "URL for the telemetry endpoint") + @NotBlank String endpoint, + + @Schema(description = "Protocol used for communication") + @NotNull TelemetryProtocolEnum protocol, + + @Schema(description = "Telemetry provider") + @NotNull TelemetryProviderEnum provider, + + @Schema(description = "Set of telemetry data types") + @NotNull @NotEmpty Set types, + + @Schema(description = "Telemetry creation timestamp") + @NotNull Instant createdAt) { +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/telemetry/dto/TelemetryProtocolEnum.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/telemetry/dto/TelemetryProtocolEnum.java new file mode 100644 index 000000000..d00b57068 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/telemetry/dto/TelemetryProtocolEnum.java @@ -0,0 +1,48 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.telemetry.dto; + +import java.util.EnumSet; +import lombok.NonNull; + +public enum TelemetryProtocolEnum { + HTTP("HTTP"), + GRPC("GRPC"); + + private static final String MESG_UNSUPPORTED_TELEMETRY_PROTOCOL = + "Unsupported telemetry protocol: '%s'"; + + private final String name; + + TelemetryProtocolEnum(String name) { + this.name = name; + } + + @Override + public String toString() { + return this.name; + } + + public static TelemetryProtocolEnum fromText(@NonNull String val) { + return EnumSet.allOf(TelemetryProtocolEnum.class) + .stream() + .filter(e -> e.name.equalsIgnoreCase(val)) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException(String.format(MESG_UNSUPPORTED_TELEMETRY_PROTOCOL, val))); + } + +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/telemetry/dto/TelemetryProviderEnum.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/telemetry/dto/TelemetryProviderEnum.java new file mode 100644 index 000000000..05d445a66 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/telemetry/dto/TelemetryProviderEnum.java @@ -0,0 +1,56 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.telemetry.dto; + +import java.util.EnumSet; +import lombok.NonNull; + +public enum TelemetryProviderEnum { + PROMETHEUS("PROMETHEUS"), + GRAFANA_CLOUD("GRAFANA_CLOUD"), + SPLUNK("SPLUNK"), + DATADOG("DATADOG"), + SERVICENOW("SERVICENOW"), + KRATOS("KRATOS"), + KRATOS_THANOS("KRATOS_THANOS"), + TIMESTREAM("TIMESTREAM"), + VICTORIAMETRICS("VICTORIAMETRICS"), + AZURE_MONITOR("AZURE_MONITOR"), + OTEL_COLLECTOR("OTEL_COLLECTOR"); + + private static final String MESG_UNSUPPORTED_TELEMETRY_PROVIDER = + "Unsupported telemetry provider: '%s'"; + + private final String name; + + TelemetryProviderEnum(String name) { + this.name = name; + } + + @Override + public String toString() { + return this.name; + } + + public static TelemetryProviderEnum fromText(@NonNull String val) { + return EnumSet.allOf(TelemetryProviderEnum.class) + .stream() + .filter(e -> e.name.equalsIgnoreCase(val)) + .findFirst() + .orElseThrow(() -> new IllegalArgumentException(String.format(MESG_UNSUPPORTED_TELEMETRY_PROVIDER,val))); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/telemetry/dto/TelemetryTypeEnum.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/telemetry/dto/TelemetryTypeEnum.java new file mode 100644 index 000000000..795207b85 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/telemetry/dto/TelemetryTypeEnum.java @@ -0,0 +1,51 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.telemetry.dto; + +import static java.lang.String.format; + +import java.util.EnumSet; +import lombok.NonNull; + +public enum TelemetryTypeEnum { + + LOGS("LOGS"), + METRICS("METRICS"), + TRACES("TRACES"); + + private static final String MESG_UNSUPPORTED_TELEMETRY_TYPE = + "Unsupported telemetry type: '%s'"; + + private final String name; + + TelemetryTypeEnum(String name) { + this.name = name; + } + + @Override + public String toString() { + return this.name; + } + + public static TelemetryTypeEnum fromText(@NonNull String val) { + return EnumSet.allOf(TelemetryTypeEnum.class) + .stream() + .filter(e -> e.name.equalsIgnoreCase(val)) + .findFirst() + .orElseThrow(() -> new IllegalStateException(format(MESG_UNSUPPORTED_TELEMETRY_TYPE, val))); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/token/GrpcAuthService.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/token/GrpcAuthService.java new file mode 100644 index 000000000..0ff8926a6 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/token/GrpcAuthService.java @@ -0,0 +1,53 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.token; + +import com.nvidia.boot.exceptions.ForbiddenException; +import com.nvidia.nvct.grpc.auth.AuthHeaderPassthroughServerHttpRequest; +import com.nvidia.nvct.grpc.auth.SecurityExpression; +import jakarta.servlet.http.HttpServletRequest; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.AuthenticationManagerResolver; +import org.springframework.security.core.Authentication; +import org.springframework.security.oauth2.server.resource.authentication.BearerTokenAuthenticationToken; +import org.springframework.stereotype.Service; + +@Slf4j +@Service +@RequiredArgsConstructor +public class GrpcAuthService { + + private final AuthenticationManagerResolver authenticationManagerResolver; + + /** + * grpc calls do not flow through the regular spring security filters, so we have to check manually + */ + public Authentication validateBearer( + BearerTokenAuthenticationToken bearer, + String... authorities) { + AuthenticationManager authenticationManager = authenticationManagerResolver.resolve( + new AuthHeaderPassthroughServerHttpRequest(bearer)); + Authentication authenticate = authenticationManager.authenticate(bearer); + boolean hasAnyAuthority = new SecurityExpression(authenticate).hasAnyAuthority(authorities); + if (!hasAnyAuthority) { + throw new ForbiddenException("missing task privileges"); + } + return authenticate; + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/token/TokenService.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/token/TokenService.java new file mode 100644 index 000000000..a4adb5cf4 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/token/TokenService.java @@ -0,0 +1,86 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.token; + +import com.nvidia.boot.exceptions.UnauthorizedException; +import com.nvidia.nvct.persistence.task.entity.TaskEntity; +import com.nvidia.nvct.service.account.AccountService; +import com.nvidia.nvct.service.token.client.NotaryClient; +import java.util.UUID; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.cloud.context.config.annotation.RefreshScope; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.stereotype.Service; + +@Slf4j +@Service +@RefreshScope +public class TokenService { + private static final String MESG_MISSING_TOKEN = "Missing token"; + + private final NotaryClient notaryClient; + private final AccountService accountService; + private final WorkerAssertionValidator workerAssertionValidator; + + public TokenService( + NotaryClient notaryClient, + AccountService accountService, + WorkerAssertionValidator workerAssertionValidator) { + this.notaryClient = notaryClient; + this.accountService = accountService; + this.workerAssertionValidator = workerAssertionValidator; + } + + public String issueSecretsAssertion(TaskEntity task) { + var taskId = task.getTaskId(); + var ncaId = task.getNcaId(); + var taskSecretsPresent = task.hasSecrets(); + var telemetries = task.getTelemetries(); + var telemetrySecretsPresent = (telemetries != null); + + if (telemetrySecretsPresent && taskSecretsPresent) { + return notaryClient.issueSecretPathsAssertionToken(ncaId, taskId, telemetries); + } else if (telemetrySecretsPresent) { + return notaryClient.issueSecretPathsAssertionToken(ncaId, telemetries); + } else if (taskSecretsPresent) { + return notaryClient.issueSecretPathsAssertionToken(taskId); + } + + return StringUtils.EMPTY; + } + + public String issueWorkerAccessAssertion(String ncaId, UUID taskId) { + accountService.getAccountName(ncaId); + return notaryClient.issueWorkerAccessAssertionToken(ncaId, taskId); + } + + public void validateWorkerAccessAssertion(String ncaId, UUID taskId) { + accountService.getAccountName(ncaId); + workerAssertionValidator.validate(getAccessToken(), ncaId, taskId); + } + + private static String getAccessToken() { + var authentication = SecurityContextHolder.getContext().getAuthentication(); + if (authentication == null || !(authentication.getCredentials() instanceof String token)) { + log.error(MESG_MISSING_TOKEN); + throw new UnauthorizedException(MESG_MISSING_TOKEN); + } + return token; + } + +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/token/WorkerAssertionValidator.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/token/WorkerAssertionValidator.java new file mode 100644 index 000000000..31c1db214 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/token/WorkerAssertionValidator.java @@ -0,0 +1,154 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.token; + +import tools.jackson.core.JacksonException; +import tools.jackson.databind.json.JsonMapper; +import com.nvidia.boot.exceptions.ForbiddenException; +import com.nvidia.nvct.service.token.client.NotaryStubService.WorkerAccessAssertion; +import java.time.Clock; +import java.time.Duration; +import java.time.Instant; +import java.util.Map; +import java.util.UUID; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.security.oauth2.jwt.Jwt; +import org.springframework.security.oauth2.jwt.JwtDecoder; +import org.springframework.security.oauth2.jwt.JwtException; +import org.springframework.stereotype.Component; + +@Slf4j +@Component +public class WorkerAssertionValidator { + + private static final String MESG_INVALID_SIGNATURE = + "Task id '%s': Invalid worker assertion token"; + private static final String MESG_INVALID_ISSUER = + "Task id '%s': Invalid or missing issuer in worker assertion token"; + private static final String MESG_EXPIRED_TOKEN = + "Task id '%s': Expired worker assertion token"; + private static final String MESG_INVALID_SUBJECT = + "Task id '%s': Invalid or missing subject in worker assertion token"; + private static final String MESG_INVALID_ASSERTION = + "Task id '%s': Invalid or missing assertion claim in worker assertion token"; + private static final String MESG_MISMATCH_NCA_ID = + "NCA id '%s': Does not match the one in the access token"; + private static final String MESG_MISMATCH_TASK_ID = + "Task id '%s': Does not match the one in the access token"; + + private static final Duration VALIDITY = Duration.ofHours(3); + + private final JwtDecoder jwtDecoder; + private final JsonMapper jsonMapper; + private final Clock clock; + private final String issuer; + private final String subject; + + public WorkerAssertionValidator( + @Qualifier("notaryJwtDecoder") JwtDecoder jwtDecoder, + JsonMapper jsonMapper, + Clock clock, + @Value("${nvct.notary.base-url}") String issuer, + @Value("${spring.security.oauth2.client.registration.notary.client-id}") + String subject) { + this.jwtDecoder = jwtDecoder; + this.jsonMapper = jsonMapper; + this.clock = clock; + this.issuer = issuer; + this.subject = subject; + } + + public void validate(String token, String ncaId, UUID taskId) { + var jwt = decode(token, taskId); + validateIssuer(jwt, taskId); + validateIssuedAt(jwt, taskId); + validateSubject(jwt, taskId); + var accessAssertion = getAssertion(jwt, taskId); + + if (!accessAssertion.ncaId().equals(ncaId)) { + var mesg = MESG_MISMATCH_NCA_ID.formatted(ncaId); + log.error(mesg); + throw new ForbiddenException(mesg); + } + + if (!accessAssertion.taskId().equals(taskId)) { + var mesg = MESG_MISMATCH_TASK_ID.formatted(taskId); + log.error(mesg); + throw new ForbiddenException(mesg); + } + } + + private Jwt decode(String token, UUID taskId) { + try { + return jwtDecoder.decode(token); + } catch (JwtException ex) { + var mesg = MESG_INVALID_SIGNATURE.formatted(taskId); + log.error(mesg, ex); + throw new ForbiddenException(mesg, ex); + } + } + + private void validateIssuer(Jwt jwt, UUID taskId) { + if (jwt.getIssuer() == null || !issuer.equals(jwt.getIssuer().toString())) { + var mesg = MESG_INVALID_ISSUER.formatted(taskId); + log.error(mesg); + throw new ForbiddenException(mesg); + } + } + + private void validateIssuedAt(Jwt jwt, UUID taskId) { + var issuedAt = jwt.getIssuedAt(); + if (issuedAt == null) { + var mesg = MESG_EXPIRED_TOKEN.formatted(taskId); + log.error(mesg); + throw new ForbiddenException(mesg); + } + if (issuedAt.plus(VALIDITY).isBefore(Instant.now(clock))) { + var mesg = MESG_EXPIRED_TOKEN.formatted(taskId); + log.error(mesg); + throw new ForbiddenException(mesg); + } + } + + private void validateSubject(Jwt jwt, UUID taskId) { + if (StringUtils.isBlank(jwt.getSubject()) || !jwt.getSubject().equals(subject)) { + var mesg = MESG_INVALID_SUBJECT.formatted(taskId); + log.error(mesg); + throw new ForbiddenException(mesg); + } + } + + private WorkerAccessAssertion getAssertion(Jwt jwt, UUID taskId) { + try { + var assertionClaim = jwt.getClaim("assertion"); + if (!(assertionClaim instanceof Map assertionMap)) { + var mesg = MESG_INVALID_ASSERTION.formatted(taskId); + log.error(mesg); + throw new ForbiddenException(mesg); + } + var assertionJson = jsonMapper.writeValueAsString(assertionMap); + return jsonMapper.readValue(assertionJson, WorkerAccessAssertion.class); + } catch (JacksonException | IllegalArgumentException ex) { + var mesg = MESG_INVALID_ASSERTION.formatted(taskId); + log.error(mesg, ex); + throw new ForbiddenException(mesg, ex); + } + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/token/client/NotaryAudiencesConfiguration.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/token/client/NotaryAudiencesConfiguration.java new file mode 100644 index 000000000..1c8fb6fc2 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/token/client/NotaryAudiencesConfiguration.java @@ -0,0 +1,31 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.token.client; + +import java.util.Map; +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.cloud.context.config.annotation.RefreshScope; +import org.springframework.context.annotation.Configuration; + +@Configuration +@ConfigurationProperties(prefix = "nvct.notary") +@RefreshScope +@Data +public class NotaryAudiencesConfiguration { + private Map audiences; +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/token/client/NotaryClient.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/token/client/NotaryClient.java new file mode 100644 index 000000000..21cde18fa --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/token/client/NotaryClient.java @@ -0,0 +1,188 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.token.client; + +import static com.nvidia.nvct.util.NvctConstants.ESS_NAMESPACE; +import static java.lang.String.format; + +import com.nvidia.boot.exceptions.UpstreamException; +import com.nvidia.nvct.configuration.staticclientauth.FixedBearerExchangeFilterFunction; +import com.nvidia.nvct.configuration.staticclientauth.StaticClientAuthConfiguration.StaticClientNotaryProperties; +import com.nvidia.nvct.persistence.task.entity.TelemetriesUdt; +import com.nvidia.nvct.service.ess.EssService; +import com.nvidia.nvct.service.token.client.NotaryStubService.SecretPathsAssertion; +import com.nvidia.nvct.service.token.client.NotaryStubService.SignResponse; +import com.nvidia.nvct.service.token.client.NotaryStubService.SignSecretPathsRequest; +import com.nvidia.nvct.service.token.client.NotaryStubService.SignWorkerAccessRequest; +import com.nvidia.nvct.service.token.client.NotaryStubService.WorkerAccessAssertion; +import com.nvidia.nvct.util.NvctOAuth2ClientUtils; +import com.nvidia.nvct.util.NvctOAuth2ClientUtils.ManagedHttpResources; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.UUID; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.cloud.context.config.annotation.RefreshScope; +import org.springframework.stereotype.Service; +import org.springframework.web.reactive.function.client.ExchangeFilterFunction; +import org.springframework.web.reactive.function.client.WebClient; +import org.springframework.web.reactive.function.client.support.WebClientAdapter; +import org.springframework.web.service.invoker.HttpServiceProxyFactory; + +@Service +@RefreshScope +@Slf4j +public class NotaryClient { + + public enum Audience { + ESS, + NVCT; + } + + private static final String TELEMETRY_SECRETS_PATH_TEMPLATE = "accounts/%s/telemetries/%s"; + private static final String TASKS_SECRETS_PATH_TEMPLATE = "tasks/%s/secrets"; + private static final String MESG_ASSERTION_MISSING_MESSAGE = + "Assertion missing from notary response"; + public static final String CLIENT_REGISTRATION_ID = "notary"; + + private final NotaryStubService notaryStubService; + private final Map audiences; + private final EssService essService; + + // We could have used OAuth2AuthorizedClientManager and relied on Spring Security to + // pick up the configuration properties using ClientRegistrationRepository directly. However, + // the client-secret value held in the ClientRegistrationRepository does not get refreshed when + // client-secret is rotated. Addressing these issues requires introducing a refreshable + // ClientRegistrationRepository that wasn't clean. Instead, we will keep it simple and use + // the tried and tested approach of using @Value and @RefreshScope annotations and wire + // things up ourselves. + public NotaryClient( + @Value("${nvct.notary.base-url}") String baseUrl, + @Value("${spring.security.oauth2.client.registration.notary.client-id}") String clientId, + @Value("${spring.security.oauth2.client.registration.notary.client-secret}") String clientSecret, + @Value("${spring.security.oauth2.client.registration.notary.scope}") String scope, + @Value("${spring.security.oauth2.client.provider.notary.token-uri}") String tokenUri, + NotaryAudiencesConfiguration audiencesConfiguration, + EssService essService, + ManagedHttpResources notaryHttpResources, + WebClient.Builder webClientBuilder, // Prototype-scoped - Safe to mutate. + Optional staticClientNotaryProperties) { + this.audiences = audiencesConfiguration.getAudiences(); + this.essService = essService; + var authFilter = oauthFilter(staticClientNotaryProperties, webClientBuilder, + clientId, clientSecret, scope, tokenUri); + var webClient = webClientBuilder + .baseUrl(baseUrl) + .clientConnector(notaryHttpResources.connector()) + .filter(NvctOAuth2ClientUtils.getRetryableFilter(CLIENT_REGISTRATION_ID)) + .filter(authFilter) + .filter(NvctOAuth2ClientUtils.getResponseFilterProcessor("Notary")) + .build(); + var adapter = WebClientAdapter.create(webClient); + var factory = HttpServiceProxyFactory.builderFor(adapter).build(); + this.notaryStubService = factory.createClient(NotaryStubService.class); + } + + private static ExchangeFilterFunction oauthFilter( + Optional staticClientNotaryProperties, + WebClient.Builder webClientBuilder, + String clientId, + String clientSecret, + String scope, + String tokenUri) { + return staticClientNotaryProperties + .map(p -> (ExchangeFilterFunction) + new FixedBearerExchangeFilterFunction(p::getToken)) + .orElseGet(() -> NvctOAuth2ClientUtils + .getOAuth2ExchangeFilter(webClientBuilder, CLIENT_REGISTRATION_ID, + tokenUri, clientId, clientSecret, scope)); + } + + public String issueSecretPathsAssertionToken(String ncaId, TelemetriesUdt telemetries) { + var paths = getTelemetrySecretPaths(ncaId, telemetries); + return issueSecretPathsAssertionTokenInternal(paths); + } + + public String issueSecretPathsAssertionToken(UUID taskId) { + var paths = Set.of(String.format(TASKS_SECRETS_PATH_TEMPLATE, taskId)); + return issueSecretPathsAssertionTokenInternal(paths); + } + + public String issueSecretPathsAssertionToken( + String ncaId, + UUID taskId, + TelemetriesUdt telemetries) { + var paths = getTelemetrySecretPaths(ncaId, telemetries); + paths.add(String.format(TASKS_SECRETS_PATH_TEMPLATE, taskId)); + return issueSecretPathsAssertionTokenInternal(paths); + } + + public String issueWorkerAccessAssertionToken(String ncaId, UUID taskId) { + var assertion = new WorkerAccessAssertion(ncaId, taskId); + var audience = audiences.get(Audience.NVCT); + var request = new SignWorkerAccessRequest(List.of(audience), assertion); + var response = notaryStubService.signWorkerAccess(request); + return Optional.ofNullable(response) + .map(SignResponse::assertion) + .orElseThrow(() -> new UpstreamException(MESG_ASSERTION_MISSING_MESSAGE)); + } + + private String issueSecretPathsAssertionTokenInternal(Set paths) { + var assertions = new SecretPathsAssertion(ESS_NAMESPACE, paths.stream().toList()); + var audience = audiences.get(Audience.ESS); + var secretPathsRequest = new SignSecretPathsRequest(List.of(audience), assertions); + var response = notaryStubService.signSecretPaths(secretPathsRequest); + return Optional.ofNullable(response) + .map(SignResponse::assertion) + .orElseThrow(() -> new UpstreamException(MESG_ASSERTION_MISSING_MESSAGE)); + } + + private Set getTelemetrySecretPaths( + String ncaId, + TelemetriesUdt telemetries) { + var telemetrySecretPaths = new HashSet(); + if (telemetries == null) { + return telemetrySecretPaths; // Return an updatable/modifiable set. + } + + var logsTelemetryId = telemetries.getLogsTelemetryId(); + if (logsTelemetryId != null + && essService.telemetrySecretExist(ncaId, logsTelemetryId)) { + var path = format(TELEMETRY_SECRETS_PATH_TEMPLATE, ncaId, logsTelemetryId); + telemetrySecretPaths.add(path); + } + + var metricsTelemetryId = telemetries.getMetricsTelemetryId(); + if (metricsTelemetryId != null + && essService.telemetrySecretExist(ncaId, metricsTelemetryId)) { + var path = format(TELEMETRY_SECRETS_PATH_TEMPLATE, ncaId, metricsTelemetryId); + telemetrySecretPaths.add(path); + } + + var tracesTelemetryId = telemetries.getTracesTelemetryId(); + if (tracesTelemetryId != null + && essService.telemetrySecretExist(ncaId, tracesTelemetryId)) { + var path = format(TELEMETRY_SECRETS_PATH_TEMPLATE, ncaId, tracesTelemetryId); + telemetrySecretPaths.add(path); + } + return telemetrySecretPaths; + } + +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/token/client/NotaryStubService.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/token/client/NotaryStubService.java new file mode 100644 index 000000000..c5615944d --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/token/client/NotaryStubService.java @@ -0,0 +1,56 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.token.client; + +import tools.jackson.databind.PropertyNamingStrategies.SnakeCaseStrategy; +import tools.jackson.databind.annotation.JsonNaming; +import java.util.List; +import java.util.UUID; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.service.annotation.PostExchange; + +public interface NotaryStubService { + + @PostExchange("/sign") + SignResponse signSecretPaths(@RequestBody SignSecretPathsRequest request); + + @PostExchange("/sign") + SignResponse signWorkerAccess(@RequestBody SignWorkerAccessRequest request); + + record SecretPathsAssertion(String namespace, List secretPaths) { + } + + @JsonNaming(SnakeCaseStrategy.class) + record SignSecretPathsRequest( + List audienceServiceIds, + SecretPathsAssertion data) { + } + + record WorkerAccessAssertion(String ncaId, UUID taskId) { + } + + @JsonNaming(SnakeCaseStrategy.class) + record SignWorkerAccessRequest( + List audienceServiceIds, + WorkerAccessAssertion data) { + } + + @JsonNaming(SnakeCaseStrategy.class) + record SignResponse(String assertion) { + + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/util/NvctConstants.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/util/NvctConstants.java new file mode 100644 index 000000000..c41187354 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/util/NvctConstants.java @@ -0,0 +1,166 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.util; + +import static com.nvidia.nvct.persistence.task.entity.TaskStatus.CANCELED; +import static com.nvidia.nvct.persistence.task.entity.TaskStatus.COMPLETED; +import static com.nvidia.nvct.persistence.task.entity.TaskStatus.ERRORED; +import static com.nvidia.nvct.persistence.task.entity.TaskStatus.EXCEEDED_MAX_QUEUED_DURATION; +import static com.nvidia.nvct.persistence.task.entity.TaskStatus.EXCEEDED_MAX_RUNTIME_DURATION; + +import com.nvidia.nvct.persistence.task.entity.TaskStatus; +import java.nio.charset.StandardCharsets; +import java.util.Base64; +import java.util.Collections; +import java.util.EnumSet; +import java.util.Set; +import java.util.UUID; +import lombok.experimental.UtilityClass; + +@UtilityClass +public final class NvctConstants { + + // Super-Admin Scopes + public static final String ADMIN_SCOPE_LAUNCH_TASK = "admin:launch_task"; + public static final String ADMIN_SCOPE_LIST_TASKS = "admin:list_tasks"; + public static final String ADMIN_SCOPE_TASK_DETAILS = "admin:task_details"; + public static final String ADMIN_SCOPE_CANCEL_TASK = "admin:cancel_task"; + public static final String ADMIN_SCOPE_DELETE_TASK = "admin:delete_task"; + public static final String ADMIN_SCOPE_LIST_EVENTS = "admin:list_events"; + public static final String ADMIN_SCOPE_LIST_RESULTS = "admin:list_results"; + public static final String ADMIN_SCOPE_UPDATE_SECRETS = "admin:update_secrets"; + public static final Set SUPER_ADMIN_SCOPES = Set.of(ADMIN_SCOPE_LAUNCH_TASK, + ADMIN_SCOPE_LIST_TASKS, + ADMIN_SCOPE_TASK_DETAILS, + ADMIN_SCOPE_CANCEL_TASK, + ADMIN_SCOPE_DELETE_TASK, + ADMIN_SCOPE_LIST_EVENTS, + ADMIN_SCOPE_LIST_RESULTS, + ADMIN_SCOPE_UPDATE_SECRETS); + + // Account-Admin Scopes + public static final String SCOPE_LAUNCH_TASK = "launch_task"; + public static final String SCOPE_LIST_TASKS = "list_tasks"; + public static final String SCOPE_TASK_DETAILS = "task_details"; + public static final String SCOPE_CANCEL_TASK = "cancel_task"; + public static final String SCOPE_DELETE_TASK = "delete_task"; + public static final String SCOPE_LIST_EVENTS = "list_events"; + public static final String SCOPE_LIST_RESULTS = "list_results"; + public static final String SCOPE_UPDATE_SECRETS = "update_secrets"; + public static final Set ACCOUNT_ADMIN_SCOPES = Set.of(SCOPE_LAUNCH_TASK, + SCOPE_LIST_TASKS, + SCOPE_TASK_DETAILS, + SCOPE_CANCEL_TASK, + SCOPE_DELETE_TASK, + SCOPE_LIST_EVENTS, + SCOPE_LIST_RESULTS, + SCOPE_UPDATE_SECRETS); + + // Base64 encoded empty JSON array []. + public static final String DEFAULT_CONTAINER_ENV = Base64.getEncoder() + .encodeToString("[]".getBytes(StandardCharsets.UTF_8)); + + public static final String REQUEST_URI = "requestUri"; + public static final String REMOTE_ADDRESS = "remoteAddress"; + public static final String HTTP_METHOD = "httpMethod"; + public static final String UNKNOWN = "UNKNOWN"; + public static final String ACTOR_ID_DELIMITER = "_"; + public static final String NGC_API_KEY = "NGC_API_KEY"; + + public static final String TASK_OBJECT_LOCATION = "urn:nvcf:cassandra:nvct:tasks"; + + public static final String GRP_TYPE_TASK_MANAGEMENT = "TASK_MANAGEMENT"; + + public static final String OPER_CREATE_TASK = "CREATE_TASK"; + public static final String OPER_CANCEL_TASK = "CANCEL_TASK"; + public static final String OPER_DELETE_TASK = "DELETE_TASK"; + public static final String OPER_UPDATE_TASK = "UPDATE_TASK"; + + public static final String SUMMARY_CREATE_TASK = "Created task '%s' for account '%s'"; + public static final String SUMMARY_CANCEL_TASK = "Canceled task '%s'"; + public static final String SUMMARY_DELETE_TASK = "Deleted task '%s'"; + public static final String SUMMARY_UPDATE_TASK = "Updated task '%s' status to '%s'"; + public static final String SUMMARY_UPDATE_TASK_HEARTBEAT = "Updated task '%s' heartbeat"; + public static final String SUMMARY_UPDATE_TASK_ENTITY = "Updated task '%s' entity"; + + public static final String STATE_CREATED = "CREATED"; + public static final String STATE_CANCELED = "CANCELED"; + public static final String STATE_DELETED = "DELETED"; + public static final String STATE_UPDATED = "UPDATED"; + + public static final String NCA_ID = "nca_id"; + public static final String TASK_ID = "task_id"; + public static final String TASK_STATUS = "task_status"; + public static final String UPDATE_TYPE = "update_type"; + public static final String UPDATE_TYPE_STATUS = "status"; + public static final String UPDATE_TYPE_HEARTBEAT = "heartbeat"; + public static final String UPDATE_TYPE_ENTITY = "entity"; + + public static final String ENC_KEY_NAME = "current-kid"; + + public static final String SPAN_TAG_TASK_ID = "task_id"; + public static final String SPAN_TAG_TASK_NAME = "task_name"; + public static final String SPAN_TAG_NCA_ID = "nca_id"; + public static final String SPAN_TAG_ACCOUNT_NAME = "account_name"; + public static final String SPAN_TAG_TASK_STATUS = "task_status"; + + public static final int MAX_TAGS_COUNT = 64; + public static final int MAX_TAG_LENGTH = 128; + public static final int MAX_DESCRIPTION_LENGTH = 256; + public static final String NAME_REGEX = "^[a-z0-9A-Z][a-z0-9A-Z\\-_]*$"; + + public static final UUID UUID_WILDCARD = new UUID(0, 0); + + public static final String DEFAULT_PAGINATION_LIMIT = "10"; + public static final String MESG_INVALID_CURSOR = "Invalid cursor: '%s'"; + + // Metrics - Meter names + public static final String METER_TASK_RUNNING = "nvct.task.running"; + public static final String METER_TASK_SUCCESS = "nvct.task.success"; + public static final String METER_TASK_ERROR = "nvct.task.error"; + + // Metrics - Tag names + public static final String TAG_NCA_ID = "nca_id"; + public static final String TAG_TASK_ID = "task_id"; + public static final String TAG_ORG_NAME = "account_name"; + public static final String TAG_ERROR_SOURCE = "error_source"; + + public static final String ESS_NAMESPACE = "nvcf"; + + public static final Set TERMINAL_TASK_STATUSES = + Collections.unmodifiableSet(EnumSet.of(CANCELED, + COMPLETED, + ERRORED, + EXCEEDED_MAX_RUNTIME_DURATION, + EXCEEDED_MAX_QUEUED_DURATION)); + + public static final int MAX_BUFFER_LIMIT = 10 * 1024 * 1024; + + public static final int MAX_SECRET_VALUE_LENGTH = 32768; + public static final int MAX_SECRET_NAME_LENGTH = 48; + + + // Hostname Syntax - https://en.wikipedia.org/wiki/Hostname#Syntax + // public static final String HOSTNAME_REGEX = "^[a-z0-9A-Z][a-z0-9A-Z\\-.]*$"; + // public static final String HOSTNAME_REGEX = "^[A-Za-z0-9][A-Za-z0-9-.]*\\.\\D{2,4}$"; + public static final String HOSTNAME_REGEX = + "(?=^.{4,253}$)(^((?!-)[a-zA-Z0-9-]{1,63}(? connection + .addHandlerFirst(new ReadTimeoutHandler(READ_TIMEOUT, TimeUnit.SECONDS)) + .addHandlerFirst(new WriteTimeoutHandler(WRITE_TIMEOUT, TimeUnit.SECONDS))) + .responseTimeout(RESPONSE_TIMEOUT_DURATION) + .followRedirect(true) + .runOn(loopResources); + httpClient.warmup().block(); + return new ManagedHttpResources( + new ReactorClientHttpConnector(httpClient), + provider, + loopResources, + clientRegistrationId); + } + + // Returns a retry filter for both token server and resource server. Retries twice on + // 5xx from either the resource server or token server - server_error, temporarily_unavailable, + // or HTTP 5xx and then throws UpstreamException. + // + // For other ClientAuthorizationException (auth failures typically from token server), retries + // once and throws UnauthorizedException with details if the retry fails. + public static ExchangeFilterFunction getRetryableFilter(String upstream) { + var svcName = upstream.toUpperCase(); + var retrySpec = Retry.backoff(2, Duration.ofMillis(200)) + .jitter(0.75) + .doBeforeRetry(retrySignal -> log.info("Before retrying {} call", svcName)) + .doAfterRetry(retrySignal -> log.info("After retrying {} call", svcName)) + .filter(throwable -> throwable instanceof UpstreamException + || isTokenServer5xx(throwable)) + .onRetryExhaustedThrow((retryBackoffSpec, retrySignal) -> { + log.error("{} failed to process after max retries", svcName); + var mesg = "Failed to get response from '%s' after retries.".formatted(svcName); + return new UpstreamException(mesg); + }); + + return (request, next) -> next.exchange(request) + .onErrorResume(ClientAuthorizationException.class, ex -> { + if (isTokenServer5xx(ex)) { + return Mono.error(ex); + } + log.warn("OAuth2 token fetch failed for '{}', retrying: {}", svcName, + ex.getMessage()); + return next.exchange(request) + .onErrorResume(ClientAuthorizationException.class, retryEx -> { + var mesg = getClientAuthErrorMessage(svcName, retryEx); + return Mono.error(new UnauthorizedException(mesg, ex)); + }); + }) + .flatMap(clientResponse -> Mono.just(clientResponse).thenReturn(clientResponse)) + .retryWhen(retrySpec); + } + + public static ServerOAuth2AuthorizedClientExchangeFilterFunction getOAuth2ExchangeFilter( + WebClient.Builder webClientBuilder, + String clientRegistrationId, + String tokenUri, + String clientId, + String clientSecret, + String scope) { + var scopes = StringUtils.isBlank(scope) ? List.of() : + Arrays.stream(scope.split(",")).map(String::trim).toList(); + var clientRegistration = ClientRegistration.withRegistrationId(clientRegistrationId) + .authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS) + .clientId(clientId) + .clientSecret(clientSecret) + .scope(scopes) + .tokenUri(tokenUri) + .build(); + var clientRegistrationRepository = + new InMemoryReactiveClientRegistrationRepository(clientRegistration); + var clientService = + new InMemoryReactiveOAuth2AuthorizedClientService(clientRegistrationRepository); + + // Use the Boot-customized builder for the token endpoint so token and resource calls + // share the same observation convention. When the token client used a raw + // WebClient.builder(), it registered http.client.requests with legacy tag keys while + // resource clients registered the same metric name with Boot's current tag keys. + // Prometheus requires every time series under the same metric name to have the same tag + // keys, so it rejected the resource-server meters after the token-server meter existed. + var tokenWebClient = webClientBuilder.clone() + .build(); + var tokenResponseClient = new WebClientReactiveClientCredentialsTokenResponseClient(); + tokenResponseClient.setWebClient(tokenWebClient); + + var clientCredentialsProvider = + new ClientCredentialsReactiveOAuth2AuthorizedClientProvider(); + clientCredentialsProvider.setAccessTokenResponseClient(tokenResponseClient); + + var reactiveClientManager = + new AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager( + clientRegistrationRepository, clientService); + reactiveClientManager.setAuthorizedClientProvider(clientCredentialsProvider); + + var oauth2ExchangeFilter = + new ServerOAuth2AuthorizedClientExchangeFilterFunction(reactiveClientManager); + oauth2ExchangeFilter.setDefaultClientRegistrationId(clientRegistrationId); + return oauth2ExchangeFilter; + } + + public static ExchangeFilterFunction getResponseFilterProcessor(String upstream) { + return ExchangeFilterFunction.ofResponseProcessor(response -> { + if (response.statusCode().is5xxServerError()) { + return handle5xxError(upstream, response); + } + if (response.statusCode().is4xxClientError()) { + return handle4xxError(upstream, response); + } + return Mono.just(response); + }); + } + + private static Mono handle4xxError( + String serviceName, ClientResponse response) { + var status = response.statusCode(); + var errorMsg = MESG_4XX_RESPONSE.formatted(serviceName, status.value()); + log.error(errorMsg); + + return response.bodyToMono(String.class) + .defaultIfEmpty(errorMsg) + .flatMap(body -> { + var detail = getDetailFromProblemDetailsResponse(JSON_MAPPER, serviceName, body); + if (status.isSameCodeAs(UNAUTHORIZED)) { + return Mono.error(new UnauthorizedException(detail)); + } + if (status.isSameCodeAs(PAYMENT_REQUIRED)) { + return Mono.error(new PaymentRequiredException(detail)); + } + if (status.isSameCodeAs(FORBIDDEN)) { + return Mono.error(new ForbiddenException(detail)); + } + if (status.isSameCodeAs(NOT_FOUND)) { + return Mono.error(new NotFoundException(detail)); + } + if (status.isSameCodeAs(CONFLICT)) { + return Mono.error(new ConflictException(detail)); + } + if (status.isSameCodeAs(TOO_MANY_REQUESTS)) { + return Mono.error(new TooManyRequestsException(detail)); + } + if (status.isSameCodeAs(INSUFFICIENT_STORAGE)) { + return Mono.error(new UpstreamException(detail)); + } + if (status.isSameCodeAs(UNPROCESSABLE_CONTENT)) { + return Mono.error(new UnprocessableEntityException(detail)); + } + if (status.isSameCodeAs(BAD_REQUEST)) { + return Mono.error(new BadRequestException(detail)); + } + return Mono.error(new UpstreamException(detail)); + }); + } + + private static Mono handle5xxError( + String serviceName, ClientResponse response) { + var statusValue = response.statusCode().value(); + var errorMsg = MESG_5XX_RESPONSE.formatted(serviceName, statusValue); + log.error(errorMsg); + + return response.bodyToMono(String.class) + .switchIfEmpty(Mono.defer(() -> { + log.error(errorMsg); + return Mono.error(new UpstreamException(errorMsg)); + })) + .flatMap(body -> { + var detail = getDetailFromProblemDetailsResponse(JSON_MAPPER, serviceName, body); + var mesg = MESG_5XX_RESPONSE_WITH_DETAIL + .formatted(serviceName, statusValue, detail); + log.error(mesg); + return Mono.error(new UpstreamException(mesg)); + }); + } + + private static boolean isTokenServer5xx(Throwable throwable) { + if (!(throwable instanceof ClientAuthorizationException ex)) { + return false; + } + if (ex.getError() != null) { + var code = ex.getError().getErrorCode(); + if (OAuth2ErrorCodes.SERVER_ERROR.equals(code) + || OAuth2ErrorCodes.TEMPORARILY_UNAVAILABLE.equals(code)) { + return true; + } + } + var cause = ex.getCause(); + if (cause instanceof WebClientResponseException wce) { + return wce.getStatusCode().is5xxServerError(); + } + return false; + } + + private static String getClientAuthErrorMessage( + String upstream, + ClientAuthorizationException ex) { + var mesg = upstream + " authentication failed: " + ex.getMessage(); + if (ex.getError() != null) { + mesg += " [OAuth2 error: " + ex.getError().getErrorCode(); + if (ex.getError().getDescription() != null) { + mesg += " - " + ex.getError().getDescription(); + } + mesg += "]"; + } + return mesg; + } + + /** + * Bundles a {@link ClientHttpConnector} with the Reactor Netty + * {@link ConnectionProvider} and {@link LoopResources} that back it, so they + * can be disposed together via {@link #close()}. + * + *

BLOCK_TIMEOUT must stay under {@code spring.lifecycle.timeout-per-shutdown-phase} + * (default 30s), otherwise Spring kills the JVM before disposal finishes. + * Ideally DISPOSE_TIMEOUT ≥ {@link #RESPONSE_TIMEOUT_DURATION} so in-flight + * requests can finish cleanly, but this is not required. + */ + @Slf4j + public static final class ManagedHttpResources implements AutoCloseable { + static final Duration QUIET_PERIOD = Duration.ofSeconds(2); + static final Duration DISPOSE_TIMEOUT = Duration.ofSeconds(25); + static final Duration BLOCK_TIMEOUT = DISPOSE_TIMEOUT.plusSeconds(2); + + private static final String MESG_DISPOSED_CLEANLY = "%s '%s' disposed cleanly"; + private static final String MESG_DISPOSE_TIMED_OUT = + "%s '%s' dispose did not complete within %s — resources may be force-closed by " + + "Netty shutdown hooks"; + + private final ClientHttpConnector connector; + private final ConnectionProvider connectionProvider; + private final LoopResources loopResources; + private final String name; + + public ManagedHttpResources( + ClientHttpConnector connector, + ConnectionProvider connectionProvider, + LoopResources loopResources, + String name) { + this.connector = connector; + this.connectionProvider = connectionProvider; + this.loopResources = loopResources; + this.name = name; + } + + public ClientHttpConnector connector() { + return connector; + } + + @Override + public void close() { + disposeQuietly("ConnectionProvider", connectionProvider == null ? null : + connectionProvider.disposeLater()); + disposeQuietly("LoopResources", loopResources == null ? null : + loopResources.disposeLater(QUIET_PERIOD, DISPOSE_TIMEOUT)); + } + + private void disposeQuietly(String kind, Mono disposeMono) { + if (disposeMono == null) { + return; + } + try { + disposeMono.block(BLOCK_TIMEOUT); + log.info(MESG_DISPOSED_CLEANLY.formatted(kind, name)); + } catch (Exception ex) { + log.warn(MESG_DISPOSE_TIMED_OUT.formatted(kind, name, BLOCK_TIMEOUT), ex); + } + } + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/util/NvctUtils.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/util/NvctUtils.java new file mode 100644 index 000000000..6ba3f8d62 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/util/NvctUtils.java @@ -0,0 +1,103 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.util; + +import static com.nvidia.nvct.util.NvctConstants.HTTP_METHOD; +import static com.nvidia.nvct.util.NvctConstants.REMOTE_ADDRESS; +import static com.nvidia.nvct.util.NvctConstants.REQUEST_URI; + +import tools.jackson.databind.json.JsonMapper; +import io.micrometer.tracing.Tracer; +import jakarta.annotation.Nullable; +import jakarta.servlet.http.HttpServletRequest; +import java.util.Map; +import lombok.experimental.UtilityClass; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.http.ProblemDetail; + +@Slf4j +@UtilityClass +public final class NvctUtils { + private static final String MISSING_PROBLEM_DETAILS_RESPONSE = + "Missing ProblemDetails response from %s"; + private static final String INVALID_PROBLEM_DETAILS_RESPONSE = + "Invalid ProblemDetails response from {} - '{}'"; + + public static Map getCustomProperties(@Nullable HttpServletRequest request) { + if (request == null) { + // An internal background thread is updating the state and causing the audit log to + // be generated. + return Map.of(REMOTE_ADDRESS, "0.0.0.0"); + } + + return Map.of(REQUEST_URI, request.getRequestURI(), + REMOTE_ADDRESS, request.getRemoteAddr(), + HTTP_METHOD, request.getMethod()); + } + + // Returns detail from ProblemDetails response. + public static String getDetailFromProblemDetailsResponse( + JsonMapper jsonMapper, + String service, + String body) { + if (StringUtils.isBlank(body)) { + return MISSING_PROBLEM_DETAILS_RESPONSE.formatted(service); + } + + try { + var pd = jsonMapper.readValue(body, ProblemDetail.class); + return ((pd != null) && StringUtils.isNotBlank(pd.getDetail())) ? pd.getDetail() : body; + } catch (Exception ex) { + log.warn(INVALID_PROBLEM_DETAILS_RESPONSE, service, ex.getMessage()); + return body; // Return original response body as-is. + } + } + + public static void addTagsToCurrentSpan(Tracer tracer, Map tags) { + var span = tracer.currentSpan(); + if (span != null) { + tags.forEach((key, value) -> span.tag(key, String.valueOf(value))); + } + } + + /** + * Creates a child span with the given name, adds the tags to it, and ends the span. + * The child span becomes the current span for the duration of this method. A parent span + * can have multiple child spans with the same name. Each child span is a separate span + * with its own span ID and timestamps - the name is just a label for the span type. + */ + public static void addTagsToChildSpan( + Tracer tracer, + Map tags, + String childSpanName) { + var span = tracer.nextSpan().name(childSpanName).start(); + try (var unused = tracer.withSpan(span)) { // Replace unused with _(underscore) with Java 25 + tags.forEach((key, value) -> span.tag(key, String.valueOf(value))); + } finally { + span.end(); + } + } + + public static void recordExceptionUsingCurrentSpan(Tracer tracer, Throwable throwable) { + var span = tracer.currentSpan(); + if (span != null) { + span.error(throwable); + } + } + +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/util/ProtoMappingUtils.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/util/ProtoMappingUtils.java new file mode 100644 index 000000000..cb0887a6a --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/util/ProtoMappingUtils.java @@ -0,0 +1,36 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.util; + +import com.google.protobuf.Timestamp; +import java.time.Instant; +import lombok.experimental.UtilityClass; + +@UtilityClass +public class ProtoMappingUtils { + + public static Timestamp toTimestamp(Instant instant) { + return Timestamp.newBuilder() + .setSeconds(instant.getEpochSecond()) + .setNanos(instant.getNano()) + .build(); + } + + public static Instant fromTimestamp(Timestamp timestamp) { + return Instant.ofEpochSecond(timestamp.getSeconds(), timestamp.getNanos()); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/proto/nvct.proto b/src/control-plane-services/cloud-tasks/nvct-core/src/main/proto/nvct.proto new file mode 100644 index 000000000..80949f474 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/proto/nvct.proto @@ -0,0 +1,169 @@ +// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +syntax = "proto3"; + +package nvct; + +import "google/protobuf/timestamp.proto"; + +option java_multiple_files = true; +option java_package = "com.nvidia.nvct.proto"; + +service Worker { + rpc Connect (ConnectRequest) returns (ConnectResponse); + rpc SendHeartbeat (HeartbeatRequest) returns (HeartbeatResponse); + rpc SendResultMetadata (stream ResultMetadataRequest) returns (ResultMetadataResponse); + rpc GetArtifacts (ArtifactsRequest) returns (ArtifactsResponse); + rpc RefreshToken (RefreshTokenRequest) returns (RefreshTokenResponse); + rpc RequestSecretCredentials (SecretCredentialsRequest) returns (SecretCredentialsResponse); +} + +message ConnectRequest { + string instanceId = 1; + string taskId = 2; +} + +message ConnectResponse { + string connectedRegion = 1; +} + +message HeartbeatRequest { + string instanceId = 1; + string taskId = 2; + string instanceType = 3; + ExecutionStatus status = 4; // ERRORED, EXCEEDED_MAX_DURATION + optional string errorMessage = 5; +} + +message HeartbeatResponse { + string taskId = 1; // UUID + string ExecutionStatus = 2; // COMPLETED, ERRORED, etc. +} + +message StringKV { + string key = 1; + string value = 2; +} + +message ResultMetadata { + bytes body = 1; +} + +message ErrorDetails { + string type = 1; + string title = 2; + uint32 status = 3; + string detail = 4; +} + +enum ExecutionStatus { + ERRORED = 0; + IN_PROGRESS = 1; + COMPLETED = 2; + PENDING_EVALUATION = 3; + EXCEEDED_MAX_RUNTIME_DURATION = 4; + EXCEEDED_MAX_QUEUED_DURATION = 5; + QUEUED = 6; + LAUNCHED = 7; + RUNNING = 8; + CANCELED = 9; + TASK_CONTAINER_INITIALIZING = 10; + WORKER_TERMINATED = 11; +} + +message ResultMetadataRequest { + string taskId = 1; // UUID + string instanceId = 2; // UUID + string instanceType = 3; + ExecutionStatus status = 4; // ERRORED, IN_PROGRESS, COMPLETED, etc. + optional uint32 percentComplete = 5; + string resultName = 6; // Result/Checkpoints metadata + oneof result { + ResultMetadata metadata = 7; // Results/Checkpoints metadata + ErrorDetails errorDetails = 8; + } +} + +message ResultMetadataResponse { + string taskId = 1; // UUID + string ExecutionStatus = 2; // COMPLETED, ERRORED, etc. +} + +message ArtifactsRequest { + string taskId = 1; // UUID +} + +message ArtifactsResponse { + repeated ArtifactResponse artifacts = 1; + message ArtifactResponse { + string name = 1; + string version = 2; + ArtifactKindEnum kind = 3; + repeated ArtifactFile files = 4; + enum ArtifactKindEnum { + MODEL = 0; + RESOURCE = 1; + } + message ArtifactFile { + string path = 1; + string url = 2; + } + } +} + +message RefreshTokenRequest { + string taskId = 1; // UUID +} + +message RefreshTokenResponse { + string token = 1; +} + +message SecretCredentialsRequest { + string taskId = 1; +} + +message SecretCredentialsResponse { + string secretCredentialsToken = 1; + google.protobuf.Timestamp expiration = 2; +} + + +service Skyway { + rpc AuthGetLogs (SkywayAuthRequest) returns (SkywayAuthResponse); + rpc AuthExecuteCommand (SkywayAuthRequest) returns (SkywayAuthResponse); + rpc AuthListInstances (SkywayAuthRequest) returns (SkywayAuthResponse); +} + + +message SkywayAuthRequest { + string clientAuthorizationToken = 1; + string taskId = 2; + // used for super admins (KAS) to invoke on behalf of a given nca id + optional string targetNcaId = 3; +} + +message SkywayAuthResponse { + message Instance { + string instanceId = 1; + string location = 2; + string state = 3; + } + string taskId = 1; + string clientAuthSubject = 2; + string clientNcaId = 3; + optional string backend = 4; + repeated Instance instances = 5; +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/IntegrationTestConfiguration.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/IntegrationTestConfiguration.java new file mode 100644 index 000000000..e9d4998d5 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/IntegrationTestConfiguration.java @@ -0,0 +1,396 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import tools.jackson.core.JacksonException; +import tools.jackson.databind.json.JsonMapper; +import tools.jackson.databind.node.ArrayNode; +import tools.jackson.databind.node.ObjectNode; +import com.nvidia.boot.audit.AuditProperties; +import com.nvidia.boot.mock.oauth2.MockOAuth2TokenServer; +import com.nvidia.boot.mock.oauth2.OAuth2TokenServerConfigurationProperties; +import jakarta.annotation.Nonnull; +import java.io.File; +import java.io.IOException; +import java.net.JarURLConnection; +import java.net.URISyntaxException; +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardCopyOption; +import java.nio.file.attribute.PosixFilePermissions; +import java.time.Clock; +import java.time.Duration; +import java.time.Instant; +import java.time.temporal.ChronoUnit; +import java.util.Base64; +import java.util.Comparator; +import java.util.Enumeration; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.jar.JarEntry; +import java.util.stream.Stream; +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.test.util.TestPropertyValues; +import org.springframework.context.ApplicationContextInitializer; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.data.cassandra.repository.config.EnableCassandraRepositories; +import org.testcontainers.containers.ComposeContainer; +import org.testcontainers.containers.wait.strategy.Wait; +import org.testcontainers.containers.wait.strategy.WaitAllStrategy; +import org.testcontainers.utility.DockerImageName; + +@Slf4j +@Configuration +@EnableCassandraRepositories(basePackages = "com.nvidia") +public class IntegrationTestConfiguration { + + /** + * Classpath prefix for compose assets bundled in nvct-core-tests.jar (see nvct-core {@code + * maven-resources-plugin} {@code copy-integration-local-env}). + */ + private static final String LOCAL_ENV_CLASSPATH_PREFIX = "local_env"; + + private static final String COMPOSE_FILE_NAME = "docker-compose.test.yml"; + + private static final String DOCKER_COMPOSE_IMAGE = "docker:24.0.2"; + + /** + * Relative to working directory (legacy / IDE): {@code local_env/docker-compose.test.yml}. + */ + private static final String FS_FALLBACK_COMPOSE = + LOCAL_ENV_CLASSPATH_PREFIX + "/" + COMPOSE_FILE_NAME; + + /** + * If {@code false}, failure to create an extract directory under {@code target/} is a hard + * error (set in CI via {@code -D...=false} or env). Default {@code true} keeps a + * java.io.tmpdir fallback for constrained local environments. + */ + private static final String ALLOW_TMPDIR_FALLBACK_PROPERTY = + "nvct.integration.extract.allowTmpdirFallback"; + + private static final String ALLOW_TMPDIR_FALLBACK_ENV = "NVCT_INTEGRATION_ALLOW_TMPDIR_FALLBACK"; + + private static final List INTEGRATION_EXTRACT_ROOTS = new CopyOnWriteArrayList<>(); + + private static final AtomicBoolean INTEGRATION_EXTRACT_SHUTDOWN_HOOK = new AtomicBoolean(); + + private static final String KEY_SPACE = "nvct"; + private static final String CASSANDRA_SERVICE_NAME = "cassandra-1"; + private static final int CASSANDRA_PORT = 9042; + + public static final MockOAuth2TokenServer MOCK_OAUTH2_TOKEN_SERVER; // Used in test files + private static final String OAUTH2_TOKEN_ISSUER = "http://localhost:9092"; + private static final String OAUTH2_KEYSET_URL = "http://localhost:9092/.well-known/jwks.json"; + + private static String CASSANDRA_HOST; + private static int CASSANDRA_MAPPED_PORT; + + private static final String AUDIT_SIGNING_KID = "integration-audit-kid"; + private static final byte[] AUDIT_SIGNING_KEY_RAW = new byte[32]; + + static { + for (int i = 0; i < AUDIT_SIGNING_KEY_RAW.length; i++) { + AUDIT_SIGNING_KEY_RAW[i] = (byte) (i + 1); + } + + var cassandraWaitStrategy = new WaitAllStrategy(WaitAllStrategy.Mode.WITH_OUTER_TIMEOUT); + cassandraWaitStrategy.withStartupTimeout(Duration.of(3, ChronoUnit.MINUTES)); + cassandraWaitStrategy.withStrategy( + Wait.forLogMessage(".*Cassandra init scripts executed.*", 1)); + + File composeDir = resolveComposeAssetDirectory(); + File composeFile = new File(composeDir, COMPOSE_FILE_NAME); + if (!composeFile.isFile()) { + throw new IllegalStateException( + "Compose file missing at " + composeFile.getAbsolutePath()); + } + + var composeContainer = createComposeContainer(composeFile) + .withExposedService(CASSANDRA_SERVICE_NAME, + CASSANDRA_PORT, + cassandraWaitStrategy) + .withBuild(false); + + composeContainer.start(); + + CASSANDRA_HOST = composeContainer.getServiceHost(CASSANDRA_SERVICE_NAME, CASSANDRA_PORT); + CASSANDRA_MAPPED_PORT = composeContainer.getServicePort(CASSANDRA_SERVICE_NAME, + CASSANDRA_PORT); + composeContainer.getContainerByServiceName(CASSANDRA_SERVICE_NAME) + .ifPresentOrElse( + container -> log.info(container.getLogs()), + () -> { + throw new IllegalStateException("Missing container " + + CASSANDRA_SERVICE_NAME); + }); + + + MOCK_OAUTH2_TOKEN_SERVER = new MockOAuth2TokenServer( + new OAuth2TokenServerConfigurationProperties(OAUTH2_TOKEN_ISSUER, OAUTH2_KEYSET_URL, + null, null, null, null)); + MOCK_OAUTH2_TOKEN_SERVER.start(); + } + + /** + * Directory containing {@link #COMPOSE_FILE_NAME} and the {@code cassandra/} subtree required + * by that compose file (volume mounts use paths relative to the compose file). + */ + private static File resolveComposeAssetDirectory() { + var cl = IntegrationTestConfiguration.class.getClassLoader(); + var composeUrl = cl.getResource(LOCAL_ENV_CLASSPATH_PREFIX + "/" + COMPOSE_FILE_NAME); + if (composeUrl == null) { + var fallbackCompose = new File(FS_FALLBACK_COMPOSE); + if (fallbackCompose.isFile()) { + File dir = fallbackCompose.getParentFile(); + log.info("Using compose bundle from filesystem: {}", dir.getAbsolutePath()); + return dir; + } + throw new IllegalStateException( + "Missing classpath resource " + + LOCAL_ENV_CLASSPATH_PREFIX + "/" + COMPOSE_FILE_NAME + + " (ensure nvct-core-tests.jar is on the test classpath and built with" + + " copy-integration-local-env), and no " + FS_FALLBACK_COMPOSE + + " in the working directory."); + } + + try { + if ("file".equalsIgnoreCase(composeUrl.getProtocol())) { + var composePath = Path.of(composeUrl.toURI()); + var dir = composePath.getParent().toFile(); + log.debug("Using compose bundle from filesystem (test-classes): {}", + dir.getAbsolutePath()); + return dir; + } + + if ("jar".equalsIgnoreCase(composeUrl.getProtocol())) { + return extractLocalEnvFromJar(composeUrl); + } + } catch (IOException | URISyntaxException e) { + throw new IllegalStateException("Failed to resolve compose bundle", e); + } + + throw new IllegalStateException( + "Unsupported compose URL protocol: " + composeUrl + "; expected file or jar."); + } + + /** + * Extract {@code local_env/**} from the tests JAR so Docker can bind-mount files by host path. + * Uses {@code target/nvct-integration-local-env-*} under the module directory (same class of path + * as checkout-local {@code local_env/}), not {@code java.io.tmpdir}. Nested/containerised Compose + * in CI often fails mounts from {@code /tmp} while mounts from the job workspace succeed. + */ + private static File extractLocalEnvFromJar(URL composeUrlInsideJar) throws IOException { + + JarURLConnection connection = (JarURLConnection) composeUrlInsideJar.openConnection(); + try (var jarFile = connection.getJarFile()) { + var extractRoot = createIntegrationExtractDirectory(); + var prefix = LOCAL_ENV_CLASSPATH_PREFIX + "/"; + + Enumeration entries = jarFile.entries(); + while (entries.hasMoreElements()) { + var entry = entries.nextElement(); + var name = entry.getName(); + if (!name.startsWith(prefix) || entry.isDirectory()) { + continue; + } + + var dest = extractRoot.resolve(name.substring(prefix.length())); + Files.createDirectories(dest.getParent()); + try (var in = jarFile.getInputStream(entry)) { + Files.copy(in, dest, StandardCopyOption.REPLACE_EXISTING); + } + if (name.endsWith("entrypoint.sh")) { + try { + Files.setPosixFilePermissions(dest, + PosixFilePermissions.fromString("rwxr-xr-x")); + } catch (UnsupportedOperationException ignored) { + // Non-POSIX filesystems (e.g. Windows): Docker Desktop still runs via bash. + } catch (IOException e) { + throw new IllegalStateException("Could not chmod entrypoint script", e); + } + } + } + + log.info("Extracted integration compose bundle from {} to {}", + jarFile.getName(), extractRoot.toAbsolutePath()); + return extractRoot.toFile(); + } + } + + /** + * Creates a directory for JAR-extracted compose assets, preferring {@code target/} under the + * module. Registers recursive deletion on JVM exit (unlike {@link File#deleteOnExit()} on a + * directory, which does not remove contents). + */ + private static Path createIntegrationExtractDirectory() throws IOException { + var target = Path.of(System.getProperty("user.dir"), "target"); + try { + Files.createDirectories(target); + var dir = Files.createTempDirectory(target, "nvct-integration-local-env-"); + registerExtractRootForCleanup(dir); + return dir; + } catch (IOException e) { + if (!isTmpdirFallbackAllowed()) { + throw new IllegalStateException( + "Could not create integration extract directory under " + target.toAbsolutePath() + + ". Set " + ALLOW_TMPDIR_FALLBACK_PROPERTY + "=true or " + + ALLOW_TMPDIR_FALLBACK_ENV + "=true to allow java.io.tmpdir, or fix " + + "permissions on target/.", + e); + } + log.warn("Could not extract under {}; using java.io.tmpdir: {}", + target.toAbsolutePath(), e.toString()); + var fallback = Files.createTempDirectory("nvct-integration-local-env"); + registerExtractRootForCleanup(fallback); + return fallback; + } + } + + private static boolean isTmpdirFallbackAllowed() { + var fromEnv = System.getenv(ALLOW_TMPDIR_FALLBACK_ENV); + if (fromEnv != null && !fromEnv.isBlank()) { + return Boolean.parseBoolean(fromEnv); + } + return Boolean.parseBoolean(System.getProperty(ALLOW_TMPDIR_FALLBACK_PROPERTY, "true")); + } + + private static void registerExtractRootForCleanup(Path root) { + if (INTEGRATION_EXTRACT_SHUTDOWN_HOOK.compareAndSet(false, true)) { + Runtime.getRuntime().addShutdownHook( + new Thread(IntegrationTestConfiguration::deleteIntegrationExtractRoots, + "nvct-integration-extract-cleanup")); + } + INTEGRATION_EXTRACT_ROOTS.add(root); + } + + private static void deleteIntegrationExtractRoots() { + for (var root : INTEGRATION_EXTRACT_ROOTS) { + deleteRecursively(root); + } + } + + private static void deleteRecursively(Path root) { + if (root == null || !Files.exists(root)) { + return; + } + try (Stream walk = Files.walk(root)) { + walk.sorted(Comparator.reverseOrder()).forEach( + p -> { + try { + Files.deleteIfExists(p); + } catch (IOException ignored) { + // best-effort (shutdown hook) + } + }); + } catch (IOException ignored) { + // walk failed — best-effort + } + } + + // This is needed for tests to run consistently locally and also in the CI pipeline. + // Testcontainers 2.x uses the host's Docker Compose CLI for the File-only constructor. The + // Maven image used in the CI pipeline can access the Docker daemon, but it does not include + // the Docker Compose CLI. So, use local Docker Compose CLI when available. Otherwise, run + // Compose using a pinned Docker image for reproducible local and CI test execution. + private static ComposeContainer createComposeContainer(File composeFile) { + if (isLocalComposeAvailable()) { + return new ComposeContainer(composeFile); + } + + return new ComposeContainer(DockerImageName.parse(DOCKER_COMPOSE_IMAGE), composeFile); + } + + private static boolean isLocalComposeAvailable() { + try { + var process = new ProcessBuilder("docker", "compose", "version") + .redirectErrorStream(true) + .start(); + boolean completed = process.waitFor(5, TimeUnit.SECONDS); + if (!completed) { + process.destroyForcibly(); + return false; + } + return process.exitValue() == 0; + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + return false; + } catch (IOException e) { + return false; + } + } + + public static class Initializer implements + ApplicationContextInitializer { + + @Override + public void initialize(@Nonnull ConfigurableApplicationContext applicationContext) { + TestPropertyValues.of( + "spring.cassandra.contact-points=" + CASSANDRA_HOST, + "spring.cassandra.port=" + CASSANDRA_MAPPED_PORT, + "spring.cassandra.local-datacenter=datacenter1", + "spring.cassandra.keyspace-name=" + KEY_SPACE, + "spring.cassandra.ssl.enabled=false", + "spring.cassandra.ssl.bundle=", + "spring.security.oauth2.resourceserver.jwt.issuer-uri=" + OAUTH2_TOKEN_ISSUER, + "spring.security.oauth2.resourceserver.jwt.jwk-set-uri=" + OAUTH2_KEYSET_URL, + "spring.security.oauth2.resourceserver.jwt.jws-algorithms=ES256" + ).applyTo(applicationContext); + } + } + + /** + * Mock clock so it can be set to appropriate value for functional testing. + */ + @Primary + @Bean("mockClock") + public Clock getMockClock() { + var clock = mock(Clock.class); + when(clock.instant()).thenReturn(Instant.now()); + return clock; + } + + @Bean + public AuditProperties auditProperties(JsonMapper jsonMapper) { + ArrayNode keys = jsonMapper.createArrayNode(); + ObjectNode entry = jsonMapper.createObjectNode(); + entry.put("kid", AUDIT_SIGNING_KID); + entry.put("key", Base64.getEncoder().encodeToString(AUDIT_SIGNING_KEY_RAW)); + keys.add(entry); + + ObjectNode root = jsonMapper.createObjectNode(); + root.set("keys", keys); + + var props = new AuditProperties(); + props.setHmacKid(AUDIT_SIGNING_KID); + try { + props.setHmacKeys(Base64.getEncoder() + .encodeToString(jsonMapper.writeValueAsBytes(root))); + } catch (JacksonException e) { + throw new IllegalStateException("Failed to serialize HMAC keys configuration", e); + } + return props; + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/NvctTestApp.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/NvctTestApp.java new file mode 100644 index 000000000..1e1b53005 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/NvctTestApp.java @@ -0,0 +1,31 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct; + +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.micrometer.tracing.autoconfigure.prometheus.PrometheusExemplarsAutoConfiguration; +import org.springframework.boot.security.autoconfigure.ReactiveUserDetailsServiceAutoConfiguration; + +/** + * Test-only Spring Boot application class for nvct-core. + * Core is a pure library with no main class — this provides the boot context for tests. + */ +@SpringBootApplication(exclude = { + ReactiveUserDetailsServiceAutoConfiguration.class, + PrometheusExemplarsAutoConfiguration.class}) +public class NvctTestApp { +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/actuator/ActuatorTracingIntegrationTest.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/actuator/ActuatorTracingIntegrationTest.java new file mode 100644 index 000000000..2d1fb988b --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/actuator/ActuatorTracingIntegrationTest.java @@ -0,0 +1,123 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.actuator; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.awaitility.Awaitility.await; + +import com.nvidia.nvct.IntegrationTestConfiguration; +import com.nvidia.nvct.NvctTestApp; +import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.sdk.trace.data.SpanData; +import java.time.Duration; +import java.util.List; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.resttestclient.TestRestTemplate; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; +import org.springframework.boot.test.web.server.LocalManagementPort; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.ContextConfiguration; + +/** + * Integration tests verifying that actuator endpoints on the management port + * produce traces when using a separate management server (ManagementTracingConfiguration). + */ +@SpringBootTest( + classes = {NvctTestApp.class, IntegrationTestConfiguration.class, + ActuatorTracingTestConfiguration.class}, + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + properties = { + "spring.profiles.active=test", + "management.server.port=0", + "management.tracing.enabled=true" + }) +@ContextConfiguration(initializers = IntegrationTestConfiguration.Initializer.class) +@AutoConfigureTestRestTemplate +class ActuatorTracingIntegrationTest { + + private static final AttributeKey URL_PATH = AttributeKey.stringKey("url.path"); + private static final AttributeKey HTTP_REQUEST_METHOD = + AttributeKey.stringKey("http.request.method"); + + @LocalManagementPort + private int managementPort; + + @Autowired + private TestRestTemplate testRestTemplate; + + @BeforeEach + void resetSpanExporter() { + ActuatorTracingTestConfiguration.SPAN_EXPORTER.reset(); + } + + private String actuatorUrl(String path) { + return "http://localhost:" + managementPort + path; + } + + private List awaitSpans() { + return await() + .atMost(Duration.ofSeconds(5)) + .until( + ActuatorTracingTestConfiguration.SPAN_EXPORTER::getFinishedSpanItems, + items -> !items.isEmpty()); + } + + @Test + @DisplayName("Actuator health endpoint produces HTTP trace span") + void actuatorHealthEndpointProducesTrace() { + ResponseEntity response = testRestTemplate.getForEntity( + actuatorUrl("/actuator/health"), + String.class); + assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); + + List spans = awaitSpans(); + + assertThat(spans) + .anyMatch(span -> hasHttpPath(span, "/actuator/health") + && hasHttpMethod(span, "GET")); + } + + @Test + @DisplayName("Actuator prometheus endpoint produces HTTP trace span") + void actuatorPrometheusEndpointProducesTrace() { + ResponseEntity response = testRestTemplate.getForEntity( + actuatorUrl("/actuator/prometheus"), + String.class); + assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); + + List spans = awaitSpans(); + + assertThat(spans) + .anyMatch(span -> hasHttpPath(span, "/actuator/prometheus") + && hasHttpMethod(span, "GET")); + } + + private static boolean hasHttpPath(SpanData span, String path) { + var urlPath = span.getAttributes().get(URL_PATH); + return urlPath != null && urlPath.contains(path); + } + + private static boolean hasHttpMethod(SpanData span, String method) { + var httpMethod = span.getAttributes().get(HTTP_REQUEST_METHOD); + return method.equals(httpMethod); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/actuator/ActuatorTracingTestConfiguration.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/actuator/ActuatorTracingTestConfiguration.java new file mode 100644 index 000000000..0da71f118 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/actuator/ActuatorTracingTestConfiguration.java @@ -0,0 +1,52 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.actuator; + +import io.opentelemetry.sdk.testing.exporter.InMemorySpanExporter; +import io.opentelemetry.sdk.trace.SpanProcessor; +import io.opentelemetry.sdk.trace.export.SimpleSpanProcessor; +import io.opentelemetry.sdk.trace.export.SpanExporter; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; + +/** + * Test configuration that provides an in-memory span exporter for asserting + * that actuator endpoints produce traces when using a separate management port. + * + *

Uses {@link SimpleSpanProcessor} so spans are exported immediately rather than + * batched, avoiding timing-related test failures with {@link io.opentelemetry.sdk.trace.export.BatchSpanProcessor}. + */ +@Configuration +public class ActuatorTracingTestConfiguration { + + public static final InMemorySpanExporter SPAN_EXPORTER = InMemorySpanExporter.create(); + + @Bean + @Primary + public SpanExporter inMemorySpanExporter() { + return SPAN_EXPORTER; + } + + /** + * Ensures spans are exported immediately to the in-memory exporter for reliable test assertions. + */ + @Bean + public SpanProcessor testSpanProcessor() { + return SimpleSpanProcessor.create(SPAN_EXPORTER); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/actuator/MetricsIntegrationTest.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/actuator/MetricsIntegrationTest.java new file mode 100644 index 000000000..2b73be16c --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/actuator/MetricsIntegrationTest.java @@ -0,0 +1,150 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.actuator; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.springframework.http.MediaType.TEXT_PLAIN; + +import com.nvidia.nvct.IntegrationTestConfiguration; +import com.nvidia.nvct.NvctTestApp; +import io.micrometer.core.instrument.MeterRegistry; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.resttestclient.TestRestTemplate; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; +import org.springframework.boot.test.web.server.LocalManagementPort; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.ContextConfiguration; + +/** + * Integration tests for the public actuator surface on the management port. + * Uses a separate management port (management.server.port=0) so actuator is tested on its own + * server. Verifies the expected exposed endpoints remain available and non-allowed endpoints are + * not exposed. + */ +@SpringBootTest( + classes = {NvctTestApp.class, IntegrationTestConfiguration.class}, + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + properties = { + "spring.profiles.active=test", + "management.server.port=0" + }) +@ContextConfiguration(initializers = IntegrationTestConfiguration.Initializer.class) +@AutoConfigureTestRestTemplate +class MetricsIntegrationTest { + + @LocalManagementPort + private int managementPort; + + @Autowired + private TestRestTemplate testRestTemplate; + + @Autowired + private MeterRegistry meterRegistry; + + private String actuatorUrl(String path) { + return "http://localhost:" + managementPort + path; + } + + @Test + @DisplayName("Actuator health endpoint is available") + void actuatorHealthEndpointIsAvailable() { + ResponseEntity response = testRestTemplate.getForEntity( + actuatorUrl("/actuator/health"), + String.class); + assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); + } + + @Test + @DisplayName("Actuator liveness endpoint is available") + void actuatorLivenessEndpointIsAvailable() { + ResponseEntity response = testRestTemplate.getForEntity( + actuatorUrl("/actuator/health/liveness"), + String.class); + assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); + } + + @Test + @DisplayName("Actuator readiness endpoint is available") + void actuatorReadinessEndpointIsAvailable() { + ResponseEntity response = testRestTemplate.getForEntity( + actuatorUrl("/actuator/health/readiness"), + String.class); + assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); + } + + @Test + @DisplayName("Prometheus endpoint returns 200 and Prometheus text format") + void prometheusEndpointReturnsMetrics() { + ResponseEntity response = testRestTemplate.getForEntity( + actuatorUrl("/actuator/prometheus"), + String.class); + + assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); + assertThat(response.getHeaders().getContentType()) + .isNotNull() + .satisfies(mediaType -> assertThat(mediaType.isCompatibleWith(TEXT_PLAIN)).isTrue()); + + var body = response.getBody(); + assertThat(body).isNotNull(); + assertThat(body).contains("# HELP"); + assertThat(body).contains("# TYPE"); + } + + @Test + @DisplayName("Prometheus endpoint includes JVM metrics") + void prometheusEndpointIncludesJvmMetrics() { + ResponseEntity response = testRestTemplate.getForEntity( + actuatorUrl("/actuator/prometheus"), + String.class); + + assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); + var body = response.getBody(); + assertThat(body).isNotNull(); + assertThat(body).contains("jvm_"); + } + + @Test + @DisplayName("Metrics endpoint is available") + void metricsEndpointIsAvailable() { + ResponseEntity response = testRestTemplate.getForEntity( + actuatorUrl("/actuator/metrics"), + String.class); + + assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); + } + + @Test + @DisplayName("Environment endpoint is not exposed via management.endpoints.web.exposure.include") + void envEndpointIsNotAnonymouslyAvailable() { + ResponseEntity response = testRestTemplate.getForEntity( + actuatorUrl("/actuator/env"), + String.class); + + assertThat(response.getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND); + } + + @Test + @DisplayName("MeterRegistry is configured and has metrics") + void meterRegistryHasMetrics() { + assertThat(meterRegistry).isNotNull(); + assertThat(meterRegistry.getMeters()).isNotEmpty(); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/configuration/exceptions/ValidationAwareExceptionHandlerTest.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/configuration/exceptions/ValidationAwareExceptionHandlerTest.java new file mode 100644 index 000000000..787b9b8d3 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/configuration/exceptions/ValidationAwareExceptionHandlerTest.java @@ -0,0 +1,123 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.configuration.exceptions; + +import static com.nvidia.nvct.IntegrationTestConfiguration.MOCK_OAUTH2_TOKEN_SERVER; +import static com.nvidia.nvct.util.NvctConstants.MAX_TAG_LENGTH; +import static com.nvidia.nvct.util.NvctConstants.NGC_API_KEY; +import static com.nvidia.nvct.util.NvctConstants.SCOPE_LAUNCH_TASK; +import static com.nvidia.nvct.util.TestConstants.TEST_CLIENT_SUBJECT; +import static com.nvidia.nvct.util.TestConstants.TEST_CONTAINER_ARGS; +import static com.nvidia.nvct.util.TestConstants.TEST_CONTAINER_ENVIRONMENT; +import static com.nvidia.nvct.util.TestConstants.TEST_CONTAINER_IMAGE; +import static com.nvidia.nvct.util.TestConstants.TEST_DESCRIPTION; +import static com.nvidia.nvct.util.TestConstants.TEST_OCI_GPU_SPEC_DTO; +import static com.nvidia.nvct.util.TestConstants.TEST_RESULTS_LOCATION_1; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_NAME_1; +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; + +import tools.jackson.databind.node.StringNode; +import com.nvidia.nvct.IntegrationTestConfiguration; +import com.nvidia.nvct.NvctTestApp; +import com.nvidia.nvct.rest.task.dto.CreateTaskRequest; +import com.nvidia.nvct.rest.task.dto.ResultHandlingStrategyEnum; +import com.nvidia.nvct.rest.task.dto.SecretDto; +import java.net.URI; +import java.time.Duration; +import java.util.List; +import java.util.Set; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.resttestclient.TestRestTemplate; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.RequestEntity; +import org.springframework.test.context.ContextConfiguration; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@Slf4j +@SpringBootTest( + classes = {NvctTestApp.class, IntegrationTestConfiguration.class}, + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + properties = "spring.profiles.active=test") +@ContextConfiguration(initializers = IntegrationTestConfiguration.Initializer.class) +@AutoConfigureTestRestTemplate +class ValidationAwareExceptionHandlerTest { + + @Autowired + private TestRestTemplate testRestTemplate; + + @BeforeAll + void beforeAll() { + log.info("{}: Started running tests", this.getClass().getSimpleName()); + } + + @AfterAll + void cleanup() { + log.info("{}: Completed running tests", this.getClass().getSimpleName()); + } + + @Test + void validationErrorShouldContainDetails() { + var token = MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK), 100); + var tags = Set.of(StringUtils.repeat("tag1", MAX_TAG_LENGTH), + StringUtils.repeat("tag2", MAX_TAG_LENGTH)); + var secrets = Set.of(SecretDto.builder() + .name(NGC_API_KEY) + .value(new StringNode("shhh!shhh!")) + .build(), + SecretDto.builder() + .name("secret2") + .value(new StringNode("confidential")) + .build()); + var requestBody = CreateTaskRequest.builder() + .name(TEST_TASK_NAME_1) + .containerArgs(TEST_CONTAINER_ARGS) + .containerImage(TEST_CONTAINER_IMAGE) + .tags(tags) + .gpuSpecification(TEST_OCI_GPU_SPEC_DTO) + .maxRuntimeDuration(Duration.ofHours(2)) + .maxQueuedDuration(Duration.ofHours(3)) + .terminationGracePeriodDuration(Duration.ofHours(1)) + .description(TEST_DESCRIPTION) + .resultsLocation(TEST_RESULTS_LOCATION_1) + .resultHandlingStrategy(ResultHandlingStrategyEnum.UPLOAD) + .secrets(secrets) + .containerEnvironment(TEST_CONTAINER_ENVIRONMENT) + .build(); + var requestEntity = RequestEntity.post(URI.create("/v1/nvct/tasks")) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", "Bearer " + token) + .body(requestBody); + var responseEntity = + testRestTemplate.exchange(requestEntity, String.class); + + assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.BAD_REQUEST); + log.info(responseEntity.getBody()); + // Error message should contain the failed value, the max correct value, and the + // field in error + assertThat(responseEntity.getBody()).contains(Integer.toString(MAX_TAG_LENGTH), "tags"); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/grpc/GrpcSkywayServiceTest.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/grpc/GrpcSkywayServiceTest.java new file mode 100644 index 000000000..967fdd805 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/grpc/GrpcSkywayServiceTest.java @@ -0,0 +1,461 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.grpc; + +import static com.nvidia.nvct.IntegrationTestConfiguration.MOCK_OAUTH2_TOKEN_SERVER; +import static com.nvidia.nvct.util.MockIcmsServer.InstancesState.HEALTHY; +import static com.nvidia.nvct.util.NvctConstants.SCOPE_DELETE_TASK; +import static com.nvidia.nvct.util.NvctConstants.SCOPE_LAUNCH_TASK; +import static com.nvidia.nvct.util.NvctConstants.SCOPE_LIST_TASKS; +import static com.nvidia.nvct.util.TestConstants.MD_KEY_AUTHORIZATION; +import static com.nvidia.nvct.util.TestConstants.TEST_CLIENT_SUBJECT; +import static com.nvidia.nvct.util.TestConstants.TEST_NCA_ID; +import static com.nvidia.nvct.util.TestConstants.TEST_NCA_ID_2; +import static com.nvidia.nvct.util.TestConstants.TEST_ICMS_REQ_ID_1; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_ID_1; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_ID_2; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import tools.jackson.databind.json.JsonMapper; +import com.nvidia.nvct.IntegrationTestConfiguration; +import com.nvidia.nvct.NvctTestApp; +import com.nvidia.nvct.persistence.task.entity.TaskStatus; +import com.nvidia.nvct.proto.SkywayAuthRequest; +import com.nvidia.nvct.proto.SkywayAuthResponse; +import com.nvidia.nvct.proto.SkywayGrpc; +import com.nvidia.nvct.rest.task.dto.InstanceStateEnum; +import com.nvidia.nvct.util.MockNvcfServer; +import com.nvidia.nvct.util.MockIcmsServer; +import io.grpc.ManagedChannelBuilder; +import io.grpc.Metadata; +import io.grpc.StatusRuntimeException; +import io.grpc.stub.MetadataUtils; +import java.net.URL; +import java.util.List; +import java.util.UUID; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ContextConfiguration; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@Slf4j +@SpringBootTest(classes = {NvctTestApp.class, + IntegrationTestConfiguration.class}, + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + properties = { + "spring.profiles.active=test", + "grpc.server.port=9090" + }) +@ContextConfiguration(initializers = IntegrationTestConfiguration.Initializer.class) +class GrpcSkywayServiceTest { + private static final String SKYWAY_AUTH_SCOPE = "skyway:auth"; + + @Autowired + private TestTaskService testTaskService; + + @Autowired + private JsonMapper jsonMapper; + + @Value("${nvct.icms.base-url}") + private URL icmsBaseUrl; + + @Value("${nvct.nvcf.base-url}") + private URL nvcfBaseUrl; + + @BeforeAll + void setupMocks() { + var mockIcmsServerHealthContexts = List.of(MockIcmsServer.IcmsRequestContext.builder() + .instanceState(HEALTHY).build()); + MockIcmsServer.start(icmsBaseUrl, jsonMapper, mockIcmsServerHealthContexts); + MockNvcfServer.start(nvcfBaseUrl); + } + + @AfterAll + void cleanupMocks() { + MockIcmsServer.stop(); + MockNvcfServer.stop(); + } + + @AfterEach + void reset() { + testTaskService.clearAll(); + } + + @Test + void authGetLogs() { + testTaskService.createTask(TEST_NCA_ID, TEST_TASK_ID_1, TEST_ICMS_REQ_ID_1, + TaskStatus.RUNNING); + var md = new Metadata(); + var jwt = MOCK_OAUTH2_TOKEN_SERVER.getJwt(SKYWAY_AUTH_SCOPE); + md.put(MD_KEY_AUTHORIZATION, "Bearer " + jwt); + var channel = ManagedChannelBuilder + .forAddress("localhost", 9090) + .usePlaintext() + .intercept(MetadataUtils.newAttachHeadersInterceptor(md)) + .build(); + var proxyBlockingStub = SkywayGrpc.newBlockingStub(channel); + var clientAuth = MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LIST_TASKS), 100); + var proxyAuthRequest = SkywayAuthRequest.newBuilder() + .setTaskId(TEST_TASK_ID_1.toString()) + .setClientAuthorizationToken(clientAuth) + .build(); + var authResponse = proxyBlockingStub.authGetLogs(proxyAuthRequest); + validateSuccessResponse(authResponse); + channel.shutdownNow(); + } + + @Test + void authGetLogsInvalidClientSecretScope() { + testTaskService.createTask(TEST_NCA_ID, TEST_TASK_ID_1, TEST_ICMS_REQ_ID_1, + TaskStatus.RUNNING); + var md = new Metadata(); + var jwt = MOCK_OAUTH2_TOKEN_SERVER.getJwt(SKYWAY_AUTH_SCOPE); + md.put(MD_KEY_AUTHORIZATION, "Bearer " + jwt); + var channel = ManagedChannelBuilder + .forAddress("localhost", 9090) + .usePlaintext() + .intercept(MetadataUtils.newAttachHeadersInterceptor(md)) + .build(); + var proxyBlockingStub = SkywayGrpc.newBlockingStub(channel); + var clientAuth = MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_DELETE_TASK), 100); + var proxyAuthRequest = SkywayAuthRequest.newBuilder() + .setTaskId(TEST_TASK_ID_1.toString()) + .setClientAuthorizationToken(clientAuth) + .build(); + assertThatThrownBy(() -> proxyBlockingStub.authGetLogs(proxyAuthRequest)) + .isInstanceOf(StatusRuntimeException.class) + .hasMessageContaining("PERMISSION_DENIED"); + channel.shutdownNow(); + } + + @Test + void authGetLogsInvalidClientSecret() { + testTaskService.createTask(TEST_NCA_ID, TEST_TASK_ID_1, TEST_ICMS_REQ_ID_1, + TaskStatus.RUNNING); + var md = new Metadata(); + var jwt = MOCK_OAUTH2_TOKEN_SERVER.getJwt(SKYWAY_AUTH_SCOPE); + md.put(MD_KEY_AUTHORIZATION, "Bearer " + jwt); + var channel = ManagedChannelBuilder + .forAddress("localhost", 9090) + .usePlaintext() + .intercept(MetadataUtils.newAttachHeadersInterceptor(md)) + .build(); + var proxyBlockingStub = SkywayGrpc.newBlockingStub(channel); + var clientAuth = "invalid_secret"; + var proxyAuthRequest = SkywayAuthRequest.newBuilder() + .setTaskId(TEST_TASK_ID_1.toString()) + .setClientAuthorizationToken(clientAuth) + .build(); + assertThatThrownBy(() -> proxyBlockingStub.authGetLogs(proxyAuthRequest)) + .isInstanceOf(StatusRuntimeException.class) + .hasMessageContaining("UNAUTHENTICATED"); + channel.shutdownNow(); + } + + @Test + void authExecuteCommand() { + testTaskService.createTask(TEST_NCA_ID, TEST_TASK_ID_1, TEST_ICMS_REQ_ID_1, + TaskStatus.RUNNING); + var md = new Metadata(); + var jwt = MOCK_OAUTH2_TOKEN_SERVER.getJwt(SKYWAY_AUTH_SCOPE); + md.put(MD_KEY_AUTHORIZATION, "Bearer " + jwt); + var channel = ManagedChannelBuilder + .forAddress("localhost", 9090) + .usePlaintext() + .intercept(MetadataUtils.newAttachHeadersInterceptor(md)) + .build(); + var proxyBlockingStub = SkywayGrpc.newBlockingStub(channel); + var clientAuth = + MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, List.of(SCOPE_LAUNCH_TASK), 100); + var proxyAuthRequest = SkywayAuthRequest.newBuilder() + .setTaskId(TEST_TASK_ID_1.toString()) + .setClientAuthorizationToken(clientAuth) + .build(); + var authResponse = proxyBlockingStub.authExecuteCommand(proxyAuthRequest); + validateSuccessResponse(authResponse); + channel.shutdownNow(); + } + + @Test + void authExecuteCommandInvalidClientSecretScope() { + testTaskService.createTask(TEST_NCA_ID, TEST_TASK_ID_1, TEST_ICMS_REQ_ID_1, + TaskStatus.RUNNING); + var md = new Metadata(); + var jwt = MOCK_OAUTH2_TOKEN_SERVER.getJwt(SKYWAY_AUTH_SCOPE); + md.put(MD_KEY_AUTHORIZATION, "Bearer " + jwt); + var channel = ManagedChannelBuilder + .forAddress("localhost", 9090) + .usePlaintext() + .intercept(MetadataUtils.newAttachHeadersInterceptor(md)) + .build(); + var proxyBlockingStub = SkywayGrpc.newBlockingStub(channel); + var clientAuth = + MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, List.of(SCOPE_DELETE_TASK), 100); + var proxyAuthRequest = SkywayAuthRequest.newBuilder() + .setTaskId(TEST_TASK_ID_1.toString()) + .setClientAuthorizationToken(clientAuth) + .build(); + assertThatThrownBy(() -> proxyBlockingStub.authExecuteCommand(proxyAuthRequest)) + .isInstanceOf(StatusRuntimeException.class) + .hasMessageContaining("PERMISSION_DENIED"); + channel.shutdownNow(); + } + + @Test + void authExecuteCommandInvalidClientSecret() { + testTaskService.createTask(TEST_NCA_ID, TEST_TASK_ID_1, TEST_ICMS_REQ_ID_1, + TaskStatus.RUNNING); + var md = new Metadata(); + var jwt = MOCK_OAUTH2_TOKEN_SERVER.getJwt(SKYWAY_AUTH_SCOPE); + md.put(MD_KEY_AUTHORIZATION, "Bearer " + jwt); + var channel = ManagedChannelBuilder + .forAddress("localhost", 9090) + .usePlaintext() + .intercept(MetadataUtils.newAttachHeadersInterceptor(md)) + .build(); + var proxyBlockingStub = SkywayGrpc.newBlockingStub(channel); + var clientAuth = "invalid_secret"; + var proxyAuthRequest = SkywayAuthRequest.newBuilder() + .setTaskId(TEST_TASK_ID_1.toString()) + .setClientAuthorizationToken(clientAuth) + .build(); + assertThatThrownBy(() -> proxyBlockingStub.authExecuteCommand(proxyAuthRequest)) + .isInstanceOf(StatusRuntimeException.class) + .hasMessageContaining("UNAUTHENTICATED"); + channel.shutdownNow(); + } + + @Test + void authListInstances() { + testTaskService.createTask(TEST_NCA_ID, TEST_TASK_ID_1, TEST_ICMS_REQ_ID_1, + TaskStatus.RUNNING); + var md = new Metadata(); + var jwt = MOCK_OAUTH2_TOKEN_SERVER.getJwt(SKYWAY_AUTH_SCOPE); + md.put(MD_KEY_AUTHORIZATION, "Bearer " + jwt); + var channel = ManagedChannelBuilder + .forAddress("localhost", 9090) + .usePlaintext() + .intercept(MetadataUtils.newAttachHeadersInterceptor(md)) + .build(); + var proxyBlockingStub = SkywayGrpc.newBlockingStub(channel); + var clientAuth = + MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, List.of(SCOPE_LIST_TASKS), 100); + var proxyAuthRequest = SkywayAuthRequest.newBuilder() + .setTaskId(TEST_TASK_ID_1.toString()) + .setClientAuthorizationToken(clientAuth) + .build(); + var authResponse = proxyBlockingStub.authListInstances(proxyAuthRequest); + validateSuccessResponse(authResponse); + channel.shutdownNow(); + } + + @Test + void authListInstancesInvalidAccountAccess() { + testTaskService.createTask(TEST_NCA_ID_2, TEST_TASK_ID_2, TEST_ICMS_REQ_ID_1, + TaskStatus.RUNNING); + var md = new Metadata(); + var jwt = MOCK_OAUTH2_TOKEN_SERVER.getJwt(SKYWAY_AUTH_SCOPE); + md.put(MD_KEY_AUTHORIZATION, "Bearer " + jwt); + var channel = ManagedChannelBuilder + .forAddress("localhost", 9090) + .usePlaintext() + .intercept(MetadataUtils.newAttachHeadersInterceptor(md)) + .build(); + var proxyBlockingStub = SkywayGrpc.newBlockingStub(channel); + var clientAuth = + MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, List.of(SCOPE_LIST_TASKS), 100); + var proxyAuthRequest = SkywayAuthRequest.newBuilder() + .setTaskId(TEST_TASK_ID_1.toString()) + .setClientAuthorizationToken(clientAuth) + .build(); + assertThatThrownBy(() -> proxyBlockingStub.authListInstances(proxyAuthRequest)) + .isInstanceOf(StatusRuntimeException.class) + .hasMessageContaining("PERMISSION_DENIED"); + channel.shutdownNow(); + } + + @Test + void authListInstancesInvalidClientSecretScope() { + testTaskService.createTask(TEST_NCA_ID, TEST_TASK_ID_1, TEST_ICMS_REQ_ID_1, + TaskStatus.RUNNING); + var md = new Metadata(); + var jwt = MOCK_OAUTH2_TOKEN_SERVER.getJwt(SKYWAY_AUTH_SCOPE); + md.put(MD_KEY_AUTHORIZATION, "Bearer " + jwt); + var channel = ManagedChannelBuilder + .forAddress("localhost", 9090) + .usePlaintext() + .intercept(MetadataUtils.newAttachHeadersInterceptor(md)) + .build(); + var proxyBlockingStub = SkywayGrpc.newBlockingStub(channel); + var clientAuth = + MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, List.of(SCOPE_DELETE_TASK), 100); + var proxyAuthRequest = SkywayAuthRequest.newBuilder() + .setTaskId(TEST_TASK_ID_1.toString()) + .setClientAuthorizationToken(clientAuth) + .build(); + assertThatThrownBy(() -> proxyBlockingStub.authListInstances(proxyAuthRequest)) + .isInstanceOf(StatusRuntimeException.class) + .hasMessageContaining("PERMISSION_DENIED"); + channel.shutdownNow(); + } + + @Test + void authListInstancesInvalidClientSecret() { + testTaskService.createTask(TEST_NCA_ID, TEST_TASK_ID_1, TEST_ICMS_REQ_ID_1, + TaskStatus.RUNNING); + var md = new Metadata(); + var jwt = MOCK_OAUTH2_TOKEN_SERVER.getJwt(SKYWAY_AUTH_SCOPE); + md.put(MD_KEY_AUTHORIZATION, "Bearer " + jwt); + var channel = ManagedChannelBuilder + .forAddress("localhost", 9090) + .usePlaintext() + .intercept(MetadataUtils.newAttachHeadersInterceptor(md)) + .build(); + var proxyBlockingStub = SkywayGrpc.newBlockingStub(channel); + var clientAuth = "invalid_secret"; + var proxyAuthRequest = SkywayAuthRequest.newBuilder() + .setTaskId(TEST_TASK_ID_1.toString()) + .setClientAuthorizationToken(clientAuth) + .build(); + assertThatThrownBy(() -> proxyBlockingStub.authListInstances(proxyAuthRequest)) + .isInstanceOf(StatusRuntimeException.class) + .hasMessageContaining("UNAUTHENTICATED"); + channel.shutdownNow(); + } + + @Test + void invalidServiceSecretScopes() { + testTaskService.createTask(TEST_NCA_ID, TEST_TASK_ID_1, TEST_ICMS_REQ_ID_1, + TaskStatus.RUNNING); + var md = new Metadata(); + var jwt = MOCK_OAUTH2_TOKEN_SERVER.getJwt(SCOPE_DELETE_TASK); + md.put(MD_KEY_AUTHORIZATION, "Bearer " + jwt); + var channel = ManagedChannelBuilder + .forAddress("localhost", 9090) + .usePlaintext() + .intercept(MetadataUtils.newAttachHeadersInterceptor(md)) + .build(); + var proxyBlockingStub = SkywayGrpc.newBlockingStub(channel); + var clientAuth = + MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, List.of(SCOPE_LIST_TASKS), 100); + var proxyAuthRequest = SkywayAuthRequest.newBuilder() + .setTaskId(TEST_TASK_ID_1.toString()) + .setClientAuthorizationToken(clientAuth) + .build(); + assertThatThrownBy(() -> proxyBlockingStub.authListInstances(proxyAuthRequest)) + .isInstanceOf(StatusRuntimeException.class) + .hasMessageContaining("PERMISSION_DENIED"); + channel.shutdownNow(); + } + + @Test + void invalidServiceSecret() { + testTaskService.createTask(TEST_NCA_ID, TEST_TASK_ID_1, TEST_ICMS_REQ_ID_1, + TaskStatus.RUNNING); + var md = new Metadata(); + var jwt = "invalid_secret"; + md.put(MD_KEY_AUTHORIZATION, "Bearer " + jwt); + var channel = ManagedChannelBuilder + .forAddress("localhost", 9090) + .usePlaintext() + .intercept(MetadataUtils.newAttachHeadersInterceptor(md)) + .build(); + var proxyBlockingStub = SkywayGrpc.newBlockingStub(channel); + var clientAuth = + MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, List.of(SCOPE_LIST_TASKS), 100); + var proxyAuthRequest = SkywayAuthRequest.newBuilder() + .setTaskId(TEST_TASK_ID_1.toString()) + .setClientAuthorizationToken(clientAuth) + .build(); + assertThatThrownBy(() -> proxyBlockingStub.authListInstances(proxyAuthRequest)) + .isInstanceOf(StatusRuntimeException.class) + .hasMessageContaining("UNAUTHENTICATED"); + channel.shutdownNow(); + } + + @Test + void inactiveFunction() { + var md = new Metadata(); + var jwt = MOCK_OAUTH2_TOKEN_SERVER.getJwt(SKYWAY_AUTH_SCOPE); + md.put(MD_KEY_AUTHORIZATION, "Bearer " + jwt); + var channel = ManagedChannelBuilder + .forAddress("localhost", 9090) + .usePlaintext() + .intercept(MetadataUtils.newAttachHeadersInterceptor(md)) + .build(); + var proxyBlockingStub = SkywayGrpc.newBlockingStub(channel); + var clientAuth = MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LIST_TASKS), 100); + var proxyAuthRequest = SkywayAuthRequest.newBuilder() + .setTaskId(TEST_TASK_ID_1.toString()) + .setClientAuthorizationToken(clientAuth) + .build(); + assertThatThrownBy(() -> proxyBlockingStub.authExecuteCommand(proxyAuthRequest)) + .isInstanceOf(StatusRuntimeException.class) + .hasMessageContaining("PERMISSION_DENIED"); + channel.shutdownNow(); + } + + @Test + void nonExistingFunction() { + var md = new Metadata(); + var jwt = MOCK_OAUTH2_TOKEN_SERVER.getJwt(SKYWAY_AUTH_SCOPE); + md.put(MD_KEY_AUTHORIZATION, "Bearer " + jwt); + var channel = ManagedChannelBuilder + .forAddress("localhost", 9090) + .usePlaintext() + .intercept(MetadataUtils.newAttachHeadersInterceptor(md)) + .build(); + var proxyBlockingStub = SkywayGrpc.newBlockingStub(channel); + var clientAuth = MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LIST_TASKS), 100); + var notExistingTaskId = UUID.randomUUID().toString(); + var proxyAuthRequest = SkywayAuthRequest.newBuilder() + .setTaskId(notExistingTaskId) + .setClientAuthorizationToken(clientAuth) + .build(); + assertThatThrownBy(() -> proxyBlockingStub.authExecuteCommand(proxyAuthRequest)) + .isInstanceOf(StatusRuntimeException.class) + .hasMessageContaining("PERMISSION_DENIED"); + channel.shutdownNow(); + } + + private static void validateSuccessResponse(SkywayAuthResponse authResponse) { + assertThat(authResponse).isNotNull(); + assertThat(authResponse.getTaskId()).isEqualTo(TEST_TASK_ID_1.toString()); + assertThat(authResponse.getClientAuthSubject()).isEqualTo(TEST_CLIENT_SUBJECT); + assertThat(authResponse.getClientNcaId()).isEqualTo(TEST_NCA_ID); + assertThat(authResponse.getBackend()).isEmpty(); // For backward compatible only + assertThat(authResponse.getInstancesList()).hasSize(1); + authResponse.getInstancesList().forEach(instance -> { + assertThat(instance.getInstanceId()).isNotEmpty(); + // Hardcoded in `src/test/resources/fixtures/icms/raw-healthy-instance.json` + assertThat(instance.getLocation()).isEqualTo("NP-LAX-03"); + assertThat(instance.getState()).isEqualTo(InstanceStateEnum.RUNNING.toString()); + }); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/grpc/GrpcWorkerRefreshSecretAssertionsTokenTest.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/grpc/GrpcWorkerRefreshSecretAssertionsTokenTest.java new file mode 100644 index 000000000..13035b9b4 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/grpc/GrpcWorkerRefreshSecretAssertionsTokenTest.java @@ -0,0 +1,247 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.grpc; + +import static com.nvidia.nvct.util.ProtoMappingUtils.fromTimestamp; +import static com.nvidia.nvct.util.TestConstants.MD_KEY_AUTHORIZATION; +import static com.nvidia.nvct.util.TestConstants.TEST_NCA_ID; +import static com.nvidia.nvct.util.TestConstants.TEST_NCA_ID_WITH_TELEMETRIES_4; +import static com.nvidia.nvct.util.TestConstants.TEST_SECRETS; +import static com.nvidia.nvct.util.TestConstants.TEST_ICMS_REQ_ID_1; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_ID_1; +import static com.nvidia.nvct.util.TestConstants.TEST_TELEMETRY_LOGS_ID; +import static org.assertj.core.api.Assertions.assertThat; + +import tools.jackson.databind.json.JsonMapper; +import com.nvidia.nvct.IntegrationTestConfiguration; +import com.nvidia.nvct.NvctTestApp; +import com.nvidia.nvct.persistence.task.entity.TelemetriesUdt; +import com.nvidia.nvct.proto.SecretCredentialsRequest; +import com.nvidia.nvct.proto.WorkerGrpc; +import com.nvidia.nvct.service.ess.EssService; +import com.nvidia.nvct.service.task.TaskService; +import com.nvidia.nvct.service.token.TokenService; +import com.nvidia.nvct.util.MockEssServer; +import com.nvidia.nvct.util.MockNotaryServer; +import com.nvidia.nvct.util.MockNvcfServer; +import com.nvidia.nvct.util.MockIcmsServer; +import io.grpc.ManagedChannel; +import io.grpc.ManagedChannelBuilder; +import io.grpc.Metadata; +import io.grpc.stub.MetadataUtils; +import java.net.URL; +import java.time.Duration; +import java.time.Instant; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ContextConfiguration; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@Slf4j +@SpringBootTest(classes = {NvctTestApp.class, + IntegrationTestConfiguration.class}, + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + properties = { + "spring.profiles.active=test", + "grpc.server.port=9090" + }) +@ContextConfiguration(initializers = IntegrationTestConfiguration.Initializer.class) +class GrpcWorkerRefreshSecretAssertionsTokenTest { + @Autowired + private TestTaskService testTaskService; + + @Autowired + private TokenService tokenService; + + @Autowired + private TaskService taskService; + + @Autowired + private JsonMapper jsonMapper; + + @Autowired + private EssService essService; + + @Value("${nvct.notary.base-url}") + private String notaryBaseUrl; + + @Value("${spring.security.oauth2.client.registration.notary.client-id}") + private String notaryClientId; + + @Value("${nvct.nvcf.base-url}") + private URL nvcfBaseUrl; + + @Value("${nvct.icms.base-url}") + private URL icmsBaseUrl; + + @Value("${nvct.ess.base-url}") + private String essBaseUrl; + + private ManagedChannel channel; + private WorkerGrpc.WorkerBlockingStub workerBlockingStub; + private WorkerGrpc.WorkerStub workerStub; + + @SneakyThrows + @BeforeAll + void beforeAll() { + log.info("{}: Started running tests", this.getClass().getSimpleName()); + MockNvcfServer.start(nvcfBaseUrl); + MockEssServer.start(essBaseUrl); + MockIcmsServer.start(icmsBaseUrl, jsonMapper); + MockNotaryServer.start(notaryBaseUrl, notaryClientId); + } + + @AfterAll + void cleanup() { + MockNvcfServer.stop(); + MockIcmsServer.stop(); + MockEssServer.stop(); + MockNotaryServer.stop(); + log.info("{}: Completed running tests", this.getClass().getSimpleName()); + } + + @AfterEach + void reset() { + log.info("{} reset", this.getClass().getSimpleName()); + channel.shutdown(); + testTaskService.clearAll(); + MockEssServer.clearSecrets(); + } + + @BeforeEach + void setup() { + log.info("{} setup", this.getClass().getSimpleName()); + } + + private void setupGrpc(String jwtToken) { + var md = new Metadata(); + md.put(MD_KEY_AUTHORIZATION, "Bearer " + jwtToken); + channel = ManagedChannelBuilder + .forAddress("localhost", 9090) + .usePlaintext() + .intercept(MetadataUtils.newAttachHeadersInterceptor(md)) + .build(); + workerBlockingStub = WorkerGrpc.newBlockingStub(channel); + workerStub = WorkerGrpc.newStub(channel); + } + + @Test + void refreshSecretsAssertionTokenForTaskWithoutSecretsAndTelemetries() { + // Create Task with no secrets. + testTaskService.createTask(TEST_NCA_ID, TEST_TASK_ID_1, TEST_ICMS_REQ_ID_1); + + var token = tokenService.issueWorkerAccessAssertion(TEST_NCA_ID, TEST_TASK_ID_1); + setupGrpc(token); + + var taskId = TEST_TASK_ID_1.toString(); + var request = SecretCredentialsRequest.newBuilder().setTaskId(taskId).build(); + var response = workerBlockingStub.requestSecretCredentials(request); + assertThat(response).isNotNull(); + assertThat(response.getExpiration()).isNotNull(); + assertThat(response.getSecretCredentialsToken()).isBlank(); + assertThat(fromTimestamp(response.getExpiration())) + .isAfterOrEqualTo(Instant.now().plus(Duration.ofHours(1))); + } + + @Test + void refreshSecretsAssertionTokenForTaskWithSecretsAndWithoutTelemetries() { + // Create Task with secrets. + testTaskService.createTask(TEST_NCA_ID, TEST_TASK_ID_1, TEST_ICMS_REQ_ID_1); + essService.saveSecrets(TEST_TASK_ID_1, TEST_SECRETS); + + // Update task to indicate it has secrets + var taskEntity = taskService.fetchTask(TEST_TASK_ID_1); + taskEntity.setHasSecrets(true); + taskService.updateTask(taskEntity); + + var token = tokenService.issueWorkerAccessAssertion(TEST_NCA_ID, TEST_TASK_ID_1); + setupGrpc(token); + + var taskId = TEST_TASK_ID_1.toString(); + var request = SecretCredentialsRequest.newBuilder().setTaskId(taskId).build(); + var response = workerBlockingStub.requestSecretCredentials(request); + assertThat(response).isNotNull(); + assertThat(response.getExpiration()).isNotNull(); + assertThat(response.getSecretCredentialsToken()).isNotBlank(); + assertThat(fromTimestamp(response.getExpiration())) + .isAfterOrEqualTo(Instant.now().plus(Duration.ofHours(1))); + } + + @Test + void refreshSecretsAssertionTokenForTaskWithoutSecretsAndWithTelemetries() { + // Create Task with Telemetries defined in account TEST_NCA_ID_WITH_TELEMETRIES_4. + var telemetriesUdt = TelemetriesUdt.builder() + .logsTelemetryId(TEST_TELEMETRY_LOGS_ID).build(); + testTaskService.createTaskWithTelemetries(TEST_NCA_ID_WITH_TELEMETRIES_4, + TEST_TASK_ID_1, + TEST_ICMS_REQ_ID_1, + telemetriesUdt); + + var token = tokenService.issueWorkerAccessAssertion(TEST_NCA_ID_WITH_TELEMETRIES_4, + TEST_TASK_ID_1); + setupGrpc(token); + + var taskId = TEST_TASK_ID_1.toString(); + var request = SecretCredentialsRequest.newBuilder().setTaskId(taskId).build(); + var response = workerBlockingStub.requestSecretCredentials(request); + assertThat(response).isNotNull(); + assertThat(response.getExpiration()).isNotNull(); + assertThat(response.getSecretCredentialsToken()).isNotBlank(); + assertThat(fromTimestamp(response.getExpiration())) + .isAfterOrEqualTo(Instant.now().plus(Duration.ofHours(1))); + } + + @Test + void refreshSecretsAssertionTokenForTaskWithSecretsAndWithTelemetries() { + // Create Task with secrets amd Telemetries defined in account TEST_NCA_ID_WITH_TELEMETRIES_4. + var telemetriesUdt = TelemetriesUdt.builder() + .logsTelemetryId(TEST_TELEMETRY_LOGS_ID).build(); + testTaskService.createTaskWithTelemetries(TEST_NCA_ID_WITH_TELEMETRIES_4, + TEST_TASK_ID_1, + TEST_ICMS_REQ_ID_1, + telemetriesUdt); + essService.saveSecrets(TEST_TASK_ID_1, TEST_SECRETS); + + // Update task to indicate it has secrets + var taskEntity = taskService.fetchTask(TEST_TASK_ID_1); + taskEntity.setHasSecrets(true); + taskService.updateTask(taskEntity); + + var token = tokenService.issueWorkerAccessAssertion(TEST_NCA_ID_WITH_TELEMETRIES_4, + TEST_TASK_ID_1); + setupGrpc(token); + + var taskId = TEST_TASK_ID_1.toString(); + var request = SecretCredentialsRequest.newBuilder().setTaskId(taskId).build(); + var response = workerBlockingStub.requestSecretCredentials(request); + assertThat(response).isNotNull(); + assertThat(response.getExpiration()).isNotNull(); + assertThat(response.getSecretCredentialsToken()).isNotBlank(); + assertThat(fromTimestamp(response.getExpiration())) + .isAfterOrEqualTo(Instant.now().plus(Duration.ofHours(1))); + } + +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/grpc/GrpcWorkerServiceTest.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/grpc/GrpcWorkerServiceTest.java new file mode 100644 index 000000000..3d14b15eb --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/grpc/GrpcWorkerServiceTest.java @@ -0,0 +1,817 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.grpc; + +import static com.nvidia.nvct.proto.ArtifactsResponse.ArtifactResponse.ArtifactKindEnum.MODEL; +import static com.nvidia.nvct.proto.ArtifactsResponse.ArtifactResponse.ArtifactKindEnum.RESOURCE; +import static com.nvidia.nvct.proto.ExecutionStatus.COMPLETED; +import static com.nvidia.nvct.proto.ExecutionStatus.ERRORED; +import static com.nvidia.nvct.proto.ExecutionStatus.EXCEEDED_MAX_RUNTIME_DURATION; +import static com.nvidia.nvct.proto.ExecutionStatus.IN_PROGRESS; +import static com.nvidia.nvct.proto.ExecutionStatus.LAUNCHED; +import static com.nvidia.nvct.proto.ExecutionStatus.PENDING_EVALUATION; +import static com.nvidia.nvct.proto.ExecutionStatus.TASK_CONTAINER_INITIALIZING; +import static com.nvidia.nvct.proto.ExecutionStatus.WORKER_TERMINATED; +import static com.nvidia.nvct.util.ProtoMappingUtils.fromTimestamp; +import static com.nvidia.nvct.util.TestConstants.L40G_INSTANCE_TYPE; +import static com.nvidia.nvct.util.TestConstants.MD_KEY_AUTHORIZATION; +import static com.nvidia.nvct.util.TestConstants.TEST_MODELS; +import static com.nvidia.nvct.util.TestConstants.TEST_NCA_ID; +import static com.nvidia.nvct.util.TestConstants.TEST_NCA_ID_2; +import static com.nvidia.nvct.util.TestConstants.TEST_ICMS_REQ_ID_1; +import static com.nvidia.nvct.util.TestConstants.TEST_ICMS_REQ_ID_2; +import static com.nvidia.nvct.util.TestConstants.TEST_ICMS_REQ_ID_3; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_ID_1; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_ID_2; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_ID_3; +import static org.assertj.core.api.Assertions.assertThat; + +import tools.jackson.databind.json.JsonMapper; +import com.google.protobuf.ByteString; +import com.nimbusds.jwt.JWTClaimsSet; +import com.nimbusds.jwt.PlainJWT; +import com.nvidia.boot.mock.ngc.MockCasServer; +import com.nvidia.nvct.IntegrationTestConfiguration; +import com.nvidia.nvct.NvctTestApp; +import com.nvidia.nvct.persistence.task.entity.TaskStatus; +import com.nvidia.nvct.proto.ArtifactsRequest; +import com.nvidia.nvct.proto.ArtifactsResponse; +import com.nvidia.nvct.proto.ConnectRequest; +import com.nvidia.nvct.proto.ErrorDetails; +import com.nvidia.nvct.proto.HeartbeatRequest; +import com.nvidia.nvct.proto.HeartbeatResponse; +import com.nvidia.nvct.proto.RefreshTokenRequest; +import com.nvidia.nvct.proto.ResultMetadata; +import com.nvidia.nvct.proto.ResultMetadataRequest; +import com.nvidia.nvct.proto.SecretCredentialsRequest; +import com.nvidia.nvct.proto.WorkerGrpc; +import com.nvidia.nvct.rest.result.dto.ResultDto; +import com.nvidia.nvct.service.result.ResultService; +import com.nvidia.nvct.service.task.TaskService; +import com.nvidia.nvct.service.token.TokenService; +import com.nvidia.nvct.util.MockEssServer; +import com.nvidia.nvct.util.MockNotaryServer; +import com.nvidia.nvct.util.MockNvcfServer; +import com.nvidia.nvct.util.MockIcmsServer; +import io.grpc.ManagedChannel; +import io.grpc.ManagedChannelBuilder; +import io.grpc.Metadata; +import io.grpc.Status; +import io.grpc.stub.MetadataUtils; +import io.grpc.stub.StreamObserver; +import java.net.URL; +import java.time.Duration; +import java.time.Instant; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.stream.Stream; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ContextConfiguration; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@Slf4j +@SpringBootTest(classes = {NvctTestApp.class, + IntegrationTestConfiguration.class}, + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + properties = { + "spring.profiles.active=test", + "grpc.server.port=9090" + }) +@ContextConfiguration(initializers = IntegrationTestConfiguration.Initializer.class) +class GrpcWorkerServiceTest { + + @Autowired + private TestTaskService testTaskService; + + @Autowired + private TaskService taskService; + + @Autowired + private TokenService tokenService; + + @Autowired + private ResultService resultService; + + @Autowired + private JsonMapper jsonMapper; + + @Value("${nvct.registries.recognized.model.ngc.hostname}") + private String casBaseUrl; + + @Value("${nvct.registries.recognized.model.ngc.oauth2.base-url}") + private String authnBaseUrl; + + @Value("${nvct.notary.base-url}") + private String notaryBaseUrl; + + @Value("${spring.security.oauth2.client.registration.notary.client-id}") + private String notaryClientId; + + @Value("${nvct.nvcf.base-url}") + private URL nvcfBaseUrl; + + @Value("${nvct.icms.base-url}") + private URL icmsBaseUrl; + + @Value("${nvct.ess.base-url}") + private String essBaseUrl; + + private ManagedChannel channel; + private WorkerGrpc.WorkerBlockingStub workerBlockingStub; + private WorkerGrpc.WorkerStub workerStub; + + @SneakyThrows + @BeforeAll + void beforeAll() { + log.info("{}: Started running tests", this.getClass().getSimpleName()); + MockCasServer.start(authnBaseUrl, casBaseUrl); + MockNvcfServer.start(nvcfBaseUrl); + MockEssServer.start(essBaseUrl); + MockIcmsServer.start(icmsBaseUrl, jsonMapper); + MockNotaryServer.start(notaryBaseUrl, notaryClientId); + } + + @AfterAll + void cleanup() { + MockCasServer.stop(); + MockNvcfServer.stop(); + MockIcmsServer.stop(); + MockEssServer.stop(); + MockNotaryServer.stop(); + log.info("{}: Completed running tests", this.getClass().getSimpleName()); + } + + @AfterEach + void reset() { + log.info("{} reset", this.getClass().getSimpleName()); + channel.shutdown(); + testTaskService.clearAll(); + MockEssServer.clearSecrets(); + } + + @BeforeEach + void setup() { + log.info("{} setup", this.getClass().getSimpleName()); + testTaskService.createTask(TEST_NCA_ID, TEST_TASK_ID_1, TEST_ICMS_REQ_ID_1); + testTaskService.createTaskWithModel(TEST_NCA_ID, TEST_TASK_ID_2, TEST_ICMS_REQ_ID_2, + TEST_MODELS); + testTaskService.createTaskWithModelAndResources(TEST_NCA_ID_2, TEST_TASK_ID_3, + TEST_ICMS_REQ_ID_3); + } + + private void setupGrpc(String jwtToken) { + var md = new Metadata(); + md.put(MD_KEY_AUTHORIZATION, "Bearer " + jwtToken); + channel = ManagedChannelBuilder + .forAddress("localhost", 9090) + .usePlaintext() + .intercept(MetadataUtils.newAttachHeadersInterceptor(md)) + .build(); + workerBlockingStub = WorkerGrpc.newBlockingStub(channel); + workerStub = WorkerGrpc.newStub(channel); + } + + private void resetGrpc(String jwtToken) { + channel.shutdown(); + setupGrpc(jwtToken); + } + + Stream connectArgs() { + return Stream.of( + Arguments.of(tokenService.issueWorkerAccessAssertion(TEST_NCA_ID, + TEST_TASK_ID_1), + TEST_TASK_ID_1, + Status.Code.OK), + // task-id mismatch + Arguments.of(tokenService.issueWorkerAccessAssertion(TEST_NCA_ID, + TEST_TASK_ID_1), + TEST_TASK_ID_2, + Status.Code.PERMISSION_DENIED) + ); + } + + @ParameterizedTest + @MethodSource("connectArgs") + void testConnect( + String token, + UUID taskIdConnect, + Status.Code expectedStatus) { + setupGrpc(token); + validateTaskStatus(TEST_NCA_ID, taskIdConnect, TaskStatus.QUEUED); + var status = Status.Code.OK; + try { + connect(taskIdConnect); + validateTaskStatus(TEST_NCA_ID, taskIdConnect, TaskStatus.LAUNCHED); + assertThat(testTaskService.getEventCount(taskIdConnect)).isEqualTo(1); + } catch (Exception e) { + status = Status.fromThrowable(e).getCode(); + } + assertThat(status).isEqualTo(expectedStatus); + } + + @Test + void testConnectRejectsUnsignedWorkerAssertion() { + var unsignedToken = new PlainJWT(new JWTClaimsSet.Builder() + .issuer(notaryBaseUrl) + .subject(notaryClientId) + .issueTime(new Date()) + .claim("assertion", + Map.of("ncaId", TEST_NCA_ID, "taskId", TEST_TASK_ID_1.toString())) + .build()).serialize(); + + setupGrpc(unsignedToken); + validateTaskStatus(TEST_NCA_ID, TEST_TASK_ID_1, TaskStatus.QUEUED); + + var status = Status.Code.OK; + try { + connect(TEST_TASK_ID_1); + } catch (Exception e) { + status = Status.fromThrowable(e).getCode(); + } + + assertThat(status).isEqualTo(Status.Code.PERMISSION_DENIED); + validateTaskStatus(TEST_NCA_ID, TEST_TASK_ID_1, TaskStatus.QUEUED); + } + + Stream heartBeatArgs() { + var requestOk = HeartbeatRequest.newBuilder() + .setTaskId(TEST_TASK_ID_1.toString()) + .build(); + var requestErr = HeartbeatRequest.newBuilder() + .setTaskId(TEST_TASK_ID_1.toString()) + .setErrorMessage("I am in error") + .setStatus(ERRORED) + .setInstanceType(L40G_INSTANCE_TYPE) + .build(); + var requestErrNoInstance = HeartbeatRequest.newBuilder() + .setTaskId(TEST_TASK_ID_1.toString()) + .setErrorMessage("I am in error") + .build(); + var requestErrBadInstance = + HeartbeatRequest.newBuilder() + .setTaskId(TEST_TASK_ID_1.toString()) + .setErrorMessage("I am in error") + .setInstanceType("I am a teapot!") + .build(); + var requestOkErrrored = + HeartbeatRequest.newBuilder() + .setTaskId(TEST_TASK_ID_1.toString()) + .setInstanceType(L40G_INSTANCE_TYPE) + .setStatus(ERRORED) + .setErrorMessage("System error - ESS Agent failed") + .build(); + var requestOkExceededMaxDuration = + HeartbeatRequest.newBuilder() + .setTaskId(TEST_TASK_ID_1.toString()) + .setInstanceType(L40G_INSTANCE_TYPE) + .setStatus(EXCEEDED_MAX_RUNTIME_DURATION) + .setErrorMessage("System error - Exceeded specified max runtime duration") + .build(); + var requestContainerInitializing = + HeartbeatRequest.newBuilder() + .setTaskId(TEST_TASK_ID_1.toString()) + .setInstanceType(L40G_INSTANCE_TYPE) + .setStatus(TASK_CONTAINER_INITIALIZING) + .build(); + var workerTerminated = + HeartbeatRequest.newBuilder() + .setTaskId(TEST_TASK_ID_1.toString()) + .setInstanceType(L40G_INSTANCE_TYPE) + .setStatus(WORKER_TERMINATED) + .build(); + + return Stream.of( + Arguments.of(tokenService.issueWorkerAccessAssertion(TEST_NCA_ID, + TEST_TASK_ID_1), + TEST_TASK_ID_1, + TaskStatus.RUNNING, + TaskStatus.RUNNING, + requestOk, + null, + Status.Code.OK), + Arguments.of(tokenService.issueWorkerAccessAssertion(TEST_NCA_ID, + TEST_TASK_ID_1), + TEST_TASK_ID_1, + TaskStatus.RUNNING, + TaskStatus.ERRORED, + requestOk, + requestOkErrrored, + Status.Code.OK), + Arguments.of(tokenService.issueWorkerAccessAssertion(TEST_NCA_ID, + TEST_TASK_ID_1), + TEST_TASK_ID_1, + TaskStatus.RUNNING, + TaskStatus.EXCEEDED_MAX_RUNTIME_DURATION, + requestOk, + requestOkExceededMaxDuration, + Status.Code.OK), + // ok followed by error + Arguments.of(tokenService.issueWorkerAccessAssertion(TEST_NCA_ID, + TEST_TASK_ID_1), + TEST_TASK_ID_1, + TaskStatus.RUNNING, + TaskStatus.ERRORED, + requestOk, + requestErr, + Status.Code.OK), + // task-id mismatch + Arguments.of(tokenService.issueWorkerAccessAssertion(TEST_NCA_ID, + TEST_TASK_ID_1), + TEST_TASK_ID_1, + TaskStatus.LAUNCHED, + TaskStatus.LAUNCHED, + requestOk.toBuilder().setTaskId(TEST_TASK_ID_2.toString()).build(), + null, + Status.Code.PERMISSION_DENIED), + // invalid instance in error details + Arguments.of(tokenService.issueWorkerAccessAssertion(TEST_NCA_ID, + TEST_TASK_ID_1), + TEST_TASK_ID_1, + TaskStatus.RUNNING, + TaskStatus.RUNNING, + requestOk, + requestErrNoInstance, + Status.Code.INTERNAL), + // Heartbeat with TASK_CONTAINER_INITIALIZING as ExecutionStatus + Arguments.of(tokenService.issueWorkerAccessAssertion(TEST_NCA_ID, + TEST_TASK_ID_1), + TEST_TASK_ID_1, + TaskStatus.LAUNCHED, + TaskStatus.LAUNCHED, + requestContainerInitializing, + null, + Status.Code.OK), + // Heartbeat with WORKER_TERMINATED as ExecutionStatus + Arguments.of(tokenService.issueWorkerAccessAssertion(TEST_NCA_ID, + TEST_TASK_ID_1), + TEST_TASK_ID_1, + TaskStatus.LAUNCHED, + TaskStatus.LAUNCHED, + workerTerminated, + null, + Status.Code.OK) + // ### Temporarily commented out till NVCA sends correct instanceType to Utils. + // Arguments.of(tokenService.issueWorkerAccessAssertion(TEST_NCA_ID, + // TEST_TASK_ID_1), + // TEST_TASK_ID_1, + // TaskStatus.RUNNING, + // TaskStatus.RUNNING, + // requestOk, + // requestErrBadInstance, + // Status.Code.INTERNAL) + ); + } + + @ParameterizedTest + @MethodSource("heartBeatArgs") + void testHeartBeat( + String token, + UUID taskId, + TaskStatus initialStatus, + TaskStatus finalStatus, + HeartbeatRequest reqOk, + HeartbeatRequest reqErr, + Status.Code expectedStatus) { + setupGrpc(tokenService.issueWorkerAccessAssertion(TEST_NCA_ID, taskId)); + connect(taskId); + resetGrpc(token); + var status = Status.Code.OK; + try { + var responseOK = sendHeartbeat(reqOk); + assertThat(responseOK.getTaskId()).isEqualTo(taskId.toString()); + assertThat(responseOK.getExecutionStatus()).isEqualTo(LAUNCHED.toString()); + validateTaskStatus(TEST_NCA_ID, taskId, initialStatus); + connect(taskId); + validateTaskStatus(TEST_NCA_ID, taskId, initialStatus); + if ((reqOk.getStatus() == TASK_CONTAINER_INITIALIZING) + || (reqOk.getStatus() == WORKER_TERMINATED)) { + assertThat(testTaskService.getEventCount(taskId)).isEqualTo(1); + } else { + assertThat(testTaskService.getEventCount(taskId)).isEqualTo(2); + } + // Send same heartbeat again + // This time the task execution status from last grpc call should be reflected + responseOK = sendHeartbeat(reqOk); + assertThat(responseOK.getTaskId()).isEqualTo(taskId.toString()); + assertThat(responseOK.getExecutionStatus()).isEqualTo(initialStatus.toString()); + if (reqErr != null) { + var responseErr = sendHeartbeat(reqErr); + assertThat(responseErr.getTaskId()).isEqualTo(taskId.toString()); + assertThat(responseErr.getExecutionStatus()).isEqualTo(initialStatus.toString()); + validateTaskStatus(TEST_NCA_ID, taskId, finalStatus); + // Send same heartbeat again + // This time the errored task execution status from last grpc call should be reflected + responseErr = sendHeartbeat(reqErr); + assertThat(responseErr.getTaskId()).isEqualTo(taskId.toString()); + assertThat(responseErr.getExecutionStatus()).isEqualTo(finalStatus.toString()); + } + } catch (Exception e) { + status = Status.fromThrowable(e).getCode(); + } + assertThat(status).isEqualTo(expectedStatus); + } + + Stream artifactsArgs() { + return Stream.of( + Arguments.of(tokenService.issueWorkerAccessAssertion(TEST_NCA_ID, + TEST_TASK_ID_1), + TEST_TASK_ID_1, + 0, 0, 0, 0, 0, + Status.Code.OK), + Arguments.of(tokenService.issueWorkerAccessAssertion(TEST_NCA_ID, + TEST_TASK_ID_2), + TEST_TASK_ID_2, + 2, 2, 4, 0, 0, + Status.Code.OK), + // task-id mismatch + Arguments.of(tokenService.issueWorkerAccessAssertion(TEST_NCA_ID, + TEST_TASK_ID_1), + TEST_TASK_ID_2, + 0, 0, 0, 0, 0, + Status.Code.PERMISSION_DENIED) + ); + } + + @ParameterizedTest + @MethodSource("artifactsArgs") + void testGetArtifacts( + String token, + UUID taskId, + int artifactCount, + int modelCount, + int modelFiles, + int resourceCount, + int resourceFiles, + Status.Code expectedStatus) { + setupGrpc(tokenService.issueWorkerAccessAssertion(TEST_NCA_ID, taskId)); + connect(taskId); + resetGrpc(token); + var status = Status.Code.OK; + var request = ArtifactsRequest.newBuilder() + .setTaskId(taskId.toString()) + .build(); + try { + var artifacts = getArtifacts(request); + assertThat(artifacts).isNotNull(); + assertThat(artifacts.getArtifactsCount()).isEqualTo(artifactCount); + for (int i = 0; i < artifactCount; i++) { + if (artifacts.getArtifacts(i).getKind().equals(MODEL)) { + modelCount--; + modelFiles -= artifacts.getArtifacts(i).getFilesCount(); + } else if (artifacts.getArtifacts(i).getKind().equals(RESOURCE)) { + resourceCount--; + resourceFiles -= artifacts.getArtifacts(i).getFilesCount(); + } + } + assertThat(modelCount).isZero(); + assertThat(resourceCount).isZero(); + assertThat(modelFiles).isZero(); + assertThat(resourceFiles).isZero(); + } catch (Exception e) { + status = Status.fromThrowable(e).getCode(); + } + assertThat(status).isEqualTo(expectedStatus); + } + + Stream resultMetadataArgs() { + var metadataJSON = """ + {"step-number": 2000, "token_accuracy": 0.874} + """; + + var metadata = ResultMetadata.newBuilder() + .setBody(ByteString.copyFromUtf8(metadataJSON)) + .build(); + var metadataText = "I am a teapot!"; + var metadataErr = ResultMetadata.newBuilder() + .setBody(ByteString.copyFromUtf8(metadataText)) + .build(); + var resultMetadataRequest = ResultMetadataRequest.newBuilder() + .setTaskId(TEST_TASK_ID_1.toString()) + .setPercentComplete(10) + .setResultName("Name 10") + .setStatus(IN_PROGRESS) + .setMetadata(metadata) + .setInstanceType(L40G_INSTANCE_TYPE) + .build(); + var errorDetails = ErrorDetails.newBuilder() + .setType("Type1") + .setTitle("Failed Execution") + .setStatus(75) + .setDetail("Failed Execution") + .build(); + return Stream.of( + Arguments.of(tokenService.issueWorkerAccessAssertion(TEST_NCA_ID, + TEST_TASK_ID_1), + TEST_TASK_ID_1, + resultMetadataRequest, + resultMetadataRequest.toBuilder() + .setStatus(COMPLETED) + .setPercentComplete(100) + .build(), + 100, + Status.Code.OK), + // Null ResultMetadata and null ErrorDetails + Arguments.of(tokenService.issueWorkerAccessAssertion(TEST_NCA_ID, + TEST_TASK_ID_1), + TEST_TASK_ID_1, + resultMetadataRequest, + ResultMetadataRequest.newBuilder() + .setTaskId(TEST_TASK_ID_1.toString()) + .setPercentComplete(50) + .setResultName("PERCENT_50") + .setStatus(IN_PROGRESS) + .setInstanceType(L40G_INSTANCE_TYPE) + .build(), + 50, + Status.Code.INTERNAL), + // Empty ResultMetadata + Arguments.of(tokenService.issueWorkerAccessAssertion(TEST_NCA_ID, + TEST_TASK_ID_1), + TEST_TASK_ID_1, + resultMetadataRequest, + resultMetadataRequest.toBuilder() + .setStatus(COMPLETED) + .setPercentComplete(100) + .setMetadata(ResultMetadata.newBuilder().build()) + .build(), + 100, + Status.Code.OK), + // "null" ResultMetadata + Arguments.of(tokenService.issueWorkerAccessAssertion(TEST_NCA_ID, + TEST_TASK_ID_1), + TEST_TASK_ID_1, + resultMetadataRequest, + resultMetadataRequest.toBuilder() + .setStatus(COMPLETED) + .setPercentComplete(100) + .setMetadata(ResultMetadata.newBuilder() + .setBody(ByteString.copyFromUtf8("null")) + .build()) + .build(), + 100, + Status.Code.OK), + Arguments.of(tokenService.issueWorkerAccessAssertion(TEST_NCA_ID, + TEST_TASK_ID_1), + TEST_TASK_ID_1, + resultMetadataRequest, + resultMetadataRequest.toBuilder() + .setStatus(ERRORED) + .setPercentComplete(10) + .setErrorDetails(errorDetails) + .build(), + 10, + Status.Code.OK), + Arguments.of(tokenService.issueWorkerAccessAssertion(TEST_NCA_ID, + TEST_TASK_ID_1), + TEST_TASK_ID_1, + resultMetadataRequest, + resultMetadataRequest.toBuilder() + .setStatus(EXCEEDED_MAX_RUNTIME_DURATION) + .setPercentComplete(10) + .setErrorDetails(errorDetails) + .build(), + 10, + Status.Code.OK), + // bad metadata + Arguments.of(tokenService.issueWorkerAccessAssertion(TEST_NCA_ID, + TEST_TASK_ID_1), + TEST_TASK_ID_1, + resultMetadataRequest.toBuilder() + .setMetadata(metadataErr) + .build(), + null, + null, + Status.Code.INTERNAL), + // task-id mismatch + Arguments.of(tokenService.issueWorkerAccessAssertion(TEST_NCA_ID, + TEST_TASK_ID_1), + TEST_TASK_ID_1, + resultMetadataRequest.toBuilder() + .setTaskId(TEST_TASK_ID_2.toString()) + .build(), + null, + null, + Status.Code.PERMISSION_DENIED), + // invalid state + Arguments.of(tokenService.issueWorkerAccessAssertion(TEST_NCA_ID, + TEST_TASK_ID_1), + TEST_TASK_ID_1, + resultMetadataRequest.toBuilder() + .setStatus(PENDING_EVALUATION) + .build(), + null, + null, + Status.Code.INTERNAL) + // ### Temporarily commented out till NVCA sends correct instanceType to Utils. + // invalid instance + // Arguments.of(tokenService.issueWorkerAccessAssertion(TEST_NCA_ID, + // TEST_TASK_ID_1), + // TEST_TASK_ID_1, + // resultMetadataRequest.toBuilder() + // .setStatus(ERRORED) + // .setInstanceType("Invalid Instance") + // .setErrorDetails(errorDetails).build(), + // null, + // null, + // Status.Code.INTERNAL) + ); + } + + @ParameterizedTest + @MethodSource("resultMetadataArgs") + void testResultMetadata( + String token, + UUID taskId, + ResultMetadataRequest reqInitial, + ResultMetadataRequest reqFinal, + Integer percentComplete, + Status.Code expectedStatus) { + setupGrpc(tokenService.issueWorkerAccessAssertion(TEST_NCA_ID, taskId)); + connect(taskId); + sendHeartbeat(taskId); + resetGrpc(token); + + var event = 2; + final CountDownLatch finishLatch = new CountDownLatch(1); + StreamObserver requestStreamObserver = + workerStub.sendResultMetadata( + new TestResultMetadataStreamObserver(taskId, + TaskStatus.RUNNING, + finishLatch, + expectedStatus)); + requestStreamObserver.onNext(reqInitial); + + if (reqFinal != null) { + assertThat(finishLatch.getCount()).isEqualTo(1); + requestStreamObserver.onNext(reqFinal); + assertThat(finishLatch.getCount()).isEqualTo(1); + requestStreamObserver.onCompleted(); + event++; + } + + // Receiving happens asynchronously + try { + if (!finishLatch.await(1, TimeUnit.MINUTES)) { + log.error("ResultMetadataResponse can not finish within 1 minutes"); + assertThat(finishLatch.getCount()).isZero(); + } + } catch (InterruptedException e) { + log.error("Interrupted", e); + Assertions.fail("Test failed: " + e.getMessage()); + } + + if (expectedStatus != Status.Code.OK) { + return; + } + + assertThat(testTaskService.getEventCount(taskId)).isEqualTo(event); + if (reqFinal != null && reqFinal.hasPercentComplete()) { + assertThat(testTaskService.getPercentComplete(taskId)) + .isEqualTo(reqFinal.getPercentComplete()); + } + if (percentComplete != null) { + var results = resultService.fetchResults(TEST_NCA_ID, taskId); + List mutableList = new ArrayList<>(results); + mutableList.sort(Comparator.comparing(ResultDto::createdAt)); + assertThat(mutableList.getLast().metadata().get("percentComplete").asInt()) + .isEqualTo(percentComplete.intValue()); + } + } + + Stream tokenArgs() { + return Stream.of( + Arguments.of(tokenService.issueWorkerAccessAssertion(TEST_NCA_ID, + TEST_TASK_ID_1), + TEST_TASK_ID_1, + Status.Code.OK), + // task-id mismatch + Arguments.of(tokenService.issueWorkerAccessAssertion(TEST_NCA_ID, + TEST_TASK_ID_1), + TEST_TASK_ID_2, + Status.Code.PERMISSION_DENIED) + ); + } + + @ParameterizedTest + @MethodSource("tokenArgs") + void testRefreshToken( + String token, + UUID taskId, + Status.Code expectedStatus) { + var request = RefreshTokenRequest.newBuilder().setTaskId(taskId.toString()).build(); + setupGrpc(token); + var status = Status.Code.OK; + try { + var newToken = refreshToken(request); + resetGrpc(newToken); + connect(taskId); + } catch (Exception e) { + status = Status.fromThrowable(e).getCode(); + } + assertThat(status).isEqualTo(expectedStatus); + } + + @Test + void testRequestSecretCredentials() { + var token = tokenService.issueWorkerAccessAssertion(TEST_NCA_ID, + TEST_TASK_ID_1); + setupGrpc(token); + var status = Status.Code.OK; + var taskId = TEST_TASK_ID_1; + var request = SecretCredentialsRequest.newBuilder() + .setTaskId(taskId.toString()) + .build(); + try { + requestSecretCredentials(request); + } catch (Exception e) { + status = Status.fromThrowable(e).getCode(); + } + assertThat(status).isEqualTo(Status.Code.OK); + } + + private void connect(UUID taskId) { + var connect = workerBlockingStub.connect(ConnectRequest.newBuilder() + .setTaskId(taskId.toString()) + .setInstanceId("local-instance") + .build()); + assertThat(connect).isNotNull(); + assertThat(connect.getConnectedRegion()).isNotNull(); + log.info("worker connected"); + } + + private void sendHeartbeat(UUID taskId) { + var heartbeat = workerBlockingStub.sendHeartbeat(HeartbeatRequest.newBuilder() + .setTaskId(taskId.toString()) + .build()); + assertThat(heartbeat).isNotNull(); + } + + private HeartbeatResponse sendHeartbeat(HeartbeatRequest heartbeatRequest) { + var heartbeat = workerBlockingStub.sendHeartbeat(heartbeatRequest); + assertThat(heartbeat).isNotNull(); + return heartbeat; + } + + private String refreshToken(RefreshTokenRequest request) { + var tokenResponse = workerBlockingStub.refreshToken(request); + assertThat(tokenResponse).isNotNull(); + assertThat(tokenResponse.getToken()).isNotNull(); + return tokenResponse.getToken(); + } + + private void requestSecretCredentials(SecretCredentialsRequest request) { + var response = workerBlockingStub.requestSecretCredentials(request); + assertThat(response).isNotNull(); + assertThat(response.getExpiration()).isNotNull(); + assertThat(fromTimestamp(response.getExpiration())) + .isAfterOrEqualTo(Instant.now().plus(Duration.ofHours(1))); + } + + private ArtifactsResponse getArtifacts(ArtifactsRequest request) { + return workerBlockingStub.getArtifacts(request); + } + + private void validateTaskStatus(String ncaId, UUID taskId, TaskStatus status) { + var taskEntity = taskService.fetchTask(taskId); + assertThat(taskEntity.getStatus()).isEqualTo(status); + assertThat(taskEntity.getNcaId()).isEqualTo(ncaId); + if (status == TaskStatus.ERRORED) { + assertThat(taskEntity.getHealth()).isNotBlank(); + } + } + +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/grpc/TestResultMetadataStreamObserver.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/grpc/TestResultMetadataStreamObserver.java new file mode 100644 index 000000000..fd57a7160 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/grpc/TestResultMetadataStreamObserver.java @@ -0,0 +1,69 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.grpc; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThat; + +import com.nvidia.nvct.persistence.task.entity.TaskStatus; +import com.nvidia.nvct.proto.ResultMetadataResponse; +import io.grpc.Status; +import io.grpc.stub.StreamObserver; +import java.util.UUID; +import java.util.concurrent.CountDownLatch; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class TestResultMetadataStreamObserver + implements StreamObserver { + + private final CountDownLatch finishLatch; + private final Status.Code expectedStatus; + private final UUID taskId; + private final TaskStatus taskStatus; + + public TestResultMetadataStreamObserver(UUID taskId, + TaskStatus taskStatus, + CountDownLatch finishLatch, + Status.Code expectedStatus) { + this.finishLatch = finishLatch; + this.expectedStatus = expectedStatus; + this.taskId = taskId; + this.taskStatus = taskStatus; + } + + @Override + public void onNext(ResultMetadataResponse resultMetadataResponse) { + assertThat(resultMetadataResponse).isNotNull(); + log.debug("Received metadata response '{}'", resultMetadataResponse); + assertThat(taskId).hasToString(resultMetadataResponse.getTaskId()); + assertThat(taskStatus).hasToString(resultMetadataResponse.getExecutionStatus()); + } + + @Override + public void onError(Throwable throwable) { + log.error("Encountered error in TestResultMetadataStreamObserver ", throwable); + var status = Status.fromThrowable(throwable).getCode(); + assertThat(status).isEqualTo(expectedStatus); + finishLatch.countDown(); + } + + @Override + public void onCompleted() { + log.debug("Finished ResultMetadataRequest"); + finishLatch.countDown(); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/grpc/TestTaskService.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/grpc/TestTaskService.java new file mode 100644 index 000000000..4980c276a --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/grpc/TestTaskService.java @@ -0,0 +1,216 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.grpc; + +import static com.nvidia.nvct.util.TestConstants.TEST_CONTAINER_ARGS; +import static com.nvidia.nvct.util.TestConstants.TEST_CONTAINER_ENVIRONMENT; +import static com.nvidia.nvct.util.TestConstants.TEST_GFN_GPU_SPEC; +import static com.nvidia.nvct.util.TestConstants.TEST_MODELS; +import static com.nvidia.nvct.util.TestConstants.TEST_RESOURCES; +import static com.nvidia.nvct.util.TestConstants.TEST_RESULTS_LOCATION_1; + +import tools.jackson.databind.json.JsonMapper; +import com.nvidia.boot.registries.service.registry.container.ContainerRegistry; +import com.nvidia.boot.registries.service.registry.helm.HelmRegistry; +import com.nvidia.boot.registries.service.registry.model.ModelRegistry; +import com.nvidia.boot.registries.service.registry.resource.ResourceRegistry; +import com.nvidia.nvct.persistence.event.EventsByTaskRepository; +import com.nvidia.nvct.persistence.result.ResultsByTaskRepository; +import com.nvidia.nvct.persistence.task.TasksRepository; +import com.nvidia.nvct.persistence.task.entity.GpuSpecUdt; +import com.nvidia.nvct.persistence.task.entity.ModelUdt; +import com.nvidia.nvct.persistence.task.entity.ResourceUdt; +import com.nvidia.nvct.persistence.task.entity.ResultHandlingStrategy; +import com.nvidia.nvct.persistence.task.entity.TaskEntity; +import com.nvidia.nvct.persistence.task.entity.TaskStatus; +import com.nvidia.nvct.persistence.task.entity.TelemetriesUdt; +import com.nvidia.nvct.service.registry.RegistryArtifactService; +import com.nvidia.nvct.service.task.TaskService; +import com.nvidia.nvct.util.MockEssServer; +import java.time.Duration; +import java.time.Instant; +import java.util.Base64; +import java.util.List; +import java.util.Set; +import java.util.UUID; +import lombok.RequiredArgsConstructor; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +@Slf4j +@Service +@RequiredArgsConstructor +public class TestTaskService { + @Autowired + TasksRepository tasksRepository; + @Autowired + private EventsByTaskRepository eventsByTaskRepository; + @Autowired + private ResultsByTaskRepository resultsByTaskRepository; + @Autowired + private JsonMapper jsonMapper; + @Autowired + private TaskService taskService; + @Autowired + private RegistryArtifactService artifactService; + @Autowired + private List containerRegistries; + @Autowired + private List helmRegistries; + @Autowired + private List modelRegistries; + @Autowired + private List resourceRegistries; + + public void createTaskWithModel(String ncaId, + UUID taskId, + UUID icmsRequestId, + Set models) { + createTask(ncaId, taskId, icmsRequestId, ResultHandlingStrategy.UPLOAD, + models, null, null, null, null, null); + + } + + public void createTaskWithResource(String ncaId, UUID taskId, UUID icmsRequestId) { + createTask(ncaId, taskId, icmsRequestId, ResultHandlingStrategy.UPLOAD, + null, TEST_RESOURCES, null, null, null, null); + } + + public void createTaskWithTelemetries(String ncaId, + UUID taskId, + UUID icmsRequestId, + TelemetriesUdt telemetriesUdt) { + createTask(ncaId, taskId, icmsRequestId, ResultHandlingStrategy.UPLOAD, + null, TEST_RESOURCES, null, null, null, telemetriesUdt); + + } + + public void createTaskWithModelAndResources(String ncaId, + UUID taskId, + UUID icmsRequestId) { + createTask(ncaId, taskId, icmsRequestId, ResultHandlingStrategy.UPLOAD, + TEST_MODELS, TEST_RESOURCES, null, null, null, null); + } + + public void createTask(String ncaId, + UUID taskId, + UUID icmsRequestId) { + createTask(ncaId, taskId, icmsRequestId, ResultHandlingStrategy.UPLOAD, + null, null, null, null, null, null); + } + + public void createTask(String ncaId, + UUID taskId, + UUID icmsRequestId, + TaskStatus status, + GpuSpecUdt gpu) { + createTask(ncaId, taskId, icmsRequestId, ResultHandlingStrategy.UPLOAD, + null, null, null, status, gpu, null); + } + + public void createTask(String ncaId, + UUID taskId, + UUID icmsRequestId, + TaskStatus status) { + createTask(ncaId, taskId, icmsRequestId, ResultHandlingStrategy.UPLOAD, + null, null, null, status, null, null); + } + + public void createTask(String ncaId, + UUID taskId, + UUID icmsRequestId, + Instant createdAt) { + createTask(ncaId, taskId, icmsRequestId, ResultHandlingStrategy.UPLOAD, + null, null, createdAt, null, null, null); + } + + public void createTask(String ncaId, + UUID taskId, + UUID icmsRequestId, + ResultHandlingStrategy resultHandlingStrategy) { + createTask(ncaId, taskId, icmsRequestId, resultHandlingStrategy, + null, null, null, null, null, null); + } + + @SneakyThrows + private void createTask(String ncaId, + UUID taskId, + UUID icmsRequestId, + ResultHandlingStrategy resultHandlingStrategy, + Set models, + Set resources, + Instant createTime, + TaskStatus status, + GpuSpecUdt gpu, + TelemetriesUdt telemetries) { + var createdAt = createTime != null ? createTime : Instant.now(); + var taskStatus = status == null ? TaskStatus.QUEUED : status; + var gpuSpec = gpu == null ? TEST_GFN_GPU_SPEC : gpu; + var name = "Task-" + taskId; + var containerEnv = Base64.getEncoder() + .encodeToString(jsonMapper + .writeValueAsBytes(TEST_CONTAINER_ENVIRONMENT)); + var taskEntity = TaskEntity.builder() + .taskId(taskId) + .ncaId(ncaId) + .name(name) + .status(taskStatus) + .description("My first task") + .tags(Set.of("tag1", "tag2")) + .containerImage("alpine:3.14") + .containerArgs(TEST_CONTAINER_ARGS) + .containerEnvironment(containerEnv) + .models(models) + .resources(resources) + .gpuSpec(gpuSpec) + .maxRuntimeDuration(Duration.parse("PT1H")) + .maxQueuedDuration(Duration.parse("PT1H")) + .terminalGracePeriodDuration(Duration.parse("PT1H")) + .resultHandlingStrategy(resultHandlingStrategy) + .resultsLocation(TEST_RESULTS_LOCATION_1) + .telemetries(telemetries) + .createdAt(createdAt) + .status(taskStatus) + .hasSecrets(null) // Simulate old tasks before this field existed + .build(); + tasksRepository.save(taskEntity); + } + + public void clearAll() { + tasksRepository.deleteAll(); + eventsByTaskRepository.deleteAll(); + resultsByTaskRepository.deleteAll(); + artifactService.invalidateCache(); + + containerRegistries.forEach(ContainerRegistry::invalidateCache); + helmRegistries.forEach(HelmRegistry::invalidateCache); + modelRegistries.forEach(ModelRegistry::invalidateCache); + resourceRegistries.forEach(ResourceRegistry::invalidateCache); + + MockEssServer.clearSecrets(); + } + + public int getEventCount(UUID taskId) { + return (int)eventsByTaskRepository.findByKeyTaskId(taskId).count(); + } + + public Integer getPercentComplete(UUID taskId) { + return taskService.fetchTask(taskId).getPercentComplete(); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/persistence/event/EventsByTaskRepositoryTest.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/persistence/event/EventsByTaskRepositoryTest.java new file mode 100644 index 000000000..ebe914855 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/persistence/event/EventsByTaskRepositoryTest.java @@ -0,0 +1,126 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.persistence.event; + +import static com.nvidia.nvct.util.TestConstants.TEST_NCA_ID; +import static org.assertj.core.api.Assertions.assertThat; + +import tools.jackson.databind.json.JsonMapper; +import com.nvidia.nvct.IntegrationTestConfiguration; +import com.nvidia.nvct.NvctTestApp; +import com.nvidia.nvct.grpc.TestTaskService; +import com.nvidia.nvct.persistence.event.entity.EventByTaskEntity; +import com.nvidia.nvct.persistence.event.entity.EventByTaskKey; +import com.nvidia.nvct.persistence.task.TasksRepository; +import com.nvidia.nvct.util.TestUtil; +import java.time.Instant; +import java.util.List; +import java.util.UUID; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ContextConfiguration; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@Slf4j +@SpringBootTest( + classes = {NvctTestApp.class, IntegrationTestConfiguration.class}, + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + properties = "spring.profiles.active=test") +@ContextConfiguration(initializers = IntegrationTestConfiguration.Initializer.class) +class EventsByTaskRepositoryTest { + + @Autowired + private TasksRepository tasksRepository; + + @Autowired + private TestTaskService testTaskService; + + @Autowired + private EventsByTaskRepository eventsByTaskRepository; + + @Autowired + private JsonMapper jsonMapper; + + @BeforeAll + void beforeAll() { + log.info("{}: Started running tests", this.getClass().getSimpleName()); + } + + @AfterAll + void cleanup() { + log.info("{}: Completed running tests", this.getClass().getSimpleName()); + } + + @BeforeEach + void init() { + tasksRepository.deleteAll(); + eventsByTaskRepository.deleteAll(); + } + + @AfterEach + void reset() { + tasksRepository.deleteAll(); + eventsByTaskRepository.deleteAll(); + testTaskService.clearAll(); + } + + @Test + void testTaskEvents() { + var taskId = UUID.randomUUID(); + var task = TestUtil.createTaskEntity(taskId, TEST_NCA_ID, "task-1", jsonMapper); + + // Create Task. + tasksRepository.save(task); + + // Create Task Events. + var eventId1 = UUID.randomUUID(); + var event1 = EventByTaskEntity.builder() + .key(EventByTaskKey.builder().taskId(taskId).eventId(eventId1).build()) + .ncaId(TEST_NCA_ID) + .message("Task status: QUEUED") + .createdAt(Instant.now()) + .build(); + var eventId2 = UUID.randomUUID(); + var event2 = EventByTaskEntity.builder() + .key(EventByTaskKey.builder().taskId(taskId).eventId(eventId2).build()) + .ncaId(TEST_NCA_ID) + .message("Task status: LAUNCHED") + .createdAt(Instant.now()) + .build(); + eventsByTaskRepository.saveAll(List.of(event1, event2)); + + // Verify Task Events. + assertThat(eventsByTaskRepository.findByKeyTaskId(taskId)).hasSize(2); + + // Delete Task Event. + eventsByTaskRepository.delete(event1); + + // Verify Task Events. + assertThat(eventsByTaskRepository.findByKeyTaskId(taskId)).hasSize(1); + assertThat(eventsByTaskRepository.getByKeyTaskIdAndKeyEventId(taskId, eventId2)) + .isPresent() + .map(entity -> entity.getKey().getEventId()) + .hasValue(eventId2); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/persistence/result/ResultsByTaskRepositoryTest.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/persistence/result/ResultsByTaskRepositoryTest.java new file mode 100644 index 000000000..48d79c93a --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/persistence/result/ResultsByTaskRepositoryTest.java @@ -0,0 +1,128 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.persistence.result; + +import static com.nvidia.nvct.util.TestConstants.TEST_NCA_ID; +import static org.assertj.core.api.Assertions.assertThat; + +import tools.jackson.databind.json.JsonMapper; +import com.nvidia.nvct.IntegrationTestConfiguration; +import com.nvidia.nvct.NvctTestApp; +import com.nvidia.nvct.grpc.TestTaskService; +import com.nvidia.nvct.persistence.result.entity.ResultByTaskEntity; +import com.nvidia.nvct.persistence.result.entity.ResultByTaskKey; +import com.nvidia.nvct.persistence.task.TasksRepository; +import com.nvidia.nvct.util.TestUtil; +import java.time.Instant; +import java.util.List; +import java.util.UUID; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ContextConfiguration; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@Slf4j +@SpringBootTest( + classes = {NvctTestApp.class, IntegrationTestConfiguration.class}, + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + properties = "spring.profiles.active=test") +@ContextConfiguration(initializers = IntegrationTestConfiguration.Initializer.class) +class ResultsByTaskRepositoryTest { + + @Autowired + private TasksRepository tasksRepository; + + @Autowired + private TestTaskService testTaskService; + + @Autowired + private ResultsByTaskRepository resultsByTaskRepository; + + @Autowired + private JsonMapper jsonMapper; + + @BeforeAll + void beforeAll() { + log.info("{}: Started running tests", this.getClass().getSimpleName()); + } + + @AfterAll + void cleanup() { + log.info("{}: Completed running tests", this.getClass().getSimpleName()); + } + + @BeforeEach + void init() { + tasksRepository.deleteAll(); + resultsByTaskRepository.deleteAll(); + } + + @AfterEach + void reset() { + tasksRepository.deleteAll(); + resultsByTaskRepository.deleteAll(); + testTaskService.clearAll(); + } + + @Test + void testTaskResults() { + var taskId = UUID.randomUUID(); + var task = TestUtil.createTaskEntity(taskId, TEST_NCA_ID, "task-1", jsonMapper); + + // Create Task. + tasksRepository.save(task); + + // Create Task Results. + var resultId1 = UUID.randomUUID(); + var result1 = ResultByTaskEntity.builder() + .key(ResultByTaskKey.builder().taskId(taskId).resultId(resultId1).build()) + .ncaId(TEST_NCA_ID) + .name("result-1") + .metadata("{'foo': 'bar'}") + .createdAt(Instant.now()) + .build(); + var resultId2 = UUID.randomUUID(); + var result2 = ResultByTaskEntity.builder() + .key(ResultByTaskKey.builder().taskId(taskId).resultId(resultId2).build()) + .ncaId(TEST_NCA_ID) + .name("result-2") + .metadata("{'foo': 'baz'}") + .createdAt(Instant.now()) + .build(); + resultsByTaskRepository.saveAll(List.of(result1, result2)); + + // Verify Task Results. + assertThat(resultsByTaskRepository.findByKeyTaskId(taskId)).hasSize(2); + + // Delete Task Result. + resultsByTaskRepository.delete(result1); + + // Verify Task Events. + assertThat(resultsByTaskRepository.findByKeyTaskId(taskId)).hasSize(1); + assertThat(resultsByTaskRepository.getByKeyTaskIdAndKeyResultId(taskId, resultId2)) + .isPresent() + .map(entity -> entity.getKey().getResultId()) + .hasValue(resultId2); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/persistence/task/TasksRepositoryTest.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/persistence/task/TasksRepositoryTest.java new file mode 100644 index 000000000..d2db386be --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/persistence/task/TasksRepositoryTest.java @@ -0,0 +1,326 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.persistence.task; + +import static com.nvidia.nvct.util.TestConstants.TEST_NCA_ID; +import static com.nvidia.nvct.util.TestConstants.TEST_NCA_ID_2; +import static org.assertj.core.api.Assertions.assertThat; + +import com.datastax.oss.driver.api.core.CqlSession; +import com.nvidia.nvct.IntegrationTestConfiguration; +import com.nvidia.nvct.NvctTestApp; +import com.nvidia.nvct.grpc.TestTaskService; +import com.nvidia.nvct.persistence.task.entity.HealthUdt; +import com.nvidia.nvct.persistence.task.entity.TaskEntity; +import com.nvidia.nvct.persistence.task.entity.TaskStatus; +import com.nvidia.nvct.rest.task.dto.HealthDto; +import com.nvidia.nvct.service.task.TaskMapperService; +import com.nvidia.nvct.service.task.TaskService; +import com.nvidia.nvct.util.TestUtil; +import java.time.Instant; +import java.util.UUID; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ContextConfiguration; +import tools.jackson.databind.json.JsonMapper; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@Slf4j +@SpringBootTest( + classes = {NvctTestApp.class, IntegrationTestConfiguration.class}, + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + properties = "spring.profiles.active=test") +@ContextConfiguration(initializers = IntegrationTestConfiguration.Initializer.class) +class TasksRepositoryTest { + @Autowired + private TestTaskService testTaskService; + + @Autowired + private TasksRepository tasksRepository; + + @Autowired + private TaskMapperService taskMapperService; + + @Autowired + private TaskService taskService; + + @Autowired + private CqlSession cqlSession; + + @Autowired + private JsonMapper jsonMapper; + + @BeforeAll + void beforeAll() { + log.info("{}: Started running tests", this.getClass().getSimpleName()); + } + + @AfterAll + void cleanup() { + log.info("{}: Completed running tests", this.getClass().getSimpleName()); + } + + @BeforeEach + void init() { + tasksRepository.deleteAll(); + } + + @AfterEach + void reset() { + tasksRepository.deleteAll(); + testTaskService.clearAll(); + } + + @Test + void createAndDeleteTask() { + var taskId = UUID.randomUUID(); + var task = TestUtil.createTaskEntity(taskId, TEST_NCA_ID, "task-1", jsonMapper); + + // Save the task. + tasksRepository.save(task); + + // Make sure that the entry was created in all the tables. + assertThat(tasksRepository.getByTaskId(taskId)) + .isPresent() + .map(entity -> entity.getTaskId()) + .hasValue(taskId); + assertThat(tasksRepository.getByTaskId(taskId)) + .isPresent() + .map(entity -> entity.getTaskId()) + .hasValue(taskId); + + assertThat(tasksRepository.findAll()).hasSize(1); + assertThat(tasksRepository.countByNcaId(TEST_NCA_ID)).isEqualTo(1); + assertThat(tasksRepository.getByTaskId(taskId)) + .isPresent() + .map(entity -> entity.getTaskId()) + .hasValue(taskId); + var entity = tasksRepository.getByTaskId(taskId).get(); + assertThat(entity.getMaxRuntimeDuration()).isNotNull(); + + // Delete the task using. + tasksRepository.delete(task); + + // Make sure that the entry was deleted from the table. + assertThat(tasksRepository.getByTaskId(taskId)).isNotPresent(); + } + + @SneakyThrows + @Test + void countTasksByNcaId() { + var taskId1 = UUID.randomUUID(); + var task1 = TestUtil.createTaskEntity(taskId1, TEST_NCA_ID, "task-1", jsonMapper); + + var taskId2 = UUID.randomUUID(); + var task2 = TestUtil.createTaskEntity(taskId2, TEST_NCA_ID, "task-2", jsonMapper); + + var taskId3 = UUID.randomUUID(); + var task3 = TestUtil.createTaskEntity(taskId3, TEST_NCA_ID_2, "task-3", jsonMapper); + + // Save the tasks. + tasksRepository.save(task1); + tasksRepository.save(task2); + tasksRepository.save(task3); + + // Confirm that there are three Tasks in the repository. + assertThat(tasksRepository.count()).isEqualTo(3); + + // Confirm there are 2 Tasks belonging to TEST_NCA_ID account. + assertThat(tasksRepository.countByNcaId(TEST_NCA_ID)).isEqualTo(2); + } + + @Test + void updateTask() throws InterruptedException { + var taskId = UUID.randomUUID(); + var task = TestUtil.createTaskEntity(taskId, TEST_NCA_ID, "task-1", jsonMapper); + + // Save the task. + tasksRepository.save(task); + + assertThat(tasksRepository.findAll()).hasSize(1); + + // Check the initial status. + assertThat(tasksRepository.getByTaskId(taskId)) + .isPresent() + .map(TaskEntity::getStatus) + .hasValue(TaskStatus.QUEUED); + + // Change the status to LAUNCHED. + task.setStatus(TaskStatus.LAUNCHED); + + // Update the task. + var timestamp = Instant.now(); // Save the timestamp before updating the task. + Thread.sleep(1000); // Sleep for a second before updating the task. + tasksRepository.insert(task); + + // Verify new status. + assertThat(tasksRepository.getByTaskId(taskId)) + .isPresent() + .map(TaskEntity::getStatus) + .hasValue(TaskStatus.LAUNCHED); + + // Verify last_updated_at is after the saved timestamp. + assertThat(tasksRepository.getByTaskId(taskId)) + .isPresent() + .map(TaskEntity::getLastUpdatedAt) + .hasValueSatisfying(updatedAt -> { + assertThat(updatedAt).isAfter(timestamp); + }); + + assertThat(tasksRepository.findAll()).hasSize(1); + } + + @Test + void writesHealthDetailsAsJsonToHealthColumnOnly() { + var taskId = UUID.randomUUID(); + var task = TestUtil.createTaskEntity(taskId, TEST_NCA_ID, "task-1", jsonMapper); + var healthInfo = taskMapperService.deserializeHealth(task.getHealth()).orElseThrow(); + + tasksRepository.save(task); + + var row = cqlSession.execute( + "SELECT health, health_info FROM tasks_v2 WHERE task_id = ?", taskId).one(); + assertThat(row).isNotNull(); + assertThat(row.getString(TaskEntity.COLUMN_HEALTH)) + .doesNotContain("sis_request_id") + .contains("\"gpu\":\"" + healthInfo.gpu() + "\"") + .contains("\"backend\":\"" + healthInfo.backend() + "\"") + .contains("\"instanceType\":\"" + healthInfo.instanceType() + "\"") + .contains("\"error\":\"" + healthInfo.error() + "\""); + assertThat(row.isNull(TaskEntity.COLUMN_HEALTH_INFO)).isTrue(); + + var updatedHealthInfo = HealthDto.builder() + .backend("GFN") + .gpu("T10") + .instanceType("g6.full") + .error("updated-error") + .build(); + + taskService.updateTask(taskId, TaskStatus.ERRORED, updatedHealthInfo); + + row = cqlSession.execute( + "SELECT health, health_info FROM tasks_v2 WHERE task_id = ?", taskId).one(); + assertThat(row).isNotNull(); + assertThat(row.getString(TaskEntity.COLUMN_HEALTH)).contains("updated-error"); + assertThat(row.isNull(TaskEntity.COLUMN_HEALTH_INFO)).isTrue(); + + var reloadedTask = tasksRepository.getByTaskId(taskId).orElseThrow(); + assertThat(taskMapperService.toTaskDto(reloadedTask).healthInfo()).isEqualTo(updatedHealthInfo); + } + + @Test + void readFromLegacyHealthInfoColumnWhenHealthColumnIsBlank() { + var taskId = UUID.randomUUID(); + var task = TestUtil.createTaskEntity(taskId, TEST_NCA_ID, "task-1", jsonMapper); + task.setHealth(null); + tasksRepository.save(task); + + var legacyHealthInfo = HealthUdt.builder() + .legacyIcmsRequestId(UUID.randomUUID()) + .backend("legacy-backend") + .gpu("legacy-gpu") + .instanceType("legacy-instance") + .error("legacy-error") + .build(); + updateLegacyHealthInfo(taskId, legacyHealthInfo); + + var reloadedTask = tasksRepository.getByTaskId(taskId); + + assertThat(reloadedTask).isPresent(); + assertThat(reloadedTask.get().getHealth()).isNull(); + assertThat(reloadedTask.get().getLegacyHealthInfo()).isEqualTo(legacyHealthInfo); + assertThat(taskMapperService.toTaskDto(reloadedTask.get()).healthInfo()) + .isEqualTo(HealthDto.builder() + .backend(legacyHealthInfo.getBackend()) + .gpu(legacyHealthInfo.getGpu()) + .instanceType(legacyHealthInfo.getInstanceType()) + .error(legacyHealthInfo.getError()) + .build()); + } + + @Test + @SneakyThrows + void readFirstFromHealthColumnBeforeReadingFromLegacyHealthInfoColumn() { + var taskId = UUID.randomUUID(); + var task = TestUtil.createTaskEntity(taskId, TEST_NCA_ID, "task-1", jsonMapper); + task.setHealth(null); + tasksRepository.save(task); + + var legacyHealthInfo = HealthUdt.builder() + .legacyIcmsRequestId(UUID.randomUUID()) + .backend("legacy-backend") + .gpu("legacy-gpu") + .instanceType("legacy-instance") + .error("legacy-error") + .build(); + var healthInfo = HealthDto.builder() + .backend("new-backend") + .gpu("new-gpu") + .instanceType("new-instance") + .error("new-error") + .build(); + cqlSession.execute( + "UPDATE tasks_v2 SET health = ? WHERE task_id = ?", + """ + { + "sis_request_id": "e807603b-5224-4d7e-af7f-740c22c006e0", + "gpu": "%s", + "backend": "%s", + "instanceType": "%s", + "error": "%s" + } + """.formatted(healthInfo.gpu(), + healthInfo.backend(), + healthInfo.instanceType(), + healthInfo.error()), + taskId); + updateLegacyHealthInfo(taskId, legacyHealthInfo); + + var reloadedTask = tasksRepository.getByTaskId(taskId); + + assertThat(reloadedTask).isPresent(); + assertThat(reloadedTask.get().getHealth()).isNotBlank(); + assertThat(taskMapperService.toTaskDto(reloadedTask.get()).healthInfo()).isEqualTo(healthInfo); + } + + private void updateLegacyHealthInfo(UUID taskId, HealthUdt healthInfo) { + cqlSession.execute(""" + UPDATE tasks_v2 + SET health_info = { + sis_request_id: %s, + gpu: '%s', + backend: '%s', + instance_type: '%s', + error: '%s' + } + WHERE task_id = %s + """.formatted(healthInfo.getLegacyIcmsRequestId(), + healthInfo.getGpu(), + healthInfo.getBackend(), + healthInfo.getInstanceType(), + healthInfo.getError(), + taskId)); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/event/EventControllerTest.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/event/EventControllerTest.java new file mode 100644 index 000000000..824ed53a8 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/event/EventControllerTest.java @@ -0,0 +1,444 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.rest.event; + +import static com.nvidia.nvct.IntegrationTestConfiguration.MOCK_OAUTH2_TOKEN_SERVER; +import static com.nvidia.nvct.persistence.task.entity.TaskStatus.LAUNCHED; +import static com.nvidia.nvct.persistence.task.entity.TaskStatus.QUEUED; +import static com.nvidia.nvct.persistence.task.entity.TaskStatus.RUNNING; +import static com.nvidia.nvct.service.event.EventService.STATUS_CHANGE_EVENT_MESSAGE; +import static com.nvidia.nvct.util.NvctConstants.SCOPE_LIST_EVENTS; +import static com.nvidia.nvct.util.NvctConstants.SCOPE_LIST_RESULTS; +import static com.nvidia.nvct.util.NvctConstants.SCOPE_LIST_TASKS; +import static com.nvidia.nvct.util.TestConstants.EVENT_ID_1; +import static com.nvidia.nvct.util.TestConstants.EVENT_ID_2; +import static com.nvidia.nvct.util.TestConstants.EVENT_ID_3; +import static com.nvidia.nvct.util.TestConstants.EVENT_ID_4; +import static com.nvidia.nvct.util.TestConstants.TEST_CLIENT_SUBJECT; +import static com.nvidia.nvct.util.TestConstants.TEST_CLIENT_SUBJECT_2; +import static com.nvidia.nvct.util.TestConstants.TEST_NCA_ID; +import static com.nvidia.nvct.util.TestConstants.TEST_OWNER_ID; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_ID_1; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_ID_2; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_ID_3; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_NAME_1; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_NAME_2; +import static org.apache.commons.lang3.StringUtils.EMPTY; +import static org.assertj.core.api.Assertions.assertThat; + +import tools.jackson.databind.json.JsonMapper; +import com.nvidia.nvct.IntegrationTestConfiguration; +import com.nvidia.nvct.NvctTestApp; +import com.nvidia.nvct.grpc.TestTaskService; +import com.nvidia.nvct.persistence.event.EventsByTaskRepository; +import com.nvidia.nvct.persistence.task.TasksRepository; +import com.nvidia.nvct.rest.event.dto.EventDto; +import com.nvidia.nvct.rest.event.dto.ListEventsResponse; +import com.nvidia.nvct.service.account.AccountService; +import com.nvidia.nvct.service.apikeys.ApiKeyValidationResult.Resource; +import com.nvidia.nvct.service.apikeys.ApiKeysService; +import com.nvidia.nvct.util.MockApiKeysServer; +import com.nvidia.nvct.util.MockNvcfServer; +import com.nvidia.nvct.util.TestUtil; +import java.net.URI; +import java.net.URL; +import java.util.List; +import java.util.Set; +import java.util.UUID; +import java.util.function.Supplier; +import java.util.stream.Stream; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.resttestclient.TestRestTemplate; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; +import org.springframework.http.HttpStatus; +import org.springframework.http.RequestEntity; +import org.springframework.test.context.ContextConfiguration; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@Slf4j +@SpringBootTest( + classes = {NvctTestApp.class, IntegrationTestConfiguration.class}, + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + properties = "spring.profiles.active=test") +@ContextConfiguration(initializers = IntegrationTestConfiguration.Initializer.class) +@AutoConfigureTestRestTemplate +class EventControllerTest { + + @Autowired + private TestRestTemplate testRestTemplate; + + @Autowired + private TestTaskService testTaskService; + + @Autowired + private TestEventService testEventService; + + @Autowired + private AccountService accountService; + + @Autowired + private ApiKeysService apiKeysService; + + @Autowired + private TasksRepository tasksRepository; + + @Autowired + private EventsByTaskRepository eventsByTaskRepository; + + @Autowired + private JsonMapper jsonMapper; + + @Value("${nvct.api-keys.base-url}") + private String apiKeysBaseUrl; + + @Value("${nvct.nvcf.base-url}") + private URL nvcfBaseUrl; + + @BeforeAll + void beforeAll() { + log.info("{}: Started running tests", this.getClass().getSimpleName()); + MockApiKeysServer.start(apiKeysBaseUrl); + MockNvcfServer.start(nvcfBaseUrl); + tasksRepository.deleteAll(); + eventsByTaskRepository.deleteAll(); + } + + @AfterAll + void cleanup() { + MockApiKeysServer.stop(); + MockNvcfServer.stop(); + log.info("{}: Completed running tests", this.getClass().getSimpleName()); + } + + @BeforeEach + void beforeEach() { + // Create Tasks in TEST_NCA_ID account tied to TEST_CLIENT_ID. + var task1 = TestUtil.createTaskEntity(TEST_TASK_ID_1, TEST_NCA_ID, TEST_TASK_NAME_1, + jsonMapper); + var task2 = TestUtil.createTaskEntity(TEST_TASK_ID_2, TEST_NCA_ID, TEST_TASK_NAME_2, + jsonMapper); + + // Save tasks. + tasksRepository.save(task1); + tasksRepository.save(task2); + + // Events for TEST_TASK_ID_1. + testEventService.populateEventForTask(EVENT_ID_1, TEST_NCA_ID, TEST_TASK_ID_1, + STATUS_CHANGE_EVENT_MESSAGE.formatted(EMPTY, QUEUED)); + testEventService.populateEventForTask(EVENT_ID_2, TEST_NCA_ID, TEST_TASK_ID_1, + STATUS_CHANGE_EVENT_MESSAGE.formatted(QUEUED, LAUNCHED)); + testEventService.populateEventForTask(EVENT_ID_3, TEST_NCA_ID, TEST_TASK_ID_1, + STATUS_CHANGE_EVENT_MESSAGE.formatted(LAUNCHED, RUNNING)); + + // Event for TEST_TASK_ID_2 to make sure there is no cross contamination query + testEventService.populateEventForTask(EVENT_ID_4, TEST_NCA_ID, TEST_TASK_ID_2, + STATUS_CHANGE_EVENT_MESSAGE.formatted(EMPTY, RUNNING)); + } + + @AfterEach + void reset() { + MockApiKeysServer.resetToDefault(); + // use of MockApiKeysServer with different scopes causes the api-keys cache to dirty + apiKeysService.invalidateCache(); + accountService.invalidateCache(); + tasksRepository.deleteAll(); + eventsByTaskRepository.deleteAll(); + testTaskService.clearAll(); + } + + Stream taskEventsArgs() { + var jwtCases = Stream.of( + // TEST_TASK_ID_1 belongs to TEST_NCA_ID. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LIST_EVENTS, + SCOPE_LIST_TASKS, + SCOPE_LIST_RESULTS), + 100), + TEST_NCA_ID, + TEST_TASK_ID_1, + Set.of(EVENT_ID_1, EVENT_ID_2, EVENT_ID_3), + HttpStatus.OK), + // TEST_TASK_ID_2 belongs to TEST_NCA_ID. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LIST_EVENTS, + SCOPE_LIST_TASKS, + SCOPE_LIST_RESULTS), + 100), + TEST_NCA_ID, + TEST_TASK_ID_2, + Set.of(EVENT_ID_4), + HttpStatus.OK), + // Task in different account. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT_2, + List.of(SCOPE_LIST_EVENTS, + SCOPE_LIST_TASKS, + SCOPE_LIST_RESULTS), + 100), + TEST_NCA_ID, + TEST_TASK_ID_1, + Set.of(), + HttpStatus.NOT_FOUND), + // Non-existent client. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt("non-existent-client", + List.of(SCOPE_LIST_EVENTS, + SCOPE_LIST_TASKS, + SCOPE_LIST_RESULTS), + 100), + TEST_NCA_ID, + TEST_TASK_ID_1, + Set.of(), + HttpStatus.NOT_FOUND), + // Non-existent task. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LIST_EVENTS, + SCOPE_LIST_TASKS, + SCOPE_LIST_RESULTS), + 100), + TEST_NCA_ID, + TEST_TASK_ID_3, + Set.of(), + HttpStatus.NOT_FOUND), + // Missing scopes. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(), + 100), + TEST_NCA_ID, + TEST_TASK_ID_1, + Set.of(), + HttpStatus.FORBIDDEN), + // No token. + Arguments.of(null, + TEST_NCA_ID, + TEST_TASK_ID_1, + Set.of(), + HttpStatus.UNAUTHORIZED) + ); + + var apiKeysCases = Stream.of( + // api-key with list_events scope and account-tasks resource + Arguments.of((Supplier) () -> { + MockApiKeysServer.setResponse(TEST_NCA_ID, TEST_OWNER_ID, + List.of(new Resource("account-tasks", "*")), + List.of("list_events")); + return "nvapi-stg-some-key"; + }, + TEST_NCA_ID, + TEST_TASK_ID_1, + Set.of(EVENT_ID_1, EVENT_ID_2, EVENT_ID_3), + HttpStatus.OK), + // api-key with list_events scope and specific task resource (matching) + Arguments.of((Supplier) () -> { + MockApiKeysServer.setResponse(TEST_NCA_ID, TEST_OWNER_ID, + List.of(new Resource("task", TEST_TASK_ID_1.toString())), + List.of("list_events")); + return "nvapi-stg-some-key"; + }, + TEST_NCA_ID, + TEST_TASK_ID_1, + Set.of(EVENT_ID_1, EVENT_ID_2, EVENT_ID_3), + HttpStatus.OK), + // api-key with list_events scope and specific task resource (not matching) + Arguments.of((Supplier) () -> { + MockApiKeysServer.setResponse(TEST_NCA_ID, TEST_OWNER_ID, + List.of(new Resource("task", TEST_TASK_ID_2.toString())), + List.of("list_events")); + return "nvapi-stg-some-key"; + }, + TEST_NCA_ID, + TEST_TASK_ID_1, + Set.of(), + HttpStatus.FORBIDDEN), + // api-key with scope but no resources + Arguments.of((Supplier) () -> { + MockApiKeysServer.setResponse(TEST_NCA_ID, TEST_OWNER_ID, + List.of(), + List.of("list_events")); + return "nvapi-stg-some-key"; + }, + TEST_NCA_ID, + TEST_TASK_ID_1, + Set.of(), + HttpStatus.FORBIDDEN), + // api-key with missing scope + Arguments.of((Supplier) () -> { + MockApiKeysServer.setResponse(TEST_NCA_ID, TEST_OWNER_ID, + List.of(), List.of()); + return "nvapi-stg-some-key"; + }, + TEST_NCA_ID, + TEST_TASK_ID_1, + Set.of(), + HttpStatus.FORBIDDEN) + ); + + return Stream.concat(jwtCases, apiKeysCases); + } + + @ParameterizedTest + @MethodSource("taskEventsArgs") + void shouldListEvents(Object tokenSupplier, + String ncaId, + UUID taskId, + Set eventIds, + HttpStatus expectedStatus) { + var token = TestUtil.getToken(tokenSupplier); + var requestEntity = + RequestEntity.get(URI.create("/v1/nvct/tasks/" + taskId + "/events")) + .header("Authorization", "Bearer " + token) + .build(); + var responseEntity = testRestTemplate.exchange(requestEntity, ListEventsResponse.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(expectedStatus); + if (expectedStatus.isError()) { + return; + } + + var responseBody = responseEntity.getBody(); + assertThat(responseBody).isNotNull(); + assertThat(responseBody.events()).hasSize(eventIds.size()); + assertThat(responseBody.cursor()).isNull(); + assertThat(responseBody.limit()).isNull(); + verifyReturnedEventsIntegrity(eventIds, responseBody.events(), ncaId, taskId); + } + + void verifyReturnedEventsIntegrity( + Set expectedEvents, List events, String ncaId, UUID taskId) { + for (var eventDto : events) { + assertThat(eventDto.createdAt()).isNotNull(); + assertThat(eventDto.ncaId()).isEqualTo(ncaId); + assertThat(eventDto.eventId()).isIn(expectedEvents); + assertThat(eventDto.taskId()).isEqualTo(taskId); + assertThat(eventDto.message()).isNotBlank(); + } + } + + Stream listEventsWithPaginationLimitArgs() { + return Stream.of( + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LIST_EVENTS, + SCOPE_LIST_TASKS, + SCOPE_LIST_RESULTS), + 100), + TEST_NCA_ID, + TEST_TASK_ID_1, + 1, + Set.of(EVENT_ID_1, EVENT_ID_2, EVENT_ID_3)), + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LIST_EVENTS, + SCOPE_LIST_TASKS, + SCOPE_LIST_RESULTS), + 100), + TEST_NCA_ID, + TEST_TASK_ID_1, + 100, + Set.of(EVENT_ID_1, EVENT_ID_2, EVENT_ID_3)) + + ); + } + + @ParameterizedTest + @MethodSource("listEventsWithPaginationLimitArgs") + void shouldListEventsWithPaginationLimit(String token, + String ncaId, + UUID taskId, + int limit, + Set expectedEventIds) { + var requestEntity = + RequestEntity.get(URI.create("/v1/nvct/tasks/" + taskId + "/events?limit=" + limit)) + .header("Authorization", "Bearer " + token) + .build(); + var responseEntity = testRestTemplate.exchange(requestEntity, ListEventsResponse.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK); + + var responseBody = responseEntity.getBody(); + assertThat(responseBody).isNotNull(); + if (limit < 3) { + assertThat(responseBody.events()).hasSize(limit); + assertThat(responseBody.cursor()).isNotNull(); + assertThat(responseBody.limit()).isEqualTo(limit); + } else { + assertThat(responseBody.events()).hasSize(3); + assertThat(responseBody.cursor()).isNull(); + assertThat(responseBody.limit()).isNull(); + } + + verifyReturnedEventsIntegrity(expectedEventIds, responseBody.events(), ncaId, taskId); + } + + @Test + void shouldListEventsWithPaginationCursor() { + var token = MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LIST_EVENTS, + SCOPE_LIST_TASKS, + SCOPE_LIST_RESULTS), + 100); + var expectedResults = Set.of(EVENT_ID_1, EVENT_ID_2, EVENT_ID_3); + + // get the first 2 out of 3 events first + var url = "/v1/nvct/tasks/" + TEST_TASK_ID_1 + "/events?limit=2"; + var requestEntity = + RequestEntity.get(URI.create(url)) + .header("Authorization", "Bearer " + token) + .build(); + var responseEntity = + testRestTemplate.exchange(requestEntity, ListEventsResponse.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK); + var responseBody = responseEntity.getBody(); + assertThat(responseBody).isNotNull(); + var currentCursor = responseBody.cursor(); + assertThat(currentCursor).isNotNull(); + var firstPageEvent = responseBody.events(); + assertThat(firstPageEvent).hasSize(2); + assertThat(responseBody.limit()).isEqualTo(2); + + // using the cursor from previous response, continue to listing the rest of the results + url = "/v1/nvct/tasks/" + TEST_TASK_ID_1 + "/events?limit=2&cursor=" + currentCursor; + requestEntity = + RequestEntity.get(URI.create(url)) + .header("Authorization", "Bearer " + token) + .build(); + responseEntity = + testRestTemplate.exchange(requestEntity, ListEventsResponse.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK); + + // make sure the last event is correct + responseBody = responseEntity.getBody(); + assertThat(responseBody).isNotNull(); + currentCursor = responseBody.cursor(); + assertThat(currentCursor).isNull(); + assertThat(responseBody.limit()).isNull(); + var secondPageEvent = responseBody.events(); + assertThat(secondPageEvent).hasSize(1); + + // make sure all 3 results have the right metadata + verifyReturnedEventsIntegrity(expectedResults, + Stream.concat(firstPageEvent.stream(), secondPageEvent.stream()).toList(), + TEST_NCA_ID, + TEST_TASK_ID_1); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/event/TestEventService.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/event/TestEventService.java new file mode 100644 index 000000000..538f0c7bf --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/event/TestEventService.java @@ -0,0 +1,48 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.rest.event; + +import com.nvidia.nvct.persistence.event.EventsByTaskRepository; +import com.nvidia.nvct.persistence.event.entity.EventByTaskEntity; +import com.nvidia.nvct.persistence.event.entity.EventByTaskKey; +import java.time.Instant; +import java.util.UUID; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +@Slf4j +@Service +@RequiredArgsConstructor +public class TestEventService { + + private final EventsByTaskRepository eventsByTaskRepository; + + public void populateEventForTask(UUID eventId, + String ncaId, + UUID taskId, + String message) { + var event = EventByTaskEntity.builder() + .key(EventByTaskKey.builder().taskId(taskId).eventId(eventId).build()) + .ncaId(ncaId) + .message(message) + .createdAt(Instant.now()) + .build(); + eventsByTaskRepository.save(event); + } + +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/event/XAccountEventControllerTest.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/event/XAccountEventControllerTest.java new file mode 100644 index 000000000..a2b98d3c0 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/event/XAccountEventControllerTest.java @@ -0,0 +1,394 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.rest.event; + +import static com.nvidia.nvct.IntegrationTestConfiguration.MOCK_OAUTH2_TOKEN_SERVER; +import static com.nvidia.nvct.util.NvctConstants.ADMIN_SCOPE_LIST_EVENTS; +import static com.nvidia.nvct.util.NvctConstants.ADMIN_SCOPE_LIST_RESULTS; +import static com.nvidia.nvct.util.NvctConstants.ADMIN_SCOPE_LIST_TASKS; +import static com.nvidia.nvct.util.TestConstants.EVENT_ID_1; +import static com.nvidia.nvct.util.TestConstants.EVENT_ID_2; +import static com.nvidia.nvct.util.TestConstants.EVENT_ID_3; +import static com.nvidia.nvct.util.TestConstants.TEST_ADMIN_SUBJECT; +import static com.nvidia.nvct.util.TestConstants.TEST_NCA_ID; +import static com.nvidia.nvct.util.TestConstants.TEST_NCA_ID_2; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_ID_1; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_ID_2; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_ID_3; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_NAME_1; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_NAME_2; +import static org.assertj.core.api.Assertions.assertThat; + +import tools.jackson.databind.json.JsonMapper; +import com.nvidia.nvct.IntegrationTestConfiguration; +import com.nvidia.nvct.NvctTestApp; +import com.nvidia.nvct.grpc.TestTaskService; +import com.nvidia.nvct.persistence.event.EventsByTaskRepository; +import com.nvidia.nvct.persistence.task.TasksRepository; +import com.nvidia.nvct.rest.event.dto.EventDto; +import com.nvidia.nvct.rest.event.dto.ListEventsResponse; +import com.nvidia.nvct.service.account.AccountService; +import com.nvidia.nvct.service.apikeys.ApiKeysService; +import com.nvidia.nvct.util.MockApiKeysServer; +import com.nvidia.nvct.util.MockNvcfServer; +import com.nvidia.nvct.util.TestUtil; +import java.net.URI; +import java.net.URL; +import java.util.List; +import java.util.Set; +import java.util.UUID; +import java.util.stream.Stream; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.resttestclient.TestRestTemplate; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; +import org.springframework.http.HttpStatus; +import org.springframework.http.RequestEntity; +import org.springframework.test.context.ContextConfiguration; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@Slf4j +@SpringBootTest( + classes = {NvctTestApp.class, IntegrationTestConfiguration.class}, + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + properties = "spring.profiles.active=test") +@ContextConfiguration(initializers = IntegrationTestConfiguration.Initializer.class) +@AutoConfigureTestRestTemplate +class XAccountEventControllerTest { + + @Autowired + private TestRestTemplate testRestTemplate; + + @Autowired + private TestTaskService testTaskService; + + @Autowired + private TestEventService testEventService; + + @Autowired + private AccountService accountService; + + @Autowired + private ApiKeysService apiKeysService; + + @Autowired + private TasksRepository tasksRepository; + + @Autowired + private EventsByTaskRepository eventsByTaskRepository; + + @Autowired + private JsonMapper jsonMapper; + + @Value("${nvct.api-keys.base-url}") + private String apiKeysBaseUrl; + + @Value("${nvct.nvcf.base-url}") + private URL nvcfBaseUrl; + + @BeforeAll + void beforeAll() { + log.info("{}: Started running tests", this.getClass().getSimpleName()); + MockApiKeysServer.start(apiKeysBaseUrl); + MockNvcfServer.start(nvcfBaseUrl); + tasksRepository.deleteAll(); + eventsByTaskRepository.deleteAll(); + } + + @AfterAll + void cleanup() { + MockApiKeysServer.stop(); + MockNvcfServer.stop(); + log.info("{}: Completed running tests", this.getClass().getSimpleName()); + } + + @BeforeEach + void beforeEach() { + // Create Tasks in TEST_NCA_ID account tied to TEST_CLIENT_ID. + var task1 = TestUtil.createTaskEntity(TEST_TASK_ID_1, TEST_NCA_ID, TEST_TASK_NAME_1, + jsonMapper); + var task2 = TestUtil.createTaskEntity(TEST_TASK_ID_2, TEST_NCA_ID, TEST_TASK_NAME_2, + jsonMapper); + + // Save tasks. + tasksRepository.save(task1); + tasksRepository.save(task2); + + // Events for TEST_TASK_ID_1. + testEventService.populateEventForTask(EVENT_ID_1, TEST_NCA_ID, TEST_TASK_ID_1, + "Status: QUEUED"); + testEventService.populateEventForTask(EVENT_ID_2, TEST_NCA_ID, TEST_TASK_ID_1, + "Status: LAUNCHED"); + testEventService.populateEventForTask(EVENT_ID_3, TEST_NCA_ID, TEST_TASK_ID_1, + "Status: RUNNING"); + + // Event for TEST_TASK_ID_2 to make sure there is no cross contamination query + testEventService.populateEventForTask(EVENT_ID_1, TEST_NCA_ID, TEST_TASK_ID_2, + "Status: RUNNING"); + } + + @AfterEach + void reset() { + MockApiKeysServer.resetToDefault(); + // use of MockApiKeysServer with different scopes causes the api-keys cache to dirty + apiKeysService.invalidateCache(); + accountService.invalidateCache(); + tasksRepository.deleteAll(); + eventsByTaskRepository.deleteAll(); + testTaskService.clearAll(); + } + + Stream taskEventsArgs() { + return Stream.of( + // TEST_TASK_ID_1 belongs to TEST_NCA_ID. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LIST_EVENTS, + ADMIN_SCOPE_LIST_TASKS, + ADMIN_SCOPE_LIST_RESULTS), + 100), + TEST_NCA_ID, + TEST_TASK_ID_1, + Set.of(EVENT_ID_1, EVENT_ID_2, EVENT_ID_3), + HttpStatus.OK), + // TEST_TASK_ID_1 belongs to TEST_NCA_ID. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt("another-admin", + List.of(ADMIN_SCOPE_LIST_EVENTS, + ADMIN_SCOPE_LIST_TASKS, + ADMIN_SCOPE_LIST_RESULTS), + 100), + TEST_NCA_ID, + TEST_TASK_ID_1, + Set.of(EVENT_ID_1, EVENT_ID_2, EVENT_ID_3), + HttpStatus.OK), + // TEST_TASK_ID_2 belongs to TEST_NCA_ID. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LIST_EVENTS, + ADMIN_SCOPE_LIST_TASKS, + ADMIN_SCOPE_LIST_RESULTS), + 100), + TEST_NCA_ID, + TEST_TASK_ID_2, + Set.of(EVENT_ID_1), + HttpStatus.OK), + // Non-existent account. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LIST_EVENTS, + ADMIN_SCOPE_LIST_TASKS, + ADMIN_SCOPE_LIST_RESULTS), + 100), + "non-existent-account", + TEST_TASK_ID_1, + Set.of(), + HttpStatus.NOT_FOUND), + // Task in different account. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LIST_EVENTS, + ADMIN_SCOPE_LIST_TASKS, + ADMIN_SCOPE_LIST_RESULTS), + 100), + TEST_NCA_ID_2, + TEST_TASK_ID_2, + Set.of(), + HttpStatus.NOT_FOUND), + // Non-existent task. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LIST_EVENTS, + ADMIN_SCOPE_LIST_TASKS, + ADMIN_SCOPE_LIST_RESULTS), + 100), + TEST_NCA_ID, + TEST_TASK_ID_3, + Set.of(), + HttpStatus.NOT_FOUND), + // Missing scopes. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(), + 100), + TEST_NCA_ID, + TEST_TASK_ID_1, + Set.of(), + HttpStatus.FORBIDDEN), + // No token. + Arguments.of(null, + TEST_NCA_ID, + TEST_TASK_ID_1, + Set.of(), + HttpStatus.UNAUTHORIZED) + ); + } + + @ParameterizedTest + @MethodSource("taskEventsArgs") + void shouldListEvents(Object tokenSupplier, + String ncaId, + UUID taskId, + Set eventIds, + HttpStatus expectedStatus) { + var token = TestUtil.getToken(tokenSupplier); + var uri = URI.create("/v1/nvct/accounts/" + ncaId + "/tasks/" + taskId + "/events"); + var requestEntity = + RequestEntity.get(uri) + .header("Authorization", "Bearer " + token) + .build(); + var responseEntity = testRestTemplate.exchange(requestEntity, ListEventsResponse.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(expectedStatus); + if (expectedStatus.isError()) { + return; + } + + var responseBody = responseEntity.getBody(); + assertThat(responseBody).isNotNull(); + assertThat(responseBody.events()).hasSize(eventIds.size()); + assertThat(responseBody.cursor()).isNull(); + assertThat(responseBody.limit()).isNull(); + for (EventDto eventDto : responseBody.events()) { + assertThat(eventDto.createdAt()).isNotNull(); + assertThat(eventDto.ncaId()).isEqualTo(ncaId); + assertThat(eventDto.eventId()).isIn(eventIds); + assertThat(eventDto.taskId()).isEqualTo(taskId); + assertThat(eventDto.message()).isNotBlank(); + } + } + + void verifyReturnedEventsIntegrity( + Set expectedEvents, List events, String ncaId, UUID taskId) { + for (var eventDto : events) { + assertThat(eventDto.createdAt()).isNotNull(); + assertThat(eventDto.ncaId()).isEqualTo(ncaId); + assertThat(eventDto.eventId()).isIn(expectedEvents); + assertThat(eventDto.taskId()).isEqualTo(taskId); + assertThat(eventDto.message()).isNotBlank(); + } + } + + Stream listEventsWithPaginationLimitArgs() { + return Stream.of( + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LIST_EVENTS, + ADMIN_SCOPE_LIST_TASKS, + ADMIN_SCOPE_LIST_RESULTS), + 100), + TEST_NCA_ID, + TEST_TASK_ID_1, + 1, + Set.of(EVENT_ID_1, EVENT_ID_2, EVENT_ID_3)), + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LIST_EVENTS, + ADMIN_SCOPE_LIST_TASKS, + ADMIN_SCOPE_LIST_RESULTS), + 100), + TEST_NCA_ID, + TEST_TASK_ID_1, + 100, + Set.of(EVENT_ID_1, EVENT_ID_2, EVENT_ID_3)) + + ); + } + + @ParameterizedTest + @MethodSource("listEventsWithPaginationLimitArgs") + void shouldListEventsWithPaginationLimit(String token, + String ncaId, + UUID taskId, + int limit, + Set expectedEventIds) { + var requestEntity = RequestEntity + .get(URI.create("/v1/nvct/accounts/" + ncaId + + "/tasks/" + taskId + "/events?limit=" + limit)) + .header("Authorization", "Bearer " + token) + .build(); + var responseEntity = testRestTemplate.exchange(requestEntity, ListEventsResponse.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK); + + var responseBody = responseEntity.getBody(); + assertThat(responseBody).isNotNull(); + if (limit < 3) { + assertThat(responseBody.events()).hasSize(limit); + assertThat(responseBody.cursor()).isNotNull(); + assertThat(responseBody.limit()).isEqualTo(limit); + } else { + assertThat(responseBody.events()).hasSize(3); + assertThat(responseBody.cursor()).isNull(); + assertThat(responseBody.limit()).isNull(); + } + + verifyReturnedEventsIntegrity(expectedEventIds, responseBody.events(), ncaId, taskId); + } + + @Test + void shouldListEventsWithPaginationCursor() { + var token = MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LIST_EVENTS, + ADMIN_SCOPE_LIST_TASKS, + ADMIN_SCOPE_LIST_RESULTS), + 100); + var expectedResults = Set.of(EVENT_ID_1, EVENT_ID_2, EVENT_ID_3); + // get the first 2 out of 3 events first + var url = "/v1/nvct/accounts/" + TEST_NCA_ID + "/tasks/" + TEST_TASK_ID_1 + "/events?limit=2"; + var requestEntity = RequestEntity + .get(URI.create(url)) + .header("Authorization", "Bearer " + token) + .build(); + var responseEntity = + testRestTemplate.exchange(requestEntity, ListEventsResponse.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK); + var responseBody = responseEntity.getBody(); + assertThat(responseBody).isNotNull(); + var currentCursor = responseBody.cursor(); + assertThat(currentCursor).isNotNull(); + var firstPageEvent = responseBody.events(); + assertThat(firstPageEvent).hasSize(2); + assertThat(responseBody.limit()).isEqualTo(2); + + // using the cursor from previous response, continue to listing the rest of the results + url = "/v1/nvct/accounts/" + TEST_NCA_ID + "/tasks/" + TEST_TASK_ID_1 + + "/events?limit=2&cursor=" + currentCursor; + requestEntity = + RequestEntity.get(URI.create(url)) + .header("Authorization", "Bearer " + token) + .build(); + responseEntity = + testRestTemplate.exchange(requestEntity, ListEventsResponse.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK); + + // make sure the last event is correct + responseBody = responseEntity.getBody(); + assertThat(responseBody).isNotNull(); + currentCursor = responseBody.cursor(); + assertThat(currentCursor).isNull(); + assertThat(responseBody.limit()).isNull(); + var secondPageEvent = responseBody.events(); + assertThat(secondPageEvent).hasSize(1); + + // make sure all 3 results have the right metadata + verifyReturnedEventsIntegrity(expectedResults, + Stream.concat(firstPageEvent.stream(), secondPageEvent.stream()).toList(), + TEST_NCA_ID, + TEST_TASK_ID_1); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/misc/MiscEndpointsTest.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/misc/MiscEndpointsTest.java new file mode 100644 index 000000000..2a51a919e --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/misc/MiscEndpointsTest.java @@ -0,0 +1,115 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.rest.misc; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.springframework.http.HttpHeaders.ACCESS_CONTROL_REQUEST_HEADERS; +import static org.springframework.http.HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD; +import static org.springframework.http.HttpHeaders.ORIGIN; +import static org.springframework.http.HttpMethod.POST; + +import com.nvidia.nvct.IntegrationTestConfiguration; +import com.nvidia.nvct.NvctTestApp; +import java.net.URI; +import java.util.stream.Stream; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.api.TestInstance.Lifecycle; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.resttestclient.TestRestTemplate; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; +import org.springframework.http.HttpStatus; +import org.springframework.http.RequestEntity; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.web.cors.CorsConfiguration; + +@Slf4j +@TestInstance(Lifecycle.PER_CLASS) +@SpringBootTest( + classes = {NvctTestApp.class, IntegrationTestConfiguration.class}, + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + properties = "spring.profiles.active=test") +@ContextConfiguration(initializers = IntegrationTestConfiguration.Initializer.class) +@AutoConfigureTestRestTemplate +class MiscEndpointsTest { + + @Autowired + private TestRestTemplate testRestTemplate; + + @BeforeAll + void beforeAll() { + log.info("{}: Started running tests", this.getClass().getSimpleName()); + } + + @AfterAll + void cleanup() { + log.info("{}: Completed running tests", this.getClass().getSimpleName()); + } + + @SneakyThrows + @Test + void testHealth() { + var requestEntity = RequestEntity.get(URI.create("/health")).build(); + var responseEntity = testRestTemplate.exchange(requestEntity, String.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK); + } + + @Test + void testOpenApiDocs() { + var requestEntity = RequestEntity.get(URI.create("/v3/openapi")).build(); + var responseEntity = testRestTemplate.exchange(requestEntity, String.class); + var responseBody = responseEntity.getBody(); + assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK); + assertThat(responseBody).isNotNull(); + } + + @ParameterizedTest + @MethodSource("getRecognizedOrigins") + void testCorsPreflightRequest(String origin) { + var requestEntity = RequestEntity.options(URI.create("/v1/nvct/tasks")) + .header(ORIGIN, origin) + .header(ACCESS_CONTROL_REQUEST_METHOD, POST.toString()) + .build(); + var responseEntity = testRestTemplate.exchange(requestEntity, Void.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK); + assertThat(responseEntity.getHeaders().getVary()).contains(ORIGIN); + assertThat(responseEntity.getHeaders().getVary()).contains(ACCESS_CONTROL_REQUEST_METHOD); + assertThat(responseEntity.getHeaders().getVary()).contains(ACCESS_CONTROL_REQUEST_HEADERS); + assertThat(responseEntity.getHeaders().getAccessControlAllowOrigin()).contains(origin); + assertThat(responseEntity.getHeaders().getAccessControlAllowCredentials()).isTrue(); + assertThat(responseEntity.getHeaders().getAccessControlAllowMethods()).contains(POST); + assertThat(responseEntity.getHeaders().getAccessControlExposeHeaders()) + .contains(CorsConfiguration.ALL); + assertThat(responseEntity.getHeaders().getAccessControlMaxAge()).isEqualTo(86400); // 1d + } + + private static Stream getRecognizedOrigins() { + return Stream.of("http://localhost:3000", + "https://demo.stg.nvct.nvidia.com", + "https://picasso.nvct.nvidia.com", + "https://picasso.stg.nvct.nvidia.com", + "foo.bar.baz", + "*"); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/result/ResultControllerTest.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/result/ResultControllerTest.java new file mode 100644 index 000000000..a0060aece --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/result/ResultControllerTest.java @@ -0,0 +1,478 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.rest.result; + +import static com.nvidia.nvct.IntegrationTestConfiguration.MOCK_OAUTH2_TOKEN_SERVER; +import static com.nvidia.nvct.util.NvctConstants.SCOPE_LIST_EVENTS; +import static com.nvidia.nvct.util.NvctConstants.SCOPE_LIST_RESULTS; +import static com.nvidia.nvct.util.NvctConstants.SCOPE_LIST_TASKS; +import static com.nvidia.nvct.util.TestConstants.RESULT_ID_1; +import static com.nvidia.nvct.util.TestConstants.RESULT_ID_2; +import static com.nvidia.nvct.util.TestConstants.RESULT_ID_3; +import static com.nvidia.nvct.util.TestConstants.TEST_CLIENT_SUBJECT; +import static com.nvidia.nvct.util.TestConstants.TEST_CLIENT_SUBJECT_2; +import static com.nvidia.nvct.util.TestConstants.TEST_NCA_ID; +import static com.nvidia.nvct.util.TestConstants.TEST_OWNER_ID; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_ID_1; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_ID_2; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_ID_3; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_NAME_1; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_NAME_2; +import static org.assertj.core.api.Assertions.assertThat; + +import tools.jackson.databind.json.JsonMapper; +import tools.jackson.databind.node.ObjectNode; +import com.nvidia.nvct.IntegrationTestConfiguration; +import com.nvidia.nvct.NvctTestApp; +import com.nvidia.nvct.grpc.TestTaskService; +import com.nvidia.nvct.persistence.result.ResultsByTaskRepository; +import com.nvidia.nvct.persistence.task.TasksRepository; +import com.nvidia.nvct.rest.result.dto.ListResultsResponse; +import com.nvidia.nvct.rest.result.dto.ResultDto; +import com.nvidia.nvct.service.account.AccountService; +import com.nvidia.nvct.service.apikeys.ApiKeyValidationResult.Resource; +import com.nvidia.nvct.service.apikeys.ApiKeysService; +import com.nvidia.nvct.util.MockApiKeysServer; +import com.nvidia.nvct.util.MockNvcfServer; +import com.nvidia.nvct.util.TestUtil; +import java.net.URI; +import java.net.URL; +import java.util.List; +import java.util.Set; +import java.util.UUID; +import java.util.function.Supplier; +import java.util.stream.Stream; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.resttestclient.TestRestTemplate; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; +import org.springframework.http.HttpStatus; +import org.springframework.http.RequestEntity; +import org.springframework.test.context.ContextConfiguration; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@Slf4j +@SpringBootTest( + classes = {NvctTestApp.class, IntegrationTestConfiguration.class}, + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + properties = "spring.profiles.active=test") +@ContextConfiguration(initializers = IntegrationTestConfiguration.Initializer.class) +@AutoConfigureTestRestTemplate +class ResultControllerTest { + + @Autowired + private TestRestTemplate testRestTemplate; + + @Autowired + private TestTaskService testTaskService; + + @Autowired + private TestResultService testResultService; + + @Autowired + private AccountService accountService; + + @Autowired + private TasksRepository tasksRepository; + + @Autowired + private ResultsByTaskRepository resultsByTaskRepository; + + @Autowired + private JsonMapper jsonMapper; + + @Autowired + private ApiKeysService apiKeysService; + + @Value("${nvct.nvcf.base-url}") + private URL nvcfBaseUrl; + + @Value("${nvct.api-keys.base-url}") + private String apiKeysBaseUrl; + + @BeforeAll + void beforeAll() { + log.info("{}: Started running tests", this.getClass().getSimpleName()); + MockApiKeysServer.start(apiKeysBaseUrl); + MockNvcfServer.start(nvcfBaseUrl); + tasksRepository.deleteAll(); + resultsByTaskRepository.deleteAll(); + } + + @AfterAll + void cleanup() { + MockNvcfServer.stop(); + MockApiKeysServer.stop(); + log.info("{}: Completed running tests", this.getClass().getSimpleName()); + } + + @SneakyThrows + @BeforeEach + void beforeEach() { + // Create Tasks in TEST_NCA_ID account tied to TEST_CLIENT_ID. + var task1 = TestUtil.createTaskEntity(TEST_TASK_ID_1, TEST_NCA_ID, + TEST_TASK_NAME_1, jsonMapper); + var task2 = TestUtil.createTaskEntity(TEST_TASK_ID_2, TEST_NCA_ID, + TEST_TASK_NAME_2, jsonMapper); + + // Save tasks. + tasksRepository.save(task1); + tasksRepository.save(task2); + + var metadataTemplate = """ + { + "fine_tuned_model_checkpoint": "ckpt-step-%s", + "metrics": { + "full_valid_loss": %s, + "full_valid_mean_token_accuracy": %s + }, + "fine_tuning_job_id": "ftjob-abc123", + "step_number": %s, + "percentComplete": %s + } + """; + // Results for TEST_TASK_ID_1. + var metadata1 = metadataTemplate.formatted(1000, 0.2, 0.3, 1000, 10); + testResultService.populateResultForTask(RESULT_ID_1, TEST_NCA_ID, TEST_TASK_ID_1, + (ObjectNode) jsonMapper.readTree(metadata1)); + + var metadata2 = metadataTemplate.formatted(2000, 0.3, 0.4, 2000, 20); + testResultService.populateResultForTask(RESULT_ID_2, TEST_NCA_ID, TEST_TASK_ID_1, + (ObjectNode) jsonMapper.readTree(metadata2)); + + var metadata3 = metadataTemplate.formatted(3000, 0.4, 0.5, 3000, 30); + testResultService.populateResultForTask(RESULT_ID_3, TEST_NCA_ID, TEST_TASK_ID_1, + (ObjectNode) jsonMapper.readTree(metadata3)); + + // Results for TEST_TASK_ID_2 to make sure there is no cross contamination query + var otherMetadata1 = metadataTemplate.formatted(3000, 0.4, 0.5, 3000, 30); + testResultService.populateResultForTask(RESULT_ID_1, TEST_NCA_ID, TEST_TASK_ID_2, + (ObjectNode) jsonMapper.readTree(otherMetadata1)); + } + + @AfterEach + void reset() { + MockApiKeysServer.resetToDefault(); + // use of MockApiKeysServer with different scopes causes the api-keys cache to dirty + apiKeysService.invalidateCache(); + accountService.invalidateCache(); + tasksRepository.deleteAll(); + resultsByTaskRepository.deleteAll(); + testTaskService.clearAll(); + } + + Stream taskResultsArgs() { + var jwtCases = Stream.of( + // TEST_TASK_ID_1 belongs to TEST_NCA_ID. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LIST_EVENTS, + SCOPE_LIST_TASKS, + SCOPE_LIST_RESULTS), + 100), + TEST_NCA_ID, + TEST_TASK_ID_1, + Set.of(RESULT_ID_1, RESULT_ID_2, RESULT_ID_3), + HttpStatus.OK), + // TEST_TASK_ID_2 belongs to TEST_NCA_ID. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LIST_EVENTS, + SCOPE_LIST_TASKS, + SCOPE_LIST_RESULTS), + 100), + TEST_NCA_ID, + TEST_TASK_ID_2, + Set.of(RESULT_ID_1), + HttpStatus.OK), + // Task in different account. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT_2, + List.of(SCOPE_LIST_EVENTS, + SCOPE_LIST_TASKS, + SCOPE_LIST_RESULTS), + 100), + TEST_NCA_ID, + TEST_TASK_ID_1, + Set.of(), + HttpStatus.NOT_FOUND), + // Non-existent client. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt("non-existent-client", + List.of(SCOPE_LIST_EVENTS, + SCOPE_LIST_TASKS, + SCOPE_LIST_RESULTS), + 100), + TEST_NCA_ID, + TEST_TASK_ID_1, + Set.of(), + HttpStatus.NOT_FOUND), + // Non-existent task. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LIST_EVENTS, + SCOPE_LIST_TASKS, + SCOPE_LIST_RESULTS), + 100), + TEST_NCA_ID, + TEST_TASK_ID_3, + Set.of(), + HttpStatus.NOT_FOUND), + // Missing scopes. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(), + 100), + TEST_NCA_ID, + TEST_TASK_ID_1, + Set.of(), + HttpStatus.FORBIDDEN), + // No token. + Arguments.of(null, + TEST_NCA_ID, + TEST_TASK_ID_1, + Set.of(), + HttpStatus.UNAUTHORIZED) + ); + + var apiKeyCases = Stream.of( + // api-key with list_results scope and account-tasks resource + Arguments.of((Supplier) () -> { + MockApiKeysServer.setResponse(TEST_NCA_ID, TEST_OWNER_ID, + List.of(new Resource("account-tasks", "*")), + List.of("list_results")); + return "nvapi-stg-some-key"; + }, + TEST_NCA_ID, + TEST_TASK_ID_1, + Set.of(RESULT_ID_1, RESULT_ID_2, RESULT_ID_3), + HttpStatus.OK), + // api-key with list_results scope and specific task resource (matching) + Arguments.of((Supplier) () -> { + MockApiKeysServer.setResponse(TEST_NCA_ID, TEST_OWNER_ID, + List.of(new Resource("task", TEST_TASK_ID_1.toString())), + List.of("list_results")); + return "nvapi-stg-some-key"; + }, + TEST_NCA_ID, + TEST_TASK_ID_1, + Set.of(RESULT_ID_1, RESULT_ID_2, RESULT_ID_3), + HttpStatus.OK), + // api-key with list_results scope and specific task resource (not matching) + Arguments.of((Supplier) () -> { + MockApiKeysServer.setResponse(TEST_NCA_ID, TEST_OWNER_ID, + List.of(new Resource("task", TEST_TASK_ID_2.toString())), + List.of("list_results")); + return "nvapi-stg-some-key"; + }, + TEST_NCA_ID, + TEST_TASK_ID_1, + Set.of(), + HttpStatus.FORBIDDEN), + // api-key with scope but no resources + Arguments.of((Supplier) () -> { + MockApiKeysServer.setResponse(TEST_NCA_ID, TEST_OWNER_ID, + List.of(), + List.of("list_results")); + return "nvapi-stg-some-key"; + }, + TEST_NCA_ID, + TEST_TASK_ID_1, + Set.of(), + HttpStatus.FORBIDDEN), + // api-key with missing scope + Arguments.of((Supplier) () -> { + MockApiKeysServer.setResponse(TEST_NCA_ID, TEST_OWNER_ID, + List.of(new Resource("account-tasks", "*")), + List.of()); + return "nvapi-stg-some-key"; + }, + TEST_NCA_ID, + TEST_TASK_ID_1, + Set.of(), + HttpStatus.FORBIDDEN) + ); + + return Stream.concat(jwtCases, apiKeyCases); + } + + @SneakyThrows + @ParameterizedTest + @MethodSource("taskResultsArgs") + void shouldListResults(Object tokenSupplier, + String ncaId, + UUID taskId, + Set resultIds, + HttpStatus expectedStatus) { + var token = TestUtil.getToken(tokenSupplier); + var requestEntity = + RequestEntity.get(URI.create("/v1/nvct/tasks/" + taskId + "/results")) + .header("Authorization", "Bearer " + token) + .build(); + var responseEntity = testRestTemplate.exchange(requestEntity, ListResultsResponse.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(expectedStatus); + if (expectedStatus.isError()) { + return; + } + + var responseBody = responseEntity.getBody(); + assertThat(responseBody).isNotNull(); + assertThat(responseBody.cursor()).isNull(); + assertThat(responseBody.limit()).isNull(); + assertThat(responseBody.results()).hasSize(resultIds.size()); + for (var resultDto : responseBody.results()) { + assertThat(resultDto.createdAt()).isNotNull(); + assertThat(resultDto.ncaId()).isEqualTo(ncaId); + assertThat(resultDto.resultId()).isIn(resultIds); + assertThat(resultDto.taskId()).isEqualTo(taskId); + assertThat(resultDto.metadata()).isNotNull(); + assertThat(resultDto.metadata()).hasSize(5); + assertThat(resultDto.metadata().get("step_number").asInt()) + .isIn(Set.of(1000, 2000, 3000)); + assertThat(resultDto.metadata().get("percentComplete").asInt()) + .isIn(Set.of(10, 20, 30)); + assertThat(resultDto.name()).isNotBlank(); + } + } + + Stream taskResultsWithPaginationLimitArgs() { + return Stream.of( + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LIST_EVENTS, + SCOPE_LIST_TASKS, + SCOPE_LIST_RESULTS), + 100), + TEST_NCA_ID, + TEST_TASK_ID_1, + 1, + Set.of(RESULT_ID_1, RESULT_ID_2, RESULT_ID_3)), + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LIST_EVENTS, + SCOPE_LIST_TASKS, + SCOPE_LIST_RESULTS), + 100), + TEST_NCA_ID, + TEST_TASK_ID_1, + 100, + Set.of(RESULT_ID_1, RESULT_ID_2, RESULT_ID_3)) + ); + } + + @ParameterizedTest + @MethodSource("taskResultsWithPaginationLimitArgs") + void shouldListResultsWithPaginationLimit(String token, + String ncaId, + UUID taskId, + int limit, + Set expectedResultIds) { + var requestEntity = + RequestEntity.get(URI.create("/v1/nvct/tasks/" + taskId + "/results?limit=" + limit)) + .header("Authorization", "Bearer " + token) + .build(); + var responseEntity = testRestTemplate.exchange(requestEntity, ListResultsResponse.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK); + + var responseBody = responseEntity.getBody(); + assertThat(responseBody).isNotNull(); + if (limit < 3) { + assertThat(responseBody.results()).hasSize(limit); + assertThat(responseBody.cursor()).isNotNull(); + assertThat(responseBody.limit()).isEqualTo(limit); + } else { + assertThat(responseBody.results()).hasSize(3); + assertThat(responseBody.cursor()).isNull(); + assertThat(responseBody.limit()).isNull(); + } + + verifyReturnedResultsIntegrity(expectedResultIds, responseBody.results(), ncaId, taskId); + } + + void verifyReturnedResultsIntegrity( + Set expectedResults, List results, String ncaId, UUID taskId) { + for (var resultDto : results) { + assertThat(resultDto.createdAt()).isNotNull(); + assertThat(resultDto.ncaId()).isEqualTo(ncaId); + assertThat(resultDto.resultId()).isIn(expectedResults); + assertThat(resultDto.taskId()).isEqualTo(taskId); + assertThat(resultDto.metadata()).isNotNull(); + assertThat(resultDto.metadata()).hasSize(5); + assertThat(resultDto.metadata().get("step_number").asInt()) + .isIn(Set.of(1000, 2000, 3000)); + assertThat(resultDto.name()).isNotBlank(); + } + } + + @Test + void shouldListResultsWithPaginationCursor() { + var token = MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LIST_EVENTS, + SCOPE_LIST_TASKS, + SCOPE_LIST_RESULTS), + 100); + var expectedResults = Set.of(RESULT_ID_1, RESULT_ID_2, RESULT_ID_3); + + // get the first 2 out of 3 results first + var url = "/v1/nvct/tasks/" + TEST_TASK_ID_1 + "/results?limit=2"; + var requestEntity = + RequestEntity.get(URI.create(url)) + .header("Authorization", "Bearer " + token) + .build(); + var responseEntity = + testRestTemplate.exchange(requestEntity, ListResultsResponse.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK); + var responseBody = responseEntity.getBody(); + assertThat(responseBody).isNotNull(); + var currentCursor = responseBody.cursor(); + assertThat(currentCursor).isNotNull(); + var firstPageResult = responseBody.results(); + assertThat(firstPageResult).hasSize(2); + assertThat(responseBody.limit()).isEqualTo(2); + + // using the cursor from previous response, continue to listing the rest of the results + url = "/v1/nvct/tasks/" + TEST_TASK_ID_1 + "/results?limit=2&cursor=" + currentCursor; + requestEntity = + RequestEntity.get(URI.create(url)) + .header("Authorization", "Bearer " + token) + .build(); + responseEntity = + testRestTemplate.exchange(requestEntity, ListResultsResponse.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK); + + // make sure the last result is correct + responseBody = responseEntity.getBody(); + assertThat(responseBody).isNotNull(); + currentCursor = responseBody.cursor(); + assertThat(responseBody.limit()).isNull(); + assertThat(currentCursor).isNull(); + var secondPageResult = responseBody.results(); + assertThat(secondPageResult).hasSize(1); + + // make sure all 3 results have the right metadata + verifyReturnedResultsIntegrity(expectedResults, + Stream.concat(firstPageResult.stream(), + secondPageResult.stream()).toList(), + TEST_NCA_ID, + TEST_TASK_ID_1); + } + +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/result/TestResultService.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/result/TestResultService.java new file mode 100644 index 000000000..f11655d33 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/result/TestResultService.java @@ -0,0 +1,50 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.rest.result; + +import tools.jackson.databind.node.ObjectNode; +import com.nvidia.nvct.persistence.result.ResultsByTaskRepository; +import com.nvidia.nvct.persistence.result.entity.ResultByTaskEntity; +import com.nvidia.nvct.persistence.result.entity.ResultByTaskKey; +import java.time.Instant; +import java.util.UUID; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +@Slf4j +@Service +@RequiredArgsConstructor +public class TestResultService { + + private final ResultsByTaskRepository resultsByTaskRepository; + + public void populateResultForTask(UUID resultId, + String ncaId, + UUID taskId, + ObjectNode resultMetadata) { + var event = ResultByTaskEntity.builder() + .key(ResultByTaskKey.builder().taskId(taskId).resultId(resultId).build()) + .ncaId(ncaId) + .metadata(resultMetadata.toString()) + .name(taskId.toString()) + .createdAt(Instant.now()) + .build(); + resultsByTaskRepository.save(event); + } + +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/result/XAccountResultControllerTest.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/result/XAccountResultControllerTest.java new file mode 100644 index 000000000..ca3782d3e --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/result/XAccountResultControllerTest.java @@ -0,0 +1,427 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.rest.result; + +import static com.nvidia.nvct.IntegrationTestConfiguration.MOCK_OAUTH2_TOKEN_SERVER; +import static com.nvidia.nvct.util.NvctConstants.ADMIN_SCOPE_LIST_EVENTS; +import static com.nvidia.nvct.util.NvctConstants.ADMIN_SCOPE_LIST_RESULTS; +import static com.nvidia.nvct.util.NvctConstants.ADMIN_SCOPE_LIST_TASKS; +import static com.nvidia.nvct.util.TestConstants.RESULT_ID_1; +import static com.nvidia.nvct.util.TestConstants.RESULT_ID_2; +import static com.nvidia.nvct.util.TestConstants.RESULT_ID_3; +import static com.nvidia.nvct.util.TestConstants.TEST_ADMIN_SUBJECT; +import static com.nvidia.nvct.util.TestConstants.TEST_NCA_ID; +import static com.nvidia.nvct.util.TestConstants.TEST_NCA_ID_2; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_ID_1; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_ID_2; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_ID_3; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_NAME_1; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_NAME_2; +import static org.assertj.core.api.Assertions.assertThat; + +import tools.jackson.databind.json.JsonMapper; +import tools.jackson.databind.node.ObjectNode; +import com.nvidia.nvct.IntegrationTestConfiguration; +import com.nvidia.nvct.NvctTestApp; +import com.nvidia.nvct.grpc.TestTaskService; +import com.nvidia.nvct.persistence.result.ResultsByTaskRepository; +import com.nvidia.nvct.persistence.task.TasksRepository; +import com.nvidia.nvct.rest.result.dto.ListResultsResponse; +import com.nvidia.nvct.rest.result.dto.ResultDto; +import com.nvidia.nvct.service.account.AccountService; +import com.nvidia.nvct.service.apikeys.ApiKeysService; +import com.nvidia.nvct.util.MockApiKeysServer; +import com.nvidia.nvct.util.MockNvcfServer; +import com.nvidia.nvct.util.TestUtil; +import java.net.URI; +import java.net.URL; +import java.util.List; +import java.util.Set; +import java.util.UUID; +import java.util.stream.Stream; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.resttestclient.TestRestTemplate; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; +import org.springframework.http.HttpStatus; +import org.springframework.http.RequestEntity; +import org.springframework.test.context.ContextConfiguration; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@Slf4j +@SpringBootTest( + classes = {NvctTestApp.class, IntegrationTestConfiguration.class}, + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + properties = "spring.profiles.active=test") +@ContextConfiguration(initializers = IntegrationTestConfiguration.Initializer.class) +@AutoConfigureTestRestTemplate +class XAccountResultControllerTest { + + @Autowired + private TestRestTemplate testRestTemplate; + + @Autowired + private TestTaskService testTaskService; + + @Autowired + private TestResultService testResultService; + + @Autowired + private AccountService accountService; + + @Autowired + private TasksRepository tasksRepository; + + @Autowired + private ResultsByTaskRepository resultsByTaskRepository; + + @Autowired + private JsonMapper jsonMapper; + + @Autowired + private ApiKeysService apiKeysService; + + @Value("${nvct.nvcf.base-url}") + private URL nvcfBaseUrl; + + @Value("${nvct.api-keys.base-url}") + private String apiKeysBaseUrl; + + @BeforeAll + void beforeAll() { + log.info("{}: Started running tests", this.getClass().getSimpleName()); + MockApiKeysServer.start(apiKeysBaseUrl); + MockNvcfServer.start(nvcfBaseUrl); + tasksRepository.deleteAll(); + resultsByTaskRepository.deleteAll(); + + } + + @AfterAll + void cleanup() { + MockNvcfServer.stop(); + MockApiKeysServer.stop(); + log.info("{}: Completed running tests", this.getClass().getSimpleName()); + } + + @SneakyThrows + @BeforeEach + void beforeEach() { + // Create Tasks in TEST_NCA_ID account tied to TEST_CLIENT_ID. + var task1 = TestUtil.createTaskEntity(TEST_TASK_ID_1, TEST_NCA_ID, TEST_TASK_NAME_1, + jsonMapper); + var task2 = TestUtil.createTaskEntity(TEST_TASK_ID_2, TEST_NCA_ID, TEST_TASK_NAME_2, + jsonMapper); + + // Save tasks. + tasksRepository.save(task1); + tasksRepository.save(task2); + + var metadataTemplate = """ + { + "fine_tuned_model_checkpoint": "ckpt-step-%s", + "metrics": { + "full_valid_loss": %s, + "full_valid_mean_token_accuracy": %s + }, + "fine_tuning_job_id": "ftjob-abc123", + "step_number": %s + } + """; + // Results for TEST_TASK_ID_1. + var metadata1 = metadataTemplate.formatted(1000, 0.2, 0.3, 1000); + testResultService.populateResultForTask(RESULT_ID_1, TEST_NCA_ID, TEST_TASK_ID_1, + (ObjectNode) jsonMapper.readTree(metadata1)); + + var metadata2 = metadataTemplate.formatted(2000, 0.3, 0.4, 2000); + testResultService.populateResultForTask(RESULT_ID_2, TEST_NCA_ID, TEST_TASK_ID_1, + (ObjectNode) jsonMapper.readTree(metadata2)); + + var metadata3 = metadataTemplate.formatted(3000, 0.4, 0.5, 3000); + testResultService.populateResultForTask(RESULT_ID_3, TEST_NCA_ID, TEST_TASK_ID_1, + (ObjectNode) jsonMapper.readTree(metadata3)); + + // Results for TEST_TASK_ID_2 to make sure there is no cross contamination query + var otherMetadata1 = metadataTemplate.formatted(3000, 0.4, 0.5, 3000); + testResultService.populateResultForTask(RESULT_ID_1, TEST_NCA_ID, TEST_TASK_ID_2, + (ObjectNode) jsonMapper.readTree(otherMetadata1)); + } + + @AfterEach + void reset() { + MockApiKeysServer.resetToDefault(); + // use of MockApiKeysServer with different scopes causes the api-keys cache to dirty + apiKeysService.invalidateCache(); + accountService.invalidateCache(); + tasksRepository.deleteAll(); + resultsByTaskRepository.deleteAll(); + testTaskService.clearAll(); + } + + Stream taskResultsArgs() { + return Stream.of( + // TEST_TASK_ID_1 belongs to TEST_NCA_ID. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LIST_EVENTS, + ADMIN_SCOPE_LIST_TASKS, + ADMIN_SCOPE_LIST_RESULTS), + 100), + TEST_NCA_ID, + TEST_TASK_ID_1, + Set.of(RESULT_ID_1, RESULT_ID_2, RESULT_ID_3), + HttpStatus.OK), + // TEST_TASK_ID_1 belongs to TEST_NCA_ID. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt("another-admin", + List.of(ADMIN_SCOPE_LIST_EVENTS, + ADMIN_SCOPE_LIST_TASKS, + ADMIN_SCOPE_LIST_RESULTS), + 100), + TEST_NCA_ID, + TEST_TASK_ID_1, + Set.of(RESULT_ID_1, RESULT_ID_2, RESULT_ID_3), + HttpStatus.OK), + // TEST_TASK_ID_2 belongs to TEST_NCA_ID. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LIST_EVENTS, + ADMIN_SCOPE_LIST_TASKS, + ADMIN_SCOPE_LIST_RESULTS), + 100), + TEST_NCA_ID, + TEST_TASK_ID_2, + Set.of(RESULT_ID_1), + HttpStatus.OK), + // Non-existent account. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LIST_EVENTS, + ADMIN_SCOPE_LIST_TASKS, + ADMIN_SCOPE_LIST_RESULTS), + 100), + "non-existent-account", + TEST_TASK_ID_1, + Set.of(), + HttpStatus.NOT_FOUND), + // Task in different account. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LIST_EVENTS, + ADMIN_SCOPE_LIST_TASKS, + ADMIN_SCOPE_LIST_RESULTS), + 100), + TEST_NCA_ID_2, + TEST_TASK_ID_2, + Set.of(), + HttpStatus.NOT_FOUND), + // Non-existent task. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LIST_EVENTS, + ADMIN_SCOPE_LIST_TASKS, + ADMIN_SCOPE_LIST_RESULTS), + 100), + TEST_NCA_ID, + TEST_TASK_ID_3, + Set.of(), + HttpStatus.NOT_FOUND), + // Missing scopes. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(), + 100), + TEST_NCA_ID, + TEST_TASK_ID_1, + Set.of(), + HttpStatus.FORBIDDEN), + // No token. + Arguments.of(null, + TEST_NCA_ID, + TEST_TASK_ID_1, + Set.of(), + HttpStatus.UNAUTHORIZED) + ); + } + + @SneakyThrows + @ParameterizedTest + @MethodSource("taskResultsArgs") + void shouldListResults(Object tokenSupplier, + String ncaId, + UUID taskId, + Set resultIds, + HttpStatus expectedStatus) { + var token = TestUtil.getToken(tokenSupplier); + var uri = URI.create("/v1/nvct/accounts/" + ncaId + "/tasks/" + taskId + "/results"); + var requestEntity = + RequestEntity.get(uri) + .header("Authorization", "Bearer " + token) + .build(); + var responseEntity = testRestTemplate.exchange(requestEntity, ListResultsResponse.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(expectedStatus); + if (expectedStatus.isError()) { + return; + } + + var responseBody = responseEntity.getBody(); + assertThat(responseBody).isNotNull(); + assertThat(responseBody.results()).hasSize(resultIds.size()); + assertThat(responseBody.cursor()).isNull(); + assertThat(responseBody.limit()).isNull(); + for (var resultDto : responseBody.results()) { + assertThat(resultDto.createdAt()).isNotNull(); + assertThat(resultDto.ncaId()).isEqualTo(ncaId); + assertThat(resultDto.resultId()).isIn(resultIds); + assertThat(resultDto.taskId()).isEqualTo(taskId); + assertThat(resultDto.metadata()).isNotNull(); + assertThat(resultDto.metadata()).hasSize(4); + assertThat(resultDto.metadata().get("step_number").asInt()) + .isIn(Set.of(1000, 2000, 3000)); + assertThat(resultDto.name()).isNotBlank(); + } + } + + Stream taskResultsWithPaginationLimitArgs() { + return Stream.of( + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LIST_EVENTS, + ADMIN_SCOPE_LIST_TASKS, + ADMIN_SCOPE_LIST_RESULTS), + 100), + TEST_NCA_ID, + TEST_TASK_ID_1, + 1, + Set.of(RESULT_ID_1, RESULT_ID_2, RESULT_ID_3)), + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LIST_EVENTS, + ADMIN_SCOPE_LIST_TASKS, + ADMIN_SCOPE_LIST_RESULTS), + 100), + TEST_NCA_ID, + TEST_TASK_ID_1, + 100, + Set.of(RESULT_ID_1, RESULT_ID_2, RESULT_ID_3)) + ); + } + + @ParameterizedTest + @MethodSource("taskResultsWithPaginationLimitArgs") + void shouldListResultsWithPaginationLimit(String token, + String ncaId, + UUID taskId, + int limit, + Set expectedResultIds) { + var requestEntity = RequestEntity + .get(URI.create("/v1/nvct/accounts/" + ncaId + + "/tasks/" + taskId + "/results?limit=" + limit)) + .header("Authorization", "Bearer " + token) + .build(); + var responseEntity = testRestTemplate.exchange(requestEntity, ListResultsResponse.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK); + + var responseBody = responseEntity.getBody(); + assertThat(responseBody).isNotNull(); + + if (limit < 3) { + assertThat(responseBody.results()).hasSize(limit); + assertThat(responseBody.cursor()).isNotNull(); + assertThat(responseBody.limit()).isEqualTo(limit); + } else { + assertThat(responseBody.results()).hasSize(3); + assertThat(responseBody.cursor()).isNull(); + assertThat(responseBody.limit()).isNull(); + } + + verifyReturnedResultsIntegrity(expectedResultIds, responseBody.results(), ncaId, taskId); + } + + void verifyReturnedResultsIntegrity( + Set expectedResults, List results, String ncaId, UUID taskId) { + for (var resultDto : results) { + assertThat(resultDto.createdAt()).isNotNull(); + assertThat(resultDto.ncaId()).isEqualTo(ncaId); + assertThat(resultDto.resultId()).isIn(expectedResults); + assertThat(resultDto.taskId()).isEqualTo(taskId); + assertThat(resultDto.metadata()).isNotNull(); + assertThat(resultDto.metadata()).hasSize(4); + assertThat(resultDto.metadata().get("step_number").asInt()) + .isIn(Set.of(1000, 2000, 3000)); + assertThat(resultDto.name()).isNotBlank(); + } + } + + @Test + void shouldListResultsWithPaginationCursor() { + var token = MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LIST_EVENTS, + ADMIN_SCOPE_LIST_TASKS, + ADMIN_SCOPE_LIST_RESULTS), + 100); + var expectedResults = Set.of(RESULT_ID_1, RESULT_ID_2, RESULT_ID_3); + + // get the first 2 out of 3 results first + var url = "/v1/nvct/accounts/" + TEST_NCA_ID + "/tasks/" + TEST_TASK_ID_1 + "/results?limit=2"; + var requestEntity = RequestEntity + .get(URI.create(url)) + .header("Authorization", "Bearer " + token) + .build(); + var responseEntity = + testRestTemplate.exchange(requestEntity, ListResultsResponse.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK); + var responseBody = responseEntity.getBody(); + assertThat(responseBody).isNotNull(); + var currentCursor = responseBody.cursor(); + assertThat(currentCursor).isNotNull(); + var firstPageResult = responseBody.results(); + assertThat(firstPageResult).hasSize(2); + assertThat(responseBody.limit()).isEqualTo(2); + + // using the cursor from previous response, continue to listing the rest of the tasks + url = "/v1/nvct/accounts/" + TEST_NCA_ID + "/tasks/" + TEST_TASK_ID_1 + + "/results?limit=2&cursor=" + currentCursor; + requestEntity = + RequestEntity.get(URI.create(url)) + .header("Authorization", "Bearer " + token) + .build(); + responseEntity = + testRestTemplate.exchange(requestEntity, ListResultsResponse.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK); + + // make sure the last result is correct + responseBody = responseEntity.getBody(); + assertThat(responseBody).isNotNull(); + currentCursor = responseBody.cursor(); + assertThat(currentCursor).isNull(); + assertThat(responseBody.limit()).isNull(); + var secondPageResult = responseBody.results(); + assertThat(secondPageResult).hasSize(1); + + // make sure all 3 tasks have the right metadata + verifyReturnedResultsIntegrity(expectedResults, + Stream.concat(firstPageResult.stream(), + secondPageResult.stream()).toList(), + TEST_NCA_ID, + TEST_TASK_ID_1); + } + +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/secret/SecretManagementControllerTest.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/secret/SecretManagementControllerTest.java new file mode 100644 index 000000000..dd72e8b1d --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/secret/SecretManagementControllerTest.java @@ -0,0 +1,482 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.rest.secret; + +import static com.nvidia.nvct.IntegrationTestConfiguration.MOCK_OAUTH2_TOKEN_SERVER; +import static com.nvidia.nvct.persistence.task.entity.TaskStatus.CANCELED; +import static com.nvidia.nvct.persistence.task.entity.TaskStatus.COMPLETED; +import static com.nvidia.nvct.persistence.task.entity.TaskStatus.ERRORED; +import static com.nvidia.nvct.persistence.task.entity.TaskStatus.EXCEEDED_MAX_QUEUED_DURATION; +import static com.nvidia.nvct.persistence.task.entity.TaskStatus.EXCEEDED_MAX_RUNTIME_DURATION; +import static com.nvidia.nvct.util.NvctConstants.MAX_SECRET_NAME_LENGTH; +import static com.nvidia.nvct.util.NvctConstants.MAX_SECRET_VALUE_LENGTH; +import static com.nvidia.nvct.util.NvctConstants.NGC_API_KEY; +import static com.nvidia.nvct.util.NvctConstants.SCOPE_UPDATE_SECRETS; +import static com.nvidia.nvct.util.TestConstants.TEST_CLIENT_SUBJECT; +import static com.nvidia.nvct.util.TestConstants.TEST_CLIENT_SUBJECT_2; +import static com.nvidia.nvct.util.TestConstants.TEST_NCA_ID; +import static com.nvidia.nvct.util.TestConstants.TEST_OWNER_ID; +import static com.nvidia.nvct.util.TestConstants.TEST_ICMS_REQ_ID_1; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_ID_1; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_ID_2; +import static com.nvidia.nvct.util.TestUtil.getToken; +import static org.assertj.core.api.Assertions.assertThat; + +import tools.jackson.databind.json.JsonMapper; +import tools.jackson.databind.node.StringNode; +import com.nvidia.boot.mock.ngc.MockCasServer; +import com.nvidia.nvct.IntegrationTestConfiguration; +import com.nvidia.nvct.NvctTestApp; +import com.nvidia.nvct.grpc.TestTaskService; +import com.nvidia.nvct.persistence.task.entity.ResultHandlingStrategy; +import com.nvidia.nvct.persistence.task.entity.TaskStatus; +import com.nvidia.nvct.rest.secret.dto.UpdateSecretsRequest; +import com.nvidia.nvct.rest.task.dto.SecretDto; +import com.nvidia.nvct.service.account.AccountService; +import com.nvidia.nvct.service.apikeys.ApiKeyValidationResult.Resource; +import com.nvidia.nvct.service.apikeys.ApiKeysService; +import com.nvidia.nvct.service.ess.EssService; +import com.nvidia.nvct.service.task.TaskService; +import com.nvidia.nvct.util.MockApiKeysServer; +import com.nvidia.nvct.util.MockEssServer; +import com.nvidia.nvct.util.MockNvcfServer; +import java.net.URI; +import java.net.URL; +import java.util.List; +import java.util.Set; +import java.util.function.Supplier; +import java.util.stream.Stream; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.resttestclient.TestRestTemplate; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.RequestEntity; +import org.springframework.test.context.ContextConfiguration; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@Slf4j +@SpringBootTest( + classes = {NvctTestApp.class, IntegrationTestConfiguration.class}, + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + properties = "spring.profiles.active=test") +@ContextConfiguration(initializers = IntegrationTestConfiguration.Initializer.class) +@AutoConfigureTestRestTemplate +class SecretManagementControllerTest { + + @Autowired + private JsonMapper jsonMapper; + + @Autowired + private TestRestTemplate testRestTemplate; + + + @Autowired + private TestTaskService testTaskService; + + @Autowired + private EssService essService; + + @Autowired + private TaskService taskService; + + @Autowired + private AccountService accountService; + + @Autowired + private ApiKeysService apiKeysService; + + @Value("${nvct.registries.recognized.model.ngc.hostname}") + private String casBaseUrl; + + @Value("${nvct.registries.recognized.model.ngc.oauth2.base-url}") + private String authnBaseUrl; + + @Value("${nvct.ess.base-url}") + private String essBaseUrl; + + @Value("${nvct.nvcf.base-url}") + private URL nvcfBaseUrl; + + @Value("${nvct.api-keys.base-url}") + private String apiKeysBaseUrl; + + @BeforeAll + void beforeAll() { + log.info("{}: Started running tests", this.getClass().getSimpleName()); + + MockApiKeysServer.start(apiKeysBaseUrl); + MockEssServer.start(essBaseUrl); + MockNvcfServer.start(nvcfBaseUrl); + MockCasServer.start(authnBaseUrl, casBaseUrl); + } + + @AfterAll + void cleanup() { + MockApiKeysServer.stop(); + MockEssServer.stop(); + MockNvcfServer.stop(); + MockCasServer.stop(); + log.info("{}: Completed running tests", this.getClass().getSimpleName()); + } + + @AfterEach + void reset() { + MockApiKeysServer.resetToDefault(); + // use of MockApiKeysServer with different scopes causes the api-keys cache to dirty + apiKeysService.invalidateCache(); + accountService.invalidateCache(); + testTaskService.clearAll(); + MockEssServer.clearSecrets(); + } + + Stream updateSecretArgs() { + var secretJsonNodeValue = jsonMapper.createObjectNode() + .put("AWS_REGION", "us-west-2") + .put("AWS_BUCKET", "ov-content") + .put("AWS_ACCESS_KEY_ID", "ov-content-key-id") + .put("AWS_SECRET_ACCESS_KEY", "ov-content-access-key") + .put("AWS_SESSION_TOKEN", "ov-content-session-token"); + var jwtCases = Stream.of( + // no secrets with default resultHandlingStrategy + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_UPDATE_SECRETS), + 100), + null, + null, + HttpStatus.BAD_REQUEST), + // no secrets with resultHandlingStrategy UPLOAD + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_UPDATE_SECRETS), + 100), + null, + ResultHandlingStrategy.UPLOAD, + HttpStatus.BAD_REQUEST), + // single secret + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_UPDATE_SECRETS), + 100), + Set.of(SecretDto.builder() + .name(NGC_API_KEY) + .value(new StringNode("value1")).build()), + ResultHandlingStrategy.UPLOAD, + HttpStatus.NO_CONTENT), + // update secret of a Task that belongs to a different account + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT_2, + List.of(SCOPE_UPDATE_SECRETS), + 100), + Set.of(SecretDto.builder() + .name(NGC_API_KEY) + .value(new StringNode("value1")).build()), + ResultHandlingStrategy.UPLOAD, + HttpStatus.NOT_FOUND), + // duplicate secrets + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_UPDATE_SECRETS), + 100), + Set.of(SecretDto.builder() + .name("secret1") + .value(new StringNode("value1")).build(), + SecretDto.builder() + .name("secret1") + .value(new StringNode("value2")).build()), + ResultHandlingStrategy.UPLOAD, + HttpStatus.BAD_REQUEST), + // Secret name -- exactly MAX_SECRET_NAME_LENGTH in length + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_UPDATE_SECRETS), + 100), + Set.of(SecretDto.builder() + .name(StringUtils.repeat("x", MAX_SECRET_NAME_LENGTH)) + .value(new StringNode("value1")).build(), + SecretDto.builder() + .name("secret1") + .value(new StringNode("value2")).build()), + ResultHandlingStrategy.NONE, + HttpStatus.NO_CONTENT), + // secret names with periods, and hyphens + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_UPDATE_SECRETS), + 100), + Set.of(SecretDto.builder() + .name("omni.s3.us-west-2.amazonaws.com") + .value(new StringNode("value1")).build(), + SecretDto.builder() + .name("omni.s3.eu-north-1.amazonaws.com") + .value(new StringNode("value2")).build(), + SecretDto.builder() + .name("omni.s3.ap-northeast-1.amazonaws.com") + .value(secretJsonNodeValue).build()), + ResultHandlingStrategy.NONE, + HttpStatus.NO_CONTENT), + // secret names with underscores + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_UPDATE_SECRETS), + 100), + Set.of(SecretDto.builder() + .name("omni_s3_us-west-2_amazonaws_com") + .value(new StringNode("value1")).build(), + SecretDto.builder() + .name("omni_s3_eu-north-1_amazonaws_com") + .value(new StringNode("value2")).build(), + SecretDto.builder() + .name("omni.s3.ap-northeast-1.amazonaws.com") + .value(secretJsonNodeValue).build()), + ResultHandlingStrategy.NONE, + HttpStatus.NO_CONTENT), + // empty secret name + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_UPDATE_SECRETS), + 100), + Set.of(SecretDto.builder() + .name("") + .value(new StringNode("value1")).build()), + ResultHandlingStrategy.NONE, + HttpStatus.BAD_REQUEST), + // long secret name - exceeds MAX_SECRET_NAME_LENGTH chars + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_UPDATE_SECRETS), + 100), + Set.of(SecretDto.builder() + .name(StringUtils.repeat("secret1", MAX_SECRET_NAME_LENGTH)) + .value(new StringNode("value1")).build()), + ResultHandlingStrategy.NONE, + HttpStatus.BAD_REQUEST), + // empty secret value + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_UPDATE_SECRETS), + 100), + Set.of(SecretDto.builder() + .name("") + .value(new StringNode("value1")).build()), + ResultHandlingStrategy.NONE, + HttpStatus.BAD_REQUEST), + // long secret value + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_UPDATE_SECRETS), + 100), + Set.of(SecretDto.builder().name("secret1") + .value(new StringNode(StringUtils.repeat("value1", + MAX_SECRET_VALUE_LENGTH))) + .build()), + ResultHandlingStrategy.NONE, + HttpStatus.BAD_REQUEST), + // bad secret name + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_UPDATE_SECRETS), + 100), + Set.of(SecretDto.builder().name("*secret1*-\"") + .value(new StringNode("value1")).build()), + ResultHandlingStrategy.NONE, + HttpStatus.BAD_REQUEST) + ); + + var apiKeysCases = Stream.of( + // api-key with update_secrets scope and account-tasks resource + Arguments.of((Supplier) () -> { + MockApiKeysServer.setResponse(TEST_NCA_ID, TEST_OWNER_ID, + List.of(new Resource("account-tasks", "*")), + List.of("update_secrets")); + return "nvapi-stg-some-key"; + }, + Set.of(SecretDto.builder() + .name("secret1") + .value(new StringNode("value1")).build()), + ResultHandlingStrategy.UPLOAD, + HttpStatus.NO_CONTENT), + // api-key with update_secrets scope and specific task resource (matching) + Arguments.of((Supplier) () -> { + MockApiKeysServer.setResponse(TEST_NCA_ID, TEST_OWNER_ID, + List.of(new Resource("task", TEST_TASK_ID_1.toString())), + List.of("update_secrets")); + return "nvapi-stg-some-key"; + }, + Set.of(SecretDto.builder() + .name("secret1") + .value(new StringNode("value1")).build()), + ResultHandlingStrategy.UPLOAD, + HttpStatus.NO_CONTENT), + // api-key with update_secrets scope and specific task resource (not matching) + Arguments.of((Supplier) () -> { + MockApiKeysServer.setResponse(TEST_NCA_ID, TEST_OWNER_ID, + List.of(new Resource("task", TEST_TASK_ID_2.toString())), + List.of("update_secrets")); + return "nvapi-stg-some-key"; + }, + Set.of(SecretDto.builder() + .name("secret1") + .value(new StringNode("value1")).build()), + ResultHandlingStrategy.UPLOAD, + HttpStatus.FORBIDDEN), + // api-key with scope but no resources + Arguments.of((Supplier) () -> { + MockApiKeysServer.setResponse(TEST_NCA_ID, TEST_OWNER_ID, + List.of(), + List.of("update_secrets")); + return "nvapi-stg-some-key"; + }, + Set.of(SecretDto.builder() + .name("secret1") + .value(new StringNode("value1")).build()), + ResultHandlingStrategy.UPLOAD, + HttpStatus.FORBIDDEN), + // api-key with missing scope + Arguments.of((Supplier) () -> { + MockApiKeysServer.setResponse(TEST_NCA_ID, TEST_OWNER_ID, + List.of(), List.of()); + return "nvapi-stg-some-key"; + }, + Set.of(SecretDto.builder() + .name("secret1") + .value(new StringNode("value1")).build()), + ResultHandlingStrategy.UPLOAD, + HttpStatus.FORBIDDEN) + ); + + return Stream.concat(jwtCases, apiKeysCases); + } + + @ParameterizedTest + @MethodSource("updateSecretArgs") + void shouldUpdateForTasksWithSecrets( + Object tokenSupplier, + Set secrets, + ResultHandlingStrategy resultHandlingStrategy, + HttpStatus expectedStatus) { + var token = getToken(tokenSupplier); + // Create a task with a secret in TEST_NCA_ID + testTaskService.createTask(TEST_NCA_ID, TEST_TASK_ID_1, + TEST_ICMS_REQ_ID_1, resultHandlingStrategy); + essService.saveSecrets(TEST_TASK_ID_1, + Set.of(SecretDto.builder() + .name("test") + .value(new StringNode("value1")) + .build())); + + // Update task to indicate it has secrets + var taskEntity = taskService.fetchTask(TEST_TASK_ID_1); + taskEntity.setHasSecrets(true); + taskService.updateTask(taskEntity); + + // Update the task with new secrets + var updateRequestBody = UpdateSecretsRequest.builder() + .secrets(secrets) + .build(); + var url = URI.create("/v1/nvct/secrets/tasks/" + TEST_TASK_ID_1); + var updateRequestEntity = RequestEntity.put(url) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", "Bearer " + token) + .body(updateRequestBody); + var updateResponseEntity = testRestTemplate.exchange(updateRequestEntity, Void.class); + assertThat(updateResponseEntity.getStatusCode()).isEqualTo(expectedStatus); + if (expectedStatus.isError()) { + return; + } + + // Check new secrets are actually added + var newSecretDtos = essService.getSecrets(TEST_TASK_ID_1).orElse(null); + assertThat(newSecretDtos).isNotNull().containsAll(secrets); + } + + @Test + void shouldNotUpdateForTasksWithoutSecrets() { + var tokenSupplier = MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_UPDATE_SECRETS), + 100); + var token = getToken(tokenSupplier); + // Create a task without secrets in TEST_NCA_ID + testTaskService.createTask(TEST_NCA_ID, TEST_TASK_ID_1, + TEST_ICMS_REQ_ID_1, ResultHandlingStrategy.UPLOAD); + + // Check there are no secrets + var secretDtos = essService.getSecrets(TEST_TASK_ID_1).orElse(null); + assertThat(secretDtos).isNull(); + + // Update the task with new secrets + var secrets = Set.of(SecretDto.builder().name("test").value(new StringNode("value1")).build()); + var updateRequestBody = UpdateSecretsRequest.builder() + .secrets(secrets) + .build(); + var url = URI.create("/v1/nvct/secrets/tasks/" + TEST_TASK_ID_1); + var updateRequestEntity = RequestEntity.put(url) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", "Bearer " + token) + .body(updateRequestBody); + var updateResponseEntity = testRestTemplate.exchange(updateRequestEntity, Void.class); + assertThat(updateResponseEntity.getStatusCode()).isEqualTo(HttpStatus.BAD_REQUEST); + } + + Stream updateSecretTerminalStatusArgs() { + return Stream.of( + Arguments.of(ERRORED), + Arguments.of(CANCELED), + Arguments.of(COMPLETED), + Arguments.of(EXCEEDED_MAX_QUEUED_DURATION), + Arguments.of(EXCEEDED_MAX_RUNTIME_DURATION) + ); + } + + @ParameterizedTest + @MethodSource("updateSecretTerminalStatusArgs") + void shouldNotUpdateForTasksWithTerminalStatus(TaskStatus taskStatus) { + var tokenSupplier = MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_UPDATE_SECRETS), + 100); + var token = getToken(tokenSupplier); + // Create a task with secrets in TEST_NCA_ID and status set to terminal + testTaskService.createTask(TEST_NCA_ID, + TEST_TASK_ID_1, + TEST_ICMS_REQ_ID_1, + taskStatus); + essService.saveSecrets(TEST_TASK_ID_1, + Set.of(SecretDto.builder() + .name("test") + .value(new StringNode("value1")) + .build())); + + // Update task to indicate it has secrets + var taskEntity = taskService.fetchTask(TEST_TASK_ID_1); + taskEntity.setHasSecrets(true); + taskService.updateTask(taskEntity); + + // Update the task with new secrets + var secrets = Set.of(SecretDto.builder().name("test").value(new StringNode("value1")).build()); + var updateRequestBody = UpdateSecretsRequest.builder() + .secrets(secrets) + .build(); + var url = URI.create("/v1/nvct/secrets/tasks/" + TEST_TASK_ID_1); + var updateRequestEntity = RequestEntity.put(url) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", "Bearer " + token) + .body(updateRequestBody); + var updateResponseEntity = testRestTemplate.exchange(updateRequestEntity, Void.class); + assertThat(updateResponseEntity.getStatusCode()).isEqualTo(HttpStatus.BAD_REQUEST); + } + +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/secret/XAccountSecretManagementControllerTest.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/secret/XAccountSecretManagementControllerTest.java new file mode 100644 index 000000000..9f7c5f2c4 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/secret/XAccountSecretManagementControllerTest.java @@ -0,0 +1,407 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.rest.secret; + +import static com.nvidia.nvct.IntegrationTestConfiguration.MOCK_OAUTH2_TOKEN_SERVER; +import static com.nvidia.nvct.persistence.task.entity.TaskStatus.CANCELED; +import static com.nvidia.nvct.persistence.task.entity.TaskStatus.COMPLETED; +import static com.nvidia.nvct.persistence.task.entity.TaskStatus.ERRORED; +import static com.nvidia.nvct.persistence.task.entity.TaskStatus.EXCEEDED_MAX_QUEUED_DURATION; +import static com.nvidia.nvct.persistence.task.entity.TaskStatus.EXCEEDED_MAX_RUNTIME_DURATION; +import static com.nvidia.nvct.util.NvctConstants.ADMIN_SCOPE_UPDATE_SECRETS; +import static com.nvidia.nvct.util.NvctConstants.MAX_SECRET_NAME_LENGTH; +import static com.nvidia.nvct.util.NvctConstants.MAX_SECRET_VALUE_LENGTH; +import static com.nvidia.nvct.util.TestConstants.TEST_ADMIN_SUBJECT; +import static com.nvidia.nvct.util.TestConstants.TEST_NCA_ID; +import static com.nvidia.nvct.util.TestConstants.TEST_NCA_ID_2; +import static com.nvidia.nvct.util.TestConstants.TEST_ICMS_REQ_ID_1; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_ID_1; +import static com.nvidia.nvct.util.TestUtil.getToken; +import static org.assertj.core.api.Assertions.assertThat; + +import tools.jackson.databind.json.JsonMapper; +import tools.jackson.databind.node.StringNode; +import com.nvidia.boot.mock.ngc.MockCasServer; +import com.nvidia.nvct.IntegrationTestConfiguration; +import com.nvidia.nvct.NvctTestApp; +import com.nvidia.nvct.grpc.TestTaskService; +import com.nvidia.nvct.persistence.task.entity.ResultHandlingStrategy; +import com.nvidia.nvct.persistence.task.entity.TaskStatus; +import com.nvidia.nvct.rest.secret.dto.UpdateSecretsRequest; +import com.nvidia.nvct.rest.task.dto.SecretDto; +import com.nvidia.nvct.service.account.AccountService; +import com.nvidia.nvct.service.apikeys.ApiKeysService; +import com.nvidia.nvct.service.ess.EssService; +import com.nvidia.nvct.service.task.TaskService; +import com.nvidia.nvct.util.MockApiKeysServer; +import com.nvidia.nvct.util.MockEssServer; +import com.nvidia.nvct.util.MockNvcfServer; +import java.net.URI; +import java.net.URL; +import java.util.List; +import java.util.Set; +import java.util.stream.Stream; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.resttestclient.TestRestTemplate; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.RequestEntity; +import org.springframework.test.context.ContextConfiguration; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@Slf4j +@SpringBootTest( + classes = {NvctTestApp.class, IntegrationTestConfiguration.class}, + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + properties = "spring.profiles.active=test") +@ContextConfiguration(initializers = IntegrationTestConfiguration.Initializer.class) +@AutoConfigureTestRestTemplate +class XAccountSecretManagementControllerTest { + + @Autowired + private JsonMapper jsonMapper; + + @Autowired + private TestRestTemplate testRestTemplate; + + + @Autowired + private EssService essService; + + @Autowired + private TestTaskService testTaskService; + + @Autowired + private TaskService taskService; + + @Autowired + private AccountService accountService; + + @Autowired + private ApiKeysService apiKeysService; + + @Value("${nvct.registries.recognized.model.ngc.hostname}") + private String casBaseUrl; + + @Value("${nvct.registries.recognized.model.ngc.oauth2.base-url}") + private String authnBaseUrl; + + @Value("${nvct.ess.base-url}") + private String essBaseUrl; + + @Value("${nvct.nvcf.base-url}") + private URL nvcfBaseUrl; + + @Value("${nvct.api-keys.base-url}") + private String apiKeysBaseUrl; + + @BeforeAll + void beforeAll() { + log.info("{}: Started running tests", this.getClass().getSimpleName()); + + MockApiKeysServer.start(apiKeysBaseUrl); + MockEssServer.start(essBaseUrl); + MockNvcfServer.start(nvcfBaseUrl); + MockCasServer.start(authnBaseUrl, casBaseUrl); + } + + @AfterAll + void cleanup() { + MockApiKeysServer.stop(); + MockEssServer.stop(); + MockNvcfServer.stop(); + MockCasServer.stop(); + log.info("{}: Completed running tests", this.getClass().getSimpleName()); + } + + @AfterEach + void reset() { + MockApiKeysServer.resetToDefault(); + // use of MockApiKeysServer with different scopes causes the api-keys cache to dirty + apiKeysService.invalidateCache(); + accountService.invalidateCache(); + testTaskService.clearAll(); + MockEssServer.clearSecrets(); + } + + Stream updateSecretArgs() { + var secretJsonNodeValue = jsonMapper.createObjectNode() + .put("AWS_REGION", "us-west-2") + .put("AWS_BUCKET", "ov-content") + .put("AWS_ACCESS_KEY_ID", "ov-content-key-id") + .put("AWS_SECRET_ACCESS_KEY", "ov-content-access-key") + .put("AWS_SESSION_TOKEN", "ov-content-session-token"); + return Stream.of( + // no secrets with default resultHandlingStrategy + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_UPDATE_SECRETS), + 100), + TEST_NCA_ID, + null, + null, + HttpStatus.BAD_REQUEST), + // no secrets with resultHandlingStrategy UPLOAD + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_UPDATE_SECRETS), + 100), + TEST_NCA_ID, + null, + ResultHandlingStrategy.UPLOAD, + HttpStatus.BAD_REQUEST), + // update secret for task that belongs to a different account + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_UPDATE_SECRETS), + 100), + TEST_NCA_ID_2, + Set.of(SecretDto.builder().name("secret1").value(new StringNode("value1")).build()), + ResultHandlingStrategy.UPLOAD, + HttpStatus.NOT_FOUND), + // single secret + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_UPDATE_SECRETS), + 100), + TEST_NCA_ID, + Set.of(SecretDto.builder().name("secret1").value(new StringNode("value1")).build()), + ResultHandlingStrategy.UPLOAD, + HttpStatus.NO_CONTENT), + // duplicate secrets + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_UPDATE_SECRETS), + 100), + TEST_NCA_ID, + Set.of(SecretDto.builder().name("secret1").value(new StringNode("value1")).build(), + SecretDto.builder().name("secret1").value(new StringNode("value2")).build()), + ResultHandlingStrategy.UPLOAD, + HttpStatus.BAD_REQUEST), + // Secret name -- exactly MAX_SECRET_NAME_LENGTH in length + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_UPDATE_SECRETS), + 100), + TEST_NCA_ID, + Set.of(SecretDto.builder() + .name(StringUtils.repeat("x", MAX_SECRET_NAME_LENGTH)) + .value(new StringNode("value1")).build(), + SecretDto.builder().name("secret1").value(new StringNode("value2")).build()), + ResultHandlingStrategy.NONE, + HttpStatus.NO_CONTENT), + // secret names with periods, and hyphens + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_UPDATE_SECRETS), + 100), + TEST_NCA_ID, + Set.of(SecretDto.builder() + .name("omni.s3.us-west-2.amazonaws.com") + .value(new StringNode("value1")).build(), + SecretDto.builder() + .name("omni.s3.eu-north-1.amazonaws.com") + .value(new StringNode("value2")).build(), + SecretDto.builder() + .name("omni.s3.ap-northeast-1.amazonaws.com") + .value(secretJsonNodeValue).build()), + ResultHandlingStrategy.NONE, + HttpStatus.NO_CONTENT), + // secret names with underscores + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_UPDATE_SECRETS), + 100), + TEST_NCA_ID, + Set.of(SecretDto.builder() + .name("omni_s3_us-west-2_amazonaws_com") + .value(new StringNode("value1")).build(), + SecretDto.builder() + .name("omni_s3_eu-north-1_amazonaws_com") + .value(new StringNode("value2")).build(), + SecretDto.builder() + .name("omni.s3.ap-northeast-1.amazonaws.com") + .value(secretJsonNodeValue).build()), + ResultHandlingStrategy.NONE, + HttpStatus.NO_CONTENT), + // empty secret name + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_UPDATE_SECRETS), + 100), + TEST_NCA_ID, + Set.of(SecretDto.builder().name("").value(new StringNode("value1")).build()), + ResultHandlingStrategy.NONE, + HttpStatus.BAD_REQUEST), + // long secret name - exceeds MAX_SECRET_NAME_LENGTH char + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_UPDATE_SECRETS), + 100), + TEST_NCA_ID, + Set.of(SecretDto.builder() + .name(StringUtils.repeat("secret1", MAX_SECRET_NAME_LENGTH)) + .value(new StringNode("value1")).build()), + ResultHandlingStrategy.NONE, + HttpStatus.BAD_REQUEST), + // empty secret value + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_UPDATE_SECRETS), + 100), + TEST_NCA_ID, + Set.of(SecretDto.builder().name("secret1") + .value(new StringNode("")).build()), + ResultHandlingStrategy.NONE, + HttpStatus.BAD_REQUEST), + // long secret value + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_UPDATE_SECRETS), + 100), + TEST_NCA_ID, + Set.of(SecretDto.builder().name("secret1") + .value(new StringNode(StringUtils.repeat("value1", MAX_SECRET_VALUE_LENGTH))) + .build()), + ResultHandlingStrategy.NONE, + HttpStatus.BAD_REQUEST), + // bad secret name + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_UPDATE_SECRETS), + 100), + TEST_NCA_ID, + Set.of(SecretDto.builder().name("*secret1*-\"") + .value(new StringNode("value1")).build()), + ResultHandlingStrategy.NONE, + HttpStatus.BAD_REQUEST) + ); + } + + @ParameterizedTest + @MethodSource("updateSecretArgs") + void shouldUpdateForTasksWithSecrets( + Object tokenSupplier, + String ncaId, + Set secrets, + ResultHandlingStrategy resultHandlingStrategy, + HttpStatus expectedStatus) { + var token = getToken(tokenSupplier); + // Create a task with a secret in TEST_NCA_ID + testTaskService.createTask(TEST_NCA_ID, TEST_TASK_ID_1, + TEST_ICMS_REQ_ID_1, resultHandlingStrategy); + essService.saveSecrets(TEST_TASK_ID_1, + Set.of(SecretDto.builder().name("test").value(new StringNode("value1")).build())); + + // Update task to indicate it has secrets + var taskEntity = taskService.fetchTask(TEST_TASK_ID_1); + taskEntity.setHasSecrets(true); + taskService.updateTask(taskEntity); + + // Update the task with new secrets + var updateRequestBody = UpdateSecretsRequest.builder() + .secrets(secrets) + .build(); + var url = URI.create("/v1/nvct/accounts/" + ncaId + "/secrets/tasks/" + TEST_TASK_ID_1); + var updateRequestEntity = RequestEntity.put(url) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", "Bearer " + token) + .body(updateRequestBody); + var updateResponseEntity = testRestTemplate.exchange(updateRequestEntity, Void.class); + assertThat(updateResponseEntity.getStatusCode()).isEqualTo(expectedStatus); + if (expectedStatus.isError()) { + return; + } + + // Check new secrets are actually added + var newSecretDtos = essService.getSecrets(TEST_TASK_ID_1).orElse(null); + assertThat(newSecretDtos).isNotNull().containsAll(secrets); + } + + @Test + void shouldNotUpdateForTasksWithoutSecrets() { + var tokenSupplier = MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_UPDATE_SECRETS), + 100); + var token = getToken(tokenSupplier); + // Create a task without secrets in TEST_NCA_ID + testTaskService.createTask(TEST_NCA_ID, TEST_TASK_ID_1, + TEST_ICMS_REQ_ID_1, ResultHandlingStrategy.UPLOAD); + + // Check there are no secrets + var secretDtos = essService.getSecrets(TEST_TASK_ID_1).orElse(null); + assertThat(secretDtos).isNull(); + + // Update the task with new secrets + var secrets = Set.of(SecretDto.builder().name("test").value(new StringNode("value1")).build()); + var updateRequestBody = UpdateSecretsRequest.builder() + .secrets(secrets) + .build(); + var url = URI.create("/v1/nvct/accounts/" + TEST_NCA_ID + "/secrets/tasks/" + TEST_TASK_ID_1); + var updateRequestEntity = RequestEntity.put(url) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", "Bearer " + token) + .body(updateRequestBody); + var updateResponseEntity = testRestTemplate.exchange(updateRequestEntity, Void.class); + assertThat(updateResponseEntity.getStatusCode()).isEqualTo(HttpStatus.BAD_REQUEST); + } + + Stream updateSecretTerminalStatusArgs() { + return Stream.of( + Arguments.of(ERRORED), + Arguments.of(CANCELED), + Arguments.of(COMPLETED), + Arguments.of(EXCEEDED_MAX_QUEUED_DURATION), + Arguments.of(EXCEEDED_MAX_RUNTIME_DURATION) + ); + } + + @ParameterizedTest + @MethodSource("updateSecretTerminalStatusArgs") + void shouldNotUpdateForTasksWithTerminalStatus(TaskStatus taskStatus) { + var tokenSupplier = MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_UPDATE_SECRETS), + 100); + var token = getToken(tokenSupplier); + // Create a task with secrets in TEST_NCA_ID and status set to terminal + testTaskService.createTask(TEST_NCA_ID, + TEST_TASK_ID_1, + TEST_ICMS_REQ_ID_1, + taskStatus); + essService.saveSecrets(TEST_TASK_ID_1, + Set.of(SecretDto.builder().name("test").value(new StringNode("value1")).build())); + + // Update task to indicate it has secrets + var taskEntity = taskService.fetchTask(TEST_TASK_ID_1); + taskEntity.setHasSecrets(true); + taskService.updateTask(taskEntity); + + // Update the task with new secrets + var secrets = Set.of(SecretDto.builder().name("test").value(new StringNode("value1")).build()); + var updateRequestBody = UpdateSecretsRequest.builder() + .secrets(secrets) + .build(); + var url = URI.create("/v1/nvct/accounts/" + TEST_NCA_ID + "/secrets/tasks/" + TEST_TASK_ID_1); + var updateRequestEntity = RequestEntity.put(url) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", "Bearer " + token) + .body(updateRequestBody); + var updateResponseEntity = testRestTemplate.exchange(updateRequestEntity, Void.class); + assertThat(updateResponseEntity.getStatusCode()).isEqualTo(HttpStatus.BAD_REQUEST); + } + +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/FilterTaskTest.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/FilterTaskTest.java new file mode 100644 index 000000000..1065b4ad7 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/FilterTaskTest.java @@ -0,0 +1,348 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.rest.task; + +import static com.nvidia.nvct.IntegrationTestConfiguration.MOCK_OAUTH2_TOKEN_SERVER; +import static com.nvidia.nvct.persistence.task.entity.TaskStatus.QUEUED; +import static com.nvidia.nvct.persistence.task.entity.TaskStatus.RUNNING; +import static com.nvidia.nvct.util.NvctConstants.SCOPE_LIST_TASKS; +import static com.nvidia.nvct.util.TestConstants.TEST_CLIENT_ID; +import static com.nvidia.nvct.util.TestConstants.TEST_MODELS; +import static com.nvidia.nvct.util.TestConstants.TEST_NCA_ID; +import static com.nvidia.nvct.util.TestConstants.TEST_NCA_ID_2; +import static com.nvidia.nvct.util.TestConstants.TEST_RESOURCES; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_ID_1; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_ID_2; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_ID_3; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_ID_4; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_ID_5; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_NAME_1; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_NAME_2; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_NAME_3; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.fail; + +import tools.jackson.databind.json.JsonMapper; +import com.nvidia.boot.mock.ngc.MockCasServer; +import com.nvidia.nvct.IntegrationTestConfiguration; +import com.nvidia.nvct.NvctTestApp; +import com.nvidia.nvct.grpc.TestTaskService; +import com.nvidia.nvct.persistence.task.TasksRepository; +import com.nvidia.nvct.persistence.task.entity.TaskStatus; +import com.nvidia.nvct.rest.task.dto.ListTasksResponse; +import com.nvidia.nvct.rest.task.dto.TaskDto; +import com.nvidia.nvct.rest.task.dto.TaskStatusEnum; +import com.nvidia.nvct.service.task.TaskMapperService; +import com.nvidia.nvct.util.MockEssServer; +import com.nvidia.nvct.util.MockNvcfServer; +import com.nvidia.nvct.util.MockIcmsServer; +import com.nvidia.nvct.util.TestUtil; +import java.net.URI; +import java.net.URL; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.resttestclient.TestRestTemplate; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; +import org.springframework.http.HttpStatus; +import org.springframework.http.RequestEntity; +import org.springframework.test.context.ContextConfiguration; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@Slf4j +@SpringBootTest( + classes = {NvctTestApp.class, IntegrationTestConfiguration.class}, + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + properties = "spring.profiles.active=test") +@ContextConfiguration(initializers = IntegrationTestConfiguration.Initializer.class) +@AutoConfigureTestRestTemplate +class FilterTaskTest { + + @Autowired + private TestRestTemplate testRestTemplate; + + @Autowired + private TestTaskService testTaskService; + + @Autowired + private JsonMapper jsonMapper; + + @Autowired + private TasksRepository tasksRepository; + + @Autowired + private TaskMapperService taskMapperService; + + @Value("${nvct.ess.base-url}") + private String essBaseUrl; + + @Value("${nvct.registries.recognized.model.ngc.hostname}") + private String casBaseUrl; + + @Value("${nvct.registries.recognized.model.ngc.oauth2.base-url}") + private String authnBaseUrl; + + @Value("${nvct.nvcf.base-url}") + private URL nvcfBaseUrl; + + @Value("${nvct.icms.base-url}") + private URL icmsBaseUrl; + + + @BeforeAll + void beforeAll() { + log.info("{}: Started running tests", this.getClass().getSimpleName()); + MockEssServer.start(essBaseUrl); + MockNvcfServer.start(nvcfBaseUrl); + MockIcmsServer.start(icmsBaseUrl, jsonMapper); + MockCasServer.start(authnBaseUrl, casBaseUrl); + } + + @AfterAll + void cleanup() { + MockEssServer.stop(); + MockNvcfServer.stop(); + MockIcmsServer.stop(); + MockCasServer.stop(); + log.info("{}: Completed running tests", this.getClass().getSimpleName()); + } + + @AfterEach + void reset() { + testTaskService.clearAll(); + MockEssServer.clearSecrets(); + } + + @Test + void shouldListTasksWithStatus() { + var token = MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_ID, + List.of(SCOPE_LIST_TASKS), + 100); + var expectedTasks = List.of(TEST_TASK_ID_2, TEST_TASK_ID_3); + // Create Tasks in TEST_NCA_ID account tied to TEST_CLIENT_ID + var task1 = TestUtil.createContainerBasedTaskEntity(TEST_TASK_ID_1, TEST_NCA_ID, TEST_TASK_NAME_1, QUEUED, + jsonMapper); + var task2 = TestUtil.createContainerBasedTaskEntity(TEST_TASK_ID_2, TEST_NCA_ID, TEST_TASK_NAME_2, RUNNING, + jsonMapper); + var task3 = TestUtil.createContainerBasedTaskEntity(TEST_TASK_ID_3, TEST_NCA_ID, TEST_TASK_NAME_3, RUNNING, + jsonMapper); + // Create Tasks in TEST_NCA_ID_2 account to make sure there is no cross contamination query + var otherTask1 = TestUtil.createTaskEntity(TEST_TASK_ID_4, TEST_NCA_ID_2, TEST_TASK_NAME_1, + jsonMapper); + var otherTask2 = TestUtil.createTaskEntity(TEST_TASK_ID_5, TEST_NCA_ID_2, TEST_TASK_NAME_2, + jsonMapper); + + // Save tasks. + tasksRepository.save(task1); + tasksRepository.save(task2); + tasksRepository.save(task3); + tasksRepository.save(otherTask1); + tasksRepository.save(otherTask2); + + // get the all tasks with status RUNNING + var url = "/v1/nvct/tasks?status=RUNNING"; + var requestEntity = + RequestEntity.get(URI.create(url)) + .header("Authorization", "Bearer " + token) + .build(); + var responseEntity = + testRestTemplate.exchange(requestEntity, ListTasksResponse.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK); + var responseBody = responseEntity.getBody(); + assertThat(responseBody).isNotNull(); + var tasks = responseBody.tasks().stream() + .collect(Collectors.toMap(TaskDto::id, Function.identity())); + assertThat(tasks).hasSize(2); + verifyReturnedTasksIntegrity(expectedTasks, RUNNING, tasks); + } + + @Test + void shouldListTasksWithPaginationCursor() { + var token = MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_ID, + List.of(SCOPE_LIST_TASKS), + 100); + var expectedTasks = List.of(TEST_TASK_ID_1, TEST_TASK_ID_2, TEST_TASK_ID_3); + // Create Tasks in TEST_NCA_ID account tied to TEST_CLIENT_ID + var task1 = TestUtil.createTaskEntity(TEST_TASK_ID_1, TEST_NCA_ID, TEST_TASK_NAME_1, + jsonMapper); + var task2 = TestUtil.createTaskEntity(TEST_TASK_ID_2, TEST_NCA_ID, TEST_TASK_NAME_2, + jsonMapper); + var task3 = TestUtil.createTaskEntity(TEST_TASK_ID_3, TEST_NCA_ID, TEST_TASK_NAME_3, + jsonMapper); + // Create Tasks in TEST_NCA_ID_2 account to make sure there is no cross contamination query + var otherTask1 = TestUtil.createTaskEntity(TEST_TASK_ID_4, TEST_NCA_ID_2, TEST_TASK_NAME_1, + jsonMapper); + var otherTask2 = TestUtil.createTaskEntity(TEST_TASK_ID_5, TEST_NCA_ID_2, TEST_TASK_NAME_2, + jsonMapper); + + // Save tasks. + tasksRepository.save(task1); + tasksRepository.save(task2); + tasksRepository.save(task3); + tasksRepository.save(otherTask1); + tasksRepository.save(otherTask2); + + // get the first 2 out of 3 tasks first + var url = "/v1/nvct/tasks?limit=2"; + var requestEntity = + RequestEntity.get(URI.create(url)) + .header("Authorization", "Bearer " + token) + .build(); + var responseEntity = + testRestTemplate.exchange(requestEntity, ListTasksResponse.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK); + var responseBody = responseEntity.getBody(); + assertThat(responseBody).isNotNull(); + var currentCursor = responseBody.cursor(); + assertThat(currentCursor).isNotNull(); + var firstPageTasks = responseBody.tasks().stream() + .collect(Collectors.toMap(TaskDto::id, Function.identity())); + assertThat(firstPageTasks).hasSize(2); + assertThat(responseBody.limit()).isEqualTo(2); + // using the cursor from previous response, continue to listing the rest of the tasks + url = "/v1/nvct/tasks?limit=2&cursor=" + currentCursor; + requestEntity = + RequestEntity.get(URI.create(url)) + .header("Authorization", "Bearer " + token) + .build(); + responseEntity = + testRestTemplate.exchange(requestEntity, ListTasksResponse.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK); + + // make sure the last task is correct + responseBody = responseEntity.getBody(); + assertThat(responseBody).isNotNull(); + currentCursor = responseBody.cursor(); + assertThat(currentCursor).isNull(); + assertThat(responseBody.limit()).isNull(); + var secondPageTask = responseBody.tasks().stream() + .collect(Collectors.toMap(TaskDto::id, Function.identity())); + assertThat(secondPageTask).hasSize(1); + + // make sure all 3 tasks have the right metadata + var tasks = new HashMap(); + tasks.putAll(firstPageTasks); + tasks.putAll(secondPageTask); + verifyReturnedTasksIntegrity(expectedTasks, QUEUED, tasks); + } + + Stream listTasksWithPaginationLimitArgs() { + return Stream.of( + // List tasks in TEST_NCA_ID account with 1 limit + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_ID, + List.of(SCOPE_LIST_TASKS), + 100), + List.of(TEST_TASK_ID_2), + 1, + HttpStatus.OK), + + // List tasks in TEST_NCA_ID account with 100 limit + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_ID, + List.of(SCOPE_LIST_TASKS), + 100), + List.of(TEST_TASK_ID_1, TEST_TASK_ID_2), + 100, + HttpStatus.OK)); + + } + + @ParameterizedTest + @MethodSource("listTasksWithPaginationLimitArgs") + void shouldListTasksWithPaginationLimit( + String token, List expectedTasks, int limit, HttpStatus expectedStatus) { + // Create Tasks in TEST_NCA_ID account tied to TEST_CLIENT_ID. + var task1 = TestUtil.createTaskEntity(TEST_TASK_ID_1, TEST_NCA_ID, TEST_TASK_NAME_1, + jsonMapper); + var task2 = TestUtil.createTaskEntity(TEST_TASK_ID_2, TEST_NCA_ID, TEST_TASK_NAME_2, + jsonMapper); + + // Save tasks. + tasksRepository.save(task1); + tasksRepository.save(task2); + + var requestEntity = + RequestEntity.get(URI.create("/v1/nvct/tasks?limit=" + limit)) + .header("Authorization", "Bearer " + token) + .build(); + var responseEntity = + testRestTemplate.exchange(requestEntity, ListTasksResponse.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(expectedStatus); + if (expectedStatus.isError()) { + return; + } + + var responseBody = responseEntity.getBody(); + assertThat(responseBody).isNotNull(); + if (limit == 1) { + assertThat(responseBody.cursor()).isNotNull(); + assertThat(responseBody.tasks()).hasSize(1); + assertThat(responseBody.limit()).isEqualTo(limit); + } else if (limit > 2) { + assertThat(responseBody.cursor()).isNull(); + assertThat(responseBody.tasks()).hasSize(2); + assertThat(responseBody.limit()).isNull(); + } + var tasks = responseBody.tasks().stream() + .collect(Collectors.toMap(TaskDto::id, Function.identity())); + verifyReturnedTasksIntegrity(expectedTasks, QUEUED, tasks); + } + + void verifyReturnedTasksIntegrity(List expectedTasks, TaskStatus expectedStatus, Map tasks) { + for (UUID expectedTaskId : expectedTasks) { + var taskDto = tasks.get(expectedTaskId); + assertThat(taskDto).isNotNull(); + assertThat(taskDto.createdAt()).isNotNull(); + assertThat(taskDto.status()).isEqualTo(TaskStatusEnum.fromText(expectedStatus.toString())); + assertThat(taskDto.containerImage()).isNotNull(); + assertThat(taskDto.containerArgs()).isNotBlank(); + assertThat(taskDto.containerEnvironment()).hasSize(3); + if (taskDto.id().equals(TEST_TASK_ID_1)) { + assertThat(taskDto.name()).isEqualTo(TEST_TASK_NAME_1); + } else if (taskDto.id().equals(TEST_TASK_ID_2)) { + assertThat(taskDto.name()).isEqualTo(TEST_TASK_NAME_2); + } else if (taskDto.id().equals(TEST_TASK_ID_3)) { + assertThat(taskDto.name()).isEqualTo(TEST_TASK_NAME_3); + } else { + fail("unknown function returned"); + } + assertThat(taskDto.description()).isNotEmpty(); + assertThat(taskDto.tags()).isNotEmpty(); + assertThat(taskDto.gpuSpecification()).isNotNull(); + assertThat(taskDto.models()) + .isEqualTo(taskMapperService.getModelDtos(TEST_MODELS).get()); + assertThat(taskDto.resources()) + .isEqualTo(taskMapperService.getResourceDtos(TEST_RESOURCES).get()); + } + } + +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/HelmChartBasedTaskCreationTest.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/HelmChartBasedTaskCreationTest.java new file mode 100644 index 000000000..4879cf64c --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/HelmChartBasedTaskCreationTest.java @@ -0,0 +1,444 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.rest.task; + +import static com.nvidia.nvct.IntegrationTestConfiguration.MOCK_OAUTH2_TOKEN_SERVER; +import static com.nvidia.nvct.util.NvctConstants.SCOPE_LAUNCH_TASK; +import static com.nvidia.nvct.util.NvctConstants.SCOPE_LIST_TASKS; +import static com.nvidia.nvct.util.NvctConstants.SCOPE_TASK_DETAILS; +import static com.nvidia.nvct.util.TestConstants.L40G; +import static com.nvidia.nvct.util.TestConstants.OCI; +import static com.nvidia.nvct.util.TestConstants.OCI_L40G_INSTANCE_TYPE; +import static com.nvidia.nvct.util.TestConstants.TEST_CLIENT_SUBJECT; +import static com.nvidia.nvct.util.TestConstants.TEST_CONTAINER_ARGS; +import static com.nvidia.nvct.util.TestConstants.TEST_CONTAINER_ENVIRONMENT; +import static com.nvidia.nvct.util.TestConstants.TEST_CONTAINER_IMAGE; +import static com.nvidia.nvct.util.TestConstants.TEST_DESCRIPTION; +import static com.nvidia.nvct.util.TestConstants.TEST_HELM_CHART; +import static com.nvidia.nvct.util.TestConstants.TEST_HELM_CHART_NOT_EXISTS; +import static com.nvidia.nvct.util.TestConstants.TEST_HELM_CHART_NOT_SUPPORTED_REGISTRY; +import static com.nvidia.nvct.util.TestConstants.TEST_HELM_CHART_PERMISSION_DENIED; +import static com.nvidia.nvct.util.TestConstants.TEST_HELM_CHART_UNKNOWN_REGISTRY; +import static com.nvidia.nvct.util.TestConstants.TEST_HELM_CHART_WITH_CANARY_HOST; +import static com.nvidia.nvct.util.TestConstants.TEST_HELM_VALIDATION_POLICY_DTO; +import static com.nvidia.nvct.util.TestConstants.TEST_NCA_ID; +import static com.nvidia.nvct.util.TestConstants.TEST_OCI_GPU_SPEC_HELM_CONFIG_DTO; +import static com.nvidia.nvct.util.TestConstants.TEST_OCI_GPU_SPEC_WITH_HELM_POLICY_DTO; +import static com.nvidia.nvct.util.TestConstants.TEST_RESULTS_LOCATION_1; +import static com.nvidia.nvct.util.TestConstants.TEST_RESULTS_LOCATION_2; +import static com.nvidia.nvct.util.TestConstants.TEST_SECRETS; +import static com.nvidia.nvct.util.TestConstants.TEST_TAGS; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_NAME_1; +import static org.assertj.core.api.Assertions.assertThat; + +import tools.jackson.databind.json.JsonMapper; +import com.nvidia.boot.mock.ngc.MockCasServer; +import com.nvidia.boot.mock.ngc.MockNgcContainerRegistryServer; +import com.nvidia.nvct.IntegrationTestConfiguration; +import com.nvidia.nvct.NvctTestApp; +import com.nvidia.nvct.grpc.TestTaskService; +import com.nvidia.nvct.rest.task.dto.CreateTaskRequest; +import com.nvidia.nvct.rest.task.dto.GpuSpecificationDto; +import com.nvidia.nvct.rest.task.dto.ResultHandlingStrategyEnum; +import com.nvidia.nvct.rest.task.dto.TaskResponse; +import com.nvidia.nvct.rest.task.dto.TaskStatusEnum; +import com.nvidia.nvct.service.account.AccountService; +import com.nvidia.nvct.util.MockEssServer; +import com.nvidia.nvct.util.MockNotaryServer; +import com.nvidia.nvct.util.MockNvcfServer; +import com.nvidia.nvct.util.MockRevalServer; +import com.nvidia.nvct.util.MockIcmsServer; +import java.net.URI; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.time.Duration; +import java.util.Base64; +import java.util.List; +import java.util.stream.Stream; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.resttestclient.TestRestTemplate; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.RequestEntity; +import org.springframework.test.context.ContextConfiguration; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@Slf4j +@SpringBootTest( + classes = {NvctTestApp.class, IntegrationTestConfiguration.class}, + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + properties = "spring.profiles.active=test") +@ContextConfiguration(initializers = IntegrationTestConfiguration.Initializer.class) +@AutoConfigureTestRestTemplate +class HelmChartBasedTaskCreationTest { + + @Autowired + private TestRestTemplate testRestTemplate; + + + @Autowired + private AccountService accountService; + + @Autowired + private JsonMapper jsonMapper; + + @Autowired + private TestTaskService testTaskService; + + @Value("${nvct.registries.recognized.model.ngc.hostname}") + private String casBaseUrl; + + @Value("${nvct.registries.recognized.model.ngc.oauth2.base-url}") + private String authnBaseUrl; + + @Value("${nvct.ess.base-url}") + private String essBaseUrl; + + @Value("${nvct.notary.base-url}") + private String notaryBaseUrl; + + @Value("${spring.security.oauth2.client.registration.notary.client-id}") + private String notaryClientId; + + @Value("${nvct.reval.base-url}") + private URI revalBaseUrl; + + @Value("${nvct.nvcf.base-url}") + private URL nvcfBaseUrl; + + @Value("${nvct.icms.base-url}") + private URL icmsBaseUrl; + + @Value("${nvct.registries.recognized.container.ngc.hostname}") + private String ngcContainerRegistryHostname; + + @BeforeAll + void beforeAll() { + log.info("{}: Started running tests", this.getClass().getSimpleName()); + MockNvcfServer.start(nvcfBaseUrl); + MockIcmsServer.start(icmsBaseUrl, jsonMapper); + MockCasServer.start(authnBaseUrl, casBaseUrl); + MockEssServer.start(essBaseUrl); + MockNotaryServer.start(notaryBaseUrl, notaryClientId); + MockRevalServer.start(revalBaseUrl); + MockNgcContainerRegistryServer.start(ngcContainerRegistryHostname); + } + + @AfterAll + void cleanup() { + MockNvcfServer.stop(); + MockIcmsServer.stop(); + MockCasServer.stop(); + MockEssServer.stop(); + MockNotaryServer.stop(); + MockRevalServer.stop(); + MockNgcContainerRegistryServer.stop(); + log.info("{}: Completed running tests", this.getClass().getSimpleName()); + } + + @AfterEach + void reset() { + accountService.invalidateCache(); + testTaskService.clearAll(); + } + + Stream helmBasedTaskArgs() { + return Stream.of( + Arguments.of(null, + null, + null, + TEST_HELM_CHART, + HttpStatus.OK), + Arguments.of(TEST_CONTAINER_IMAGE, + TEST_CONTAINER_ARGS, + TEST_CONTAINER_ENVIRONMENT, + null, + HttpStatus.BAD_REQUEST), + Arguments.of(TEST_CONTAINER_IMAGE, + null, + null, + null, + HttpStatus.BAD_REQUEST), + Arguments.of(null, + TEST_CONTAINER_ARGS, + null, + null, + HttpStatus.BAD_REQUEST), + Arguments.of(null, + null, + TEST_CONTAINER_ENVIRONMENT, + null, + HttpStatus.BAD_REQUEST), + Arguments.of(TEST_CONTAINER_IMAGE, + null, + null, + TEST_HELM_CHART, + HttpStatus.BAD_REQUEST), + Arguments.of(null, + TEST_CONTAINER_ARGS, + null, + TEST_HELM_CHART, + HttpStatus.BAD_REQUEST), + Arguments.of(null, + null, + TEST_CONTAINER_ENVIRONMENT, + TEST_HELM_CHART, + HttpStatus.BAD_REQUEST), + Arguments.of(null, + null, + null, + TEST_HELM_CHART_NOT_EXISTS, + HttpStatus.NOT_FOUND), + Arguments.of(null, + null, + null, + TEST_HELM_CHART_PERMISSION_DENIED, + HttpStatus.FORBIDDEN), + Arguments.of(null, + null, + null, + TEST_HELM_CHART_UNKNOWN_REGISTRY, + HttpStatus.BAD_REQUEST), + Arguments.of(null, + null, + null, + TEST_HELM_CHART_NOT_SUPPORTED_REGISTRY, + HttpStatus.BAD_REQUEST), + Arguments.of(null, + null, + null, + TEST_HELM_CHART_WITH_CANARY_HOST, + HttpStatus.OK) + ); + } + + @ParameterizedTest + @MethodSource("helmBasedTaskArgs") + void shouldLaunchHelmChartBasedTasks( + URI containerImage, + String containerArgs, + List containerEnvironment, + URI helmChart, + HttpStatus expectedStatus) { + var token = MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100); + var requestBodyBuilder = CreateTaskRequest.builder() + .name(TEST_TASK_NAME_1) + .containerArgs(containerArgs) + .helmChart(helmChart) + .containerImage(containerImage) + .tags(TEST_TAGS) + .gpuSpecification(TEST_OCI_GPU_SPEC_HELM_CONFIG_DTO) + .maxRuntimeDuration(Duration.ofHours(2)) + .maxQueuedDuration(Duration.ofHours(1)) + .terminationGracePeriodDuration(Duration.ofHours(1)) + .description(TEST_DESCRIPTION) + .resultsLocation(TEST_RESULTS_LOCATION_1) + .resultHandlingStrategy(ResultHandlingStrategyEnum.UPLOAD) + .secrets(TEST_SECRETS) + .containerEnvironment(containerEnvironment); + var requestEntity = RequestEntity.post(URI.create("/v1/nvct/tasks")) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", "Bearer " + token) + .body(requestBodyBuilder.build()); + var responseEntity = + testRestTemplate.exchange(requestEntity, TaskResponse.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(expectedStatus); + if (expectedStatus.isError()) { + return; + } + + var responseBody = responseEntity.getBody(); + assertThat(responseBody).isNotNull(); + assertThat(responseBody.task().id()).isNotNull(); + assertThat(responseBody.task().name()).isEqualTo(TEST_TASK_NAME_1); + assertThat(responseBody.task().status()).isEqualTo(TaskStatusEnum.QUEUED); + assertThat(responseBody.task().ncaId()).isEqualTo(TEST_NCA_ID); + assertThat(responseBody.task().containerArgs()).isEqualTo(containerArgs); + assertThat(responseBody.task().containerEnvironment()).isEqualTo(containerEnvironment); + assertThat(responseBody.task().createdAt()).isNotNull(); + assertThat(responseBody.task().gpuSpecification()).isEqualTo( + TEST_OCI_GPU_SPEC_HELM_CONFIG_DTO); + assertThat(responseBody.task().containerImage()).isEqualTo(containerImage); + assertThat(responseBody.task().helmChart()).isEqualTo(helmChart); + } + + @Test + void shouldFailToLaunchHelmChartBasedTask() { + var token = MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100); + // MockRevalServer is setup report validation failure when this configuration is used. + var configuration = jsonMapper.createObjectNode() + .put("serviceAccountName", "nvct") + .put("fail", "fail"); + var gpuSpec = GpuSpecificationDto.builder().gpu(L40G).instanceType(OCI_L40G_INSTANCE_TYPE) + .backend(OCI).configuration(configuration).build(); + var requestBodyBuilder = CreateTaskRequest.builder() + .name(TEST_TASK_NAME_1) + .containerArgs(TEST_CONTAINER_ARGS) + .helmChart(TEST_HELM_CHART) + .tags(TEST_TAGS) + .gpuSpecification(gpuSpec) + .maxRuntimeDuration(Duration.ofHours(2)) + .maxQueuedDuration(Duration.ofHours(1)) + .terminationGracePeriodDuration(Duration.ofHours(1)) + .description(TEST_DESCRIPTION) + .resultsLocation(TEST_RESULTS_LOCATION_1) + .resultHandlingStrategy(ResultHandlingStrategyEnum.UPLOAD) + .secrets(TEST_SECRETS) + .containerEnvironment(TEST_CONTAINER_ENVIRONMENT); + var requestEntity = RequestEntity.post(URI.create("/v1/nvct/tasks")) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", "Bearer " + token) + .body(requestBodyBuilder.build()); + var responseEntity = + testRestTemplate.exchange(requestEntity, TaskResponse.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.BAD_REQUEST); + } + + Stream invalidHelmChartUriArgs() { + return Stream.of( + Arguments.of(URI.create("ftp://registry.example.com/chart.tgz")), + Arguments.of(URI.create("file:///path/to/chart.tgz")), + Arguments.of(URI.create("ldap://registry.example.com/chart")), + Arguments.of(URI.create("ssh://registry.example.com/chart.tgz")), + Arguments.of(URI.create( + "helm.stg.ngc.nvidia.com/test-org/charts/test-chart-1.0.0.tgz")), + Arguments.of(URI.create( + "123456789000.dkr.ecr.us-west-2.amazonaws.com/test-repo/test-chart:1.0.0")) + ); + } + + @Test + void shouldStoreAndReturnHelmValidationPolicy() { + var token = MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS, + SCOPE_TASK_DETAILS), + 100); + var createRequest = CreateTaskRequest.builder() + .name(TEST_TASK_NAME_1) + .helmChart(TEST_HELM_CHART) + .gpuSpecification(TEST_OCI_GPU_SPEC_WITH_HELM_POLICY_DTO) + .maxRuntimeDuration(Duration.ofHours(2)) + .maxQueuedDuration(Duration.ofHours(1)) + .terminationGracePeriodDuration(Duration.ofHours(1)) + .description(TEST_DESCRIPTION) + .resultsLocation(TEST_RESULTS_LOCATION_1) + .resultHandlingStrategy(ResultHandlingStrategyEnum.UPLOAD) + .secrets(TEST_SECRETS) + .build(); + var createEntity = RequestEntity.post(URI.create("/v1/nvct/tasks")) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", "Bearer " + token) + .body(createRequest); + var createResponse = testRestTemplate.exchange(createEntity, TaskResponse.class); + + assertThat(createResponse.getStatusCode()).isEqualTo(HttpStatus.OK); + var created = createResponse.getBody(); + assertThat(created).isNotNull(); + assertThat(created.task().gpuSpecification()).isEqualTo(TEST_OCI_GPU_SPEC_WITH_HELM_POLICY_DTO); + + var taskId = created.task().id(); + var getEntity = RequestEntity.get(URI.create("/v1/nvct/tasks/" + taskId)) + .header("Authorization", "Bearer " + token) + .build(); + var getResponse = testRestTemplate.exchange(getEntity, TaskResponse.class); + + assertThat(getResponse.getStatusCode()).isEqualTo(HttpStatus.OK); + var retrieved = getResponse.getBody(); + assertThat(retrieved).isNotNull(); + var retrievedSpec = retrieved.task().gpuSpecification(); + assertThat(retrievedSpec.gpu()).isEqualTo(TEST_OCI_GPU_SPEC_WITH_HELM_POLICY_DTO.gpu()); + assertThat(retrievedSpec.backend()).isEqualTo(TEST_OCI_GPU_SPEC_WITH_HELM_POLICY_DTO.backend()); + assertThat(retrievedSpec.instanceType()) + .isEqualTo(TEST_OCI_GPU_SPEC_WITH_HELM_POLICY_DTO.instanceType()); + assertThat(retrievedSpec.helmValidationPolicy()) + .isEqualTo(TEST_OCI_GPU_SPEC_WITH_HELM_POLICY_DTO.helmValidationPolicy()); + } + + @Test + @lombok.SneakyThrows + void shouldSendHelmValidationPolicyToIcms() { + var token = MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100); + var createRequest = CreateTaskRequest.builder() + .name(TEST_TASK_NAME_1) + .helmChart(TEST_HELM_CHART) + .gpuSpecification(TEST_OCI_GPU_SPEC_WITH_HELM_POLICY_DTO) + .maxRuntimeDuration(Duration.ofHours(2)) + .maxQueuedDuration(Duration.ofHours(1)) + .terminationGracePeriodDuration(Duration.ofHours(1)) + .description(TEST_DESCRIPTION) + .resultsLocation(TEST_RESULTS_LOCATION_1) + .resultHandlingStrategy(ResultHandlingStrategyEnum.UPLOAD) + .secrets(TEST_SECRETS) + .build(); + var createEntity = RequestEntity.post(URI.create("/v1/nvct/tasks")) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", "Bearer " + token) + .body(createRequest); + var createResponse = testRestTemplate.exchange(createEntity, TaskResponse.class); + + assertThat(createResponse.getStatusCode()).isEqualTo(HttpStatus.OK); + + var expectedPolicyJson = jsonMapper.writeValueAsString(TEST_HELM_VALIDATION_POLICY_DTO); + var policyRaw = MockIcmsServer.getCapturedHelmValidationPolicy(); + var policy = new String(Base64.getDecoder().decode(policyRaw), StandardCharsets.UTF_8); + assertThat(policy).isEqualTo(expectedPolicyJson); + } + + @ParameterizedTest + @MethodSource("invalidHelmChartUriArgs") + void shouldFailWithInvalidHelmChartUri(URI helmChartUri) { + var token = MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100); + var requestBodyBuilder = CreateTaskRequest.builder() + .name(TEST_TASK_NAME_1) + .helmChart(helmChartUri) + .tags(TEST_TAGS) + .gpuSpecification(TEST_OCI_GPU_SPEC_HELM_CONFIG_DTO) + .maxRuntimeDuration(Duration.ofHours(2)) + .maxQueuedDuration(Duration.ofHours(1)) + .terminationGracePeriodDuration(Duration.ofHours(1)) + .description(TEST_DESCRIPTION) + .resultHandlingStrategy(ResultHandlingStrategyEnum.UPLOAD) + .resultsLocation(TEST_RESULTS_LOCATION_2) + .secrets(TEST_SECRETS); + var requestEntity = RequestEntity.post(URI.create("/v1/nvct/tasks")) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", "Bearer " + token) + .body(requestBodyBuilder.build()); + var responseEntity = testRestTemplate.exchange(requestEntity, TaskResponse.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.BAD_REQUEST); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/ListTasksWithBasicDetailsTest.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/ListTasksWithBasicDetailsTest.java new file mode 100644 index 000000000..009b8db7e --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/ListTasksWithBasicDetailsTest.java @@ -0,0 +1,181 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.rest.task; + +import static com.nvidia.nvct.IntegrationTestConfiguration.MOCK_OAUTH2_TOKEN_SERVER; +import static com.nvidia.nvct.persistence.task.entity.TaskStatus.QUEUED; +import static com.nvidia.nvct.persistence.task.entity.TaskStatus.RUNNING; +import static com.nvidia.nvct.util.NvctConstants.SCOPE_LIST_TASKS; +import static com.nvidia.nvct.util.TestConstants.TEST_CLIENT_ID; +import static com.nvidia.nvct.util.TestConstants.TEST_ICMS_REQ_ID_1; +import static com.nvidia.nvct.util.TestConstants.TEST_ICMS_REQ_ID_2; +import static com.nvidia.nvct.util.TestConstants.TEST_NCA_ID; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_ID_1; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_ID_2; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_ID_3; +import static org.assertj.core.api.Assertions.assertThat; + +import com.nvidia.nvct.IntegrationTestConfiguration; +import com.nvidia.nvct.NvctTestApp; +import com.nvidia.nvct.grpc.TestTaskService; +import com.nvidia.nvct.persistence.task.TasksRepository; +import com.nvidia.nvct.rest.task.dto.BasicTaskDto; +import com.nvidia.nvct.rest.task.dto.BulkTaskDetailsRequest; +import com.nvidia.nvct.rest.task.dto.ListBasicTaskDetailsResponse; +import com.nvidia.nvct.service.account.AccountService; +import com.nvidia.nvct.util.MockNvcfServer; +import java.net.URI; +import java.net.URL; +import java.util.List; +import java.util.Set; +import java.util.UUID; +import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.resttestclient.TestRestTemplate; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.HttpStatus; +import org.springframework.http.RequestEntity; +import org.springframework.test.context.ContextConfiguration; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@Slf4j +@SpringBootTest( + classes = {NvctTestApp.class, IntegrationTestConfiguration.class}, + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + properties = "spring.profiles.active=test") +@ContextConfiguration(initializers = IntegrationTestConfiguration.Initializer.class) +@AutoConfigureTestRestTemplate +class ListTasksWithBasicDetailsTest { + @Autowired + private TestRestTemplate testRestTemplate; + + @Autowired + private AccountService accountService; + + @Autowired + private TestTaskService testTaskService; + + @Autowired + private TasksRepository tasksRepository; + + @Value("${nvct.nvcf.base-url}") + private URL nvcfBaseUrl; + + @BeforeAll + void beforeAll() { + log.info("{}: Started running tests", this.getClass().getSimpleName()); + MockNvcfServer.start(nvcfBaseUrl); + + // Create Tasks in TEST_NCA_ID account tied to TEST_CLIENT_ID. + testTaskService.createTask(TEST_NCA_ID, TEST_TASK_ID_1, TEST_ICMS_REQ_ID_1, QUEUED); + testTaskService.createTask(TEST_NCA_ID, TEST_TASK_ID_2, TEST_ICMS_REQ_ID_2, RUNNING); + } + + @AfterAll + void cleanup() { + MockNvcfServer.stop(); + log.info("{}: Completed running tests", this.getClass().getSimpleName()); + } + + @AfterEach + void reset() { + accountService.invalidateCache(); + testTaskService.clearAll(); + } + + Stream listTasksWithBasicDetailsArgs() { + return Stream.of( + // List tasks with basic details in TEST_NCA_ID account + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_ID, + List.of(SCOPE_LIST_TASKS), + 100), + Set.of(TEST_TASK_ID_1, TEST_TASK_ID_2), + HttpStatus.OK), + // Empty set of taskIds + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_ID, + List.of(SCOPE_LIST_TASKS), + 100), + Set.of(), + HttpStatus.BAD_REQUEST), + // List basic details for a non-existent TEST_TASK_ID_3 in TEST_NCA_ID account + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_ID, + List.of(SCOPE_LIST_TASKS), + 100), + Set.of(TEST_TASK_ID_1, TEST_TASK_ID_3), + HttpStatus.NOT_FOUND), + // Unknown client listing tasks in an unknown account + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt("unknown-client-id", + List.of(SCOPE_LIST_TASKS), + 100), + Set.of(TEST_TASK_ID_1, TEST_TASK_ID_2), + HttpStatus.NOT_FOUND), + // Missing scope. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_ID, List.of(), 100), + Set.of(TEST_TASK_ID_1, TEST_TASK_ID_2), + HttpStatus.FORBIDDEN), + // Missing token. + Arguments.of(null, + Set.of(TEST_TASK_ID_1, TEST_TASK_ID_2), + HttpStatus.UNAUTHORIZED) + ); + } + + @ParameterizedTest + @MethodSource("listTasksWithBasicDetailsArgs") + void shouldListTasksWithBasicDetails(String token, + Set expectedTaskIds, + HttpStatus expectedStatus) { + var requestBody = BulkTaskDetailsRequest.builder().taskIds(expectedTaskIds).build(); + var requestEntity = + RequestEntity.post(URI.create("/v1/nvct/tasks/bulk")) + .header("Authorization", "Bearer " + token) + .body(requestBody); + var responseEntity = + testRestTemplate.exchange(requestEntity, ListBasicTaskDetailsResponse.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(expectedStatus); + if (expectedStatus.isError()) { + return; + } + + var responseBody = responseEntity.getBody(); + assertThat(responseBody).isNotNull(); + assertThat(responseBody.tasks()).isNotNull().isNotEmpty(); + assertThat(responseBody.tasks()).hasSize(expectedTaskIds.size()); + var tasks = responseBody.tasks().stream() + .collect(Collectors.toMap(BasicTaskDto::id, Function.identity())); + assertThat(tasks.keySet()).containsExactlyInAnyOrderElementsOf(expectedTaskIds); + var dtos = responseBody.tasks(); + dtos.forEach(dto -> { + assertThat(dto.id()).isIn(expectedTaskIds); + assertThat(dto.name()).isNotBlank(); + assertThat(dto.status()).isNotNull(); + }); + assertThat(responseBody.ncaId()).isEqualTo(TEST_NCA_ID); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/TaskCreationWithAcrRegistryTest.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/TaskCreationWithAcrRegistryTest.java new file mode 100644 index 000000000..6e22ad017 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/TaskCreationWithAcrRegistryTest.java @@ -0,0 +1,282 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.rest.task; + +import static com.nvidia.boot.mock.BootTestConstants.TEST_ACR_CONTAINER_IMAGE_NOT_EXISTS; +import static com.nvidia.boot.mock.BootTestConstants.TEST_ACR_CONTAINER_IMAGE_PERMISSION_DENIED; +import static com.nvidia.boot.mock.BootTestConstants.TEST_ACR_CONTAINER_IMAGE_WITH_DIGEST; +import static com.nvidia.boot.mock.BootTestConstants.TEST_ACR_CONTAINER_IMAGE_WITH_TAG; +import static com.nvidia.boot.mock.BootTestConstants.TEST_ACR_HELM_CHART_NOT_EXISTS; +import static com.nvidia.boot.mock.BootTestConstants.TEST_ACR_HELM_CHART_PERMISSION_DENIED; +import static com.nvidia.boot.mock.BootTestConstants.TEST_ACR_HELM_CHART_WITH_DIGEST; +import static com.nvidia.boot.mock.BootTestConstants.TEST_ACR_HELM_CHART_WITH_TAG; +import static com.nvidia.nvct.IntegrationTestConfiguration.MOCK_OAUTH2_TOKEN_SERVER; +import static com.nvidia.nvct.util.NvctConstants.SCOPE_LAUNCH_TASK; +import static com.nvidia.nvct.util.NvctConstants.SCOPE_LIST_TASKS; +import static com.nvidia.nvct.util.TestConstants.TEST_CLIENT_SUBJECT; +import static com.nvidia.nvct.util.TestConstants.TEST_CONTAINER_ARGS; +import static com.nvidia.nvct.util.TestConstants.TEST_DESCRIPTION; +import static com.nvidia.nvct.util.TestConstants.TEST_NCA_ID; +import static com.nvidia.nvct.util.TestConstants.TEST_OCI_GPU_SPEC_DTO; +import static com.nvidia.nvct.util.TestConstants.TEST_OCI_GPU_SPEC_HELM_CONFIG_DTO; +import static com.nvidia.nvct.util.TestConstants.TEST_RESULTS_LOCATION_2; +import static com.nvidia.nvct.util.TestConstants.TEST_SECRETS; +import static com.nvidia.nvct.util.TestConstants.TEST_TAGS; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_NAME_1; +import static org.assertj.core.api.Assertions.assertThat; + +import tools.jackson.databind.json.JsonMapper; +import com.nvidia.boot.mock.azure.MockAcrAuthServer; +import com.nvidia.boot.mock.ngc.MockCasServer; +import com.nvidia.boot.mock.oci.MockOciRegistryServer; +import com.nvidia.nvct.IntegrationTestConfiguration; +import com.nvidia.nvct.NvctTestApp; +import com.nvidia.nvct.grpc.TestTaskService; +import com.nvidia.nvct.rest.task.dto.CreateTaskRequest; +import com.nvidia.nvct.rest.task.dto.ResultHandlingStrategyEnum; +import com.nvidia.nvct.rest.task.dto.TaskResponse; +import com.nvidia.nvct.rest.task.dto.TaskStatusEnum; +import com.nvidia.nvct.service.account.AccountService; +import com.nvidia.nvct.util.MockEssServer; +import com.nvidia.nvct.util.MockNotaryServer; +import com.nvidia.nvct.util.MockNvcfServer; +import com.nvidia.nvct.util.MockRevalServer; +import com.nvidia.nvct.util.MockIcmsServer; +import java.net.URI; +import java.net.URL; +import java.time.Duration; +import java.util.List; +import java.util.stream.Stream; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.resttestclient.TestRestTemplate; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.RequestEntity; +import org.springframework.test.context.ContextConfiguration; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@Slf4j +@SpringBootTest( + classes = {NvctTestApp.class, IntegrationTestConfiguration.class}, + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + properties = "spring.profiles.active=test") +@ContextConfiguration(initializers = IntegrationTestConfiguration.Initializer.class) +@AutoConfigureTestRestTemplate +class TaskCreationWithAcrRegistryTest { + + @Autowired + private TestRestTemplate testRestTemplate; + + @Autowired + private AccountService accountService; + + @Autowired + private JsonMapper jsonMapper; + + @Autowired + private TestTaskService testTaskService; + + @Value("${nvct.ess.base-url}") + private String essBaseUrl; + + @Value("${nvct.notary.base-url}") + private String notaryBaseUrl; + + @Value("${spring.security.oauth2.client.registration.notary.client-id}") + private String notaryClientId; + + @Value("${nvct.reval.base-url}") + private URI revalBaseUrl; + + @Value("${nvct.nvcf.base-url}") + private URL nvcfBaseUrl; + + @Value("${nvct.icms.base-url}") + private URL icmsBaseUrl; + + @Value("${nvct.registries.recognized.container.ngc.hostname}") + private String ngcContainerRegistryHostname; + + @Value("${nvct.registries.recognized.model.ngc.hostname}") + private String casBaseUrl; + + @Value("${nvct.registries.recognized.model.ngc.oauth2.base-url}") + private String authnBaseUrl; + + @Value("${nvct.registries.recognized.container.acr.hostname}") + private String acrBaseUrl; + + @Value("${nvct.registries.recognized.container.acr.oauth2.base-url}") + private String acrAuthBaseUrl; + + private MockOciRegistryServer mockAcrRegistryServer; + + @BeforeAll + void beforeAll() { + log.info("{}: Started running tests", this.getClass().getSimpleName()); + MockNvcfServer.start(nvcfBaseUrl); + MockIcmsServer.start(icmsBaseUrl, jsonMapper); + MockCasServer.start(authnBaseUrl, casBaseUrl); + MockEssServer.start(essBaseUrl); + MockNotaryServer.start(notaryBaseUrl, notaryClientId); + MockRevalServer.start(revalBaseUrl); + + // Start ACR mock servers + MockAcrAuthServer.start(acrAuthBaseUrl); + mockAcrRegistryServer = new MockOciRegistryServer(); + mockAcrRegistryServer.start(acrBaseUrl); + } + + @AfterAll + void cleanup() { + MockNvcfServer.stop(); + MockIcmsServer.stop(); + MockCasServer.stop(); + MockEssServer.stop(); + MockNotaryServer.stop(); + MockRevalServer.stop(); + MockAcrAuthServer.stop(); + mockAcrRegistryServer.stop(); + log.info("{}: Completed running tests", this.getClass().getSimpleName()); + } + + @AfterEach + void reset() { + accountService.invalidateCache(); + testTaskService.clearAll(); + } + + Stream CreateTaskWithContainerImageArgs() { + return Stream.of( + // existing acr container image + Arguments.of(TEST_ACR_CONTAINER_IMAGE_WITH_TAG, HttpStatus.OK), + // acr container image with digest + Arguments.of(TEST_ACR_CONTAINER_IMAGE_WITH_DIGEST, HttpStatus.OK), + // acr container image does not exist + Arguments.of(TEST_ACR_CONTAINER_IMAGE_NOT_EXISTS, HttpStatus.NOT_FOUND), + // acr container image no permission + Arguments.of(TEST_ACR_CONTAINER_IMAGE_PERMISSION_DENIED, HttpStatus.FORBIDDEN) + ); + } + + @ParameterizedTest + @MethodSource("CreateTaskWithContainerImageArgs") + void shouldLaunchContainerBasedTask( + URI containerImage, + HttpStatus expectedStatus) { + var token = MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100); + var requestBodyBuilder = CreateTaskRequest.builder() + .name(TEST_TASK_NAME_1) + .containerArgs(TEST_CONTAINER_ARGS) + .containerImage(containerImage) + .tags(TEST_TAGS) + .gpuSpecification(TEST_OCI_GPU_SPEC_DTO) + .maxRuntimeDuration(Duration.ofHours(2)) + .maxQueuedDuration(Duration.ofHours(1)) + .terminationGracePeriodDuration(Duration.ofHours(1)) + .description(TEST_DESCRIPTION) + .resultHandlingStrategy(ResultHandlingStrategyEnum.UPLOAD) + .resultsLocation(TEST_RESULTS_LOCATION_2) + .secrets(TEST_SECRETS); + var requestEntity = RequestEntity.post(URI.create("/v1/nvct/tasks")) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", "Bearer " + token) + .body(requestBodyBuilder.build()); + var responseEntity = + testRestTemplate.exchange(requestEntity, TaskResponse.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(expectedStatus); + if (expectedStatus.isError()) { + return; + } + + var responseBody = responseEntity.getBody(); + assertThat(responseBody).isNotNull(); + assertThat(responseBody.task().id()).isNotNull(); + assertThat(responseBody.task().name()).isEqualTo(TEST_TASK_NAME_1); + assertThat(responseBody.task().status()).isEqualTo(TaskStatusEnum.QUEUED); + assertThat(responseBody.task().ncaId()).isEqualTo(TEST_NCA_ID); + assertThat(responseBody.task().createdAt()).isNotNull(); + assertThat(responseBody.task().containerImage()).isEqualTo(containerImage); + } + + Stream CreateTaskWithHelmChartArgs() { + return Stream.of( + // existing acr helm chart + Arguments.of(TEST_ACR_HELM_CHART_WITH_TAG, HttpStatus.OK), + // acr helm chart with digest + Arguments.of(TEST_ACR_HELM_CHART_WITH_DIGEST, HttpStatus.OK), + // acr helm chart does not exist + Arguments.of(TEST_ACR_HELM_CHART_NOT_EXISTS, HttpStatus.NOT_FOUND), + // acr helm chart no permission + Arguments.of(TEST_ACR_HELM_CHART_PERMISSION_DENIED, HttpStatus.FORBIDDEN) + ); + } + + @ParameterizedTest + @MethodSource("CreateTaskWithHelmChartArgs") + void shouldLaunchTasksWithHelmCharts( + URI helmChart, + HttpStatus expectedStatus) { + var token = MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100); + var requestBodyBuilder = CreateTaskRequest.builder() + .name(TEST_TASK_NAME_1) + .helmChart(helmChart) + .tags(TEST_TAGS) + .gpuSpecification(TEST_OCI_GPU_SPEC_HELM_CONFIG_DTO) + .maxRuntimeDuration(Duration.ofHours(2)) + .maxQueuedDuration(Duration.ofHours(1)) + .terminationGracePeriodDuration(Duration.ofHours(1)) + .description(TEST_DESCRIPTION) + .resultHandlingStrategy(ResultHandlingStrategyEnum.UPLOAD) + .resultsLocation(TEST_RESULTS_LOCATION_2) + .secrets(TEST_SECRETS); + var requestEntity = RequestEntity.post(URI.create("/v1/nvct/tasks")) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", "Bearer " + token) + .body(requestBodyBuilder.build()); + var responseEntity = + testRestTemplate.exchange(requestEntity, TaskResponse.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(expectedStatus); + if (expectedStatus.isError()) { + return; + } + + var responseBody = responseEntity.getBody(); + assertThat(responseBody).isNotNull(); + assertThat(responseBody.task().id()).isNotNull(); + assertThat(responseBody.task().name()).isEqualTo(TEST_TASK_NAME_1); + assertThat(responseBody.task().status()).isEqualTo(TaskStatusEnum.QUEUED); + assertThat(responseBody.task().ncaId()).isEqualTo(TEST_NCA_ID); + assertThat(responseBody.task().createdAt()).isNotNull(); + assertThat(responseBody.task().helmChart()).isEqualTo(helmChart); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/TaskCreationWithArtifactoryRegistryTest.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/TaskCreationWithArtifactoryRegistryTest.java new file mode 100644 index 000000000..bf309f41e --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/TaskCreationWithArtifactoryRegistryTest.java @@ -0,0 +1,282 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.rest.task; + +import static com.nvidia.boot.mock.BootTestConstants.TEST_ARTIFACTORY_CONTAINER_IMAGE_NOT_EXISTS; +import static com.nvidia.boot.mock.BootTestConstants.TEST_ARTIFACTORY_CONTAINER_IMAGE_PERMISSION_DENIED; +import static com.nvidia.boot.mock.BootTestConstants.TEST_ARTIFACTORY_CONTAINER_IMAGE_WITH_DIGEST; +import static com.nvidia.boot.mock.BootTestConstants.TEST_ARTIFACTORY_CONTAINER_IMAGE_WITH_TAG; +import static com.nvidia.boot.mock.BootTestConstants.TEST_ARTIFACTORY_HELM_CHART_NOT_EXISTS; +import static com.nvidia.boot.mock.BootTestConstants.TEST_ARTIFACTORY_HELM_CHART_PERMISSION_DENIED; +import static com.nvidia.boot.mock.BootTestConstants.TEST_ARTIFACTORY_HELM_CHART_WITH_DIGEST; +import static com.nvidia.boot.mock.BootTestConstants.TEST_ARTIFACTORY_HELM_CHART_WITH_TAG; +import static com.nvidia.nvct.IntegrationTestConfiguration.MOCK_OAUTH2_TOKEN_SERVER; +import static com.nvidia.nvct.util.NvctConstants.SCOPE_LAUNCH_TASK; +import static com.nvidia.nvct.util.NvctConstants.SCOPE_LIST_TASKS; +import static com.nvidia.nvct.util.TestConstants.TEST_CLIENT_SUBJECT; +import static com.nvidia.nvct.util.TestConstants.TEST_CONTAINER_ARGS; +import static com.nvidia.nvct.util.TestConstants.TEST_DESCRIPTION; +import static com.nvidia.nvct.util.TestConstants.TEST_NCA_ID; +import static com.nvidia.nvct.util.TestConstants.TEST_OCI_GPU_SPEC_DTO; +import static com.nvidia.nvct.util.TestConstants.TEST_OCI_GPU_SPEC_HELM_CONFIG_DTO; +import static com.nvidia.nvct.util.TestConstants.TEST_RESULTS_LOCATION_2; +import static com.nvidia.nvct.util.TestConstants.TEST_SECRETS; +import static com.nvidia.nvct.util.TestConstants.TEST_TAGS; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_NAME_1; +import static org.assertj.core.api.Assertions.assertThat; + +import tools.jackson.databind.json.JsonMapper; +import com.nvidia.boot.mock.artifactory.MockArtifactoryAuthServer; +import com.nvidia.boot.mock.ngc.MockCasServer; +import com.nvidia.boot.mock.oci.MockOciRegistryServer; +import com.nvidia.nvct.IntegrationTestConfiguration; +import com.nvidia.nvct.NvctTestApp; +import com.nvidia.nvct.grpc.TestTaskService; +import com.nvidia.nvct.rest.task.dto.CreateTaskRequest; +import com.nvidia.nvct.rest.task.dto.ResultHandlingStrategyEnum; +import com.nvidia.nvct.rest.task.dto.TaskResponse; +import com.nvidia.nvct.rest.task.dto.TaskStatusEnum; +import com.nvidia.nvct.service.account.AccountService; +import com.nvidia.nvct.util.MockEssServer; +import com.nvidia.nvct.util.MockNotaryServer; +import com.nvidia.nvct.util.MockNvcfServer; +import com.nvidia.nvct.util.MockRevalServer; +import com.nvidia.nvct.util.MockIcmsServer; +import java.net.URI; +import java.net.URL; +import java.time.Duration; +import java.util.List; +import java.util.stream.Stream; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.resttestclient.TestRestTemplate; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.RequestEntity; +import org.springframework.test.context.ContextConfiguration; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@Slf4j +@SpringBootTest( + classes = {NvctTestApp.class, IntegrationTestConfiguration.class}, + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + properties = "spring.profiles.active=test") +@ContextConfiguration(initializers = IntegrationTestConfiguration.Initializer.class) +@AutoConfigureTestRestTemplate +class TaskCreationWithArtifactoryRegistryTest { + + @Autowired + private TestRestTemplate testRestTemplate; + + @Autowired + private AccountService accountService; + + @Autowired + private JsonMapper jsonMapper; + + @Autowired + private TestTaskService testTaskService; + + @Value("${nvct.ess.base-url}") + private String essBaseUrl; + + @Value("${nvct.notary.base-url}") + private String notaryBaseUrl; + + @Value("${spring.security.oauth2.client.registration.notary.client-id}") + private String notaryClientId; + + @Value("${nvct.reval.base-url}") + private URI revalBaseUrl; + + @Value("${nvct.nvcf.base-url}") + private URL nvcfBaseUrl; + + @Value("${nvct.icms.base-url}") + private URL icmsBaseUrl; + + @Value("${nvct.registries.recognized.container.ngc.hostname}") + private String ngcContainerRegistryHostname; + + @Value("${nvct.registries.recognized.model.ngc.hostname}") + private String casBaseUrl; + + @Value("${nvct.registries.recognized.model.ngc.oauth2.base-url}") + private String authnBaseUrl; + + @Value("${nvct.registries.recognized.container.artifactory.hostname}") + private String artifactoryBaseUrl; + + @Value("${nvct.registries.recognized.container.artifactory.oauth2.base-url}") + private String artifactoryAuthBaseUrl; + + private MockOciRegistryServer mockArtifactoryRegistryServer; + + @BeforeAll + void beforeAll() { + log.info("{}: Started running tests", this.getClass().getSimpleName()); + MockNvcfServer.start(nvcfBaseUrl); + MockIcmsServer.start(icmsBaseUrl, jsonMapper); + MockCasServer.start(authnBaseUrl, casBaseUrl); + MockEssServer.start(essBaseUrl); + MockNotaryServer.start(notaryBaseUrl, notaryClientId); + MockRevalServer.start(revalBaseUrl); + + // Start Artifactory mock servers + MockArtifactoryAuthServer.start(artifactoryAuthBaseUrl); + mockArtifactoryRegistryServer = new MockOciRegistryServer(); + mockArtifactoryRegistryServer.start(artifactoryBaseUrl); + } + + @AfterAll + void cleanup() { + MockNvcfServer.stop(); + MockIcmsServer.stop(); + MockCasServer.stop(); + MockEssServer.stop(); + MockNotaryServer.stop(); + MockRevalServer.stop(); + MockArtifactoryAuthServer.stop(); + mockArtifactoryRegistryServer.stop(); + log.info("{}: Completed running tests", this.getClass().getSimpleName()); + } + + @AfterEach + void reset() { + accountService.invalidateCache(); + testTaskService.clearAll(); + } + + Stream CreateTaskWithContainerImageArgs() { + return Stream.of( + // existing artifactory container image + Arguments.of(TEST_ARTIFACTORY_CONTAINER_IMAGE_WITH_TAG, HttpStatus.OK), + // artifactory container image with digest + Arguments.of(TEST_ARTIFACTORY_CONTAINER_IMAGE_WITH_DIGEST, HttpStatus.OK), + // artifactory container image does not exist + Arguments.of(TEST_ARTIFACTORY_CONTAINER_IMAGE_NOT_EXISTS, HttpStatus.NOT_FOUND), + // artifactory container image no permission + Arguments.of(TEST_ARTIFACTORY_CONTAINER_IMAGE_PERMISSION_DENIED, HttpStatus.FORBIDDEN) + ); + } + + @ParameterizedTest + @MethodSource("CreateTaskWithContainerImageArgs") + void shouldLaunchContainerBasedTask( + URI containerImage, + HttpStatus expectedStatus) { + var token = MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100); + var requestBodyBuilder = CreateTaskRequest.builder() + .name(TEST_TASK_NAME_1) + .containerArgs(TEST_CONTAINER_ARGS) + .containerImage(containerImage) + .tags(TEST_TAGS) + .gpuSpecification(TEST_OCI_GPU_SPEC_DTO) + .maxRuntimeDuration(Duration.ofHours(2)) + .maxQueuedDuration(Duration.ofHours(1)) + .terminationGracePeriodDuration(Duration.ofHours(1)) + .description(TEST_DESCRIPTION) + .resultHandlingStrategy(ResultHandlingStrategyEnum.UPLOAD) + .resultsLocation(TEST_RESULTS_LOCATION_2) + .secrets(TEST_SECRETS); + var requestEntity = RequestEntity.post(URI.create("/v1/nvct/tasks")) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", "Bearer " + token) + .body(requestBodyBuilder.build()); + var responseEntity = + testRestTemplate.exchange(requestEntity, TaskResponse.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(expectedStatus); + if (expectedStatus.isError()) { + return; + } + + var responseBody = responseEntity.getBody(); + assertThat(responseBody).isNotNull(); + assertThat(responseBody.task().id()).isNotNull(); + assertThat(responseBody.task().name()).isEqualTo(TEST_TASK_NAME_1); + assertThat(responseBody.task().status()).isEqualTo(TaskStatusEnum.QUEUED); + assertThat(responseBody.task().ncaId()).isEqualTo(TEST_NCA_ID); + assertThat(responseBody.task().createdAt()).isNotNull(); + assertThat(responseBody.task().containerImage()).isEqualTo(containerImage); + } + + Stream CreateTaskWithHelmChartArgs() { + return Stream.of( + // existing artifactory helm chart + Arguments.of(TEST_ARTIFACTORY_HELM_CHART_WITH_TAG, HttpStatus.OK), + // artifactory helm chart with digest + Arguments.of(TEST_ARTIFACTORY_HELM_CHART_WITH_DIGEST, HttpStatus.OK), + // artifactory helm chart does not exist + Arguments.of(TEST_ARTIFACTORY_HELM_CHART_NOT_EXISTS, HttpStatus.NOT_FOUND), + // artifactory helm chart no permission + Arguments.of(TEST_ARTIFACTORY_HELM_CHART_PERMISSION_DENIED, HttpStatus.FORBIDDEN) + ); + } + + @ParameterizedTest + @MethodSource("CreateTaskWithHelmChartArgs") + void shouldLaunchTasksWithHelmCharts( + URI helmChart, + HttpStatus expectedStatus) { + var token = MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100); + var requestBodyBuilder = CreateTaskRequest.builder() + .name(TEST_TASK_NAME_1) + .helmChart(helmChart) + .tags(TEST_TAGS) + .gpuSpecification(TEST_OCI_GPU_SPEC_HELM_CONFIG_DTO) + .maxRuntimeDuration(Duration.ofHours(2)) + .maxQueuedDuration(Duration.ofHours(1)) + .terminationGracePeriodDuration(Duration.ofHours(1)) + .description(TEST_DESCRIPTION) + .resultHandlingStrategy(ResultHandlingStrategyEnum.UPLOAD) + .resultsLocation(TEST_RESULTS_LOCATION_2) + .secrets(TEST_SECRETS); + var requestEntity = RequestEntity.post(URI.create("/v1/nvct/tasks")) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", "Bearer " + token) + .body(requestBodyBuilder.build()); + var responseEntity = + testRestTemplate.exchange(requestEntity, TaskResponse.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(expectedStatus); + if (expectedStatus.isError()) { + return; + } + + var responseBody = responseEntity.getBody(); + assertThat(responseBody).isNotNull(); + assertThat(responseBody.task().id()).isNotNull(); + assertThat(responseBody.task().name()).isEqualTo(TEST_TASK_NAME_1); + assertThat(responseBody.task().status()).isEqualTo(TaskStatusEnum.QUEUED); + assertThat(responseBody.task().ncaId()).isEqualTo(TEST_NCA_ID); + assertThat(responseBody.task().createdAt()).isNotNull(); + assertThat(responseBody.task().helmChart()).isEqualTo(helmChart); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/TaskCreationWithDockerHubRegistryTest.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/TaskCreationWithDockerHubRegistryTest.java new file mode 100644 index 000000000..4404f87cf --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/TaskCreationWithDockerHubRegistryTest.java @@ -0,0 +1,284 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.rest.task; + +import static com.nvidia.boot.mock.BootTestConstants.TEST_DOCKER_CONTAINER_IMAGE; +import static com.nvidia.boot.mock.BootTestConstants.TEST_DOCKER_CONTAINER_IMAGE_NOT_EXISTS; +import static com.nvidia.boot.mock.BootTestConstants.TEST_DOCKER_CONTAINER_IMAGE_PERMISSION_DENIED; +import static com.nvidia.boot.mock.BootTestConstants.TEST_DOCKER_CONTAINER_IMAGE_WITH_DIGEST; +import static com.nvidia.boot.mock.BootTestConstants.TEST_DOCKER_HELM_CHART; +import static com.nvidia.nvct.IntegrationTestConfiguration.MOCK_OAUTH2_TOKEN_SERVER; +import static com.nvidia.nvct.util.NvctConstants.SCOPE_LAUNCH_TASK; +import static com.nvidia.nvct.util.NvctConstants.SCOPE_LIST_TASKS; +import static com.nvidia.nvct.util.TestConstants.TEST_CLIENT_SUBJECT; +import static com.nvidia.nvct.util.TestConstants.TEST_CONTAINER_ARGS; +import static com.nvidia.nvct.util.TestConstants.TEST_DESCRIPTION; +import static com.nvidia.nvct.util.TestConstants.TEST_NCA_ID; +import static com.nvidia.nvct.util.TestConstants.TEST_OCI_GPU_SPEC_DTO; +import static com.nvidia.nvct.util.TestConstants.TEST_RESULTS_LOCATION_2; +import static com.nvidia.nvct.util.TestConstants.TEST_SECRETS; +import static com.nvidia.nvct.util.TestConstants.TEST_TAGS; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_NAME_1; +import static org.assertj.core.api.Assertions.assertThat; + +import tools.jackson.databind.json.JsonMapper; +import com.nvidia.boot.mock.docker.MockDockerRegistryAuthServer; +import com.nvidia.boot.mock.docker.MockDockerRegistryServer; +import com.nvidia.boot.mock.ngc.MockCasServer; +import com.nvidia.boot.mock.ngc.MockNgcContainerRegistryServer; +import com.nvidia.nvct.IntegrationTestConfiguration; +import com.nvidia.nvct.NvctTestApp; +import com.nvidia.nvct.grpc.TestTaskService; +import com.nvidia.nvct.rest.task.dto.CreateTaskRequest; +import com.nvidia.nvct.rest.task.dto.ResultHandlingStrategyEnum; +import com.nvidia.nvct.rest.task.dto.TaskResponse; +import com.nvidia.nvct.rest.task.dto.TaskStatusEnum; +import com.nvidia.nvct.service.account.AccountService; +import com.nvidia.nvct.util.MockEssServer; +import com.nvidia.nvct.util.MockNotaryServer; +import com.nvidia.nvct.util.MockNvcfServer; +import com.nvidia.nvct.util.MockRevalServer; +import com.nvidia.nvct.util.MockIcmsServer; +import java.net.URI; +import java.net.URL; +import java.time.Duration; +import java.util.List; +import java.util.stream.Stream; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.resttestclient.TestRestTemplate; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.RequestEntity; +import org.springframework.test.context.ContextConfiguration; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@Slf4j +@SpringBootTest( + classes = {NvctTestApp.class, IntegrationTestConfiguration.class}, + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + properties = "spring.profiles.active=test") +@ContextConfiguration(initializers = IntegrationTestConfiguration.Initializer.class) +@AutoConfigureTestRestTemplate +class TaskCreationWithDockerHubRegistryTest { + + @Autowired + private TestRestTemplate testRestTemplate; + + @Autowired + private AccountService accountService; + + @Autowired + private JsonMapper jsonMapper; + + @Autowired + private TestTaskService testTaskService; + + @Value("${nvct.ess.base-url}") + private String essBaseUrl; + + @Value("${nvct.notary.base-url}") + private String notaryBaseUrl; + + @Value("${spring.security.oauth2.client.registration.notary.client-id}") + private String notaryClientId; + + @Value("${nvct.reval.base-url}") + private URI revalBaseUrl; + + @Value("${nvct.nvcf.base-url}") + private URL nvcfBaseUrl; + + @Value("${nvct.icms.base-url}") + private URL icmsBaseUrl; + + @Value("${nvct.registries.recognized.container.ngc.hostname}") + private String ngcContainerRegistryHostname; + + @Value("${nvct.registries.recognized.model.ngc.hostname}") + private String casBaseUrl; + + @Value("${nvct.registries.recognized.model.ngc.oauth2.base-url}") + private String authnBaseUrl; + + @Value("${nvct.registries.recognized.container.docker.hostname}") + private String dockerBaseUrl; + + @Value("${nvct.registries.recognized.container.docker.oauth2.base-url}") + private String dockerAuthBaseUrl; + + + @BeforeAll + void beforeAll() { + log.info("{}: Started running tests", this.getClass().getSimpleName()); + MockNvcfServer.start(nvcfBaseUrl); + MockIcmsServer.start(icmsBaseUrl, jsonMapper); + MockCasServer.start(authnBaseUrl, casBaseUrl); + MockEssServer.start(essBaseUrl); + MockNotaryServer.start(notaryBaseUrl, notaryClientId); + MockRevalServer.start(revalBaseUrl); + MockNgcContainerRegistryServer.start(ngcContainerRegistryHostname); + MockDockerRegistryAuthServer.start(dockerAuthBaseUrl); + MockDockerRegistryServer.start(dockerBaseUrl); + } + + @AfterAll + void cleanup() { + MockNvcfServer.stop(); + MockIcmsServer.stop(); + MockCasServer.stop(); + MockEssServer.stop(); + MockNotaryServer.stop(); + MockRevalServer.stop(); + MockNgcContainerRegistryServer.stop(); + MockDockerRegistryServer.stop(); + MockDockerRegistryAuthServer.stop(); + log.info("{}: Completed running tests", this.getClass().getSimpleName()); + } + + @AfterEach + void reset() { + accountService.invalidateCache(); + testTaskService.clearAll(); + } + + Stream CreateTaskWithDockerImageArgs() { + return Stream.of( + // existing docker image + Arguments.of(TEST_DOCKER_CONTAINER_IMAGE, + HttpStatus.OK), + // docker image with digest + Arguments.of(TEST_DOCKER_CONTAINER_IMAGE_WITH_DIGEST, + HttpStatus.OK), + // image doesn't exist + Arguments.of(TEST_DOCKER_CONTAINER_IMAGE_NOT_EXISTS, + HttpStatus.NOT_FOUND), + // no permission + Arguments.of(TEST_DOCKER_CONTAINER_IMAGE_PERMISSION_DENIED, + HttpStatus.FORBIDDEN)); + } + + @ParameterizedTest + @MethodSource("CreateTaskWithDockerImageArgs") + void shouldLaunchTasksWithDockerImages( + URI containerImage, + HttpStatus expectedStatus) { + var token = MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100); + + + var requestBodyBuilder = CreateTaskRequest.builder() + .name(TEST_TASK_NAME_1) + .containerArgs(TEST_CONTAINER_ARGS) + .containerImage(containerImage) + .tags(TEST_TAGS) + .gpuSpecification(TEST_OCI_GPU_SPEC_DTO) + .maxRuntimeDuration(Duration.ofHours(2)) + .maxQueuedDuration(Duration.ofHours(1)) + .terminationGracePeriodDuration(Duration.ofHours(1)) + .description(TEST_DESCRIPTION) + .resultHandlingStrategy(ResultHandlingStrategyEnum.UPLOAD) + .resultsLocation(TEST_RESULTS_LOCATION_2) + .secrets(TEST_SECRETS); + var requestEntity = RequestEntity.post(URI.create("/v1/nvct/tasks")) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", "Bearer " + token) + .body(requestBodyBuilder.build()); + var responseEntity = + testRestTemplate.exchange(requestEntity, TaskResponse.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(expectedStatus); + if (expectedStatus.isError()) { + return; + } + + var responseBody = responseEntity.getBody(); + assertThat(responseBody).isNotNull(); + assertThat(responseBody.task().id()).isNotNull(); + assertThat(responseBody.task().name()).isEqualTo(TEST_TASK_NAME_1); + assertThat(responseBody.task().status()).isEqualTo(TaskStatusEnum.QUEUED); + assertThat(responseBody.task().ncaId()).isEqualTo(TEST_NCA_ID); + assertThat(responseBody.task().createdAt()).isNotNull(); + assertThat(responseBody.task().containerImage()).isEqualTo(containerImage); + } + + Stream CreateTaskWithDockerHelmArgs() { + return Stream.of( + // existing docker helm + Arguments.of("oci://" + TEST_DOCKER_HELM_CHART, + HttpStatus.OK), + // helm doesn't exist + Arguments.of("oci://" + TEST_DOCKER_CONTAINER_IMAGE_NOT_EXISTS, + HttpStatus.NOT_FOUND) + // the rest situations are the same as docker containers since they share the + // same url pattern + ); + } + @ParameterizedTest + @MethodSource("CreateTaskWithDockerHelmArgs") + void shouldLaunchTasksWithDockerHelm( + URI helmUrl, + HttpStatus expectedStatus) { + var token = MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100); + + + var requestBodyBuilder = CreateTaskRequest.builder() + .name(TEST_TASK_NAME_1) + .helmChart(helmUrl) + .tags(TEST_TAGS) + .gpuSpecification(TEST_OCI_GPU_SPEC_DTO) + .maxRuntimeDuration(Duration.ofHours(2)) + .maxQueuedDuration(Duration.ofHours(1)) + .terminationGracePeriodDuration(Duration.ofHours(1)) + .description(TEST_DESCRIPTION) + .resultHandlingStrategy(ResultHandlingStrategyEnum.UPLOAD) + .resultsLocation(TEST_RESULTS_LOCATION_2) + .secrets(TEST_SECRETS); + var requestEntity = RequestEntity.post(URI.create("/v1/nvct/tasks")) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", "Bearer " + token) + .body(requestBodyBuilder.build()); + var responseEntity = + testRestTemplate.exchange(requestEntity, TaskResponse.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(expectedStatus); + if (expectedStatus.isError()) { + return; + } + + var responseBody = responseEntity.getBody(); + assertThat(responseBody).isNotNull(); + assertThat(responseBody.task().id()).isNotNull(); + assertThat(responseBody.task().name()).isEqualTo(TEST_TASK_NAME_1); + assertThat(responseBody.task().status()).isEqualTo(TaskStatusEnum.QUEUED); + assertThat(responseBody.task().ncaId()).isEqualTo(TEST_NCA_ID); + assertThat(responseBody.task().createdAt()).isNotNull(); + assertThat(responseBody.task().helmChart()).isEqualTo(helmUrl); + } + +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/TaskCreationWithEcrRegistryTest.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/TaskCreationWithEcrRegistryTest.java new file mode 100644 index 000000000..92ea7dcfd --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/TaskCreationWithEcrRegistryTest.java @@ -0,0 +1,319 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.rest.task; + +import static com.nvidia.boot.mock.BootTestConstants.TEST_ECR_CONTAINER_IMAGE_DIGEST_NOT_FOUND; +import static com.nvidia.boot.mock.BootTestConstants.TEST_ECR_CONTAINER_IMAGE_PERMISSION_DENIED; +import static com.nvidia.boot.mock.BootTestConstants.TEST_ECR_CONTAINER_IMAGE_TAG_NOT_FOUND; +import static com.nvidia.boot.mock.BootTestConstants.TEST_ECR_CONTAINER_IMAGE_WITH_DIGEST; +import static com.nvidia.boot.mock.BootTestConstants.TEST_ECR_CONTAINER_IMAGE_WITH_TAG; +import static com.nvidia.boot.mock.BootTestConstants.TEST_ECR_HELM_CHART_DIGEST_NOT_FOUND; +import static com.nvidia.boot.mock.BootTestConstants.TEST_ECR_HELM_CHART_PERMISSION_DENIED; +import static com.nvidia.boot.mock.BootTestConstants.TEST_ECR_HELM_CHART_TAG_NOT_FOUND; +import static com.nvidia.boot.mock.BootTestConstants.TEST_ECR_HELM_CHART_WITH_DIGEST; +import static com.nvidia.boot.mock.BootTestConstants.TEST_ECR_HELM_CHART_WITH_TAG; +import static com.nvidia.boot.mock.BootTestConstants.TEST_ECR_PUBLIC_CONTAINER_IMAGE_DIGEST_NOT_FOUND; +import static com.nvidia.boot.mock.BootTestConstants.TEST_ECR_PUBLIC_CONTAINER_IMAGE_PERMISSION_DENIED; +import static com.nvidia.boot.mock.BootTestConstants.TEST_ECR_PUBLIC_CONTAINER_IMAGE_TAG_NOT_FOUND; +import static com.nvidia.boot.mock.BootTestConstants.TEST_ECR_PUBLIC_CONTAINER_IMAGE_WITH_DIGEST; +import static com.nvidia.boot.mock.BootTestConstants.TEST_ECR_PUBLIC_CONTAINER_IMAGE_WITH_TAG; +import static com.nvidia.boot.mock.BootTestConstants.TEST_ECR_PUBLIC_HELM_CHART_DIGEST_NOT_FOUND; +import static com.nvidia.boot.mock.BootTestConstants.TEST_ECR_PUBLIC_HELM_CHART_PERMISSION_DENIED; +import static com.nvidia.boot.mock.BootTestConstants.TEST_ECR_PUBLIC_HELM_CHART_TAG_NOT_FOUND; +import static com.nvidia.boot.mock.BootTestConstants.TEST_ECR_PUBLIC_HELM_CHART_WITH_DIGEST; +import static com.nvidia.boot.mock.BootTestConstants.TEST_ECR_PUBLIC_HELM_CHART_WITH_TAG; +import static com.nvidia.nvct.IntegrationTestConfiguration.MOCK_OAUTH2_TOKEN_SERVER; +import static com.nvidia.nvct.util.NvctConstants.SCOPE_LAUNCH_TASK; +import static com.nvidia.nvct.util.NvctConstants.SCOPE_LIST_TASKS; +import static com.nvidia.nvct.util.TestConstants.TEST_CLIENT_SUBJECT; +import static com.nvidia.nvct.util.TestConstants.TEST_CONTAINER_ARGS; +import static com.nvidia.nvct.util.TestConstants.TEST_DESCRIPTION; +import static com.nvidia.nvct.util.TestConstants.TEST_NCA_ID; +import static com.nvidia.nvct.util.TestConstants.TEST_OCI_GPU_SPEC_DTO; +import static com.nvidia.nvct.util.TestConstants.TEST_OCI_GPU_SPEC_HELM_CONFIG_DTO; +import static com.nvidia.nvct.util.TestConstants.TEST_RESULTS_LOCATION_2; +import static com.nvidia.nvct.util.TestConstants.TEST_SECRETS; +import static com.nvidia.nvct.util.TestConstants.TEST_TAGS; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_NAME_1; +import static org.assertj.core.api.Assertions.assertThat; + +import tools.jackson.databind.json.JsonMapper; +import com.nvidia.boot.mock.ecr.MockEcrPrivateRegistryServer; +import com.nvidia.boot.mock.ecr.MockEcrPublicRegistryServer; +import com.nvidia.boot.mock.ngc.MockCasServer; +import com.nvidia.boot.mock.ngc.MockNgcContainerRegistryServer; +import com.nvidia.nvct.IntegrationTestConfiguration; +import com.nvidia.nvct.NvctTestApp; +import com.nvidia.nvct.grpc.TestTaskService; +import com.nvidia.nvct.rest.task.dto.CreateTaskRequest; +import com.nvidia.nvct.rest.task.dto.ResultHandlingStrategyEnum; +import com.nvidia.nvct.rest.task.dto.TaskResponse; +import com.nvidia.nvct.rest.task.dto.TaskStatusEnum; +import com.nvidia.nvct.service.account.AccountService; +import com.nvidia.nvct.util.MockEssServer; +import com.nvidia.nvct.util.MockNotaryServer; +import com.nvidia.nvct.util.MockNvcfServer; +import com.nvidia.nvct.util.MockRevalServer; +import com.nvidia.nvct.util.MockIcmsServer; +import java.net.URI; +import java.net.URL; +import java.time.Duration; +import java.util.List; +import java.util.stream.Stream; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.resttestclient.TestRestTemplate; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.RequestEntity; +import org.springframework.test.context.ContextConfiguration; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@Slf4j +@SpringBootTest( + classes = {NvctTestApp.class, IntegrationTestConfiguration.class}, + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + properties = "spring.profiles.active=test") +@ContextConfiguration(initializers = IntegrationTestConfiguration.Initializer.class) +@AutoConfigureTestRestTemplate +class TaskCreationWithEcrRegistryTest { + + @Autowired + private TestRestTemplate testRestTemplate; + + @Autowired + private AccountService accountService; + + @Autowired + private JsonMapper jsonMapper; + + @Autowired + private TestTaskService testTaskService; + + @Value("${nvct.ess.base-url}") + private String essBaseUrl; + + @Value("${nvct.notary.base-url}") + private String notaryBaseUrl; + + @Value("${spring.security.oauth2.client.registration.notary.client-id}") + private String notaryClientId; + + @Value("${nvct.reval.base-url}") + private URI revalBaseUrl; + + @Value("${nvct.nvcf.base-url}") + private URL nvcfBaseUrl; + + @Value("${nvct.icms.base-url}") + private URL icmsBaseUrl; + + @Value("${nvct.registries.recognized.container.ngc.hostname}") + private String ngcContainerRegistryHostname; + + @Value("${nvct.registries.recognized.model.ngc.hostname}") + private String casBaseUrl; + + @Value("${nvct.registries.recognized.model.ngc.oauth2.base-url}") + private String authnBaseUrl; + + @Value("${nvct.registries.recognized.container.ecr.hostname}") + private String ecrPrivateBaseUrl; + + @Value("${nvct.registries.recognized.container.ecr-public.hostname}") + private String ecrPublicBaseUrl; + + @BeforeAll + void beforeAll() { + log.info("{}: Started running tests", this.getClass().getSimpleName()); + MockNvcfServer.start(nvcfBaseUrl); + MockIcmsServer.start(icmsBaseUrl, jsonMapper); + MockCasServer.start(authnBaseUrl, casBaseUrl); + MockEssServer.start(essBaseUrl); + MockNotaryServer.start(notaryBaseUrl, notaryClientId); + MockRevalServer.start(revalBaseUrl); + MockNgcContainerRegistryServer.start(ngcContainerRegistryHostname); + MockEcrPrivateRegistryServer.start(ecrPrivateBaseUrl); + MockEcrPublicRegistryServer.start(ecrPublicBaseUrl); + } + + @AfterAll + void cleanup() { + MockNvcfServer.stop(); + MockIcmsServer.stop(); + MockCasServer.stop(); + MockEssServer.stop(); + MockNotaryServer.stop(); + MockRevalServer.stop(); + MockNgcContainerRegistryServer.stop(); + MockEcrPrivateRegistryServer.stop(); + MockEcrPublicRegistryServer.stop(); + log.info("{}: Completed running tests", this.getClass().getSimpleName()); + } + + @AfterEach + void reset() { + accountService.invalidateCache(); + testTaskService.clearAll(); + } + + Stream CreateTaskWithContainerImageArgs() { + return Stream.of( + // existing ecr private image + Arguments.of(TEST_ECR_CONTAINER_IMAGE_WITH_TAG, HttpStatus.OK), + // ecr private image with digest + Arguments.of(TEST_ECR_CONTAINER_IMAGE_WITH_DIGEST, HttpStatus.OK), + // ecr private image tag does not exist + Arguments.of(TEST_ECR_CONTAINER_IMAGE_TAG_NOT_FOUND, HttpStatus.BAD_REQUEST), + // ecr private image digest does not exist + Arguments.of(TEST_ECR_CONTAINER_IMAGE_DIGEST_NOT_FOUND, HttpStatus.BAD_REQUEST), + // ecr private image no permission + Arguments.of(TEST_ECR_CONTAINER_IMAGE_PERMISSION_DENIED, HttpStatus.FORBIDDEN), + // existing ecr public image + Arguments.of(TEST_ECR_PUBLIC_CONTAINER_IMAGE_WITH_TAG, HttpStatus.OK), + // ecr public image with digest + Arguments.of(TEST_ECR_PUBLIC_CONTAINER_IMAGE_WITH_DIGEST, HttpStatus.OK), + // ecr public image tag does not exist + Arguments.of(TEST_ECR_PUBLIC_CONTAINER_IMAGE_TAG_NOT_FOUND, HttpStatus.BAD_REQUEST), + // ecr public image digest does not exist + Arguments.of(TEST_ECR_PUBLIC_CONTAINER_IMAGE_DIGEST_NOT_FOUND, + HttpStatus.BAD_REQUEST), + // ecr public image no permission + Arguments.of(TEST_ECR_PUBLIC_CONTAINER_IMAGE_PERMISSION_DENIED, + HttpStatus.FORBIDDEN) + ); + } + + @ParameterizedTest + @MethodSource("CreateTaskWithContainerImageArgs") + void shouldLaunchContainerBasedTask( + URI containerImage, + HttpStatus expectedStatus) { + var token = MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100); + var requestBodyBuilder = CreateTaskRequest.builder() + .name(TEST_TASK_NAME_1) + .containerArgs(TEST_CONTAINER_ARGS) + .containerImage(containerImage) + .tags(TEST_TAGS) + .gpuSpecification(TEST_OCI_GPU_SPEC_DTO) + .maxRuntimeDuration(Duration.ofHours(2)) + .maxQueuedDuration(Duration.ofHours(1)) + .terminationGracePeriodDuration(Duration.ofHours(1)) + .description(TEST_DESCRIPTION) + .resultHandlingStrategy(ResultHandlingStrategyEnum.UPLOAD) + .resultsLocation(TEST_RESULTS_LOCATION_2) + .secrets(TEST_SECRETS); + var requestEntity = RequestEntity.post(URI.create("/v1/nvct/tasks")) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", "Bearer " + token) + .body(requestBodyBuilder.build()); + var responseEntity = + testRestTemplate.exchange(requestEntity, TaskResponse.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(expectedStatus); + if (expectedStatus.isError()) { + return; + } + + var responseBody = responseEntity.getBody(); + assertThat(responseBody).isNotNull(); + assertThat(responseBody.task().id()).isNotNull(); + assertThat(responseBody.task().name()).isEqualTo(TEST_TASK_NAME_1); + assertThat(responseBody.task().status()).isEqualTo(TaskStatusEnum.QUEUED); + assertThat(responseBody.task().ncaId()).isEqualTo(TEST_NCA_ID); + assertThat(responseBody.task().createdAt()).isNotNull(); + assertThat(responseBody.task().containerImage()).isEqualTo(containerImage); + } + + Stream CreateTaskWithHelmChartArgs() { + return Stream.of( + // existing ecr private helm chart + Arguments.of(TEST_ECR_HELM_CHART_WITH_TAG, HttpStatus.OK), + // ecr private helm chart with digest + Arguments.of(TEST_ECR_HELM_CHART_WITH_DIGEST, HttpStatus.OK), + // ecr private helm chart tag does not exist + Arguments.of(TEST_ECR_HELM_CHART_TAG_NOT_FOUND, HttpStatus.BAD_REQUEST), + // ecr private helm chart digest does not exist + Arguments.of(TEST_ECR_HELM_CHART_DIGEST_NOT_FOUND, HttpStatus.BAD_REQUEST), + // ecr private helm chart no permission + Arguments.of(TEST_ECR_HELM_CHART_PERMISSION_DENIED, HttpStatus.FORBIDDEN), + + // existing ecr public helm chart + Arguments.of(TEST_ECR_PUBLIC_HELM_CHART_WITH_TAG, HttpStatus.OK), + // ecr private helm chart with digest + Arguments.of(TEST_ECR_PUBLIC_HELM_CHART_WITH_DIGEST, HttpStatus.OK), + // ecr private helm chart tag does not exist + Arguments.of(TEST_ECR_PUBLIC_HELM_CHART_TAG_NOT_FOUND, HttpStatus.BAD_REQUEST), + // ecr private helm chart digest does not exist + Arguments.of(TEST_ECR_PUBLIC_HELM_CHART_DIGEST_NOT_FOUND, HttpStatus.BAD_REQUEST), + // ecr private helm chart no permission + Arguments.of(TEST_ECR_PUBLIC_HELM_CHART_PERMISSION_DENIED, HttpStatus.FORBIDDEN) + ); + } + + @ParameterizedTest + @MethodSource("CreateTaskWithHelmChartArgs") + void shouldLaunchTasksWithHelmCharts( + URI helmChart, + HttpStatus expectedStatus) { + var token = MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100); + var requestBodyBuilder = CreateTaskRequest.builder() + .name(TEST_TASK_NAME_1) + .helmChart(helmChart) + .tags(TEST_TAGS) + .gpuSpecification(TEST_OCI_GPU_SPEC_HELM_CONFIG_DTO) + .maxRuntimeDuration(Duration.ofHours(2)) + .maxQueuedDuration(Duration.ofHours(1)) + .terminationGracePeriodDuration(Duration.ofHours(1)) + .description(TEST_DESCRIPTION) + .resultHandlingStrategy(ResultHandlingStrategyEnum.UPLOAD) + .resultsLocation(TEST_RESULTS_LOCATION_2) + .secrets(TEST_SECRETS); + var requestEntity = RequestEntity.post(URI.create("/v1/nvct/tasks")) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", "Bearer " + token) + .body(requestBodyBuilder.build()); + var responseEntity = + testRestTemplate.exchange(requestEntity, TaskResponse.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(expectedStatus); + if (expectedStatus.isError()) { + return; + } + + var responseBody = responseEntity.getBody(); + assertThat(responseBody).isNotNull(); + assertThat(responseBody.task().id()).isNotNull(); + assertThat(responseBody.task().name()).isEqualTo(TEST_TASK_NAME_1); + assertThat(responseBody.task().status()).isEqualTo(TaskStatusEnum.QUEUED); + assertThat(responseBody.task().ncaId()).isEqualTo(TEST_NCA_ID); + assertThat(responseBody.task().createdAt()).isNotNull(); + assertThat(responseBody.task().helmChart()).isEqualTo(helmChart); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/TaskCreationWithHarborRegistryTest.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/TaskCreationWithHarborRegistryTest.java new file mode 100644 index 000000000..85c6ed321 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/TaskCreationWithHarborRegistryTest.java @@ -0,0 +1,275 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.rest.task; + +import static com.nvidia.boot.mock.BootTestConstants.TEST_HARBOR_CONTAINER_IMAGE_NOT_EXISTS; +import static com.nvidia.boot.mock.BootTestConstants.TEST_HARBOR_CONTAINER_IMAGE_PERMISSION_DENIED; +import static com.nvidia.boot.mock.BootTestConstants.TEST_HARBOR_CONTAINER_IMAGE_WITH_DIGEST; +import static com.nvidia.boot.mock.BootTestConstants.TEST_HARBOR_CONTAINER_IMAGE_WITH_TAG; +import static com.nvidia.boot.mock.BootTestConstants.TEST_HARBOR_HELM_CHART_NOT_EXISTS; +import static com.nvidia.boot.mock.BootTestConstants.TEST_HARBOR_HELM_CHART_PERMISSION_DENIED; +import static com.nvidia.boot.mock.BootTestConstants.TEST_HARBOR_HELM_CHART_WITH_DIGEST; +import static com.nvidia.boot.mock.BootTestConstants.TEST_HARBOR_HELM_CHART_WITH_TAG; +import static com.nvidia.nvct.IntegrationTestConfiguration.MOCK_OAUTH2_TOKEN_SERVER; +import static com.nvidia.nvct.util.NvctConstants.SCOPE_LAUNCH_TASK; +import static com.nvidia.nvct.util.NvctConstants.SCOPE_LIST_TASKS; +import static com.nvidia.nvct.util.TestConstants.TEST_CLIENT_SUBJECT; +import static com.nvidia.nvct.util.TestConstants.TEST_CONTAINER_ARGS; +import static com.nvidia.nvct.util.TestConstants.TEST_DESCRIPTION; +import static com.nvidia.nvct.util.TestConstants.TEST_NCA_ID; +import static com.nvidia.nvct.util.TestConstants.TEST_OCI_GPU_SPEC_DTO; +import static com.nvidia.nvct.util.TestConstants.TEST_OCI_GPU_SPEC_HELM_CONFIG_DTO; +import static com.nvidia.nvct.util.TestConstants.TEST_RESULTS_LOCATION_2; +import static com.nvidia.nvct.util.TestConstants.TEST_SECRETS; +import static com.nvidia.nvct.util.TestConstants.TEST_TAGS; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_NAME_1; +import static org.assertj.core.api.Assertions.assertThat; + +import tools.jackson.databind.json.JsonMapper; +import com.nvidia.boot.mock.harbor.MockHarborAuthServer; +import com.nvidia.boot.mock.ngc.MockCasServer; +import com.nvidia.boot.mock.oci.MockOciRegistryServer; +import com.nvidia.nvct.IntegrationTestConfiguration; +import com.nvidia.nvct.NvctTestApp; +import com.nvidia.nvct.grpc.TestTaskService; +import com.nvidia.nvct.rest.task.dto.CreateTaskRequest; +import com.nvidia.nvct.rest.task.dto.ResultHandlingStrategyEnum; +import com.nvidia.nvct.rest.task.dto.TaskResponse; +import com.nvidia.nvct.rest.task.dto.TaskStatusEnum; +import com.nvidia.nvct.service.account.AccountService; +import com.nvidia.nvct.util.MockEssServer; +import com.nvidia.nvct.util.MockNotaryServer; +import com.nvidia.nvct.util.MockNvcfServer; +import com.nvidia.nvct.util.MockRevalServer; +import com.nvidia.nvct.util.MockIcmsServer; +import java.net.URI; +import java.net.URL; +import java.time.Duration; +import java.util.List; +import java.util.stream.Stream; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.resttestclient.TestRestTemplate; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.RequestEntity; +import org.springframework.test.context.ContextConfiguration; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@Slf4j +@SpringBootTest( + classes = {NvctTestApp.class, IntegrationTestConfiguration.class}, + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + properties = "spring.profiles.active=test") +@ContextConfiguration(initializers = IntegrationTestConfiguration.Initializer.class) +@AutoConfigureTestRestTemplate +class TaskCreationWithHarborRegistryTest { + + @Autowired + private TestRestTemplate testRestTemplate; + + @Autowired + private AccountService accountService; + + @Autowired + private JsonMapper jsonMapper; + + @Autowired + private TestTaskService testTaskService; + + @Value("${nvct.ess.base-url}") + private String essBaseUrl; + + @Value("${nvct.notary.base-url}") + private String notaryBaseUrl; + + @Value("${spring.security.oauth2.client.registration.notary.client-id}") + private String notaryClientId; + + @Value("${nvct.reval.base-url}") + private URI revalBaseUrl; + + @Value("${nvct.nvcf.base-url}") + private URL nvcfBaseUrl; + + @Value("${nvct.icms.base-url}") + private URL icmsBaseUrl; + + @Value("${nvct.registries.recognized.model.ngc.hostname}") + private String casBaseUrl; + + @Value("${nvct.registries.recognized.model.ngc.oauth2.base-url}") + private String authnBaseUrl; + + @Value("${nvct.registries.recognized.container.harbor.hostname}") + private String harborBaseUrl; + + @Value("${nvct.registries.recognized.container.harbor.oauth2.base-url}") + private String harborAuthBaseUrl; + + MockOciRegistryServer mockHarborRegistryServer; + + @BeforeAll + void beforeAll() { + log.info("{}: Started running tests", this.getClass().getSimpleName()); + MockNvcfServer.start(nvcfBaseUrl); + MockIcmsServer.start(icmsBaseUrl, jsonMapper); + MockCasServer.start(authnBaseUrl, casBaseUrl); + MockEssServer.start(essBaseUrl); + MockNotaryServer.start(notaryBaseUrl, notaryClientId); + MockRevalServer.start(revalBaseUrl); + mockHarborRegistryServer = new MockOciRegistryServer(); + mockHarborRegistryServer.start(harborBaseUrl); + MockHarborAuthServer.start(harborAuthBaseUrl); + } + + @AfterAll + void cleanup() { + MockNvcfServer.stop(); + MockIcmsServer.stop(); + MockCasServer.stop(); + MockEssServer.stop(); + MockNotaryServer.stop(); + MockRevalServer.stop(); + mockHarborRegistryServer.stop(); + MockHarborAuthServer.stop(); + + log.info("{}: Completed running tests", this.getClass().getSimpleName()); + } + + @AfterEach + void reset() { + accountService.invalidateCache(); + testTaskService.clearAll(); + } + + Stream createTaskWithContainerImageArgs() { + return Stream.of( + // existing harbor image + Arguments.of(TEST_HARBOR_CONTAINER_IMAGE_WITH_TAG, HttpStatus.OK), + Arguments.of(TEST_HARBOR_CONTAINER_IMAGE_WITH_DIGEST, HttpStatus.OK), + // harbor image tag does not exist + Arguments.of(TEST_HARBOR_CONTAINER_IMAGE_NOT_EXISTS, HttpStatus.NOT_FOUND), + // harbor image mismatch with secret + Arguments.of(TEST_HARBOR_CONTAINER_IMAGE_PERMISSION_DENIED, + HttpStatus.FORBIDDEN)); + } + + @ParameterizedTest + @MethodSource("createTaskWithContainerImageArgs") + void shouldLaunchContainerBasedTask( + URI containerImage, + HttpStatus expectedStatus) { + var token = MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100); + var requestBodyBuilder = CreateTaskRequest.builder() + .name(TEST_TASK_NAME_1) + .containerArgs(TEST_CONTAINER_ARGS) + .containerImage(containerImage) + .tags(TEST_TAGS) + .gpuSpecification(TEST_OCI_GPU_SPEC_DTO) + .maxRuntimeDuration(Duration.ofHours(2)) + .maxQueuedDuration(Duration.ofHours(1)) + .terminationGracePeriodDuration(Duration.ofHours(1)) + .description(TEST_DESCRIPTION) + .resultHandlingStrategy(ResultHandlingStrategyEnum.UPLOAD) + .resultsLocation(TEST_RESULTS_LOCATION_2) + .secrets(TEST_SECRETS); + var requestEntity = RequestEntity.post(URI.create("/v1/nvct/tasks")) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", "Bearer " + token) + .body(requestBodyBuilder.build()); + var responseEntity = + testRestTemplate.exchange(requestEntity, TaskResponse.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(expectedStatus); + if (expectedStatus.isError()) { + return; + } + + var responseBody = responseEntity.getBody(); + assertThat(responseBody).isNotNull(); + assertThat(responseBody.task().id()).isNotNull(); + assertThat(responseBody.task().name()).isEqualTo(TEST_TASK_NAME_1); + assertThat(responseBody.task().status()).isEqualTo(TaskStatusEnum.QUEUED); + assertThat(responseBody.task().ncaId()).isEqualTo(TEST_NCA_ID); + assertThat(responseBody.task().createdAt()).isNotNull(); + assertThat(responseBody.task().containerImage()).isEqualTo(containerImage); + } + + Stream createTaskWithHelmChartArgs() { + return Stream.of( + // existing harbor helm chart + Arguments.of(TEST_HARBOR_HELM_CHART_WITH_TAG, HttpStatus.OK), + Arguments.of(TEST_HARBOR_HELM_CHART_WITH_DIGEST, HttpStatus.OK), + // harbor helm chart tag does not exist + Arguments.of(TEST_HARBOR_HELM_CHART_NOT_EXISTS, HttpStatus.NOT_FOUND), + // harbor helm chart mismatch with secret + Arguments.of(TEST_HARBOR_HELM_CHART_PERMISSION_DENIED, HttpStatus.FORBIDDEN)); + } + + @ParameterizedTest + @MethodSource("createTaskWithHelmChartArgs") + void shouldLaunchTasksWithHelmCharts( + URI helmChart, + HttpStatus expectedStatus) { + var token = MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100); + var requestBodyBuilder = CreateTaskRequest.builder() + .name(TEST_TASK_NAME_1) + .helmChart(helmChart) + .tags(TEST_TAGS) + .gpuSpecification(TEST_OCI_GPU_SPEC_HELM_CONFIG_DTO) + .maxRuntimeDuration(Duration.ofHours(2)) + .maxQueuedDuration(Duration.ofHours(1)) + .terminationGracePeriodDuration(Duration.ofHours(1)) + .description(TEST_DESCRIPTION) + .resultHandlingStrategy(ResultHandlingStrategyEnum.UPLOAD) + .resultsLocation(TEST_RESULTS_LOCATION_2) + .secrets(TEST_SECRETS); + var requestEntity = RequestEntity.post(URI.create("/v1/nvct/tasks")) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", "Bearer " + token) + .body(requestBodyBuilder.build()); + var responseEntity = + testRestTemplate.exchange(requestEntity, TaskResponse.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(expectedStatus); + if (expectedStatus.isError()) { + return; + } + + var responseBody = responseEntity.getBody(); + assertThat(responseBody).isNotNull(); + assertThat(responseBody.task().id()).isNotNull(); + assertThat(responseBody.task().name()).isEqualTo(TEST_TASK_NAME_1); + assertThat(responseBody.task().status()).isEqualTo(TaskStatusEnum.QUEUED); + assertThat(responseBody.task().ncaId()).isEqualTo(TEST_NCA_ID); + assertThat(responseBody.task().createdAt()).isNotNull(); + assertThat(responseBody.task().helmChart()).isEqualTo(helmChart); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/TaskCreationWithVolcengineRegistryTest.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/TaskCreationWithVolcengineRegistryTest.java new file mode 100644 index 000000000..04b5832b3 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/TaskCreationWithVolcengineRegistryTest.java @@ -0,0 +1,263 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.rest.task; + +import static com.nvidia.boot.mock.BootTestConstants.TEST_VOLCENGINE_CONTAINER_IMAGE_TAG_NOT_FOUND; +import static com.nvidia.boot.mock.BootTestConstants.TEST_VOLCENGINE_CONTAINER_IMAGE_WITH_TAG; +import static com.nvidia.boot.mock.BootTestConstants.TEST_VOLCENGINE_HELM_CHART_TAG_NOT_FOUND; +import static com.nvidia.boot.mock.BootTestConstants.TEST_VOLCENGINE_HELM_CHART_WITH_TAG; +import static com.nvidia.nvct.IntegrationTestConfiguration.MOCK_OAUTH2_TOKEN_SERVER; +import static com.nvidia.nvct.util.NvctConstants.SCOPE_LAUNCH_TASK; +import static com.nvidia.nvct.util.NvctConstants.SCOPE_LIST_TASKS; +import static com.nvidia.nvct.util.TestConstants.TEST_CLIENT_SUBJECT; +import static com.nvidia.nvct.util.TestConstants.TEST_CONTAINER_ARGS; +import static com.nvidia.nvct.util.TestConstants.TEST_DESCRIPTION; +import static com.nvidia.nvct.util.TestConstants.TEST_NCA_ID; +import static com.nvidia.nvct.util.TestConstants.TEST_OCI_GPU_SPEC_DTO; +import static com.nvidia.nvct.util.TestConstants.TEST_OCI_GPU_SPEC_HELM_CONFIG_DTO; +import static com.nvidia.nvct.util.TestConstants.TEST_RESULTS_LOCATION_2; +import static com.nvidia.nvct.util.TestConstants.TEST_SECRETS; +import static com.nvidia.nvct.util.TestConstants.TEST_TAGS; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_NAME_1; +import static org.assertj.core.api.Assertions.assertThat; + +import tools.jackson.databind.json.JsonMapper; +import com.nvidia.boot.mock.ngc.MockCasServer; +import com.nvidia.boot.mock.ngc.MockNgcContainerRegistryServer; +import com.nvidia.boot.mock.volcengine.MockVolcengineRegistryServer; +import com.nvidia.nvct.IntegrationTestConfiguration; +import com.nvidia.nvct.NvctTestApp; +import com.nvidia.nvct.grpc.TestTaskService; +import com.nvidia.nvct.rest.task.dto.CreateTaskRequest; +import com.nvidia.nvct.rest.task.dto.ResultHandlingStrategyEnum; +import com.nvidia.nvct.rest.task.dto.TaskResponse; +import com.nvidia.nvct.rest.task.dto.TaskStatusEnum; +import com.nvidia.nvct.service.account.AccountService; +import com.nvidia.nvct.util.MockEssServer; +import com.nvidia.nvct.util.MockNotaryServer; +import com.nvidia.nvct.util.MockNvcfServer; +import com.nvidia.nvct.util.MockRevalServer; +import com.nvidia.nvct.util.MockIcmsServer; +import java.net.URI; +import java.net.URL; +import java.time.Duration; +import java.util.List; +import java.util.stream.Stream; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.resttestclient.TestRestTemplate; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.RequestEntity; +import org.springframework.test.context.ContextConfiguration; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@Slf4j +@SpringBootTest( + classes = {NvctTestApp.class, IntegrationTestConfiguration.class}, + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + properties = "spring.profiles.active=test") +@ContextConfiguration(initializers = IntegrationTestConfiguration.Initializer.class) +@AutoConfigureTestRestTemplate +class TaskCreationWithVolcengineRegistryTest { + + @Autowired + private TestRestTemplate testRestTemplate; + + @Autowired + private AccountService accountService; + + @Autowired + private JsonMapper jsonMapper; + + @Autowired + private TestTaskService testTaskService; + + @Value("${nvct.ess.base-url}") + private String essBaseUrl; + + @Value("${nvct.notary.base-url}") + private String notaryBaseUrl; + + @Value("${spring.security.oauth2.client.registration.notary.client-id}") + private String notaryClientId; + + @Value("${nvct.reval.base-url}") + private URI revalBaseUrl; + + @Value("${nvct.nvcf.base-url}") + private URL nvcfBaseUrl; + + @Value("${nvct.icms.base-url}") + private URL icmsBaseUrl; + + @Value("${nvct.registries.recognized.container.ngc.hostname}") + private String ngcContainerRegistryHostname; + + @Value("${nvct.registries.recognized.model.ngc.hostname}") + private String casBaseUrl; + + @Value("${nvct.registries.recognized.model.ngc.oauth2.base-url}") + private String authnBaseUrl; + + @Value("${nvct.registries.recognized.container.volcengine.hostname}") + private String volcengineBaseUrl; + + @BeforeAll + void beforeAll() { + log.info("{}: Started running tests", this.getClass().getSimpleName()); + MockNvcfServer.start(nvcfBaseUrl); + MockIcmsServer.start(icmsBaseUrl, jsonMapper); + MockCasServer.start(authnBaseUrl, casBaseUrl); + MockEssServer.start(essBaseUrl); + MockNotaryServer.start(notaryBaseUrl, notaryClientId); + MockRevalServer.start(revalBaseUrl); + MockNgcContainerRegistryServer.start(ngcContainerRegistryHostname); + MockVolcengineRegistryServer.start(volcengineBaseUrl); + } + + @AfterAll + void cleanup() { + MockNvcfServer.stop(); + MockIcmsServer.stop(); + MockCasServer.stop(); + MockEssServer.stop(); + MockNotaryServer.stop(); + MockRevalServer.stop(); + MockNgcContainerRegistryServer.stop(); + MockVolcengineRegistryServer.stop(); + + log.info("{}: Completed running tests", this.getClass().getSimpleName()); + } + + @AfterEach + void reset() { + accountService.invalidateCache(); + testTaskService.clearAll(); + } + + Stream createTaskWithContainerImageArgs() { + return Stream.of( + // existing volcengine image + Arguments.of(TEST_VOLCENGINE_CONTAINER_IMAGE_WITH_TAG, HttpStatus.OK), + // volcengine image tag does not exist + Arguments.of(TEST_VOLCENGINE_CONTAINER_IMAGE_TAG_NOT_FOUND, HttpStatus.NOT_FOUND) + ); + } + + @ParameterizedTest + @MethodSource("createTaskWithContainerImageArgs") + void shouldLaunchContainerBasedTask( + URI containerImage, + HttpStatus expectedStatus) { + var token = MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100); + var requestBodyBuilder = CreateTaskRequest.builder() + .name(TEST_TASK_NAME_1) + .containerArgs(TEST_CONTAINER_ARGS) + .containerImage(containerImage) + .tags(TEST_TAGS) + .gpuSpecification(TEST_OCI_GPU_SPEC_DTO) + .maxRuntimeDuration(Duration.ofHours(2)) + .maxQueuedDuration(Duration.ofHours(1)) + .terminationGracePeriodDuration(Duration.ofHours(1)) + .description(TEST_DESCRIPTION) + .resultHandlingStrategy(ResultHandlingStrategyEnum.UPLOAD) + .resultsLocation(TEST_RESULTS_LOCATION_2) + .secrets(TEST_SECRETS); + var requestEntity = RequestEntity.post(URI.create("/v1/nvct/tasks")) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", "Bearer " + token) + .body(requestBodyBuilder.build()); + var responseEntity = + testRestTemplate.exchange(requestEntity, TaskResponse.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(expectedStatus); + if (expectedStatus.isError()) { + return; + } + + var responseBody = responseEntity.getBody(); + assertThat(responseBody).isNotNull(); + assertThat(responseBody.task().id()).isNotNull(); + assertThat(responseBody.task().name()).isEqualTo(TEST_TASK_NAME_1); + assertThat(responseBody.task().status()).isEqualTo(TaskStatusEnum.QUEUED); + assertThat(responseBody.task().ncaId()).isEqualTo(TEST_NCA_ID); + assertThat(responseBody.task().createdAt()).isNotNull(); + assertThat(responseBody.task().containerImage()).isEqualTo(containerImage); + } + + Stream createTaskWithHelmChartArgs() { + return Stream.of( + // existing volcengine helm chart + Arguments.of(TEST_VOLCENGINE_HELM_CHART_WITH_TAG, HttpStatus.OK), + // volcengine helm chart tag does not exist + Arguments.of(TEST_VOLCENGINE_HELM_CHART_TAG_NOT_FOUND, HttpStatus.NOT_FOUND) + ); + } + + @ParameterizedTest + @MethodSource("createTaskWithHelmChartArgs") + void shouldLaunchTasksWithHelmCharts( + URI helmChart, + HttpStatus expectedStatus) { + var token = MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100); + var requestBodyBuilder = CreateTaskRequest.builder() + .name(TEST_TASK_NAME_1) + .helmChart(helmChart) + .tags(TEST_TAGS) + .gpuSpecification(TEST_OCI_GPU_SPEC_HELM_CONFIG_DTO) + .maxRuntimeDuration(Duration.ofHours(2)) + .maxQueuedDuration(Duration.ofHours(1)) + .terminationGracePeriodDuration(Duration.ofHours(1)) + .description(TEST_DESCRIPTION) + .resultHandlingStrategy(ResultHandlingStrategyEnum.UPLOAD) + .resultsLocation(TEST_RESULTS_LOCATION_2) + .secrets(TEST_SECRETS); + var requestEntity = RequestEntity.post(URI.create("/v1/nvct/tasks")) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", "Bearer " + token) + .body(requestBodyBuilder.build()); + var responseEntity = + testRestTemplate.exchange(requestEntity, TaskResponse.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(expectedStatus); + if (expectedStatus.isError()) { + return; + } + + var responseBody = responseEntity.getBody(); + assertThat(responseBody).isNotNull(); + assertThat(responseBody.task().id()).isNotNull(); + assertThat(responseBody.task().name()).isEqualTo(TEST_TASK_NAME_1); + assertThat(responseBody.task().status()).isEqualTo(TaskStatusEnum.QUEUED); + assertThat(responseBody.task().ncaId()).isEqualTo(TEST_NCA_ID); + assertThat(responseBody.task().createdAt()).isNotNull(); + assertThat(responseBody.task().helmChart()).isEqualTo(helmChart); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/TaskCreationWithoutRegistryCredentialsTest.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/TaskCreationWithoutRegistryCredentialsTest.java new file mode 100644 index 000000000..8a3ef13dc --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/TaskCreationWithoutRegistryCredentialsTest.java @@ -0,0 +1,260 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.rest.task; + +import static com.nvidia.nvct.IntegrationTestConfiguration.MOCK_OAUTH2_TOKEN_SERVER; +import static com.nvidia.nvct.util.NvctConstants.SCOPE_LAUNCH_TASK; +import static com.nvidia.nvct.util.NvctConstants.SCOPE_LIST_TASKS; +import static com.nvidia.nvct.util.TestConstants.TEST_CLIENT_SUBJECT; +import static com.nvidia.nvct.util.TestConstants.TEST_CONTAINER_ARGS; +import static com.nvidia.nvct.util.TestConstants.TEST_CUSTOM_CONTAINER_IMAGE_WITH_TAG_1; +import static com.nvidia.nvct.util.TestConstants.TEST_CUSTOM_HELM_CHART_WITH_TAG_1; +import static com.nvidia.nvct.util.TestConstants.TEST_DESCRIPTION; +import static com.nvidia.nvct.util.TestConstants.TEST_MODEL_DTOS; +import static com.nvidia.nvct.util.TestConstants.TEST_NCA_ID; +import static com.nvidia.nvct.util.TestConstants.TEST_OCI_GPU_SPEC_DTO; +import static com.nvidia.nvct.util.TestConstants.TEST_OCI_GPU_SPEC_HELM_CONFIG_DTO; +import static com.nvidia.nvct.util.TestConstants.TEST_RESOURCE_DTOS; +import static com.nvidia.nvct.util.TestConstants.TEST_RESULTS_LOCATION_2; +import static com.nvidia.nvct.util.TestConstants.TEST_SECRETS; +import static com.nvidia.nvct.util.TestConstants.TEST_TAGS; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_NAME_1; +import static org.assertj.core.api.Assertions.assertThat; + +import tools.jackson.databind.json.JsonMapper; +import com.nvidia.boot.mock.ngc.MockCasServer; +import com.nvidia.boot.mock.ngc.MockNgcContainerRegistryServer; +import com.nvidia.nvct.IntegrationTestConfiguration; +import com.nvidia.nvct.NvctTestApp; +import com.nvidia.nvct.grpc.TestTaskService; +import com.nvidia.nvct.rest.task.dto.CreateTaskRequest; +import com.nvidia.nvct.rest.task.dto.ResultHandlingStrategyEnum; +import com.nvidia.nvct.rest.task.dto.TaskResponse; +import com.nvidia.nvct.rest.task.dto.TaskStatusEnum; +import com.nvidia.nvct.service.account.AccountService; +import com.nvidia.nvct.util.MockEssServer; +import com.nvidia.nvct.util.MockNotaryServer; +import com.nvidia.nvct.util.MockNvcfServer; +import com.nvidia.nvct.util.MockRevalServer; +import com.nvidia.nvct.util.MockIcmsServer; +import java.net.URI; +import java.net.URL; +import java.time.Duration; +import java.util.List; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.resttestclient.TestRestTemplate; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.RequestEntity; +import org.springframework.test.context.ContextConfiguration; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@Slf4j +@SpringBootTest( + classes = {NvctTestApp.class, IntegrationTestConfiguration.class}, + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + properties = "spring.profiles.active=test") +@ContextConfiguration(initializers = IntegrationTestConfiguration.Initializer.class) +@AutoConfigureTestRestTemplate +class TaskCreationWithoutRegistryCredentialsTest { + + @Autowired + private TestRestTemplate testRestTemplate; + + @Autowired + private AccountService accountService; + + @Autowired + private JsonMapper jsonMapper; + + @Autowired + private TestTaskService testTaskService; + + @Value("${nvct.ess.base-url}") + private String essBaseUrl; + + @Value("${nvct.notary.base-url}") + private String notaryBaseUrl; + + @Value("${spring.security.oauth2.client.registration.notary.client-id}") + private String notaryClientId; + + @Value("${nvct.reval.base-url}") + private URI revalBaseUrl; + + @Value("${nvct.nvcf.base-url}") + private URL nvcfBaseUrl; + + @Value("${nvct.icms.base-url}") + private URL icmsBaseUrl; + + @Value("${nvct.registries.recognized.container.ngc.hostname}") + private String ngcContainerRegistryHostname; + + @Value("${nvct.registries.recognized.model.ngc.hostname}") + private String casBaseUrl; + + @Value("${nvct.registries.recognized.model.ngc.oauth2.base-url}") + private String authnBaseUrl; + + @BeforeAll + void beforeAll() { + log.info("{}: Started running tests", this.getClass().getSimpleName()); + MockNvcfServer.start(nvcfBaseUrl); + MockIcmsServer.start(icmsBaseUrl, jsonMapper); + MockCasServer.start(authnBaseUrl, casBaseUrl); + MockEssServer.start(essBaseUrl); + MockNotaryServer.start(notaryBaseUrl, notaryClientId); + MockRevalServer.start(revalBaseUrl); + MockNgcContainerRegistryServer.start(ngcContainerRegistryHostname); + } + + @AfterAll + void cleanup() { + MockNvcfServer.stop(); + MockIcmsServer.stop(); + MockCasServer.stop(); + MockEssServer.stop(); + MockNotaryServer.stop(); + MockRevalServer.stop(); + MockNgcContainerRegistryServer.stop(); + log.info("{}: Completed running tests", this.getClass().getSimpleName()); + } + + @AfterEach + void reset() { + accountService.invalidateCache(); + testTaskService.clearAll(); + } + + @Test + void shouldCreateContainerTaskWithoutRegistryCredentials() { + var token = MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), 100); + + var requestBody = CreateTaskRequest.builder() + .name(TEST_TASK_NAME_1) + .containerArgs(TEST_CONTAINER_ARGS) + .containerImage(TEST_CUSTOM_CONTAINER_IMAGE_WITH_TAG_1) + .tags(TEST_TAGS) + .gpuSpecification(TEST_OCI_GPU_SPEC_DTO) + .maxRuntimeDuration(Duration.ofHours(2)) + .maxQueuedDuration(Duration.ofHours(1)) + .terminationGracePeriodDuration(Duration.ofHours(1)) + .description(TEST_DESCRIPTION) + .resultHandlingStrategy(ResultHandlingStrategyEnum.UPLOAD) + .resultsLocation(TEST_RESULTS_LOCATION_2) + .secrets(TEST_SECRETS) + .build(); + var requestEntity = RequestEntity.post(URI.create("/v1/nvct/tasks")) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", "Bearer " + token) + .body(requestBody); + + var responseEntity = testRestTemplate.exchange(requestEntity, TaskResponse.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK); + + var responseBody = responseEntity.getBody(); + assertThat(responseBody).isNotNull(); + assertThat(responseBody.task().id()).isNotNull(); + assertThat(responseBody.task().name()).isEqualTo(TEST_TASK_NAME_1); + assertThat(responseBody.task().status()).isEqualTo(TaskStatusEnum.QUEUED); + assertThat(responseBody.task().ncaId()).isEqualTo(TEST_NCA_ID); + assertThat(responseBody.task().containerImage()) + .isEqualTo(TEST_CUSTOM_CONTAINER_IMAGE_WITH_TAG_1); + } + + @Test + void shouldCreateHelmTaskWithoutRegistryCredentials() { + var token = MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), 100); + + var requestBody = CreateTaskRequest.builder() + .name(TEST_TASK_NAME_1) + .helmChart(TEST_CUSTOM_HELM_CHART_WITH_TAG_1) + .tags(TEST_TAGS) + .gpuSpecification(TEST_OCI_GPU_SPEC_HELM_CONFIG_DTO) + .maxRuntimeDuration(Duration.ofHours(2)) + .maxQueuedDuration(Duration.ofHours(1)) + .terminationGracePeriodDuration(Duration.ofHours(1)) + .description(TEST_DESCRIPTION) + .resultHandlingStrategy(ResultHandlingStrategyEnum.UPLOAD) + .resultsLocation(TEST_RESULTS_LOCATION_2) + .secrets(TEST_SECRETS) + .build(); + var requestEntity = RequestEntity.post(URI.create("/v1/nvct/tasks")) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", "Bearer " + token) + .body(requestBody); + + var responseEntity = testRestTemplate.exchange(requestEntity, TaskResponse.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK); + + var responseBody = responseEntity.getBody(); + assertThat(responseBody).isNotNull(); + assertThat(responseBody.task().id()).isNotNull(); + assertThat(responseBody.task().name()).isEqualTo(TEST_TASK_NAME_1); + assertThat(responseBody.task().status()).isEqualTo(TaskStatusEnum.QUEUED); + assertThat(responseBody.task().ncaId()).isEqualTo(TEST_NCA_ID); + assertThat(responseBody.task().helmChart()) + .isEqualTo(TEST_CUSTOM_HELM_CHART_WITH_TAG_1); + } + + @Test + void shouldCreateContainerTaskWithNgcModelAndResourceWithoutContainerCredentials() { + var token = MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), 100); + + var requestBody = CreateTaskRequest.builder() + .name(TEST_TASK_NAME_1) + .containerArgs(TEST_CONTAINER_ARGS) + .containerImage(TEST_CUSTOM_CONTAINER_IMAGE_WITH_TAG_1) + .models(TEST_MODEL_DTOS) + .resources(TEST_RESOURCE_DTOS) + .tags(TEST_TAGS) + .gpuSpecification(TEST_OCI_GPU_SPEC_DTO) + .maxRuntimeDuration(Duration.ofHours(2)) + .maxQueuedDuration(Duration.ofHours(1)) + .terminationGracePeriodDuration(Duration.ofHours(1)) + .description(TEST_DESCRIPTION) + .resultHandlingStrategy(ResultHandlingStrategyEnum.UPLOAD) + .resultsLocation(TEST_RESULTS_LOCATION_2) + .secrets(TEST_SECRETS) + .build(); + var requestEntity = RequestEntity.post(URI.create("/v1/nvct/tasks")) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", "Bearer " + token) + .body(requestBody); + + var responseEntity = testRestTemplate.exchange(requestEntity, TaskResponse.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK); + + var responseBody = responseEntity.getBody(); + assertThat(responseBody).isNotNull(); + assertThat(responseBody.task().id()).isNotNull(); + assertThat(responseBody.task().status()).isEqualTo(TaskStatusEnum.QUEUED); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/TaskManagementControllerTest.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/TaskManagementControllerTest.java new file mode 100644 index 000000000..62d0c7695 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/TaskManagementControllerTest.java @@ -0,0 +1,2335 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.rest.task; + +import static com.nvidia.boot.registries.service.registry.client.ngc.NgcRegistryUtils.removeArtifactHostName; +import static com.nvidia.nvct.IntegrationTestConfiguration.MOCK_OAUTH2_TOKEN_SERVER; +import static com.nvidia.nvct.persistence.task.entity.TaskStatus.CANCELED; +import static com.nvidia.nvct.persistence.task.entity.TaskStatus.COMPLETED; +import static com.nvidia.nvct.persistence.task.entity.TaskStatus.ERRORED; +import static com.nvidia.nvct.persistence.task.entity.TaskStatus.QUEUED; +import static com.nvidia.nvct.util.NvctConstants.MAX_TAGS_COUNT; +import static com.nvidia.nvct.util.NvctConstants.MAX_TAG_LENGTH; +import static com.nvidia.nvct.util.NvctConstants.NGC_API_KEY; +import static com.nvidia.nvct.util.NvctConstants.SCOPE_CANCEL_TASK; +import static com.nvidia.nvct.util.NvctConstants.SCOPE_DELETE_TASK; +import static com.nvidia.nvct.util.NvctConstants.SCOPE_LAUNCH_TASK; +import static com.nvidia.nvct.util.NvctConstants.SCOPE_LIST_TASKS; +import static com.nvidia.nvct.util.NvctConstants.SCOPE_TASK_DETAILS; +import static com.nvidia.nvct.util.TestConstants.BASE_ARTIFACT_URL; +import static com.nvidia.nvct.util.TestConstants.GFN; +import static com.nvidia.nvct.util.TestConstants.L40G; +import static com.nvidia.nvct.util.TestConstants.L40G_INSTANCE_TYPE; +import static com.nvidia.nvct.util.TestConstants.MODEL_ARTIFACTS_URL_2; +import static com.nvidia.nvct.util.TestConstants.MODEL_ARTIFACTS_URL_3; +import static com.nvidia.nvct.util.TestConstants.MODEL_ARTIFACTS_URL_4; +import static com.nvidia.nvct.util.TestConstants.MODEL_ARTIFACTS_URL_MISSING_PROTOCOL_1; +import static com.nvidia.nvct.util.TestConstants.MODEL_ARTIFACTS_URL_NOT_EXISTS_1; +import static com.nvidia.nvct.util.TestConstants.MODEL_ARTIFACTS_URL_NOT_SUPPORTED_REGISTRY_1; +import static com.nvidia.nvct.util.TestConstants.MODEL_ARTIFACTS_URL_PERMISSION_DENIED_REGISTRY_1; +import static com.nvidia.nvct.util.TestConstants.MODEL_ARTIFACTS_URL_UNKNOWN_REGISTRY_1; +import static com.nvidia.nvct.util.TestConstants.MODEL_ARTIFACTS_URL_WITH_CANARY_HOST; +import static com.nvidia.nvct.util.TestConstants.RESOURCE_ARTIFACTS_URL_2; +import static com.nvidia.nvct.util.TestConstants.RESOURCE_ARTIFACTS_URL_3; +import static com.nvidia.nvct.util.TestConstants.RESOURCE_ARTIFACTS_URL_4; +import static com.nvidia.nvct.util.TestConstants.RESOURCE_ARTIFACTS_URL_MISSING_PROTOCOL_1; +import static com.nvidia.nvct.util.TestConstants.RESOURCE_ARTIFACTS_URL_NOT_EXISTS_1; +import static com.nvidia.nvct.util.TestConstants.RESOURCE_ARTIFACTS_URL_NOT_SUPPORTED_REGISTRY_1; +import static com.nvidia.nvct.util.TestConstants.RESOURCE_ARTIFACTS_URL_PERMISSION_DENIED_REGISTRY_1; +import static com.nvidia.nvct.util.TestConstants.RESOURCE_ARTIFACTS_URL_UNKNOWN_REGISTRY_1; +import static com.nvidia.nvct.util.TestConstants.RESOURCE_ARTIFACTS_URL_WITH_CANARY_HOST_1; +import static com.nvidia.nvct.util.TestConstants.TEST_CLIENT_ID; +import static com.nvidia.nvct.util.TestConstants.TEST_CLIENT_ID_2; +import static com.nvidia.nvct.util.TestConstants.TEST_CLIENT_ID_5; +import static com.nvidia.nvct.util.TestConstants.TEST_CLIENT_SUBJECT; +import static com.nvidia.nvct.util.TestConstants.TEST_CONTAINER_ARGS; +import static com.nvidia.nvct.util.TestConstants.TEST_CONTAINER_ENVIRONMENT; +import static com.nvidia.nvct.util.TestConstants.TEST_CONTAINER_IMAGE; +import static com.nvidia.nvct.util.TestConstants.TEST_CONTAINER_IMAGE_NOT_EXISTS; +import static com.nvidia.nvct.util.TestConstants.TEST_CONTAINER_IMAGE_NOT_SUPPORTED; +import static com.nvidia.nvct.util.TestConstants.TEST_CONTAINER_IMAGE_PERMISSION_DENIED; +import static com.nvidia.nvct.util.TestConstants.TEST_CONTAINER_IMAGE_UNKNOWN_REGISTRY; +import static com.nvidia.nvct.util.TestConstants.TEST_CONTAINER_IMAGE_WITHOUT_TAG; +import static com.nvidia.nvct.util.TestConstants.TEST_CONTAINER_IMAGE_WITH_CANARY_HOST; +import static com.nvidia.nvct.util.TestConstants.TEST_CONTAINER_IMAGE_WITH_DIGEST; +import static com.nvidia.nvct.util.TestConstants.TEST_CONTAINER_IMAGE_WITH_INVALID_TAG; +import static com.nvidia.nvct.util.TestConstants.TEST_DESCRIPTION; +import static com.nvidia.nvct.util.TestConstants.TEST_MODELS; +import static com.nvidia.nvct.util.TestConstants.TEST_MODEL_NAME; +import static com.nvidia.nvct.util.TestConstants.TEST_NCA_ID; +import static com.nvidia.nvct.util.TestConstants.TEST_OCI_GPU_SPEC_DTO; +import static com.nvidia.nvct.util.TestConstants.TEST_OWNER_ID; +import static com.nvidia.nvct.util.TestConstants.TEST_RESOURCES; +import static com.nvidia.nvct.util.TestConstants.TEST_RESULTS_LOCATION_1; +import static com.nvidia.nvct.util.TestConstants.TEST_RESULTS_LOCATION_2; +import static com.nvidia.nvct.util.TestConstants.TEST_TAGS; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_ID_1; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_ID_2; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_ID_3; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_NAME_1; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_NAME_2; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_NAME_3; +import static com.nvidia.nvct.util.TestConstants.TEST_UNKNOWN_ORG_NAME; +import static com.nvidia.nvct.util.TestConstants.TEST_UNKNOWN_TEAM_NAME; +import static com.nvidia.nvct.util.TestConstants.TEST_VALID_ORG_NAME; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.fail; + +import tools.jackson.databind.json.JsonMapper; +import tools.jackson.databind.node.StringNode; +import com.nvidia.boot.exceptions.NotFoundException; +import com.nvidia.boot.mock.ngc.MockCasServer; +import com.nvidia.boot.mock.ngc.MockNgcContainerRegistryServer; +import com.nvidia.nvct.IntegrationTestConfiguration; +import com.nvidia.nvct.NvctTestApp; +import com.nvidia.nvct.grpc.TestTaskService; +import com.nvidia.nvct.persistence.task.TasksRepository; +import com.nvidia.nvct.persistence.task.entity.TaskStatus; +import com.nvidia.nvct.rest.task.dto.ArtifactDto; +import com.nvidia.nvct.rest.task.dto.ContainerEnvironmentEntryDto; +import com.nvidia.nvct.rest.task.dto.CreateTaskRequest; +import com.nvidia.nvct.rest.task.dto.GpuSpecificationDto; +import com.nvidia.nvct.rest.task.dto.ListTasksResponse; +import com.nvidia.nvct.rest.task.dto.ResultHandlingStrategyEnum; +import com.nvidia.nvct.rest.task.dto.SecretDto; +import com.nvidia.nvct.rest.task.dto.TaskDto; +import com.nvidia.nvct.rest.task.dto.TaskResponse; +import com.nvidia.nvct.rest.task.dto.TaskStatusEnum; +import com.nvidia.nvct.service.account.AccountService; +import com.nvidia.nvct.service.apikeys.ApiKeyValidationResult.Resource; +import com.nvidia.nvct.service.apikeys.ApiKeysService; +import com.nvidia.nvct.service.task.TaskMapperService; +import com.nvidia.nvct.util.MockApiKeysServer; +import com.nvidia.nvct.util.MockEssServer; +import com.nvidia.nvct.util.MockNotaryServer; +import com.nvidia.nvct.util.MockNvcfServer; +import com.nvidia.nvct.util.MockIcmsServer; +import com.nvidia.nvct.util.TestUtil; +import java.net.URI; +import java.net.URL; +import java.time.Duration; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.UUID; +import java.util.function.Function; +import java.util.function.Supplier; +import java.util.stream.Collectors; +import java.util.stream.IntStream; +import java.util.stream.Stream; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.resttestclient.TestRestTemplate; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.RequestEntity; +import org.springframework.test.context.ContextConfiguration; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@Slf4j +@SpringBootTest( + classes = {NvctTestApp.class, IntegrationTestConfiguration.class}, + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + properties = "spring.profiles.active=test") +@ContextConfiguration(initializers = IntegrationTestConfiguration.Initializer.class) +@AutoConfigureTestRestTemplate +class TaskManagementControllerTest { + + @Autowired + private TestRestTemplate testRestTemplate; + + @Autowired + private AccountService accountService; + + @Autowired + private ApiKeysService apiKeysService; + + @Autowired + private TasksRepository tasksRepository; + + @Autowired + private JsonMapper jsonMapper; + + @Autowired + private TestTaskService testTaskService; + + @Autowired + private TaskMapperService taskMapperService; + + @Value("${nvct.registries.recognized.model.ngc.hostname}") + private String casBaseUrl; + + @Value("${nvct.registries.recognized.model.ngc.oauth2.base-url}") + private String authnBaseUrl; + + @Value("${nvct.ess.base-url}") + private String essBaseUrl; + + @Value("${nvct.notary.base-url}") + private String notaryBaseUrl; + + @Value("${spring.security.oauth2.client.registration.notary.client-id}") + private String notaryClientId; + + @Value("${nvct.nvcf.base-url}") + private URL nvcfBaseUrl; + + @Value("${nvct.icms.base-url}") + private URL icmsBaseUrl; + + @Value("${nvct.api-keys.base-url}") + private String apiKeysBaseUrl; + + @Value("${nvct.registries.recognized.container.ngc.hostname}") + private String ngcContainerRegistryHostname; + + @BeforeAll + void beforeAll() { + log.info("{}: Started running tests", this.getClass().getSimpleName()); + MockApiKeysServer.start(apiKeysBaseUrl); + MockNvcfServer.start(nvcfBaseUrl); + MockIcmsServer.start(icmsBaseUrl, jsonMapper); + MockCasServer.start(authnBaseUrl, casBaseUrl); + MockEssServer.start(essBaseUrl); + MockNgcContainerRegistryServer.start(ngcContainerRegistryHostname); + MockNotaryServer.start(notaryBaseUrl, notaryClientId); + } + + @AfterAll + void cleanup() { + MockApiKeysServer.stop(); + MockNvcfServer.stop(); + MockIcmsServer.stop(); + MockCasServer.stop(); + MockEssServer.stop(); + MockNotaryServer.stop(); + MockNgcContainerRegistryServer.stop(); + log.info("{}: Completed running tests", this.getClass().getSimpleName()); + } + + @AfterEach + void reset() { + MockApiKeysServer.resetToDefault(); + // use of MockApiKeysServer with different scopes causes the api-keys cache to dirty + apiKeysService.invalidateCache(); + accountService.invalidateCache(); + testTaskService.clearAll(); + } + + + Stream createTaskArgs() { + var validGfnSpec = GpuSpecificationDto.builder() + .gpu(L40G).instanceType(L40G_INSTANCE_TYPE).backend(GFN) + .clusters(Set.of("cluster01", "cluster02")).build(); + var specWithMissingInstanceType = GpuSpecificationDto.builder() + .gpu(L40G).backend(GFN).clusters(Set.of("cluster01", "cluster02")).build(); + var specWithInvalidInstanceType = GpuSpecificationDto.builder() + .gpu(L40G).backend(GFN).instanceType("invalid-instance-type").build(); + var specWithMissingBackend = GpuSpecificationDto.builder() + .gpu(L40G).instanceType(L40G_INSTANCE_TYPE).build(); + var specWithClusters = GpuSpecificationDto.builder() + .gpu(L40G).instanceType(L40G_INSTANCE_TYPE) + .clusters(Set.of("cluster01", "cluster02")).build(); + var specWithMissingGpu = GpuSpecificationDto.builder() + .backend(GFN).instanceType(L40G_INSTANCE_TYPE).build(); + var specWithInvalidGpu = GpuSpecificationDto.builder() + .gpu("invalid-gpu").backend(GFN).instanceType(L40G_INSTANCE_TYPE).build(); + var specWithNonEmptyConfiguration = + GpuSpecificationDto.builder().gpu(L40G).instanceType(L40G_INSTANCE_TYPE) + .clusters(Set.of("cluster01", "cluster02")) + .configuration(jsonMapper.createObjectNode().put("foo", "bar")) + .build(); + var secretJsonNodeValue = jsonMapper.createObjectNode() + .put("AWS_REGION", "us-west-2") + .put("AWS_BUCKET", "ov-content") + .put("AWS_ACCESS_KEY_ID", "ov-content-key-id") + .put("AWS_SECRET_ACCESS_KEY", "ov-content-access-key") + .put("AWS_SESSION_TOKEN", "ov-content-session-token"); + var secrets = Set.of(SecretDto.builder() + .name(NGC_API_KEY) + .value(new StringNode("shhh!shhh!")) + .build(), + SecretDto.builder() + .name("secret2") + .value(secretJsonNodeValue) + .build()); + var containerEnvKeyWithHyphen = + List.of(ContainerEnvironmentEntryDto.builder().key("KEY-1").value("VALUE_1") + .build(), + ContainerEnvironmentEntryDto.builder().key("KEY_2").value("VALUE_2") + .build()); + var containerEnvKeyWithSpace = + List.of(ContainerEnvironmentEntryDto.builder().key("KEY 1").value("VALUE_1") + .build(), + ContainerEnvironmentEntryDto.builder().key("KEY_2").value("VALUE_2") + .build()); + var containerEnvKeyWithDollar = + List.of(ContainerEnvironmentEntryDto.builder().key("KEY$1").value("VALUE_1") + .build(), + ContainerEnvironmentEntryDto.builder().key("KEY_2").value("VALUE_2") + .build()); + + + var jwtCases = Stream.of( + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100), + TEST_CONTAINER_IMAGE, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_2, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.OK), + // URIs containing team name. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100), + TEST_CONTAINER_IMAGE, + MODEL_ARTIFACTS_URL_2, + RESOURCE_ARTIFACTS_URL_2, + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_1, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.OK), + // non-fully qualified model/resource URLS + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100), + TEST_CONTAINER_IMAGE, + removeArtifactHostName(MODEL_ARTIFACTS_URL_3), + removeArtifactHostName(RESOURCE_ARTIFACTS_URL_3), + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_2, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.BAD_REQUEST), + // Model URI containing version name. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100), + TEST_CONTAINER_IMAGE, + MODEL_ARTIFACTS_URL_4, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_1, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.BAD_REQUEST), + // Model artifact with canary hostname + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100), + TEST_CONTAINER_IMAGE, + MODEL_ARTIFACTS_URL_WITH_CANARY_HOST, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_2, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.OK), + // Model artifact with unknown registry + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100), + TEST_CONTAINER_IMAGE, + MODEL_ARTIFACTS_URL_UNKNOWN_REGISTRY_1, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_2, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.BAD_REQUEST), + // Model artifact url without protocol + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100), + TEST_CONTAINER_IMAGE, + MODEL_ARTIFACTS_URL_MISSING_PROTOCOL_1, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_2, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.BAD_REQUEST), + // Model artifact with not supported registry + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100), + TEST_CONTAINER_IMAGE, + MODEL_ARTIFACTS_URL_NOT_SUPPORTED_REGISTRY_1, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_2, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.BAD_REQUEST), + // Model artifact with invalid token + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100), + TEST_CONTAINER_IMAGE, + MODEL_ARTIFACTS_URL_PERMISSION_DENIED_REGISTRY_1, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_2, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.FORBIDDEN), + // Model artifact not exists + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100), + TEST_CONTAINER_IMAGE, + MODEL_ARTIFACTS_URL_NOT_EXISTS_1, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_2, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.NOT_FOUND), + // Resource URI containing version name. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100), + TEST_CONTAINER_IMAGE, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_4, + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_1, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.BAD_REQUEST), + // Resource artifact with canary registry + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100), + TEST_CONTAINER_IMAGE, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_WITH_CANARY_HOST_1, + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_2, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.OK), + // Resource artifact with unknown registry + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100), + TEST_CONTAINER_IMAGE, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_UNKNOWN_REGISTRY_1, + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_2, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.BAD_REQUEST), + // Resource artifact url without protocol + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100), + TEST_CONTAINER_IMAGE, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_MISSING_PROTOCOL_1, + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_2, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.BAD_REQUEST), + // Resource artifact with not supported registry + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100), + TEST_CONTAINER_IMAGE, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_NOT_SUPPORTED_REGISTRY_1, + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_2, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.BAD_REQUEST), + // Resource artifact with invalid token + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100), + TEST_CONTAINER_IMAGE, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_PERMISSION_DENIED_REGISTRY_1, + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_2, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.FORBIDDEN), + // Resource artifact not exists + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100), + TEST_CONTAINER_IMAGE, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_NOT_EXISTS_1, + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_2, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.NOT_FOUND), + // Optional model. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100), + TEST_CONTAINER_IMAGE, + null, + RESOURCE_ARTIFACTS_URL_2, + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_1, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.OK), + // Optional resource. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100), + TEST_CONTAINER_IMAGE, + MODEL_ARTIFACTS_URL_3, + null, + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_1, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.OK), + // Model URI does not end with "/files". + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100), + TEST_CONTAINER_IMAGE, + BASE_ARTIFACT_URL + "/v2/org/ajwc672qsbdd/models/svc/bis-test:v1", + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_1, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.BAD_REQUEST), + // Null GpuSpecificationDto. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100), + TEST_CONTAINER_IMAGE, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + null, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_1, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.BAD_REQUEST), + // Missing instanceType in GpuSpec. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100), + TEST_CONTAINER_IMAGE, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + specWithMissingInstanceType, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_1, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.BAD_REQUEST), + // Invalid instanceType in GpuSpec. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100), + TEST_CONTAINER_IMAGE, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + specWithInvalidInstanceType, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_1, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.BAD_REQUEST), + // Missing gpu in GpuSpec. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100), + TEST_CONTAINER_IMAGE, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + specWithMissingGpu, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_1, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.BAD_REQUEST), + // Invalid gpu in GpuSpec. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100), + TEST_CONTAINER_IMAGE, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + specWithInvalidGpu, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_1, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.BAD_REQUEST), + // Missing backend in GpuSpec. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100), + TEST_CONTAINER_IMAGE, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + specWithMissingBackend, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_1, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.OK), + // Clusters only in GpuSpec. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100), + TEST_CONTAINER_IMAGE, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + specWithClusters, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_1, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.OK), + // Unknown client trying to create a task in an unknown account. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt("some-unknown-client", + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100), + TEST_CONTAINER_IMAGE, + MODEL_ARTIFACTS_URL_3, + null, + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_1, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.NOT_FOUND), + // Missing scope. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, List.of(), 100), + TEST_CONTAINER_IMAGE, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_1, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.FORBIDDEN), + // Missing token. + Arguments.of(null, + TEST_CONTAINER_IMAGE, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_1, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.UNAUTHORIZED), + // Too many tags (limit=64). + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100), + TEST_CONTAINER_IMAGE, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + IntStream.range(0, MAX_TAGS_COUNT + 1).mapToObj(i -> "tag" + i) + .collect(Collectors.toSet()), + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_1, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.BAD_REQUEST), + // Too long tags (limit=128). + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100), + TEST_CONTAINER_IMAGE, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + Set.of(StringUtils.repeat("tag1", MAX_TAG_LENGTH), + StringUtils.repeat("tag2", MAX_TAG_LENGTH)), + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_1, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.BAD_REQUEST), + // Invalid tag character. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100), + TEST_CONTAINER_IMAGE, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + Set.of("\n&abc123["), + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_1, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.BAD_REQUEST), + // Null maxRuntimeDuration with non-GFN backend. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100), + TEST_CONTAINER_IMAGE, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + null, + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_1, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.OK), + // Null maxRuntimeDuration with GFN backend. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100), + TEST_CONTAINER_IMAGE, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + validGfnSpec, + null, + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_1, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.BAD_REQUEST), + // Greater than 8hours of maxRuntimeDuration with GFN backend. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100), + TEST_CONTAINER_IMAGE, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + validGfnSpec, + Duration.ofHours(9), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_1, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.BAD_REQUEST), + // Zero maxRuntimeDuration + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100), + TEST_CONTAINER_IMAGE, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + validGfnSpec, + Duration.ZERO, + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_1, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.BAD_REQUEST), + // Zero maxQueuedDuration + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100), + TEST_CONTAINER_IMAGE, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + validGfnSpec, + Duration.ofHours(4), + Duration.ZERO, + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_1, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.BAD_REQUEST), + // Zero terminationGacePeriodDuration + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100), + TEST_CONTAINER_IMAGE, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + validGfnSpec, + Duration.ofHours(4), + Duration.ofHours(3), + Duration.ZERO, + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_1, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.BAD_REQUEST), + // Null maxQueuedDuration. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100), + TEST_CONTAINER_IMAGE, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + validGfnSpec, + Duration.ofHours(2), + null, + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_1, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.OK), + // Null terminationGracePeriodDuration. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100), + TEST_CONTAINER_IMAGE, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + validGfnSpec, + Duration.ofHours(2), + Duration.ofHours(3), + null, + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_1, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.OK), + // terminationGracePeriodDuration greater than maxRuntimeDuration. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100), + TEST_CONTAINER_IMAGE, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + validGfnSpec, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(4), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_1, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.BAD_REQUEST), + // Default terminationGracePeriodDuration greater than maxRuntimeDuration. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100), + TEST_CONTAINER_IMAGE, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + validGfnSpec, + Duration.ofMinutes(30), // 30minutes + Duration.ofHours(3), + null, // Default terminationGracePeriodDuration 1h + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_1, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.BAD_REQUEST), + // Null secrets with resultHandlingStrategy UPLOAD + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100), + TEST_CONTAINER_IMAGE, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + null, + TEST_RESULTS_LOCATION_1, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.BAD_REQUEST), + // No NGC_API_KEY in secrets with resultHandlingStrategy UPLOAD + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100), + TEST_CONTAINER_IMAGE, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + Set.of(SecretDto.builder() + .name("secret-key") + .value(new StringNode("shhh!shhh!")) + .build()), + TEST_RESULTS_LOCATION_1, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.BAD_REQUEST), + // Invalid resultsLocation with just org name and resultsHandlingStrategy UPLOAD + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100), + TEST_CONTAINER_IMAGE, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + "orgA", + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.BAD_REQUEST), + // Invalid resultsLocation with just trailing slash after org name. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100), + TEST_CONTAINER_IMAGE, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + "orgA/", + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.BAD_REQUEST), + // Invalid resultsLocation with trailing slash after team name. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100), + TEST_CONTAINER_IMAGE, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + "orgA/teamB/", + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.BAD_REQUEST), + // Invalid resultsLocation with trailing slash after model name. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100), + TEST_CONTAINER_IMAGE, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + "orgA/teamB/modelC/", + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.BAD_REQUEST), + // Invalid resultsLocation with more than org, team, and model names in the path. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100), + TEST_CONTAINER_IMAGE, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + "orgA/teamB/modelC/extraD", + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.BAD_REQUEST), + // Invalid/unknown org name in resultsLocation. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100), + TEST_CONTAINER_IMAGE, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_UNKNOWN_ORG_NAME + "/" + TEST_MODEL_NAME, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.NOT_FOUND), + // Invalid/unknown team name in resultsLocation. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100), + TEST_CONTAINER_IMAGE, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_VALID_ORG_NAME + "/" + TEST_UNKNOWN_TEAM_NAME + "/" + + TEST_MODEL_NAME, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.NOT_FOUND), + // Invalid resultsLocation with just org name and resultsHandlingStrategy NONE. + // resultsLocation is not validated if resultHandlingStrategy is NONE. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100), + TEST_CONTAINER_IMAGE, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.NONE, + secrets, + "orgA", + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.OK), + // Blank resultsLocation with resultsHandlingStrategy NONE. + // resultsLocation is not validated if resultHandlingStrategy is NONE. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100), + TEST_CONTAINER_IMAGE, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.NONE, + secrets, + null, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.OK), + // No NGC_API_KEY in secrets with resultHandlingStrategy NONE. Presence of + // NGC_API_KEY in the secrets is not validated if resultHandlingStrategy is NONE. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100), + TEST_CONTAINER_IMAGE, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.NONE, + Set.of(SecretDto.builder() + .name("secret-key") + .value(new StringNode("shhh!shhh!")) + .build()), + TEST_RESULTS_LOCATION_1, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.OK), + // Null secrets with resultHandlingStrategy NONE. Presence of NGC_API_KEY in + // the secrets is not validated if resultHandlingStrategy is NONE. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100), + TEST_CONTAINER_IMAGE, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.NONE, + null, + TEST_RESULTS_LOCATION_1, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.OK), + // Environment key with hyphen. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100), + TEST_CONTAINER_IMAGE, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_2, + containerEnvKeyWithHyphen, + HttpStatus.BAD_REQUEST), + // Environment key with space. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100), + TEST_CONTAINER_IMAGE, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_2, + containerEnvKeyWithSpace, + HttpStatus.BAD_REQUEST), + // Environment key with dollar. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100), + TEST_CONTAINER_IMAGE, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_2, + containerEnvKeyWithDollar, + HttpStatus.BAD_REQUEST), + // bad task tags + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100), + TEST_CONTAINER_IMAGE, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + Set.of("\n&abc123["), + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_2, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.BAD_REQUEST), + // Tags with special namespace:key=value + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100), + TEST_CONTAINER_IMAGE, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + Set.of("namespace:key=value"), + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_2, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.OK), + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100), + TEST_CONTAINER_IMAGE_WITH_CANARY_HOST, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_2, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.OK), + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100), + TEST_CONTAINER_IMAGE_UNKNOWN_REGISTRY, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_2, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.BAD_REQUEST), + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100), + TEST_CONTAINER_IMAGE_WITHOUT_TAG, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_2, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.OK), + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100), + TEST_CONTAINER_IMAGE_WITH_DIGEST, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_2, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.OK), + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100), + TEST_CONTAINER_IMAGE_NOT_EXISTS, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_2, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.NOT_FOUND), + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100), + TEST_CONTAINER_IMAGE_WITH_INVALID_TAG, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_2, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.BAD_REQUEST), + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100), + TEST_CONTAINER_IMAGE_PERMISSION_DENIED, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_2, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.FORBIDDEN), + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100), + TEST_CONTAINER_IMAGE_NOT_SUPPORTED, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_2, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.BAD_REQUEST), + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100), + TEST_CONTAINER_IMAGE, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + specWithNonEmptyConfiguration, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_2, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.BAD_REQUEST)); + + var apiKeysCases = Stream.of( + // api-key with launch_task scope and account-tasks resource + Arguments.of((Supplier) () -> { + MockApiKeysServer.setResponse(TEST_NCA_ID, TEST_OWNER_ID, + List.of(new Resource("account-tasks", "*")), + List.of("launch_task")); + return "nvapi-stg-some-key"; + }, + TEST_CONTAINER_IMAGE, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_2, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.OK), + // api-key with scope but no resources + Arguments.of((Supplier) () -> { + MockApiKeysServer.setResponse(TEST_NCA_ID, TEST_OWNER_ID, + List.of(), + List.of("launch_task")); + return "nvapi-stg-some-key"; + }, + TEST_CONTAINER_IMAGE, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_2, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.FORBIDDEN), + // api-key with missing scope + Arguments.of((Supplier) () -> { + MockApiKeysServer.setResponse(TEST_NCA_ID, TEST_OWNER_ID, + List.of(), List.of()); + return "nvapi-stg-some-key"; + }, + TEST_CONTAINER_IMAGE, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_2, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.FORBIDDEN) + ); + + return Stream.concat(jwtCases, apiKeysCases); + } + + @ParameterizedTest + @MethodSource("createTaskArgs") + void shouldCreateTask(Object tokenSupplier, + URI containerImage, + String modelUri, + String resourceUri, + Set tags, + GpuSpecificationDto gpuSpecificationDto, + Duration maxRuntimeDuration, + Duration maxQueuedDuration, + Duration terminationGracePeriodDuration, + ResultHandlingStrategyEnum resultHandlingStrategy, + Set secrets, + String resultsLocation, + List containerEnvironment, + HttpStatus expectedStatus) { + var requestBodyBuilder = CreateTaskRequest.builder() + .name(TEST_TASK_NAME_1) + .containerArgs(TEST_CONTAINER_ARGS) + .containerImage(containerImage) + .tags(tags) + .gpuSpecification(gpuSpecificationDto) + .maxRuntimeDuration(maxRuntimeDuration) + .maxQueuedDuration(maxQueuedDuration) + .terminationGracePeriodDuration(terminationGracePeriodDuration) + .description(TEST_DESCRIPTION) + .resultsLocation(resultsLocation) + .resultHandlingStrategy(resultHandlingStrategy) + .secrets(secrets) + .containerEnvironment(containerEnvironment); + + if (StringUtils.isNotBlank(modelUri)) { + requestBodyBuilder.models(Set.of( + ArtifactDto.builder().name("model-1") + .version("1.0") + .uri(URI.create(modelUri)) + .build())); + } + + if (StringUtils.isNotBlank(resourceUri)) { + requestBodyBuilder.resources(Set.of( + ArtifactDto.builder().name("resource-1") + .version("1.0") + .uri(URI.create(resourceUri)) + .build())); + } + var token = TestUtil.getToken(tokenSupplier); + var requestEntity = RequestEntity.post(URI.create("/v1/nvct/tasks")) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", "Bearer " + token) + .body(requestBodyBuilder.build()); + var responseEntity = + testRestTemplate.exchange(requestEntity, TaskResponse.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(expectedStatus); + if (expectedStatus.isError()) { + return; + } + + var responseBody = responseEntity.getBody(); + assertThat(responseBody).isNotNull(); + assertThat(responseBody.task().id()).isNotNull(); + assertThat(responseBody.task().name()).isEqualTo(TEST_TASK_NAME_1); + assertThat(responseBody.task().status()).isEqualTo(TaskStatusEnum.QUEUED); + assertThat(responseBody.task().ncaId()).isEqualTo(TEST_NCA_ID); + assertThat(responseBody.task().containerArgs()).isEqualTo(TEST_CONTAINER_ARGS); + assertThat(responseBody.task().helmChart()).isNull(); + assertThat(responseBody.task().containerImage()).isEqualTo(containerImage); + assertThat(responseBody.task().containerEnvironment()).isEqualTo(containerEnvironment); + assertThat(responseBody.task().createdAt()).isNotNull(); + assertThat(responseBody.task().gpuSpecification()).isEqualTo(gpuSpecificationDto); + assertThat(responseBody.task().telemetries()).isNull(); + + if (StringUtils.isNotBlank(resultsLocation)) { + assertThat(responseBody.task().resultsLocation()).isEqualTo(resultsLocation); + } else { + assertThat(responseBody.task().resultsLocation()).isBlank(); + } + + if (resultHandlingStrategy != null) { + assertThat(responseBody.task().resultHandlingStrategy()) + .isEqualTo(resultHandlingStrategy); + } else { + assertThat(responseBody.task().resultHandlingStrategy()).isNull(); + } + + if (maxRuntimeDuration != null) { + assertThat(responseBody.task().maxRuntimeDuration()).isNotNull(); + assertThat(responseBody.task().maxRuntimeDuration().toString()) + .hasToString(maxRuntimeDuration.toString()); + } else { + assertThat(responseBody.task().maxRuntimeDuration()).isNull(); + } + assertThat(responseBody.task().maxQueuedDuration()).isNotNull(); + if (maxQueuedDuration != null) { + assertThat(responseBody.task().maxQueuedDuration().toString()) + .hasToString(maxQueuedDuration.toString()); + } else { + assertThat(responseBody.task().maxQueuedDuration().toString()) + .hasToString("PT72H"); // Default value. + } + assertThat(responseBody.task().terminationGracePeriodDuration()).isNotNull(); + if (terminationGracePeriodDuration != null) { + assertThat(responseBody.task().terminationGracePeriodDuration().toString()) + .hasToString(terminationGracePeriodDuration.toString()); + } else { + assertThat(responseBody.task().terminationGracePeriodDuration().toString()) + .hasToString("PT1H"); // Default value + } + + if (StringUtils.isNotBlank(modelUri)) { + assertThat(responseBody.task().models()).isNotNull().hasSize(1); + var model = responseBody.task().models().stream().findFirst().get(); + if (modelUri.startsWith("http")) { + assertThat(model.getUri()).isEqualTo(URI.create(modelUri)); + } else { + // Make sure it already be transformed to fully-qualified url. + // Since we are reading the artifact hostname from + assertThat(model.getUri()).isEqualTo(URI.create("https://localhost-ngc" + modelUri)); + } + } else { + assertThat(responseBody.task().models()).isNull(); + } + if (StringUtils.isNotBlank(resourceUri)) { + assertThat(responseBody.task().resources()).isNotNull().hasSize(1); + var resource = responseBody.task().resources().stream().findFirst().get(); + if (resourceUri.startsWith("http")) { + assertThat(resource.getUri()).isEqualTo(URI.create(resourceUri)); + } else { + // Make sure it already be transformed to fully-qualified url. + assertThat(resource.getUri()).isEqualTo( + URI.create("https://localhost-ngc" + resourceUri)); + } + } else { + assertThat(responseBody.task().resources()).isNull(); + } + + assertThat(responseBody.task().tags()).isEqualTo(tags); + assertThat(responseBody.task().description()).isEqualTo(TEST_DESCRIPTION); + + var taskId = responseBody.task().id(); + var entity = tasksRepository + .getByTaskId(taskId) + .orElseThrow(() -> new NotFoundException("Task not found")); + assertThat(entity).isNotNull(); + assertThat(entity.getHealth()).isBlank(); + } + + @Test + void shouldThrowExceptionForTooLongDescription() { + var token = MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK), + 100); + var requestBody = CreateTaskRequest.builder() + .name(TEST_TASK_NAME_1) + .containerArgs(TEST_CONTAINER_ARGS) + .containerImage(TEST_CONTAINER_IMAGE) + .tags(TEST_TAGS) + .gpuSpecification(TEST_OCI_GPU_SPEC_DTO) + .maxRuntimeDuration(Duration.ofHours(2)) + .maxQueuedDuration(Duration.ofHours(3)) + .terminationGracePeriodDuration(Duration.ofHours(1)) + // Create a description that exceeds MAX_DESCRIPTION_LENGTH (256) + .description(StringUtils.repeat("a", 257)) + .resultHandlingStrategy(ResultHandlingStrategyEnum.NONE) + .containerEnvironment(TEST_CONTAINER_ENVIRONMENT) + .build(); + + var requestEntity = RequestEntity.post(URI.create("/v1/nvct/tasks")) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", "Bearer " + token) + .body(requestBody); + + var responseEntity = testRestTemplate.exchange(requestEntity, TaskResponse.class); + + assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.BAD_REQUEST); + } + + @Test + @Disabled + void shouldThrowTooManyTasksException() { + // Create 1st Task in TEST_NCA_ID_WITH_1_MAX_ALLOWED_TASKS_5 account that is + // associated with client TEST_CLIENT_ID_5. TEST_NCA_ID_WITH_1_MAX_ALLOWED_TASKS_5 is + // set up with maxTasksAllowed = 1. + var token = MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_ID_5, + List.of(SCOPE_LAUNCH_TASK), + 100); + var requestBodyBuilder = CreateTaskRequest.builder() + .name(TEST_TASK_NAME_1) + .containerArgs(TEST_CONTAINER_ARGS) + .containerImage(TEST_CONTAINER_IMAGE) + .tags(TEST_TAGS) + .gpuSpecification(GpuSpecificationDto.builder() + .gpu(L40G).instanceType(L40G_INSTANCE_TYPE).backend(GFN) + .clusters(Set.of("cluster01", "cluster02")).build()) + .maxRuntimeDuration(Duration.ofHours(2)) + .maxQueuedDuration(Duration.ofHours(2)) + .terminationGracePeriodDuration(Duration.ofHours(2)) + .description(TEST_DESCRIPTION) + .resultHandlingStrategy(ResultHandlingStrategyEnum.NONE) + .containerEnvironment(TEST_CONTAINER_ENVIRONMENT); + var requestEntity = RequestEntity.post(URI.create("/v1/nvct/tasks")) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", "Bearer " + token) + .body(requestBodyBuilder.build()); + var responseEntity = + testRestTemplate.exchange(requestEntity, TaskResponse.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK); + + // Create 2nd Task, expecting BAD_REQUEST. + var secondRequestEntity = RequestEntity.post(URI.create("/v1/nvct/tasks")) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", "Bearer " + token) + .body(requestBodyBuilder.build()); + responseEntity = testRestTemplate.exchange(secondRequestEntity, TaskResponse.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.BAD_REQUEST); + } + + Stream listTasksArgs() { + return Stream.of( + // List tasks in TEST_NCA_ID account + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_ID, + List.of(SCOPE_LIST_TASKS), + 100), + List.of(TEST_TASK_ID_1, TEST_TASK_ID_2), + HttpStatus.OK), + // List non-existent tasks in TEST_NCA_ID_2 account + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_ID_2, + List.of(SCOPE_LIST_TASKS), + 100), + List.of(), + HttpStatus.OK), + // Unknown client listing tasks in an unknown account + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt("unknown-client-id", + List.of(SCOPE_LIST_TASKS), + 100), + List.of(), + HttpStatus.NOT_FOUND), + // Missing scope. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_ID, List.of(), 100), + List.of(), + HttpStatus.FORBIDDEN), + // Missing token. + Arguments.of(null, + List.of(), + HttpStatus.UNAUTHORIZED) + ); + } + + @ParameterizedTest + @MethodSource("listTasksArgs") + void shouldListTasks(String token, List expectedTasks, HttpStatus expectedStatus) { + // Create Tasks in TEST_NCA_ID account tied to TEST_CLIENT_ID. + var task1 = TestUtil.createTaskEntity(TEST_TASK_ID_1, TEST_NCA_ID, TEST_TASK_NAME_1, + jsonMapper); + var task2 = TestUtil.createTaskEntity(TEST_TASK_ID_2, TEST_NCA_ID, TEST_TASK_NAME_2, + jsonMapper); + + // Save tasks. + tasksRepository.save(task1); + tasksRepository.save(task2); + + var requestEntity = + RequestEntity.get(URI.create("/v1/nvct/tasks")) + .header("Authorization", "Bearer " + token) + .build(); + var responseEntity = + testRestTemplate.exchange(requestEntity, ListTasksResponse.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(expectedStatus); + if (expectedStatus.isError()) { + return; + } + + var responseBody = responseEntity.getBody(); + assertThat(responseBody).isNotNull(); + assertThat(responseBody.cursor()).isNull(); + assertThat(responseBody.limit()).isNull(); + assertThat(expectedTasks).isNotNull(); + assertThat(responseBody.tasks()).hasSize(expectedTasks.size()); + var tasks = responseBody.tasks().stream() + .collect(Collectors.toMap(TaskDto::id, Function.identity())); + assertThat(tasks.keySet()).isEqualTo(new HashSet<>(expectedTasks)); + + verifyReturnedTasksIntegrity(expectedTasks, QUEUED, tasks); + } + + void verifyReturnedTasksIntegrity( + List expectedTasks, + TaskStatus expectedStatus, + Map tasks) { + for (UUID expectedTaskId : expectedTasks) { + var taskDto = tasks.get(expectedTaskId); + assertThat(taskDto).isNotNull(); + assertThat(taskDto.createdAt()).isNotNull(); + assertThat(taskDto.status()).isEqualTo( + TaskStatusEnum.fromText(expectedStatus.toString())); + assertThat(taskDto.containerImage()).isNotNull(); + assertThat(taskDto.containerArgs()).isNotBlank(); + assertThat(taskDto.containerEnvironment()).hasSize(3); + if (taskDto.id().equals(TEST_TASK_ID_1)) { + assertThat(taskDto.name()).isEqualTo(TEST_TASK_NAME_1); + } else if (taskDto.id().equals(TEST_TASK_ID_2)) { + assertThat(taskDto.name()).isEqualTo(TEST_TASK_NAME_2); + } else if (taskDto.id().equals(TEST_TASK_ID_3)) { + assertThat(taskDto.name()).isEqualTo(TEST_TASK_NAME_3); + } else { + fail("unknown function returned"); + } + assertThat(taskDto.description()).isNotEmpty(); + assertThat(taskDto.tags()).isNotEmpty(); + assertThat(taskDto.gpuSpecification()).isNotNull(); + assertThat(taskDto.models()) + .isEqualTo(taskMapperService.getModelDtos(TEST_MODELS).get()); + assertThat(taskDto.resources()) + .isEqualTo(taskMapperService.getResourceDtos(TEST_RESOURCES).get()); + } + } + + Stream taskArgs() { + var jwtCases = Stream.of( + // TEST_TASK_ID_1 belongs to NCA ID tied to TEST_CLIENT_ID. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_ID, + List.of(SCOPE_TASK_DETAILS, + SCOPE_CANCEL_TASK, + SCOPE_DELETE_TASK), + 100), + TEST_TASK_ID_1, + HttpStatus.OK), + // TEST_TASK_ID_3 does not exist. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_ID, + List.of(SCOPE_TASK_DETAILS, + SCOPE_CANCEL_TASK, + SCOPE_DELETE_TASK), + 100), + TEST_TASK_ID_3, + HttpStatus.NOT_FOUND), + // TEST_TASK_ID_1 does not belong to the NCA ID tied to TEST_CLIENT_ID_2. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_ID_2, + List.of(SCOPE_TASK_DETAILS, + SCOPE_CANCEL_TASK, + SCOPE_DELETE_TASK), + 100), + TEST_TASK_ID_1, + HttpStatus.NOT_FOUND), + // Unknown subject/client. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt("unknown-client-id", + List.of(SCOPE_TASK_DETAILS, + SCOPE_CANCEL_TASK, + SCOPE_DELETE_TASK), + 100), + TEST_TASK_ID_1, + HttpStatus.NOT_FOUND), + // Missing scope. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_ID, List.of(), 100), + TEST_TASK_ID_1, + HttpStatus.FORBIDDEN), + // No token. + Arguments.of(null, + TEST_TASK_ID_1, + HttpStatus.UNAUTHORIZED) + ); + + var apiKeysCases = Stream.of( + // api-key with task_details scope and account-tasks resource + Arguments.of((Supplier) () -> { + MockApiKeysServer.setResponse(TEST_NCA_ID, TEST_OWNER_ID, + List.of(new Resource("account-tasks", "*")), + List.of("task_details")); + return "nvapi-stg-some-key"; + }, + TEST_TASK_ID_1, + HttpStatus.OK), + // api-key with task_details scope and specific task resource (matching) + Arguments.of((Supplier) () -> { + MockApiKeysServer.setResponse(TEST_NCA_ID, TEST_OWNER_ID, + List.of(new Resource("task", TEST_TASK_ID_1.toString())), + List.of("task_details")); + return "nvapi-stg-some-key"; + }, + TEST_TASK_ID_1, + HttpStatus.OK), + // api-key with task_details scope and specific task resource (not matching) + Arguments.of((Supplier) () -> { + MockApiKeysServer.setResponse(TEST_NCA_ID, TEST_OWNER_ID, + List.of(new Resource("task", TEST_TASK_ID_2.toString())), + List.of("task_details")); + return "nvapi-stg-some-key"; + }, + TEST_TASK_ID_1, + HttpStatus.FORBIDDEN), + // api-key with scope but no resources + Arguments.of((Supplier) () -> { + MockApiKeysServer.setResponse(TEST_NCA_ID, TEST_OWNER_ID, + List.of(), + List.of("task_details")); + return "nvapi-stg-some-key"; + }, + TEST_TASK_ID_1, + HttpStatus.FORBIDDEN), + // api-key with missing scope + Arguments.of((Supplier) () -> { + MockApiKeysServer.setResponse(TEST_NCA_ID, TEST_OWNER_ID, + List.of(), List.of()); + return "nvapi-stg-some-key"; + }, + TEST_TASK_ID_1, + HttpStatus.FORBIDDEN) + ); + + return Stream.concat(jwtCases, apiKeysCases); + } + + @ParameterizedTest + @MethodSource("taskArgs") + void shouldGetTaskDetails(Object tokenSupplier, UUID taskId, HttpStatus expectedStatus) { + var token = TestUtil.getToken(tokenSupplier); + // Create Tasks in TEST_NCA_ID account tied to TEST_CLIENT_ID. + testTaskService.createTaskWithModelAndResources(TEST_NCA_ID, TEST_TASK_ID_1, + UUID.randomUUID()); + testTaskService.createTaskWithModelAndResources(TEST_NCA_ID, TEST_TASK_ID_2, + UUID.randomUUID()); + + var requestEntity = + RequestEntity.get(URI.create("/v1/nvct/tasks/" + taskId)) + .accept(MediaType.APPLICATION_JSON) + .header("Authorization", "Bearer " + token) + .build(); + var responseEntity = + testRestTemplate.exchange(requestEntity, TaskResponse.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(expectedStatus); + if (expectedStatus.isError()) { + return; + } + + var responseBody = responseEntity.getBody(); + assertThat(responseBody).isNotNull(); + assertThat(responseBody.task()).isNotNull(); + + var taskDto = responseBody.task(); + assertThat(taskDto).isNotNull(); + assertThat(taskDto.createdAt()).isNotNull(); + assertThat(taskDto.status()).isEqualTo(TaskStatusEnum.QUEUED); + assertThat(taskDto.containerImage()).isNotNull(); + assertThat(taskDto.containerArgs()).isNotBlank(); + assertThat(taskDto.containerEnvironment()).hasSize(3); + assertThat(taskDto.name()).isEqualTo("Task-" + taskDto.id()); + assertThat(taskDto.description()).isNotEmpty(); + assertThat(taskDto.tags()).isNotEmpty(); + assertThat(taskDto.gpuSpecification()).isNotNull(); + assertThat(taskDto.models()).isEqualTo(taskMapperService.getModelDtos(TEST_MODELS).get()); + assertThat(taskDto.resources()) + .isEqualTo(taskMapperService.getResourceDtos(TEST_RESOURCES).get()); + assertThat(taskDto.resultsLocation()).isNotEmpty(); + assertThat(taskDto.resultHandlingStrategy()).isEqualTo(ResultHandlingStrategyEnum.UPLOAD); + assertThat(taskDto.instances()).isNotEmpty(); + } + + Stream cancelTaskArgs() { + var jwtCases = Stream.of( + // TEST_TASK_ID_1 belongs to NCA ID tied to TEST_CLIENT_ID. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_ID, + List.of(SCOPE_TASK_DETAILS, + SCOPE_CANCEL_TASK, + SCOPE_DELETE_TASK), + 100), + TEST_TASK_ID_1, + QUEUED, + HttpStatus.OK), + // TEST_TASK_ID_3 does not exist. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_ID, + List.of(SCOPE_TASK_DETAILS, + SCOPE_CANCEL_TASK, + SCOPE_DELETE_TASK), + 100), + TEST_TASK_ID_3, + QUEUED, + HttpStatus.NOT_FOUND), + // TEST_TASK_ID_1 does not belong to the NCA ID tied to TEST_CLIENT_ID_2. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_ID_2, + List.of(SCOPE_TASK_DETAILS, + SCOPE_CANCEL_TASK, + SCOPE_DELETE_TASK), + 100), + TEST_TASK_ID_1, + QUEUED, + HttpStatus.NOT_FOUND), + // Unknown subject/client. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt("unknown-client-id", + List.of(SCOPE_TASK_DETAILS, + SCOPE_CANCEL_TASK, + SCOPE_DELETE_TASK), + 100), + TEST_TASK_ID_1, + QUEUED, + HttpStatus.NOT_FOUND), + // Task status is CANCELED already + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_ID, + List.of(SCOPE_TASK_DETAILS, + SCOPE_CANCEL_TASK, + SCOPE_DELETE_TASK), + 100), + TEST_TASK_ID_1, + CANCELED, + HttpStatus.BAD_REQUEST), + // Task status is ERRORED already + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_ID, + List.of(SCOPE_TASK_DETAILS, + SCOPE_CANCEL_TASK, + SCOPE_DELETE_TASK), + 100), + TEST_TASK_ID_1, + ERRORED, + HttpStatus.BAD_REQUEST), + // Task status is COMPLETED already + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_ID, + List.of(SCOPE_TASK_DETAILS, + SCOPE_CANCEL_TASK, + SCOPE_DELETE_TASK), + 100), + TEST_TASK_ID_1, + COMPLETED, + HttpStatus.BAD_REQUEST), + // Missing scope. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_ID, List.of(), 100), + TEST_TASK_ID_1, + QUEUED, + HttpStatus.FORBIDDEN), + // No token. + Arguments.of(null, + TEST_TASK_ID_1, + QUEUED, + HttpStatus.UNAUTHORIZED) + ); + + var apiKeysCases = Stream.of( + // api-key authorized to cancel any private tasks of TEST_NCA_ID account. + Arguments.of((Supplier) () -> { + MockApiKeysServer.setResponse(TEST_NCA_ID, TEST_OWNER_ID, + List.of(new Resource("account-tasks", "*")), + List.of("cancel_task")); + return "nvapi-stg-some-key"; + }, + TEST_TASK_ID_1, + QUEUED, + HttpStatus.OK), + // api-key authorized to cancel specific task of TEST_NCA_ID account. + Arguments.of((Supplier) () -> { + MockApiKeysServer.setResponse(TEST_NCA_ID, TEST_OWNER_ID, + List.of(new Resource("task", TEST_TASK_ID_1.toString())), + List.of("cancel_task")); + return "nvapi-stg-some-key"; + }, + TEST_TASK_ID_1, + QUEUED, + HttpStatus.OK), + // api-key attempt to cancel a task that does not have a matching resource entry. + Arguments.of((Supplier) () -> { + MockApiKeysServer.setResponse(TEST_NCA_ID, TEST_OWNER_ID, + List.of(new Resource("task", TEST_TASK_ID_2.toString())), + List.of("cancel_task")); + return "nvapi-stg-some-key"; + }, + TEST_TASK_ID_1, + QUEUED, + HttpStatus.FORBIDDEN), + // api-key attempt to cancel with no resource entries in the policy result. + Arguments.of((Supplier) () -> { + MockApiKeysServer.setResponse(TEST_NCA_ID, TEST_OWNER_ID, + List.of(), + List.of("cancel_task")); + return "nvapi-stg-some-key"; + }, + TEST_TASK_ID_1, + QUEUED, + HttpStatus.FORBIDDEN) + ); + + return Stream.concat(jwtCases, apiKeysCases); + } + + @ParameterizedTest + @MethodSource("cancelTaskArgs") + void shouldCancelTask(Object tokenSupplier, UUID taskId, TaskStatus status, HttpStatus expectedStatus) { + var token = TestUtil.getToken(tokenSupplier); + // Create Tasks in TEST_NCA_ID account tied to TEST_CLIENT_ID. + var task1 = TestUtil.createTaskEntity(TEST_TASK_ID_1, TEST_NCA_ID, TEST_TASK_NAME_1, + jsonMapper); + var task2 = TestUtil.createTaskEntity(TEST_TASK_ID_2, TEST_NCA_ID, TEST_TASK_NAME_2, + jsonMapper); + task1.setStatus(status); + task2.setStatus(status); + + // Save tasks. + tasksRepository.save(task1); + tasksRepository.save(task2); + + var requestEntity = + RequestEntity.post(URI.create("/v1/nvct/tasks/" + taskId + "/cancel")) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", "Bearer " + token) + .build(); + var responseEntity = + testRestTemplate.exchange(requestEntity, TaskResponse.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(expectedStatus); + if (expectedStatus.isError()) { + return; + } + + var responseBody = responseEntity.getBody(); + assertThat(responseBody).isNotNull(); + assertThat(responseBody.task()).isNotNull(); + + var taskDto = responseBody.task(); + assertThat(taskDto).isNotNull(); + assertThat(taskDto.createdAt()).isNotNull(); + assertThat(taskDto.status()).isEqualTo(TaskStatusEnum.CANCELED); + assertThat(taskDto.containerImage()).isNotNull(); + assertThat(taskDto.containerArgs()).isNotBlank(); + assertThat(taskDto.containerEnvironment()).hasSize(3); + assertThat(taskDto.name()).isEqualTo(TEST_TASK_NAME_1); + assertThat(taskDto.description()).isNotEmpty(); + assertThat(taskDto.tags()).isNotEmpty(); + assertThat(taskDto.gpuSpecification()).isNotNull(); + assertThat(taskDto.models()).isEqualTo(taskMapperService.getModelDtos(TEST_MODELS).get()); + assertThat(taskDto.resources()) + .isEqualTo(taskMapperService.getResourceDtos(TEST_RESOURCES).get()); + } + + Stream deleteTaskArgs() { + var jwtCases = Stream.of( + // TEST_TASK_ID_1 belongs to NCA ID tied to TEST_CLIENT_ID. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_ID, + List.of(SCOPE_TASK_DETAILS, + SCOPE_CANCEL_TASK, + SCOPE_DELETE_TASK), + 100), + TEST_TASK_ID_1, + HttpStatus.NO_CONTENT), + // TEST_TASK_ID_3 does not exist. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_ID, + List.of(SCOPE_TASK_DETAILS, + SCOPE_CANCEL_TASK, + SCOPE_DELETE_TASK), + 100), + TEST_TASK_ID_3, + HttpStatus.NOT_FOUND), + // TEST_TASK_ID_1 does not belong to the NCA ID tied to TEST_CLIENT_ID_2. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_ID_2, + List.of(SCOPE_TASK_DETAILS, + SCOPE_CANCEL_TASK, + SCOPE_DELETE_TASK), + 100), + TEST_TASK_ID_1, + HttpStatus.NOT_FOUND), + // Unknown subject/client. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt("unknown-client-id", + List.of(SCOPE_TASK_DETAILS, + SCOPE_CANCEL_TASK, + SCOPE_DELETE_TASK), + 100), + TEST_TASK_ID_1, + HttpStatus.NOT_FOUND), + // Missing scope. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_ID, List.of(), 100), + TEST_TASK_ID_1, + HttpStatus.FORBIDDEN), + // No token. + Arguments.of(null, + TEST_TASK_ID_1, + HttpStatus.UNAUTHORIZED) + ); + + var apiKeysCases = Stream.of( + // api-key authorized to delete any private tasks of TEST_NCA_ID account. + Arguments.of((Supplier) () -> { + MockApiKeysServer.setResponse(TEST_NCA_ID, TEST_OWNER_ID, + List.of(new Resource("account-tasks", "*")), + List.of("delete_task")); + return "nvapi-stg-some-key"; + }, + TEST_TASK_ID_1, + HttpStatus.NO_CONTENT), + // api-key authorized to delete specific task of TEST_NCA_ID account. + Arguments.of((Supplier) () -> { + MockApiKeysServer.setResponse(TEST_NCA_ID, TEST_OWNER_ID, + List.of(new Resource("task", TEST_TASK_ID_1.toString())), + List.of("delete_task")); + return "nvapi-stg-some-key"; + }, + TEST_TASK_ID_1, + HttpStatus.NO_CONTENT), + // api-key attempt to delete a task that does not have a matching resource entry. + Arguments.of((Supplier) () -> { + MockApiKeysServer.setResponse(TEST_NCA_ID, TEST_OWNER_ID, + List.of(new Resource("task", TEST_TASK_ID_2.toString())), + List.of("delete_task")); + return "nvapi-stg-some-key"; + }, + TEST_TASK_ID_1, + HttpStatus.FORBIDDEN), + // api-key attempt to delete with no resource entries in the policy result. + Arguments.of((Supplier) () -> { + MockApiKeysServer.setResponse(TEST_NCA_ID, TEST_OWNER_ID, + List.of(), + List.of("delete_task")); + return "nvapi-stg-some-key"; + }, + TEST_TASK_ID_1, + HttpStatus.FORBIDDEN) + ); + + return Stream.concat(jwtCases, apiKeysCases); + } + + @ParameterizedTest + @MethodSource("deleteTaskArgs") + void shouldDeleteTask(Object tokenSupplier, UUID taskId, HttpStatus expectedStatus) { + var token = TestUtil.getToken(tokenSupplier); + // Create Tasks in TEST_NCA_ID account tied to TEST_CLIENT_ID. + var task1 = TestUtil.createTaskEntity(TEST_TASK_ID_1, TEST_NCA_ID, TEST_TASK_NAME_1, + jsonMapper); + var task2 = TestUtil.createTaskEntity(TEST_TASK_ID_2, TEST_NCA_ID, TEST_TASK_NAME_2, + jsonMapper); + + // Save tasks. + tasksRepository.save(task1); + tasksRepository.save(task2); + + var requestEntity = + RequestEntity.delete(URI.create("/v1/nvct/tasks/" + taskId)) + .header("Authorization", "Bearer " + token) + .build(); + var responseEntity = + testRestTemplate.exchange(requestEntity, Void.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(expectedStatus); + var entity = tasksRepository.getByTaskId(taskId); + if (expectedStatus.isError()) { + if (responseEntity.getStatusCode() != HttpStatus.NOT_FOUND) { + assertThat(entity).isNotEmpty(); + } + return; + } + assertThat(entity).isEmpty(); + } + + @Test + void shouldFailWhenGracePeriodIsGreaterThanMaxRuntimeDuration() { + var token = MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100); + var modelUri = URI.create(BASE_ARTIFACT_URL + + "/v2/org/whw3rcpsilnj/models/playground_llama2_trt_l40g/0.1/files"); + var modelDtos = Set.of(ArtifactDto.builder().name("model-1") + .version("1.0").uri(modelUri).build()); + var resourceUri = URI.create(RESOURCE_ARTIFACTS_URL_3); + var resourceDtos = Set.of(ArtifactDto.builder().name("resource-1") + .version("1.0") + .uri(resourceUri) + .build()); + var requestBodyBuilder = CreateTaskRequest.builder() + .name(TEST_TASK_NAME_1) + .containerArgs(TEST_CONTAINER_ARGS) + .containerImage(TEST_CONTAINER_IMAGE) + .models(modelDtos) + .resources(resourceDtos) + .tags(TEST_TAGS) + .resultsLocation(TEST_RESULTS_LOCATION_1) + .gpuSpecification(TEST_OCI_GPU_SPEC_DTO) + .maxRuntimeDuration(Duration.ofHours(3)) + .terminationGracePeriodDuration(Duration.ofHours(5)) + .description(TEST_DESCRIPTION); + var requestEntity = RequestEntity.post(URI.create("/v1/nvct/tasks")) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", "Bearer " + token) + .body(requestBodyBuilder.build()); + var responseEntity = + testRestTemplate.exchange(requestEntity, TaskResponse.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.BAD_REQUEST); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/TaskWithHelmValidationPolicyTest.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/TaskWithHelmValidationPolicyTest.java new file mode 100644 index 000000000..8851a01f9 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/TaskWithHelmValidationPolicyTest.java @@ -0,0 +1,411 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.rest.task; + +import static com.nvidia.nvct.IntegrationTestConfiguration.MOCK_OAUTH2_TOKEN_SERVER; +import static com.nvidia.nvct.util.NvctConstants.SCOPE_LAUNCH_TASK; +import static com.nvidia.nvct.util.NvctConstants.SCOPE_LIST_TASKS; +import static com.nvidia.nvct.util.NvctConstants.SCOPE_TASK_DETAILS; +import static com.nvidia.nvct.util.TestConstants.TEST_CLIENT_SUBJECT; +import static com.nvidia.nvct.util.TestConstants.TEST_CONTAINER_IMAGE; +import static com.nvidia.nvct.util.TestConstants.TEST_DESCRIPTION; +import static com.nvidia.nvct.util.TestConstants.TEST_HELM_CHART; +import static com.nvidia.nvct.util.TestConstants.TEST_HELM_VALIDATION_POLICY_DTO; +import static com.nvidia.nvct.util.TestConstants.TEST_NCA_ID; +import static com.nvidia.nvct.util.TestConstants.TEST_OCI_GPU_SPEC_WITH_HELM_POLICY_DTO; +import static com.nvidia.nvct.util.TestConstants.TEST_RESULTS_LOCATION_1; +import static com.nvidia.nvct.util.TestConstants.TEST_SECRETS; +import static com.nvidia.nvct.util.TestConstants.TEST_TAGS; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_NAME_1; +import static org.assertj.core.api.Assertions.assertThat; + +import tools.jackson.databind.json.JsonMapper; +import com.nvidia.boot.mock.ngc.MockCasServer; +import com.nvidia.boot.mock.ngc.MockNgcContainerRegistryServer; +import com.nvidia.nvct.IntegrationTestConfiguration; +import com.nvidia.nvct.NvctTestApp; +import com.nvidia.nvct.grpc.TestTaskService; +import com.nvidia.nvct.rest.task.dto.CreateTaskRequest; +import com.nvidia.nvct.rest.task.dto.GpuSpecificationDto; +import com.nvidia.nvct.rest.task.dto.HelmValidationPolicyDto; +import com.nvidia.nvct.rest.task.dto.ListTasksResponse; +import com.nvidia.nvct.rest.task.dto.ResultHandlingStrategyEnum; +import com.nvidia.nvct.rest.task.dto.TaskResponse; +import com.nvidia.nvct.rest.task.dto.ValidationPolicyNameEnum; +import com.nvidia.nvct.util.MockEssServer; +import com.nvidia.nvct.util.MockNotaryServer; +import com.nvidia.nvct.util.MockNvcfServer; +import com.nvidia.nvct.util.MockRevalServer; +import com.nvidia.nvct.util.MockIcmsServer; +import java.net.URI; +import java.net.URL; +import java.time.Duration; +import java.util.List; +import java.util.stream.Stream; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.resttestclient.TestRestTemplate; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.RequestEntity; +import org.springframework.test.context.ContextConfiguration; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@Slf4j +@SpringBootTest(classes = {NvctTestApp.class, + IntegrationTestConfiguration.class}, + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + properties = "spring.profiles.active=test") +@ContextConfiguration(initializers = IntegrationTestConfiguration.Initializer.class) +@AutoConfigureTestRestTemplate +class TaskWithHelmValidationPolicyTest { + @Autowired + private TestRestTemplate testRestTemplate; + + @Autowired + private TestTaskService testTaskService; + + @Autowired + private JsonMapper jsonMapper; + + @Value("${nvct.registries.recognized.container.ngc.hostname}") + private String ngcContainerRegistryHostname; + + @Value("${nvct.registries.recognized.model.ngc.hostname}") + private String casBaseUrl; + + @Value("${nvct.registries.recognized.model.ngc.oauth2.base-url}") + private String authnBaseUrl; + + @Value("${nvct.notary.base-url}") + private String notaryBaseUrl; + + @Value("${spring.security.oauth2.client.registration.notary.client-id}") + private String notaryClientId; + + @Value("${nvct.nvcf.base-url}") + private URL nvcfBaseUrl; + + @Value("${nvct.icms.base-url}") + private URL icmsBaseUrl; + + @Value("${nvct.ess.base-url}") + private String essBaseUrl; + + @Value("${nvct.reval.base-url}") + private URI revalBaseUrl; + + @BeforeAll + void beforeAll() { + log.info("{}: Started running tests", this.getClass().getSimpleName()); + MockNvcfServer.start(nvcfBaseUrl); + MockCasServer.start(authnBaseUrl, casBaseUrl); + MockEssServer.start(essBaseUrl); + MockIcmsServer.start(icmsBaseUrl, jsonMapper); + MockNotaryServer.start(notaryBaseUrl, notaryClientId); + MockRevalServer.start(revalBaseUrl); + MockNgcContainerRegistryServer.start(ngcContainerRegistryHostname); + } + + @AfterAll + void cleanup() { + MockNvcfServer.stop(); + MockCasServer.stop(); + MockIcmsServer.stop(); + MockEssServer.stop(); + MockNotaryServer.stop(); + MockRevalServer.stop(); + MockNgcContainerRegistryServer.stop(); + log.info("{}: Completed running tests", this.getClass().getSimpleName()); + } + + @AfterEach + void reset() { + log.info("{} reset", this.getClass().getSimpleName()); + testTaskService.clearAll(); + MockEssServer.clearSecrets(); + } + + @BeforeEach + void setup() { + log.info("{} setup", this.getClass().getSimpleName()); + } + + Stream createTaskWithHelmValidationPolicyArgs() { + var validPolicyDefault = HelmValidationPolicyDto.builder() + .name(ValidationPolicyNameEnum.DEFAULT) + .extraKubernetesTypes(List.of( + HelmValidationPolicyDto.KubernetesType.builder() + .group("apps") + .version("v1") + .kind("Deployment") + .build())) + .build(); + var validPolicyUnrestricted = HelmValidationPolicyDto.builder() + .name(ValidationPolicyNameEnum.UNRESTRICTED) + .build(); + var validPolicyNoExtraTypes = HelmValidationPolicyDto.builder() + .name(ValidationPolicyNameEnum.DEFAULT) + .build(); + var invalidPolicyNullName = HelmValidationPolicyDto.builder() + .name(null) + .extraKubernetesTypes(List.of( + HelmValidationPolicyDto.KubernetesType.builder() + .group("apps") + .version("v1") + .kind("Deployment") + .build())) + .build(); + var invalidPolicyBlankGroup = HelmValidationPolicyDto.builder() + .name(ValidationPolicyNameEnum.DEFAULT) + .extraKubernetesTypes(List.of( + HelmValidationPolicyDto.KubernetesType.builder() + .group("") + .version("v1") + .kind("Deployment") + .build())) + .build(); + var invalidPolicyBlankVersion = HelmValidationPolicyDto.builder() + .name(ValidationPolicyNameEnum.DEFAULT) + .extraKubernetesTypes(List.of( + HelmValidationPolicyDto.KubernetesType.builder() + .group("apps") + .version("") + .kind("Deployment") + .build())) + .build(); + var invalidPolicyBlankKind = HelmValidationPolicyDto.builder() + .name(ValidationPolicyNameEnum.DEFAULT) + .extraKubernetesTypes(List.of( + HelmValidationPolicyDto.KubernetesType.builder() + .group("apps") + .version("v1") + .kind("") + .build())) + .build(); + var invalidPolicyEmptyExtraTypes = HelmValidationPolicyDto.builder() + .name(ValidationPolicyNameEnum.DEFAULT) + .extraKubernetesTypes(List.of()) + .build(); + + return Stream.of( + // Valid policy with DEFAULT name and extraKubernetesTypes. + Arguments.of(validPolicyDefault, HttpStatus.OK), + // Valid policy with UNRESTRICTED name and no extraKubernetesTypes. + Arguments.of(validPolicyUnrestricted, HttpStatus.OK), + // Valid policy with DEFAULT name and no extraKubernetesTypes. + Arguments.of(validPolicyNoExtraTypes, HttpStatus.OK), + // Invalid policy with null name. + Arguments.of(invalidPolicyNullName, HttpStatus.BAD_REQUEST), + // Invalid policy with blank group in extraKubernetesTypes. + Arguments.of(invalidPolicyBlankGroup, HttpStatus.BAD_REQUEST), + // Invalid policy with blank version in extraKubernetesTypes. + Arguments.of(invalidPolicyBlankVersion, HttpStatus.BAD_REQUEST), + // Invalid policy with blank kind in extraKubernetesTypes. + Arguments.of(invalidPolicyBlankKind, HttpStatus.BAD_REQUEST), + // Invalid policy with empty extraKubernetesTypes list. + Arguments.of(invalidPolicyEmptyExtraTypes, HttpStatus.BAD_REQUEST)); + } + + @ParameterizedTest + @MethodSource("createTaskWithHelmValidationPolicyArgs") + void shouldCreateTaskWithHelmValidationPolicy( + HelmValidationPolicyDto helmValidationPolicy, + HttpStatus expectedStatus) { + var token = MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, + SCOPE_LIST_TASKS), + 100); + var gpuSpec = GpuSpecificationDto.builder() + .gpu(TEST_OCI_GPU_SPEC_WITH_HELM_POLICY_DTO.gpu()) + .instanceType(TEST_OCI_GPU_SPEC_WITH_HELM_POLICY_DTO.instanceType()) + .backend(TEST_OCI_GPU_SPEC_WITH_HELM_POLICY_DTO.backend()) + .helmValidationPolicy(helmValidationPolicy) + .build(); + var requestBody = CreateTaskRequest.builder() + .name(TEST_TASK_NAME_1) + .helmChart(TEST_HELM_CHART) + .tags(TEST_TAGS) + .gpuSpecification(gpuSpec) + .maxRuntimeDuration(Duration.ofHours(2)) + .maxQueuedDuration(Duration.ofHours(1)) + .terminationGracePeriodDuration(Duration.ofHours(1)) + .description(TEST_DESCRIPTION) + .resultsLocation(TEST_RESULTS_LOCATION_1) + .resultHandlingStrategy(ResultHandlingStrategyEnum.UPLOAD) + .secrets(TEST_SECRETS) + .build(); + + var requestEntity = RequestEntity.post(URI.create("/v1/nvct/tasks")) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", "Bearer " + token) + .body(requestBody); + var responseEntity = + testRestTemplate.exchange(requestEntity, TaskResponse.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(expectedStatus); + if (expectedStatus.isError()) { + return; + } + + var responseBody = responseEntity.getBody(); + assertThat(responseBody).isNotNull(); + assertThat(responseBody.task().id()).isNotNull(); + assertThat(responseBody.task().name()).isEqualTo(TEST_TASK_NAME_1); + assertThat(responseBody.task().ncaId()).isEqualTo(TEST_NCA_ID); + assertThat(responseBody.task().gpuSpecification()).isNotNull(); + assertThat(responseBody.task().gpuSpecification().helmValidationPolicy()) + .isEqualTo(helmValidationPolicy); + } + + @Test + void shouldListTasksWithHelmValidationPolicy() { + var token = MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, + SCOPE_LIST_TASKS), + 100); + var requestBody = CreateTaskRequest.builder() + .name(TEST_TASK_NAME_1) + .helmChart(TEST_HELM_CHART) + .gpuSpecification(TEST_OCI_GPU_SPEC_WITH_HELM_POLICY_DTO) + .maxRuntimeDuration(Duration.ofHours(2)) + .maxQueuedDuration(Duration.ofHours(1)) + .terminationGracePeriodDuration(Duration.ofHours(1)) + .description(TEST_DESCRIPTION) + .resultsLocation(TEST_RESULTS_LOCATION_1) + .resultHandlingStrategy(ResultHandlingStrategyEnum.UPLOAD) + .secrets(TEST_SECRETS) + .build(); + var createEntity = RequestEntity.post(URI.create("/v1/nvct/tasks")) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", "Bearer " + token) + .body(requestBody); + var createResponse = + testRestTemplate.exchange(createEntity, TaskResponse.class); + assertThat(createResponse.getStatusCode()).isEqualTo(HttpStatus.OK); + + var listEntity = RequestEntity.get(URI.create("/v1/nvct/tasks")) + .header("Authorization", "Bearer " + token) + .build(); + var listResponse = + testRestTemplate.exchange(listEntity, ListTasksResponse.class); + assertThat(listResponse.getStatusCode()).isEqualTo(HttpStatus.OK); + + var responseBody = listResponse.getBody(); + assertThat(responseBody).isNotNull(); + + var tasks = responseBody.tasks(); + assertThat(tasks).isNotEmpty(); + + tasks.forEach(task -> { + assertThat(task.gpuSpecification()).isNotNull(); + assertThat(task.gpuSpecification().helmValidationPolicy()) + .isEqualTo(TEST_HELM_VALIDATION_POLICY_DTO); + }); + } + + @Test + void shouldGetTaskDetailsWithHelmValidationPolicy() { + var token = MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, + SCOPE_TASK_DETAILS), + 100); + var requestBody = CreateTaskRequest.builder() + .name(TEST_TASK_NAME_1) + .helmChart(TEST_HELM_CHART) + .gpuSpecification(TEST_OCI_GPU_SPEC_WITH_HELM_POLICY_DTO) + .maxRuntimeDuration(Duration.ofHours(2)) + .maxQueuedDuration(Duration.ofHours(1)) + .terminationGracePeriodDuration(Duration.ofHours(1)) + .description(TEST_DESCRIPTION) + .resultsLocation(TEST_RESULTS_LOCATION_1) + .resultHandlingStrategy(ResultHandlingStrategyEnum.UPLOAD) + .secrets(TEST_SECRETS) + .build(); + var createEntity = RequestEntity.post(URI.create("/v1/nvct/tasks")) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", "Bearer " + token) + .body(requestBody); + var createResponse = + testRestTemplate.exchange(createEntity, TaskResponse.class); + assertThat(createResponse.getStatusCode()).isEqualTo(HttpStatus.OK); + var taskId = createResponse.getBody().task().id(); + + var getEntity = RequestEntity + .get(URI.create("/v1/nvct/tasks/" + taskId)) + .header("Authorization", "Bearer " + token) + .build(); + var getResponse = + testRestTemplate.exchange(getEntity, TaskResponse.class); + assertThat(getResponse.getStatusCode()).isEqualTo(HttpStatus.OK); + + var responseBody = getResponse.getBody(); + assertThat(responseBody).isNotNull(); + + var task = responseBody.task(); + assertThat(task).isNotNull(); + assertThat(task.id()).isEqualTo(taskId); + assertThat(task.gpuSpecification()).isNotNull(); + assertThat(task.gpuSpecification().helmValidationPolicy()) + .isEqualTo(TEST_HELM_VALIDATION_POLICY_DTO); + } + + @Test + void shouldRejectContainerBasedTaskWithHelmValidationPolicy() { + var token = MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK), + 100); + var gpuSpec = GpuSpecificationDto.builder() + .gpu(TEST_OCI_GPU_SPEC_WITH_HELM_POLICY_DTO.gpu()) + .instanceType(TEST_OCI_GPU_SPEC_WITH_HELM_POLICY_DTO.instanceType()) + .backend(TEST_OCI_GPU_SPEC_WITH_HELM_POLICY_DTO.backend()) + .helmValidationPolicy(TEST_HELM_VALIDATION_POLICY_DTO) + .build(); + var requestBody = CreateTaskRequest.builder() + .name(TEST_TASK_NAME_1) + .containerImage(TEST_CONTAINER_IMAGE) + .tags(TEST_TAGS) + .gpuSpecification(gpuSpec) + .maxRuntimeDuration(Duration.ofHours(2)) + .maxQueuedDuration(Duration.ofHours(1)) + .terminationGracePeriodDuration(Duration.ofHours(1)) + .description(TEST_DESCRIPTION) + .resultsLocation(TEST_RESULTS_LOCATION_1) + .resultHandlingStrategy(ResultHandlingStrategyEnum.UPLOAD) + .secrets(TEST_SECRETS) + .build(); + + var requestEntity = RequestEntity.post(URI.create("/v1/nvct/tasks")) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", "Bearer " + token) + .body(requestBody); + var responseEntity = + testRestTemplate.exchange(requestEntity, TaskResponse.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.BAD_REQUEST); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/TaskWithTelemetriesTest.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/TaskWithTelemetriesTest.java new file mode 100644 index 000000000..bc9d473e6 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/TaskWithTelemetriesTest.java @@ -0,0 +1,398 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.rest.task; + +import static com.nvidia.nvct.IntegrationTestConfiguration.MOCK_OAUTH2_TOKEN_SERVER; +import static com.nvidia.nvct.util.NvctConstants.SCOPE_LAUNCH_TASK; +import static com.nvidia.nvct.util.NvctConstants.SCOPE_LIST_TASKS; +import static com.nvidia.nvct.util.NvctConstants.SCOPE_TASK_DETAILS; +import static com.nvidia.nvct.util.TestConstants.TEST_CLIENT_ID_4; +import static com.nvidia.nvct.util.TestConstants.TEST_CLIENT_SUBJECT; +import static com.nvidia.nvct.util.TestConstants.TEST_CONTAINER_ARGS; +import static com.nvidia.nvct.util.TestConstants.TEST_CONTAINER_ENVIRONMENT; +import static com.nvidia.nvct.util.TestConstants.TEST_CONTAINER_IMAGE; +import static com.nvidia.nvct.util.TestConstants.TEST_DESCRIPTION; +import static com.nvidia.nvct.util.TestConstants.TEST_ICMS_REQ_ID_1; +import static com.nvidia.nvct.util.TestConstants.TEST_NCA_ID_WITH_TELEMETRIES_4; +import static com.nvidia.nvct.util.TestConstants.TEST_OCI_GPU_SPEC_DTO; +import static com.nvidia.nvct.util.TestConstants.TEST_RESULTS_LOCATION_1; +import static com.nvidia.nvct.util.TestConstants.TEST_SECRETS; +import static com.nvidia.nvct.util.TestConstants.TEST_TAGS; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_ID_1; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_NAME_1; +import static com.nvidia.nvct.util.TestConstants.TEST_TELEMETRY_LOGS_ID; +import static com.nvidia.nvct.util.TestConstants.TEST_TELEMETRY_METRICS_ID; +import static com.nvidia.nvct.util.TestConstants.TEST_TELEMETRY_TRACES_ID; +import static org.assertj.core.api.Assertions.assertThat; + +import com.nvidia.boot.exceptions.NotFoundException; +import com.nvidia.boot.mock.ngc.MockCasServer; +import com.nvidia.boot.mock.ngc.MockNgcContainerRegistryServer; +import com.nvidia.nvct.IntegrationTestConfiguration; +import com.nvidia.nvct.NvctTestApp; +import com.nvidia.nvct.grpc.TestTaskService; +import com.nvidia.nvct.persistence.task.TasksRepository; +import com.nvidia.nvct.persistence.task.entity.TelemetriesUdt; +import com.nvidia.nvct.rest.task.dto.CreateTaskRequest; +import com.nvidia.nvct.rest.task.dto.ListTasksResponse; +import com.nvidia.nvct.rest.task.dto.ResultHandlingStrategyEnum; +import com.nvidia.nvct.rest.task.dto.TaskResponse; +import com.nvidia.nvct.rest.task.dto.TaskStatusEnum; +import com.nvidia.nvct.service.telemetry.dto.TelemetriesDto; +import com.nvidia.nvct.util.MockEssServer; +import com.nvidia.nvct.util.MockIcmsServer; +import com.nvidia.nvct.util.MockNotaryServer; +import com.nvidia.nvct.util.MockNvcfServer; +import java.net.URI; +import java.net.URL; +import java.time.Duration; +import java.util.List; +import java.util.UUID; +import java.util.stream.Stream; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.resttestclient.TestRestTemplate; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.RequestEntity; +import org.springframework.test.context.ContextConfiguration; +import tools.jackson.databind.json.JsonMapper; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@Slf4j +@SpringBootTest(classes = {NvctTestApp.class, + IntegrationTestConfiguration.class}, + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + properties = "spring.profiles.active=test") +@ContextConfiguration(initializers = IntegrationTestConfiguration.Initializer.class) +@AutoConfigureTestRestTemplate +class TaskWithTelemetriesTest { + @Autowired + private TestRestTemplate testRestTemplate; + + @Autowired + private TasksRepository tasksRepository; + + @Autowired + private TestTaskService testTaskService; + + @Autowired + private JsonMapper jsonMapper; + + @Value("${nvct.registries.recognized.model.ngc.hostname}") + private String casBaseUrl; + + @Value("${nvct.registries.recognized.model.ngc.oauth2.base-url}") + private String authnBaseUrl; + + @Value("${nvct.notary.base-url}") + private String notaryBaseUrl; + + @Value("${spring.security.oauth2.client.registration.notary.client-id}") + private String notaryClientId; + + @Value("${nvct.nvcf.base-url}") + private URL nvcfBaseUrl; + + @Value("${nvct.icms.base-url}") + private URL icmsBaseUrl; + + @Value("${nvct.ess.base-url}") + private String essBaseUrl; + + @Value("${nvct.registries.recognized.container.ngc.hostname}") + private String ngcContainerRegistryHostname; + + @SneakyThrows + @BeforeAll + void beforeAll() { + log.info("{}: Started running tests", this.getClass().getSimpleName()); + MockNvcfServer.start(nvcfBaseUrl); + MockCasServer.start(authnBaseUrl, casBaseUrl); + MockEssServer.start(essBaseUrl); + MockIcmsServer.start(icmsBaseUrl, jsonMapper); + MockNotaryServer.start(notaryBaseUrl, notaryClientId); + MockNgcContainerRegistryServer.start(ngcContainerRegistryHostname); + } + + @AfterAll + void cleanup() { + MockNvcfServer.stop(); + MockCasServer.stop(); + MockIcmsServer.stop(); + MockEssServer.stop(); + MockNotaryServer.stop(); + MockNgcContainerRegistryServer.stop(); + log.info("{}: Completed running tests", this.getClass().getSimpleName()); + } + + @AfterEach + void reset() { + log.info("{} reset", this.getClass().getSimpleName()); + testTaskService.clearAll(); + MockEssServer.clearSecrets(); + } + + @BeforeEach + void setup() { + log.info("{} setup", this.getClass().getSimpleName()); + } + + Stream createTaskWithTelemetriesArgs() { + var validCompleteTelemetriesDto = TelemetriesDto.builder() + .logsTelemetryId(TEST_TELEMETRY_LOGS_ID) + .metricsTelemetryId(TEST_TELEMETRY_METRICS_ID) + .tracesTelemetryId(TEST_TELEMETRY_TRACES_ID) + .build(); + var validPartialTelemetriesDto = TelemetriesDto.builder() + .logsTelemetryId(TEST_TELEMETRY_LOGS_ID) + .build(); + var mismatchedTelemtriesDto = TelemetriesDto.builder() + .logsTelemetryId(TEST_TELEMETRY_TRACES_ID) + .metricsTelemetryId(TEST_TELEMETRY_LOGS_ID) + .tracesTelemetryId(TEST_TELEMETRY_METRICS_ID) + .build(); + var mismatchedPartialTelemtriesDto = TelemetriesDto.builder() + .logsTelemetryId(TEST_TELEMETRY_TRACES_ID) + .build(); + + return Stream.of( + // Valid telemetries with token for a client that is associated with an account + // with telemetries. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_ID_4, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100), + validCompleteTelemetriesDto, + TEST_TELEMETRY_LOGS_ID, + TEST_TELEMETRY_METRICS_ID, + TEST_TELEMETRY_TRACES_ID, + HttpStatus.OK), + // Valid telemetries with token for a client that is associated with an account + // with telemetries. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_ID_4, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100), + validPartialTelemetriesDto, + TEST_TELEMETRY_LOGS_ID, + null, + null, + HttpStatus.OK), + // Valid telemetries with token for a client that is NOT associated with an account + // with telemetries. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100), + validCompleteTelemetriesDto, + TEST_TELEMETRY_LOGS_ID, + TEST_TELEMETRY_METRICS_ID, + TEST_TELEMETRY_TRACES_ID, + HttpStatus.BAD_REQUEST), + // Invalid telemetries with token for a client that is associated with an account + // with telemetries. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_ID_4, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100), + mismatchedTelemtriesDto, + null, + null, + null, + HttpStatus.BAD_REQUEST), + // Invalid telemetries with token for a client that is associated with an account + // with telemetries. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_ID_4, + List.of(SCOPE_LAUNCH_TASK, SCOPE_LIST_TASKS), + 100), + mismatchedPartialTelemtriesDto, + null, + null, + null, + HttpStatus.BAD_REQUEST) + ); + } + + @ParameterizedTest + @MethodSource("createTaskWithTelemetriesArgs") + void shouldCreateTaskWithTelemetries( + String token, + TelemetriesDto telemetriesDto, + UUID logsTelemetryId, + UUID metricsTelemetryId, + UUID tracesTelemetryId, + HttpStatus expectedStatus) { + var maxRuntimeDuration = Duration.ofHours(2); + var maxQueuedDuration = Duration.ofHours(3); + var terminationGracePeriodDuration = Duration.ofHours(1); + var requestBody = CreateTaskRequest.builder() + .name(TEST_TASK_NAME_1) + .containerArgs(TEST_CONTAINER_ARGS) + .containerImage(TEST_CONTAINER_IMAGE) + .tags(TEST_TAGS) + .gpuSpecification(TEST_OCI_GPU_SPEC_DTO) + .maxRuntimeDuration(maxRuntimeDuration) + .maxQueuedDuration(maxQueuedDuration) + .terminationGracePeriodDuration(terminationGracePeriodDuration) + .description(TEST_DESCRIPTION) + .resultsLocation(TEST_RESULTS_LOCATION_1) + .resultHandlingStrategy(ResultHandlingStrategyEnum.UPLOAD) + .secrets(TEST_SECRETS) + .containerEnvironment(TEST_CONTAINER_ENVIRONMENT) + .telemetries(telemetriesDto) + .build(); + + var requestEntity = RequestEntity.post(URI.create("/v1/nvct/tasks")) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", "Bearer " + token) + .body(requestBody); + var responseEntity = testRestTemplate.exchange(requestEntity, TaskResponse.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(expectedStatus); + if (expectedStatus.isError()) { + return; + } + + var responseBody = responseEntity.getBody(); + assertThat(responseBody).isNotNull(); + assertThat(responseBody.task().id()).isNotNull(); + assertThat(responseBody.task().name()).isEqualTo(TEST_TASK_NAME_1); + assertThat(responseBody.task().status()).isEqualTo(TaskStatusEnum.QUEUED); + assertThat(responseBody.task().ncaId()).isEqualTo(TEST_NCA_ID_WITH_TELEMETRIES_4); + assertThat(responseBody.task().containerArgs()).isEqualTo(TEST_CONTAINER_ARGS); + assertThat(responseBody.task().helmChart()).isNull(); + assertThat(responseBody.task().containerImage()).isEqualTo(TEST_CONTAINER_IMAGE); + assertThat(responseBody.task().containerEnvironment()).isEqualTo( + TEST_CONTAINER_ENVIRONMENT); + assertThat(responseBody.task().createdAt()).isNotNull(); + assertThat(responseBody.task().gpuSpecification()).isEqualTo(TEST_OCI_GPU_SPEC_DTO); + assertThat(responseBody.task().resultsLocation()).isEqualTo(TEST_RESULTS_LOCATION_1); + assertThat(responseBody.task().resultHandlingStrategy()) + .isEqualTo(ResultHandlingStrategyEnum.UPLOAD); + assertThat(responseBody.task().maxRuntimeDuration()).isNotNull(); + assertThat(responseBody.task().maxRuntimeDuration().toString()) + .hasToString(maxRuntimeDuration.toString()); + assertThat(responseBody.task().maxQueuedDuration().toString()) + .hasToString(maxQueuedDuration.toString()); + assertThat(responseBody.task().terminationGracePeriodDuration()).isNotNull(); + assertThat(responseBody.task().terminationGracePeriodDuration().toString()) + .hasToString(terminationGracePeriodDuration.toString()); + assertThat(responseBody.task().tags()).isEqualTo(TEST_TAGS); + assertThat(responseBody.task().description()).isEqualTo(TEST_DESCRIPTION); + + var actualTelemetriesDto = responseBody.task().telemetries(); + assertThat(actualTelemetriesDto).isNotNull(); + assertThat(actualTelemetriesDto.logsTelemetryId()).isEqualTo(logsTelemetryId); + assertThat(actualTelemetriesDto.metricsTelemetryId()).isEqualTo(metricsTelemetryId); + assertThat(actualTelemetriesDto.tracesTelemetryId()).isEqualTo(tracesTelemetryId); + + var taskId = responseBody.task().id(); + var entity = tasksRepository + .getByTaskId(taskId) + .orElseThrow(() -> new NotFoundException("Task not found")); + assertThat(entity).isNotNull(); + assertThat(entity.getHealth()).isBlank(); + } + + @Test + void shouldListTasksWithTelemetries() { + // Create Task in TEST_NCA_ID_WITH_TELEMETRIES_4 account with telemetries. + var telemetriesUdt = TelemetriesUdt.builder() + .logsTelemetryId(TEST_TELEMETRY_LOGS_ID) + .metricsTelemetryId(TEST_TELEMETRY_METRICS_ID) + .tracesTelemetryId(TEST_TELEMETRY_TRACES_ID) + .build(); + testTaskService.createTaskWithTelemetries(TEST_NCA_ID_WITH_TELEMETRIES_4, + TEST_TASK_ID_1, + TEST_ICMS_REQ_ID_1, + telemetriesUdt); + + // Create token for the client that is associated with TEST_NCA_ID_WITH_TELEMETRIES_4 + // account. + var token = MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_ID_4, + List.of(SCOPE_LIST_TASKS), + 100); + var requestEntity = RequestEntity.get(URI.create("/v1/nvct/tasks")) + .header("Authorization", "Bearer " + token) + .build(); + var responseEntity = + testRestTemplate.exchange(requestEntity, ListTasksResponse.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK); + + var responseBody = responseEntity.getBody(); + assertThat(responseBody).isNotNull(); + + var tasks = responseBody.tasks(); + assertThat(tasks).isNotEmpty(); + + tasks.forEach(task -> { + assertThat(task.telemetries()).isNotNull(); + assertThat(task.telemetries().logsTelemetryId()).isEqualTo(TEST_TELEMETRY_LOGS_ID); + assertThat(task.telemetries().metricsTelemetryId()).isEqualTo( + TEST_TELEMETRY_METRICS_ID); + assertThat(task.telemetries().tracesTelemetryId()).isEqualTo(TEST_TELEMETRY_TRACES_ID); + }); + } + + @Test + void shouldGetTaskDetailsWithTelemetries() { + // Create Task in TEST_NCA_ID_WITH_TELEMETRIES_4 account with telemetries. + var telemetriesUdt = TelemetriesUdt.builder() + .logsTelemetryId(TEST_TELEMETRY_LOGS_ID) + .metricsTelemetryId(TEST_TELEMETRY_METRICS_ID) + .tracesTelemetryId(TEST_TELEMETRY_TRACES_ID) + .build(); + testTaskService.createTaskWithTelemetries(TEST_NCA_ID_WITH_TELEMETRIES_4, + TEST_TASK_ID_1, + TEST_ICMS_REQ_ID_1, + telemetriesUdt); + + // Create token for the client that is associated with TEST_NCA_ID_WITH_TELEMETRIES_4 + // account. + var token = MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_ID_4, + List.of(SCOPE_TASK_DETAILS), + 100); + var requestEntity = RequestEntity.get(URI.create("/v1/nvct/tasks/" + TEST_TASK_ID_1)) + .header("Authorization", "Bearer " + token) + .build(); + var responseEntity = + testRestTemplate.exchange(requestEntity, TaskResponse.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK); + + var responseBody = responseEntity.getBody(); + assertThat(responseBody).isNotNull(); + + var task = responseBody.task(); + assertThat(task).isNotNull(); + assertThat(task.id()).isEqualTo(TEST_TASK_ID_1); + + assertThat(task.telemetries()).isNotNull(); + assertThat(task.telemetries().logsTelemetryId()).isEqualTo(TEST_TELEMETRY_LOGS_ID); + assertThat(task.telemetries().metricsTelemetryId()).isEqualTo(TEST_TELEMETRY_METRICS_ID); + assertThat(task.telemetries().tracesTelemetryId()).isEqualTo(TEST_TELEMETRY_TRACES_ID); + } + +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/TaskWithUserSecretsTest.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/TaskWithUserSecretsTest.java new file mode 100644 index 000000000..286e02cc9 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/TaskWithUserSecretsTest.java @@ -0,0 +1,578 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.rest.task; + +import static com.nvidia.nvct.IntegrationTestConfiguration.MOCK_OAUTH2_TOKEN_SERVER; +import static com.nvidia.nvct.util.NvctConstants.MAX_SECRET_NAME_LENGTH; +import static com.nvidia.nvct.util.NvctConstants.MAX_SECRET_VALUE_LENGTH; +import static com.nvidia.nvct.util.NvctConstants.NGC_API_KEY; +import static com.nvidia.nvct.util.NvctConstants.SCOPE_DELETE_TASK; +import static com.nvidia.nvct.util.NvctConstants.SCOPE_LAUNCH_TASK; +import static com.nvidia.nvct.util.NvctConstants.SCOPE_LIST_TASKS; +import static com.nvidia.nvct.util.NvctConstants.SCOPE_TASK_DETAILS; +import static com.nvidia.nvct.util.TestConstants.TEST_CLIENT_SUBJECT; +import static com.nvidia.nvct.util.TestConstants.TEST_CONTAINER_ARGS; +import static com.nvidia.nvct.util.TestConstants.TEST_CONTAINER_IMAGE; +import static com.nvidia.nvct.util.TestConstants.TEST_DESCRIPTION; +import static com.nvidia.nvct.util.TestConstants.TEST_OCI_GPU_SPEC_DTO; +import static com.nvidia.nvct.util.TestConstants.TEST_RESULTS_LOCATION_1; +import static com.nvidia.nvct.util.TestConstants.TEST_RESULTS_LOCATION_2; +import static com.nvidia.nvct.util.TestConstants.TEST_TAGS; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_NAME_1; +import static org.assertj.core.api.Assertions.assertThat; + +import tools.jackson.databind.json.JsonMapper; +import tools.jackson.databind.node.StringNode; +import com.nvidia.boot.mock.ngc.MockCasServer; +import com.nvidia.boot.mock.ngc.MockNgcContainerRegistryServer; +import com.nvidia.nvct.IntegrationTestConfiguration; +import com.nvidia.nvct.NvctTestApp; +import com.nvidia.nvct.grpc.TestTaskService; +import com.nvidia.nvct.persistence.task.TasksRepository; +import com.nvidia.nvct.rest.task.dto.CreateTaskRequest; +import com.nvidia.nvct.rest.task.dto.ListTasksResponse; +import com.nvidia.nvct.rest.task.dto.ResultHandlingStrategyEnum; +import com.nvidia.nvct.rest.task.dto.SecretDto; +import com.nvidia.nvct.rest.task.dto.TaskResponse; +import com.nvidia.nvct.service.ess.EssService; +import com.nvidia.nvct.util.MockEssServer; +import com.nvidia.nvct.util.MockNotaryServer; +import com.nvidia.nvct.util.MockNvcfServer; +import com.nvidia.nvct.util.MockIcmsServer; +import java.net.URI; +import java.net.URL; +import java.util.List; +import java.util.Set; +import java.util.stream.Stream; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.resttestclient.TestRestTemplate; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.RequestEntity; +import org.springframework.test.context.ContextConfiguration; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@Slf4j +@SpringBootTest( + classes = {NvctTestApp.class, IntegrationTestConfiguration.class}, + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + properties = "spring.profiles.active=test") +@ContextConfiguration(initializers = IntegrationTestConfiguration.Initializer.class) +@AutoConfigureTestRestTemplate +class TaskWithUserSecretsTest { + + @Autowired + private TestRestTemplate testRestTemplate; + + @Autowired + private EssService essService; + + @Autowired + private TestTaskService testTaskService; + + @Autowired + private JsonMapper jsonMapper; + + @Autowired + private TasksRepository tasksRepository; + + @Value("${nvct.registries.recognized.container.ngc.hostname}") + private String ngcContainerRegistryHostname; + + @Value("${nvct.ess.base-url}") + private String essBaseUrl; + + @Value("${nvct.registries.recognized.model.ngc.hostname}") + private String casBaseUrl; + + @Value("${nvct.registries.recognized.model.ngc.oauth2.base-url}") + private String authnBaseUrl; + + @Value("${nvct.notary.base-url}") + private String notaryBaseUrl; + + @Value("${spring.security.oauth2.client.registration.notary.client-id}") + private String notaryClientId; + + @Value("${nvct.nvcf.base-url}") + private URL nvcfBaseUrl; + + @Value("${nvct.icms.base-url}") + private URL icmsBaseUrl; + + @BeforeAll + void beforeAll() { + log.info("{}: Started running tests", this.getClass().getSimpleName()); + MockEssServer.start(essBaseUrl); + MockNvcfServer.start(nvcfBaseUrl); + MockIcmsServer.start(icmsBaseUrl, jsonMapper); + MockCasServer.start(authnBaseUrl, casBaseUrl); + MockNotaryServer.start(notaryBaseUrl, notaryClientId); + MockNgcContainerRegistryServer.start(ngcContainerRegistryHostname); + } + + @AfterAll + void cleanup() { + MockEssServer.stop(); + MockNvcfServer.stop(); + MockIcmsServer.stop(); + MockCasServer.stop(); + MockNotaryServer.stop(); + MockNgcContainerRegistryServer.stop(); + log.info("{}: Completed running tests", this.getClass().getSimpleName()); + } + + @AfterEach + void reset() { + testTaskService.clearAll(); + MockEssServer.clearSecrets(); + } + + Stream createTaskWithSecretsArgs() { + var secretJsonNodeValue = jsonMapper.createObjectNode() + .put("AWS_REGION", "us-west-2") + .put("AWS_BUCKET", "ov-content") + .put("AWS_ACCESS_KEY_ID", "ov-content-key-id") + .put("AWS_SECRET_ACCESS_KEY", "ov-content-access-key") + .put("AWS_SESSION_TOKEN", "ov-content-session-token") + .put(NGC_API_KEY, "value2");; + return Stream.of( + // no secrets with default resultHandlingStrategy + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK), + 100), + null, + null, + null, + HttpStatus.BAD_REQUEST), + // no secrets with resultHandlingStrategy UPLOAD(default) + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK), + 100), + null, + null, + ResultHandlingStrategyEnum.UPLOAD, + HttpStatus.BAD_REQUEST), + // Only NGC_API_KEY secret + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK), + 100), + Set.of(SecretDto.builder().name(NGC_API_KEY) + .value(new StringNode("value1")).build()), + Set.of(NGC_API_KEY), + ResultHandlingStrategyEnum.UPLOAD, + HttpStatus.OK), + // single secret + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK), + 100), + Set.of(SecretDto.builder().name(NGC_API_KEY) + .value(new StringNode("value1")).build()), + Set.of(NGC_API_KEY), + ResultHandlingStrategyEnum.UPLOAD, + HttpStatus.OK), + // multiple secrets + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK), + 100), + Set.of(SecretDto.builder().name(NGC_API_KEY) + .value(new StringNode("value1")).build(), + SecretDto.builder().name("secret2") + .value(new StringNode("value2")).build(), + SecretDto.builder().name("secret3") + .value(secretJsonNodeValue).build() + ), + Set.of(NGC_API_KEY, "secret2", "secret3"), + ResultHandlingStrategyEnum.UPLOAD, + HttpStatus.OK), + // Secret name -- exactly MAX_SECRET_NAME_LENGTH in length + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK), + 100), + Set.of(SecretDto.builder() + .name(StringUtils.repeat("x", MAX_SECRET_NAME_LENGTH)) + .value(new StringNode("value1")).build()), + Set.of(StringUtils.repeat("x", MAX_SECRET_NAME_LENGTH)), + ResultHandlingStrategyEnum.NONE, + HttpStatus.OK), + // secret names with periods, and hyphens + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK), + 100), + Set.of(SecretDto.builder() + .name("omni.s3.us-west-2.amazonaws.com") + .value(new StringNode("value1")).build(), + SecretDto.builder() + .name("omni.s3.eu-north-1.amazonaws.com") + .value(new StringNode("value2")).build(), + SecretDto.builder() + .name("omni.s3.ap-northeast-1.amazonaws.com") + .value(secretJsonNodeValue).build() + ), + Set.of("omni.s3.us-west-2.amazonaws.com", + "omni.s3.eu-north-1.amazonaws.com", + "omni.s3.ap-northeast-1.amazonaws.com"), + ResultHandlingStrategyEnum.NONE, + HttpStatus.OK), + // secret names with underscores + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK), + 100), + Set.of(SecretDto.builder() + .name("omni_s3_us-west-2_amazonaws_com") + .value(new StringNode("value1")).build(), + SecretDto.builder() + .name("omni_s3_eu-north-1_amazonaws_com") + .value(new StringNode("value2")).build(), + SecretDto.builder() + .name("omni_s3.ap-northeast-1_amazonaws_com") + .value(secretJsonNodeValue).build()), + Set.of("omni_s3_us-west-2_amazonaws_com", + "omni_s3_eu-north-1_amazonaws_com", + "omni_s3.ap-northeast-1_amazonaws_com"), + ResultHandlingStrategyEnum.NONE, + HttpStatus.OK), + // resultHandlingStrategy NONE and missing NGC_API_KEY + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK), + 100), + Set.of(SecretDto.builder() + .name("secret2") + .value(new StringNode("value2")).build()), + Set.of("secret2"), + ResultHandlingStrategyEnum.NONE, + HttpStatus.OK), + // resultHandlingStrategy UPLOAD and missing NGC_API_KEY + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK), + 100), + Set.of(SecretDto.builder() + .name("secret2") + .value(new StringNode("value2")).build()), + Set.of("secret2"), + ResultHandlingStrategyEnum.UPLOAD, + HttpStatus.BAD_REQUEST), + // duplicate secrets + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK), + 100), + Set.of(SecretDto.builder() + .name(NGC_API_KEY) + .value(new StringNode("value1")).build(), + SecretDto.builder() + .name(NGC_API_KEY) + .value(new StringNode("value2")).build()), + null, + ResultHandlingStrategyEnum.NONE, + HttpStatus.BAD_REQUEST), + // empty secret name + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK), + 100), + Set.of(SecretDto.builder() + .name("") + .value(new StringNode("value1")).build()), + null, + ResultHandlingStrategyEnum.NONE, + HttpStatus.BAD_REQUEST), + // long secret name - exceeds MAX_SECRET_NAME_LENGTH length + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK), + 100), + Set.of(SecretDto.builder() + .name(StringUtils.repeat("secret1", MAX_SECRET_NAME_LENGTH)) + .value(new StringNode("value1")).build()), + null, + ResultHandlingStrategyEnum.NONE, + HttpStatus.BAD_REQUEST), + // empty secret value + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK), + 100), + Set.of(SecretDto.builder().name("secret1") + .value(new StringNode("")).build()), + null, + ResultHandlingStrategyEnum.NONE, + HttpStatus.BAD_REQUEST), + // long secret value + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK), + 100), + Set.of(SecretDto.builder().name("secret1") + .value(new StringNode(StringUtils.repeat("value1", + MAX_SECRET_VALUE_LENGTH))) + .build()), + null, + ResultHandlingStrategyEnum.NONE, + HttpStatus.BAD_REQUEST), + // bad secret name + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK), + 100), + Set.of(SecretDto.builder().name("*secret1*-\"") + .value(new StringNode("value1")).build()), + null, + ResultHandlingStrategyEnum.NONE, + HttpStatus.BAD_REQUEST) + ); + } + + @ParameterizedTest + @MethodSource("createTaskWithSecretsArgs") + void shouldCreateTaskWithSecrets( + String token, + Set secrets, + Set expectedSecretNames, + ResultHandlingStrategyEnum resultHandlingStrategy, + HttpStatus expectedStatus) { + // Create the task in TEST_NCA_ID + var requestBody = CreateTaskRequest.builder() + .name(TEST_TASK_NAME_1) + .containerArgs(TEST_CONTAINER_ARGS) + .containerImage(TEST_CONTAINER_IMAGE) + .tags(TEST_TAGS) + .gpuSpecification(TEST_OCI_GPU_SPEC_DTO) + .description(TEST_DESCRIPTION) + .resultsLocation(TEST_RESULTS_LOCATION_1) + .resultHandlingStrategy(resultHandlingStrategy) + .secrets(secrets) + .build(); + var requestEntity = RequestEntity.post(URI.create("/v1/nvct/tasks")) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", "Bearer " + token) + .body(requestBody); + var responseEntity = testRestTemplate.exchange(requestEntity, TaskResponse.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(expectedStatus); + if (expectedStatus.isError()) { + return; + } + + var responseBody = responseEntity.getBody(); + assertThat(responseBody).isNotNull(); + var taskId = responseBody.task().id(); + var taskDto = responseBody.task(); + if (expectedSecretNames == null) { + assertThat(taskDto.secrets()).isNull(); + } else { + assertThat(taskDto.secrets()) + .containsExactlyInAnyOrderElementsOf(expectedSecretNames); + + // Confirm secrets are saved in ESS + var returnedNames = essService.getSecretNames(taskId).orElse(null); + assertThat(returnedNames).isNotNull(); + assertThat(returnedNames).containsExactlyInAnyOrderElementsOf(expectedSecretNames); + + // Confirm hasSecrets is set + var taskEntity = tasksRepository.getByTaskId(taskId).orElse(null); + assertThat(taskEntity).isNotNull(); + assertThat(taskEntity.hasSecrets()).isTrue(); + } + + } + + @Test + void shouldListTasksWithSecretsByAccount() { + var token = MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, + SCOPE_LIST_TASKS), + 100); + // Create a task with secrets in TEST_NCA_ID + var secretJsonNodeValue = jsonMapper.createObjectNode() + .put("AWS_REGION", "us-west-2") + .put("AWS_BUCKET", "ov-content") + .put("AWS_ACCESS_KEY_ID", "ov-content-key-id") + .put("AWS_SECRET_ACCESS_KEY", "ov-content-access-key") + .put("AWS_SESSION_TOKEN", "ov-content-session-token"); + var secrets = Set.of(SecretDto.builder().name("AWS_SECRET_ACCESS_KEY") + .value(new StringNode("value1")).build(), + SecretDto.builder().name("NGC_API_KEY") + .value(new StringNode("value2")).build(), + SecretDto.builder().name("OV.US-WEST-2.CONTENT") + .value(secretJsonNodeValue).build()); + var requestBody = CreateTaskRequest.builder() + .name(TEST_TASK_NAME_1) + .containerArgs(TEST_CONTAINER_ARGS) + .containerImage(TEST_CONTAINER_IMAGE) + .gpuSpecification(TEST_OCI_GPU_SPEC_DTO) + .resultsLocation(TEST_RESULTS_LOCATION_2) + .secrets(secrets) + .build(); + var requestEntity = RequestEntity.post(URI.create("/v1/nvct/tasks")) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", "Bearer " + token) + .body(requestBody); + var responseEntity = testRestTemplate.exchange(requestEntity, TaskResponse.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK); + + // After task creation, list task + var endpoint = "/v1/nvct/tasks"; + var listRequestEntity = RequestEntity.get(URI.create(endpoint)) + .header("Authorization", "Bearer " + token) + .build(); + var listResponseEntity = testRestTemplate.exchange(listRequestEntity, ListTasksResponse.class); + var responseBody = listResponseEntity.getBody(); + assertThat(responseBody).isNotNull(); + assertThat(responseBody.tasks()).hasSize(1); + + var taskDto = responseBody.tasks().getFirst(); + assertThat(taskDto).isNotNull(); + assertThat(taskDto.secrets()).isNull(); + } + + Stream listTasksWithSecretsArgs() { + return Stream.of( + Arguments.of(Boolean.TRUE), + Arguments.of(Boolean.FALSE), + Arguments.of(Boolean.TRUE), + Arguments.of(Boolean.FALSE)); + } + + @ParameterizedTest + @MethodSource("listTasksWithSecretsArgs") + void shouldGetTaskDetailsWithSecretsByAccount(Boolean includeSecrets) { + var token = MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, + SCOPE_TASK_DETAILS), + 100); + // Create a task with secrets in TEST_NCA_ID + var secretJsonNodeValue = jsonMapper.createObjectNode() + .put("AWS_REGION", "us-west-2") + .put("AWS_BUCKET", "ov-content") + .put("AWS_ACCESS_KEY_ID", "ov-content-key-id") + .put("AWS_SECRET_ACCESS_KEY", "ov-content-access-key") + .put("AWS_SESSION_TOKEN", "ov-content-session-token"); + var secrets = Set.of(SecretDto.builder().name("AWS_SECRET_ACCESS_KEY") + .value(new StringNode("value1")).build(), + SecretDto.builder().name("NGC_API_KEY") + .value(new StringNode("value2")).build(), + SecretDto.builder().name("OV.US-WEST-2.CONTENT") + .value(secretJsonNodeValue).build()); + var expectedSecretNames = Set.of("AWS_SECRET_ACCESS_KEY", + "NGC_API_KEY", "OV.US-WEST-2.CONTENT"); + var requestBody = CreateTaskRequest.builder() + .name(TEST_TASK_NAME_1) + .containerArgs(TEST_CONTAINER_ARGS) + .containerImage(TEST_CONTAINER_IMAGE) + .gpuSpecification(TEST_OCI_GPU_SPEC_DTO) + .resultsLocation(TEST_RESULTS_LOCATION_1) + .secrets(secrets) + .build(); + var requestEntity = RequestEntity.post(URI.create("/v1/nvct/tasks")) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", "Bearer " + token) + .body(requestBody); + var responseEntity = testRestTemplate.exchange(requestEntity, TaskResponse.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK); + var taskId = responseEntity.getBody().task().id(); + + // After task creation, get task details + var endpoint = "/v1/nvct/tasks/" + taskId; + if (includeSecrets != null) { + endpoint += "?includeSecrets=" + includeSecrets; + } + var listRequestEntity = RequestEntity.get(URI.create(endpoint)) + .header("Authorization", "Bearer " + token) + .build(); + var listResponseEntity = testRestTemplate.exchange(listRequestEntity, TaskResponse.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK); + var responseBody = listResponseEntity.getBody(); + assertThat(responseBody).isNotNull(); + + var taskDto = responseBody.task(); + assertThat(taskDto).isNotNull(); + if ((includeSecrets == null) || includeSecrets) { + assertThat(taskDto.secrets()).isNotNull(); + assertThat(taskDto.secrets()).containsExactlyInAnyOrderElementsOf(expectedSecretNames); + } else { + assertThat(taskDto.secrets()).isNull(); + } + } + + @Test + void shouldDeleteTaskWithSecrets() { + var token = MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_CLIENT_SUBJECT, + List.of(SCOPE_LAUNCH_TASK, + SCOPE_DELETE_TASK), + 100); + + // Create a task with secrets in TEST_NCA_ID + var secretJsonNodeValue = jsonMapper.createObjectNode() + .put("AWS_REGION", "us-west-2") + .put("AWS_BUCKET", "ov-content") + .put("AWS_ACCESS_KEY_ID", "ov-content-key-id") + .put("AWS_SECRET_ACCESS_KEY", "ov-content-access-key") + .put("AWS_SESSION_TOKEN", "ov-content-session-token"); + var secrets = Set.of(SecretDto.builder().name("AWS_SECRET_ACCESS_KEY") + .value(new StringNode("value1")).build(), + SecretDto.builder().name("NGC_API_KEY") + .value(new StringNode("value2")).build(), + SecretDto.builder().name("OV.US-WEST-2.CONTENT") + .value(secretJsonNodeValue).build()); + var requestBody = CreateTaskRequest.builder() + .name(TEST_TASK_NAME_1) + .containerArgs(TEST_CONTAINER_ARGS) + .containerImage(TEST_CONTAINER_IMAGE) + .gpuSpecification(TEST_OCI_GPU_SPEC_DTO) + .secrets(secrets) + .resultsLocation(TEST_RESULTS_LOCATION_1) + .build(); + var requestEntity = + RequestEntity.post(URI.create("/v1/nvct/tasks")) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", "Bearer " + token) + .body(requestBody); + var responseEntity = testRestTemplate.exchange(requestEntity, TaskResponse.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK); + var taskId = responseEntity.getBody().task().id(); + + // Make sure there are secrets first before deleting a task + var secretDtos = essService.getSecrets(taskId).orElse(null); + assertThat(secretDtos).isNotNull().hasSize(3); + + // Confirm hasSecrets is set + var taskEntity = tasksRepository.getByTaskId(taskId).orElse(null); + assertThat(taskEntity).isNotNull(); + assertThat(taskEntity.hasSecrets()).isTrue(); + + var deleteRequestEntity = + RequestEntity.delete(URI.create("/v1/nvct/tasks/" + taskId)) + .header("Authorization", "Bearer " + token) + .build(); + var deleteResponseEntity = testRestTemplate.exchange(deleteRequestEntity, Void.class); + assertThat(deleteResponseEntity.getStatusCode()).isEqualTo(HttpStatus.NO_CONTENT); + var entity = tasksRepository + .getByTaskId(taskId); + assertThat(entity).isEmpty(); + + // Make sure secrets no longer exist after task deletion + secretDtos = essService.getSecrets(taskId).orElse(null); + assertThat(secretDtos).isNull(); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/XAccountFilterTaskTest.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/XAccountFilterTaskTest.java new file mode 100644 index 000000000..1357a5b78 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/XAccountFilterTaskTest.java @@ -0,0 +1,350 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.rest.task; + +import static com.nvidia.nvct.IntegrationTestConfiguration.MOCK_OAUTH2_TOKEN_SERVER; +import static com.nvidia.nvct.persistence.task.entity.TaskStatus.QUEUED; +import static com.nvidia.nvct.persistence.task.entity.TaskStatus.RUNNING; +import static com.nvidia.nvct.util.NvctConstants.ADMIN_SCOPE_LIST_TASKS; +import static com.nvidia.nvct.util.TestConstants.TEST_ADMIN_SUBJECT; +import static com.nvidia.nvct.util.TestConstants.TEST_MODELS; +import static com.nvidia.nvct.util.TestConstants.TEST_NCA_ID; +import static com.nvidia.nvct.util.TestConstants.TEST_NCA_ID_2; +import static com.nvidia.nvct.util.TestConstants.TEST_RESOURCES; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_ID_1; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_ID_2; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_ID_3; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_ID_4; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_ID_5; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_NAME_1; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_NAME_2; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_NAME_3; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.fail; + +import tools.jackson.databind.json.JsonMapper; +import com.nvidia.boot.mock.ngc.MockCasServer; +import com.nvidia.nvct.IntegrationTestConfiguration; +import com.nvidia.nvct.NvctTestApp; +import com.nvidia.nvct.grpc.TestTaskService; +import com.nvidia.nvct.persistence.task.TasksRepository; +import com.nvidia.nvct.persistence.task.entity.TaskStatus; +import com.nvidia.nvct.rest.task.dto.ListTasksResponse; +import com.nvidia.nvct.rest.task.dto.TaskDto; +import com.nvidia.nvct.rest.task.dto.TaskStatusEnum; +import com.nvidia.nvct.service.task.TaskMapperService; +import com.nvidia.nvct.util.MockEssServer; +import com.nvidia.nvct.util.MockNvcfServer; +import com.nvidia.nvct.util.MockIcmsServer; +import com.nvidia.nvct.util.TestUtil; +import java.net.URI; +import java.net.URL; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.resttestclient.TestRestTemplate; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; +import org.springframework.http.HttpStatus; +import org.springframework.http.RequestEntity; +import org.springframework.test.context.ContextConfiguration; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@Slf4j +@SpringBootTest( + classes = {NvctTestApp.class, IntegrationTestConfiguration.class}, + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + properties = "spring.profiles.active=test") +@ContextConfiguration(initializers = IntegrationTestConfiguration.Initializer.class) +@AutoConfigureTestRestTemplate +class XAccountFilterTaskTest { + + @Autowired + private TestRestTemplate testRestTemplate; + + @Autowired + private TestTaskService testTaskService; + + @Autowired + private JsonMapper jsonMapper; + + @Autowired + private TasksRepository tasksRepository; + + @Autowired + private TaskMapperService taskMapperService; + + @Value("${nvct.ess.base-url}") + private String essBaseUrl; + + @Value("${nvct.registries.recognized.model.ngc.hostname}") + private String casBaseUrl; + + @Value("${nvct.registries.recognized.model.ngc.oauth2.base-url}") + private String authnBaseUrl; + + @Value("${nvct.nvcf.base-url}") + private URL nvcfBaseUrl; + + @Value("${nvct.icms.base-url}") + private URL icmsBaseUrl; + + @BeforeAll + void beforeAll() { + log.info("{}: Started running tests", this.getClass().getSimpleName()); + MockEssServer.start(essBaseUrl); + MockNvcfServer.start(nvcfBaseUrl); + MockIcmsServer.start(icmsBaseUrl, jsonMapper); + MockCasServer.start(authnBaseUrl, casBaseUrl); + } + + @AfterAll + void cleanup() { + MockEssServer.stop(); + MockNvcfServer.stop(); + MockIcmsServer.stop(); + MockCasServer.stop(); + log.info("{}: Completed running tests", this.getClass().getSimpleName()); + } + + @AfterEach + void reset() { + testTaskService.clearAll(); + MockEssServer.clearSecrets(); + } + + Stream listTasksWithPaginationLimitArgs() { + return Stream.of( + // List tasks in TEST_NCA_ID account with 1 limit + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LIST_TASKS), + 100), + TEST_NCA_ID, + List.of(TEST_TASK_ID_2), + 1, + HttpStatus.OK), + + // List tasks in TEST_NCA_ID account with 100 limit + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LIST_TASKS), + 100), + TEST_NCA_ID, + List.of(TEST_TASK_ID_1, TEST_TASK_ID_2), + 100, + HttpStatus.OK)); + + } + + @ParameterizedTest + @MethodSource("listTasksWithPaginationLimitArgs") + void shouldListTasksWithPaginationLimit( + String token, String ncaId, List expectedTasks, int limit, HttpStatus expectedStatus) { + // Create Tasks in TEST_NCA_ID account tied to TEST_CLIENT_ID. + var task1 = TestUtil.createTaskEntity(TEST_TASK_ID_1, TEST_NCA_ID, TEST_TASK_NAME_1, + jsonMapper); + var task2 = TestUtil.createTaskEntity(TEST_TASK_ID_2, TEST_NCA_ID, TEST_TASK_NAME_2, + jsonMapper); + + // Save tasks. + tasksRepository.save(task1); + tasksRepository.save(task2); + + var requestEntity = + RequestEntity.get(URI.create("/v1/nvct/accounts/" + ncaId + "/tasks?limit=" + limit)) + .header("Authorization", "Bearer " + token) + .build(); + var responseEntity = + testRestTemplate.exchange(requestEntity, ListTasksResponse.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(expectedStatus); + if (expectedStatus.isError()) { + return; + } + + var responseBody = responseEntity.getBody(); + assertThat(responseBody).isNotNull(); + if (limit == 1) { + assertThat(responseBody.cursor()).isNotNull(); + assertThat(responseBody.tasks()).hasSize(1); + assertThat(responseBody.limit()).isEqualTo(limit); + } else if (limit > 2) { + assertThat(responseBody.cursor()).isNull(); + assertThat(responseBody.limit()).isNull(); + assertThat(responseBody.tasks()).hasSize(2); + } + var tasks = responseBody.tasks().stream() + .collect(Collectors.toMap(TaskDto::id, Function.identity())); + verifyReturnedTasksIntegrity(expectedTasks, QUEUED, tasks); + } + + @Test + void shouldListTasksWithPaginationCursor() { + var token = MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LIST_TASKS), + 100); + var expectedTasks = List.of(TEST_TASK_ID_1, TEST_TASK_ID_2, TEST_TASK_ID_3); + // Create Tasks in TEST_NCA_ID account tied to TEST_CLIENT_ID + var task1 = TestUtil.createTaskEntity(TEST_TASK_ID_1, TEST_NCA_ID, TEST_TASK_NAME_1, + jsonMapper); + var task2 = TestUtil.createTaskEntity(TEST_TASK_ID_2, TEST_NCA_ID, TEST_TASK_NAME_2, + jsonMapper); + var task3 = TestUtil.createTaskEntity(TEST_TASK_ID_3, TEST_NCA_ID, TEST_TASK_NAME_3, + jsonMapper); + // Create Tasks in TEST_NCA_ID_2 account to make sure there is no cross contamination query + var otherTask1 = TestUtil.createTaskEntity(TEST_TASK_ID_4, TEST_NCA_ID_2, TEST_TASK_NAME_1, + jsonMapper); + var otherTask2 = TestUtil.createTaskEntity(TEST_TASK_ID_5, TEST_NCA_ID_2, TEST_TASK_NAME_2, + jsonMapper); + + // Save tasks. + tasksRepository.save(task1); + tasksRepository.save(task2); + tasksRepository.save(task3); + tasksRepository.save(otherTask1); + tasksRepository.save(otherTask2); + + // get the first 2 out of 3 tasks first + var url = "/v1/nvct/accounts/" + TEST_NCA_ID + "/tasks?limit=2"; + var requestEntity = + RequestEntity.get(URI.create(url)) + .header("Authorization", "Bearer " + token) + .build(); + var responseEntity = + testRestTemplate.exchange(requestEntity, ListTasksResponse.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK); + var responseBody = responseEntity.getBody(); + assertThat(responseBody).isNotNull(); + var currentCursor = responseBody.cursor(); + assertThat(currentCursor).isNotNull(); + var firstPageTasks = responseBody.tasks().stream() + .collect(Collectors.toMap(TaskDto::id, Function.identity())); + assertThat(firstPageTasks).hasSize(2); + assertThat(responseBody.limit()).isEqualTo(2); + + // using the cursor from previous response, continue to listing the rest of the tasks + url = "/v1/nvct/accounts/" + TEST_NCA_ID + "/tasks?limit=2&cursor=" + currentCursor; + requestEntity = + RequestEntity.get(URI.create(url)) + .header("Authorization", "Bearer " + token) + .build(); + responseEntity = + testRestTemplate.exchange(requestEntity, ListTasksResponse.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK); + + // make sure the last task is correct + responseBody = responseEntity.getBody(); + assertThat(responseBody).isNotNull(); + currentCursor = responseBody.cursor(); + assertThat(currentCursor).isNull(); + assertThat(responseBody.limit()).isNull(); + var secondPageTask = responseBody.tasks().stream() + .collect(Collectors.toMap(TaskDto::id, Function.identity())); + assertThat(secondPageTask).hasSize(1); + + // make sure all 3 tasks have the right metadata + var tasks = new HashMap(); + tasks.putAll(firstPageTasks); + tasks.putAll(secondPageTask); + verifyReturnedTasksIntegrity(expectedTasks, QUEUED, tasks); + } + + @Test + void shouldListTasksWithStatus() { + var token = MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LIST_TASKS), + 100); + var expectedTasks = List.of(TEST_TASK_ID_2, TEST_TASK_ID_3); + // Create Tasks in TEST_NCA_ID account tied to TEST_CLIENT_ID + var task1 = TestUtil.createContainerBasedTaskEntity(TEST_TASK_ID_1, TEST_NCA_ID, TEST_TASK_NAME_1, QUEUED, + jsonMapper); + var task2 = TestUtil.createContainerBasedTaskEntity(TEST_TASK_ID_2, TEST_NCA_ID, TEST_TASK_NAME_2, RUNNING, + jsonMapper); + var task3 = TestUtil.createContainerBasedTaskEntity(TEST_TASK_ID_3, TEST_NCA_ID, TEST_TASK_NAME_3, RUNNING, + jsonMapper); + // Create Tasks in TEST_NCA_ID_2 account to make sure there is no cross contamination query + var otherTask1 = TestUtil.createTaskEntity(TEST_TASK_ID_4, TEST_NCA_ID_2, TEST_TASK_NAME_1, + jsonMapper); + var otherTask2 = TestUtil.createTaskEntity(TEST_TASK_ID_5, TEST_NCA_ID_2, TEST_TASK_NAME_2, + jsonMapper); + + // Save tasks. + tasksRepository.save(task1); + tasksRepository.save(task2); + tasksRepository.save(task3); + tasksRepository.save(otherTask1); + tasksRepository.save(otherTask2); + + // get all the tasks with RUNNING status + var url = "/v1/nvct/accounts/" + TEST_NCA_ID + "/tasks?status=RUNNING"; + var requestEntity = + RequestEntity.get(URI.create(url)) + .header("Authorization", "Bearer " + token) + .build(); + var responseEntity = + testRestTemplate.exchange(requestEntity, ListTasksResponse.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK); + var responseBody = responseEntity.getBody(); + assertThat(responseBody).isNotNull(); + var tasks = responseBody.tasks().stream() + .collect(Collectors.toMap(TaskDto::id, Function.identity())); + assertThat(tasks).hasSize(2); + verifyReturnedTasksIntegrity(expectedTasks, RUNNING, tasks); + } + + void verifyReturnedTasksIntegrity(List expectedTasks, TaskStatus expectedStatus, Map tasks) { + for (UUID expectedTaskId : expectedTasks) { + var taskDto = tasks.get(expectedTaskId); + assertThat(taskDto).isNotNull(); + assertThat(taskDto.createdAt()).isNotNull(); + assertThat(taskDto.status()).isEqualTo(TaskStatusEnum.fromText(expectedStatus.toString())); + assertThat(taskDto.containerImage()).isNotNull(); + assertThat(taskDto.containerArgs()).isNotBlank(); + assertThat(taskDto.containerEnvironment()).hasSize(3); + if (taskDto.id().equals(TEST_TASK_ID_1)) { + assertThat(taskDto.name()).isEqualTo(TEST_TASK_NAME_1); + } else if (taskDto.id().equals(TEST_TASK_ID_2)) { + assertThat(taskDto.name()).isEqualTo(TEST_TASK_NAME_2); + } else if (taskDto.id().equals(TEST_TASK_ID_3)) { + assertThat(taskDto.name()).isEqualTo(TEST_TASK_NAME_3); + } else { + fail("unknown function returned"); + } + assertThat(taskDto.description()).isNotEmpty(); + assertThat(taskDto.tags()).isNotEmpty(); + assertThat(taskDto.gpuSpecification()).isNotNull(); + assertThat(taskDto.models()) + .isEqualTo(taskMapperService.getModelDtos(TEST_MODELS).get()); + assertThat(taskDto.resources()) + .isEqualTo(taskMapperService.getResourceDtos(TEST_RESOURCES).get()); + } + } + +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/XAccountListTasksWithBasicDetailsTest.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/XAccountListTasksWithBasicDetailsTest.java new file mode 100644 index 000000000..a11e49d86 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/XAccountListTasksWithBasicDetailsTest.java @@ -0,0 +1,173 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.rest.task; + +import static com.nvidia.nvct.IntegrationTestConfiguration.MOCK_OAUTH2_TOKEN_SERVER; +import static com.nvidia.nvct.persistence.task.entity.TaskStatus.QUEUED; +import static com.nvidia.nvct.persistence.task.entity.TaskStatus.RUNNING; +import static com.nvidia.nvct.util.NvctConstants.ADMIN_SCOPE_LIST_TASKS; +import static com.nvidia.nvct.util.TestConstants.TEST_ADMIN_SUBJECT; +import static com.nvidia.nvct.util.TestConstants.TEST_ICMS_REQ_ID_1; +import static com.nvidia.nvct.util.TestConstants.TEST_ICMS_REQ_ID_2; +import static com.nvidia.nvct.util.TestConstants.TEST_NCA_ID; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_ID_1; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_ID_2; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_ID_3; +import static org.assertj.core.api.Assertions.assertThat; + +import com.nvidia.nvct.IntegrationTestConfiguration; +import com.nvidia.nvct.NvctTestApp; +import com.nvidia.nvct.grpc.TestTaskService; +import com.nvidia.nvct.rest.task.dto.BasicTaskDto; +import com.nvidia.nvct.rest.task.dto.BulkTaskDetailsRequest; +import com.nvidia.nvct.rest.task.dto.ListBasicTaskDetailsResponse; +import com.nvidia.nvct.service.account.AccountService; +import com.nvidia.nvct.util.MockNvcfServer; +import java.net.URI; +import java.net.URL; +import java.util.List; +import java.util.Set; +import java.util.UUID; +import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.resttestclient.TestRestTemplate; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.HttpStatus; +import org.springframework.http.RequestEntity; +import org.springframework.test.context.ContextConfiguration; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@Slf4j +@SpringBootTest( + classes = {NvctTestApp.class, IntegrationTestConfiguration.class}, + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + properties = "spring.profiles.active=test") +@ContextConfiguration(initializers = IntegrationTestConfiguration.Initializer.class) +@AutoConfigureTestRestTemplate +class XAccountListTasksWithBasicDetailsTest { + @Autowired + private TestRestTemplate testRestTemplate; + + @Autowired + private AccountService accountService; + + @Autowired + private TestTaskService testTaskService; + + @Value("${nvct.nvcf.base-url}") + private URL nvcfBaseUrl; + + @BeforeAll + void beforeAll() { + log.info("{}: Started running tests", this.getClass().getSimpleName()); + MockNvcfServer.start(nvcfBaseUrl); + + // Create Tasks in TEST_NCA_ID account tied to TEST_CLIENT_ID. + testTaskService.createTask(TEST_NCA_ID, TEST_TASK_ID_1, TEST_ICMS_REQ_ID_1, QUEUED); + testTaskService.createTask(TEST_NCA_ID, TEST_TASK_ID_2, TEST_ICMS_REQ_ID_2, RUNNING); + } + + @AfterAll + void cleanup() { + MockNvcfServer.stop(); + log.info("{}: Completed running tests", this.getClass().getSimpleName()); + } + + @AfterEach + void reset() { + accountService.invalidateCache(); + testTaskService.clearAll(); + } + + Stream listTasksWithBasicDetailsArgs() { + return Stream.of( + // List tasks with basic details in TEST_NCA_ID account + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LIST_TASKS), + 100), + Set.of(TEST_TASK_ID_1, TEST_TASK_ID_2), + HttpStatus.OK), + // Empty set of taskIds + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LIST_TASKS), + 100), + Set.of(), + HttpStatus.BAD_REQUEST), + // List basic details for a non-existent TEST_TASK_ID_3 in TEST_NCA_ID account + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LIST_TASKS), + 100), + Set.of(TEST_TASK_ID_1, TEST_TASK_ID_3), + HttpStatus.NOT_FOUND), + // Missing scope. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(), + 100), + Set.of(TEST_TASK_ID_1, TEST_TASK_ID_2), + HttpStatus.FORBIDDEN), + // Missing token. + Arguments.of(null, + Set.of(TEST_TASK_ID_1, TEST_TASK_ID_2), + HttpStatus.UNAUTHORIZED) + ); + } + + @ParameterizedTest + @MethodSource("listTasksWithBasicDetailsArgs") + void shouldListTasksWithBasicDetails(String token, + Set expectedTaskIds, + HttpStatus expectedStatus) { + var requestBody = BulkTaskDetailsRequest.builder().taskIds(expectedTaskIds).build(); + var requestEntity = + RequestEntity.post(URI.create("/v1/nvct/accounts/" + TEST_NCA_ID + "/tasks/bulk")) + .header("Authorization", "Bearer " + token) + .body(requestBody); + var responseEntity = + testRestTemplate.exchange(requestEntity, ListBasicTaskDetailsResponse.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(expectedStatus); + if (expectedStatus.isError()) { + return; + } + + var responseBody = responseEntity.getBody(); + assertThat(responseBody).isNotNull(); + assertThat(responseBody.tasks()).isNotNull().isNotEmpty(); + assertThat(responseBody.tasks()).hasSize(expectedTaskIds.size()); + var tasks = responseBody.tasks().stream() + .collect(Collectors.toMap(BasicTaskDto::id, Function.identity())); + assertThat(tasks.keySet()).containsExactlyInAnyOrderElementsOf(expectedTaskIds); + var dtos = responseBody.tasks(); + dtos.forEach(dto -> { + assertThat(dto.id()).isIn(expectedTaskIds); + assertThat(dto.name()).isNotBlank(); + assertThat(dto.status()).isNotNull(); + }); + assertThat(responseBody.ncaId()).isEqualTo(TEST_NCA_ID); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/XAccountMiscEndpointsControllerTest.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/XAccountMiscEndpointsControllerTest.java new file mode 100644 index 000000000..6bec8812c --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/XAccountMiscEndpointsControllerTest.java @@ -0,0 +1,271 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.rest.task; + +import static com.nvidia.nvct.IntegrationTestConfiguration.MOCK_OAUTH2_TOKEN_SERVER; +import static com.nvidia.nvct.util.NvctConstants.ADMIN_SCOPE_LAUNCH_TASK; +import static com.nvidia.nvct.util.TestConstants.TEST_ADMIN_SUBJECT; +import static com.nvidia.nvct.util.TestConstants.TEST_NCA_ID; +import static com.nvidia.nvct.util.TestConstants.TEST_ICMS_REQ_ID_1; +import static com.nvidia.nvct.util.TestConstants.TEST_ICMS_REQ_ID_2; +import static com.nvidia.nvct.util.TestConstants.TEST_ICMS_REQ_ID_3; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_ID_1; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_ID_2; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_ID_3; +import static org.assertj.core.api.Assertions.assertThat; + +import tools.jackson.databind.json.JsonMapper; +import com.nvidia.nvct.IntegrationTestConfiguration; +import com.nvidia.nvct.NvctTestApp; +import com.nvidia.nvct.grpc.TestTaskService; +import com.nvidia.nvct.persistence.task.TasksRepository; +import com.nvidia.nvct.persistence.task.entity.GpuSpecUdt; +import com.nvidia.nvct.persistence.task.entity.TaskStatus; +import com.nvidia.nvct.rest.misc.dto.GpuPlacementDto; +import com.nvidia.nvct.rest.misc.dto.GpuUsageDto; +import com.nvidia.nvct.rest.misc.dto.ListGpuUsageResponse; +import com.nvidia.nvct.service.account.AccountService; +import com.nvidia.nvct.service.apikeys.ApiKeysService; +import com.nvidia.nvct.util.MockApiKeysServer; +import com.nvidia.nvct.util.MockNvcfServer; +import com.nvidia.nvct.util.MockIcmsServer; +import com.nvidia.nvct.util.TestUtil; +import java.net.URI; +import java.net.URL; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.api.TestInstance.Lifecycle; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.resttestclient.TestRestTemplate; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; +import org.springframework.http.HttpStatus; +import org.springframework.http.RequestEntity; +import org.springframework.test.context.ContextConfiguration; + +@Slf4j +@SpringBootTest( + classes = {NvctTestApp.class, IntegrationTestConfiguration.class}, + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + properties = "spring.profiles.active=test") +@TestInstance(Lifecycle.PER_CLASS) +@ContextConfiguration(initializers = IntegrationTestConfiguration.Initializer.class) +@AutoConfigureTestRestTemplate +class XAccountMiscEndpointsControllerTest { + + @Autowired + private TestRestTemplate testRestTemplate; + + @Autowired + private JsonMapper jsonMapper; + + @Autowired + private TasksRepository tasksRepository; + + @Autowired + private TestTaskService testTaskService; + + @Autowired + private AccountService accountService; + + @Autowired + private ApiKeysService apiKeysService; + + @Value("${nvct.icms.base-url}") + private URL icmsBaseUrl; + + @Value("${nvct.api-keys.base-url}") + private String apiKeysBaseUrl; + + @Value("${nvct.nvcf.base-url}") + private URL nvcfBaseUrl; + + @BeforeAll + void beforeAll() { + log.info("{}: Started running tests", this.getClass().getSimpleName()); + MockApiKeysServer.start(apiKeysBaseUrl); + MockNvcfServer.start(nvcfBaseUrl); + MockIcmsServer.start(icmsBaseUrl, jsonMapper); + } + + @AfterAll + void cleanup() { + MockApiKeysServer.stop(); + MockNvcfServer.stop(); + MockIcmsServer.stop(); + + log.info("{}: Completed running tests", this.getClass().getSimpleName()); + } + + @AfterEach + void reset() { + MockApiKeysServer.resetToDefault(); + // use of MockApiKeysServer with different scopes causes the api-keys cache to dirty + apiKeysService.invalidateCache(); + accountService.invalidateCache(); + tasksRepository.deleteAll(); + } + + Stream gpuUsageArgs() { + return Stream.of( + Arguments.of(null, HttpStatus.UNAUTHORIZED), + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(), 100), HttpStatus.FORBIDDEN), + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK), 100), + HttpStatus.OK) + ); + } + + @ParameterizedTest + @MethodSource("gpuUsageArgs") + void shouldListGpuUsageForAccount(Object tokenSupplier, HttpStatus expectedStatus) { + var token = TestUtil.getToken(tokenSupplier); + var gpuSpec1 = GpuSpecUdt.builder() + .backend("BYOC-OCI-1").gpu("A100_80GB").instanceType("BM.GPU.A100-v2.8") + .build(); + var gpuSpec2 = GpuSpecUdt.builder() + .backend("GFN").gpu("T10").instanceType("g6.full") + .build(); + var gpuSpec3 = GpuSpecUdt.builder() + .backend("nvcf-dgxc-k8s-aws-use1-dev1").gpu("H100").instanceType("AWS.GPU.H100_4x") + .build(); + testTaskService.createTask(TEST_NCA_ID, TEST_TASK_ID_1, TEST_ICMS_REQ_ID_1, TaskStatus.QUEUED, gpuSpec1); + testTaskService.createTask(TEST_NCA_ID, TEST_TASK_ID_2, TEST_ICMS_REQ_ID_2, TaskStatus.LAUNCHED, gpuSpec2); + testTaskService.createTask(TEST_NCA_ID, TEST_TASK_ID_3, TEST_ICMS_REQ_ID_3, TaskStatus.RUNNING, gpuSpec3); + + // Invoke endpoint to get GPU usage in TEST_NCA_ID account + var requestEntity = RequestEntity + .get(URI.create("/v1/nvct/accounts/" + TEST_NCA_ID + "/usage/gpus")) + .header("Authorization", "Bearer " + token) + .build(); + var responseEntity = testRestTemplate.exchange(requestEntity, ListGpuUsageResponse.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(expectedStatus); + if (expectedStatus.isError()) { + return; + } + + var responseBody = responseEntity.getBody(); + assertThat(responseBody).isNotNull(); + var dtos = responseBody.gpus(); + assertThat(dtos).hasSize(3); + dtos.forEach(dto -> { + assertThat(dto.gpu()).isIn("A100_80GB", "T10", "H100"); + assertThat(dto.instanceType()).isNotBlank(); + if (dto.gpu().equals("H100")) { + assertThat(dto.placements()).isNotEmpty(); + } + }); + } + + @Test + void gpuUsageWithNoTaskCreated() { + var token = MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK), 100); + // Invoke endpoint to get GPU usage in TEST_NCA_ID account + var requestEntity = RequestEntity + .get(URI.create("/v1/nvct/accounts/" + TEST_NCA_ID + "/usage/gpus")) + .header("Authorization", "Bearer " + token) + .build(); + var responseEntity = testRestTemplate.exchange(requestEntity, ListGpuUsageResponse.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK); + var responseBody = responseEntity.getBody(); + assertThat(responseBody).isNotNull(); + var dtos = responseBody.gpus(); + assertThat(dtos).isEmpty(); + } + + Stream gpuUsageFlow() { + return Stream.of( + // 1. Old flow, backend is specified + Arguments.of(GpuSpecUdt.builder() + .backend("nvcf-dgxc-k8s-forge-az24-dev6").gpu("AD102GL") + .instanceType("DGX-CLOUD.GPU.AD102GL_2x").build(), + 1, + Map.of("nvcf-dgxc-k8s-forge-az24-dev6", 1)), + // 2. New flow, cluster list is specified + Arguments.of(GpuSpecUdt.builder() + .gpu("AD102GL") + .instanceType("DGX-CLOUD.GPU.AD102GL_2x") + .clusters(Set.of( + "nvcf-dgxc-k8s-forge-az24-dev6", + "dgxc-k8saas-forge-dev2-az24")).build(), + 1, + Map.of("nvcf-dgxc-k8s-forge-az24-dev6", 1, + "dgxc-k8saas-forge-dev2-az24", 1)), + // 3. New flow, no constraints + Arguments.of(GpuSpecUdt.builder() + .gpu("AD102GL") + .instanceType("DGX-CLOUD.GPU.AD102GL_2x").build(), + 1, + Map.of("nvcf-dgxc-k8s-forge-az24-dev6", 1, + "dgxc-k8saas-forge-dev2-az24", 1, + "dgxc-k8saas-forge-az24-ct1", 1)) + ); + } + + @ParameterizedTest + @MethodSource("gpuUsageFlow") + void gpuUsage(GpuSpecUdt gpuSpec, int totalInstances, + Map cluster2Instances) { + var token = MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK), 100); + testTaskService.createTask(TEST_NCA_ID, TEST_TASK_ID_1, TEST_ICMS_REQ_ID_1, + TaskStatus.QUEUED, gpuSpec); + + // Invoke endpoint to get GPU usage in TEST_NCA_ID account + var requestEntity = RequestEntity + .get(URI.create("/v1/nvct/accounts/" + TEST_NCA_ID + "/usage/gpus")) + .header("Authorization", "Bearer " + token) + .build(); + + var responseEntity = testRestTemplate.exchange(requestEntity, ListGpuUsageResponse.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK); + + var responseBody = responseEntity.getBody(); + assertThat(responseBody).isNotNull(); + var dtos = responseBody.gpus(); + assertThat(dtos).hasSize(1); + GpuUsageDto gpuUsageDto = dtos.stream().findFirst().get(); + assertThat(gpuUsageDto.instanceType()).isEqualTo("DGX-CLOUD.GPU.AD102GL_2x"); + assertThat(gpuUsageDto.currentMaxUsage()).isEqualTo(totalInstances); + assertThat(gpuUsageDto.currentMinUsage()).isEqualTo(totalInstances); + var clusterList = gpuUsageDto.placements().stream().map( + GpuPlacementDto::cluster).collect(Collectors.toSet()); + assertThat(clusterList).containsAll(cluster2Instances.keySet()); + gpuUsageDto.placements().forEach(placement -> { + assertThat(cluster2Instances).containsKey(placement.cluster()); + assertThat(placement.currentMaxUsage()) + .isEqualTo(cluster2Instances.get(placement.cluster())); + assertThat(placement.currentMinUsage()) + .isEqualTo(cluster2Instances.get(placement.cluster())); + }); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/XAccountTaskManagementControllerTest.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/XAccountTaskManagementControllerTest.java new file mode 100644 index 000000000..4bd6b0395 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/XAccountTaskManagementControllerTest.java @@ -0,0 +1,1877 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.rest.task; + +import static com.nvidia.boot.registries.service.registry.client.ngc.NgcRegistryUtils.removeArtifactHostName; +import static com.nvidia.nvct.IntegrationTestConfiguration.MOCK_OAUTH2_TOKEN_SERVER; +import static com.nvidia.nvct.persistence.task.entity.TaskStatus.CANCELED; +import static com.nvidia.nvct.persistence.task.entity.TaskStatus.COMPLETED; +import static com.nvidia.nvct.persistence.task.entity.TaskStatus.ERRORED; +import static com.nvidia.nvct.persistence.task.entity.TaskStatus.QUEUED; +import static com.nvidia.nvct.util.NvctConstants.ADMIN_SCOPE_CANCEL_TASK; +import static com.nvidia.nvct.util.NvctConstants.ADMIN_SCOPE_DELETE_TASK; +import static com.nvidia.nvct.util.NvctConstants.ADMIN_SCOPE_LAUNCH_TASK; +import static com.nvidia.nvct.util.NvctConstants.ADMIN_SCOPE_LIST_TASKS; +import static com.nvidia.nvct.util.NvctConstants.ADMIN_SCOPE_TASK_DETAILS; +import static com.nvidia.nvct.util.NvctConstants.MAX_TAGS_COUNT; +import static com.nvidia.nvct.util.NvctConstants.MAX_TAG_LENGTH; +import static com.nvidia.nvct.util.NvctConstants.NGC_API_KEY; +import static com.nvidia.nvct.util.TestConstants.BASE_ARTIFACT_URL; +import static com.nvidia.nvct.util.TestConstants.GFN; +import static com.nvidia.nvct.util.TestConstants.L40G; +import static com.nvidia.nvct.util.TestConstants.L40G_INSTANCE_TYPE; +import static com.nvidia.nvct.util.TestConstants.MODEL_ARTIFACTS_URL; +import static com.nvidia.nvct.util.TestConstants.MODEL_ARTIFACTS_URL_3; +import static com.nvidia.nvct.util.TestConstants.MODEL_ARTIFACTS_URL_4; +import static com.nvidia.nvct.util.TestConstants.RESOURCE_ARTIFACTS_URL_2; +import static com.nvidia.nvct.util.TestConstants.RESOURCE_ARTIFACTS_URL_3; +import static com.nvidia.nvct.util.TestConstants.RESOURCE_ARTIFACTS_URL_4; +import static com.nvidia.nvct.util.TestConstants.TEST_ADMIN_SUBJECT; +import static com.nvidia.nvct.util.TestConstants.TEST_CONTAINER_ARGS; +import static com.nvidia.nvct.util.TestConstants.TEST_CONTAINER_ENVIRONMENT; +import static com.nvidia.nvct.util.TestConstants.TEST_CONTAINER_IMAGE; +import static com.nvidia.nvct.util.TestConstants.TEST_DESCRIPTION; +import static com.nvidia.nvct.util.TestConstants.TEST_GFN_GPU_SPEC_DTO; +import static com.nvidia.nvct.util.TestConstants.TEST_MODELS; +import static com.nvidia.nvct.util.TestConstants.TEST_MODEL_NAME; +import static com.nvidia.nvct.util.TestConstants.TEST_NCA_ID; +import static com.nvidia.nvct.util.TestConstants.TEST_NCA_ID_2; +import static com.nvidia.nvct.util.TestConstants.TEST_OCI_GPU_SPEC_DTO; +import static com.nvidia.nvct.util.TestConstants.TEST_RESOURCES; +import static com.nvidia.nvct.util.TestConstants.TEST_RESULTS_LOCATION_1; +import static com.nvidia.nvct.util.TestConstants.TEST_RESULTS_LOCATION_2; +import static com.nvidia.nvct.util.TestConstants.TEST_TAGS; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_ID_1; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_ID_2; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_ID_3; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_NAME_1; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_NAME_2; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_NAME_3; +import static com.nvidia.nvct.util.TestConstants.TEST_UNKNOWN_ORG_NAME; +import static com.nvidia.nvct.util.TestConstants.TEST_UNKNOWN_TEAM_NAME; +import static com.nvidia.nvct.util.TestConstants.TEST_VALID_ORG_NAME; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.fail; + +import tools.jackson.databind.json.JsonMapper; +import tools.jackson.databind.node.StringNode; +import com.nvidia.boot.exceptions.NotFoundException; +import com.nvidia.boot.mock.ngc.MockCasServer; +import com.nvidia.boot.mock.ngc.MockNgcContainerRegistryServer; +import com.nvidia.nvct.IntegrationTestConfiguration; +import com.nvidia.nvct.NvctTestApp; +import com.nvidia.nvct.grpc.TestTaskService; +import com.nvidia.nvct.persistence.task.TasksRepository; +import com.nvidia.nvct.persistence.task.entity.TaskStatus; +import com.nvidia.nvct.rest.task.dto.ArtifactDto; +import com.nvidia.nvct.rest.task.dto.ContainerEnvironmentEntryDto; +import com.nvidia.nvct.rest.task.dto.CreateTaskRequest; +import com.nvidia.nvct.rest.task.dto.GpuSpecificationDto; +import com.nvidia.nvct.rest.task.dto.ListTasksResponse; +import com.nvidia.nvct.rest.task.dto.ResultHandlingStrategyEnum; +import com.nvidia.nvct.rest.task.dto.SecretDto; +import com.nvidia.nvct.rest.task.dto.TaskDto; +import com.nvidia.nvct.rest.task.dto.TaskResponse; +import com.nvidia.nvct.rest.task.dto.TaskStatusEnum; +import com.nvidia.nvct.service.account.AccountService; +import com.nvidia.nvct.service.apikeys.ApiKeysService; +import com.nvidia.nvct.service.task.TaskMapperService; +import com.nvidia.nvct.util.MockApiKeysServer; +import com.nvidia.nvct.util.MockEssServer; +import com.nvidia.nvct.util.MockNotaryServer; +import com.nvidia.nvct.util.MockNvcfServer; +import com.nvidia.nvct.util.MockIcmsServer; +import com.nvidia.nvct.util.TestUtil; +import java.net.URI; +import java.net.URL; +import java.time.Duration; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.UUID; +import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.stream.IntStream; +import java.util.stream.Stream; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.resttestclient.TestRestTemplate; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.RequestEntity; +import org.springframework.test.context.ContextConfiguration; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@Slf4j +@SpringBootTest( + classes = {NvctTestApp.class, IntegrationTestConfiguration.class}, + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + properties = "spring.profiles.active=test") +@ContextConfiguration(initializers = IntegrationTestConfiguration.Initializer.class) +@AutoConfigureTestRestTemplate +class XAccountTaskManagementControllerTest { + + @Autowired + private TestRestTemplate testRestTemplate; + + @Autowired + private TestTaskService testTaskService; + + @Autowired + private AccountService accountService; + + @Autowired + private ApiKeysService apiKeysService; + + @Autowired + private TasksRepository tasksRepository; + + @Autowired + private TaskMapperService taskMapperService; + + @Autowired + private JsonMapper jsonMapper; + + @Value("${nvct.registries.recognized.container.ngc.hostname}") + private String ngcContainerRegistryHostname; + + @Value("${nvct.api-keys.base-url}") + private String apiKeysBaseUrl; + + @Value("${nvct.registries.recognized.model.ngc.hostname}") + private String casBaseUrl; + + @Value("${nvct.registries.recognized.model.ngc.oauth2.base-url}") + private String authnBaseUrl; + + @Value("${nvct.ess.base-url}") + private String essBaseUrl; + + @Value("${nvct.notary.base-url}") + private String notaryBaseUrl; + + @Value("${spring.security.oauth2.client.registration.notary.client-id}") + private String notaryClientId; + + @Value("${nvct.nvcf.base-url}") + private URL nvcfBaseUrl; + + @Value("${nvct.icms.base-url}") + private URL icmsBaseUrl; + + @BeforeAll + void beforeAll() { + log.info("{}: Started running tests", this.getClass().getSimpleName()); + MockApiKeysServer.start(apiKeysBaseUrl); + MockNvcfServer.start(nvcfBaseUrl); + MockIcmsServer.start(icmsBaseUrl, jsonMapper); + MockCasServer.start(authnBaseUrl, casBaseUrl); + MockEssServer.start(essBaseUrl); + MockNotaryServer.start(notaryBaseUrl, notaryClientId); + MockNgcContainerRegistryServer.start(ngcContainerRegistryHostname); + tasksRepository.deleteAll(); + } + + @AfterAll + void cleanup() { + MockApiKeysServer.stop(); + MockNvcfServer.stop(); + MockIcmsServer.stop(); + MockCasServer.stop(); + MockEssServer.stop(); + MockNotaryServer.stop(); + MockNgcContainerRegistryServer.stop(); + log.info("{}: Completed running tests", this.getClass().getSimpleName()); + } + + @AfterEach + void reset() { + MockApiKeysServer.resetToDefault(); + // use of MockApiKeysServer with different scopes causes the api-keys cache to dirty + apiKeysService.invalidateCache(); + accountService.invalidateCache(); + tasksRepository.deleteAll(); + testTaskService.clearAll(); + } + + + Stream createTaskArgs() { + var specWithMissingInstanceType = GpuSpecificationDto.builder() + .gpu(L40G).backend(GFN).build(); + var specWithInvalidInstanceType = GpuSpecificationDto.builder() + .gpu(L40G).backend(GFN).instanceType("invalid-instance-type").build(); + var specWithMissingBackend = GpuSpecificationDto.builder() + .gpu(L40G).instanceType(L40G_INSTANCE_TYPE).build(); + var specWithMissingGpu = GpuSpecificationDto.builder() + .backend(GFN).instanceType(L40G_INSTANCE_TYPE).build(); + var specWithInvalidGpu = GpuSpecificationDto.builder() + .gpu("invalid-gpu").backend(GFN).instanceType(L40G_INSTANCE_TYPE).build(); + var specWithNonEmptyConfiguration = + GpuSpecificationDto.builder().gpu(L40G).instanceType(L40G_INSTANCE_TYPE) + .clusters(Set.of("cluster01", "cluster02")) + .configuration(jsonMapper.createObjectNode().put("foo", "bar")) + .build(); + var secretJsonNodeValue = jsonMapper.createObjectNode() + .put("AWS_REGION", "us-west-2") + .put("AWS_BUCKET", "ov-content") + .put("AWS_ACCESS_KEY_ID", "ov-content-key-id") + .put("AWS_SECRET_ACCESS_KEY", "ov-content-access-key") + .put("AWS_SESSION_TOKEN", "ov-content-session-token"); + var secrets = Set.of(SecretDto.builder() + .name(NGC_API_KEY) + .value(new StringNode("shhh!shhh!")) + .build(), + SecretDto.builder() + .name("secret2") + .value(secretJsonNodeValue) + .build() + ); + var containerEnvKeyWithHyphen = + List.of(ContainerEnvironmentEntryDto.builder().key("KEY-1").value("VALUE_1").build(), + ContainerEnvironmentEntryDto.builder().key("KEY_2").value("VALUE_2").build()); + var containerEnvKeyWithSpace = + List.of(ContainerEnvironmentEntryDto.builder().key("KEY 1").value("VALUE_1").build(), + ContainerEnvironmentEntryDto.builder().key("KEY_2").value("VALUE_2").build()); + var containerEnvKeyWithDollar = + List.of(ContainerEnvironmentEntryDto.builder().key("KEY$1").value("VALUE_1").build(), + ContainerEnvironmentEntryDto.builder().key("KEY_2").value("VALUE_2").build()); + + return Stream.of( + // Admin creating task in TEST_NCA_ID account. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK, + ADMIN_SCOPE_LIST_TASKS), + 100), + TEST_NCA_ID, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_2, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.OK), + // Admin creating task in TEST_NCA_ID_2 account. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK, + ADMIN_SCOPE_LIST_TASKS), + 100), + TEST_NCA_ID_2, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_1, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.OK), + // Another admin creating task in TEST_NCA_ID account. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt("another-admin", + List.of(ADMIN_SCOPE_LAUNCH_TASK, + ADMIN_SCOPE_LIST_TASKS), + 100), + TEST_NCA_ID, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_1, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.OK), + // Admin creating task in an unknown account. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK, + ADMIN_SCOPE_LIST_TASKS), + 100), + "unknown-account", + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_1, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.NOT_FOUND), + // URIs containing team name. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK, + ADMIN_SCOPE_LIST_TASKS), + 100), + TEST_NCA_ID, + MODEL_ARTIFACTS_URL, + RESOURCE_ARTIFACTS_URL_2, + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_1, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.OK), + // non-fully qualified model/resource URLS + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK, + ADMIN_SCOPE_LIST_TASKS), + 100), + TEST_NCA_ID, + removeArtifactHostName(MODEL_ARTIFACTS_URL_3), + removeArtifactHostName(RESOURCE_ARTIFACTS_URL_3), + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_2, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.BAD_REQUEST), + // Model URI containing version name. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK, + ADMIN_SCOPE_LIST_TASKS), + 100), + TEST_NCA_ID, + MODEL_ARTIFACTS_URL_4, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_1, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.BAD_REQUEST), + // Resource URI containing version name. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK, + ADMIN_SCOPE_LIST_TASKS), + 100), + TEST_NCA_ID, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_4, + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_1, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.BAD_REQUEST), + // Optional model. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK, + ADMIN_SCOPE_LIST_TASKS), + 100), + TEST_NCA_ID, + null, + RESOURCE_ARTIFACTS_URL_2, + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_1, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.OK), + // Optional resource. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK, + ADMIN_SCOPE_LIST_TASKS), + 100), + TEST_NCA_ID, + MODEL_ARTIFACTS_URL_3, + null, + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_1, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.OK), + // Model URI does not end with "/files". + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK, + ADMIN_SCOPE_LIST_TASKS), + 100), + TEST_NCA_ID, + "/v2/org/ajwc672qsbdd/models/svc/bis-test:v1", + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_1, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.BAD_REQUEST), + // Resource URI does not end with "/files". + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK, + ADMIN_SCOPE_LIST_TASKS), + 100), + TEST_NCA_ID, + MODEL_ARTIFACTS_URL_3, + "/v2/org/whw3rcpsilnj/resources/svc/bis-test:v1", + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_1, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.BAD_REQUEST), + // Null GpuSpecificationDto. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK, + ADMIN_SCOPE_LIST_TASKS), + 100), + TEST_NCA_ID, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + null, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_1, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.BAD_REQUEST), + // Missing instanceType in GpuSpec. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK, + ADMIN_SCOPE_LIST_TASKS), + 100), + TEST_NCA_ID, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + specWithMissingInstanceType, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_1, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.BAD_REQUEST), + // Invalid instanceType in GpuSpec. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK, + ADMIN_SCOPE_LIST_TASKS), + 100), + TEST_NCA_ID, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + specWithInvalidInstanceType, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_1, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.BAD_REQUEST), + // Missing gpu in GpuSpec. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK, + ADMIN_SCOPE_LIST_TASKS), + 100), + TEST_NCA_ID, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + specWithMissingGpu, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_1, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.BAD_REQUEST), + // Invalid gpu in GpuSpec. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK, + ADMIN_SCOPE_LIST_TASKS), + 100), + TEST_NCA_ID, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + specWithInvalidGpu, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_1, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.BAD_REQUEST), + // Missing backend in GpuSpec. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK, + ADMIN_SCOPE_LIST_TASKS), + 100), + TEST_NCA_ID, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + specWithMissingBackend, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_1, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.OK), + // Missing scope. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, List.of(), 100), + TEST_NCA_ID, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_1, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.FORBIDDEN), + // Missing token. + Arguments.of(null, + TEST_NCA_ID, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_1, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.UNAUTHORIZED), + // Too many tags (limit=64). + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK, + ADMIN_SCOPE_LIST_TASKS), + 100), + TEST_NCA_ID, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + IntStream.range(0, MAX_TAGS_COUNT + 1).mapToObj(i -> "tag" + i) + .collect(Collectors.toSet()), + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_1, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.BAD_REQUEST), + // Too long tags (limit=128). + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK, + ADMIN_SCOPE_LIST_TASKS), + 100), + TEST_NCA_ID, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + Set.of(StringUtils.repeat("tag1", MAX_TAG_LENGTH), + StringUtils.repeat("tag2", MAX_TAG_LENGTH)), + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_1, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.BAD_REQUEST), + // Invalid tag character. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK, + ADMIN_SCOPE_LIST_TASKS), + 100), + TEST_NCA_ID, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + Set.of("\n&abc123["), + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_1, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.BAD_REQUEST), + // Null maxRuntimeDuration with non-GFN backend. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK, + ADMIN_SCOPE_LIST_TASKS), + 100), + TEST_NCA_ID, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + null, + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_2, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.OK), + // Null maxRuntimeDuration with GFN backend. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK, + ADMIN_SCOPE_LIST_TASKS), + 100), + TEST_NCA_ID, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + TEST_GFN_GPU_SPEC_DTO, + null, + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_2, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.BAD_REQUEST), + // Greater than 8hours of maxRuntimeDuration with GFN backend. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK, + ADMIN_SCOPE_LIST_TASKS), + 100), + TEST_NCA_ID, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + TEST_GFN_GPU_SPEC_DTO, + Duration.ofHours(9), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_2, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.BAD_REQUEST), + // Zero maxRuntimeDuration + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK, + ADMIN_SCOPE_LIST_TASKS), + 100), + TEST_NCA_ID, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + TEST_GFN_GPU_SPEC_DTO, + Duration.ZERO, + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_2, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.BAD_REQUEST), + // Zero maxQueuedDuration. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK, + ADMIN_SCOPE_LIST_TASKS), + 100), + TEST_NCA_ID, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + TEST_GFN_GPU_SPEC_DTO, + Duration.ofHours(6), + Duration.ZERO, + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_2, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.BAD_REQUEST), + // Zero terminationGracePeriodDuration. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK, + ADMIN_SCOPE_LIST_TASKS), + 100), + TEST_NCA_ID, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + TEST_GFN_GPU_SPEC_DTO, + Duration.ofHours(6), + Duration.ofHours(3), + Duration.ZERO, + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_2, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.BAD_REQUEST), + // Null maxQueuedDuration. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK, + ADMIN_SCOPE_LIST_TASKS), + 100), + TEST_NCA_ID, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + TEST_GFN_GPU_SPEC_DTO, + Duration.ofHours(2), + null, + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_2, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.OK), + // Null terminationGracePeriodDuration. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK, + ADMIN_SCOPE_LIST_TASKS), + 100), + TEST_NCA_ID, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + TEST_GFN_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + null, + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_2, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.OK), + // terminationGracePeriodDuration greater than maxRuntimeDuration. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK, + ADMIN_SCOPE_LIST_TASKS), + 100), + TEST_NCA_ID, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + TEST_GFN_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(4), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_2, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.BAD_REQUEST), + // Default terminationGracePeriodDuration greater than maxRuntimeDuration. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK, + ADMIN_SCOPE_LIST_TASKS), + 100), + TEST_NCA_ID, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + TEST_GFN_GPU_SPEC_DTO, + Duration.ofMinutes(30), // 30minutes + Duration.ofHours(3), + null, // Default terminationGracePeriodDuration 1h + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_2, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.BAD_REQUEST), + // Null secrets with resultHandlingStrategy UPLOAD + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK, + ADMIN_SCOPE_LIST_TASKS), + 100), + TEST_NCA_ID, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + null, + TEST_RESULTS_LOCATION_1, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.BAD_REQUEST), + // No NGC_API_KEY in secrets with resultHandlingStrategy UPLOAD + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK, + ADMIN_SCOPE_LIST_TASKS), + 100), + TEST_NCA_ID, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + Set.of(SecretDto.builder() + .name("secret-key") + .value(new StringNode("shhh!shhh!")) + .build()), + TEST_RESULTS_LOCATION_1, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.BAD_REQUEST), + // Invalid resultsLocation with just org name and resultsHandlingStrategy UPLOAD + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK, + ADMIN_SCOPE_LIST_TASKS), + 100), + TEST_NCA_ID, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + "orgA", + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.BAD_REQUEST), + // Invalid resultsLocation with just slash after org name. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK, + ADMIN_SCOPE_LIST_TASKS), + 100), + TEST_NCA_ID, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + "orgA/", + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.BAD_REQUEST), + // Invalid resultsLocation with trailing slash after team name. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK, + ADMIN_SCOPE_LIST_TASKS), + 100), + TEST_NCA_ID, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + "orgA/teamB/", + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.BAD_REQUEST), + // Invalid resultsLocation with trailing slash after model name. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK, + ADMIN_SCOPE_LIST_TASKS), + 100), + TEST_NCA_ID, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + "orgA/teamB/modelC/", + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.BAD_REQUEST), + // Invalid resultsLocation with more than org, team, and model names in the path. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK, + ADMIN_SCOPE_LIST_TASKS), + 100), + TEST_NCA_ID, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + "orgA/teamB/modelC/extraD", + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.BAD_REQUEST), + // Invalid/unknown org name in resultsLocation. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK, + ADMIN_SCOPE_LIST_TASKS), + 100), + TEST_NCA_ID, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_UNKNOWN_ORG_NAME + "/" + TEST_MODEL_NAME, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.NOT_FOUND), + // Invalid/unknown team name in resultsLocation. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK, + ADMIN_SCOPE_LIST_TASKS), + 100), + TEST_NCA_ID, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_VALID_ORG_NAME + "/" + TEST_UNKNOWN_TEAM_NAME + "/" + TEST_MODEL_NAME, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.NOT_FOUND), + // Invalid resultsLocation with just org name and resultsHandlingStrategy NONE. + // resultsLocation is not validated if resultHandlingStrategy is NONE. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK, + ADMIN_SCOPE_LIST_TASKS), + 100), + TEST_NCA_ID, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.NONE, + secrets, + "orgA", + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.OK), + // Blank resultsLocation with resultsHandlingStrategy NONE. + // resultsLocation is not validated if resultHandlingStrategy is NONE. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK, + ADMIN_SCOPE_LIST_TASKS), + 100), + TEST_NCA_ID, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.NONE, + secrets, + null, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.OK), + // No NGC_API_KEY in secrets with resultHandlingStrategy NONE. Presence of + // NGC_API_KEY in the secrets is not validated if resultHandlingStrategy is NONE. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK, + ADMIN_SCOPE_LIST_TASKS), + 100), + TEST_NCA_ID, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.NONE, + Set.of(SecretDto.builder() + .name("secret-key") + .value(new StringNode("shhh!shhh!")) + .build()), + TEST_RESULTS_LOCATION_1, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.OK), + // Null secrets with resultHandlingStrategy NONE. Presence of NGC_API_KEY in + // the secrets is not validated if resultHandlingStrategy is NONE. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK, + ADMIN_SCOPE_LIST_TASKS), + 100), + TEST_NCA_ID, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.NONE, + null, + TEST_RESULTS_LOCATION_1, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.OK), + // Environment key with hyphen. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK, + ADMIN_SCOPE_LIST_TASKS), + 100), + TEST_NCA_ID, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_2, + containerEnvKeyWithHyphen, + HttpStatus.BAD_REQUEST), + // Environment key with space. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK, + ADMIN_SCOPE_LIST_TASKS), + 100), + TEST_NCA_ID, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_2, + containerEnvKeyWithSpace, + HttpStatus.BAD_REQUEST), + // Environment key with dollar. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK, + ADMIN_SCOPE_LIST_TASKS), + 100), + TEST_NCA_ID, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + TEST_TAGS, + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_2, + containerEnvKeyWithDollar, + HttpStatus.BAD_REQUEST), + // bad task tags + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK, + ADMIN_SCOPE_LIST_TASKS), + 100), + TEST_NCA_ID, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + Set.of("\n&abc123["), + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_2, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.BAD_REQUEST), + // tags with special namespace:key=value + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK, + ADMIN_SCOPE_LIST_TASKS), + 100), + TEST_NCA_ID, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + Set.of("namespace:key=value"), + TEST_OCI_GPU_SPEC_DTO, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_2, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.OK), + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK, + ADMIN_SCOPE_LIST_TASKS), + 100), + TEST_NCA_ID, + MODEL_ARTIFACTS_URL_3, + RESOURCE_ARTIFACTS_URL_3, + Set.of("namespace:key=value"), + specWithNonEmptyConfiguration, + Duration.ofHours(2), + Duration.ofHours(3), + Duration.ofHours(1), + ResultHandlingStrategyEnum.UPLOAD, + secrets, + TEST_RESULTS_LOCATION_2, + TEST_CONTAINER_ENVIRONMENT, + HttpStatus.BAD_REQUEST) + ); + } + + @ParameterizedTest + @MethodSource("createTaskArgs") + void shouldCreateTask(Object tokenSupplier, + String ncaId, + String modelUri, + String resourceUri, + Set tags, + GpuSpecificationDto gpuSpecificationDto, + Duration maxRuntimeDuration, + Duration maxQueuedDuration, + Duration terminationGracePeriodDuration, + ResultHandlingStrategyEnum resultHandlingStrategy, + Set secrets, + String resultsLocation, + List containerEnvironment, + HttpStatus expectedStatus) { + var requestBodyBuilder = CreateTaskRequest.builder() + .name(TEST_TASK_NAME_1) + .containerArgs(TEST_CONTAINER_ARGS) + .containerImage(TEST_CONTAINER_IMAGE) + .tags(tags) + .maxRuntimeDuration(maxRuntimeDuration) + .maxQueuedDuration(maxQueuedDuration) + .terminationGracePeriodDuration(terminationGracePeriodDuration) + .gpuSpecification(gpuSpecificationDto) + .description(TEST_DESCRIPTION) + .resultsLocation(resultsLocation) + .resultHandlingStrategy(resultHandlingStrategy) + .secrets(secrets) + .containerEnvironment(containerEnvironment); + + if (StringUtils.isNotBlank(modelUri)) { + requestBodyBuilder.models(Set.of( + ArtifactDto.builder().name("model-1") + .version("1.0") + .uri(URI.create(modelUri)) + .build())); + } + + if (StringUtils.isNotBlank(resourceUri)) { + requestBodyBuilder.resources(Set.of( + ArtifactDto.builder().name("resource-1") + .version("1.0") + .uri(URI.create(resourceUri)) + .build())); + } + var token = TestUtil.getToken(tokenSupplier); + var requestEntity = RequestEntity.post(URI.create("/v1/nvct/accounts/" + ncaId + "/tasks")) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", "Bearer " + token) + .body(requestBodyBuilder.build()); + var responseEntity = + testRestTemplate.exchange(requestEntity, TaskResponse.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(expectedStatus); + if (expectedStatus.isError()) { + return; + } + + var responseBody = responseEntity.getBody(); + assertThat(responseBody).isNotNull(); + assertThat(responseBody.task().id()).isNotNull(); + assertThat(responseBody.task().name()).isEqualTo(TEST_TASK_NAME_1); + assertThat(responseBody.task().status()).isEqualTo(TaskStatusEnum.QUEUED); + assertThat(responseBody.task().ncaId()).isEqualTo(ncaId); + assertThat(responseBody.task().containerArgs()).isEqualTo(TEST_CONTAINER_ARGS); + assertThat(responseBody.task().containerImage()).isEqualTo(TEST_CONTAINER_IMAGE); + assertThat(responseBody.task().containerEnvironment()).isEqualTo(containerEnvironment); + assertThat(responseBody.task().createdAt()).isNotNull(); + assertThat(responseBody.task().gpuSpecification()).isEqualTo(gpuSpecificationDto); + + if (StringUtils.isNotBlank(resultsLocation)) { + assertThat(responseBody.task().resultsLocation()).isEqualTo(resultsLocation); + } else { + assertThat(responseBody.task().resultsLocation()).isBlank(); + } + + if (resultHandlingStrategy != null) { + assertThat(responseBody.task().resultHandlingStrategy()) + .isEqualTo(resultHandlingStrategy); + } else { + assertThat(responseBody.task().resultHandlingStrategy()).isNull(); + } + + if (maxRuntimeDuration != null) { + assertThat(responseBody.task().maxRuntimeDuration()).isNotNull(); + assertThat(responseBody.task().maxRuntimeDuration().toString()) + .hasToString(maxRuntimeDuration.toString()); + } else { + assertThat(responseBody.task().maxRuntimeDuration()).isNull(); + } + assertThat(responseBody.task().maxQueuedDuration()).isNotNull(); + if (maxQueuedDuration != null) { + assertThat(responseBody.task().maxQueuedDuration().toString()) + .hasToString(maxQueuedDuration.toString()); + } else { + assertThat(responseBody.task().maxQueuedDuration().toString()) + .hasToString("PT72H"); // Default value. + } + assertThat(responseBody.task().terminationGracePeriodDuration()).isNotNull(); + if (terminationGracePeriodDuration != null) { + assertThat(responseBody.task().terminationGracePeriodDuration().toString()) + .hasToString(terminationGracePeriodDuration.toString()); + } else { + assertThat(responseBody.task().terminationGracePeriodDuration().toString()) + .hasToString("PT1H"); // Default value + } + + if (StringUtils.isNotBlank(modelUri)) { + assertThat(responseBody.task().models()).isNotNull().hasSize(1); + var model = responseBody.task().models().stream().findFirst().get(); + if (modelUri.startsWith(BASE_ARTIFACT_URL)) { + assertThat(model.getUri()).isEqualTo(URI.create(modelUri)); + } else { + // Make sure it already be transformed to fully-qualified url. + assertThat(model.getUri()).isEqualTo(URI.create("https://localhost-ngc" + modelUri)); + } + } else { + assertThat(responseBody.task().models()).isNull(); + } + if (StringUtils.isNotBlank(resourceUri)) { + assertThat(responseBody.task().resources()).isNotNull().hasSize(1); + var resource = responseBody.task().resources().stream().findFirst().get(); + if (resourceUri.startsWith(BASE_ARTIFACT_URL)) { + assertThat(resource.getUri()).isEqualTo(URI.create(resourceUri)); + } else { + // Make sure it already be transformed to fully-qualified url. + assertThat(resource.getUri()).isEqualTo( + URI.create("https://localhost-ngc" + resourceUri)); + } + } else { + assertThat(responseBody.task().resources()).isNull(); + } + + assertThat(responseBody.task().tags()).isEqualTo(tags); + assertThat(responseBody.task().description()).isEqualTo(TEST_DESCRIPTION); + + var taskId = responseBody.task().id(); + var entity = tasksRepository + .getByTaskId(taskId) + .orElseThrow(() -> new NotFoundException("Task not found")); + assertThat(entity).isNotNull(); + assertThat(entity.getHealth()).isNull(); + } + + Stream listTasksArgs() { + return Stream.of( + // List tasks in TEST_NCA_ID account. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LIST_TASKS), + 100), + TEST_NCA_ID, + List.of(TEST_TASK_ID_1, TEST_TASK_ID_2), + HttpStatus.OK), + // List non-existent tasks in TEST_NCA_ID_2 account. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LIST_TASKS), + 100), + TEST_NCA_ID_2, + List.of(), + HttpStatus.OK), + // List non-existent tasks in non-existent account. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LIST_TASKS), + 100), + "unknown-account", + List.of(), + HttpStatus.NOT_FOUND), + // Some admin list tasks in TEST_NCA_ID account. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt("some-admin", + List.of(ADMIN_SCOPE_LIST_TASKS), + 100), + TEST_NCA_ID, + List.of(TEST_TASK_ID_1, TEST_TASK_ID_2), + HttpStatus.OK), + // Missing scope. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, List.of(), 100), + TEST_NCA_ID, + List.of(TEST_TASK_ID_1, TEST_TASK_ID_2), + HttpStatus.FORBIDDEN), + // Missing token. + Arguments.of(null, + TEST_NCA_ID, + List.of(TEST_TASK_ID_1, TEST_TASK_ID_2), + HttpStatus.UNAUTHORIZED) + ); + } + + @ParameterizedTest + @MethodSource("listTasksArgs") + void shouldListTasks(String token, + String ncaId, + List expectedTasks, + HttpStatus expectedStatus) { + // Create Tasks in TEST_NCA_ID account tied to TEST_CLIENT_ID. + var task1 = TestUtil.createTaskEntity(TEST_TASK_ID_1, TEST_NCA_ID, TEST_TASK_NAME_1, + jsonMapper); + var task2 = TestUtil.createTaskEntity(TEST_TASK_ID_2, TEST_NCA_ID, TEST_TASK_NAME_2, + jsonMapper); + + // Save tasks. + tasksRepository.save(task1); + tasksRepository.save(task2); + + var requestEntity = + RequestEntity.get(URI.create("/v1/nvct/accounts/" + ncaId + "/tasks")) + .header("Authorization", "Bearer " + token) + .build(); + var responseEntity = + testRestTemplate.exchange(requestEntity, ListTasksResponse.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(expectedStatus); + if (expectedStatus.isError()) { + return; + } + + var responseBody = responseEntity.getBody(); + assertThat(responseBody).isNotNull(); + assertThat(responseBody.cursor()).isNull(); + assertThat(responseBody.limit()).isNull(); + assertThat(expectedTasks).isNotNull(); + assertThat(responseBody.tasks()).hasSize(expectedTasks.size()); + var tasks = responseBody.tasks().stream() + .collect(Collectors.toMap(TaskDto::id, Function.identity())); + assertThat(tasks.keySet()).isEqualTo(new HashSet<>(expectedTasks)); + verifyReturnedTasksIntegrity(expectedTasks, QUEUED, tasks); + } + + void verifyReturnedTasksIntegrity(List expectedTasks, TaskStatus expectedStatus, Map tasks) { + for (UUID expectedTaskId : expectedTasks) { + var taskDto = tasks.get(expectedTaskId); + assertThat(taskDto).isNotNull(); + assertThat(taskDto.createdAt()).isNotNull(); + assertThat(taskDto.status()).isEqualTo(TaskStatusEnum.fromText(expectedStatus.toString())); + assertThat(taskDto.containerImage()).isNotNull(); + assertThat(taskDto.containerArgs()).isNotBlank(); + assertThat(taskDto.containerEnvironment()).hasSize(3); + if (taskDto.id().equals(TEST_TASK_ID_1)) { + assertThat(taskDto.name()).isEqualTo(TEST_TASK_NAME_1); + } else if (taskDto.id().equals(TEST_TASK_ID_2)) { + assertThat(taskDto.name()).isEqualTo(TEST_TASK_NAME_2); + } else if (taskDto.id().equals(TEST_TASK_ID_3)) { + assertThat(taskDto.name()).isEqualTo(TEST_TASK_NAME_3); + } else { + fail("unknown function returned"); + } + assertThat(taskDto.description()).isNotEmpty(); + assertThat(taskDto.tags()).isNotEmpty(); + assertThat(taskDto.gpuSpecification()).isNotNull(); + assertThat(taskDto.models()) + .isEqualTo(taskMapperService.getModelDtos(TEST_MODELS).get()); + assertThat(taskDto.resources()) + .isEqualTo(taskMapperService.getResourceDtos(TEST_RESOURCES).get()); + } + } + + + Stream taskArgs() { + return Stream.of( + // TEST_TASK_ID_1 belongs to TEST_NCA_ID account. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_TASK_DETAILS, + ADMIN_SCOPE_CANCEL_TASK, + ADMIN_SCOPE_DELETE_TASK), + 100), + TEST_NCA_ID, + TEST_TASK_ID_1, + HttpStatus.OK), + // Unknown task using TEST_NCA_ID account. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_TASK_DETAILS, + ADMIN_SCOPE_CANCEL_TASK, + ADMIN_SCOPE_DELETE_TASK), + 100), + TEST_NCA_ID, + UUID.randomUUID(), + HttpStatus.NOT_FOUND), + // TEST_TASK_ID_1(known task) with unknown account. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_TASK_DETAILS, + ADMIN_SCOPE_CANCEL_TASK, + ADMIN_SCOPE_DELETE_TASK), + 100), + "unknown-account", + TEST_TASK_ID_1, + HttpStatus.NOT_FOUND), + // TEST_TASK_ID_1 does not belong to the TEST_NCA_ID_2 account. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_TASK_DETAILS, + ADMIN_SCOPE_CANCEL_TASK, + ADMIN_SCOPE_DELETE_TASK), + 100), + TEST_NCA_ID_2, + TEST_TASK_ID_1, + HttpStatus.NOT_FOUND), + // Some other super admin retrieving task details. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt("some-other-super-admin", + List.of(ADMIN_SCOPE_TASK_DETAILS, + ADMIN_SCOPE_CANCEL_TASK, + ADMIN_SCOPE_DELETE_TASK), + 100), + TEST_NCA_ID, + TEST_TASK_ID_1, + HttpStatus.OK), + // Missing scope. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, List.of(), 100), + TEST_NCA_ID, + TEST_TASK_ID_1, + HttpStatus.FORBIDDEN), + // No token. + Arguments.of(null, + TEST_NCA_ID, + TEST_TASK_ID_1, + HttpStatus.UNAUTHORIZED) + ); + } + + @ParameterizedTest + @MethodSource("taskArgs") + void shouldGetTaskDetails(Object tokenSupplier, String ncaId, UUID taskId, HttpStatus expectedStatus) { + var token = TestUtil.getToken(tokenSupplier); + // Create Tasks in TEST_NCA_ID account tied to TEST_CLIENT_ID. + var task1 = TestUtil.createTaskEntity(TEST_TASK_ID_1, TEST_NCA_ID, TEST_TASK_NAME_1, + jsonMapper); + var task2 = TestUtil.createTaskEntity(TEST_TASK_ID_2, TEST_NCA_ID, TEST_TASK_NAME_2, + jsonMapper); + + // Save tasks. + tasksRepository.save(task1); + tasksRepository.save(task2); + + var requestEntity = + RequestEntity.get(URI.create("/v1/nvct/accounts/" + ncaId + "/tasks/" + taskId)) + .accept(MediaType.APPLICATION_JSON) + .header("Authorization", "Bearer " + token) + .build(); + var responseEntity = + testRestTemplate.exchange(requestEntity, TaskResponse.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(expectedStatus); + if (expectedStatus.isError()) { + return; + } + + var responseBody = responseEntity.getBody(); + assertThat(responseBody).isNotNull(); + assertThat(responseBody.task()).isNotNull(); + + var taskDto = responseBody.task(); + assertThat(taskDto).isNotNull(); + assertThat(taskDto.createdAt()).isNotNull(); + assertThat(taskDto.status()).isEqualTo(TaskStatusEnum.QUEUED); + assertThat(taskDto.containerImage()).isNotNull(); + assertThat(taskDto.containerArgs()).isNotBlank(); + assertThat(taskDto.containerEnvironment()).hasSize(3); + assertThat(taskDto.name()).isEqualTo(TEST_TASK_NAME_1); + assertThat(taskDto.description()).isNotEmpty(); + assertThat(taskDto.tags()).isNotEmpty(); + assertThat(taskDto.gpuSpecification()).isNotNull(); + assertThat(taskDto.models()).isEqualTo(taskMapperService.getModelDtos(TEST_MODELS).get()); + assertThat(taskDto.resources()) + .isEqualTo(taskMapperService.getResourceDtos(TEST_RESOURCES).get()); + assertThat(taskDto.resultsLocation()).isNotEmpty(); + assertThat(taskDto.resultHandlingStrategy()).isEqualTo(ResultHandlingStrategyEnum.UPLOAD); + } + + Stream cancelTaskArgs() { + return Stream.of( + // TEST_TASK_ID_1 belongs to TEST_NCA_ID account. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_TASK_DETAILS, + ADMIN_SCOPE_CANCEL_TASK, + ADMIN_SCOPE_DELETE_TASK), + 100), + TEST_NCA_ID, + TEST_TASK_ID_1, + QUEUED, + HttpStatus.OK), + // Unknown task using TEST_NCA_ID account. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_TASK_DETAILS, + ADMIN_SCOPE_CANCEL_TASK, + ADMIN_SCOPE_DELETE_TASK), + 100), + TEST_NCA_ID, + UUID.randomUUID(), + QUEUED, + HttpStatus.NOT_FOUND), + // TEST_TASK_ID_1(known task) with unknown account. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_TASK_DETAILS, + ADMIN_SCOPE_CANCEL_TASK, + ADMIN_SCOPE_DELETE_TASK), + 100), + "unknown-account", + TEST_TASK_ID_1, + QUEUED, + HttpStatus.NOT_FOUND), + // TEST_TASK_ID_1 does not belong to the TEST_NCA_ID_2 account. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_TASK_DETAILS, + ADMIN_SCOPE_CANCEL_TASK, + ADMIN_SCOPE_DELETE_TASK), + 100), + TEST_NCA_ID_2, + TEST_TASK_ID_1, + QUEUED, + HttpStatus.NOT_FOUND), + // Some other super admin retrieving task details. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt("some-other-super-admin", + List.of(ADMIN_SCOPE_TASK_DETAILS, + ADMIN_SCOPE_CANCEL_TASK, + ADMIN_SCOPE_DELETE_TASK), + 100), + TEST_NCA_ID, + TEST_TASK_ID_1, + QUEUED, + HttpStatus.OK), + // Task status is CANCELED already + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_TASK_DETAILS, + ADMIN_SCOPE_CANCEL_TASK, + ADMIN_SCOPE_DELETE_TASK), + 100), + TEST_NCA_ID, + TEST_TASK_ID_1, + CANCELED, + HttpStatus.BAD_REQUEST), + // Task status is ERRORED already + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_TASK_DETAILS, + ADMIN_SCOPE_CANCEL_TASK, + ADMIN_SCOPE_DELETE_TASK), + 100), + TEST_NCA_ID, + TEST_TASK_ID_1, + ERRORED, + HttpStatus.BAD_REQUEST), + // Task status is COMPLETED already + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_TASK_DETAILS, + ADMIN_SCOPE_CANCEL_TASK, + ADMIN_SCOPE_DELETE_TASK), + 100), + TEST_NCA_ID, + TEST_TASK_ID_1, + COMPLETED, + HttpStatus.BAD_REQUEST), + // Missing scope. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, List.of(), 100), + TEST_NCA_ID, + TEST_TASK_ID_1, + QUEUED, + HttpStatus.FORBIDDEN), + // No token. + Arguments.of(null, + TEST_NCA_ID, + TEST_TASK_ID_1, + QUEUED, + HttpStatus.UNAUTHORIZED) + ); + } + + @ParameterizedTest + @MethodSource("cancelTaskArgs") + void shouldCancelTask(Object tokenSupplier, String ncaId, UUID taskId, TaskStatus status, HttpStatus expectedStatus) { + var token = TestUtil.getToken(tokenSupplier); + + // Create Tasks in TEST_NCA_ID account tied to TEST_CLIENT_ID. + var task1 = TestUtil.createTaskEntity(TEST_TASK_ID_1, TEST_NCA_ID, TEST_TASK_NAME_1, + jsonMapper); + var task2 = TestUtil.createTaskEntity(TEST_TASK_ID_2, TEST_NCA_ID, TEST_TASK_NAME_2, + jsonMapper); + task1.setStatus(status); + task2.setStatus(status); + + // Save tasks. + tasksRepository.save(task1); + tasksRepository.save(task2); + + var uri = URI.create("/v1/nvct/accounts/" + ncaId + "/tasks/" + taskId + "/cancel"); + var requestEntity = + RequestEntity.post(uri) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", "Bearer " + token) + .build(); + var responseEntity = + testRestTemplate.exchange(requestEntity, TaskResponse.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(expectedStatus); + if (expectedStatus.isError()) { + return; + } + + var responseBody = responseEntity.getBody(); + assertThat(responseBody).isNotNull(); + assertThat(responseBody.task()).isNotNull(); + + var taskDto = responseBody.task(); + assertThat(taskDto).isNotNull(); + assertThat(taskDto.createdAt()).isNotNull(); + assertThat(taskDto.status()).isEqualTo(TaskStatusEnum.CANCELED); + assertThat(taskDto.containerImage()).isNotNull(); + assertThat(taskDto.containerArgs()).isNotBlank(); + assertThat(taskDto.containerEnvironment()).hasSize(3); + assertThat(taskDto.name()).isEqualTo(TEST_TASK_NAME_1); + assertThat(taskDto.description()).isNotEmpty(); + assertThat(taskDto.tags()).isNotEmpty(); + assertThat(taskDto.gpuSpecification()).isNotNull(); + assertThat(taskDto.models()).isEqualTo(taskMapperService.getModelDtos(TEST_MODELS).get()); + assertThat(taskDto.resources()) + .isEqualTo(taskMapperService.getResourceDtos(TEST_RESOURCES).get()); + } + + Stream deleteTaskArgs() { + return Stream.of( + // TEST_TASK_ID_1 belongs to TEST_NCA_ID account. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_TASK_DETAILS, + ADMIN_SCOPE_CANCEL_TASK, + ADMIN_SCOPE_DELETE_TASK), + 100), + TEST_NCA_ID, + TEST_TASK_ID_1, + HttpStatus.NO_CONTENT), + // Unknown task using TEST_NCA_ID account. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_TASK_DETAILS, + ADMIN_SCOPE_CANCEL_TASK, + ADMIN_SCOPE_DELETE_TASK), + 100), + TEST_NCA_ID, + UUID.randomUUID(), + HttpStatus.NOT_FOUND), + // TEST_TASK_ID_1(known task) with unknown account. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_TASK_DETAILS, + ADMIN_SCOPE_CANCEL_TASK, + ADMIN_SCOPE_DELETE_TASK), + 100), + "unknown-account", + TEST_TASK_ID_1, + HttpStatus.NOT_FOUND), + // TEST_TASK_ID_1 does not belong to the TEST_NCA_ID_2 account. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_TASK_DETAILS, + ADMIN_SCOPE_CANCEL_TASK, + ADMIN_SCOPE_DELETE_TASK), + 100), + TEST_NCA_ID_2, + TEST_TASK_ID_1, + HttpStatus.NOT_FOUND), + // Some other super admin retrieving task details. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt("some-other-super-admin", + List.of(ADMIN_SCOPE_TASK_DETAILS, + ADMIN_SCOPE_CANCEL_TASK, + ADMIN_SCOPE_DELETE_TASK), + 100), + TEST_NCA_ID, + TEST_TASK_ID_1, + HttpStatus.NO_CONTENT), + // Missing scope. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, List.of(), 100), + TEST_NCA_ID, + TEST_TASK_ID_1, + HttpStatus.FORBIDDEN), + // No token. + Arguments.of(null, + TEST_NCA_ID, + TEST_TASK_ID_1, + HttpStatus.UNAUTHORIZED) + ); + } + + @ParameterizedTest + @MethodSource("deleteTaskArgs") + void shouldDeleteTask(Object tokenSupplier, String ncaId, UUID taskId, HttpStatus expectedStatus) { + var token = TestUtil.getToken(tokenSupplier); + + // Create Tasks in TEST_NCA_ID account tied to TEST_CLIENT_ID. + var task1 = TestUtil.createTaskEntity(TEST_TASK_ID_1, TEST_NCA_ID, TEST_TASK_NAME_1, + jsonMapper); + var task2 = TestUtil.createTaskEntity(TEST_TASK_ID_2, TEST_NCA_ID, TEST_TASK_NAME_2, + jsonMapper); + + // Save tasks. + tasksRepository.save(task1); + tasksRepository.save(task2); + + var requestEntity = + RequestEntity.delete(URI.create("/v1/nvct/accounts/" + ncaId + "/tasks/" + taskId)) + .header("Authorization", "Bearer " + token) + .build(); + var responseEntity = + testRestTemplate.exchange(requestEntity, Void.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(expectedStatus); + var entity = tasksRepository.getByTaskId(taskId); + if (expectedStatus.isError()) { + if (responseEntity.getStatusCode() != HttpStatus.NOT_FOUND) { + assertThat(entity).isNotEmpty(); + } + return; + } + assertThat(entity).isEmpty(); + } + + @Test + void shouldFailWhenGracePeriodIsGreaterThanMaxRuntimeDuration() { + var token = MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK, ADMIN_SCOPE_LIST_TASKS), + 100); + var modelUri = URI.create(MODEL_ARTIFACTS_URL_3); + var modelDtos = Set.of(ArtifactDto.builder().name("model-1") + .version("1.0").uri(modelUri).build()); + var resourceUri = URI.create(RESOURCE_ARTIFACTS_URL_3); + var resourceDtos = Set.of(ArtifactDto.builder().name("resource-1") + .version("1.0") + .uri(resourceUri) + .build()); + var requestBodyBuilder = CreateTaskRequest.builder() + .name(TEST_TASK_NAME_1) + .containerArgs(TEST_CONTAINER_ARGS) + .containerImage(TEST_CONTAINER_IMAGE) + .models(modelDtos) + .resources(resourceDtos) + .tags(TEST_TAGS) + .resultsLocation(TEST_RESULTS_LOCATION_1) + .gpuSpecification(TEST_OCI_GPU_SPEC_DTO) + .maxRuntimeDuration(Duration.ofHours(3)) + .terminationGracePeriodDuration(Duration.ofHours(5)) + .description(TEST_DESCRIPTION); + var requestEntity = RequestEntity.post(URI.create("/v1/nvct/accounts/" + TEST_NCA_ID + "/tasks")) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", "Bearer " + token) + .body(requestBodyBuilder.build()); + var responseEntity = + testRestTemplate.exchange(requestEntity, TaskResponse.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.BAD_REQUEST); + } + + @Test + void shouldThrowExceptionForTooLongDescription() { + var token = MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK), + 100); + var requestBody = CreateTaskRequest.builder() + .name(TEST_TASK_NAME_1) + .containerArgs(TEST_CONTAINER_ARGS) + .containerImage(TEST_CONTAINER_IMAGE) + .tags(TEST_TAGS) + .gpuSpecification(TEST_OCI_GPU_SPEC_DTO) + .maxRuntimeDuration(Duration.ofHours(2)) + .maxQueuedDuration(Duration.ofHours(3)) + .terminationGracePeriodDuration(Duration.ofHours(1)) + // Create a description that exceeds MAX_DESCRIPTION_LENGTH (256) + .description(StringUtils.repeat("a", 257)) + .resultHandlingStrategy(ResultHandlingStrategyEnum.NONE) + .containerEnvironment(TEST_CONTAINER_ENVIRONMENT) + .build(); + + var requestEntity = RequestEntity.post(URI.create("/v1/nvct/accounts/" + TEST_NCA_ID + "/tasks")) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", "Bearer " + token) + .body(requestBody); + + var responseEntity = testRestTemplate.exchange(requestEntity, TaskResponse.class); + + assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.BAD_REQUEST); + } + +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/XAccountTaskWithHelmValidationPolicyTest.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/XAccountTaskWithHelmValidationPolicyTest.java new file mode 100644 index 000000000..364448160 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/XAccountTaskWithHelmValidationPolicyTest.java @@ -0,0 +1,379 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.rest.task; + +import static com.nvidia.nvct.IntegrationTestConfiguration.MOCK_OAUTH2_TOKEN_SERVER; +import static com.nvidia.nvct.util.NvctConstants.ADMIN_SCOPE_LAUNCH_TASK; +import static com.nvidia.nvct.util.NvctConstants.ADMIN_SCOPE_LIST_TASKS; +import static com.nvidia.nvct.util.NvctConstants.ADMIN_SCOPE_TASK_DETAILS; +import static com.nvidia.nvct.util.TestConstants.TEST_ADMIN_SUBJECT; +import static com.nvidia.nvct.util.TestConstants.TEST_DESCRIPTION; +import static com.nvidia.nvct.util.TestConstants.TEST_HELM_CHART; +import static com.nvidia.nvct.util.TestConstants.TEST_HELM_VALIDATION_POLICY_DTO; +import static com.nvidia.nvct.util.TestConstants.TEST_NCA_ID; +import static com.nvidia.nvct.util.TestConstants.TEST_OCI_GPU_SPEC_WITH_HELM_POLICY_DTO; +import static com.nvidia.nvct.util.TestConstants.TEST_RESULTS_LOCATION_1; +import static com.nvidia.nvct.util.TestConstants.TEST_SECRETS; +import static com.nvidia.nvct.util.TestConstants.TEST_TAGS; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_NAME_1; +import static org.assertj.core.api.Assertions.assertThat; + +import tools.jackson.databind.json.JsonMapper; +import com.nvidia.boot.mock.ngc.MockCasServer; +import com.nvidia.boot.mock.ngc.MockNgcContainerRegistryServer; +import com.nvidia.nvct.IntegrationTestConfiguration; +import com.nvidia.nvct.NvctTestApp; +import com.nvidia.nvct.grpc.TestTaskService; +import com.nvidia.nvct.persistence.task.TasksRepository; +import com.nvidia.nvct.rest.task.dto.CreateTaskRequest; +import com.nvidia.nvct.rest.task.dto.GpuSpecificationDto; +import com.nvidia.nvct.rest.task.dto.HelmValidationPolicyDto; +import com.nvidia.nvct.rest.task.dto.ListTasksResponse; +import com.nvidia.nvct.rest.task.dto.ResultHandlingStrategyEnum; +import com.nvidia.nvct.rest.task.dto.TaskResponse; +import com.nvidia.nvct.rest.task.dto.ValidationPolicyNameEnum; +import com.nvidia.nvct.util.MockEssServer; +import com.nvidia.nvct.util.MockNotaryServer; +import com.nvidia.nvct.util.MockNvcfServer; +import com.nvidia.nvct.util.MockRevalServer; +import com.nvidia.nvct.util.MockIcmsServer; +import java.net.URI; +import java.net.URL; +import java.time.Duration; +import java.util.List; +import java.util.stream.Stream; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.resttestclient.TestRestTemplate; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.RequestEntity; +import org.springframework.test.context.ContextConfiguration; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@Slf4j +@SpringBootTest(classes = {NvctTestApp.class, + IntegrationTestConfiguration.class}, + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + properties = "spring.profiles.active=test") +@ContextConfiguration(initializers = IntegrationTestConfiguration.Initializer.class) +@AutoConfigureTestRestTemplate +class XAccountTaskWithHelmValidationPolicyTest { + @Autowired + private TestRestTemplate testRestTemplate; + + @Autowired + private TasksRepository tasksRepository; + + @Autowired + private TestTaskService testTaskService; + + @Autowired + private JsonMapper jsonMapper; + + @Value("${nvct.registries.recognized.container.ngc.hostname}") + private String ngcContainerRegistryHostname; + + @Value("${nvct.registries.recognized.model.ngc.hostname}") + private String casBaseUrl; + + @Value("${nvct.registries.recognized.model.ngc.oauth2.base-url}") + private String authnBaseUrl; + + @Value("${nvct.notary.base-url}") + private String notaryBaseUrl; + + @Value("${spring.security.oauth2.client.registration.notary.client-id}") + private String notaryClientId; + + @Value("${nvct.nvcf.base-url}") + private URL nvcfBaseUrl; + + @Value("${nvct.icms.base-url}") + private URL icmsBaseUrl; + + @Value("${nvct.ess.base-url}") + private String essBaseUrl; + + @Value("${nvct.reval.base-url}") + private URI revalBaseUrl; + + @BeforeAll + void beforeAll() { + log.info("{}: Started running tests", this.getClass().getSimpleName()); + MockNvcfServer.start(nvcfBaseUrl); + MockCasServer.start(authnBaseUrl, casBaseUrl); + MockEssServer.start(essBaseUrl); + MockIcmsServer.start(icmsBaseUrl, jsonMapper); + MockNotaryServer.start(notaryBaseUrl, notaryClientId); + MockRevalServer.start(revalBaseUrl); + MockNgcContainerRegistryServer.start(ngcContainerRegistryHostname); + } + + @AfterAll + void cleanup() { + MockNvcfServer.stop(); + MockCasServer.stop(); + MockIcmsServer.stop(); + MockEssServer.stop(); + MockNotaryServer.stop(); + MockRevalServer.stop(); + MockNgcContainerRegistryServer.stop(); + log.info("{}: Completed running tests", this.getClass().getSimpleName()); + } + + @AfterEach + void reset() { + log.info("{} reset", this.getClass().getSimpleName()); + testTaskService.clearAll(); + MockEssServer.clearSecrets(); + } + + @BeforeEach + void setup() { + log.info("{} setup", this.getClass().getSimpleName()); + } + + Stream createTaskWithHelmValidationPolicyArgs() { + var validPolicyDefault = HelmValidationPolicyDto.builder() + .name(ValidationPolicyNameEnum.DEFAULT) + .extraKubernetesTypes(List.of( + HelmValidationPolicyDto.KubernetesType.builder() + .group("apps") + .version("v1") + .kind("Deployment") + .build())) + .build(); + var validPolicyUnrestricted = HelmValidationPolicyDto.builder() + .name(ValidationPolicyNameEnum.UNRESTRICTED) + .build(); + var validPolicyNoExtraTypes = HelmValidationPolicyDto.builder() + .name(ValidationPolicyNameEnum.DEFAULT) + .build(); + var invalidPolicyNullName = HelmValidationPolicyDto.builder() + .name(null) + .extraKubernetesTypes(List.of( + HelmValidationPolicyDto.KubernetesType.builder() + .group("apps") + .version("v1") + .kind("Deployment") + .build())) + .build(); + var invalidPolicyBlankGroup = HelmValidationPolicyDto.builder() + .name(ValidationPolicyNameEnum.DEFAULT) + .extraKubernetesTypes(List.of( + HelmValidationPolicyDto.KubernetesType.builder() + .group("") + .version("v1") + .kind("Deployment") + .build())) + .build(); + var invalidPolicyBlankVersion = HelmValidationPolicyDto.builder() + .name(ValidationPolicyNameEnum.DEFAULT) + .extraKubernetesTypes(List.of( + HelmValidationPolicyDto.KubernetesType.builder() + .group("apps") + .version("") + .kind("Deployment") + .build())) + .build(); + var invalidPolicyBlankKind = HelmValidationPolicyDto.builder() + .name(ValidationPolicyNameEnum.DEFAULT) + .extraKubernetesTypes(List.of( + HelmValidationPolicyDto.KubernetesType.builder() + .group("apps") + .version("v1") + .kind("") + .build())) + .build(); + + return Stream.of( + // Valid policy with DEFAULT name and extraKubernetesTypes. + Arguments.of(validPolicyDefault, HttpStatus.OK), + // Valid policy with UNRESTRICTED name and no extraKubernetesTypes. + Arguments.of(validPolicyUnrestricted, HttpStatus.OK), + // Valid policy with DEFAULT name and no extraKubernetesTypes. + Arguments.of(validPolicyNoExtraTypes, HttpStatus.OK), + // Invalid policy with null name. + Arguments.of(invalidPolicyNullName, HttpStatus.BAD_REQUEST), + // Invalid policy with blank group in extraKubernetesTypes. + Arguments.of(invalidPolicyBlankGroup, HttpStatus.BAD_REQUEST), + // Invalid policy with blank version in extraKubernetesTypes. + Arguments.of(invalidPolicyBlankVersion, HttpStatus.BAD_REQUEST), + // Invalid policy with blank kind in extraKubernetesTypes. + Arguments.of(invalidPolicyBlankKind, HttpStatus.BAD_REQUEST)); + } + + @ParameterizedTest + @MethodSource("createTaskWithHelmValidationPolicyArgs") + void shouldCreateTaskWithHelmValidationPolicy( + HelmValidationPolicyDto helmValidationPolicy, + HttpStatus expectedStatus) { + var token = MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK, + ADMIN_SCOPE_LIST_TASKS), + 100); + var gpuSpec = GpuSpecificationDto.builder() + .gpu(TEST_OCI_GPU_SPEC_WITH_HELM_POLICY_DTO.gpu()) + .instanceType(TEST_OCI_GPU_SPEC_WITH_HELM_POLICY_DTO.instanceType()) + .backend(TEST_OCI_GPU_SPEC_WITH_HELM_POLICY_DTO.backend()) + .helmValidationPolicy(helmValidationPolicy) + .build(); + var requestBody = CreateTaskRequest.builder() + .name(TEST_TASK_NAME_1) + .helmChart(TEST_HELM_CHART) + .tags(TEST_TAGS) + .gpuSpecification(gpuSpec) + .maxRuntimeDuration(Duration.ofHours(2)) + .maxQueuedDuration(Duration.ofHours(1)) + .terminationGracePeriodDuration(Duration.ofHours(1)) + .description(TEST_DESCRIPTION) + .resultsLocation(TEST_RESULTS_LOCATION_1) + .resultHandlingStrategy(ResultHandlingStrategyEnum.UPLOAD) + .secrets(TEST_SECRETS) + .build(); + + var requestEntity = RequestEntity + .post(URI.create("/v1/nvct/accounts/" + TEST_NCA_ID + "/tasks")) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", "Bearer " + token) + .body(requestBody); + var responseEntity = + testRestTemplate.exchange(requestEntity, TaskResponse.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(expectedStatus); + if (expectedStatus.isError()) { + return; + } + + var responseBody = responseEntity.getBody(); + assertThat(responseBody).isNotNull(); + assertThat(responseBody.task().id()).isNotNull(); + assertThat(responseBody.task().name()).isEqualTo(TEST_TASK_NAME_1); + assertThat(responseBody.task().ncaId()).isEqualTo(TEST_NCA_ID); + assertThat(responseBody.task().gpuSpecification()).isNotNull(); + assertThat(responseBody.task().gpuSpecification().helmValidationPolicy()) + .isEqualTo(helmValidationPolicy); + } + + @Test + void shouldListTasksWithHelmValidationPolicy() { + var token = MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK, + ADMIN_SCOPE_LIST_TASKS), + 100); + var requestBody = CreateTaskRequest.builder() + .name(TEST_TASK_NAME_1) + .helmChart(TEST_HELM_CHART) + .gpuSpecification(TEST_OCI_GPU_SPEC_WITH_HELM_POLICY_DTO) + .maxRuntimeDuration(Duration.ofHours(2)) + .maxQueuedDuration(Duration.ofHours(1)) + .terminationGracePeriodDuration(Duration.ofHours(1)) + .description(TEST_DESCRIPTION) + .resultsLocation(TEST_RESULTS_LOCATION_1) + .resultHandlingStrategy(ResultHandlingStrategyEnum.UPLOAD) + .secrets(TEST_SECRETS) + .build(); + var createEntity = RequestEntity + .post(URI.create("/v1/nvct/accounts/" + TEST_NCA_ID + "/tasks")) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", "Bearer " + token) + .body(requestBody); + var createResponse = + testRestTemplate.exchange(createEntity, TaskResponse.class); + assertThat(createResponse.getStatusCode()).isEqualTo(HttpStatus.OK); + + var listEntity = RequestEntity + .get(URI.create("/v1/nvct/accounts/" + TEST_NCA_ID + "/tasks")) + .header("Authorization", "Bearer " + token) + .build(); + var listResponse = + testRestTemplate.exchange(listEntity, ListTasksResponse.class); + assertThat(listResponse.getStatusCode()).isEqualTo(HttpStatus.OK); + + var responseBody = listResponse.getBody(); + assertThat(responseBody).isNotNull(); + + var tasks = responseBody.tasks(); + assertThat(tasks).isNotEmpty(); + + tasks.forEach(task -> { + assertThat(task.gpuSpecification()).isNotNull(); + assertThat(task.gpuSpecification().helmValidationPolicy()) + .isEqualTo(TEST_HELM_VALIDATION_POLICY_DTO); + }); + } + + @Test + void shouldGetTaskDetailsWithHelmValidationPolicy() { + var token = MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK, + ADMIN_SCOPE_TASK_DETAILS), + 100); + var requestBody = CreateTaskRequest.builder() + .name(TEST_TASK_NAME_1) + .helmChart(TEST_HELM_CHART) + .gpuSpecification(TEST_OCI_GPU_SPEC_WITH_HELM_POLICY_DTO) + .maxRuntimeDuration(Duration.ofHours(2)) + .maxQueuedDuration(Duration.ofHours(1)) + .terminationGracePeriodDuration(Duration.ofHours(1)) + .description(TEST_DESCRIPTION) + .resultsLocation(TEST_RESULTS_LOCATION_1) + .resultHandlingStrategy(ResultHandlingStrategyEnum.UPLOAD) + .secrets(TEST_SECRETS) + .build(); + var createEntity = RequestEntity + .post(URI.create("/v1/nvct/accounts/" + TEST_NCA_ID + "/tasks")) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", "Bearer " + token) + .body(requestBody); + var createResponse = + testRestTemplate.exchange(createEntity, TaskResponse.class); + assertThat(createResponse.getStatusCode()).isEqualTo(HttpStatus.OK); + var taskId = createResponse.getBody().task().id(); + + var getEntity = RequestEntity + .get(URI.create("/v1/nvct/accounts/" + TEST_NCA_ID + + "/tasks/" + taskId)) + .header("Authorization", "Bearer " + token) + .build(); + var getResponse = + testRestTemplate.exchange(getEntity, TaskResponse.class); + assertThat(getResponse.getStatusCode()).isEqualTo(HttpStatus.OK); + + var responseBody = getResponse.getBody(); + assertThat(responseBody).isNotNull(); + + var task = responseBody.task(); + assertThat(task).isNotNull(); + assertThat(task.id()).isEqualTo(taskId); + assertThat(task.gpuSpecification()).isNotNull(); + assertThat(task.gpuSpecification().helmValidationPolicy()) + .isEqualTo(TEST_HELM_VALIDATION_POLICY_DTO); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/XAccountTaskWithTelemetriesTest.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/XAccountTaskWithTelemetriesTest.java new file mode 100644 index 000000000..6ab9003fa --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/XAccountTaskWithTelemetriesTest.java @@ -0,0 +1,403 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.rest.task; + +import static com.nvidia.nvct.IntegrationTestConfiguration.MOCK_OAUTH2_TOKEN_SERVER; +import static com.nvidia.nvct.util.NvctConstants.ADMIN_SCOPE_LAUNCH_TASK; +import static com.nvidia.nvct.util.NvctConstants.ADMIN_SCOPE_LIST_TASKS; +import static com.nvidia.nvct.util.NvctConstants.ADMIN_SCOPE_TASK_DETAILS; +import static com.nvidia.nvct.util.TestConstants.TEST_ADMIN_SUBJECT; +import static com.nvidia.nvct.util.TestConstants.TEST_CONTAINER_ARGS; +import static com.nvidia.nvct.util.TestConstants.TEST_CONTAINER_ENVIRONMENT; +import static com.nvidia.nvct.util.TestConstants.TEST_CONTAINER_IMAGE; +import static com.nvidia.nvct.util.TestConstants.TEST_DESCRIPTION; +import static com.nvidia.nvct.util.TestConstants.TEST_NCA_ID; +import static com.nvidia.nvct.util.TestConstants.TEST_NCA_ID_WITH_TELEMETRIES_4; +import static com.nvidia.nvct.util.TestConstants.TEST_OCI_GPU_SPEC_DTO; +import static com.nvidia.nvct.util.TestConstants.TEST_RESULTS_LOCATION_1; +import static com.nvidia.nvct.util.TestConstants.TEST_SECRETS; +import static com.nvidia.nvct.util.TestConstants.TEST_ICMS_REQ_ID_1; +import static com.nvidia.nvct.util.TestConstants.TEST_TAGS; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_ID_1; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_NAME_1; +import static com.nvidia.nvct.util.TestConstants.TEST_TELEMETRY_LOGS_ID; +import static com.nvidia.nvct.util.TestConstants.TEST_TELEMETRY_METRICS_ID; +import static com.nvidia.nvct.util.TestConstants.TEST_TELEMETRY_TRACES_ID; +import static org.assertj.core.api.Assertions.assertThat; + +import tools.jackson.databind.json.JsonMapper; +import com.nvidia.boot.exceptions.NotFoundException; +import com.nvidia.boot.mock.ngc.MockCasServer; +import com.nvidia.boot.mock.ngc.MockNgcContainerRegistryServer; +import com.nvidia.nvct.IntegrationTestConfiguration; +import com.nvidia.nvct.NvctTestApp; +import com.nvidia.nvct.grpc.TestTaskService; +import com.nvidia.nvct.persistence.task.TasksRepository; +import com.nvidia.nvct.persistence.task.entity.TelemetriesUdt; +import com.nvidia.nvct.rest.task.dto.CreateTaskRequest; +import com.nvidia.nvct.rest.task.dto.ListTasksResponse; +import com.nvidia.nvct.rest.task.dto.ResultHandlingStrategyEnum; +import com.nvidia.nvct.rest.task.dto.TaskResponse; +import com.nvidia.nvct.rest.task.dto.TaskStatusEnum; +import com.nvidia.nvct.service.telemetry.dto.TelemetriesDto; +import com.nvidia.nvct.util.MockEssServer; +import com.nvidia.nvct.util.MockNotaryServer; +import com.nvidia.nvct.util.MockNvcfServer; +import com.nvidia.nvct.util.MockIcmsServer; +import java.net.URI; +import java.net.URL; +import java.time.Duration; +import java.util.List; +import java.util.UUID; +import java.util.stream.Stream; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.resttestclient.TestRestTemplate; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.RequestEntity; +import org.springframework.test.context.ContextConfiguration; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@Slf4j +@SpringBootTest(classes = {NvctTestApp.class, + IntegrationTestConfiguration.class}, + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + properties = "spring.profiles.active=test") +@ContextConfiguration(initializers = IntegrationTestConfiguration.Initializer.class) +@AutoConfigureTestRestTemplate +class XAccountTaskWithTelemetriesTest { + @Autowired + private TestRestTemplate testRestTemplate; + + @Autowired + private TasksRepository tasksRepository; + + @Autowired + private TestTaskService testTaskService; + + @Autowired + private JsonMapper jsonMapper; + + @Value("${nvct.registries.recognized.container.ngc.hostname}") + private String ngcContainerRegistryHostname; + + @Value("${nvct.registries.recognized.model.ngc.hostname}") + private String casBaseUrl; + + @Value("${nvct.registries.recognized.model.ngc.oauth2.base-url}") + private String authnBaseUrl; + + @Value("${nvct.notary.base-url}") + private String notaryBaseUrl; + + @Value("${spring.security.oauth2.client.registration.notary.client-id}") + private String notaryClientId; + + @Value("${nvct.nvcf.base-url}") + private URL nvcfBaseUrl; + + @Value("${nvct.icms.base-url}") + private URL icmsBaseUrl; + + @Value("${nvct.ess.base-url}") + private String essBaseUrl; + + @SneakyThrows + @BeforeAll + void beforeAll() { + log.info("{}: Started running tests", this.getClass().getSimpleName()); + MockNvcfServer.start(nvcfBaseUrl); + MockCasServer.start(authnBaseUrl, casBaseUrl); + MockEssServer.start(essBaseUrl); + MockIcmsServer.start(icmsBaseUrl, jsonMapper); + MockNotaryServer.start(notaryBaseUrl, notaryClientId); + MockNgcContainerRegistryServer.start(ngcContainerRegistryHostname); + } + + @AfterAll + void cleanup() { + MockNvcfServer.stop(); + MockCasServer.stop(); + MockIcmsServer.stop(); + MockEssServer.stop(); + MockNotaryServer.stop(); + MockNgcContainerRegistryServer.stop(); + log.info("{}: Completed running tests", this.getClass().getSimpleName()); + } + + @AfterEach + void reset() { + log.info("{} reset", this.getClass().getSimpleName()); + testTaskService.clearAll(); + MockEssServer.clearSecrets(); + } + + @BeforeEach + void setup() { + log.info("{} setup", this.getClass().getSimpleName()); + } + + Stream createTaskWithTelemetriesArgs() { + var validCompleteTelemetriesDto = TelemetriesDto.builder() + .logsTelemetryId(TEST_TELEMETRY_LOGS_ID) + .metricsTelemetryId(TEST_TELEMETRY_METRICS_ID) + .tracesTelemetryId(TEST_TELEMETRY_TRACES_ID) + .build(); + var validPartialTelemetriesDto = TelemetriesDto.builder() + .logsTelemetryId(TEST_TELEMETRY_LOGS_ID) + .build(); + var mismatchedTelemetriesDto = TelemetriesDto.builder() + .logsTelemetryId(TEST_TELEMETRY_TRACES_ID) + .metricsTelemetryId(TEST_TELEMETRY_LOGS_ID) + .tracesTelemetryId(TEST_TELEMETRY_METRICS_ID) + .build(); + var mismatchedPartialTelemetriesDto = TelemetriesDto.builder() + .logsTelemetryId(TEST_TELEMETRY_TRACES_ID) + .build(); + + return Stream.of( + // Valid telemetries from correct parent account. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK, + ADMIN_SCOPE_LIST_TASKS), + 100), + TEST_NCA_ID_WITH_TELEMETRIES_4, + validCompleteTelemetriesDto, + TEST_TELEMETRY_LOGS_ID, + TEST_TELEMETRY_METRICS_ID, + TEST_TELEMETRY_TRACES_ID, + HttpStatus.OK), + // Valid telemetries from correct parent account. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK, + ADMIN_SCOPE_LIST_TASKS), + 100), + TEST_NCA_ID_WITH_TELEMETRIES_4, + validPartialTelemetriesDto, + TEST_TELEMETRY_LOGS_ID, + null, + null, + HttpStatus.OK), + // Valid telemetries but not the correct account. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK, + ADMIN_SCOPE_LIST_TASKS), + 100), + TEST_NCA_ID, + validCompleteTelemetriesDto, + TEST_TELEMETRY_LOGS_ID, + TEST_TELEMETRY_METRICS_ID, + TEST_TELEMETRY_TRACES_ID, + HttpStatus.BAD_REQUEST), + // Mismatched telemetries from the correct parent account. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK, + ADMIN_SCOPE_LIST_TASKS), + 100), + TEST_NCA_ID_WITH_TELEMETRIES_4, + mismatchedTelemetriesDto, + null, + null, + null, + HttpStatus.BAD_REQUEST), + // Mismatched telemetries from the correct parent account. + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK, + ADMIN_SCOPE_LIST_TASKS), + 100), + TEST_NCA_ID_WITH_TELEMETRIES_4, + mismatchedPartialTelemetriesDto, + null, + null, + null, + HttpStatus.BAD_REQUEST) + ); + } + + @ParameterizedTest + @MethodSource("createTaskWithTelemetriesArgs") + void shouldCreateTaskWithTelemetries( + String token, + String ncaId, + TelemetriesDto telemetriesDto, + UUID logsTelemetryId, + UUID metricsTelemetryId, + UUID tracesTelemetryId, + HttpStatus expectedStatus) { + var maxRuntimeDuration = Duration.ofHours(2); + var maxQueuedDuration = Duration.ofHours(3); + var terminationGracePeriodDuration = Duration.ofHours(1); + var requestBody = CreateTaskRequest.builder() + .name(TEST_TASK_NAME_1) + .containerArgs(TEST_CONTAINER_ARGS) + .containerImage(TEST_CONTAINER_IMAGE) + .tags(TEST_TAGS) + .gpuSpecification(TEST_OCI_GPU_SPEC_DTO) + .maxRuntimeDuration(maxRuntimeDuration) + .maxQueuedDuration(maxQueuedDuration) + .terminationGracePeriodDuration(terminationGracePeriodDuration) + .description(TEST_DESCRIPTION) + .resultsLocation(TEST_RESULTS_LOCATION_1) + .resultHandlingStrategy(ResultHandlingStrategyEnum.UPLOAD) + .secrets(TEST_SECRETS) + .containerEnvironment(TEST_CONTAINER_ENVIRONMENT) + .telemetries(telemetriesDto) + .build(); + + var requestEntity = RequestEntity.post(URI.create("/v1/nvct/accounts/" + ncaId + "/tasks")) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", "Bearer " + token) + .body(requestBody); + var responseEntity = testRestTemplate.exchange(requestEntity, TaskResponse.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(expectedStatus); + if (expectedStatus.isError()) { + return; + } + + var responseBody = responseEntity.getBody(); + assertThat(responseBody).isNotNull(); + assertThat(responseBody.task().id()).isNotNull(); + assertThat(responseBody.task().name()).isEqualTo(TEST_TASK_NAME_1); + assertThat(responseBody.task().status()).isEqualTo(TaskStatusEnum.QUEUED); + assertThat(responseBody.task().ncaId()).isEqualTo(ncaId); + assertThat(responseBody.task().containerArgs()).isEqualTo(TEST_CONTAINER_ARGS); + assertThat(responseBody.task().helmChart()).isNull(); + assertThat(responseBody.task().containerImage()).isEqualTo(TEST_CONTAINER_IMAGE); + assertThat(responseBody.task().containerEnvironment()).isEqualTo(TEST_CONTAINER_ENVIRONMENT); + assertThat(responseBody.task().createdAt()).isNotNull(); + assertThat(responseBody.task().gpuSpecification()).isEqualTo(TEST_OCI_GPU_SPEC_DTO); + assertThat(responseBody.task().resultsLocation()).isEqualTo(TEST_RESULTS_LOCATION_1); + assertThat(responseBody.task().resultHandlingStrategy()) + .isEqualTo(ResultHandlingStrategyEnum.UPLOAD); + assertThat(responseBody.task().maxRuntimeDuration()).isNotNull(); + assertThat(responseBody.task().maxRuntimeDuration().toString()) + .hasToString(maxRuntimeDuration.toString()); + assertThat(responseBody.task().maxQueuedDuration().toString()) + .hasToString(maxQueuedDuration.toString()); + assertThat(responseBody.task().terminationGracePeriodDuration()).isNotNull(); + assertThat(responseBody.task().terminationGracePeriodDuration().toString()) + .hasToString(terminationGracePeriodDuration.toString()); + assertThat(responseBody.task().tags()).isEqualTo(TEST_TAGS); + assertThat(responseBody.task().description()).isEqualTo(TEST_DESCRIPTION); + + var actualTelemetriesDto = responseBody.task().telemetries(); + assertThat(actualTelemetriesDto).isNotNull(); + assertThat(actualTelemetriesDto.logsTelemetryId()).isEqualTo(logsTelemetryId); + assertThat(actualTelemetriesDto.metricsTelemetryId()).isEqualTo(metricsTelemetryId); + assertThat(actualTelemetriesDto.tracesTelemetryId()).isEqualTo(tracesTelemetryId); + + var taskId = responseBody.task().id(); + var entity = tasksRepository + .getByTaskId(taskId) + .orElseThrow(() -> new NotFoundException("Task not found")); + assertThat(entity).isNotNull(); + assertThat(entity.getHealth()).isBlank(); + } + + @Test + void shouldListTasksWithTelemetries() { + // Create Task in TEST_NCA_ID_WITH_TELEMETRIES_4 account with telemetries. + var telemetriesUdt = TelemetriesUdt.builder() + .logsTelemetryId(TEST_TELEMETRY_LOGS_ID) + .metricsTelemetryId(TEST_TELEMETRY_METRICS_ID) + .tracesTelemetryId(TEST_TELEMETRY_TRACES_ID) + .build(); + testTaskService.createTaskWithTelemetries(TEST_NCA_ID_WITH_TELEMETRIES_4, + TEST_TASK_ID_1, + TEST_ICMS_REQ_ID_1, + telemetriesUdt); + + // Create token for the admin. + var token = MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LIST_TASKS), + 100); + var uri = URI.create("/v1/nvct/accounts/" + TEST_NCA_ID_WITH_TELEMETRIES_4 + "/tasks"); + var requestEntity = RequestEntity.get(uri) + .header("Authorization", "Bearer " + token) + .build(); + var responseEntity = + testRestTemplate.exchange(requestEntity, ListTasksResponse.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK); + + var responseBody = responseEntity.getBody(); + assertThat(responseBody).isNotNull(); + + var tasks = responseBody.tasks(); + assertThat(tasks).isNotEmpty(); + + tasks.forEach(task -> { + assertThat(task.telemetries()).isNotNull(); + assertThat(task.telemetries().logsTelemetryId()).isEqualTo(TEST_TELEMETRY_LOGS_ID); + assertThat(task.telemetries().metricsTelemetryId()).isEqualTo(TEST_TELEMETRY_METRICS_ID); + assertThat(task.telemetries().tracesTelemetryId()).isEqualTo(TEST_TELEMETRY_TRACES_ID); + }); + } + + @Test + void shouldGetTaskDetailsWithTelemetries() { + // Create Task in TEST_NCA_ID_WITH_TELEMETRIES_4 account with telemetries. + var telemetriesUdt = TelemetriesUdt.builder() + .logsTelemetryId(TEST_TELEMETRY_LOGS_ID) + .metricsTelemetryId(TEST_TELEMETRY_METRICS_ID) + .tracesTelemetryId(TEST_TELEMETRY_TRACES_ID) + .build(); + testTaskService.createTaskWithTelemetries(TEST_NCA_ID_WITH_TELEMETRIES_4, + TEST_TASK_ID_1, + TEST_ICMS_REQ_ID_1, + telemetriesUdt); + + // Create token for the admin. + var token = MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_TASK_DETAILS), + 100); + var uri = URI.create("/v1/nvct/accounts/" + TEST_NCA_ID_WITH_TELEMETRIES_4 + + "/tasks/" + TEST_TASK_ID_1); + var requestEntity = RequestEntity.get(uri) + .header("Authorization", "Bearer " + token) + .build(); + var responseEntity = + testRestTemplate.exchange(requestEntity, TaskResponse.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK); + + var responseBody = responseEntity.getBody(); + assertThat(responseBody).isNotNull(); + + var task = responseBody.task(); + assertThat(task).isNotNull(); + assertThat(task.id()).isEqualTo(TEST_TASK_ID_1); + + assertThat(task.telemetries()).isNotNull(); + assertThat(task.telemetries().logsTelemetryId()).isEqualTo(TEST_TELEMETRY_LOGS_ID); + assertThat(task.telemetries().metricsTelemetryId()).isEqualTo(TEST_TELEMETRY_METRICS_ID); + assertThat(task.telemetries().tracesTelemetryId()).isEqualTo(TEST_TELEMETRY_TRACES_ID); + } + +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/XAccountTaskWithUserSecretsTest.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/XAccountTaskWithUserSecretsTest.java new file mode 100644 index 000000000..2e1d335c0 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/XAccountTaskWithUserSecretsTest.java @@ -0,0 +1,571 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.rest.task; + +import static com.nvidia.nvct.IntegrationTestConfiguration.MOCK_OAUTH2_TOKEN_SERVER; +import static com.nvidia.nvct.util.NvctConstants.ADMIN_SCOPE_DELETE_TASK; +import static com.nvidia.nvct.util.NvctConstants.ADMIN_SCOPE_LAUNCH_TASK; +import static com.nvidia.nvct.util.NvctConstants.ADMIN_SCOPE_LIST_TASKS; +import static com.nvidia.nvct.util.NvctConstants.ADMIN_SCOPE_TASK_DETAILS; +import static com.nvidia.nvct.util.NvctConstants.MAX_SECRET_NAME_LENGTH; +import static com.nvidia.nvct.util.NvctConstants.MAX_SECRET_VALUE_LENGTH; +import static com.nvidia.nvct.util.NvctConstants.NGC_API_KEY; +import static com.nvidia.nvct.util.TestConstants.TEST_ADMIN_SUBJECT; +import static com.nvidia.nvct.util.TestConstants.TEST_CONTAINER_ARGS; +import static com.nvidia.nvct.util.TestConstants.TEST_CONTAINER_IMAGE; +import static com.nvidia.nvct.util.TestConstants.TEST_DESCRIPTION; +import static com.nvidia.nvct.util.TestConstants.TEST_NCA_ID; +import static com.nvidia.nvct.util.TestConstants.TEST_OCI_GPU_SPEC_DTO; +import static com.nvidia.nvct.util.TestConstants.TEST_RESULTS_LOCATION_1; +import static com.nvidia.nvct.util.TestConstants.TEST_RESULTS_LOCATION_2; +import static com.nvidia.nvct.util.TestConstants.TEST_TAGS; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_NAME_1; +import static org.assertj.core.api.Assertions.assertThat; + +import tools.jackson.databind.json.JsonMapper; +import tools.jackson.databind.node.StringNode; +import com.nvidia.boot.mock.ngc.MockCasServer; +import com.nvidia.boot.mock.ngc.MockNgcContainerRegistryServer; +import com.nvidia.nvct.IntegrationTestConfiguration; +import com.nvidia.nvct.NvctTestApp; +import com.nvidia.nvct.grpc.TestTaskService; +import com.nvidia.nvct.persistence.task.TasksRepository; +import com.nvidia.nvct.rest.task.dto.CreateTaskRequest; +import com.nvidia.nvct.rest.task.dto.ListTasksResponse; +import com.nvidia.nvct.rest.task.dto.ResultHandlingStrategyEnum; +import com.nvidia.nvct.rest.task.dto.SecretDto; +import com.nvidia.nvct.rest.task.dto.TaskResponse; +import com.nvidia.nvct.service.ess.EssService; +import com.nvidia.nvct.util.MockEssServer; +import com.nvidia.nvct.util.MockNotaryServer; +import com.nvidia.nvct.util.MockNvcfServer; +import com.nvidia.nvct.util.MockIcmsServer; +import java.net.URI; +import java.net.URL; +import java.util.List; +import java.util.Set; +import java.util.stream.Stream; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.resttestclient.TestRestTemplate; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.RequestEntity; +import org.springframework.test.context.ContextConfiguration; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@Slf4j +@SpringBootTest( + classes = {NvctTestApp.class, IntegrationTestConfiguration.class}, + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + properties = "spring.profiles.active=test") +@ContextConfiguration(initializers = IntegrationTestConfiguration.Initializer.class) +@AutoConfigureTestRestTemplate +class XAccountTaskWithUserSecretsTest { + + @Autowired + private TestRestTemplate testRestTemplate; + + @Autowired + private EssService essService; + + @Autowired + private TestTaskService testTaskService; + + @Autowired + private JsonMapper jsonMapper; + + @Autowired + private TasksRepository tasksRepository; + + @Value("${nvct.registries.recognized.container.ngc.hostname}") + private String ngcContainerRegistryHostname; + + @Value("${nvct.ess.base-url}") + private String essBaseUrl; + + @Value("${nvct.registries.recognized.model.ngc.hostname}") + private String casBaseUrl; + + @Value("${nvct.registries.recognized.model.ngc.oauth2.base-url}") + private String authnBaseUrl; + + @Value("${nvct.notary.base-url}") + private String notaryBaseUrl; + + @Value("${spring.security.oauth2.client.registration.notary.client-id}") + private String notaryClientId; + + @Value("${nvct.nvcf.base-url}") + private URL nvcfBaseUrl; + + @Value("${nvct.icms.base-url}") + private URL icmsBaseUrl; + + @BeforeAll + void beforeAll() { + log.info("{}: Started running tests", this.getClass().getSimpleName()); + MockEssServer.start(essBaseUrl); + MockNvcfServer.start(nvcfBaseUrl); + MockIcmsServer.start(icmsBaseUrl, jsonMapper); + MockCasServer.start(authnBaseUrl, casBaseUrl); + MockNotaryServer.start(notaryBaseUrl, notaryClientId); + MockNgcContainerRegistryServer.start(ngcContainerRegistryHostname); + } + + @AfterAll + void cleanup() { + MockEssServer.stop(); + MockNvcfServer.stop(); + MockIcmsServer.stop(); + MockCasServer.stop(); + MockNotaryServer.stop(); + MockNgcContainerRegistryServer.stop(); + log.info("{}: Completed running tests", this.getClass().getSimpleName()); + } + + @AfterEach + void reset() { + testTaskService.clearAll(); + MockEssServer.clearSecrets(); + } + + Stream createTaskWithSecretsArgs() { + var secretJsonNodeValue = jsonMapper.createObjectNode() + .put("AWS_REGION", "us-west-2") + .put("AWS_BUCKET", "ov-content") + .put("AWS_ACCESS_KEY_ID", "ov-content-key-id") + .put("AWS_SECRET_ACCESS_KEY", "ov-content-access-key") + .put("AWS_SESSION_TOKEN", "ov-content-session-token"); + return Stream.of( + // no secrets with default resultHandlingStrategy + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK), + 100), + null, + null, + null, + HttpStatus.BAD_REQUEST), + // no secrets with resultHandlingStrategy UPLOAD(default) + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK), + 100), + null, + null, + ResultHandlingStrategyEnum.UPLOAD, + HttpStatus.BAD_REQUEST), + // Only NGC_API_KEY secret + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK), + 100), + Set.of(SecretDto.builder().name(NGC_API_KEY).value(new StringNode("value1")).build()), + Set.of(NGC_API_KEY), + ResultHandlingStrategyEnum.UPLOAD, + HttpStatus.OK), + // single secret + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK), + 100), + Set.of(SecretDto.builder().name(NGC_API_KEY).value(new StringNode("value1")).build()), + Set.of(NGC_API_KEY), + ResultHandlingStrategyEnum.UPLOAD, + HttpStatus.OK), + // multiple secrets + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK), + 100), + Set.of(SecretDto.builder().name(NGC_API_KEY).value(new StringNode("value1")).build(), + SecretDto.builder().name("secret2").value(new StringNode("value2")).build(), + SecretDto.builder().name("secret3").value(secretJsonNodeValue).build()), + Set.of(NGC_API_KEY, "secret2", "secret3"), + ResultHandlingStrategyEnum.UPLOAD, + HttpStatus.OK), + // Secret name -- exactly MAX_SECRET_NAME_LENGTH in length + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK), + 100), + Set.of(SecretDto.builder() + .name(StringUtils.repeat("x", MAX_SECRET_NAME_LENGTH)) + .value(new StringNode("value1")).build()), + Set.of(StringUtils.repeat("x", MAX_SECRET_NAME_LENGTH)), + ResultHandlingStrategyEnum.NONE, + HttpStatus.OK), + // secret names with periods, and hyphens + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK), + 100), + Set.of(SecretDto.builder() + .name("omni.s3.us-west-2.amazonaws.com") + .value(new StringNode("value1")).build(), + SecretDto.builder() + .name("omni.s3.eu-north-1.amazonaws.com") + .value(new StringNode("value2")).build(), + SecretDto.builder() + .name("omni.s3.ap-northeast-1.amazonaws.com") + .value(secretJsonNodeValue).build()), + Set.of("omni.s3.us-west-2.amazonaws.com", + "omni.s3.eu-north-1.amazonaws.com", + "omni.s3.ap-northeast-1.amazonaws.com"), + ResultHandlingStrategyEnum.NONE, + HttpStatus.OK), + // secret names with underscores + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK), + 100), + Set.of(SecretDto.builder() + .name("omni_s3_us-west-2_amazonaws_com") + .value(new StringNode("value1")).build(), + SecretDto.builder() + .name("omni_s3_eu-north-1_amazonaws_com") + .value(new StringNode("value2")).build(), + SecretDto.builder() + .name("omni.s3.ap-northeast-1.amazonaws.com") + .value(secretJsonNodeValue).build()), + Set.of("omni_s3_us-west-2_amazonaws_com", + "omni_s3_eu-north-1_amazonaws_com", + "omni.s3.ap-northeast-1.amazonaws.com"), + ResultHandlingStrategyEnum.NONE, + HttpStatus.OK), + // resultHandlingStrategy NONE and missing NGC_API_KEY + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK), + 100), + Set.of(SecretDto.builder() + .name("secret2") + .value(new StringNode("value2")).build()), + Set.of("secret2"), + ResultHandlingStrategyEnum.NONE, + HttpStatus.OK), + // resultHandlingStrategy UPLOAD and missing NGC_API_KEY + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK), + 100), + Set.of(SecretDto.builder() + .name("secret2") + .value(new StringNode("value2")).build()), + Set.of("secret2"), + ResultHandlingStrategyEnum.UPLOAD, + HttpStatus.BAD_REQUEST), + // duplicate secrets + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK), + 100), + Set.of(SecretDto.builder() + .name(NGC_API_KEY) + .value(new StringNode("value1")).build(), + SecretDto.builder() + .name(NGC_API_KEY) + .value(new StringNode("value2")).build()), + null, + ResultHandlingStrategyEnum.NONE, + HttpStatus.BAD_REQUEST), + // empty secret name + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK), + 100), + Set.of(SecretDto.builder() + .name("") + .value(new StringNode("value1")).build()), + null, + ResultHandlingStrategyEnum.NONE, + HttpStatus.BAD_REQUEST), + // long secret name - exceeds MAX_SECRET_NAME_LENGTH length + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK), + 100), + Set.of(SecretDto.builder() + .name(StringUtils.repeat("secret1", MAX_SECRET_NAME_LENGTH)) + .value(new StringNode("value1")).build()), + null, + ResultHandlingStrategyEnum.NONE, + HttpStatus.BAD_REQUEST), + // empty secret value + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK), + 100), + Set.of(SecretDto.builder() + .name("secret1") + .value(new StringNode("")).build()), + null, + ResultHandlingStrategyEnum.NONE, + HttpStatus.BAD_REQUEST), + // long secret value + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK), + 100), + Set.of(SecretDto.builder().name("secret1") + .value(new StringNode(StringUtils.repeat("value1", + MAX_SECRET_VALUE_LENGTH))) + .build()), + null, + ResultHandlingStrategyEnum.NONE, + HttpStatus.BAD_REQUEST), + // bad secret name + Arguments.of(MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK), + 100), + Set.of(SecretDto.builder().name("*secret1*-\"").value(new StringNode("value1")).build()), + null, + ResultHandlingStrategyEnum.NONE, + HttpStatus.BAD_REQUEST) + ); + } + + @ParameterizedTest + @MethodSource("createTaskWithSecretsArgs") + void shouldCreateTaskWithSecrets( + String token, + Set secrets, + Set expectedSecretNames, + ResultHandlingStrategyEnum resultHandlingStrategy, + HttpStatus expectedStatus) { + // Create the task in TEST_NCA_ID + var requestBody = CreateTaskRequest.builder() + .name(TEST_TASK_NAME_1) + .containerArgs(TEST_CONTAINER_ARGS) + .containerImage(TEST_CONTAINER_IMAGE) + .tags(TEST_TAGS) + .gpuSpecification(TEST_OCI_GPU_SPEC_DTO) + .description(TEST_DESCRIPTION) + .resultsLocation(TEST_RESULTS_LOCATION_2) + .resultHandlingStrategy(resultHandlingStrategy) + .secrets(secrets) + .build(); + var requestEntity = RequestEntity.post(URI.create("/v1/nvct/accounts/" + TEST_NCA_ID + "/tasks")) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", "Bearer " + token) + .body(requestBody); + var responseEntity = testRestTemplate.exchange(requestEntity, TaskResponse.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(expectedStatus); + if (expectedStatus.isError()) { + return; + } + + var responseBody = responseEntity.getBody(); + assertThat(responseBody).isNotNull(); + var taskId = responseBody.task().id(); + var taskDto = responseBody.task(); + if (expectedSecretNames == null) { + assertThat(taskDto.secrets()).isNull(); + } else { + assertThat(taskDto.secrets()) + .containsExactlyInAnyOrderElementsOf(expectedSecretNames); + + // Confirm secrets are saved in ESS + var returnedNames = essService.getSecretNames(taskId).orElse(null); + assertThat(returnedNames).isNotNull(); + assertThat(returnedNames).containsExactlyInAnyOrderElementsOf(expectedSecretNames); + + // Confirm hasSecrets is set + var taskEntity = tasksRepository.getByTaskId(taskId).orElse(null); + assertThat(taskEntity).isNotNull(); + assertThat(taskEntity.hasSecrets()).isTrue(); + } + + } + + @Test + void shouldListTasksWithSecretsByAccount() { + var token = MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK, + ADMIN_SCOPE_LIST_TASKS), + 100); + // Create a task with secrets in TEST_NCA_ID + var secretJsonNodeValue = jsonMapper.createObjectNode() + .put("AWS_REGION", "us-west-2") + .put("AWS_BUCKET", "ov-content") + .put("AWS_ACCESS_KEY_ID", "ov-content-key-id") + .put("AWS_SECRET_ACCESS_KEY", "ov-content-access-key") + .put("AWS_SESSION_TOKEN", "ov-content-session-token"); + var secrets = Set.of(SecretDto.builder().name("AWS_SECRET_ACCESS_KEY") + .value(new StringNode("value1")).build(), + SecretDto.builder().name("NGC_API_KEY") + .value(new StringNode("value2")).build(), + SecretDto.builder().name("OV.US-WEST-2.CONTENT") + .value(secretJsonNodeValue).build()); + var requestBody = CreateTaskRequest.builder() + .name(TEST_TASK_NAME_1) + .containerArgs(TEST_CONTAINER_ARGS) + .containerImage(TEST_CONTAINER_IMAGE) + .gpuSpecification(TEST_OCI_GPU_SPEC_DTO) + .resultsLocation(TEST_RESULTS_LOCATION_1) + .secrets(secrets) + .build(); + var requestEntity = RequestEntity.post(URI.create("/v1/nvct/accounts/" + TEST_NCA_ID + "/tasks")) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", "Bearer " + token) + .body(requestBody); + var responseEntity = testRestTemplate.exchange(requestEntity, TaskResponse.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK); + + // After task creation, list task + var endpoint = "/v1/nvct/accounts/" + TEST_NCA_ID + "/tasks"; + var listRequestEntity = RequestEntity.get(URI.create(endpoint)) + .header("Authorization", "Bearer " + token) + .build(); + var listResponseEntity = testRestTemplate.exchange(listRequestEntity, ListTasksResponse.class); + var responseBody = listResponseEntity.getBody(); + assertThat(responseBody).isNotNull(); + assertThat(responseBody.tasks()).hasSize(1); + + var taskDto = responseBody.tasks().getFirst(); + assertThat(taskDto).isNotNull(); + assertThat(taskDto.secrets()).isNull(); + } + + Stream listTasksWithSecretsArgs() { + return Stream.of( + Arguments.of(Boolean.TRUE), + Arguments.of(Boolean.FALSE), + Arguments.of(Boolean.TRUE), + Arguments.of(Boolean.FALSE)); + } + + @ParameterizedTest + @MethodSource("listTasksWithSecretsArgs") + void shouldGetTaskDetailsWithSecretsByAccount(Boolean includeSecrets) { + var token = MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK, + ADMIN_SCOPE_TASK_DETAILS), + 100); + // Create a task with secrets in TEST_NCA_ID + var secretJsonNodeValue = jsonMapper.createObjectNode() + .put("AWS_REGION", "us-west-2") + .put("AWS_BUCKET", "ov-content") + .put("AWS_ACCESS_KEY_ID", "ov-content-key-id") + .put("AWS_SECRET_ACCESS_KEY", "ov-content-access-key") + .put("AWS_SESSION_TOKEN", "ov-content-session-token"); + var secrets = Set.of(SecretDto.builder().name("AWS_SECRET_ACCESS_KEY") + .value(new StringNode("value1")).build(), + SecretDto.builder().name("NGC_API_KEY") + .value(new StringNode("value2")).build(), + SecretDto.builder().name("OV.US-WEST-2.CONTENT") + .value(secretJsonNodeValue).build()); + var expectedSecretNames = Set.of("AWS_SECRET_ACCESS_KEY", + "NGC_API_KEY", "OV.US-WEST-2.CONTENT"); + var requestBody = CreateTaskRequest.builder() + .name(TEST_TASK_NAME_1) + .containerArgs(TEST_CONTAINER_ARGS) + .containerImage(TEST_CONTAINER_IMAGE) + .gpuSpecification(TEST_OCI_GPU_SPEC_DTO) + .resultsLocation(TEST_RESULTS_LOCATION_1) + .secrets(secrets) + .build(); + var requestEntity = RequestEntity.post(URI.create("/v1/nvct/accounts/" + TEST_NCA_ID + "/tasks")) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", "Bearer " + token) + .body(requestBody); + var responseEntity = testRestTemplate.exchange(requestEntity, TaskResponse.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK); + var taskId = responseEntity.getBody().task().id(); + + // After task creation, get task details + var endpoint = "/v1/nvct/accounts/" + TEST_NCA_ID + "/tasks/" + taskId; + if (includeSecrets != null) { + endpoint += "?includeSecrets=" + includeSecrets; + } + var listRequestEntity = RequestEntity.get(URI.create(endpoint)) + .header("Authorization", "Bearer " + token) + .build(); + var listResponseEntity = testRestTemplate.exchange(listRequestEntity, TaskResponse.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK); + var responseBody = listResponseEntity.getBody(); + assertThat(responseBody).isNotNull(); + + var taskDto = responseBody.task(); + assertThat(taskDto).isNotNull(); + if ((includeSecrets == null) || includeSecrets) { + assertThat(taskDto.secrets()).isNotNull(); + assertThat(taskDto.secrets()).containsExactlyInAnyOrderElementsOf(expectedSecretNames); + } else { + assertThat(taskDto.secrets()).isNull(); + } + } + + @Test + void shouldDeleteTaskWithSecrets() { + var token = MOCK_OAUTH2_TOKEN_SERVER.getJwt(TEST_ADMIN_SUBJECT, + List.of(ADMIN_SCOPE_LAUNCH_TASK, + ADMIN_SCOPE_DELETE_TASK), + 100); + + // Create a task with secrets in TEST_NCA_ID + var secretJsonNodeValue = jsonMapper.createObjectNode() + .put("AWS_REGION", "us-west-2") + .put("AWS_BUCKET", "ov-content") + .put("AWS_ACCESS_KEY_ID", "ov-content-key-id") + .put("AWS_SECRET_ACCESS_KEY", "ov-content-access-key") + .put("AWS_SESSION_TOKEN", "ov-content-session-token"); + var secrets = Set.of(SecretDto.builder().name("AWS_SECRET_ACCESS_KEY") + .value(new StringNode("value1")).build(), + SecretDto.builder().name("NGC_API_KEY") + .value(new StringNode("value2")).build(), + SecretDto.builder().name("OV.US-WEST-2.CONTENT") + .value(secretJsonNodeValue).build()); + var requestBody = CreateTaskRequest.builder() + .name(TEST_TASK_NAME_1) + .containerArgs(TEST_CONTAINER_ARGS) + .containerImage(TEST_CONTAINER_IMAGE) + .gpuSpecification(TEST_OCI_GPU_SPEC_DTO) + .resultsLocation(TEST_RESULTS_LOCATION_1) + .secrets(secrets) + .build(); + var requestEntity = + RequestEntity.post(URI.create("/v1/nvct/accounts/" + TEST_NCA_ID + "/tasks")) + .contentType(MediaType.APPLICATION_JSON) + .header("Authorization", "Bearer " + token) + .body(requestBody); + var responseEntity = testRestTemplate.exchange(requestEntity, TaskResponse.class); + assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK); + var taskId = responseEntity.getBody().task().id(); + + // Make sure there are secrets first before deleting a task + var secretDtos = essService.getSecrets(taskId).orElse(null); + assertThat(secretDtos).isNotNull().hasSize(3); + + // Confirm hasSecrets is set + var taskEntity = tasksRepository.getByTaskId(taskId).orElse(null); + assertThat(taskEntity).isNotNull(); + assertThat(taskEntity.hasSecrets()).isTrue(); + + var deleteRequestEntity = + RequestEntity.delete(URI.create("/v1/nvct/accounts/" + TEST_NCA_ID + "/tasks/" + taskId)) + .header("Authorization", "Bearer " + token) + .build(); + var deleteResponseEntity = testRestTemplate.exchange(deleteRequestEntity, Void.class); + assertThat(deleteResponseEntity.getStatusCode()).isEqualTo(HttpStatus.NO_CONTENT); + var entity = tasksRepository + .getByTaskId(taskId); + assertThat(entity).isEmpty(); + + // Make sure secrets no longer exist after task deletion + secretDtos = essService.getSecrets(taskId).orElse(null); + assertThat(secretDtos).isNull(); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/service/account/AccountServiceTest.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/service/account/AccountServiceTest.java new file mode 100644 index 000000000..62c8956c8 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/service/account/AccountServiceTest.java @@ -0,0 +1,197 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.account; + +import static com.github.tomakehurst.wiremock.client.WireMock.getRequestedFor; +import static com.github.tomakehurst.wiremock.client.WireMock.urlMatching; +import static com.nvidia.nvct.util.TestConstants.TEST_NCA_ID; +import static com.nvidia.nvct.util.TestConstants.TEST_NCA_ID_WITHOUT_REGISTRY_CREDENTIALS_6; +import static com.nvidia.nvct.util.TestConstants.TEST_NCA_ID_WITH_TELEMETRIES_4; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; + +import com.nvidia.boot.exceptions.NotFoundException; +import com.nvidia.nvct.IntegrationTestConfiguration; +import com.nvidia.nvct.NvctTestApp; +import com.nvidia.nvct.grpc.TestTaskService; +import com.nvidia.nvct.util.MockNvcfServer; +import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.core.instrument.Timer; +import java.net.URL; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ContextConfiguration; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@Slf4j +@SpringBootTest( + classes = {NvctTestApp.class, IntegrationTestConfiguration.class}, + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + properties = "spring.profiles.active=test") +@ContextConfiguration(initializers = IntegrationTestConfiguration.Initializer.class) +class AccountServiceTest { + + private static final String HTTP_CLIENT_REQUESTS_METRIC = "http.client.requests"; + private static final String NVCF_ACCOUNT_URI_PREFIX = "/v2/nvcf/accounts"; + + @Autowired + private AccountService accountService; + + @Autowired + private TestTaskService testTaskService; + + @Autowired + private MeterRegistry meterRegistry; + + @Value("${nvct.nvcf.base-url}") + private URL nvcfBaseUrl; + + @BeforeAll + void beforeAll() { + log.info("{}: Started running tests", this.getClass().getSimpleName()); + MockNvcfServer.start(nvcfBaseUrl); + } + + @AfterAll + void cleanup() { + log.info("{}: Completed running tests", this.getClass().getSimpleName()); + MockNvcfServer.stop(); + } + + @AfterEach + void afterEach() { + accountService.invalidateCache(); + testTaskService.clearAll(); + } + + @Test + void shouldGetAccount() { + var accountDto = accountService.getAccount(TEST_NCA_ID); + assertThat(accountDto).isNotNull(); + assertThat(accountDto.ncaId()).isEqualTo(TEST_NCA_ID); + assertThat(accountDto.clientIds()).hasSize(1); + assertThat(accountDto.name()).isNotBlank(); + assertThat(accountDto.telemetries()).isNull(); + assertThat(accountDto.registryCredentials()).hasSize(13); + } + + @Test + void shouldGetAccountWithTelemetries() { + var accountDto = accountService.getAccount(TEST_NCA_ID_WITH_TELEMETRIES_4); + assertThat(accountDto).isNotNull(); + assertThat(accountDto.ncaId()).isEqualTo(TEST_NCA_ID_WITH_TELEMETRIES_4); + assertThat(accountDto.clientIds()).hasSize(1); + assertThat(accountDto.name()).isNotBlank(); + assertThat(accountDto.telemetries()).isNotEmpty(); + var telemetryDtos = accountDto.telemetries(); + telemetryDtos.forEach(telemetryDto -> { + assertThat(telemetryDto.telemetryId()).isNotNull(); + assertThat(telemetryDto.name()).isNotBlank(); + assertThat(telemetryDto.protocol()).isNotNull(); + assertThat(telemetryDto.provider()).isNotNull(); + assertThat(telemetryDto.endpoint()).isNotBlank(); + assertThat(telemetryDto.types()).isNotEmpty(); + assertThat(telemetryDto.createdAt()).isNotNull(); + }); + } + + @Test + void shouldGetAccountWithoutRegistryCredentials() { + var accountDto = accountService.getAccount(TEST_NCA_ID_WITHOUT_REGISTRY_CREDENTIALS_6); + assertThat(accountDto).isNotNull(); + assertThat(accountDto.ncaId()).isEqualTo(TEST_NCA_ID_WITHOUT_REGISTRY_CREDENTIALS_6); + assertThat(accountDto.clientIds()).hasSize(1); + assertThat(accountDto.name()).isNotBlank(); + assertThat(accountDto.registryCredentials()).isNull(); + } + + @Test + void shouldFailToGetAccount() { + assertThatExceptionOfType(NotFoundException.class).isThrownBy( + () -> accountService.getAccount("non-existent-account")); + } + + @Test + void shouldFailToLookupAccount() { + assertThatExceptionOfType(NotFoundException.class).isThrownBy( + () -> accountService.lookupAccountUsingNcaIdOrThrow("non-existent-account")); + } + + @Test + void shouldReturnCachedAccountOnSecondCallWithinTtl() { + MockNvcfServer.getMockNvcfServer().resetRequests(); + + accountService.getAccount(TEST_NCA_ID); + accountService.getAccount(TEST_NCA_ID); + + MockNvcfServer.getMockNvcfServer().verify(1, + getRequestedFor(urlMatching("/v2/nvcf/accounts/" + TEST_NCA_ID))); + } + + @Test + void shouldRefetchAccountAfterTtlExpires() throws InterruptedException { + MockNvcfServer.getMockNvcfServer().resetRequests(); + + accountService.getAccount(TEST_NCA_ID); + Thread.sleep(3000); + accountService.getAccount(TEST_NCA_ID); + + MockNvcfServer.getMockNvcfServer().verify(2, + getRequestedFor(urlMatching("/v2/nvcf/accounts/" + TEST_NCA_ID))); + } + + @Test + void shouldRecordMetricsForNvcfResourceServerCall() { + accountService.invalidateCache(); + MockNvcfServer.getMockNvcfServer().resetRequests(); + + var resourceServerRequestCountBefore = nvcfAccountRequestCount(); + + accountService.getAccount(TEST_NCA_ID); + + assertThat(nvcfAccountRequestCount()).isGreaterThan(resourceServerRequestCountBefore); + MockNvcfServer.getMockNvcfServer().verify(1, + getRequestedFor(urlMatching("/v2/nvcf/accounts/" + TEST_NCA_ID))); + } + + private long nvcfAccountRequestCount() { + return meterRegistry.find(HTTP_CLIENT_REQUESTS_METRIC) + .timers() + .stream() + .filter(this::isNvcfAccountRequestTimer) + .mapToLong(Timer::count) + .sum(); + } + + private boolean isNvcfAccountRequestTimer(Timer timer) { + return isNvcfAccountTagValue(timer, "http.route") + || isNvcfAccountTagValue(timer, "uri"); + } + + private boolean isNvcfAccountTagValue(Timer timer, String tagKey) { + var tagValue = timer.getId().getTag(tagKey); + return tagValue != null && tagValue.contains(NVCF_ACCOUNT_URI_PREFIX); + } + +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/service/apikeys/ApiKeyValidationResultTest.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/service/apikeys/ApiKeyValidationResultTest.java new file mode 100644 index 000000000..192e4ed3c --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/service/apikeys/ApiKeyValidationResultTest.java @@ -0,0 +1,70 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.apikeys; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import com.nvidia.nvct.service.apikeys.ApiKeyValidationResult.Resource; +import java.util.List; +import java.util.UUID; +import java.util.stream.Stream; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +class ApiKeyValidationResultTest { + + static Stream resourceMatchesTaskArgs() { + var TID1 = UUID.fromString("3c000ce0-87a7-4a15-bf32-c77f088f2975"); + var TID2 = UUID.fromString("b58d839c-3cd6-4ea9-ae73-87de33dc0787"); + return Stream.of( + Arguments.of(TID1.toString(), TID1, true), + Arguments.of(TID1.toString(), TID2, false), + Arguments.of(TID2.toString(), TID2, true), + Arguments.of(TID2.toString(), TID1, false), + Arguments.of("*", TID1, false), // invalid pattern + Arguments.of(null, TID1, false), // invalid pattern + Arguments.of("invalid-uuid", TID1, false) // invalid pattern + ); + } + + @ParameterizedTest + @MethodSource("resourceMatchesTaskArgs") + void allAllowedTasks(String resourceId, UUID taskId, boolean expected) { + var access = ApiKeyValidationResult.allAllowedTasks( + List.of(new Resource("task", resourceId))); + var actual = access.hasResourcesScopedForTask(taskId); + assertEquals(expected, actual); + } + + @Test + void allAllowedTasksAccount() { + var access = ApiKeyValidationResult.allAllowedTasks( + List.of(new Resource("account-tasks", "*"))); + assertTrue(access.privateTasksAllowed()); + } + + @Test + void allAllowedTasksAccountWrongID() { + var access = ApiKeyValidationResult.allAllowedTasks( + List.of(new Resource("account-tasks", UUID.randomUUID().toString()))); + assertFalse(access.privateTasksAllowed()); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/service/apikeys/ApiKeysClientTest.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/service/apikeys/ApiKeysClientTest.java new file mode 100644 index 000000000..bd438189c --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/service/apikeys/ApiKeysClientTest.java @@ -0,0 +1,89 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.apikeys; + +import static com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor; +import static com.github.tomakehurst.wiremock.client.WireMock.urlPathEqualTo; +import static com.nvidia.nvct.util.MockApiKeysServer.EVALUATION_URI_PATH; + +import tools.jackson.databind.json.JsonMapper; +import com.nvidia.nvct.IntegrationTestConfiguration; +import com.nvidia.nvct.NvctTestApp; +import com.nvidia.nvct.configuration.staticclientauth.StaticClientAuthConfiguration.StaticClientApiKeysProperties; +import com.nvidia.nvct.util.MockApiKeysServer; +import java.util.Optional; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.web.reactive.function.client.WebClient; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@Slf4j +@SpringBootTest( + classes = {NvctTestApp.class, IntegrationTestConfiguration.class}, + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + properties = "spring.profiles.active=test") +@ContextConfiguration(initializers = IntegrationTestConfiguration.Initializer.class) +class ApiKeysClientTest { + + @Value("${nvct.api-keys.base-url}") + private String apiKeysBaseUrl; + + @BeforeEach + void setUp() { + MockApiKeysServer.start(apiKeysBaseUrl); + } + + @AfterEach + void reset() { + MockApiKeysServer.resetToDefault(); + } + + @AfterAll + void tearDown() { + MockApiKeysServer.stop(); + } + + @Test + void fetchApiKeyValidationResultPostsToConfiguredEvaluationUri() { + var baseUrl = MockApiKeysServer.getMockApiKeysServer().baseUrl(); + var staticProps = new StaticClientApiKeysProperties(); + staticProps.setToken("static-token"); + var client = new ApiKeysClient( + baseUrl, + EVALUATION_URI_PATH, + "apiKey", + "unused-client", + "unused-secret", + "", + "http://localhost:1/unused-token", + Optional.of(staticProps), + WebClient.builder(), + JsonMapper.builder().build()); + + client.fetchApiKeyValidationResult("my-api-key"); + + MockApiKeysServer.getMockApiKeysServer() + .verify(1, postRequestedFor(urlPathEqualTo(EVALUATION_URI_PATH))); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/service/client/ClientServiceTest.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/service/client/ClientServiceTest.java new file mode 100644 index 000000000..12f75771c --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/service/client/ClientServiceTest.java @@ -0,0 +1,117 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.client; + +import static com.github.tomakehurst.wiremock.client.WireMock.getRequestedFor; +import static com.github.tomakehurst.wiremock.client.WireMock.urlMatching; +import static com.nvidia.nvct.util.TestConstants.TEST_CLIENT_ID; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; + +import com.nvidia.boot.exceptions.NotFoundException; +import com.nvidia.nvct.IntegrationTestConfiguration; +import com.nvidia.nvct.NvctTestApp; +import com.nvidia.nvct.grpc.TestTaskService; +import com.nvidia.nvct.util.MockNvcfServer; +import java.net.URL; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ContextConfiguration; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@Slf4j +@SpringBootTest( + classes = {NvctTestApp.class, IntegrationTestConfiguration.class}, + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + properties = "spring.profiles.active=test") +@ContextConfiguration(initializers = IntegrationTestConfiguration.Initializer.class) +class ClientServiceTest { + + @Autowired + private ClientService clientService; + + @Autowired + private TestTaskService testTaskService; + + + @Value("${nvct.nvcf.base-url}") + private URL nvcfBaseUrl; + + @BeforeAll + void beforeAll() { + log.info("{}: Started running tests", this.getClass().getSimpleName()); + MockNvcfServer.start(nvcfBaseUrl); + } + + @AfterAll + void cleanup() { + MockNvcfServer.stop(); + log.info("{}: Completed running tests", this.getClass().getSimpleName()); + } + + @AfterEach + void afterEach() { + clientService.invalidateCache(); + testTaskService.clearAll(); + } + + @Test + void shouldGetClient() { + var dto = clientService.getClient(TEST_CLIENT_ID); + assertThat(dto).isNotNull(); + assertThat(dto.clientId()).isEqualTo(TEST_CLIENT_ID); + assertThat(dto.ncaId()).isNotBlank(); + assertThat(dto.name()).isNotBlank(); + } + + @Test + void shouldFailToGetClient() { + assertThatExceptionOfType(NotFoundException.class).isThrownBy( + () -> clientService.getClient("non-existent-client")); + } + + @Test + void shouldReturnCachedClientOnSecondCallWithinTtl() { + MockNvcfServer.getMockNvcfServer().resetRequests(); + + clientService.getClient(TEST_CLIENT_ID); + clientService.getClient(TEST_CLIENT_ID); + + MockNvcfServer.getMockNvcfServer().verify(1, + getRequestedFor(urlMatching("/v2/nvcf/clients/" + TEST_CLIENT_ID))); + } + + @Test + void shouldRefetchClientAfterTtlExpires() throws InterruptedException { + MockNvcfServer.getMockNvcfServer().resetRequests(); + + clientService.getClient(TEST_CLIENT_ID); + Thread.sleep(3000); + clientService.getClient(TEST_CLIENT_ID); + + MockNvcfServer.getMockNvcfServer().verify(2, + getRequestedFor(urlMatching("/v2/nvcf/clients/" + TEST_CLIENT_ID))); + } + +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/service/ess/EssServiceTest.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/service/ess/EssServiceTest.java new file mode 100644 index 000000000..ca7f863d8 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/service/ess/EssServiceTest.java @@ -0,0 +1,295 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.ess; + +import static com.nvidia.nvct.util.NvctConstants.NGC_API_KEY; +import static com.nvidia.nvct.util.TestConstants.TEST_NCA_ID; +import static com.nvidia.nvct.util.TestConstants.TEST_ICMS_REQ_ID_1; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_ID_1; +import static org.assertj.core.api.Assertions.assertThat; + +import tools.jackson.databind.node.StringNode; +import com.nvidia.nvct.IntegrationTestConfiguration; +import com.nvidia.nvct.NvctTestApp; +import com.nvidia.nvct.grpc.TestTaskService; +import com.nvidia.nvct.rest.task.dto.SecretDto; +import com.nvidia.nvct.service.task.TaskService; +import com.nvidia.nvct.util.MockEssServer; +import java.util.Set; +import lombok.extern.slf4j.Slf4j; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ContextConfiguration; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@Slf4j +@ExtendWith(MockitoExtension.class) +@SpringBootTest( + classes = {NvctTestApp.class, IntegrationTestConfiguration.class}, + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + properties = "spring.profiles.active=test") +@ContextConfiguration(initializers = IntegrationTestConfiguration.Initializer.class) +class EssServiceTest { + + + @Autowired + private TestTaskService testTaskService; + + @Autowired + private EssService essService; + + @Autowired + private TaskService taskService; + + @Value("${nvct.ess.base-url}") + private String essBaseUrl; + + @BeforeAll + void beforeAll() { + log.info("{}: Started running tests", this.getClass().getSimpleName()); + MockEssServer.start(essBaseUrl); + } + + @AfterAll + void cleanup() { + MockEssServer.stop(); + log.info("{}: Completed running tests", this.getClass().getSimpleName()); + } + + @AfterEach + void reset() { + MockEssServer.clearSecrets(); + testTaskService.clearAll(); + } + + @Test + void testSavingSecrets() { + // Create a task + testTaskService.createTask(TEST_NCA_ID, TEST_TASK_ID_1, TEST_ICMS_REQ_ID_1); + + // Save secrets for a task. + var secrets = Set.of(SecretDto.builder() + .name("AWS_SECRET_ACCESS_KEY") + .value(new StringNode("shhh!")) + .build()); + var version = essService.saveSecrets(TEST_TASK_ID_1, secrets); + assertThat(version).isNotNull(); + + // Update task to indicate it has secrets + var taskEntity = taskService.fetchTask(TEST_TASK_ID_1); + taskEntity.setHasSecrets(true); + taskService.updateTask(taskEntity); + + // Verify saved secrets for the task. + essService.getSecrets(TEST_TASK_ID_1) + .map(dtos -> { + assertThat(dtos).isNotNull().hasSize(1); + dtos.forEach(dto -> { + assertThat(dto.name()).isEqualTo("AWS_SECRET_ACCESS_KEY"); + assertThat(dto.value()).isEqualTo(new StringNode("shhh!")); + }); + return dtos; + }) + .orElseGet(() -> Assertions.fail("Failed to save secrets")); + } + + @Test + void testUpdatingSecrets() { + // Create a task + testTaskService.createTask(TEST_NCA_ID, TEST_TASK_ID_1, TEST_ICMS_REQ_ID_1); + + // Save secrets for a task. + var secrets = Set.of(SecretDto.builder() + .name("AWS_SECRET_ACCESS_KEY") + .value(new StringNode("shhh!")) + .build()); + var version = essService.saveSecrets(TEST_TASK_ID_1, secrets); + assertThat(version).isNotNull(); + + // Update task to indicate it has secrets + var taskEntity = taskService.fetchTask(TEST_TASK_ID_1); + taskEntity.setHasSecrets(true); + taskService.updateTask(taskEntity); + + // Verify saved secrets for the task. + essService.getSecrets(TEST_TASK_ID_1) + .map(dtos -> { + assertThat(dtos).isNotNull().hasSize(1); + dtos.forEach(dto -> { + assertThat(dto.name()).isEqualTo("AWS_SECRET_ACCESS_KEY"); + assertThat(dto.value()).isEqualTo(new StringNode("shhh!")); + }); + return dtos; + }) + .orElseGet(() -> Assertions.fail("Failed to save secrets")); + + // Update secrets for the task. + var updatedSecrets = Set.of(SecretDto.builder() + .name("AWS_SECRET_ACCESS_KEY") + .value(new StringNode("confidential!")) + .build(), + SecretDto.builder() + .name(NGC_API_KEY) + .value(new StringNode("shhh!shhh!")) + .build()); + var newVersion = essService.saveSecrets(TEST_TASK_ID_1, updatedSecrets); + assertThat(newVersion).isNotNull(); + + // Verify updated secrets for the task. + var expectedSecretValues = Set.of(new StringNode("confidential!"), + new StringNode("shhh!shhh!")); + essService.getSecrets(TEST_TASK_ID_1) + .map(dtos -> { + assertThat(dtos).isNotNull().hasSize(2); + dtos.forEach(dto -> { + assertThat(dto.name()).isIn(Set.of("AWS_SECRET_ACCESS_KEY", NGC_API_KEY)); + assertThat(dto.value()).isIn(expectedSecretValues); + }); + return dtos; + }) + .orElseGet(() -> Assertions.fail("Failed to update secrets")); + } + + @Test + void testFetchingSecretNames() { + // Create a task + testTaskService.createTask(TEST_NCA_ID, TEST_TASK_ID_1, TEST_ICMS_REQ_ID_1); + + // Save secrets for a task. + var secrets = Set.of(SecretDto.builder() + .name("AWS_SECRET_ACCESS_KEY") + .value(new StringNode("shhh!")) + .build(), + SecretDto.builder() + .name(NGC_API_KEY) + .value(new StringNode("shhh!shhh!")) + .build()); + var version = essService.saveSecrets(TEST_TASK_ID_1, secrets); + assertThat(version).isNotNull(); + + // Update task to indicate it has secrets + var taskEntity = taskService.fetchTask(TEST_TASK_ID_1); + taskEntity.setHasSecrets(true); + taskService.updateTask(taskEntity); + + // Get secret names for the task. + var result = essService.getSecretNames(TEST_TASK_ID_1) + .orElse(null); + assertThat(result).isNotNull().hasSize(2); + assertThat(result).containsExactlyInAnyOrder("AWS_SECRET_ACCESS_KEY", NGC_API_KEY); + } + + @Test + void testFetchingNonExistingSecretNames() { + // Fetch secret names without saving secrets for a task. + var result = essService.getSecretNames(TEST_TASK_ID_1); + assertThat(result).isNotNull().isEmpty(); + } + + @Test + void testFetchingNonExistingSecrets() { + // Fetch secrets without saving secrets for a task. + var secretDtos = essService.getSecrets(TEST_TASK_ID_1); + assertThat(secretDtos).isNotNull().isEmpty(); + } + + @Test + void testDeletingSecrets() { + // Create a task + testTaskService.createTask(TEST_NCA_ID, TEST_TASK_ID_1, TEST_ICMS_REQ_ID_1); + + // Save secrets for a task. + var secrets = Set.of(SecretDto.builder() + .name("AWS_SECRET_ACCESS_KEY") + .value(new StringNode("shhh!")) + .build()); + var version = essService.saveSecrets(TEST_TASK_ID_1, secrets); + assertThat(version).isNotNull(); + + // Update task to indicate it has secrets + var taskEntity = taskService.fetchTask(TEST_TASK_ID_1); + taskEntity.setHasSecrets(true); + taskService.updateTask(taskEntity); + + // Verify saved secrets for the task. + essService.getSecrets(TEST_TASK_ID_1) + .map(dtos -> { + assertThat(dtos).isNotNull().hasSize(1); + dtos.forEach(dto -> { + assertThat(dto.name()).isEqualTo("AWS_SECRET_ACCESS_KEY"); + assertThat(dto.value()).isEqualTo(new StringNode("shhh!")); + }); + return dtos; + }) + .orElseGet(() -> Assertions.fail("Failed to save secrets")); + + // Delete secrets saved for the task. + essService.deleteSecrets(TEST_TASK_ID_1); + + // Fetch secrets after deleting them. + var secretDtos = essService.getSecrets(TEST_TASK_ID_1); + assertThat(secretDtos).isNotNull().isEmpty(); + } + + @Test + void testDeletingSecretsPath() { + // Create a task + testTaskService.createTask(TEST_NCA_ID, TEST_TASK_ID_1, TEST_ICMS_REQ_ID_1); + + // Save secrets for a task. + var secrets = Set.of(SecretDto.builder() + .name("AWS_SECRET_ACCESS_KEY") + .value(new StringNode("shhh!")) + .build()); + var version = essService.saveSecrets(TEST_TASK_ID_1, secrets); + assertThat(version).isNotNull(); + + // Update task to indicate it has secrets + var taskEntity = taskService.fetchTask(TEST_TASK_ID_1); + taskEntity.setHasSecrets(true); + taskService.updateTask(taskEntity); + + // Verify saved secrets for the task. + essService.getSecrets(TEST_TASK_ID_1) + .map(dtos -> { + assertThat(dtos).isNotNull().hasSize(1); + dtos.forEach(dto -> { + assertThat(dto.name()).isEqualTo("AWS_SECRET_ACCESS_KEY"); + assertThat(dto.value()).isEqualTo(new StringNode("shhh!")); + }); + return dtos; + }) + .orElseGet(() -> Assertions.fail("Failed to save secrets")); + + // Delete secrets path. + essService.deleteSecretsPath(TEST_TASK_ID_1); + + // Fetch secrets after deleting the path. + var secretDtos = essService.getSecrets(TEST_TASK_ID_1); + assertThat(secretDtos).isNotNull().isEmpty(); + } + +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/service/icms/IcmsClusterGroupClientTest.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/service/icms/IcmsClusterGroupClientTest.java new file mode 100644 index 000000000..2500001cb --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/service/icms/IcmsClusterGroupClientTest.java @@ -0,0 +1,220 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.icms; + +import static com.nvidia.nvct.util.MockIcmsServer.ClusterGroupsResponseState; +import static com.nvidia.nvct.util.MockIcmsServer.ClusterGroupsResponseState.COMPLETE; +import static com.nvidia.nvct.util.MockIcmsServer.ClusterGroupsResponseState.MISSING_CLUSTER_GROUP; +import static com.nvidia.nvct.util.MockIcmsServer.ClusterGroupsResponseState.MISSING_GPU; +import static com.nvidia.nvct.util.MockIcmsServer.ClusterGroupsResponseState.MISSING_GPUS; +import static com.nvidia.nvct.util.MockIcmsServer.ClusterGroupsResponseState.MISSING_INSTANCE_TYPES; +import static com.nvidia.nvct.util.MockIcmsServer.ClusterGroupsResponseState.MISSING_INSTANCE_TYPE_DEFAULT; +import static com.nvidia.nvct.util.MockIcmsServer.ClusterGroupsResponseState.WITHOUT_ERROR_BODY_500; +import static com.nvidia.nvct.util.MockIcmsServer.ClusterGroupsResponseState.WITH_ERROR_BODY_400; +import static com.nvidia.nvct.util.MockIcmsServer.IcmsRequestContext; +import static com.nvidia.nvct.util.MockIcmsServer.InstancesState.HEALTHY; +import static com.nvidia.nvct.util.TestConstants.TEST_NCA_ID; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.AssertionsForClassTypes.assertThatExceptionOfType; + +import tools.jackson.databind.json.JsonMapper; +import com.nvidia.boot.exceptions.BadRequestException; +import com.nvidia.boot.exceptions.UpstreamException; +import com.nvidia.boot.mock.ngc.MockCasServer; +import com.nvidia.nvct.IntegrationTestConfiguration; +import com.nvidia.nvct.NvctTestApp; +import com.nvidia.nvct.grpc.TestTaskService; +import com.nvidia.nvct.rest.task.dto.InstanceUsageTypeEnum; +import com.nvidia.nvct.util.MockIcmsServer; +import com.nvidia.nvct.util.MockNvcfServer; +import java.net.URL; +import java.util.List; +import java.util.stream.Stream; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ContextConfiguration; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@Slf4j +@SpringBootTest( + classes = {NvctTestApp.class, IntegrationTestConfiguration.class}, + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + properties = "spring.profiles.active=test") +@ContextConfiguration(initializers = IntegrationTestConfiguration.Initializer.class) +class IcmsClusterGroupClientTest { + + @Autowired + private IcmsClusterGroupClient icmsClusterGroupClient; + + @Autowired + private TestTaskService testTaskService; + + @Autowired + private JsonMapper jsonMapper; + + @Value("${nvct.registries.recognized.model.ngc.hostname}") + private String casBaseUrl; + + @Value("${nvct.registries.recognized.model.ngc.oauth2.base-url}") + private String authnBaseUrl; + + @Value("${nvct.nvcf.base-url}") + private URL nvcfBaseUrl; + + @Value("${nvct.icms.base-url}") + private URL icmsBaseUrl; + + + @BeforeAll + void beforeAll() { + log.info("{}: Started running tests", this.getClass().getSimpleName()); + MockNvcfServer.start(nvcfBaseUrl); + MockCasServer.start(authnBaseUrl, casBaseUrl); + } + + @AfterAll + void cleanup() { + MockNvcfServer.stop(); + MockIcmsServer.stop(); + log.info("{}: Completed running tests", this.getClass().getSimpleName()); + } + + @AfterEach + void afterEach() { + MockIcmsServer.stop(); + icmsClusterGroupClient.clearClusterGroupCache(); + testTaskService.clearAll(); + } + + Stream clusterGroupArgs() { + return Stream.of( + Arguments.of(COMPLETE), + Arguments.of(MISSING_CLUSTER_GROUP), + Arguments.of(MISSING_GPUS), + Arguments.of(MISSING_GPU), + Arguments.of(MISSING_INSTANCE_TYPES), + Arguments.of(MISSING_INSTANCE_TYPE_DEFAULT), + Arguments.of(WITH_ERROR_BODY_400), + Arguments.of(WITHOUT_ERROR_BODY_500) + ); + } + + @ParameterizedTest + @MethodSource("clusterGroupArgs") + void shouldGetClusterGroups(ClusterGroupsResponseState clusterGroupResponseState) { + var contexts = List.of(IcmsRequestContext.builder().instanceState(HEALTHY).build()); + MockIcmsServer.start(icmsBaseUrl, jsonMapper, contexts, clusterGroupResponseState); + switch (clusterGroupResponseState) { + case WITH_ERROR_BODY_400: + assertThatExceptionOfType(BadRequestException.class) + .isThrownBy(() -> icmsClusterGroupClient.getClusterGroups( + TEST_NCA_ID, InstanceUsageTypeEnum.DEFAULT)) + .withMessageContaining("pretend bad deployment spec"); + break; + + case WITHOUT_ERROR_BODY_500: + assertThatExceptionOfType(UpstreamException.class) + .isThrownBy(() -> icmsClusterGroupClient.getClusterGroups( + TEST_NCA_ID, InstanceUsageTypeEnum.DEFAULT)) + .withMessageContaining("Failed to get response from 'ICMS' after retries"); + break; + + default: + var results = icmsClusterGroupClient.getClusterGroups( + TEST_NCA_ID, InstanceUsageTypeEnum.DEFAULT); + assertThat(results).isNotNull(); + } + } + + @ParameterizedTest + @MethodSource("clusterGroupArgs") + void shouldGetDefaultInstanceType(ClusterGroupsResponseState clusterGroupResponseState) { + var contexts = List.of(IcmsRequestContext.builder().instanceState(HEALTHY).build()); + MockIcmsServer.start(icmsBaseUrl, jsonMapper, contexts, clusterGroupResponseState); + switch (clusterGroupResponseState) { + case COMPLETE: + var ncaId = "jY_kY8LqzQRKL0J8pqC6avyTLyWGUrlQr4BC-SVYhbo"; + var clusterGroupName = "GFN"; + var gpuName = "T10"; + var result = icmsClusterGroupClient.getDefaultInstanceType( + ncaId, InstanceUsageTypeEnum.DEFAULT, clusterGroupName, gpuName); + assertThat(result).isEqualTo("g6.full"); + break; + + case MISSING_CLUSTER_GROUP: + ncaId = "zK0fuqHAgHZtM8zbcSAlWeOgN3KE2PO3wI6jtjidFhw"; + clusterGroupName = "OCI"; + gpuName = "A100_80GB"; + result = icmsClusterGroupClient.getDefaultInstanceType( + ncaId, InstanceUsageTypeEnum.DEFAULT, clusterGroupName, gpuName); + assertThat(result).isEqualTo("BM.GPU.A100-v2.8"); + break; + + case MISSING_GPUS: + ncaId = "zK0fuqHAgHZtM8zbcSAlWeOgN3KE2PO3wI6jtjidFhw"; + clusterGroupName = "OCI"; + gpuName = "A100_80GB"; + result = icmsClusterGroupClient.getDefaultInstanceType( + ncaId, InstanceUsageTypeEnum.DEFAULT, clusterGroupName, gpuName); + assertThat(result).isEqualTo("BM.GPU.A100-v2.8"); + break; + + case MISSING_GPU: + ncaId = "jY_kY8LqzQRKL0J8pqC6avyTLyWGUrlQr4BC-SVYhbo"; + clusterGroupName = "GFN"; + gpuName = "A10G"; + result = icmsClusterGroupClient.getDefaultInstanceType( + ncaId, InstanceUsageTypeEnum.DEFAULT, clusterGroupName, gpuName); + assertThat(result).isEqualTo("ga10g_1.br20_2xlarge"); + break; + + case MISSING_INSTANCE_TYPE_DEFAULT: + ncaId = "jY_kY8LqzQRKL0J8pqC6avyTLyWGUrlQr4BC-SVYhbo"; + clusterGroupName = "GFN"; + gpuName = "T10"; + assertThatExceptionOfType(UpstreamException.class) + .isThrownBy(() -> icmsClusterGroupClient + .getDefaultInstanceType( + ncaId, InstanceUsageTypeEnum.DEFAULT, + clusterGroupName, gpuName)); + break; + + case MISSING_INSTANCE_TYPES: + ncaId = "jY_kY8LqzQRKL0J8pqC6avyTLyWGUrlQr4BC-SVYhbo"; + clusterGroupName = "GFN"; + gpuName = "T10"; + assertThatExceptionOfType(UpstreamException.class) + .isThrownBy(() -> icmsClusterGroupClient + .getDefaultInstanceType( + ncaId, InstanceUsageTypeEnum.DEFAULT, + clusterGroupName, gpuName)); + break; + + default: + break; + } + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/service/icms/IcmsServiceTest.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/service/icms/IcmsServiceTest.java new file mode 100644 index 000000000..2590601d9 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/service/icms/IcmsServiceTest.java @@ -0,0 +1,487 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.icms; + +import static com.nvidia.nvct.util.TestConstants.BASE64_CONTAINER_REGISTRY_CRED; +import static com.nvidia.nvct.util.TestConstants.BASE64_ENCODED_ACR_CRED; +import static com.nvidia.nvct.util.TestConstants.BASE64_ENCODED_ARTIFACTORY_CRED; +import static com.nvidia.nvct.util.TestConstants.BASE64_ENCODED_DOCKER_CRED; +import static com.nvidia.nvct.util.TestConstants.BASE64_ENCODED_ECR_PRIVATE_CRED; +import static com.nvidia.nvct.util.TestConstants.BASE64_ENCODED_ECR_PUBLIC_CRED; +import static com.nvidia.nvct.util.TestConstants.BASE64_ENCODED_HARBOR_CRED; +import static com.nvidia.nvct.util.TestConstants.BASE64_ENCODED_VOLCENGINE_CRED; +import static com.nvidia.nvct.util.TestConstants.BASE64_HELM_REGISTRY_CRED; +import static com.nvidia.nvct.util.TestConstants.BASE64_SIDECAR_REGISTRY_CRED; +import static com.nvidia.nvct.util.TestConstants.TEST_CONTAINER_ARGS; +import static com.nvidia.nvct.util.TestConstants.TEST_CONTAINER_IMAGE; +import static com.nvidia.nvct.util.TestConstants.TEST_HELM_CHART; +import static com.nvidia.nvct.util.TestConstants.TEST_ICMS_REQ_ID_1; +import static com.nvidia.nvct.util.TestConstants.TEST_NCA_ID; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_ID_1; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_NAME_1; +import static com.nvidia.nvct.util.TestConstants.TEST_VALID_ORG_NAME; +import static com.nvidia.nvct.util.TestConstants.TEST_VALID_TEAM_NAME; +import static com.nvidia.nvct.util.TestUtil.buildHelmValidationPolicyDto; +import static org.assertj.core.api.Assertions.assertThat; + +import tools.jackson.databind.json.JsonMapper; +import com.github.tomakehurst.wiremock.stubbing.ServeEvent; +import com.nvidia.boot.mock.ngc.MockCasServer; +import com.nvidia.nvct.IntegrationTestConfiguration; +import com.nvidia.nvct.NvctTestApp; +import com.nvidia.nvct.grpc.TestTaskService; +import com.nvidia.nvct.persistence.task.entity.ResultHandlingStrategy; +import com.nvidia.nvct.persistence.task.entity.TaskEntity; +import com.nvidia.nvct.rest.task.dto.HelmValidationPolicyDto; +import com.nvidia.nvct.service.registry.RegistryArtifactService; +import com.nvidia.nvct.service.registry.dto.K8sSecretsDto; +import com.nvidia.nvct.service.task.TaskService; +import com.nvidia.nvct.util.MockEssServer; +import com.nvidia.nvct.util.MockNotaryServer; +import com.nvidia.nvct.util.MockNvcfServer; +import com.nvidia.nvct.util.MockIcmsServer; +import com.nvidia.nvct.util.TestUtil; +import java.net.URL; +import java.net.URLDecoder; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Base64; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import org.apache.logging.log4j.util.Strings; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ContextConfiguration; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@Slf4j +@SpringBootTest( + classes = {NvctTestApp.class, IntegrationTestConfiguration.class}, + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + properties = "spring.profiles.active=test") +@ContextConfiguration(initializers = IntegrationTestConfiguration.Initializer.class) +class IcmsServiceTest { + + @Autowired + private IcmsService icmsService; + + @Autowired + private TestTaskService testTaskService; + + @Autowired + private IcmsClient icmsClient; + + @Autowired + private JsonMapper jsonMapper; + + @Autowired + private TaskService taskService; + + @Autowired + private RegistryArtifactService artifactService; + + @Value("${nvct.ess.base-url}") + private String essBaseUrl; + + @Value("${nvct.notary.base-url}") + private String notaryBaseUrl; + + @Value("${spring.security.oauth2.client.registration.notary.client-id}") + private String notaryClientId; + + @Value("${nvct.nvcf.base-url}") + private URL nvcfBaseUrl; + + @Value("${nvct.icms.base-url}") + private URL icmsBaseUrl; + + @Value("${nvct.registries.recognized.model.ngc.hostname}") + private String casBaseUrl; + + @Value("${nvct.registries.recognized.model.ngc.oauth2.base-url}") + private String authnBaseUrl; + + + @BeforeAll + void beforeAll() { + log.info("{}: Started running tests", this.getClass().getSimpleName()); + MockNvcfServer.start(nvcfBaseUrl); + MockIcmsServer.start(icmsBaseUrl, jsonMapper); + MockCasServer.start(authnBaseUrl, casBaseUrl); + MockEssServer.start(essBaseUrl); + MockNotaryServer.start(notaryBaseUrl, notaryClientId); + } + + @AfterAll + void cleanup() { + MockNvcfServer.stop(); + MockIcmsServer.stop(); + MockCasServer.stop(); + MockEssServer.stop(); + MockNotaryServer.stop(); + log.info("{}: Completed running tests", this.getClass().getSimpleName()); + } + + @AfterEach + void afterEach() { + artifactService.invalidateCache(); + testTaskService.clearAll(); + } + + @Test + void shouldScheduleInstanceForContainerBasedTask() { + var task1 = TestUtil.createTaskEntity(TEST_TASK_ID_1, TEST_NCA_ID, TEST_TASK_NAME_1, + jsonMapper); + taskService.saveTask(task1); + + // Act + var requestId = icmsService.scheduleInstance(task1); + + // Assert + assertThat(requestId).isNotNull(); + List allServeEvents = MockIcmsServer.getMockIcmsServer().getAllServeEvents(); + String formUrlEncodedBody = allServeEvents.getFirst().getRequest().getBodyAsString(); + validateTaskInstancePayload(formUrlEncodedBody, task1); + + taskService.deleteTask(task1); + } + + @Test + void shouldScheduleInstanceForHelmBasedTask() { + var task1 = + TestUtil.createHelmBasedTaskEntity(TEST_TASK_ID_1, TEST_NCA_ID, TEST_TASK_NAME_1, + jsonMapper); + taskService.saveTask(task1); + + // Act + var requestId = icmsService.scheduleInstance(task1); + + // Assert + assertThat(requestId).isNotNull(); + List allServeEvents = MockIcmsServer.getMockIcmsServer().getAllServeEvents(); + String formUrlEncodedBody = allServeEvents.getFirst().getRequest().getBodyAsString(); + validateTaskInstancePayload(formUrlEncodedBody, task1); + + taskService.deleteTask(task1); + } + + @Test + void shouldDeleteInstances() { + icmsClient.deleteInstances(List.of("ids")); + } + + @Test + void shouldTolerateTerminateWhenIcmsWorkloadNotFound() { + MockIcmsServer.start(icmsBaseUrl, jsonMapper); + MockIcmsServer.stubTerminateInstanceNotFound(); + + testTaskService.createTask(TEST_NCA_ID, TEST_TASK_ID_1, TEST_ICMS_REQ_ID_1); + + var result = icmsService.terminateInstanceByTaskId(TEST_NCA_ID, TEST_TASK_ID_1); + + assertThat(result).isTrue(); + + taskService.deleteTask(TEST_TASK_ID_1); + } + + @SneakyThrows + private void validateTaskInstancePayload(String formUrlEncodedBody, TaskEntity task) { + Map paramMap = Arrays.stream(formUrlEncodedBody.split("&")) + .map(s -> s.split("=", 2)) + .collect(Collectors.toMap( + key -> decode(key[0]), + value -> decode(value.length > 1 ? value[1] : ""), + (existing, incoming) -> { + if (existing instanceof String) { + List list = new ArrayList<>(); + list.add((String) existing); + list.add((String) incoming); + return list; + } else { + ((List) existing).add((String) incoming); + return existing; + } + })); + + assertThat(paramMap) + .containsEntry("TaskDetails.TaskName", task.getName()) + .containsEntry("LaunchSpecification.NcaId", TEST_NCA_ID) + .containsEntry("LaunchSpecification.TerminationGracePeriodDuration", "PT1H") + .containsEntry("LaunchSpecification.CacheArtifacts", "true") + .containsEntry("LaunchSpecification.GpuSpecificationId", TEST_TASK_ID_1.toString()) + .containsEntry("LaunchSpecification.Gpu", "T10") + .containsEntry("LaunchSpecification.Backend", "GFN") + .containsEntry("LaunchSpecification.InstanceType", "g6.full") + .containsEntry("TaskDetails.AccountName", "test-nca-id-name") + .containsEntry("InstanceCount", "1") + .containsEntry("LaunchSpecification.CacheHandle", + "da56d7b9f5b145646f32b571d19ae4bf") + .containsEntry("LaunchSpecification.CacheSize", "232476667482") + .containsEntry("TaskDetails.OwnerNcaId", TEST_NCA_ID) + .containsEntry("TaskDetails.TaskId", TEST_TASK_ID_1.toString()) + .containsEntry("LaunchSpecification.MaxRuntimeDuration", "PT7H") + .containsEntry("LaunchSpecification.MaxQueuedDuration", "PT24H") + .containsEntry("LaunchSpecification.ResultHandlingStrategy", + ResultHandlingStrategy.UPLOAD.name()) + .containsEntry("LaunchSpecification.Telemetries", "") + .containsEntry("LaunchSpecification.DeploymentId", TEST_TASK_ID_1.toString()); + + // validate helm validation policy + var policyRaw = (String) paramMap.get("LaunchSpecification.HelmValidationPolicy"); + assertThat(policyRaw).isNotBlank(); + var policyDecoded = + new String(Base64.getDecoder().decode(policyRaw), StandardCharsets.UTF_8); + var policy = jsonMapper.readValue(policyDecoded, HelmValidationPolicyDto.class); + assertThat(policy).isEqualTo(buildHelmValidationPolicyDto()); + + // Validate environment variables + String environment = (String) paramMap.get("LaunchSpecification.Environment"); + assertThat(environment).isNotNull(); + Map envVars = decodeEnvironmentVariables(environment); + + assertThat(envVars) + .containsEntry("NCA_ID", TEST_NCA_ID) + .containsEntry("ACCOUNT_NAME", "test-nca-id-name") + .containsEntry("TASK_ID", TEST_TASK_ID_1.toString()) + .containsEntry("TASK_NAME", task.getName()) + .containsEntry("TERMINATION_GRACE_PERIOD", "PT1H") + .containsEntry("TASK_SECRETS_PRESENT", "false") + .containsEntry("NVCT_FQDN", "http://localhost:0") + .containsEntry("NVCT_FQDN_GRPC", "http://localhost:9090") + .containsEntry("INIT_CONTAINER", + "stg.nvcr.io/nv-cf/nvcf-core/nvcf_worker_init:0.7.0") + .containsEntry("OTEL_CONTAINER", "docker.io/otel/opentelemetry-collector:0.74.0") + .containsEntry("UTILS_CONTAINER", + "stg.nvcr.io/nv-cf/nvcf-core/nvcf_worker_utils:2.2.1") + .containsEntry("ESS_AGENT_CONTAINER", "stg.nvcr.io/nv-cf/nvcf-core/ess-agent:0.0.4") + .containsEntry("OTEL_EXPORTER_OTLP_ENDPOINT", "https://dummy:8282") + .containsEntry("TASK_CONTAINER_ENV", + "W3sia2V5IjoiS0VZXzEiLCJ2YWx1ZSI6IlZBTFVFXzEifSx7ImtleSI6IktFWV8yIiwidmFsdWUiOiJWQUxVRV8yIn0seyJrZXkiOiJLRVlfMyIsInZhbHVlIjoiVkFMVUVfMyJ9XQ==") + .containsEntry("RESULTS_LOCATION", + TEST_VALID_ORG_NAME + "/" + TEST_VALID_TEAM_NAME + + "/test-model-name") + .containsEntry("TRACING_ACCESS_TOKEN", "dummy-worker-lightstep-access-token") + .containsEntry("BYOO_OTEL_COLLECTOR_CONTAINER", + "stg.nvcr.io/nv-cf/nvcf-core/byoo-otel-collector:1.2.3") + .containsEntry("SECRETS_ASSERTION_TOKEN", "") + .containsKey("NVCT_WORKER_TOKEN") + .containsKey("CONTAINER_REGISTRIES_CREDENTIALS") + .containsKey("HELM_REGISTRIES_CREDENTIALS") + .containsKey("SIDECAR_REGISTRY_CREDENTIAL"); + + var containerRegistriesCredentials = jsonMapper.readValue( + Base64.getDecoder().decode(envVars.get("CONTAINER_REGISTRIES_CREDENTIALS")), + K8sSecretsDto.class); + + var helmRegistriesCredentials = jsonMapper.readValue( + Base64.getDecoder().decode(envVars.get("HELM_REGISTRIES_CREDENTIALS")), + K8sSecretsDto.class); + + if (Strings.isBlank(task.getHelmChart())) { + var expectedContainerRegistriesCredentialsRaw = """ + { + "k8sSecrets": [ + { + "auths": { + "stg.nvcr.io": { + "auth": "%s" + } + } + } + ] + } + """.formatted(BASE64_CONTAINER_REGISTRY_CRED); + var expectedContainerRegistriesCredentials = + jsonMapper.readValue(expectedContainerRegistriesCredentialsRaw, + K8sSecretsDto.class); + assertThat(containerRegistriesCredentials).isEqualTo( + expectedContainerRegistriesCredentials); + assertThat(paramMap) + .containsEntry("LaunchSpecification.ContainerImage", + TEST_CONTAINER_IMAGE.toString()) + .containsEntry("LaunchSpecification.HelmChart", ""); + assertThat(envVars) + .containsEntry("TASK_CONTAINER", TEST_CONTAINER_IMAGE.toString()) + .containsEntry("TASK_CONTAINER_ARGS", TEST_CONTAINER_ARGS); + String expectedHelmRegistriesCredentialsRaw = """ + { + "k8sSecrets": [] + } + """; + var expectedHelmRegistriesCredentials = + jsonMapper.readValue(expectedHelmRegistriesCredentialsRaw, + K8sSecretsDto.class); + assertThat(helmRegistriesCredentials).isEqualTo(expectedHelmRegistriesCredentials); + } else { + var expectedContainerRegistriesCredentialsRaw = """ + { + "k8sSecrets": [ + { + "auths": { + "docker.io": { + "auth": "%s" + } + } + }, + { + "auths": { + "779846807323.dkr.ecr.us-west-2.amazonaws.com": { + "auth": "%s" + } + } + }, + { + "auths": { + "public.ecr.aws": { + "auth": "%s" + } + } + }, + { + "auths": { + "test-volcengine-registry-cn-beijing.cr.volces.com": { + "auth": "%s" + } + } + }, + { + "auths": { + "test1-bmfvajfxgfcrhba5.azurecr.io": { + "auth": "%s" + } + } + }, + { + "auths": { + "demo.goharbor.io": { + "auth": "%s" + } + } + }, + { + "auths": { + "artifactorytest12345.jfrog.io": { + "auth": "%s" + } + } + }, + { + "auths": { + "stg.nvcr.io": { + "auth": "%s" + } + } + }, + { + "auths": { + "canary.nvcr.io": { + "auth": "%s" + } + } + }, + { + "auths": { + "localhost-ngc": { + "auth": "%s" + } + } + } + ] + } + """.formatted(BASE64_ENCODED_DOCKER_CRED, + BASE64_ENCODED_ECR_PRIVATE_CRED, + BASE64_ENCODED_ECR_PUBLIC_CRED, + BASE64_ENCODED_VOLCENGINE_CRED, + BASE64_ENCODED_ACR_CRED, + BASE64_ENCODED_HARBOR_CRED, + BASE64_ENCODED_ARTIFACTORY_CRED, + BASE64_CONTAINER_REGISTRY_CRED, + BASE64_CONTAINER_REGISTRY_CRED, + BASE64_CONTAINER_REGISTRY_CRED); + var expectedContainerRegistriesCredentials = + jsonMapper.readValue(expectedContainerRegistriesCredentialsRaw, + K8sSecretsDto.class); + assertThat(containerRegistriesCredentials).isEqualTo( + expectedContainerRegistriesCredentials); + assertThat(paramMap) + .containsEntry("LaunchSpecification.ContainerImage", "") + .containsEntry("LaunchSpecification.HelmChart", TEST_HELM_CHART.toString()); + assertThat(envVars) + .containsEntry("TASK_CONTAINER", "") + .containsEntry("TASK_CONTAINER_ARGS", ""); + var expectedHelmRegistriesCredentialsRaw = """ + { + "k8sSecrets": [ + { + "auths": { + "helm.stg.ngc.nvidia.com": { + "auth": "%s" + } + } + } + ] + } + """.formatted(BASE64_HELM_REGISTRY_CRED); + var expectedHelmRegistriesCredentials = + jsonMapper.readValue(expectedHelmRegistriesCredentialsRaw, + K8sSecretsDto.class); + assertThat(helmRegistriesCredentials).isEqualTo(expectedHelmRegistriesCredentials); + + var sidecarRegistryCredential = jsonMapper.readValue( + Base64.getDecoder().decode(envVars.get("SIDECAR_REGISTRY_CREDENTIAL")), + K8sSecretsDto.class); + var expectedSidecarRegistryCredentialRaw = """ + { + "auths": { + "stg.nvcr.io": { + "auth": "%s" + } + } + } + """.formatted(BASE64_SIDECAR_REGISTRY_CRED); + var expectedSidecarRegistryCredential = + jsonMapper.readValue(expectedSidecarRegistryCredentialRaw, + K8sSecretsDto.class); + assertThat(sidecarRegistryCredential).isEqualTo(expectedSidecarRegistryCredential); + } + } + + private static String decode(String s) { + return URLDecoder.decode(s, StandardCharsets.UTF_8); + } + + private static Map decodeEnvironmentVariables(String base64EncodedEnv) { + String decodedEnv = + new String(Base64.getDecoder().decode(base64EncodedEnv), StandardCharsets.UTF_8); + return Arrays.stream(decodedEnv.split("\n")) + .filter(line -> line.contains("=")) + .map(line -> line.split("=", 2)) + .collect(Collectors.toMap( + keyValue -> keyValue[0], + keyValue -> keyValue.length > 1 ? keyValue[1] : "")); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/service/instance/InstanceServiceTest.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/service/instance/InstanceServiceTest.java new file mode 100644 index 000000000..2eec5d292 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/service/instance/InstanceServiceTest.java @@ -0,0 +1,120 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.instance; + +import static com.nvidia.nvct.persistence.task.entity.TaskStatus.RUNNING; +import static com.nvidia.nvct.util.TestConstants.GFN; +import static com.nvidia.nvct.util.TestConstants.T10; +import static com.nvidia.nvct.util.TestConstants.T10_INSTANCE_TYPE; +import static com.nvidia.nvct.util.TestConstants.TEST_ICMS_REQ_ID_1; +import static com.nvidia.nvct.util.TestConstants.TEST_NCA_ID; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_ID_1; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_NAME_1; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import com.nvidia.nvct.persistence.task.entity.GpuSpecUdt; +import com.nvidia.nvct.persistence.task.entity.TaskEntity; +import com.nvidia.nvct.rest.task.dto.InstanceStateEnum; +import com.nvidia.nvct.service.icms.IcmsClient; +import com.nvidia.nvct.service.icms.IcmsStubService.Instance; +import com.nvidia.nvct.service.icms.IcmsStubService.GetInstancesResponse.InstanceRequest.InstanceState; +import com.nvidia.nvct.service.icms.IcmsStubService.GetInstancesResponse.InstanceRequest.Placement; +import java.time.Duration; +import java.time.Instant; +import java.util.List; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +class InstanceServiceTest { + + private static final String INSTANCE_ID = "instance-1"; + private static final String LOCATION = "NP-LAX-03"; + private static final Instant CREATED_AT = Instant.parse("2026-05-28T12:00:00Z"); + + @Mock + private IcmsClient icmsClient; + + private InstanceService instanceService; + + @BeforeEach + void beforeEach() { + instanceService = new InstanceService(icmsClient); + } + + @Test + void getInstancesUsesTaskIdEndpoint() { + var task = createTask(TEST_NCA_ID); + when(icmsClient.getInstancesByTaskId(TEST_NCA_ID, TEST_TASK_ID_1)) + .thenReturn(List.of(createDeploymentInstance())); + + var instances = instanceService.getInstances(task); + + assertThat(instances).isPresent(); + assertThat(instances.get()).singleElement().satisfies(instance -> { + assertThat(instance.getInstanceId()).isEqualTo(INSTANCE_ID); + assertThat(instance.getTaskId()).isEqualTo(TEST_TASK_ID_1); + assertThat(instance.getInstanceType()).isEqualTo(T10_INSTANCE_TYPE); + assertThat(instance.getInstanceState()).isEqualTo(InstanceStateEnum.RUNNING); + assertThat(instance.getIcmsRequestId()).isEqualTo(TEST_ICMS_REQ_ID_1); + assertThat(instance.getNcaId()).isEqualTo(TEST_NCA_ID); + assertThat(instance.getGpu()).isEqualTo(T10); + assertThat(instance.getBackend()).isEqualTo(GFN); + assertThat(instance.getLocation()).isEqualTo(LOCATION); + assertThat(instance.getInstanceCreatedAt()).isEqualTo(CREATED_AT); + assertThat(instance.getInstanceUpdatedAt()).isEqualTo(CREATED_AT); + }); + verify(icmsClient).getInstancesByTaskId(TEST_NCA_ID, TEST_TASK_ID_1); + } + + private static TaskEntity createTask(String ncaId) { + return TaskEntity.builder() + .taskId(TEST_TASK_ID_1) + .ncaId(ncaId) + .name(TEST_TASK_NAME_1) + .status(RUNNING) + .gpuSpec(GpuSpecUdt.builder() + .backend(GFN) + .gpu(T10) + .instanceType(T10_INSTANCE_TYPE) + .build()) + .maxQueuedDuration(Duration.ofHours(24)) + .terminalGracePeriodDuration(Duration.ofHours(1)) + .build(); + } + + private static Instance createDeploymentInstance() { + return Instance.builder() + .createTime(CREATED_AT) + .instanceId(INSTANCE_ID) + .cloudProvider(GFN) + .instanceType(T10_INSTANCE_TYPE) + .placement(Placement.builder() + .availabilityZone(LOCATION) + .build()) + .state(InstanceState.builder() + .name("running") + .build()) + .launchRequestId(TEST_ICMS_REQ_ID_1.toString()) + .build(); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/service/ngc/NgcRegistryClientTest.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/service/ngc/NgcRegistryClientTest.java new file mode 100644 index 000000000..eff7a3b85 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/service/ngc/NgcRegistryClientTest.java @@ -0,0 +1,193 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.ngc; + +import static com.nvidia.nvct.util.TestConstants.TEST_NGC_API_KEY; +import static com.nvidia.nvct.util.TestConstants.TEST_UNKNOWN_ORG_NAME; +import static com.nvidia.nvct.util.TestConstants.TEST_UNKNOWN_TEAM_NAME; +import static com.nvidia.nvct.util.TestConstants.TEST_VALID_ORG_NAME; +import static com.nvidia.nvct.util.TestConstants.TEST_VALID_ORG_NAME_INVALID_KEY; +import static com.nvidia.nvct.util.TestConstants.TEST_VALID_TEAM_NAME; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; + +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.json.JsonMapper; +import tools.jackson.databind.node.StringNode; +import com.nvidia.boot.exceptions.BadRequestException; +import com.nvidia.boot.exceptions.NotFoundException; +import com.nvidia.boot.exceptions.UnauthorizedException; +import com.nvidia.boot.mock.ngc.MockCasServer; +import com.nvidia.nvct.IntegrationTestConfiguration; +import com.nvidia.nvct.NvctTestApp; +import com.nvidia.nvct.grpc.TestTaskService; +import java.util.stream.Stream; +import lombok.extern.slf4j.Slf4j; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ContextConfiguration; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@Slf4j +@SpringBootTest( + classes = {NvctTestApp.class, IntegrationTestConfiguration.class}, + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + properties = "spring.profiles.active=test") +@ContextConfiguration(initializers = IntegrationTestConfiguration.Initializer.class) +class NgcRegistryClientTest { + + @Autowired + private JsonMapper jsonMapper; + + @Autowired + private NgcRegistryClient ngcRegistryClient; + + @Autowired + private TestTaskService testTaskService; + + @Value("${nvct.registries.recognized.model.ngc.hostname}") + private String casBaseUrl; + + @Value("${nvct.registries.recognized.model.ngc.oauth2.base-url}") + private String authnBaseUrl; + + @BeforeAll + void beforeAll() { + log.info("{}: Started running tests", this.getClass().getSimpleName()); + MockCasServer.start(authnBaseUrl, casBaseUrl); + } + + @AfterAll + void cleanup() { + MockCasServer.stop(); + log.info("{}: Completed running tests", this.getClass().getSimpleName()); + } + + @AfterEach + void reset() { + testTaskService.clearAll(); + } + + + Stream jsonNodeArgs() { + var secretJsonNodeValue = jsonMapper.createObjectNode() + .put("AWS_REGION", "us-west-2") + .put("AWS_BUCKET", "ov-content") + .put("AWS_ACCESS_KEY_ID", "ov-content-key-id") + .put("AWS_SECRET_ACCESS_KEY", "ov-content-access-key") + .put("AWS_SESSION_TOKEN", "ov-content-session-token"); + return Stream.of( + Arguments.of(secretJsonNodeValue), + Arguments.of(new StringNode(TEST_NGC_API_KEY))); + } + + @ParameterizedTest + @MethodSource("jsonNodeArgs") + void testValidOrg(JsonNode jsonNode) { + var resultsLocation = TEST_VALID_ORG_NAME + "/test-model-2"; + + try { + ngcRegistryClient.validate(jsonNode, resultsLocation); + } catch (Exception ex) { + Assertions.fail(ex.getMessage()); + } + } + + @ParameterizedTest + @MethodSource("jsonNodeArgs") + void testValidOrgAndValidTeam(JsonNode jsonNode) { + var resultsLocation = TEST_VALID_ORG_NAME + "/" + TEST_VALID_TEAM_NAME + "/test-model-2"; + + try { + ngcRegistryClient.validate(jsonNode, resultsLocation); + } catch (Exception ex) { + Assertions.fail(ex.getMessage()); + } + } + + @ParameterizedTest + @MethodSource("jsonNodeArgs") + void testNonExistentOrg(JsonNode jsonNode) { + var resultsLocation = TEST_UNKNOWN_ORG_NAME + "/test-model-2"; + + assertThatExceptionOfType(NotFoundException.class) + .isThrownBy(() -> ngcRegistryClient.validate(jsonNode, resultsLocation)); + } + + @ParameterizedTest + @MethodSource("jsonNodeArgs") + void testNonExistentTeam(JsonNode jsonNode) { + var resultsLocation = TEST_VALID_ORG_NAME + "/" + TEST_UNKNOWN_TEAM_NAME + "/test-model-2"; + + assertThatExceptionOfType(NotFoundException.class) + .isThrownBy(() -> ngcRegistryClient.validate(jsonNode, resultsLocation)); + } + + @ParameterizedTest + @MethodSource("jsonNodeArgs") + void testInvalidApiKey(JsonNode jsonNode) { + var resultsLocation = TEST_VALID_ORG_NAME_INVALID_KEY + "/test-model-2"; + + assertThatExceptionOfType(UnauthorizedException.class) + .isThrownBy(() -> ngcRegistryClient.validate(jsonNode, resultsLocation)); + } + + @ParameterizedTest + @MethodSource("jsonNodeArgs") + void testModelNameShort(JsonNode jsonNode) { + // Model name with 15 characters (well within the limit) + // Should not require truncation + var shortModelName = "short"; + var resultsLocation = TEST_VALID_ORG_NAME + "/" + shortModelName; + + // Should not throw exception - no truncation needed + ngcRegistryClient.validate(jsonNode, resultsLocation); + } + + @ParameterizedTest + @MethodSource("jsonNodeArgs") + void testModelNameAtMaxLength(JsonNode jsonNode) { + // Model name with exactly 64 characters (at the limit) + // Should be automatically truncated to fit UUID + var maxLengthModelName = "a".repeat(64); + var resultsLocation = TEST_VALID_ORG_NAME + "/" + maxLengthModelName; + + // Should not throw exception - will be truncated to fit UUID + ngcRegistryClient.validate(jsonNode, resultsLocation); + } + + @ParameterizedTest + @MethodSource("jsonNodeArgs") + void testModelNameExceedsMaxLength(JsonNode jsonNode) { + // Model name with 65 characters (exceeds the 64 character limit) + var tooLongModelName = "a".repeat(65); + var resultsLocation = TEST_VALID_ORG_NAME + "/" + tooLongModelName; + + assertThatExceptionOfType(BadRequestException.class) + .isThrownBy(() -> ngcRegistryClient.validate(jsonNode, resultsLocation)) + .withMessageContaining("exceeds the maximum allowed length of 64 characters"); + } + +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/service/ratelimit/RateLimiterServiceTest.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/service/ratelimit/RateLimiterServiceTest.java new file mode 100644 index 000000000..71dc40426 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/service/ratelimit/RateLimiterServiceTest.java @@ -0,0 +1,371 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.ratelimit; + +import static com.nvidia.nvct.util.NvctConstants.UUID_WILDCARD; +import static com.nvidia.nvct.util.TestConstants.TEST_NCA_ID; +import static com.nvidia.nvct.util.TestConstants.TEST_NCA_ID_2; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_ID_1; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_ID_2; +import static org.assertj.core.api.Assertions.assertThat; +import static org.awaitility.Awaitility.await; +import static org.mockito.Mockito.lenient; + +import com.nvidia.boot.exceptions.TooManyRequestsException; +import com.nvidia.nvct.IntegrationTestConfiguration; +import com.nvidia.nvct.NvctTestApp; +import com.nvidia.nvct.configuration.ratelimit.AccountRateLimiterProperties; +import com.nvidia.nvct.configuration.ratelimit.AccountRateLimiterProperties.AccountRateCappingProperties; +import com.nvidia.nvct.configuration.ratelimit.TaskRateLimiterProperties; +import com.nvidia.nvct.configuration.ratelimit.TaskRateLimiterProperties.TaskRateCappingProperties; +import java.time.Duration; +import java.util.Collections; +import java.util.Map; +import java.util.UUID; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.IntStream; +import java.util.stream.Stream; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.api.extension.ExtendWith; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ContextConfiguration; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@Slf4j +@ExtendWith(MockitoExtension.class) +@SpringBootTest( + classes = {NvctTestApp.class, IntegrationTestConfiguration.class}, + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + properties = "spring.profiles.active=test") +@ContextConfiguration(initializers = IntegrationTestConfiguration.Initializer.class) +class RateLimiterServiceTest { + + @Mock + private AccountRateLimiterProperties accountProperties; + @Mock + private TaskRateLimiterProperties taskProperties; + + private RateLimiterService service; + + @BeforeAll + void beforeAll() { + log.info("{}: Started running tests", this.getClass().getSimpleName()); + } + + @AfterAll + void cleanup() { + log.info("{}: Completed running tests", this.getClass().getSimpleName()); + } + + @BeforeEach + void beforeEach() { + service = new RateLimiterService(accountProperties, taskProperties); + } + + private static Stream accountRateLimiterUseCases() { + return Stream.of( + // Set up default rate limiting policy for accounts with cap of 10000 calls per sec. + // + // Allowed Calls: 10 TEST_TASK_ID_1/TEST_NCA_ID + 10 TEST_TASK_ID_2/TEST_NCA_ID_2 + // Declined Calls: 0 + Arguments.of(createAccountOverrides("*", 10000L), + Collections.emptyMap(), + 20, + 0), + + // Set up default rate limiting policy for accounts with cap of 6 calls per second. + // + // Allowed Calls: 6 TEST_TASK_ID_1/TEST_NCA_ID + 6 TEST_TASK_ID_2/TEST_NCA_ID_2 + // Declined Calls: 4 TEST_TASK_ID_1/TEST_NCA_ID + 4 TEST_TASK_ID_2/TEST_NCA_ID_2 + Arguments.of(createAccountOverrides("*", 6L), + Collections.emptyMap(), + 12, + 8), + + // Set up default rate limiting policy for accounts with cap of 6 calls per second. + // Override the default cap for TEST_NCA_ID with 4 calls per second. + // + // Allowed Calls: 4 TEST_TASK_ID_1/TEST_NCA_ID + 6 TEST_TASK_ID_2/TEST_NCA_ID_2 + // Declined Calls: 6 TEST_TASK_ID_1/TEST_NCA_ID + 4 TEST_TASK_ID_2/TEST_NCA_ID_2 + Arguments.of(createAccountOverrides("*", 6L), + Map.of(TEST_NCA_ID, createAccountOverrides(TEST_NCA_ID, 4L)), + 10, + 10) + ); + } + + @ParameterizedTest + @MethodSource("accountRateLimiterUseCases") + void verifyAccountRateLimit( + AccountRateCappingProperties defaultAccountProperties, + Map accountOverrideIds, + int expectedSuccess, + int expectedDecline) { + applyMocks(defaultAccountProperties, null, accountOverrideIds, null); + + AtomicInteger successful = new AtomicInteger(); + AtomicInteger declined = new AtomicInteger(); + IntStream.range(0, 10).parallel() + .forEach(i -> { + try { + service.verifyLimits(TEST_NCA_ID); + successful.incrementAndGet(); + } catch (TooManyRequestsException e) { + declined.incrementAndGet(); + } + try { + service.verifyLimits(TEST_NCA_ID_2); + successful.incrementAndGet(); + } catch (TooManyRequestsException e) { + declined.incrementAndGet(); + } + }); + assertThat(successful.get()).isEqualTo(expectedSuccess); + assertThat(declined.get()).isEqualTo(expectedDecline); + } + + private static Stream taskRateLimiterUseCases() { + return Stream.of( + // Set up default rate limiting policy for tasks with cap of 10000 calls per second. + // + // Allowed Calls: 10 TEST_TASK_ID_1/TEST_NCA_ID + 10 TEST_TASK_ID_2/TEST_NCA_ID_2 + // Declined Calls: 0 + Arguments.of(createTaskOverrides(UUID_WILDCARD, 10000L), + Collections.emptyMap(), + 20, + 0), + + // Set up default rate limiting policy for tasks with cap of 8 calls per second. + // + // Allowed Calls: 8 TEST_TASK_ID_1/TEST_NCA_ID + 8 for TEST_TASK_ID_2/TEST_NCA_ID_2 + // Declined Calls: 2 TEST_TASK_ID_1/TEST_NCA_ID + 2 for TEST_TASK_ID_2/TEST_NCA_ID_2 + Arguments.of(createTaskOverrides(UUID_WILDCARD, 8L), + Collections.emptyMap(), + 16, + 4), + + // Set up default rate limiting policy for tasks with cap of 8 calls per second. + // Override the default cap for task TEST_TASK_ID_1 with 4 calls per second. + // + // Allowed Calls: 4 TEST_TASK_ID_1/TEST_NCA_ID + 8 for TEST_TASK_ID_2/TEST_NCA_ID_2 + // Declined Calls: 6 TEST_TASK_ID_1/TEST_NCA_ID + 2 for TEST_TASK_ID_2/TEST_NCA_ID_2 + Arguments.of(createTaskOverrides(UUID_WILDCARD, 8L), + Map.of(TEST_TASK_ID_1, createTaskOverrides(TEST_TASK_ID_1, 4L)), + 12, + 8) + ); + } + + @ParameterizedTest + @MethodSource("taskRateLimiterUseCases") + void verifyTaskRateLimit( + TaskRateCappingProperties defaultTaskProperties, + Map taskOverrideIds, + int expectedSuccess, + int expectedDecline) { + applyMocks(null, defaultTaskProperties, null, taskOverrideIds); + + AtomicInteger successful = new AtomicInteger(); + AtomicInteger declined = new AtomicInteger(); + IntStream.range(0, 10).parallel() + .forEach(i -> { + try { + service.verifyLimits(TEST_TASK_ID_1); + successful.incrementAndGet(); + } catch (TooManyRequestsException e) { + declined.incrementAndGet(); + } + try { + service.verifyLimits(TEST_TASK_ID_2); + successful.incrementAndGet(); + } catch (TooManyRequestsException e) { + declined.incrementAndGet(); + } + }); + assertThat(successful.get()).isEqualTo(expectedSuccess); + assertThat(declined.get()).isEqualTo(expectedDecline); + } + + private static Stream accountAndTaskRateLimiterUseCases() { + return Stream.of( + // Set up default rate limiting policy for accounts with cap of 10000 calls per sec. + // Set up default rate limiting policy for tasks with cap of 10000 calls per second. + // + // Allowed Calls: 10 TEST_TASK_ID_1/TEST_NCA_ID + 10 TEST_TASK_ID_2/TEST_NCA_ID_2 + // Declined Calls: 0 + Arguments.of(createAccountOverrides("*", 10000L), + createTaskOverrides(UUID_WILDCARD, 10000L), + Collections.emptyMap(), + Collections.emptyMap(), + 20, + 0), + + // Set up default rate limiting policy for accounts with cap of 10000 calls per sec. + // Set up default rate limiting policy for tasks with cap of 6 calls per second. + // + // Allowed Calls: 6 TEST_TASK_ID_1/TEST_NCA_ID + 6 for TEST_TASK_ID_2/TEST_NCA_ID_2 + // Declined Calls: 4 TEST_TASK_ID_1/TEST_NCA_ID + 4 for TEST_TASK_ID_2/TEST_NCA_ID_2 + Arguments.of(createAccountOverrides("*", 10000L), + createTaskOverrides(UUID_WILDCARD, 6L), + Collections.emptyMap(), + Collections.emptyMap(), + 12, + 8), + + // Set up default rate limiting policy for accounts with cap of 5 calls per second. + // Set up default rate limiting policy for tasks with cap of 8 calls per second. + // + // Allowed Calls: 5 TEST_TASK_ID_1/TEST_NCA_ID + 5 for TEST_TASK_ID_2/TEST_NCA_ID_2 + // Declined Calls: 5 TEST_TASK_ID_1/TEST_NCA_ID + 5 for TEST_TASK_ID_2/TEST_NCA_ID_2 + Arguments.of(createAccountOverrides("*", 5L), + createTaskOverrides(UUID_WILDCARD, 8L), + Collections.emptyMap(), + Collections.emptyMap(), + 10, + 10), + + // Set up default rate limiting policy for accounts with cap of 10 calls per second. + // Set up default rate limiting policy for tasks with cap of 10 calls per second. + // Override the default cap for account TEST_NCA_ID with 4 calls per second. + // Override the default cap for task TEST_TASK_ID_1 with 4 calls per second. + // + // Allowed Calls: 4 TEST_TASK_ID_1/TEST_NCA_ID + 10 for TEST_TASK_ID_2/TEST_NCA_ID_2 + // Declined Calls: 6 TEST_TASK_ID_1/TEST_NCA_ID + 0 for TEST_TASK_ID_2/TEST_NCA_ID_2 + Arguments.of(createAccountOverrides("*", 10L), + createTaskOverrides(UUID_WILDCARD, 10L), + Map.of(TEST_NCA_ID, createAccountOverrides(TEST_NCA_ID, 4L)), + Map.of(TEST_TASK_ID_1, createTaskOverrides(TEST_TASK_ID_1, 4L)), + 14, + 6) + ); + } + + @ParameterizedTest + @MethodSource("accountAndTaskRateLimiterUseCases") + void verifyAccountAndTaskRateLimit( + AccountRateCappingProperties defaultAccountProperties, + TaskRateCappingProperties defaultTaskProperties, + Map accountOverrideIds, + Map taskOverrideIds, + int expectedSuccess, + int expectedDecline) { + applyMocks(defaultAccountProperties, defaultTaskProperties, accountOverrideIds, + taskOverrideIds); + + AtomicInteger successful = new AtomicInteger(); + AtomicInteger declined = new AtomicInteger(); + IntStream.range(0, 10).parallel() + .forEach(i -> { + try { + service.verifyLimits(TEST_NCA_ID, TEST_TASK_ID_1); + successful.incrementAndGet(); + } catch (TooManyRequestsException e) { + declined.incrementAndGet(); + } + try { + service.verifyLimits(TEST_NCA_ID_2, TEST_TASK_ID_2); + successful.incrementAndGet(); + } catch (TooManyRequestsException e) { + declined.incrementAndGet(); + } + }); + assertThat(successful.get()).isEqualTo(expectedSuccess); + assertThat(declined.get()).isEqualTo(expectedDecline); + } + + @Test + void verifyAccountRateLimitWithFulfillment() { + applyMocks( + createAccountOverrides("*", 6), + createTaskOverrides(UUID_WILDCARD, 6), + Collections.emptyMap(), + Collections.emptyMap()); + + AtomicInteger successful = new AtomicInteger(); + AtomicInteger declined = new AtomicInteger(); + IntStream.range(0, 10).parallel() + .forEach(i -> { + try { + service.verifyLimits(TEST_NCA_ID); + successful.incrementAndGet(); + } catch (TooManyRequestsException e) { + declined.incrementAndGet(); + } + }); + + // Fulfil the buckets + // Thread.sleep(2000L) analog + await() + .pollDelay(Duration.ofSeconds(2)) + .untilAsserted(() -> assertThat(true).isTrue()); + + IntStream.range(0, 10).parallel() + .forEach(i -> { + try { + service.verifyLimits(TEST_NCA_ID); + successful.incrementAndGet(); + } catch (TooManyRequestsException e) { + declined.incrementAndGet(); + } + }); + assertThat(successful.get()).isEqualTo(12); + assertThat(declined.get()).isEqualTo(8); + } + + private static TaskRateCappingProperties createTaskOverrides( + UUID taskId, + long allowedInvocationsPerSecond) { + return TaskRateCappingProperties + .builder() + .taskId(taskId) + .allowedInvocationsPerSecond(allowedInvocationsPerSecond) + .build(); + } + + private static AccountRateCappingProperties createAccountOverrides( + String ncaId, + long allowedInvocationsPerSecond) { + return AccountRateCappingProperties + .builder() + .ncaId(ncaId) + .allowedInvocationsPerSecond(allowedInvocationsPerSecond) + .build(); + } + + private void applyMocks( + AccountRateCappingProperties defaultAccountProperties, + TaskRateCappingProperties defaultTaskProperties, + Map accountOverrideIds, + Map taskOverrideIds) { + lenient().when(accountProperties.getDefaultRateCappingProperties()) + .thenReturn(defaultAccountProperties); + lenient().when(taskProperties.getDefaultRateCappingProperties()) + .thenReturn(defaultTaskProperties); + lenient().when(accountProperties.getOverridesMap()).thenReturn(accountOverrideIds); + lenient().when(taskProperties.getTaskOverridesMap()).thenReturn(taskOverrideIds); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/service/registry/RegistryArtifactServiceTest.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/service/registry/RegistryArtifactServiceTest.java new file mode 100644 index 000000000..3db2c359d --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/service/registry/RegistryArtifactServiceTest.java @@ -0,0 +1,149 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.registry; + +import static com.nvidia.nvct.util.TestConstants.TEST_MODELS; +import static com.nvidia.nvct.util.TestConstants.TEST_MODELS_2; +import static com.nvidia.nvct.util.TestConstants.TEST_NCA_ID; +import static com.nvidia.nvct.util.TestConstants.TEST_NCA_ID_2; +import static com.nvidia.nvct.util.TestConstants.TEST_ICMS_REQ_ID_1; +import static com.nvidia.nvct.util.TestConstants.TEST_ICMS_REQ_ID_2; +import static com.nvidia.nvct.util.TestConstants.TEST_ICMS_REQ_ID_3; +import static com.nvidia.nvct.util.TestConstants.TEST_ICMS_REQ_ID_4; +import static com.nvidia.nvct.util.TestConstants.TEST_ICMS_REQ_ID_5; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_ID_1; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_ID_2; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_ID_3; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_ID_4; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_ID_5; +import static org.assertj.core.api.Assertions.assertThat; + +import com.nvidia.boot.mock.ngc.MockCasServer; +import com.nvidia.boot.mock.ngc.MockNgcContainerRegistryServer; +import com.nvidia.nvct.IntegrationTestConfiguration; +import com.nvidia.nvct.NvctTestApp; +import com.nvidia.nvct.grpc.TestTaskService; +import com.nvidia.nvct.util.MockNvcfServer; +import java.net.URL; +import java.util.UUID; +import java.util.stream.Stream; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ContextConfiguration; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@Slf4j +@SpringBootTest( + classes = {NvctTestApp.class, IntegrationTestConfiguration.class}, + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + properties = "spring.profiles.active=test") +@ContextConfiguration(initializers = IntegrationTestConfiguration.Initializer.class) +class RegistryArtifactServiceTest { + + @Autowired + private RegistryArtifactService registryArtifactService; + + @Autowired + private TestTaskService testTaskService; + + @Value("${nvct.registries.recognized.model.ngc.hostname}") + private String casBaseUrl; + + @Value("${nvct.registries.recognized.model.ngc.oauth2.base-url}") + private String authnBaseUrl; + + @Value("${nvct.registries.recognized.container.ngc.hostname}") + private String ngcContainerRegistryHostname; + + @Value("${nvct.nvcf.base-url}") + private URL nvcfBaseUrl; + + @BeforeAll + void beforeAll() { + log.info("{}: Started running tests", this.getClass().getSimpleName()); + MockCasServer.start(authnBaseUrl, casBaseUrl); + MockNgcContainerRegistryServer.start(ngcContainerRegistryHostname); + MockNvcfServer.start(nvcfBaseUrl); + } + + @AfterAll + void cleanup() { + MockCasServer.stop(); + MockNvcfServer.stop(); + MockNgcContainerRegistryServer.stop(); + log.info("{}: Completed running tests", this.getClass().getSimpleName()); + } + + @BeforeEach + void setup() { + testTaskService.createTask(TEST_NCA_ID, TEST_TASK_ID_1, TEST_ICMS_REQ_ID_1); + testTaskService.createTaskWithModel(TEST_NCA_ID, TEST_TASK_ID_2, TEST_ICMS_REQ_ID_2, + TEST_MODELS); + testTaskService.createTaskWithModel(TEST_NCA_ID, TEST_TASK_ID_3, TEST_ICMS_REQ_ID_3, + TEST_MODELS_2); + testTaskService.createTaskWithModelAndResources(TEST_NCA_ID_2, TEST_TASK_ID_4, + TEST_ICMS_REQ_ID_4); + testTaskService.createTaskWithResource(TEST_NCA_ID_2, TEST_TASK_ID_5, + TEST_ICMS_REQ_ID_5); + } + + @AfterEach + void afterEach() { + registryArtifactService.invalidateCache(); + testTaskService.clearAll(); + } + + Stream cacheHandleArgs() { + return Stream.of( + Arguments.of( + TEST_NCA_ID, + TEST_TASK_ID_1, + "e3b0c44298fc1c149afbf4c8996fb924"), + Arguments.of( + TEST_NCA_ID, + TEST_TASK_ID_2, + "a941b29b4d8cdea172401c82cd9cdcee"), + Arguments.of( + TEST_NCA_ID, + TEST_TASK_ID_3, + "a941b29b4d8cdea172401c82cd9cdcee"), + Arguments.of( + TEST_NCA_ID_2, + TEST_TASK_ID_4, + "da56d7b9f5b145646f32b571d19ae4bf"), + Arguments.of( + TEST_NCA_ID_2, + TEST_TASK_ID_5, + "a492d24950a022cebff9f6e6c9dad0f2")); + } + + @ParameterizedTest + @MethodSource("cacheHandleArgs") + void testCacheHandle(String ncaId, UUID taskId, String cacheHandle) { + assertThat(registryArtifactService.getCacheHandle(ncaId, taskId)).isEqualTo(cacheHandle); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/service/registry/RegistryArtifactValidationServiceTest.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/service/registry/RegistryArtifactValidationServiceTest.java new file mode 100644 index 000000000..5d5fafb00 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/service/registry/RegistryArtifactValidationServiceTest.java @@ -0,0 +1,444 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.registry; + +import static com.nvidia.boot.registries.service.registry.dto.ArtifactTypeEnum.CONTAINER; +import static com.nvidia.boot.registries.service.registry.dto.ArtifactTypeEnum.HELM; +import static com.nvidia.nvct.util.TestConstants.TEST_GFN_GPU_SPEC; +import static org.assertj.core.api.Assertions.assertThatCode; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyList; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoInteractions; +import static org.mockito.Mockito.when; + +import com.nvidia.boot.exceptions.BadRequestException; +import com.nvidia.boot.exceptions.NotFoundException; +import com.nvidia.boot.registries.service.registry.RegistryValidationService; +import com.nvidia.boot.registries.service.registry.container.ContainerRegistryService; +import com.nvidia.boot.registries.service.registry.helm.HelmRegistryService; +import com.nvidia.boot.registries.service.registry.model.ModelRegistryService; +import com.nvidia.boot.registries.service.registry.resource.ResourceRegistryService; +import com.nvidia.nvct.persistence.task.entity.TaskEntity; +import com.nvidia.nvct.persistence.task.entity.TaskStatus; +import com.nvidia.nvct.service.account.dto.RegistryCredentialDto; +import java.time.Duration; +import java.util.Collections; +import java.util.List; +import java.util.UUID; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +class RegistryArtifactValidationServiceTest { + + @Mock + private RegistryCredentialService registryCredentialService; + + @Mock + private RegistryValidationService registryValidationService; + + @Mock + private ModelRegistryService modelRegistryService; + + @Mock + private ResourceRegistryService resourceRegistryService; + + @Mock + private HelmRegistryService helmRegistryService; + + @Mock + private ContainerRegistryService containerRegistryService; + + private RegistryArtifactValidationService createService(String exceptionHandling) { + return new RegistryArtifactValidationService( + registryCredentialService, + registryValidationService, + modelRegistryService, + resourceRegistryService, + helmRegistryService, + containerRegistryService, + exceptionHandling); + } + + private static TaskEntity containerTask() { + return TaskEntity.builder() + .taskId(UUID.randomUUID()) + .ncaId("test-nca-id") + .name("test-task") + .status(TaskStatus.QUEUED) + .gpuSpec(TEST_GFN_GPU_SPEC) + .maxQueuedDuration(Duration.ofHours(1)) + .terminalGracePeriodDuration(Duration.ofHours(1)) + .containerImage("docker.io/library/nginx:latest") + .build(); + } + + private static TaskEntity helmTask() { + return TaskEntity.builder() + .taskId(UUID.randomUUID()) + .ncaId("test-nca-id") + .name("test-helm-task") + .status(TaskStatus.QUEUED) + .gpuSpec(TEST_GFN_GPU_SPEC) + .maxQueuedDuration(Duration.ofHours(1)) + .terminalGracePeriodDuration(Duration.ofHours(1)) + .helmChart("oci://registry.example.com/charts/mychart:1.0") + .build(); + } + + private static TaskEntity blankContainerTask() { + return TaskEntity.builder() + .taskId(UUID.randomUUID()) + .ncaId("test-nca-id") + .name("test-blank-task") + .status(TaskStatus.QUEUED) + .gpuSpec(TEST_GFN_GPU_SPEC) + .maxQueuedDuration(Duration.ofHours(1)) + .terminalGracePeriodDuration(Duration.ofHours(1)) + .build(); + } + + // --- validateArtifacts() top-level flow --- + + @Test + void shouldThrowWhenArtifactValidationFailsAndExceptionHandlingIsThrow() { + var service = createService("throw"); + var task = containerTask(); + + when(registryCredentialService.getContainerRegistryCredentials(any())) + .thenReturn(Collections.emptyList()); + when(registryCredentialService.getRegistryHostname("docker.io/library/nginx:latest")) + .thenReturn("docker.io"); + when(registryValidationService.isArtifactValidationEnabled(CONTAINER, "docker.io")) + .thenReturn(false); + when(registryCredentialService.getModelRegistryCredentials(any())) + .thenReturn(Collections.emptyMap()); + when(registryCredentialService.getResourceRegistryCredentials(any())) + .thenReturn(Collections.emptyMap()); + when(registryCredentialService.getContainerRegistryCredentialsValue(any())) + .thenReturn(Collections.emptyList()); + doThrow(new NotFoundException("Artifact not found")) + .when(containerRegistryService).validateArtifact(any(), anyList()); + + assertThatThrownBy(() -> service.validateArtifacts(task)) + .isInstanceOf(NotFoundException.class) + .hasMessageContaining("Artifact not found"); + } + + @Test + void shouldLogAndContinueWhenArtifactValidationFailsAndExceptionHandlingIsLog() { + var service = createService("log"); + var task = containerTask(); + + when(registryCredentialService.getContainerRegistryCredentials(any())) + .thenReturn(Collections.emptyList()); + when(registryCredentialService.getRegistryHostname("docker.io/library/nginx:latest")) + .thenReturn("docker.io"); + when(registryValidationService.isArtifactValidationEnabled(CONTAINER, "docker.io")) + .thenReturn(false); + when(registryCredentialService.getModelRegistryCredentials(any())) + .thenReturn(Collections.emptyMap()); + when(registryCredentialService.getResourceRegistryCredentials(any())) + .thenReturn(Collections.emptyMap()); + when(registryCredentialService.getContainerRegistryCredentialsValue(any())) + .thenReturn(Collections.emptyList()); + doThrow(new NotFoundException("Artifact not found")) + .when(containerRegistryService).validateArtifact(any(), anyList()); + + assertThatCode(() -> service.validateArtifacts(task)) + .doesNotThrowAnyException(); + } + + @Test + void shouldThrowBadRequestWhenCredentialExistenceFailsAndExceptionHandlingIsThrow() { + var service = createService("throw"); + var task = containerTask(); + + when(registryCredentialService.getContainerRegistryCredentials(any())) + .thenReturn(Collections.emptyList()); + when(registryCredentialService.getRegistryHostname("docker.io/library/nginx:latest")) + .thenReturn("docker.io"); + when(registryValidationService.isArtifactValidationEnabled(CONTAINER, "docker.io")) + .thenReturn(true); + + assertThatThrownBy(() -> service.validateArtifacts(task)) + .isInstanceOf(BadRequestException.class) + .hasMessageContaining("Missing CONTAINER registry credential for hostname 'docker.io'"); + } + + @Test + void shouldLogAndContinueWhenCredentialExistenceFailsAndExceptionHandlingIsLog() { + var service = createService("log"); + var task = containerTask(); + + when(registryCredentialService.getContainerRegistryCredentials(any())) + .thenReturn(Collections.emptyList()); + when(registryCredentialService.getRegistryHostname("docker.io/library/nginx:latest")) + .thenReturn("docker.io"); + when(registryValidationService.isArtifactValidationEnabled(CONTAINER, "docker.io")) + .thenReturn(true); + + assertThatCode(() -> service.validateArtifacts(task)) + .doesNotThrowAnyException(); + } + + @Test + void shouldSucceedWhenCredentialResolutionReturnsEmptyAndArtifactValidationDisabled() { + var service = createService("throw"); + var task = containerTask(); + + when(registryCredentialService.getContainerRegistryCredentials(any())) + .thenReturn(Collections.emptyList()); + when(registryCredentialService.getRegistryHostname("docker.io/library/nginx:latest")) + .thenReturn("docker.io"); + when(registryValidationService.isArtifactValidationEnabled(CONTAINER, "docker.io")) + .thenReturn(false); + when(registryCredentialService.getModelRegistryCredentials(any())) + .thenReturn(Collections.emptyMap()); + when(registryCredentialService.getResourceRegistryCredentials(any())) + .thenReturn(Collections.emptyMap()); + when(registryCredentialService.getContainerRegistryCredentialsValue(any())) + .thenReturn(Collections.emptyList()); + + assertThatCode(() -> service.validateArtifacts(task)) + .doesNotThrowAnyException(); + } + + // --- validateArtifacts() top-level flow with helm task --- + + @Test + void shouldThrowWhenHelmArtifactValidationFailsAndExceptionHandlingIsThrow() { + var service = createService("throw"); + var task = helmTask(); + + when(registryCredentialService.getHelmRegistryCredentials(any())) + .thenReturn(Collections.emptyList()); + when(registryCredentialService.getHelmRegistryHostname( + "oci://registry.example.com/charts/mychart:1.0")) + .thenReturn("registry.example.com"); + when(registryValidationService.isArtifactValidationEnabled(HELM, "registry.example.com")) + .thenReturn(false); + when(registryCredentialService.getModelRegistryCredentials(any())) + .thenReturn(Collections.emptyMap()); + when(registryCredentialService.getResourceRegistryCredentials(any())) + .thenReturn(Collections.emptyMap()); + when(registryCredentialService.getHelmRegistryCredentialsValue(any())) + .thenReturn(Collections.emptyList()); + doThrow(new NotFoundException("Helm chart not found")) + .when(helmRegistryService).validateArtifact(any(), anyList()); + + assertThatThrownBy(() -> service.validateArtifacts(task)) + .isInstanceOf(NotFoundException.class) + .hasMessageContaining("Helm chart not found"); + } + + @Test + void shouldLogAndContinueWhenHelmArtifactValidationFailsAndExceptionHandlingIsLog() { + var service = createService("log"); + var task = helmTask(); + + when(registryCredentialService.getHelmRegistryCredentials(any())) + .thenReturn(Collections.emptyList()); + when(registryCredentialService.getHelmRegistryHostname( + "oci://registry.example.com/charts/mychart:1.0")) + .thenReturn("registry.example.com"); + when(registryValidationService.isArtifactValidationEnabled(HELM, "registry.example.com")) + .thenReturn(false); + when(registryCredentialService.getModelRegistryCredentials(any())) + .thenReturn(Collections.emptyMap()); + when(registryCredentialService.getResourceRegistryCredentials(any())) + .thenReturn(Collections.emptyMap()); + when(registryCredentialService.getHelmRegistryCredentialsValue(any())) + .thenReturn(Collections.emptyList()); + doThrow(new NotFoundException("Helm chart not found")) + .when(helmRegistryService).validateArtifact(any(), anyList()); + + assertThatCode(() -> service.validateArtifacts(task)) + .doesNotThrowAnyException(); + } + + @Test + void shouldThrowBadRequestWhenHelmCredentialExistenceFailsAndExceptionHandlingIsThrow() { + var service = createService("throw"); + var task = helmTask(); + + when(registryCredentialService.getHelmRegistryCredentials(any())) + .thenReturn(Collections.emptyList()); + when(registryCredentialService.getHelmRegistryHostname( + "oci://registry.example.com/charts/mychart:1.0")) + .thenReturn("registry.example.com"); + when(registryValidationService.isArtifactValidationEnabled(HELM, "registry.example.com")) + .thenReturn(true); + + assertThatThrownBy(() -> service.validateArtifacts(task)) + .isInstanceOf(BadRequestException.class) + .hasMessageContaining( + "Missing HELM registry credential for hostname 'registry.example.com'"); + } + + @Test + void shouldLogAndContinueWhenHelmCredentialExistenceFailsAndExceptionHandlingIsLog() { + var service = createService("log"); + var task = helmTask(); + + when(registryCredentialService.getHelmRegistryCredentials(any())) + .thenReturn(Collections.emptyList()); + when(registryCredentialService.getHelmRegistryHostname( + "oci://registry.example.com/charts/mychart:1.0")) + .thenReturn("registry.example.com"); + when(registryValidationService.isArtifactValidationEnabled(HELM, "registry.example.com")) + .thenReturn(true); + + assertThatCode(() -> service.validateArtifacts(task)) + .doesNotThrowAnyException(); + } + + // --- validateContainerRegistryCredentialsExist() --- + + @Test + void validateContainerCredentialsShouldThrowWhenValidationEnabledAndCredentialsMissing() { + var service = createService("throw"); + var task = containerTask(); + + when(registryCredentialService.getContainerRegistryCredentials(any())) + .thenReturn(Collections.emptyList()); + when(registryCredentialService.getRegistryHostname("docker.io/library/nginx:latest")) + .thenReturn("docker.io"); + when(registryValidationService.isArtifactValidationEnabled(CONTAINER, "docker.io")) + .thenReturn(true); + + assertThatThrownBy(() -> service.validateContainerRegistryCredentialsExist(task)) + .isInstanceOf(IllegalStateException.class) + .hasMessageContaining("Missing CONTAINER registry credential for hostname 'docker.io'"); + } + + @Test + void validateContainerCredentialsShouldPassWhenValidationDisabledAndCredentialsMissing() { + var service = createService("throw"); + var task = containerTask(); + + when(registryCredentialService.getContainerRegistryCredentials(any())) + .thenReturn(Collections.emptyList()); + when(registryCredentialService.getRegistryHostname("docker.io/library/nginx:latest")) + .thenReturn("docker.io"); + when(registryValidationService.isArtifactValidationEnabled(CONTAINER, "docker.io")) + .thenReturn(false); + + assertThatCode(() -> service.validateContainerRegistryCredentialsExist(task)) + .doesNotThrowAnyException(); + } + + @Test + void validateContainerCredentialsShouldPassWhenCredentialsPresent() { + var service = createService("throw"); + var task = containerTask(); + + var cred = Mockito.mock(RegistryCredentialDto.class); + when(registryCredentialService.getContainerRegistryCredentials(any())) + .thenReturn(List.of(cred)); + when(registryCredentialService.getRegistryHostname("docker.io/library/nginx:latest")) + .thenReturn("docker.io"); + when(registryValidationService.isArtifactValidationEnabled(CONTAINER, "docker.io")) + .thenReturn(true); + + assertThatCode(() -> service.validateContainerRegistryCredentialsExist(task)) + .doesNotThrowAnyException(); + } + + @Test + void validateContainerCredentialsShouldSkipWhenContainerImageIsBlank() { + var service = createService("throw"); + var task = blankContainerTask(); + + assertThatCode(() -> service.validateContainerRegistryCredentialsExist(task)) + .doesNotThrowAnyException(); + verifyNoInteractions(registryCredentialService); + } + + // --- validateHelmRegistryCredentialsExist() --- + + @Test + void validateHelmCredentialsShouldThrowWhenValidationEnabledAndCredentialsMissing() { + var service = createService("throw"); + var task = helmTask(); + + when(registryCredentialService.getHelmRegistryCredentials(any())) + .thenReturn(Collections.emptyList()); + when(registryCredentialService.getHelmRegistryHostname( + "oci://registry.example.com/charts/mychart:1.0")) + .thenReturn("registry.example.com"); + when(registryValidationService.isArtifactValidationEnabled(HELM, "registry.example.com")) + .thenReturn(true); + + assertThatThrownBy(() -> service.validateHelmRegistryCredentialsExist(task)) + .isInstanceOf(IllegalStateException.class) + .hasMessageContaining( + "Missing HELM registry credential for hostname 'registry.example.com'"); + } + + @Test + void validateHelmCredentialsShouldPassWhenValidationDisabledAndCredentialsMissing() { + var service = createService("throw"); + var task = helmTask(); + + when(registryCredentialService.getHelmRegistryCredentials(any())) + .thenReturn(Collections.emptyList()); + when(registryCredentialService.getHelmRegistryHostname( + "oci://registry.example.com/charts/mychart:1.0")) + .thenReturn("registry.example.com"); + when(registryValidationService.isArtifactValidationEnabled(HELM, "registry.example.com")) + .thenReturn(false); + + assertThatCode(() -> service.validateHelmRegistryCredentialsExist(task)) + .doesNotThrowAnyException(); + } + + @Test + void validateHelmCredentialsShouldPassWhenCredentialsPresent() { + var service = createService("throw"); + var task = helmTask(); + + var cred = Mockito.mock(RegistryCredentialDto.class); + when(registryCredentialService.getHelmRegistryCredentials(any())) + .thenReturn(List.of(cred)); + when(registryCredentialService.getHelmRegistryHostname( + "oci://registry.example.com/charts/mychart:1.0")) + .thenReturn("registry.example.com"); + when(registryValidationService.isArtifactValidationEnabled(HELM, "registry.example.com")) + .thenReturn(true); + + assertThatCode(() -> service.validateHelmRegistryCredentialsExist(task)) + .doesNotThrowAnyException(); + } + + @Test + void validateHelmCredentialsShouldSkipWhenHelmChartIsBlank() { + var service = createService("throw"); + var task = containerTask(); + + assertThatCode(() -> service.validateHelmRegistryCredentialsExist(task)) + .doesNotThrowAnyException(); + verify(registryCredentialService, Mockito.never()) + .getHelmRegistryCredentials(any()); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/service/reval/RevalClientIntegrationTest.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/service/reval/RevalClientIntegrationTest.java new file mode 100644 index 000000000..a52a2268b --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/service/reval/RevalClientIntegrationTest.java @@ -0,0 +1,229 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.reval; + +import static com.nvidia.nvct.service.reval.RevalClient.CLIENT_REGISTRATION_ID; +import static com.nvidia.nvct.util.TestConstants.TEST_ACCOUNT_NAME; +import static com.nvidia.nvct.util.TestConstants.TEST_ARTIFACT_REGISTRY; +import static com.nvidia.nvct.util.TestConstants.TEST_CONTAINER_REGISTRY; +import static com.nvidia.nvct.util.TestConstants.TEST_DOCKER_CONTAINER_REGISTRY; +import static com.nvidia.nvct.util.TestConstants.TEST_HELM_REGISTRY; +import static com.nvidia.nvct.util.TestConstants.TEST_NCA_ID; +import static com.nvidia.nvct.util.TestConstants.TEST_NGC_CONTAINER_REGISTRY; +import static com.nvidia.nvct.util.TestConstants.TEST_NGC_HELM_REGISTRY; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_ID_1; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_NAME_1; +import static com.nvidia.nvct.util.TestUtil.createHelmBasedTaskEntity; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import com.nvidia.boot.mock.oauth2.MockOAuth2TokenServerInstanced; +import com.nvidia.boot.mock.oauth2.OAuth2TokenServerConfigurationProperties; +import com.nvidia.boot.registries.service.registry.RegistryMapperService; +import com.nvidia.nvct.configuration.staticclientauth.StaticClientAuthConfiguration; +import com.nvidia.nvct.persistence.task.entity.TaskEntity; +import com.nvidia.nvct.rest.task.dto.GpuSpecificationDto; +import com.nvidia.nvct.service.account.AccountService; +import com.nvidia.nvct.service.account.dto.AccountDto; +import com.nvidia.nvct.service.registry.RegistryArtifactValidationService; +import com.nvidia.nvct.service.registry.RegistryCredentialService; +import com.nvidia.nvct.service.registry.RegistryTaskMapperService; +import com.nvidia.nvct.util.MockRevalServer; +import com.nvidia.nvct.util.NvctOAuth2ClientUtils; +import com.nvidia.nvct.util.NvctOAuth2ClientUtils.ManagedHttpResources; +import io.micrometer.core.instrument.simple.SimpleMeterRegistry; +import java.net.URI; +import java.time.Instant; +import java.util.List; +import java.util.Optional; +import lombok.SneakyThrows; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.web.reactive.function.client.WebClient; +import tools.jackson.databind.json.JsonMapper; +import tools.jackson.databind.node.ObjectNode; + +class RevalClientIntegrationTest { + + private static final String REVAL_BASE_URL = "http://localhost:8085"; + private static final String OAUTH_BASE_URL = "http://localhost:8086"; + private static final String CLIENT_ID = "test-client-id"; + private static final String SECRET_ID = "test-secret-id"; + private static final String STATIC_TOKEN = "static-test-token"; + + private static final JsonMapper OBJECT_MAPPER = JsonMapper.builder().build(); + + private MockOAuth2TokenServerInstanced ssaMockServer; + private AccountService accountService; + private SimpleMeterRegistry meterRegistry; + private RegistryArtifactValidationService registryArtifactValidationService; + private RegistryCredentialService registryCredentialService; + private JsonMapper jsonMapper; + private ManagedHttpResources httpResources; + + @Value("${nvct.sidecars.image-pull-secret}") + private String sidecarImagePullSecret; + @Value("${nvct.sidecars.hostname}") + private String sidecarRegistryHostname; + + @SneakyThrows + @BeforeEach + void setUp() { + this.jsonMapper = JsonMapper.builder().build(); + this.httpResources = + NvctOAuth2ClientUtils.getClientHttpConnectorManaged(CLIENT_REGISTRATION_ID); + + // Start mock Reval server + MockRevalServer.start(new URI(REVAL_BASE_URL)); + + // Create real OAuth2TokenServerConfigurationProperties + OAuth2TokenServerConfigurationProperties ssaProperties = + new OAuth2TokenServerConfigurationProperties( + OAUTH_BASE_URL, // issuer + OAUTH_BASE_URL + "/.well-known/jwks.json", // keysetUrl + "ES256", // jwsAlgorithm + null, // serviceBindings + List.of(CLIENT_ID), // clientBindings + null // customBindings + ); + + // Start OAuth mock server + ssaMockServer = new MockOAuth2TokenServerInstanced(ssaProperties); + ssaMockServer.start(); + + // Mock account service + accountService = mock(AccountService.class); + AccountDto account = AccountDto.builder() + .ncaId(TEST_NCA_ID) + .name(TEST_ACCOUNT_NAME) + .registryCredentials(List.of(TEST_DOCKER_CONTAINER_REGISTRY, + TEST_NGC_CONTAINER_REGISTRY, + TEST_NGC_HELM_REGISTRY)) + .lastUpdatedAt(Instant.now()) + .maxTasksAllowed(1) + .build(); + when(accountService.getAccount(TEST_NCA_ID)).thenReturn(account); + RegistryMapperService registryMapperService = + new RegistryMapperService(TEST_CONTAINER_REGISTRY, TEST_ARTIFACT_REGISTRY, + TEST_HELM_REGISTRY); + RegistryTaskMapperService registryTaskMapperService = + new RegistryTaskMapperService(registryMapperService); + registryCredentialService = new RegistryCredentialService(accountService, + registryMapperService, + registryTaskMapperService, + jsonMapper, + sidecarImagePullSecret, + sidecarRegistryHostname); + registryArtifactValidationService = mock(RegistryArtifactValidationService.class); + this.meterRegistry = new SimpleMeterRegistry(); + } + + @AfterEach + void tearDown() { + MockRevalServer.stop(); + + if (ssaMockServer != null) { + ssaMockServer.stop(); + } + if (httpResources != null) { + httpResources.close(); + } + } + + @Test + void testAuthWithStaticToken() { + // Given + RevalClient revalClient = createRevalClientWithStaticToken(); + GpuSpecificationDto deploymentInfo = createDeploymentInfo(); + TaskEntity taskEntity = + createHelmBasedTaskEntity(TEST_TASK_ID_1, TEST_NCA_ID, TEST_TASK_NAME_1, + jsonMapper); + // When + revalClient.validate(TEST_NCA_ID, taskEntity, deploymentInfo); + + // Then + verify(accountService, times(2)).getAccount(TEST_NCA_ID); + } + + @Test + void testAuthWithOAuth() { + // Given + RevalClient revalClient = createRevalClientWithOAuth(); + GpuSpecificationDto deploymentInfo = createDeploymentInfo(); + TaskEntity taskEntity = + createHelmBasedTaskEntity(TEST_TASK_ID_1, TEST_NCA_ID, TEST_TASK_NAME_1, + jsonMapper); + // When + revalClient.validate(TEST_NCA_ID, taskEntity, deploymentInfo); + + // Then + // Successful call with OAuth authentication + verify(accountService, times(2)).getAccount(TEST_NCA_ID); + } + + private GpuSpecificationDto createDeploymentInfo() { + ObjectNode configuration = OBJECT_MAPPER.createObjectNode() + .put("replicas", 3) + .put("serviceAccountName", "nvct"); + + return GpuSpecificationDto.builder() + .gpu("T10") + .instanceType("g6.full") + .configuration(configuration) + .build(); + } + + private RevalClient createRevalClientWithStaticToken() { + StaticClientAuthConfiguration.StaticClientRevalProperties staticProperties = + new StaticClientAuthConfiguration.StaticClientRevalProperties(); + staticProperties.setToken(STATIC_TOKEN); + + return new RevalClient( + REVAL_BASE_URL, + true, + CLIENT_ID, + SECRET_ID, + "helmreval:validate", + OAUTH_BASE_URL + "/token", + Optional.of(staticProperties), + registryArtifactValidationService, + registryCredentialService, + httpResources, + WebClient.builder(), + jsonMapper); + } + + private RevalClient createRevalClientWithOAuth() { + return new RevalClient( + REVAL_BASE_URL, + true, + CLIENT_ID, + SECRET_ID, + "helmreval:validate", + OAUTH_BASE_URL + "/token", + Optional.empty(), + registryArtifactValidationService, + registryCredentialService, + httpResources, + WebClient.builder(), + jsonMapper); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/service/reval/RevalSerializationTest.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/service/reval/RevalSerializationTest.java new file mode 100644 index 000000000..606c8bdaa --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/service/reval/RevalSerializationTest.java @@ -0,0 +1,89 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.reval; + +import static org.assertj.core.api.Assertions.assertThat; + +import tools.jackson.databind.json.JsonMapper; +import tools.jackson.databind.SerializationFeature; +import com.nvidia.nvct.service.reval.RevalStubService.RevalValidateResponse; +import java.util.Arrays; +import java.util.List; +import lombok.SneakyThrows; +import org.junit.jupiter.api.Test; + +class RevalSerializationTest { + + @Test + @SneakyThrows + void testEmptyRequestSerialization() { + var jsonMapper = JsonMapper.builder().build(); + + var request = RevalStubService.RevalValidateRequest.builder().build(); + var json = jsonMapper.writeValueAsString(request); + var expectedJson = "{}"; + + assertThat(json).isEqualTo(expectedJson); + } + + @Test + @SneakyThrows + void testRequestSerialization() { + var jsonMapper = JsonMapper.builder() + .enable(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS) + .build(); + + var configuration = jsonMapper + .createObjectNode() + .put("key", "value") + .put("key2", 2); + + var request = RevalStubService.RevalValidateRequest.builder() + .configuration(configuration) + .helmChart("my_helm_chart") + .build(); + + var requestJson = jsonMapper.writeValueAsString(request); + var expectedJson = """ + {"helmChart":"my_helm_chart","configuration":{"key":"value","key2":2}}"""; + + assertThat(jsonMapper.readTree(requestJson)).isEqualTo(jsonMapper.readTree(expectedJson)); + } + + + @Test + @SneakyThrows + void testResponseDeserialization() { + var json = """ + { + "valid": true, + "validationErrors": ["Error 1","Error 2"], + "internalErrors": ["Internal Error 1"] + } + """; + + var jsonMapper = JsonMapper.builder().build(); + var validationResult = jsonMapper.readValue(json, RevalValidateResponse.class); + var expectedValidationResult = RevalValidateResponse.builder() + .valid(true) + .validationErrors(Arrays.asList("Error 1", "Error 2")) + .internalErrors(List.of("Internal Error 1")) + .build(); + + assertThat(validationResult).isEqualTo(expectedValidationResult); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/service/scheduler/CleanTerminalTasksRoutineTest.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/service/scheduler/CleanTerminalTasksRoutineTest.java new file mode 100644 index 000000000..32de3b125 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/service/scheduler/CleanTerminalTasksRoutineTest.java @@ -0,0 +1,223 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.scheduler; + +import static com.nvidia.nvct.persistence.task.entity.TaskStatus.COMPLETED; +import static com.nvidia.nvct.persistence.task.entity.TaskStatus.QUEUED; +import static com.nvidia.nvct.util.MockIcmsServer.InstancesState.NO_CAPACITY; +import static com.nvidia.nvct.util.TestConstants.TEST_NCA_ID; +import static com.nvidia.nvct.util.TestConstants.TEST_ICMS_REQ_ID_1; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_ID_1; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; + +import tools.jackson.databind.json.JsonMapper; +import com.nvidia.boot.exceptions.NotFoundException; +import com.nvidia.boot.mock.ngc.MockCasServer; +import com.nvidia.nvct.IntegrationTestConfiguration; +import com.nvidia.nvct.NvctTestApp; +import com.nvidia.nvct.grpc.TestTaskService; +import com.nvidia.nvct.persistence.task.TasksRepository; +import com.nvidia.nvct.service.event.EventService; +import com.nvidia.nvct.service.result.ResultService; +import com.nvidia.nvct.service.task.TaskService; +import com.nvidia.nvct.util.MockEssServer; +import com.nvidia.nvct.util.MockNvcfServer; +import com.nvidia.nvct.util.MockIcmsServer; +import java.net.URL; +import java.time.Duration; +import java.time.Instant; +import java.util.List; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ContextConfiguration; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@Slf4j +@SpringBootTest( + classes = {NvctTestApp.class, IntegrationTestConfiguration.class}, + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + properties = "spring.profiles.active=test") +@ContextConfiguration(initializers = IntegrationTestConfiguration.Initializer.class) +class CleanTerminalTasksRoutineTest { + + @Autowired + private JsonMapper jsonMapper; + + @Autowired + private CleanTerminalTasksRoutine cleanTerminalTasksRoutine; + + @Autowired + private TasksRepository tasksRepository; + + @Autowired + private TestTaskService testTaskService; + + @Autowired + private EventService eventService; + + @Autowired + private TaskService taskService; + + @Autowired + private ResultService resultService; + + @Value("${nvct.registries.recognized.model.ngc.hostname}") + private String casBaseUrl; + + @Value("${nvct.registries.recognized.model.ngc.oauth2.base-url}") + private String authnBaseUrl; + + @Value("${nvct.ess.base-url}") + private String essBaseUrl; + + @Value("${nvct.icms.base-url}") + private URL icmsBaseUrl; + + @Value("${nvct.nvcf.base-url}") + private URL nvcfBaseUrl; + + @BeforeAll + void beforeAll() { + log.info("{}: Started running tests", this.getClass().getSimpleName()); + MockNvcfServer.start(nvcfBaseUrl); + MockEssServer.start(essBaseUrl); + MockCasServer.start(authnBaseUrl, casBaseUrl); + } + + @AfterAll + void cleanup() { + MockNvcfServer.stop(); + MockIcmsServer.stop(); + MockCasServer.stop(); + MockEssServer.stop(); + log.info("{}: Completed running tests", this.getClass().getSimpleName()); + } + + @AfterEach + void reset() { + testTaskService.clearAll(); + } + + + @Test + @SneakyThrows + void testUnder7DaysTerminalTasksCleanup() { + var contexts = List.of(MockIcmsServer.IcmsRequestContext.builder() + .instanceState(NO_CAPACITY).build()); + MockIcmsServer.start(icmsBaseUrl, jsonMapper, contexts); + + testTaskService.createTask(TEST_NCA_ID, TEST_TASK_ID_1, TEST_ICMS_REQ_ID_1); + // set the last heartbeat to now and status to completed + taskService.updateTask(TEST_TASK_ID_1, Instant.now()); + taskService.updateTask(TEST_TASK_ID_1, COMPLETED); + var taskEntity = tasksRepository.findById(TEST_TASK_ID_1); + assertThat(taskEntity).isNotNull(); + var events = eventService.fetchEvents(TEST_NCA_ID, TEST_TASK_ID_1); + assertThat(events).isNotNull(); + var results = resultService.fetchResults(TEST_NCA_ID, TEST_TASK_ID_1); + assertThat(results).isNotNull(); + + cleanTerminalTasksRoutine.runUnchecked(); + + // Verify tasksRepository did not change + var updatedTask = taskService.fetchTask(TEST_TASK_ID_1); + assertThat(updatedTask).isEqualTo(taskEntity.get()); + + // Verify entry in the EventsByTaskRepository did not change + var updatedEvents = eventService.fetchEvents(TEST_NCA_ID, TEST_TASK_ID_1); + assertThat(events).isEqualTo(updatedEvents); + + // Verify entry in the ResultsByTaskRepository did not change + var updatedResults = resultService.fetchResults(TEST_NCA_ID, TEST_TASK_ID_1); + assertThat(updatedResults).isEqualTo(results); + } + + @Test + @SneakyThrows + void testQueuedTasksCleanup() { + var contexts = List.of(MockIcmsServer.IcmsRequestContext.builder() + .instanceState(NO_CAPACITY).build()); + MockIcmsServer.start(icmsBaseUrl, jsonMapper, contexts); + + testTaskService.createTask(TEST_NCA_ID, TEST_TASK_ID_1, TEST_ICMS_REQ_ID_1); + // set the last heartbeat to more than 7 days ago and status to non-terminal such as queued + taskService.updateTask(TEST_TASK_ID_1, Instant.now().minus(Duration.ofDays(8))); + taskService.updateTask(TEST_TASK_ID_1, QUEUED); + var taskEntity = tasksRepository.findById(TEST_TASK_ID_1); + assertThat(taskEntity).isNotNull(); + var events = eventService.fetchEvents(TEST_NCA_ID, TEST_TASK_ID_1); + assertThat(events).isNotNull(); + var results = resultService.fetchResults(TEST_NCA_ID, TEST_TASK_ID_1); + assertThat(results).isNotNull(); + + cleanTerminalTasksRoutine.runUnchecked(); + + // Verify tasksRepository did not change + var updatedTask = taskService.fetchTask(TEST_TASK_ID_1); + assertThat(updatedTask).isEqualTo(taskEntity.get()); + + // Verify entry in the EventsByTaskRepository did not change + var updatedEvents = eventService.fetchEvents(TEST_NCA_ID, TEST_TASK_ID_1); + assertThat(events).isEqualTo(updatedEvents); + + // Verify entry in the ResultsByTaskRepository did not change + var updatedResults = resultService.fetchResults(TEST_NCA_ID, TEST_TASK_ID_1); + assertThat(updatedResults).isEqualTo(results); + } + + @Test + @SneakyThrows + void testTerminalTasksCleanup() { + var contexts = List.of(MockIcmsServer.IcmsRequestContext.builder() + .instanceState(NO_CAPACITY).build()); + MockIcmsServer.start(icmsBaseUrl, jsonMapper, contexts); + + testTaskService.createTask(TEST_NCA_ID, TEST_TASK_ID_1, TEST_ICMS_REQ_ID_1); + // set the last heartbeat to more than 7 days ago and status to terminal such as completed + taskService.updateTask(TEST_TASK_ID_1, Instant.now().minus(Duration.ofDays(8))); + taskService.updateTask(TEST_TASK_ID_1, COMPLETED); + var taskEntity = tasksRepository.findById(TEST_TASK_ID_1); + assertThat(taskEntity).isNotNull(); + var events = eventService.fetchEvents(TEST_NCA_ID, TEST_TASK_ID_1); + assertThat(events).isNotNull(); + var results = resultService.fetchResults(TEST_NCA_ID, TEST_TASK_ID_1); + assertThat(results).isNotNull(); + + cleanTerminalTasksRoutine.runUnchecked(); + + // Verify tasksRepository does not have the task anymore + assertThatExceptionOfType(NotFoundException.class).isThrownBy( + () -> taskService.fetchTask(TEST_TASK_ID_1)); + + // Verify entry in the EventsByTaskRepository does not exist + assertThatExceptionOfType(NotFoundException.class).isThrownBy( + () -> eventService.fetchEvents(TEST_NCA_ID, TEST_TASK_ID_1)); + + // Verify entry in the results does not exist + assertThatExceptionOfType(NotFoundException.class).isThrownBy( + () -> resultService.fetchResults(TEST_NCA_ID, TEST_TASK_ID_1)); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/service/scheduler/MonitorLaunchedTasksRoutineTest.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/service/scheduler/MonitorLaunchedTasksRoutineTest.java new file mode 100644 index 000000000..a713e2d36 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/service/scheduler/MonitorLaunchedTasksRoutineTest.java @@ -0,0 +1,222 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.scheduler; + +import static com.nvidia.nvct.persistence.task.entity.TaskStatus.ERRORED; +import static com.nvidia.nvct.persistence.task.entity.TaskStatus.LAUNCHED; +import static com.nvidia.nvct.persistence.task.entity.TaskStatus.RUNNING; +import static com.nvidia.nvct.util.MockIcmsServer.InstancesState.NO_CAPACITY; +import static com.nvidia.nvct.util.TestConstants.TEST_NCA_ID; +import static com.nvidia.nvct.util.TestConstants.TEST_ICMS_REQ_ID_1; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_ID_1; +import static org.assertj.core.api.Assertions.assertThat; + +import tools.jackson.databind.json.JsonMapper; +import com.nvidia.boot.mock.ngc.MockCasServer; +import com.nvidia.nvct.IntegrationTestConfiguration; +import com.nvidia.nvct.NvctTestApp; +import com.nvidia.nvct.grpc.TestTaskService; +import com.nvidia.nvct.persistence.task.TasksRepository; +import com.nvidia.nvct.service.event.EventService; +import com.nvidia.nvct.service.task.TaskMapperService; +import com.nvidia.nvct.service.task.TaskService; +import com.nvidia.nvct.util.MockNvcfServer; +import com.nvidia.nvct.util.MockIcmsServer; +import java.net.URL; +import java.time.Duration; +import java.time.Instant; +import java.util.List; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ContextConfiguration; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@Slf4j +@SpringBootTest( + classes = {NvctTestApp.class, IntegrationTestConfiguration.class}, + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + properties = "spring.profiles.active=test") +@ContextConfiguration(initializers = IntegrationTestConfiguration.Initializer.class) +class MonitorLaunchedTasksRoutineTest { + + @Autowired + private JsonMapper jsonMapper; + + @Autowired + private MonitorLaunchedTasksRoutine monitorLaunchedTasksRoutine; + + @Autowired + private TasksRepository tasksRepository; + + @Autowired + private TestTaskService testTaskService; + + @Autowired + private EventService eventService; + + @Autowired + private TaskService taskService; + + @Autowired + private TaskMapperService taskMapperService; + + @Value("${nvct.registries.recognized.model.ngc.hostname}") + private String casBaseUrl; + + @Value("${nvct.registries.recognized.model.ngc.oauth2.base-url}") + private String authnBaseUrl; + + @Value("${nvct.icms.base-url}") + private URL icmsBaseUrl; + + @Value("${nvct.nvcf.base-url}") + private URL nvcfBaseUrl; + + @BeforeAll + void beforeAll() { + log.info("{}: Started running tests", this.getClass().getSimpleName()); + MockNvcfServer.start(nvcfBaseUrl); + MockCasServer.start(authnBaseUrl, casBaseUrl); + monitorLaunchedTasksRoutine.setEnabled(true); + } + + @AfterAll + void cleanup() { + MockNvcfServer.stop(); + MockIcmsServer.stop(); + MockCasServer.stop(); + monitorLaunchedTasksRoutine.setEnabled(false); + log.info("{}: Completed running tests", this.getClass().getSimpleName()); + } + + @AfterEach + void reset() { + testTaskService.clearAll(); + } + + @Test + @SneakyThrows + void testNonLaunchedTaskRun() { + MockIcmsServer.start(icmsBaseUrl, jsonMapper); + testTaskService.createTask(TEST_NCA_ID, TEST_TASK_ID_1, TEST_ICMS_REQ_ID_1); + // explicitly set task status to anything other than LAUNCHED + taskService.updateTask(TEST_TASK_ID_1, RUNNING); + var taskEntity = tasksRepository.findById(TEST_TASK_ID_1); + assertThat(taskEntity).isNotNull(); + var events = eventService.fetchEvents(TEST_NCA_ID, TEST_TASK_ID_1); + + monitorLaunchedTasksRoutine.runUnchecked(Instant.now()); + + // Verify task entity did not change + var updatedTaskEntity = tasksRepository.findById(TEST_TASK_ID_1); + assertThat(updatedTaskEntity).isEqualTo(taskEntity); + + // Verify entry in the EventsByTaskRepository did not change + var updatedEvents = eventService.fetchEvents(TEST_NCA_ID, TEST_TASK_ID_1); + assertThat(events).isEqualTo(updatedEvents); + } + + + @Test + @SneakyThrows + void testNoCapacityRun() { + var contexts = List.of(MockIcmsServer.IcmsRequestContext.builder(). + instanceState(NO_CAPACITY).build()); + MockIcmsServer.start(icmsBaseUrl, jsonMapper, contexts); + + testTaskService.createTask(TEST_NCA_ID, TEST_TASK_ID_1, TEST_ICMS_REQ_ID_1); + tasksRepository.findById(TEST_TASK_ID_1); + // make sure current task status is LAUNCHED + var taskEntity = taskService.updateTask(TEST_TASK_ID_1, LAUNCHED); + + // Fake time for testing purposes. + monitorLaunchedTasksRoutine.runUnchecked(Instant.now().plus(Duration.ofMinutes(100))); + + // Verify health and status of task is updated + var updatedTask = taskService.fetchTask(TEST_TASK_ID_1); + var healthInfo = taskMapperService.deserializeHealth(updatedTask.getHealth()) + .orElseThrow(); + assertThat(healthInfo).isNotNull(); + var expectedErrorLog = "Instance terminated due to to capacity constraint"; + assertThat(healthInfo.error()).contains(expectedErrorLog); + assertThat(updatedTask.getStatus()).isEqualTo(ERRORED); + + // Verify entry in the EventsByTaskRepository is updated + var events = eventService.fetchEvents(TEST_NCA_ID, TEST_TASK_ID_1); + assertThat(events).isNotNull(); + assertThat(events.getLast().message()).contains(expectedErrorLog); + } + + @Test + @SneakyThrows + void testNoCapacityButNotTimedOutRun() { + var contexts = List.of(MockIcmsServer.IcmsRequestContext.builder() + .instanceState(NO_CAPACITY).build()); + MockIcmsServer.start(icmsBaseUrl, jsonMapper, contexts); + + testTaskService.createTask(TEST_NCA_ID, TEST_TASK_ID_1, TEST_ICMS_REQ_ID_1); + var taskEntity = tasksRepository.findById(TEST_TASK_ID_1); + assertThat(taskEntity).isNotNull(); + // make sure current task status is LAUNCHED + taskService.updateTask(TEST_TASK_ID_1, LAUNCHED); + taskEntity = tasksRepository.findById(TEST_TASK_ID_1); + var events = eventService.fetchEvents(TEST_NCA_ID, TEST_TASK_ID_1); + + monitorLaunchedTasksRoutine.runUnchecked(Instant.now()); + + // Verify task entity did not change + var updatedTaskEntity = tasksRepository.findById(TEST_TASK_ID_1); + assertThat(updatedTaskEntity).isEqualTo(taskEntity); + + // Verify entry in the EventsByTaskRepository did not change + var updatedEvents = eventService.fetchEvents(TEST_NCA_ID, TEST_TASK_ID_1); + assertThat(events).isEqualTo(updatedEvents); + } + + @Test + @SneakyThrows + void testHasCapacityRun() { + MockIcmsServer.start(icmsBaseUrl, jsonMapper); + + testTaskService.createTask(TEST_NCA_ID, TEST_TASK_ID_1, TEST_ICMS_REQ_ID_1); + var taskEntity = tasksRepository.findById(TEST_TASK_ID_1); + assertThat(taskEntity).isNotNull(); + + // make sure current task status is LAUNCHED + taskService.updateTask(TEST_TASK_ID_1, LAUNCHED); + taskEntity = tasksRepository.findById(TEST_TASK_ID_1); + var events = eventService.fetchEvents(TEST_NCA_ID, TEST_TASK_ID_1); + + monitorLaunchedTasksRoutine.runUnchecked(Instant.now()); + + // Verify task entity did not change + var updatedTaskEntity = tasksRepository.findById(TEST_TASK_ID_1); + assertThat(updatedTaskEntity).isEqualTo(taskEntity); + + // Verify entry in the EventsByTaskRepository did not change + var updatedEvents = eventService.fetchEvents(TEST_NCA_ID, TEST_TASK_ID_1); + assertThat(events).isEqualTo(updatedEvents); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/service/scheduler/MonitorQueuedTasksRoutineTest.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/service/scheduler/MonitorQueuedTasksRoutineTest.java new file mode 100644 index 000000000..50eef30c8 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/service/scheduler/MonitorQueuedTasksRoutineTest.java @@ -0,0 +1,279 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.scheduler; + +import static com.nvidia.nvct.persistence.task.entity.TaskStatus.ERRORED; +import static com.nvidia.nvct.persistence.task.entity.TaskStatus.EXCEEDED_MAX_QUEUED_DURATION; +import static com.nvidia.nvct.persistence.task.entity.TaskStatus.QUEUED; +import static com.nvidia.nvct.persistence.task.entity.TaskStatus.RUNNING; +import static com.nvidia.nvct.util.MockIcmsServer.InstancesState.NO_CAPACITY; +import static com.nvidia.nvct.util.TestConstants.TEST_ICMS_REQ_ID_1; +import static com.nvidia.nvct.util.TestConstants.TEST_NCA_ID; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_ID_1; +import static org.assertj.core.api.Assertions.assertThat; + +import com.nvidia.boot.mock.ngc.MockCasServer; +import com.nvidia.nvct.IntegrationTestConfiguration; +import com.nvidia.nvct.NvctTestApp; +import com.nvidia.nvct.grpc.TestTaskService; +import com.nvidia.nvct.persistence.task.TasksRepository; +import com.nvidia.nvct.service.event.EventService; +import com.nvidia.nvct.service.task.TaskMapperService; +import com.nvidia.nvct.service.task.TaskService; +import com.nvidia.nvct.util.MockIcmsServer; +import com.nvidia.nvct.util.MockNvcfServer; +import java.net.URL; +import java.time.Duration; +import java.time.Instant; +import java.util.List; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ContextConfiguration; +import tools.jackson.databind.json.JsonMapper; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@Slf4j +@SpringBootTest( + classes = {NvctTestApp.class, IntegrationTestConfiguration.class}, + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + properties = "spring.profiles.active=test") +@ContextConfiguration(initializers = IntegrationTestConfiguration.Initializer.class) +class MonitorQueuedTasksRoutineTest { + + @Autowired + private JsonMapper jsonMapper; + + @Autowired + private MonitorQueuedTasksRoutine monitorQueuedTasksRoutine; + + @Autowired + private TasksRepository tasksRepository; + + @Autowired + private TestTaskService testTaskService; + + @Autowired + private EventService eventService; + + @Autowired + private TaskService taskService; + + @Autowired + private TaskMapperService taskMapperService; + + @Value("${nvct.registries.recognized.model.ngc.hostname}") + private String casBaseUrl; + + @Value("${nvct.registries.recognized.model.ngc.oauth2.base-url}") + private String authnBaseUrl; + + @Value("${nvct.icms.base-url}") + private URL icmsBaseUrl; + + @Value("${nvct.nvcf.base-url}") + private URL nvcfBaseUrl; + + @BeforeAll + void beforeAll() { + log.info("{}: Started running tests", this.getClass().getSimpleName()); + MockNvcfServer.start(nvcfBaseUrl); + MockCasServer.start(authnBaseUrl, casBaseUrl); + } + + @AfterAll + void cleanup() { + MockNvcfServer.stop(); + MockIcmsServer.stop(); + MockCasServer.stop(); + log.info("{}: Completed running tests", this.getClass().getSimpleName()); + } + + @AfterEach + void reset() { + testTaskService.clearAll(); + } + + @Test + @SneakyThrows + void testNonQueuedTaskRun() { + MockIcmsServer.start(icmsBaseUrl, jsonMapper); + testTaskService.createTask(TEST_NCA_ID, TEST_TASK_ID_1, TEST_ICMS_REQ_ID_1); + taskService.updateTask(TEST_TASK_ID_1, RUNNING); + var taskEntity = tasksRepository.findById(TEST_TASK_ID_1); + assertThat(taskEntity).isNotNull(); + var events = eventService.fetchEvents(TEST_NCA_ID, TEST_TASK_ID_1); + + monitorQueuedTasksRoutine.runUnchecked(); + + // Verify task entity did not change + var updatedTaskEntity = tasksRepository.findById(TEST_TASK_ID_1); + assertThat(updatedTaskEntity).isEqualTo(taskEntity); + + // Verify entry in the EventsByTaskRepository did not change + var updatedEvents = eventService.fetchEvents(TEST_NCA_ID, TEST_TASK_ID_1); + assertThat(events).isEqualTo(updatedEvents); + } + + + @Test + @SneakyThrows + void testNoCapacityRun() { + var contexts = List.of(MockIcmsServer.IcmsRequestContext.builder() + .instanceState(NO_CAPACITY) + .createTime(Instant.now().minus(Duration.ofMinutes(100)) + .toString()) + .build()); + MockIcmsServer.start(icmsBaseUrl, jsonMapper, contexts); + + testTaskService.createTask(TEST_NCA_ID, TEST_TASK_ID_1, TEST_ICMS_REQ_ID_1); + var taskEntity = tasksRepository.findById(TEST_TASK_ID_1); + assertThat(taskEntity).isNotNull(); + + monitorQueuedTasksRoutine.runUnchecked(); + + // Verify health and status of task is updated + var updatedTask = taskService.fetchTask(TEST_TASK_ID_1); + var healthInfo = taskMapperService.deserializeHealth(updatedTask.getHealth()) + .orElseThrow(); + assertThat(healthInfo).isNotNull(); + + var expectedErrorLog = "Instance terminated due to to capacity constraint"; + assertThat(healthInfo.error()).contains(expectedErrorLog); + assertThat(updatedTask.getStatus()).isEqualTo(EXCEEDED_MAX_QUEUED_DURATION); + + // Verify entry in the EventsByTaskRepository is updated + var events = eventService.fetchEvents(TEST_NCA_ID, TEST_TASK_ID_1); + assertThat(events).isNotNull(); + assertThat(events.getLast().message()).contains(expectedErrorLog); + } + + @Test + @SneakyThrows + void testNoCapacityButNotTimedOutRun() { + var contexts = List.of(MockIcmsServer.IcmsRequestContext.builder() + .instanceState(NO_CAPACITY).build()); + MockIcmsServer.start(icmsBaseUrl, jsonMapper, contexts); + + testTaskService.createTask(TEST_NCA_ID, TEST_TASK_ID_1, TEST_ICMS_REQ_ID_1); + var taskEntity = tasksRepository.findById(TEST_TASK_ID_1); + assertThat(taskEntity).isPresent(); + assertThat(taskEntity.get().getStatus()).isEqualTo(QUEUED); + assertThat(taskEntity.get().getHealth()).isNull(); + var events = eventService.fetchEvents(TEST_NCA_ID, TEST_TASK_ID_1); + assertThat(events).isEmpty(); + + monitorQueuedTasksRoutine.runUnchecked(); + + // Verify task entity did not change + var updatedTaskEntity = tasksRepository.findById(TEST_TASK_ID_1); + assertThat(updatedTaskEntity).isPresent(); + assertThat(updatedTaskEntity.get().getStatus()).isEqualTo(ERRORED); + assertThat(updatedTaskEntity.get().getHealth()).isNotNull(); + assertThat(taskMapperService.deserializeHealth(updatedTaskEntity.get().getHealth()) + .orElseThrow() + .error()).isNotBlank(); + + // Verify an event has been raised for the status change. + var updatedEvents = eventService.fetchEvents(TEST_NCA_ID, TEST_TASK_ID_1); + assertThat(updatedEvents).hasSize(1); + } + + @Test + @SneakyThrows + void testHasCapacityRun() { + MockIcmsServer.start(icmsBaseUrl, jsonMapper); + testTaskService.createTask(TEST_NCA_ID, TEST_TASK_ID_1, TEST_ICMS_REQ_ID_1); + var taskEntity = tasksRepository.findById(TEST_TASK_ID_1); + assertThat(taskEntity).isNotNull(); + var events = eventService.fetchEvents(TEST_NCA_ID, TEST_TASK_ID_1); + + monitorQueuedTasksRoutine.runUnchecked(); + + // Verify task entity did not change + var updatedTaskEntity = tasksRepository.findById(TEST_TASK_ID_1); + assertThat(updatedTaskEntity).isEqualTo(taskEntity); + + // Verify entry in the EventsByTaskRepository did not change + var updatedEvents = eventService.fetchEvents(TEST_NCA_ID, TEST_TASK_ID_1); + assertThat(events).isEqualTo(updatedEvents); + } + + @Test + @SneakyThrows + void testExceededMaxQueuedDurationRun() { + var contexts = List.of(MockIcmsServer.IcmsRequestContext.builder() + .instanceState(MockIcmsServer.InstancesState.HEALTHY) + .createTime(Instant.now().minus(Duration.ofHours(10)) + .toString()) + .build()); + MockIcmsServer.start(icmsBaseUrl, jsonMapper, contexts); + + // Create a task with createdAt date 10 hours earlier + testTaskService.createTask(TEST_NCA_ID, + TEST_TASK_ID_1, + TEST_ICMS_REQ_ID_1, + Instant.now().minus(Duration.ofHours(10))); + var taskEntity = tasksRepository.findById(TEST_TASK_ID_1); + assertThat(taskEntity).isNotNull(); + + monitorQueuedTasksRoutine.runUnchecked(); + + // Verify task status is updated + var updatedTask = taskService.fetchTask(TEST_TASK_ID_1); + assertThat(updatedTask.getStatus()).isEqualTo(EXCEEDED_MAX_QUEUED_DURATION); + + // Verify entry in the EventsByTaskRepository is updated + var events = eventService.fetchEvents(TEST_NCA_ID, TEST_TASK_ID_1); + var expectedErrorLog = + "Changing status from 'QUEUED' to 'EXCEEDED_MAX_QUEUED_DURATION' with error"; + assertThat(events).isNotNull(); + assertThat(events.getLast().message()).contains(expectedErrorLog); + } + + @Test + @SneakyThrows + void testNonExceededMaxQueuedDurationRun() { + MockIcmsServer.start(icmsBaseUrl, jsonMapper); + // Create a task with createdAt date 1 min earlier + testTaskService.createTask(TEST_NCA_ID, + TEST_TASK_ID_1, + TEST_ICMS_REQ_ID_1, + Instant.now().minus(Duration.ofMinutes(1))); + var taskEntity = tasksRepository.findById(TEST_TASK_ID_1); + assertThat(taskEntity).isNotNull(); + var events = eventService.fetchEvents(TEST_NCA_ID, TEST_TASK_ID_1); + + monitorQueuedTasksRoutine.runUnchecked(); + + // Verify task entity did not change + var updatedTaskEntity = tasksRepository.findById(TEST_TASK_ID_1); + assertThat(updatedTaskEntity).isEqualTo(taskEntity); + + // Verify entry in the EventsByTaskRepository did not change + var updatedEvents = eventService.fetchEvents(TEST_NCA_ID, TEST_TASK_ID_1); + assertThat(events).isEqualTo(updatedEvents); + } + +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/service/scheduler/MonitorWorkerHeartbeatRoutineTest.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/service/scheduler/MonitorWorkerHeartbeatRoutineTest.java new file mode 100644 index 000000000..ef55cd3b2 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/service/scheduler/MonitorWorkerHeartbeatRoutineTest.java @@ -0,0 +1,284 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.scheduler; + +import static com.nvidia.nvct.persistence.task.entity.TaskStatus.CANCELED; +import static com.nvidia.nvct.persistence.task.entity.TaskStatus.COMPLETED; +import static com.nvidia.nvct.persistence.task.entity.TaskStatus.ERRORED; +import static com.nvidia.nvct.persistence.task.entity.TaskStatus.LAUNCHED; +import static com.nvidia.nvct.persistence.task.entity.TaskStatus.QUEUED; +import static com.nvidia.nvct.persistence.task.entity.TaskStatus.RUNNING; +import static com.nvidia.nvct.service.event.EventService.STATUS_CHANGE_EVENT_MESSAGE; +import static com.nvidia.nvct.util.MockIcmsServer.InstancesState.NO_CAPACITY; +import static com.nvidia.nvct.util.TestConstants.EVENT_ID_1; +import static com.nvidia.nvct.util.TestConstants.EVENT_ID_2; +import static com.nvidia.nvct.util.TestConstants.EVENT_ID_3; +import static com.nvidia.nvct.util.TestConstants.TEST_ICMS_REQ_ID_1; +import static com.nvidia.nvct.util.TestConstants.TEST_NCA_ID; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_ID_1; +import static org.assertj.core.api.Assertions.assertThat; + +import com.nvidia.boot.mock.ngc.MockCasServer; +import com.nvidia.nvct.IntegrationTestConfiguration; +import com.nvidia.nvct.NvctTestApp; +import com.nvidia.nvct.grpc.TestTaskService; +import com.nvidia.nvct.persistence.task.TasksRepository; +import com.nvidia.nvct.persistence.task.entity.TaskStatus; +import com.nvidia.nvct.rest.event.TestEventService; +import com.nvidia.nvct.service.event.EventService; +import com.nvidia.nvct.service.icms.IcmsService; +import com.nvidia.nvct.service.task.TaskMapperService; +import com.nvidia.nvct.service.task.TaskService; +import com.nvidia.nvct.util.MockIcmsServer; +import com.nvidia.nvct.util.MockNvcfServer; +import java.net.URL; +import java.time.Duration; +import java.time.Instant; +import java.util.List; +import java.util.stream.Stream; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ContextConfiguration; +import tools.jackson.databind.json.JsonMapper; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@Slf4j +@SpringBootTest( + classes = {NvctTestApp.class, IntegrationTestConfiguration.class}, + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + properties = "spring.profiles.active=test") +@ContextConfiguration(initializers = IntegrationTestConfiguration.Initializer.class) +class MonitorWorkerHeartbeatRoutineTest { + + @Autowired + private JsonMapper jsonMapper; + + @Autowired + private MonitorWorkerHeartbeatRoutine monitorWorkerHeartbeatRoutine; + + @Autowired + private TasksRepository tasksRepository; + + @Autowired + private TestTaskService testTaskService; + + @Autowired + private TestEventService testEventService; + + @Autowired + private EventService eventService; + + @Autowired + private TaskService taskService; + + @Autowired + private IcmsService icmsService; + + @Autowired + private TaskMapperService taskMapperService; + + @Value("${nvct.registries.recognized.model.ngc.hostname}") + private String casBaseUrl; + + @Value("${nvct.registries.recognized.model.ngc.oauth2.base-url}") + private String authnBaseUrl; + + @Value("${nvct.icms.base-url}") + private URL icmsBaseUrl; + + @Value("${nvct.nvcf.base-url}") + private URL nvcfBaseUrl; + + @BeforeAll + void beforeAll() { + log.info("{}: Started running tests", this.getClass().getSimpleName()); + MockNvcfServer.start(nvcfBaseUrl); + MockCasServer.start(authnBaseUrl, casBaseUrl); + } + + @AfterAll + void cleanup() { + MockNvcfServer.stop(); + MockIcmsServer.stop(); + MockCasServer.stop(); + log.info("{}: Completed running tests", this.getClass().getSimpleName()); + } + + @AfterEach + void reset() { + testTaskService.clearAll(); + } + + @Test + @SneakyThrows + void testNonRunningTaskRun() { + MockIcmsServer.start(icmsBaseUrl, jsonMapper); + testTaskService.createTask(TEST_NCA_ID, TEST_TASK_ID_1, TEST_ICMS_REQ_ID_1); + + // Explicitly set the task status to non-running such as launched, so that background + // thread won't monitor it. + taskService.updateTask(TEST_TASK_ID_1, LAUNCHED); + var taskEntity = tasksRepository.findById(TEST_TASK_ID_1); + assertThat(taskEntity).isNotNull(); + var events = eventService.fetchEvents(TEST_NCA_ID, TEST_TASK_ID_1); + + monitorWorkerHeartbeatRoutine.runUnchecked(); + + // Verify task entity did not change + var updatedTaskEntity = tasksRepository.findById(TEST_TASK_ID_1); + assertThat(updatedTaskEntity).isEqualTo(taskEntity); + + // Verify entry in the EventsByTaskRepository did not change. + var updatedEvents = eventService.fetchEvents(TEST_NCA_ID, TEST_TASK_ID_1); + assertThat(events).isEqualTo(updatedEvents); + } + + @Test + @SneakyThrows + void testNoHeartbeatRun() { + var contexts = List.of(MockIcmsServer.IcmsRequestContext.builder() + .instanceState(NO_CAPACITY).build()); + MockIcmsServer.start(icmsBaseUrl, jsonMapper, contexts); + testTaskService.createTask(TEST_NCA_ID, TEST_TASK_ID_1, TEST_ICMS_REQ_ID_1); + + // Explicitly set the task status to running and set lastHeartbeatAt to more than 4m ago + // so that background thread will monitor it. + taskService.updateTask(TEST_TASK_ID_1, RUNNING, Instant.now().minus(Duration.ofMinutes(5))); + var taskEntity = tasksRepository.findById(TEST_TASK_ID_1); + assertThat(taskEntity).isNotNull(); + + monitorWorkerHeartbeatRoutine.runUnchecked(); + + // Verify health and status of task is updated. + var updatedTask = taskService.fetchTask(TEST_TASK_ID_1); + var healthInfo = taskMapperService.deserializeHealth(updatedTask.getHealth()) + .orElseThrow(); + assertThat(healthInfo).isNotNull(); + var expectedErrorLog = "Instance terminated due to to capacity constraint"; + assertThat(healthInfo.error()).contains(expectedErrorLog); + assertThat(updatedTask.getStatus()).isEqualTo(ERRORED); + + // Verify entry in the EventsByTaskRepository is updated. + var events = eventService.fetchEvents(TEST_NCA_ID, TEST_TASK_ID_1); + assertThat(events).isNotNull(); + assertThat(events.getLast().message()).contains(expectedErrorLog); + } + + @Test + @SneakyThrows + void testHeartbeatNotTimedOutRun() { + var contexts = List.of(MockIcmsServer.IcmsRequestContext.builder() + .instanceState(NO_CAPACITY).build()); + MockIcmsServer.start(icmsBaseUrl, jsonMapper, contexts); + testTaskService.createTask(TEST_NCA_ID, TEST_TASK_ID_1, TEST_ICMS_REQ_ID_1); + + // Explicitly set the task status to running, but set lastHeartbeatAt to now + // so that background thread won't monitor it. + taskService.updateTask(TEST_TASK_ID_1, RUNNING, Instant.now()); + var taskEntity = tasksRepository.findById(TEST_TASK_ID_1); + assertThat(taskEntity).isNotNull(); + var events = eventService.fetchEvents(TEST_NCA_ID, TEST_TASK_ID_1); + + monitorWorkerHeartbeatRoutine.runUnchecked(); + + // Verify task entity did not change. + var updatedTaskEntity = tasksRepository.findById(TEST_TASK_ID_1); + assertThat(updatedTaskEntity).isEqualTo(taskEntity); + + // Verify entry in the EventsByTaskRepository did not change. + var updatedEvents = eventService.fetchEvents(TEST_NCA_ID, TEST_TASK_ID_1); + assertThat(events).isEqualTo(updatedEvents); + } + + Stream usingTerminalStatusFromLatestEventArgs() { + return Stream.of( + Arguments.of(COMPLETED, + STATUS_CHANGE_EVENT_MESSAGE.formatted(RUNNING, COMPLETED)), + Arguments.of(CANCELED, + STATUS_CHANGE_EVENT_MESSAGE.formatted(RUNNING, CANCELED)) + ); + } + + @ParameterizedTest + @MethodSource("usingTerminalStatusFromLatestEventArgs") + void testUsingTerminalStatusFromLatestEvent( + TaskStatus terminalStatus, + String eventMessage) { + MockIcmsServer.start(icmsBaseUrl, jsonMapper, List.of()); + + // Create a Task by faking the creation time to be 10 minutes in the past. + testTaskService.createTask(TEST_NCA_ID, TEST_TASK_ID_1, TEST_ICMS_REQ_ID_1, + Instant.now().minus(Duration.ofMinutes(10))); + + // Simulate events for TEST_TASK_ID_1. + testEventService.populateEventForTask(EVENT_ID_1, TEST_NCA_ID, TEST_TASK_ID_1, + STATUS_CHANGE_EVENT_MESSAGE.formatted(QUEUED, LAUNCHED)); + testEventService.populateEventForTask(EVENT_ID_2, TEST_NCA_ID, TEST_TASK_ID_1, + STATUS_CHANGE_EVENT_MESSAGE.formatted(LAUNCHED, RUNNING)); + + // Explicitly set the Task status to RUNNING and the heartbeat timestamp to be 6 min + // in the past. + taskService.updateTask(TEST_TASK_ID_1, RUNNING, Instant.now().minus(Duration.ofMinutes(6))); + + // Verify that the status of the Task is RUNNING. + var taskEntity = tasksRepository.findById(TEST_TASK_ID_1); + assertThat(taskEntity).isPresent(); + assertThat(taskEntity.get().getStatus()).isEqualTo(RUNNING); + + // Simulate race condition where the Task is marked with terminal status and then + // immediately marked as RUNNING because of heartbeat. When the Task is marked with + // terminal status, an event is generated and the corresponding ICMS request is + // terminated/deleted. Let's set the heartbeat timestamp to be 5min in the past so + // that async monitoring routine picks it up. + taskService.updateTask(TEST_TASK_ID_1, terminalStatus); + testEventService.populateEventForTask(EVENT_ID_3, TEST_NCA_ID, TEST_TASK_ID_1, + eventMessage); + icmsService.terminateInstanceByTaskId(TEST_NCA_ID, TEST_TASK_ID_1); + taskService.updateTask(TEST_TASK_ID_1, RUNNING, // Back to RUNNING + Instant.now().minus(Duration.ofMinutes(5))); + + // Verify that the status of the Task is back to RUNNING. + taskEntity = tasksRepository.findById(TEST_TASK_ID_1); + assertThat(taskEntity).isPresent(); + assertThat(taskEntity.get().getStatus()).isEqualTo(RUNNING); + + // Verify that there are 3 events now. + var events = eventService.fetchEvents(TEST_NCA_ID, TEST_TASK_ID_1); + assertThat(events).hasSize(3); + + // Run the monitoring routine that processes Tasks with status RUNNING and + // last heartbeat timestamp more than 4 minutes in the past. The routine should + // restore the status of the Task using the terminal status from the last event. + monitorWorkerHeartbeatRoutine.runUnchecked(); + + // Verify that the Task now has a terminal status. + taskEntity = tasksRepository.findById(TEST_TASK_ID_1); + assertThat(taskEntity).isPresent(); + assertThat(taskEntity.get().getStatus()).isEqualTo(terminalStatus); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/service/token/WorkerAssertionValidatorTest.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/service/token/WorkerAssertionValidatorTest.java new file mode 100644 index 000000000..83afe051d --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/service/token/WorkerAssertionValidatorTest.java @@ -0,0 +1,143 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.service.token; + +import static com.nvidia.nvct.util.TestConstants.TEST_NCA_ID; +import static com.nvidia.nvct.util.TestConstants.TEST_TASK_ID_1; +import static org.assertj.core.api.Assertions.assertThatCode; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.Mockito.when; + +import com.nimbusds.jwt.JWTClaimsSet; +import com.nimbusds.jwt.PlainJWT; +import com.nvidia.boot.exceptions.ForbiddenException; +import com.nvidia.nvct.IntegrationTestConfiguration; +import com.nvidia.nvct.NvctTestApp; +import com.nvidia.nvct.util.MockNotaryServer; +import com.nvidia.nvct.util.MockNvcfServer; +import java.net.URL; +import java.time.Clock; +import java.time.Instant; +import java.time.temporal.ChronoUnit; +import java.util.Date; +import java.util.Map; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestInstance; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.ContextConfiguration; + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +@Slf4j +@SpringBootTest( + classes = {NvctTestApp.class, IntegrationTestConfiguration.class}, + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + properties = "spring.profiles.active=test") +@ContextConfiguration(initializers = IntegrationTestConfiguration.Initializer.class) +class WorkerAssertionValidatorTest { + + @Autowired + private WorkerAssertionValidator workerAssertionValidator; + + @Autowired + private TokenService tokenService; + + @Autowired + private Clock clock; + + @Value("${nvct.notary.base-url}") + private String notaryBaseUrl; + + @Value("${spring.security.oauth2.client.registration.notary.client-id}") + private String notaryClientId; + + @Value("${nvct.nvcf.base-url}") + private URL nvcfBaseUrl; + + @BeforeAll + void beforeAll() { + log.info("{}: Started running tests", this.getClass().getSimpleName()); + MockNvcfServer.start(nvcfBaseUrl); + MockNotaryServer.start(notaryBaseUrl, notaryClientId); + } + + @AfterAll + void cleanup() { + MockNotaryServer.stop(); + MockNvcfServer.stop(); + log.info("{}: Completed running tests", this.getClass().getSimpleName()); + } + + @BeforeEach + void setClock() { + when(clock.instant()).thenReturn(Instant.now().truncatedTo(ChronoUnit.SECONDS)); + } + + @Test + void shouldAcceptValidSignedWorkerAssertion() { + var token = tokenService.issueWorkerAccessAssertion(TEST_NCA_ID, TEST_TASK_ID_1); + + assertThatCode(() -> workerAssertionValidator.validate(token, TEST_NCA_ID, TEST_TASK_ID_1)) + .doesNotThrowAnyException(); + } + + @Test + void shouldRejectUnsignedWorkerAssertion() { + var token = new PlainJWT(new JWTClaimsSet.Builder() + .issuer(notaryBaseUrl) + .subject(notaryClientId) + .issueTime(Date.from(Instant.now(clock))) + .claim("assertion", Map.of("ncaId", TEST_NCA_ID, "taskId", TEST_TASK_ID_1.toString())) + .build()).serialize(); + + assertThatThrownBy(() -> workerAssertionValidator.validate(token, TEST_NCA_ID, TEST_TASK_ID_1)) + .isInstanceOf(ForbiddenException.class); + } + + @Test + void shouldRejectSignedWorkerAssertionWithWrongIssuer() { + var token = MockNotaryServer.generateSignedWorkerAssertion( + "http://wrong-notary.example:8080", + notaryClientId, + TEST_NCA_ID, + TEST_TASK_ID_1, + Instant.now(clock)); + + assertThatThrownBy(() -> workerAssertionValidator.validate(token, TEST_NCA_ID, TEST_TASK_ID_1)) + .isInstanceOf(ForbiddenException.class) + .hasMessageContaining("issuer"); + } + + @Test + void shouldRejectExpiredWorkerAssertion() { + var token = MockNotaryServer.generateSignedWorkerAssertion( + notaryBaseUrl, + notaryClientId, + TEST_NCA_ID, + TEST_TASK_ID_1, + Instant.now(clock).minus(4, ChronoUnit.HOURS)); + + assertThatThrownBy(() -> workerAssertionValidator.validate(token, TEST_NCA_ID, TEST_TASK_ID_1)) + .isInstanceOf(ForbiddenException.class) + .hasMessageContaining("Expired"); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/util/EssResponseTransformer.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/util/EssResponseTransformer.java new file mode 100644 index 000000000..9f828a559 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/util/EssResponseTransformer.java @@ -0,0 +1,142 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.util; + +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.json.JsonMapper; +import com.github.tomakehurst.wiremock.extension.ResponseTransformerV2; +import com.github.tomakehurst.wiremock.http.Request; +import com.github.tomakehurst.wiremock.http.Response; +import com.github.tomakehurst.wiremock.stubbing.ServeEvent; +import com.google.common.annotations.VisibleForTesting; +import com.nvidia.boot.exceptions.BadRequestException; +import com.nvidia.nvct.service.ess.EssStubService.SaveSecretsRequest; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; +import lombok.Builder; +import lombok.NonNull; +import lombok.SneakyThrows; +import lombok.Value; +import lombok.extern.jackson.Jacksonized; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class EssResponseTransformer implements ResponseTransformerV2 { + public static final String NAME = "ess-response-transformer"; + + private final JsonMapper jsonMapper = JsonMapper.builder().build(); + private final Map> secretsByTaskKey = new HashMap<>(); + + @Override + public boolean applyGlobally() { + return false; + } + + @Override + public String getName() { + return NAME; + } + + @SneakyThrows + @Override + public Response transform(Response response, ServeEvent serveEvent) { + var request = serveEvent.getRequest(); + var url = request.getAbsoluteUrl(); + log.debug("Transformer '{}': Request - {} {}", this.hashCode(), request.getMethod(), url); + + return switch (request.getMethod().getName()) { + case "PUT" -> saveOrUpdateSecrets(request, response); + case "DELETE" -> deleteSecrets(request, response); + case "GET" -> fetchSecrets(request, response); + default -> throw new BadRequestException("Unexpected HTTP Method"); + }; + } + + public void clearSecrets() { + secretsByTaskKey.clear(); + } + + @SneakyThrows + private Response saveOrUpdateSecrets(Request request, Response response) { + var taskId = getTaskId(request); + log.debug("Task id '{}': Saving / Updating Secrets", taskId); + + var rawBody = request.getBodyAsString(); + var body = jsonMapper.readValue(rawBody, SaveSecretsRequest.class); + var newSecrets = body.getData(); + secretsByTaskKey.put(taskId, newSecrets); + return response; + } + + @SneakyThrows + private Response fetchSecrets(Request request, Response response) { + var taskId = getTaskId(request); + log.debug("Task id '{}': Fetching Secrets", taskId); + + if (!request.getAbsoluteUrl().contains("query_type=fetch_secret")) { + throw new BadRequestException("Only supports query_type=fetch_secret"); + } + + var existingSecrets = secretsByTaskKey.getOrDefault(taskId, Collections.emptyMap()); + if (!existingSecrets.isEmpty()) { + var payload = new FetchSecretsResponse( + new FetchSecretsResponse.FetchSecretData(existingSecrets)); + var serialized = jsonMapper.writeValueAsString(payload); + return Response.Builder.like(response).body(serialized).build(); + } + return Response.response().status(404).build(); + } + + private Response deleteSecrets(Request request, Response response) { + var taskId = getTaskId(request); + + // Delete secrets. + log.debug("Task id '{}': Deleting Secrets", taskId); + secretsByTaskKey.remove(taskId); + + return response; + } + + private UUID getTaskId(Request request) { + var url = request.getAbsoluteUrl(); + var indexOfSlashAfterTasks = url.indexOf('/', url.indexOf("tasks")); + var rawTaskId = !url.contains("secrets") ? + url.substring(indexOfSlashAfterTasks + 1) : + url.substring(indexOfSlashAfterTasks + 1, url.indexOf("secrets") - 1); + return UUID.fromString(rawTaskId); + } + + @Value + @Jacksonized + @Builder + @VisibleForTesting + static class FetchSecretsResponse { + @NonNull + FetchSecretData data; + + @Value + @Jacksonized + @Builder + public static class FetchSecretData { + @NonNull + Map data; // Object will be a Map when response is deserialized. + } + } + +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/util/ManagedHttpResourcesTest.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/util/ManagedHttpResourcesTest.java new file mode 100644 index 000000000..9b3bb72cf --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/util/ManagedHttpResourcesTest.java @@ -0,0 +1,107 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.util; + +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import com.nvidia.nvct.util.NvctOAuth2ClientUtils.ManagedHttpResources; +import java.time.Duration; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.http.client.reactive.ClientHttpConnector; +import reactor.core.publisher.Mono; +import reactor.netty.resources.ConnectionProvider; +import reactor.netty.resources.LoopResources; + +@ExtendWith(MockitoExtension.class) +class ManagedHttpResourcesTest { + + @Mock + private ClientHttpConnector connector; + + @Mock + private ConnectionProvider connectionProvider; + + @Mock + private LoopResources loopResources; + + @Test + void close_invokesDisposeLaterOnBothResources() { + when(connectionProvider.disposeLater()).thenReturn(Mono.empty()); + when(loopResources.disposeLater( + eq(ManagedHttpResources.QUIET_PERIOD), + eq(ManagedHttpResources.DISPOSE_TIMEOUT))) + .thenReturn(Mono.empty()); + + var resources = new ManagedHttpResources(connector, connectionProvider, + loopResources, "test-client"); + resources.close(); + + verify(connectionProvider).disposeLater(); + verify(loopResources).disposeLater( + ManagedHttpResources.QUIET_PERIOD, ManagedHttpResources.DISPOSE_TIMEOUT); + } + + @Test + void close_swallowsException_whenDisposeFails() { + when(connectionProvider.disposeLater()) + .thenReturn(Mono.error(new RuntimeException("simulated dispose failure"))); + when(loopResources.disposeLater( + eq(ManagedHttpResources.QUIET_PERIOD), + eq(ManagedHttpResources.DISPOSE_TIMEOUT))) + .thenReturn(Mono.empty()); + + var resources = new ManagedHttpResources(connector, connectionProvider, + loopResources, "test-client"); + + assertDoesNotThrow(resources::close); + + // LoopResources must still be disposed even though ConnectionProvider failed. + verify(loopResources).disposeLater( + ManagedHttpResources.QUIET_PERIOD, ManagedHttpResources.DISPOSE_TIMEOUT); + } + + @Test + void close_isNoOp_whenBothResourcesNull() { + var resources = new ManagedHttpResources(null, null, null, "test"); + assertDoesNotThrow(resources::close); + } + + @Test + void connector_returnsInjectedInstance() { + try (var resources = new ManagedHttpResources(connector, null, null, "test")) { + assertSame(connector, resources.connector()); + } + } + + @Test + void timeoutConstants_areInternallyConsistent() { + assertTrue(ManagedHttpResources.BLOCK_TIMEOUT.compareTo( + ManagedHttpResources.DISPOSE_TIMEOUT) > 0, + "BLOCK_TIMEOUT must be strictly greater than DISPOSE_TIMEOUT"); + + assertTrue(ManagedHttpResources.BLOCK_TIMEOUT.compareTo(Duration.ofSeconds(30)) < 0, + "BLOCK_TIMEOUT must stay under spring.lifecycle.timeout-per-shutdown-phase (default 30s)"); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/util/MockApiKeysServer.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/util/MockApiKeysServer.java new file mode 100644 index 000000000..486e0fa5b --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/util/MockApiKeysServer.java @@ -0,0 +1,97 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.util; + +import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; +import static com.github.tomakehurst.wiremock.client.WireMock.post; +import static com.github.tomakehurst.wiremock.client.WireMock.urlPathEqualTo; +import static com.nvidia.nvct.util.TestConstants.TEST_NCA_ID; +import static com.nvidia.nvct.util.TestConstants.TEST_OWNER_ID; +import static org.springframework.http.HttpHeaders.CONTENT_TYPE; +import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; + +import tools.jackson.databind.json.JsonMapper; +import com.github.tomakehurst.wiremock.WireMockServer; +import com.nvidia.nvct.service.apikeys.ApiKeyValidationResult; +import com.nvidia.nvct.service.apikeys.ApiKeyValidationResult.Policy; +import com.nvidia.nvct.service.apikeys.ApiKeyValidationResult.Resource; +import com.nvidia.nvct.service.apikeys.dto.ApiKeyValidationResponse; +import java.net.URI; +import java.util.List; +import lombok.Getter; +import lombok.SneakyThrows; +import lombok.experimental.UtilityClass; + +@UtilityClass +public class MockApiKeysServer { + + public static final String EVALUATION_URI_PATH = "/v1/namespaces/nvct/evaluations/apikey.allow"; + + private static final JsonMapper OBJECT_MAPPER = JsonMapper.builder().build(); + @Getter + private static WireMockServer mockApiKeysServer; + + @SneakyThrows + public static void start(String apiKeysBaseUrl) { + stop(); + mockApiKeysServer = new WireMockServer(new URI(apiKeysBaseUrl).getPort()); + mockApiKeysServer.start(); + resetToDefault(); + } + + public static void stop() { + if (mockApiKeysServer != null) { + mockApiKeysServer.stop(); + } + } + + @SneakyThrows + public static void setApiKeyValidationResponse( + String ncaId, + String ownerId, + List resources, + List scopes, + boolean allowed) { + var result = new ApiKeyValidationResult(allowed, + ncaId, + ownerId, + new Policy(resources, + scopes, + "nv-cloud-functions")); + var response = new ApiKeyValidationResponse("nvct", "apikey.allow", result); + byte[] responseBytes = OBJECT_MAPPER.writeValueAsBytes(response); + mockApiKeysServer.stubFor( + post(urlPathEqualTo(EVALUATION_URI_PATH)) + .willReturn(aResponse().withStatus(200) + .withHeader(CONTENT_TYPE, APPLICATION_JSON_VALUE) + .withBody(responseBytes))); + } + + + @SneakyThrows + public static void setResponse( + String ncaId, + String ownerId, + List resources, + List scopes) { + setApiKeyValidationResponse(ncaId, ownerId, resources, scopes, true); + } + + public static void resetToDefault() { + setResponse(TEST_NCA_ID, TEST_OWNER_ID, List.of(), List.of()); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/util/MockEssServer.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/util/MockEssServer.java new file mode 100644 index 000000000..5866af7ff --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/util/MockEssServer.java @@ -0,0 +1,96 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.util; + +import static com.datastax.oss.driver.shaded.guava.common.net.HttpHeaders.CONTENT_TYPE; +import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; +import static com.github.tomakehurst.wiremock.client.WireMock.delete; +import static com.github.tomakehurst.wiremock.client.WireMock.get; +import static com.github.tomakehurst.wiremock.client.WireMock.put; +import static com.github.tomakehurst.wiremock.client.WireMock.urlPathMatching; +import static com.nvidia.nvct.util.EssResponseTransformer.NAME; +import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; + +import com.github.tomakehurst.wiremock.WireMockServer; +import com.github.tomakehurst.wiremock.core.WireMockConfiguration; +import com.github.tomakehurst.wiremock.matching.EqualToPattern; +import java.net.URI; +import java.time.Instant; +import java.util.UUID; +import lombok.Getter; +import lombok.SneakyThrows; +import lombok.experimental.UtilityClass; + +@UtilityClass +public class MockEssServer { + + @Getter + private static WireMockServer mockEssServer; + + private static EssResponseTransformer essResponseTransformer; + + @SneakyThrows + public static void start(String essBaseUrl) { + stop(); + + essResponseTransformer = new EssResponseTransformer(); + var configuration = new WireMockConfiguration() + .port(URI.create(essBaseUrl).getPort()) + .extensions(essResponseTransformer); + mockEssServer = new WireMockServer(configuration); + + var saveOrUpdateSecretsResponse = """ + { + "data": { + "created_time": "%s", + "version": "%s" + } + } + """.formatted(Instant.now(), UUID.randomUUID()); + mockEssServer.stubFor(put(urlPathMatching("/v1/tasks/(.+)?/secrets")) + .willReturn(aResponse().withStatus(200) + .withHeader(CONTENT_TYPE, APPLICATION_JSON_VALUE) + .withBody(saveOrUpdateSecretsResponse) + .withTransformers(NAME))); + mockEssServer.stubFor(get(urlPathMatching("/v1/tasks/(.+)?/secrets")) + .withQueryParam("query_type", + new EqualToPattern("fetch_secret")) + .willReturn(aResponse().withStatus(200) + .withHeader(CONTENT_TYPE, APPLICATION_JSON_VALUE) + .withTransformers(NAME))); + mockEssServer.stubFor(delete(urlPathMatching("/v1/tasks/(.+)?/secrets")) + .willReturn(aResponse().withStatus(204) + .withTransformers(NAME))); + mockEssServer.stubFor(delete(urlPathMatching("/v1/tasks/(.+)")) + .willReturn(aResponse().withStatus(204) + .withTransformers(NAME))); + mockEssServer.start(); + } + + public static void stop() { + if (mockEssServer != null) { + mockEssServer.stop(); + } + } + + public static void clearSecrets() { + if (essResponseTransformer != null) { + essResponseTransformer.clearSecrets(); + } + } + +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/util/MockIcmsServer.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/util/MockIcmsServer.java new file mode 100644 index 000000000..f55eb961f --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/util/MockIcmsServer.java @@ -0,0 +1,478 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.util; + +import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; +import static com.github.tomakehurst.wiremock.client.WireMock.delete; +import static com.github.tomakehurst.wiremock.client.WireMock.equalTo; +import static com.github.tomakehurst.wiremock.client.WireMock.get; +import static com.github.tomakehurst.wiremock.client.WireMock.post; +import static com.github.tomakehurst.wiremock.client.WireMock.urlPathEqualTo; +import static com.github.tomakehurst.wiremock.client.WireMock.urlPathMatching; +import static com.nvidia.nvct.util.MockIcmsServer.ClusterGroupsResponseState.COMPLETE; +import static com.nvidia.nvct.util.MockIcmsServer.InstancesState.HEALTHY; +import static com.nvidia.nvct.util.TestConstants.L40G; +import static com.nvidia.nvct.util.TestConstants.L40G_INSTANCE_TYPE; +import static com.nvidia.nvct.util.TestUtil.readFileAsString; +import static org.springframework.http.HttpHeaders.CONTENT_TYPE; +import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; + +import com.github.tomakehurst.wiremock.WireMockServer; +import com.github.tomakehurst.wiremock.common.ListOrSingle; +import com.github.tomakehurst.wiremock.core.WireMockConfiguration; +import com.github.tomakehurst.wiremock.extension.ResponseTransformerV2; +import com.github.tomakehurst.wiremock.extension.responsetemplating.helpers.FormParser; +import com.github.tomakehurst.wiremock.http.Response; +import com.github.tomakehurst.wiremock.matching.EqualToPattern; +import com.github.tomakehurst.wiremock.stubbing.ServeEvent; +import com.nvidia.nvct.rest.task.dto.InstanceUsageTypeEnum; +import com.nvidia.nvct.service.icms.IcmsStubService; +import com.nvidia.nvct.service.icms.IcmsStubService.GetInstancesResponse; +import com.nvidia.nvct.service.icms.IcmsStubService.GetInstancesResponse.InstanceRequest; +import java.net.URL; +import java.time.Instant; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.UUID; +import lombok.Builder; +import lombok.Data; +import lombok.Getter; +import lombok.SneakyThrows; +import lombok.experimental.UtilityClass; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +import org.springframework.http.HttpHeaders; +import tools.jackson.databind.json.JsonMapper; + +@Slf4j +@UtilityClass +public class MockIcmsServer { + + public enum InstancesState { + HEALTHY, + UNHEALTHY, + NO_CAPACITY + } + + public enum ClusterGroupsResponseState { + COMPLETE, + EMPTY_BODY, + NO_BODY, + MISSING_CLUSTER_GROUP, + MISSING_GPUS, + MISSING_GPU, + MISSING_INSTANCE_TYPES, + MISSING_INSTANCE_TYPE_DEFAULT, + WITH_ERROR_BODY_400, + WITHOUT_ERROR_BODY_500 + } + + public static final String GPU_INSTANCETYPE = "g6.full"; + public static final String GPU_NAME = "GFN_T10"; + + @Data + @Builder(toBuilder = true) + public static class IcmsRequestContext { + String icmsRequestId; + InstancesState instanceState; + String createTime; + } + + private static final String KEY_CONTEXT = "Context"; + + @Getter + private static WireMockServer mockIcmsServer; + + private static JsonMapper jsonMapper; + + @Getter + private static long cacheSize; + + @Getter + private static String capturedHelmValidationPolicy; + + @SneakyThrows + public static void start(URL url, JsonMapper jsonMapper) { + var contexts = List.of(IcmsRequestContext.builder().instanceState(HEALTHY).build()); + start(url, jsonMapper, contexts); + } + + @SneakyThrows + public static void start( + URL url, + JsonMapper jsonMapper, + List contexts) { + start(url, jsonMapper, contexts, COMPLETE); + } + + @SneakyThrows + public static void start( + URL url, + JsonMapper jsonMapper, + List contexts, + ClusterGroupsResponseState clusterGroupsResponseState) { + stop(); + MockIcmsServer.jsonMapper = jsonMapper; + var instanceRequestExtension = new RequestInstancesResponseTransformer(); + var getInstancesByTaskIdExtension = new GetInstancesByTaskIdResponseTransformer(); + var config = WireMockConfiguration.options() + .port(url.getPort()) + .extensions(instanceRequestExtension, + getInstancesByTaskIdExtension); + mockIcmsServer = new WireMockServer(config); + mockIcmsServer.stubFor(post(urlPathEqualTo("/v1/si")) + .withQueryParam("Action", + new EqualToPattern("RequestInstances")) + .willReturn(aResponse().withStatus(200) + .withTransformers(instanceRequestExtension.getName()) + .withHeader(CONTENT_TYPE, APPLICATION_JSON_VALUE) + .withBody("{}"))); + mockIcmsServer.stubFor(get(urlPathMatching("/v1/si/accounts/.*/deployments/.*/instances")) + .withQueryParam("IncludeTerminated", + new EqualToPattern("false")) + .withQueryParam("UseConciseName", + new EqualToPattern("true")) + .withQueryParam("ExpiredAckedInstances", + new EqualToPattern("false")) + .willReturn(aResponse().withStatus(200) + .withTransformer( + getInstancesByTaskIdExtension.getName(), + KEY_CONTEXT, + contexts) + .withHeader(CONTENT_TYPE, APPLICATION_JSON_VALUE) + .withBody("{}"))); + mockIcmsServer.stubFor(get(urlPathMatching("/v1/si/accounts/.*/deployments/.*/instances")) + .withQueryParam("IncludeTerminated", + new EqualToPattern("true")) + .withQueryParam("UseConciseName", + new EqualToPattern("true")) + .withQueryParam("ExpiredAckedInstances", + new EqualToPattern("true")) + .willReturn(aResponse().withStatus(200) + .withTransformer( + getInstancesByTaskIdExtension.getName(), + KEY_CONTEXT, + contexts) + .withHeader(CONTENT_TYPE, APPLICATION_JSON_VALUE) + .withBody("{}"))); + mockIcmsServer.stubFor(delete(urlPathEqualTo("/v1/si")) + .withQueryParam("Action", + new EqualToPattern("TerminateInstances")) + .willReturn(aResponse().withStatus(200))); + mockIcmsServer.stubFor(delete(urlPathMatching("/v1/si/accounts/.*/workloads/.*")) + .willReturn(aResponse().withStatus(200))); + addStubForGetClusterGroupsEndpoint(mockIcmsServer, clusterGroupsResponseState); + addStubForGetClustersEndpoint(mockIcmsServer); + mockIcmsServer.start(); + } + + public static void stop() { + if (mockIcmsServer != null) { + mockIcmsServer.stop(); + } + } + + public static void stubTerminateInstanceNotFound() { + mockIcmsServer.stubFor( + delete(urlPathMatching("/v1/si/accounts/.*/workloads/.*")) + .atPriority(1) + .willReturn(aResponse().withStatus(404) + .withHeader(CONTENT_TYPE, APPLICATION_JSON_VALUE) + .withBody("{\"detail\": \"Workload not found\"}"))); + } + + private static void addStubForGetClustersEndpoint( + WireMockServer mockIcmsServer) { + var body = readFileAsString("fixtures/icms/clusters/complete-response.json"); + mockIcmsServer.stubFor(get(urlPathMatching("/v1/si/accounts/.*/clusters")) + .withQueryParam("includeAuthorizedClusters", + new EqualToPattern("true")) + .withQueryParam("includeGfnInAuthorizedClusters", + new EqualToPattern("true")) + .withQueryParam( + "instanceTypeUsage", + equalTo(InstanceUsageTypeEnum.DEFAULT.toString()) + .or(equalTo(InstanceUsageTypeEnum.CONTAINER.toString()))) + .willReturn(aResponse().withStatus(200) + .withHeader(HttpHeaders.CONTENT_TYPE, + APPLICATION_JSON_VALUE) + .withBody(body))); + } + + private static void addStubForGetClusterGroupsEndpoint( + WireMockServer mockIcmsServer, + ClusterGroupsResponseState responseState) { + var body = switch (responseState) { + case COMPLETE -> readFileAsString("fixtures/icms/cluster-groups/complete-response.json"); + case EMPTY_BODY -> "{}"; + case NO_BODY, WITHOUT_ERROR_BODY_500 -> null; + case MISSING_CLUSTER_GROUP -> readFileAsString( + "fixtures/icms/cluster-groups/missing-gfn-cluster-group-response.json"); + case MISSING_GPUS -> readFileAsString( + "fixtures/icms/cluster-groups/missing-gfn-gpus-response.json"); + case MISSING_GPU -> readFileAsString("fixtures/icms/cluster-groups/missing-t10-gpu-response.json"); + case MISSING_INSTANCE_TYPES -> readFileAsString( + "fixtures/icms/cluster-groups/missing-t10-instance-types-response.json"); + case MISSING_INSTANCE_TYPE_DEFAULT -> readFileAsString( + "fixtures/icms/cluster-groups/missing-t10-instance-type-default-response.json"); + case WITH_ERROR_BODY_400 -> "{\"error\": \"pretend bad deployment spec\"}"; + }; + var status = switch (responseState) { + case WITH_ERROR_BODY_400 -> 400; + case WITHOUT_ERROR_BODY_500 -> 500; + default -> 200; + }; + mockIcmsServer.stubFor(get(urlPathMatching("/v1/si/accounts/.*/clusterGroups")) + .withQueryParam( + "instanceTypeUsage", + equalTo(InstanceUsageTypeEnum.DEFAULT.toString()) + .or(equalTo(InstanceUsageTypeEnum.CONTAINER.toString()))) + .willReturn(aResponse().withStatus(status) + .withHeader(CONTENT_TYPE, APPLICATION_JSON_VALUE) + .withBody(body))); + mockIcmsServer.stubFor(get(urlPathEqualTo("/v1/si")) + .withQueryParam("Action", + new EqualToPattern("DescribeInstances")) + .willReturn(aResponse().withStatus(200) + .withHeader(HttpHeaders.CONTENT_TYPE, + APPLICATION_JSON_VALUE) + .withBody(""" + { + "Instances": [ + { + "ImageId": "", + "ContainerImage": "", + "InstanceId": "local-instance", + "InstanceIps": [ + "127.0.0.1", + "127.0.0.2" + ], + "CloudProvider": "GFN | OCI | AZURE | AWS | GCP", + "InstanceType": "", + "Placement": { + "AvailabilityZone": "np-lax02" + }, + "State": { + "Code": 0, + "Name": "running" + }, + "HealthInfo": { + "ErrorLog": "" + }, + "LaunchRequestId": "" + } + ] + }"""))); + + } + + public static class RequestInstancesResponseTransformer implements ResponseTransformerV2 { + + @Override + public Response transform(Response response, ServeEvent serveEvent) { + var request = serveEvent.getRequest(); + var data = FormParser.parse(request.getBodyAsString(), true); + cacheSize = Long.parseLong( + data.getOrDefault("LaunchSpecification.CacheSize", ListOrSingle.of("0")) + .getFirst()); + capturedHelmValidationPolicy = + data.containsKey("LaunchSpecification.HelmValidationPolicy") + ? data.get("LaunchSpecification.HelmValidationPolicy").getFirst() + : null; + var rawBody = """ + { + "requestId": "%s" + }"""; + var body = rawBody.formatted(UUID.randomUUID()); + return Response.Builder.like(response).body(body).build(); + } + + @Override + public boolean applyGlobally() { + return false; + } + + @Override + public String getName() { + return "request-instances"; + } + } + + public static class DescribeInstanceRequestsResponseTransformer + implements ResponseTransformerV2 { + + private static final String RAW_HEALTHY_INSTANCE_JSON = + readFileAsString("fixtures/icms/raw-healthy-instance.json"); + private static final String RAW_UNHEALTHY_INSTANCE_JSON = + readFileAsString("fixtures/icms/raw-unhealthy-instance.json"); + private static final String RAW_NO_CAPACITY_INSTANCE_JSON = + readFileAsString("fixtures/icms/raw-no-capacity-instance.json"); + + @Override + public Response transform(Response response, ServeEvent serveEvent) { + var request = serveEvent.getRequest(); + var parameters = serveEvent.getTransformerParameters(); + var icmsRequestIds = request.queryParameter("InstanceRequestId").values(); + var rawContexts = (List) parameters.get(KEY_CONTEXT); + List contexts = new ArrayList<>(); + for (int i = 0; i < icmsRequestIds.size(); i++) { + var index = i % rawContexts.size(); + var icmsRequestId = icmsRequestIds.get(i); + var ctx = rawContexts.get(index).toBuilder().icmsRequestId(icmsRequestId).build(); + contexts.add(ctx); + } + var body = getTransformedResponseBody(contexts); + return Response.Builder.like(response).body(body).build(); + } + + @Override + public boolean applyGlobally() { + return false; + } + + @Override + public String getName() { + return "describe-instance-requests"; + } + + @SneakyThrows + private static String getTransformedResponseBody( + List contexts) { + var instanceRequests = contexts.stream() + .map(DescribeInstanceRequestsResponseTransformer::getInstanceRequests) + .flatMap(Collection::stream) + .toList(); + var responseBody = GetInstancesResponse.builder() + .instanceRequests(instanceRequests).build(); + return jsonMapper.writeValueAsString(responseBody); + } + + @SneakyThrows + private static List getInstanceRequests( + IcmsRequestContext context) { + List instances; + try { + instances = switch (context.getInstanceState()) { + case HEALTHY -> List.of( + jsonMapper.readValue(RAW_HEALTHY_INSTANCE_JSON.formatted( + UUID.randomUUID(), // instance-id + GPU_INSTANCETYPE, + GPU_NAME, + context.getIcmsRequestId()), + InstanceRequest.class)); + case UNHEALTHY -> List.of( + jsonMapper.readValue(RAW_UNHEALTHY_INSTANCE_JSON.formatted( + UUID.randomUUID(), // instance-id + GPU_INSTANCETYPE, + GPU_NAME, + context.getIcmsRequestId(), + GPU_NAME), + InstanceRequest.class)); + case NO_CAPACITY -> List.of( + jsonMapper.readValue(RAW_NO_CAPACITY_INSTANCE_JSON.formatted( + UUID.randomUUID(), // instance-id + L40G_INSTANCE_TYPE, + L40G, + context.getIcmsRequestId(), + L40G), + InstanceRequest.class)); + }; + } catch (Exception ex) { + log.error("Context Status: '{}'; ICMS Request Id: '{}', Exception: '{}'", + context.getInstanceState(), context.getIcmsRequestId(), + ex.getMessage()); + throw ex; + } + + log.info("Context Status: '{}'", context.getInstanceState()); + log.info("Instance1: '{}'", instances.getFirst()); + return instances; + } + } + + public static class GetInstancesByTaskIdResponseTransformer + implements ResponseTransformerV2 { + + @Override + public Response transform(Response response, ServeEvent serveEvent) { + var parameters = serveEvent.getTransformerParameters(); + var rawContexts = (List) parameters.get(KEY_CONTEXT); + var contexts = rawContexts.stream() + .map(context -> { + var icmsRequestId = StringUtils.isBlank(context.getIcmsRequestId()) + ? UUID.randomUUID().toString() + : context.getIcmsRequestId(); + return context.toBuilder().icmsRequestId(icmsRequestId).build(); + }) + .toList(); + var body = getTransformedResponseBody(contexts); + return Response.Builder.like(response).body(body).build(); + } + + @Override + public boolean applyGlobally() { + return false; + } + + @Override + public String getName() { + return "get-instances-by-task-id"; + } + + @SneakyThrows + private static String getTransformedResponseBody( + List contexts) { + var instances = contexts.stream() + .map(GetInstancesByTaskIdResponseTransformer::getInstances) + .flatMap(Collection::stream) + .toList(); + var responseBody = IcmsStubService.Instances.builder() + .Instances(instances).build(); + return jsonMapper.writeValueAsString(responseBody); + } + + @SneakyThrows + private static List getInstances( + IcmsRequestContext context) { + return DescribeInstanceRequestsResponseTransformer.getInstanceRequests(context) + .stream() + .map(instance -> GetInstancesByTaskIdResponseTransformer.toInstance( + instance, context)) + .toList(); + } + + private static IcmsStubService.Instance toInstance( + InstanceRequest instanceRequest, + IcmsRequestContext context) { + return IcmsStubService.Instance.builder() + .createTime(context.getCreateTime() != null ? + Instant.parse(context.getCreateTime()) : Instant.now()) + .containerImage(instanceRequest.getLaunchSpecification().getContainerImage()) + .instanceId(instanceRequest.getInstanceId()) + .cloudProvider(instanceRequest.getCloudProvider()) + .instanceType(instanceRequest.getLaunchSpecification().getInstanceType()) + .placement(InstanceRequest.Placement.builder() + .availabilityZone(instanceRequest.getLaunchedAvailabilityZone()) + .build()) + .state(instanceRequest.getInstanceState()) + .healthInfo(instanceRequest.getHealthInfo()) + .launchRequestId(instanceRequest.getInstanceRequestId().toString()) + .build(); + } + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/util/MockNotaryServer.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/util/MockNotaryServer.java new file mode 100644 index 000000000..7154fdffa --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/util/MockNotaryServer.java @@ -0,0 +1,83 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.util; + +import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; +import static com.github.tomakehurst.wiremock.client.WireMock.get; +import static com.github.tomakehurst.wiremock.client.WireMock.post; +import static com.github.tomakehurst.wiremock.client.WireMock.urlPathEqualTo; +import static com.nvidia.nvct.util.NotaryServiceResponseTransformer.NAME; +import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; + +import tools.jackson.databind.json.JsonMapper; +import com.github.tomakehurst.wiremock.WireMockServer; +import com.github.tomakehurst.wiremock.core.WireMockConfiguration; +import java.net.URI; +import java.time.Instant; +import java.util.UUID; +import lombok.SneakyThrows; +import org.springframework.http.HttpHeaders; + +public class MockNotaryServer { + + private static final JsonMapper OBJECT_MAPPER = JsonMapper.builder().build(); + + private static NotaryServiceResponseTransformer notaryServiceResponseTransformer; + + private static WireMockServer mockNotaryServer; + + @SneakyThrows + public static void start(String notaryBaseUrl, String notaryClientId) { + stop(); + notaryServiceResponseTransformer = new NotaryServiceResponseTransformer(notaryBaseUrl, + notaryClientId); + var configuration = new WireMockConfiguration() + .port(URI.create(notaryBaseUrl).getPort()) + .extensions(notaryServiceResponseTransformer); + + mockNotaryServer = new WireMockServer(configuration); + mockNotaryServer + .stubFor(post(urlPathEqualTo("/sign")) + .willReturn(aResponse().withStatus(200) + .withHeader(HttpHeaders.CONTENT_TYPE, + APPLICATION_JSON_VALUE) + .withTransformers(NAME))); + mockNotaryServer + .stubFor(get(urlPathEqualTo("/.well-known/jwks.json")) + .willReturn(aResponse().withStatus(200) + .withHeader(HttpHeaders.CONTENT_TYPE, + APPLICATION_JSON_VALUE) + .withBody(notaryServiceResponseTransformer.getJwksJson()))); + mockNotaryServer.start(); + } + + public static void stop() { + if (mockNotaryServer != null) { + mockNotaryServer.stop(); + } + } + + @SneakyThrows + public static String generateSignedWorkerAssertion(String issuer, + String subject, + String ncaId, + UUID taskId, + Instant issuedAt) { + return NotaryServiceResponseTransformer.generateSignedWorkerAssertion( + issuer, subject, ncaId, taskId, issuedAt, OBJECT_MAPPER); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/util/MockNvcfServer.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/util/MockNvcfServer.java new file mode 100644 index 000000000..1fc95ea08 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/util/MockNvcfServer.java @@ -0,0 +1,170 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.util; + +import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; +import static com.github.tomakehurst.wiremock.client.WireMock.get; +import static com.github.tomakehurst.wiremock.client.WireMock.urlMatching; +import static com.nvidia.nvct.util.TestConstants.TEST_CLIENT_ID; +import static com.nvidia.nvct.util.TestConstants.TEST_CLIENT_ID_2; +import static com.nvidia.nvct.util.TestConstants.TEST_CLIENT_ID_3; +import static com.nvidia.nvct.util.TestConstants.TEST_CLIENT_ID_4; +import static com.nvidia.nvct.util.TestConstants.TEST_CLIENT_ID_5; +import static com.nvidia.nvct.util.TestConstants.TEST_CLIENT_ID_6; +import static com.nvidia.nvct.util.TestConstants.TEST_NCA_ID; +import static com.nvidia.nvct.util.TestConstants.TEST_NCA_ID_2; +import static com.nvidia.nvct.util.TestConstants.TEST_NCA_ID_3; +import static com.nvidia.nvct.util.TestConstants.TEST_NCA_ID_WITHOUT_REGISTRY_CREDENTIALS_6; +import static com.nvidia.nvct.util.TestConstants.TEST_NCA_ID_WITH_1_MAX_ALLOWED_TASKS_5; +import static com.nvidia.nvct.util.TestConstants.TEST_NCA_ID_WITH_TELEMETRIES_4; +import static com.nvidia.nvct.util.TestUtil.readFileAsString; +import static org.springframework.http.HttpHeaders.CONTENT_TYPE; +import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; + +import com.github.tomakehurst.wiremock.WireMockServer; +import com.github.tomakehurst.wiremock.core.WireMockConfiguration; +import com.github.tomakehurst.wiremock.extension.ResponseTransformerV2; +import com.github.tomakehurst.wiremock.http.Response; +import com.github.tomakehurst.wiremock.stubbing.ServeEvent; +import java.net.URL; +import java.time.Instant; +import java.util.Map; +import lombok.Getter; +import lombok.SneakyThrows; +import lombok.experimental.UtilityClass; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@UtilityClass +public class MockNvcfServer { + + @Getter + private static WireMockServer mockNvcfServer; + + private static final String ACCOUNT_RESPONSE = + readFileAsString("fixtures/nvcf/account-response.json"); + private static final String ACCOUNT_WITH_TELEMETRIES_RESPONSE = + readFileAsString("fixtures/nvcf/account-with-telemetries-response.json"); + private static final String ACCOUNT_WITHOUT_REGISTRY_CREDENTIALS_RESPONSE = + readFileAsString("fixtures/nvcf/account-without-registry-credentials-response.json"); + private static final String CLIENT_RESPONSE = + readFileAsString("fixtures/nvcf/client-response.json"); + + @SneakyThrows + public static void start(URL url) { + stop(); + var accountExtension = new AccountResponseTransformer(); + var clientResponseExtension = new ClientResponseTransformer(); + var config = WireMockConfiguration.options() + .port(url.getPort()) + .extensions(accountExtension, clientResponseExtension); + mockNvcfServer = new WireMockServer(config); + mockNvcfServer.stubFor(get(urlMatching("/v2/nvcf/accounts/(.*)")) + .willReturn(aResponse().withStatus(200) + .withTransformers(accountExtension.getName()) + .withHeader(CONTENT_TYPE, APPLICATION_JSON_VALUE) + .withBody("{}"))); + mockNvcfServer.stubFor(get(urlMatching("/v2/nvcf/clients/(.*)")) + .willReturn(aResponse().withStatus(200) + .withTransformers(clientResponseExtension.getName()) + .withHeader(CONTENT_TYPE, APPLICATION_JSON_VALUE) + .withBody("{}"))); + mockNvcfServer.start(); + } + + public static void stop() { + if (mockNvcfServer != null) { + mockNvcfServer.stop(); + } + } + + public static class AccountResponseTransformer implements ResponseTransformerV2 { + private static final Map ncaIdToClientIdMap = + Map.of(TEST_NCA_ID, TEST_CLIENT_ID, + TEST_NCA_ID_2, TEST_CLIENT_ID_2, + TEST_NCA_ID_3, TEST_CLIENT_ID_3, + TEST_NCA_ID_WITH_TELEMETRIES_4, TEST_CLIENT_ID_4, + TEST_NCA_ID_WITH_1_MAX_ALLOWED_TASKS_5, TEST_CLIENT_ID_5, + TEST_NCA_ID_WITHOUT_REGISTRY_CREDENTIALS_6, TEST_CLIENT_ID_6); + + @Override + public Response transform(Response response, ServeEvent serveEvent) { + var request = serveEvent.getRequest(); + var index = request.getUrl().lastIndexOf("/"); + var ncaId = request.getUrl().substring(index + 1); + var clientId = ncaIdToClientIdMap.get(ncaId); + if (clientId == null) { + return Response.Builder.like(response).status(404).body("").build(); + } + String rawBody; + if (ncaId.contains("without-registry-credentials")) { + rawBody = ACCOUNT_WITHOUT_REGISTRY_CREDENTIALS_RESPONSE; + } else if (ncaId.contains("telemetries")) { + rawBody = ACCOUNT_WITH_TELEMETRIES_RESPONSE; + } else { + rawBody = ACCOUNT_RESPONSE; + } + var maxTasksAllowed = ncaId.contains("1-max-allowed-tasks") ? 1 : 50; + var body = rawBody.formatted(ncaId, clientId, ncaId + "-name", maxTasksAllowed) + .replace("_instant_", Instant.now().toString()); + return Response.Builder.like(response).body(body).build(); + } + + @Override + public boolean applyGlobally() { + return false; + } + + @Override + public String getName() { + return "account-response-transformer"; + } + } + + public static class ClientResponseTransformer implements ResponseTransformerV2 { + private static final Map clientIdToNcaIdMap = + Map.of(TEST_CLIENT_ID, TEST_NCA_ID, + TEST_CLIENT_ID_2, TEST_NCA_ID_2, + TEST_CLIENT_ID_3, TEST_NCA_ID_3, + TEST_CLIENT_ID_4, TEST_NCA_ID_WITH_TELEMETRIES_4, + TEST_CLIENT_ID_5, TEST_NCA_ID_WITH_1_MAX_ALLOWED_TASKS_5, + TEST_CLIENT_ID_6, TEST_NCA_ID_WITHOUT_REGISTRY_CREDENTIALS_6); + + @Override + public Response transform(Response response, ServeEvent serveEvent) { + var request = serveEvent.getRequest(); + var index = request.getUrl().lastIndexOf("/"); + var clientId = request.getUrl().substring(index + 1); + var ncaId = clientIdToNcaIdMap.get(clientId); + if (ncaId == null) { + return Response.Builder.like(response).status(404).body("").build(); + } + var body = CLIENT_RESPONSE.formatted(clientId, ncaId, ncaId + "-name"); + return Response.Builder.like(response).body(body).build(); + } + + @Override + public boolean applyGlobally() { + return false; + } + + @Override + public String getName() { + return "client-response-transformer"; + } + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/util/MockRevalServer.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/util/MockRevalServer.java new file mode 100644 index 000000000..4d799569b --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/util/MockRevalServer.java @@ -0,0 +1,92 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.util; + +import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; +import static com.github.tomakehurst.wiremock.client.WireMock.absent; +import static com.github.tomakehurst.wiremock.client.WireMock.containing; +import static com.github.tomakehurst.wiremock.client.WireMock.equalTo; +import static com.github.tomakehurst.wiremock.client.WireMock.matchingJsonPath; +import static com.github.tomakehurst.wiremock.client.WireMock.post; +import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options; + +import com.github.tomakehurst.wiremock.WireMockServer; +import java.net.URI; +import lombok.experimental.UtilityClass; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@UtilityClass +public class MockRevalServer { + private static WireMockServer wireMockServer; + + public static void start(URI listenUrl) { + stop(); + + wireMockServer = new WireMockServer(options().port(listenUrl.getPort())); + + var validationOk = aResponse() + .withStatus(200) + .withHeader("Content-Type", "application/json") + .withBody("{\"valid\": true}"); + + var validationError = aResponse() + .withStatus(200) + .withHeader("Content-Type", "application/json") + .withBody(""" + {"valid": false, "validationErrors": ["spam", "eggs"]} + """); + + wireMockServer.stubFor( + post("/v1/validate") + .withRequestBody( + matchingJsonPath( + "$.helmChart", + containing("invalid-helm-chart"))) + .willReturn(validationError)); + wireMockServer.stubFor( + post("/v1/validate") + .atPriority(4) + .withRequestBody( + matchingJsonPath("$.configuration.fail", equalTo("fail"))) + .willReturn(validationError)); + wireMockServer.stubFor( + post("/v1/validate") + .withRequestBody( + matchingJsonPath( + "$.helmChart", + containing("test-helm-chart"))) + .willReturn(validationOk)); + + wireMockServer.stubFor( + post("/v1/validate") + .withHeader("Authorization", absent()) + .willReturn( + aResponse() + .withStatus(401) + .withBody("Authorization header required"))); + + wireMockServer.start(); + + } + + public static void stop() { + if (wireMockServer != null && wireMockServer.isRunning()) { + wireMockServer.stop(); + } + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/util/NotaryServiceResponseTransformer.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/util/NotaryServiceResponseTransformer.java new file mode 100644 index 000000000..bb0f5d886 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/util/NotaryServiceResponseTransformer.java @@ -0,0 +1,230 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.util; + +import static com.nvidia.boot.mock.oauth2.OAuth2TestUtils.getServiceId; +import static net.minidev.json.parser.JSONParser.DEFAULT_PERMISSIVE_MODE; + +import com.github.tomakehurst.wiremock.extension.ResponseTransformerV2; +import com.github.tomakehurst.wiremock.http.Request; +import com.github.tomakehurst.wiremock.http.Response; +import com.github.tomakehurst.wiremock.stubbing.ServeEvent; +import com.nimbusds.jose.JOSEException; +import com.nimbusds.jose.JWSAlgorithm; +import com.nimbusds.jose.JWSHeader; +import com.nimbusds.jose.JWSSigner; +import com.nimbusds.jose.crypto.ECDSASigner; +import com.nimbusds.jose.jwk.Curve; +import com.nimbusds.jose.jwk.ECKey; +import com.nimbusds.jose.jwk.JWKSet; +import com.nimbusds.jwt.JWTClaimsSet; +import com.nimbusds.jwt.SignedJWT; +import com.nvidia.boot.exceptions.BadRequestException; +import com.nvidia.nvct.service.token.client.NotaryStubService.SecretPathsAssertion; +import com.nvidia.nvct.service.token.client.NotaryStubService.SignResponse; +import com.nvidia.nvct.service.token.client.NotaryStubService.SignSecretPathsRequest; +import com.nvidia.nvct.service.token.client.NotaryStubService.SignWorkerAccessRequest; +import com.nvidia.nvct.service.token.client.NotaryStubService.WorkerAccessAssertion; +import java.net.URI; +import java.net.URL; +import java.security.KeyPairGenerator; +import java.security.interfaces.ECPrivateKey; +import java.security.interfaces.ECPublicKey; +import java.time.Instant; +import java.util.Date; +import java.util.List; +import java.util.UUID; +import lombok.Getter; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; +import net.minidev.json.parser.JSONParser; +import tools.jackson.databind.json.JsonMapper; + +@Slf4j +public class NotaryServiceResponseTransformer implements ResponseTransformerV2 { + + public static final String NAME = "notary-service-response-transformer"; + + private final JsonMapper jsonMapper = JsonMapper.builder().build(); + + private String notaryBaseUrl; + private String notaryClientId; + + public NotaryServiceResponseTransformer(String notaryBaseUrl, String notaryClientId) { + this.notaryBaseUrl = notaryBaseUrl; + this.notaryClientId = notaryClientId; + } + + public String getJwksJson() { + return NotaryUtils.getJwks().toString(); + } + + @Override + public boolean applyGlobally() { + return false; + } + + @Override + public String getName() { + return NAME; + } + + @SneakyThrows + @Override + public Response transform(Response response, ServeEvent serveEvent) { + var request = serveEvent.getRequest(); + var url = request.getAbsoluteUrl(); + log.info("Transformer '{}': Request - {} {}", this.hashCode(), request.getMethod(), url); + + return switch (request.getMethod().getName()) { + case "POST" -> sign(request, response); + default -> throw new BadRequestException("Unexpected HTTP Method"); + }; + } + + @SneakyThrows + private Response sign(Request request, Response response) { + if (request.getBodyAsString().contains("secretPaths")) { + // The request is secretPath request. Issue a secrets token + var assertion = jsonMapper.readValue(request.getBody(), SignSecretPathsRequest.class).data(); + var namespace = assertion.namespace(); + var secretPaths = assertion.secretPaths(); + log.info("Namespace '{}'. Secret paths '{}'", namespace, secretPaths); + var payload = new SignResponse(generateJwtForSecretsAssertion(notaryBaseUrl, + notaryClientId, + namespace, + secretPaths, + jsonMapper)); + var serialized = jsonMapper.writeValueAsString(payload); + return Response.Builder.like(response).body(serialized).build(); + } + + // Otherwise the request is worker access request. Issue a worker token + var assertion = jsonMapper.readValue(request.getBody(), SignWorkerAccessRequest.class).data(); + var taskId = assertion.taskId(); + var ncaId = assertion.ncaId(); + log.info("NCA id '{}', Task id '{}': assertion token", ncaId, taskId); + var payload = new SignResponse(generateJwtForWorkerAssertion(notaryBaseUrl, + notaryClientId, + ncaId, + taskId, + jsonMapper)); + var serialized = jsonMapper.writeValueAsString(payload); + return Response.Builder.like(response).body(serialized).build(); + } + + @SneakyThrows + private static String generateJwtForWorkerAssertion(String notaryBaseUrl, + String notaryClientId, + String ncaId, + UUID taskId, + JsonMapper jsonMapper) { + var assertion = new WorkerAccessAssertion(ncaId, taskId); + return NotaryUtils.getJwt(notaryClientId, + jsonMapper.writeValueAsString(assertion), + URI.create(notaryBaseUrl).toURL()); + } + + @SneakyThrows + public static String generateSignedWorkerAssertion(String issuer, + String subject, + String ncaId, + UUID taskId, + Instant issuedAt, + JsonMapper jsonMapper) { + var assertion = new WorkerAccessAssertion(ncaId, taskId); + return NotaryUtils.getJwt(subject, + jsonMapper.writeValueAsString(assertion), + new URL(issuer), + Date.from(issuedAt)); + } + + @SneakyThrows + private static String generateJwtForSecretsAssertion(String notaryBaseUrl, + String notaryClientId, + String namespace, + List secretPaths, + JsonMapper jsonMapper) { + var assertion = new SecretPathsAssertion(namespace, secretPaths); + return NotaryUtils.getJwt(notaryClientId, + jsonMapper.writeValueAsString(assertion), + new URL(notaryBaseUrl)); + } + + private static class NotaryUtils { + + private static final JWSSigner signer; + + @Getter + private static final JWKSet jwks; + + static { + try { + var gen = KeyPairGenerator.getInstance("EC"); + gen.initialize(Curve.P_256.toECParameterSpec()); + var keyPair = gen.generateKeyPair(); + + // Convert to JWK format + var privateJwk = new ECKey.Builder(Curve.P_256, + (ECPublicKey) keyPair.getPublic()) + .privateKey((ECPrivateKey) keyPair.getPrivate()) + .keyID(UUID.randomUUID().toString()) + .algorithm(JWSAlgorithm.ES256) + .build(); + var publicJWK = privateJwk.toPublicJWK(); + jwks = new JWKSet(publicJWK); + signer = new ECDSASigner(privateJwk); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + @SneakyThrows(JOSEException.class) + private static String getJwt(JWTClaimsSet.Builder claims) { + var jwk = jwks.getKeys().get(0); + SignedJWT signedJWT = new SignedJWT( + new JWSHeader.Builder((JWSAlgorithm) jwk.getAlgorithm()) + .keyID(jwk.getKeyID()) + .build(), + claims.build()); + signedJWT.sign(signer); + return signedJWT.serialize(); + } + + @SneakyThrows + private static String getJwt( + String subject, String assertion, URL issuer) { + return getJwt(subject, assertion, issuer, new Date()); + } + + @SneakyThrows + private static String getJwt( + String subject, String assertion, URL issuer, Date issuedAt) { + var parser = new JSONParser(DEFAULT_PERMISSIVE_MODE); + var jsonAssertion = parser.parse(assertion); + var claimsSetBuilder = new JWTClaimsSet.Builder() + .subject(subject) + .issueTime(issuedAt) + .claim("assertion", jsonAssertion) + .audience(List.of(getServiceId(issuer), subject)) + .issuer(issuer.toString()) + .jwtID(UUID.randomUUID().toString()); + return getJwt(claimsSetBuilder); + } + } + +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/util/TestConstants.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/util/TestConstants.java new file mode 100644 index 000000000..1ac112d54 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/util/TestConstants.java @@ -0,0 +1,478 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.util; + +import static com.nvidia.boot.mock.BootTestConstants.TEST_UNKNOWN_HELM_CHART_VERSION; +import static com.nvidia.boot.mock.BootTestConstants.TEST_VALID_CONTAINER_HASH; +import static com.nvidia.boot.mock.BootTestConstants.TEST_VALID_CONTAINER_NAME; +import static com.nvidia.boot.mock.BootTestConstants.TEST_VALID_CONTAINER_TAG; +import static com.nvidia.boot.mock.BootTestConstants.TEST_VALID_HELM_CHART_NAME; +import static com.nvidia.boot.mock.BootTestConstants.TEST_VALID_HELM_CHART_VERSION; +import static com.nvidia.boot.mock.BootTestConstants.TEST_VALID_OCI_HELM_CHART_NAME; +import static com.nvidia.boot.mock.BootTestConstants.TEST_VALID_OCI_HELM_CHART_TAG_NAME; +import static com.nvidia.boot.mock.BootTestConstants.TEST_VALID_OCI_IMAGE_NAME; +import static com.nvidia.boot.mock.BootTestConstants.TEST_VALID_OCI_IMAGE_TAG_NAME; +import static com.nvidia.boot.mock.ngc.MockCasServer.MODEL_FILES_NOT_EXIST_URL; +import static com.nvidia.boot.mock.ngc.MockCasServer.MODEL_FILES_URL; +import static com.nvidia.boot.mock.ngc.MockCasServer.MODEL_FILES_URL_WITH_TEAM; +import static com.nvidia.boot.mock.ngc.MockCasServer.MODEL_FILES_URL_WITH_TEAM_2; +import static com.nvidia.boot.mock.ngc.MockCasServer.MODEL_FILES_URL_WITH_VERSION; +import static com.nvidia.boot.mock.ngc.MockCasServer.MODEL_FILE_PERMISSION_DENIED_URL; +import static com.nvidia.boot.mock.ngc.MockCasServer.RESOURCE_FILES_URL; +import static com.nvidia.boot.mock.ngc.MockCasServer.RESOURCE_FILES_URL_WITH_TEAM; +import static com.nvidia.boot.mock.ngc.MockCasServer.RESOURCE_FILES_URL_WITH_TEAM_2; +import static com.nvidia.boot.mock.ngc.MockCasServer.RESOURCE_FILES_URL_WITH_VERSION; +import static com.nvidia.boot.mock.ngc.MockCasServer.RESOURCE_FILE_NOT_EXISTS_URL_WITH_TEAM; +import static com.nvidia.boot.mock.ngc.MockCasServer.RESOURCE_FILE_PERMISSION_DENIED_URL_WITH_TEAM; +import static com.nvidia.nvct.util.NvctConstants.NGC_API_KEY; +import static java.nio.charset.StandardCharsets.UTF_8; + +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.json.JsonMapper; +import tools.jackson.databind.node.ObjectNode; +import tools.jackson.databind.node.StringNode; +import com.nvidia.boot.mock.BootTestConstants; +import com.nvidia.boot.registries.service.registry.dto.ArtifactTypeEnum; +import com.nvidia.nvct.persistence.task.entity.GpuSpecUdt; +import com.nvidia.nvct.persistence.task.entity.ModelUdt; +import com.nvidia.nvct.persistence.task.entity.ResourceUdt; +import com.nvidia.nvct.rest.task.dto.ArtifactDto; +import com.nvidia.nvct.rest.task.dto.ContainerEnvironmentEntryDto; +import com.nvidia.nvct.rest.task.dto.GpuSpecificationDto; +import com.nvidia.nvct.rest.task.dto.HelmValidationPolicyDto; +import com.nvidia.nvct.rest.task.dto.SecretDto; +import com.nvidia.nvct.rest.task.dto.ValidationPolicyNameEnum; +import com.nvidia.nvct.service.account.dto.RegistryCredentialDto; +import io.grpc.Metadata; +import io.grpc.Metadata.Key; +import java.net.URI; +import java.nio.charset.StandardCharsets; +import java.util.Base64; +import java.util.List; +import java.util.Set; +import java.util.UUID; + +public class TestConstants { + + private static final JsonMapper OBJECT_MAPPER = JsonMapper.builder().build(); + + public static final String TEST_ADMIN_SUBJECT = "test-admin-id"; + + public static final String TEST_CLIENT_SUBJECT = "test-client-id"; + public static final String TEST_ACCOUNT_NAME = "test-account"; + public static final String TEST_NCA_ID = "test-nca-id"; + public static final String TEST_OWNER_ID = "test-owner-id"; + public static final String TEST_OWNER_ID_2 = "test-owner-id-2"; + public static final String TEST_CLIENT_ID = TEST_CLIENT_SUBJECT; + public static final String TEST_CLIENT_SUBJECT_2 = "test-client-id-2"; + public static final String TEST_ACCOUNT_NAME_2 = "test-account-2"; + public static final String TEST_NCA_ID_2 = "test-nca-id-2"; + public static final String TEST_CLIENT_ID_2 = TEST_CLIENT_SUBJECT_2; + public static final String TEST_ACCOUNT_NAME_3 = "test-account-3"; + public static final String TEST_NCA_ID_3 = "test-nca-id-3"; + public static final String TEST_CLIENT_ID_3 = "test-client-id-3"; + public static final String TEST_NCA_ID_WITH_TELEMETRIES_4 = "test-nca-id-with-telemetries-4"; + public static final String TEST_CLIENT_ID_4 = "test-client-id-4"; + public static final String TEST_NCA_ID_WITH_1_MAX_ALLOWED_TASKS_5 = + "test-nca-id-with-1-max-allowed-tasks-5"; + public static final String TEST_CLIENT_ID_5 = "test-client-id-5"; + public static final String TEST_NCA_ID_WITHOUT_REGISTRY_CREDENTIALS_6 = + "test-nca-id-without-registry-credentials-6"; + public static final String TEST_CLIENT_ID_6 = "test-client-id-6"; + + public static final UUID TEST_TASK_ID_1 = + UUID.fromString("571114ac-13a2-4243-8f9f-1ccbee3b374f"); + public static final String TEST_TASK_NAME_1 = "test-task-name-1"; + public static final UUID TEST_TASK_ID_2 = + UUID.fromString("bcaf4c3f-e3dd-464c-a3c7-5c7143555b22"); + public static final String TEST_TASK_NAME_2 = "test-task-name-2"; + public static final UUID TEST_TASK_ID_3 = + UUID.fromString("4ab4a3bf-f151-43b9-bf98-80c1b2f68647"); + public static final UUID TEST_TASK_ID_4 = + UUID.fromString("5bc4a3bf-f151-43b9-bf98-80c1b2f68647"); + public static final UUID TEST_TASK_ID_5 = + UUID.fromString("6ef4a3bf-f151-43b9-bf98-80c1b2f68647"); + public static final String TEST_TASK_NAME_3 = "test-task-name-3"; + public static final UUID FAKE_TASK_ID = + UUID.fromString("c4ec1ef3-2514-4189-9bb0-3f39c9eeff6e"); + + + public static final UUID EVENT_ID_1 = UUID.randomUUID(); + public static final UUID EVENT_ID_2 = UUID.randomUUID(); + public static final UUID EVENT_ID_3 = UUID.randomUUID(); + public static final UUID EVENT_ID_4 = UUID.randomUUID(); + + public static final UUID RESULT_ID_1 = UUID.randomUUID(); + public static final UUID RESULT_ID_2 = UUID.randomUUID(); + public static final UUID RESULT_ID_3 = UUID.randomUUID(); + public static final UUID RESULT_ID_4 = UUID.randomUUID(); + + public static final String TEST_VALID_ORG_NAME = "whw3rcpsilnj"; // "test-valid-org-name" + public static final String TEST_VALID_ORG_NAME_INVALID_KEY = "test-valid-org-invalid-key"; + public static final String TEST_VALID_TEAM_NAME = "jeff"; + public static final String TEST_UNKNOWN_ORG_NAME = "test-unknown-org-name"; + public static final String TEST_UNKNOWN_TEAM_NAME = "test-unknown-team-name"; + public static final String TEST_MODEL_NAME = "test-model-name"; + public static final String TEST_NGC_API_KEY = "nvapi-stg-test-key"; + + public static final String TEST_RESULTS_LOCATION_1 = + TEST_VALID_ORG_NAME + "/" + TEST_VALID_TEAM_NAME + "/" + TEST_MODEL_NAME; + public static final String TEST_RESULTS_LOCATION_2 = + TEST_VALID_ORG_NAME + "/" + TEST_MODEL_NAME; + + public static final UUID TEST_ICMS_REQ_ID_1 = + UUID.fromString("572114ac-13a2-4243-8f9f-1ccbee3b374f"); + public static final UUID TEST_ICMS_REQ_ID_2 = + UUID.fromString("672114ad-13a2-4243-8f9f-1ccbee3b374f"); + public static final UUID TEST_ICMS_REQ_ID_3 = + UUID.fromString("772114ae-13a2-4243-8f9f-1ccbee3b374f"); + public static final UUID TEST_ICMS_REQ_ID_4 = + UUID.fromString("872114ae-13a2-4243-8f9f-1ccbee3b374f"); + public static final UUID TEST_ICMS_REQ_ID_5 = + UUID.fromString("972114ae-13a2-4243-8f9f-1ccbee3b374f"); + + // Backends or Cluster Groups + public static final String GFN = "GFN"; + public static final String OCI = "OCI"; + + // GPUs + public static final String T10 = "T10"; + public static final String L40G = "L40G"; + public static final String A10G = "A10G"; + + // Instance Types + public static final String T10_INSTANCE_TYPE = "g6.full"; + public static final String L40G_INSTANCE_TYPE = "gl40g_1.br25_2xlarge"; + public static final String OCI_L40G_INSTANCE_TYPE = "BM_GPU_L40G-2X"; + + public static final GpuSpecificationDto TEST_GFN_GPU_SPEC_DTO = + GpuSpecificationDto.builder().gpu(L40G).instanceType(L40G_INSTANCE_TYPE) + .backend(GFN).build(); + public static final GpuSpecificationDto TEST_OCI_GPU_SPEC_DTO = + GpuSpecificationDto.builder().gpu(L40G).instanceType(OCI_L40G_INSTANCE_TYPE) + .backend(OCI).build(); + public static final GpuSpecUdt TEST_GFN_GPU_SPEC = + GpuSpecUdt.builder() + .gpu(L40G).instanceType(L40G_INSTANCE_TYPE).backend(GFN).build(); + private static final ObjectNode CONFIGURATION = OBJECT_MAPPER.createObjectNode() + .put("replicas", 5); + public static final GpuSpecificationDto TEST_OCI_GPU_SPEC_HELM_CONFIG_DTO = + GpuSpecificationDto.builder().gpu(L40G).instanceType(OCI_L40G_INSTANCE_TYPE) + .backend(OCI).configuration(CONFIGURATION).build(); + public static final HelmValidationPolicyDto TEST_HELM_VALIDATION_POLICY_DTO = + HelmValidationPolicyDto.builder() + .name(ValidationPolicyNameEnum.DEFAULT) + .extraKubernetesTypes(List.of(HelmValidationPolicyDto.KubernetesType.builder() + .group("apps") + .version("v1") + .kind("Deployment") + .build())) + .build(); + public static final GpuSpecificationDto TEST_OCI_GPU_SPEC_WITH_HELM_POLICY_DTO = + GpuSpecificationDto.builder().gpu(L40G).instanceType(OCI_L40G_INSTANCE_TYPE) + .backend(OCI) + .helmValidationPolicy(TEST_HELM_VALIDATION_POLICY_DTO) + .build(); + + public static final String TEST_CONTAINER_REGISTRY = "stg.nvcr.io"; + public static final String TEST_CONTAINER_REGISTRY_PROD = "nvcr.io"; + public static final String TEST_CONTAINER_REGISTRY_CANARY = "canary.nvcr.io"; + public static final String TEST_HELM_REGISTRY = "helm.stg.ngc.nvidia.com"; + public static final String TEST_HELM_REGISTRY_PROD = "helm.ngc.nvidia.com"; + public static final String TEST_HELM_REGISTRY_CANARY = "helm.canary.ngc.nvidia.com"; + public static final String TEST_ARTIFACT_REGISTRY = "api.stg.ngc.nvidia.com"; + public static final String TEST_ARTIFACT_REGISTRY_PROD = "api.ngc.nvidia.com"; + public static final String TEST_ARTIFACT_REGISTRY_CANARY = "api.canary.ngc.nvidia.com"; + public static final String TEST_DOCKER_REGISTRY = "docker.io"; + public static final String TEST_CONTAINER_ARGS = "test-container-args"; + public static final URI TEST_HELM_CHART = + URI.create("https://%s/%s/%s/charts/%s-%s.tgz".formatted(TEST_HELM_REGISTRY, + TEST_VALID_ORG_NAME, + TEST_VALID_TEAM_NAME, + TEST_VALID_HELM_CHART_NAME, + TEST_VALID_HELM_CHART_VERSION)); + public static final URI TEST_HELM_CHART_WITH_CANARY_HOST = + URI.create("https://%s/%s/%s/charts/%s-%s.tgz" + .formatted(TEST_HELM_REGISTRY_CANARY, + TEST_VALID_ORG_NAME, + TEST_VALID_TEAM_NAME, + TEST_VALID_HELM_CHART_NAME, + TEST_VALID_HELM_CHART_VERSION)); + public static final URI TEST_HELM_CHART_UNKNOWN_REGISTRY = + URI.create( + "https://unknown-registry/%s/%s/charts/%s-%s.tgz" + .formatted(TEST_VALID_ORG_NAME, + TEST_VALID_TEAM_NAME, + TEST_VALID_HELM_CHART_NAME, + TEST_VALID_HELM_CHART_VERSION)); + public static final URI TEST_HELM_CHART_NOT_EXISTS = + URI.create("https://%s/%s/%s/charts/%s-%s.tgz".formatted(TEST_HELM_REGISTRY, + TEST_VALID_ORG_NAME, + TEST_VALID_TEAM_NAME, + TEST_VALID_HELM_CHART_NAME, + TEST_UNKNOWN_HELM_CHART_VERSION)); + public static final URI TEST_HELM_CHART_PERMISSION_DENIED = + URI.create("https://%s/%s/%s/charts/%s-%s.tgz".formatted(TEST_HELM_REGISTRY, + BootTestConstants.TEST_UNKNOWN_ORG_NAME, + TEST_VALID_TEAM_NAME, + TEST_VALID_HELM_CHART_NAME, + TEST_UNKNOWN_HELM_CHART_VERSION)); + public static final URI TEST_HELM_CHART_NOT_SUPPORTED_REGISTRY = + URI.create("https://%s/%s/%s/charts/%s-%s.tgz".formatted("not.support.com", + TEST_VALID_ORG_NAME, + TEST_VALID_TEAM_NAME, + TEST_VALID_HELM_CHART_NAME, + TEST_VALID_HELM_CHART_VERSION)); + public static final URI TEST_CONTAINER_IMAGE = + URI.create(TEST_CONTAINER_REGISTRY + "/%s/%s:%s".formatted(TEST_VALID_ORG_NAME, + TEST_VALID_CONTAINER_NAME, + TEST_VALID_CONTAINER_TAG)); + public static final URI TEST_CONTAINER_IMAGE_WITH_CANARY_HOST = + URI.create(TEST_CONTAINER_REGISTRY_CANARY + "/%s/%s:%s".formatted(TEST_VALID_ORG_NAME, + TEST_VALID_CONTAINER_NAME, + TEST_VALID_CONTAINER_TAG)); + public static final URI TEST_CONTAINER_IMAGE_UNKNOWN_REGISTRY = + URI.create("not-exits/%s/%s:%s".formatted(TEST_VALID_ORG_NAME, + TEST_VALID_CONTAINER_NAME, + TEST_VALID_CONTAINER_TAG)); + public static final URI TEST_CONTAINER_IMAGE_WITHOUT_TAG = + URI.create(TEST_CONTAINER_REGISTRY + "/%s/%s".formatted(TEST_VALID_ORG_NAME, + TEST_VALID_CONTAINER_NAME)); + public static final URI TEST_CONTAINER_IMAGE_WITH_DIGEST = + URI.create(TEST_CONTAINER_REGISTRY + "/%s/%s@%s".formatted(TEST_VALID_ORG_NAME, + TEST_VALID_CONTAINER_NAME, + TEST_VALID_CONTAINER_HASH)); + public static final URI TEST_CONTAINER_IMAGE_NOT_EXISTS = + URI.create(TEST_CONTAINER_REGISTRY + "/%s/%s:%s".formatted(TEST_VALID_ORG_NAME, + TEST_VALID_CONTAINER_NAME, + "not-exists")); + public static final URI TEST_CONTAINER_IMAGE_WITH_INVALID_TAG = + URI.create(TEST_CONTAINER_REGISTRY + "/%s/%s:%s".formatted(TEST_VALID_ORG_NAME, + TEST_VALID_CONTAINER_NAME, + "latest:latest")); + public static final URI TEST_CONTAINER_IMAGE_PERMISSION_DENIED = + URI.create(TEST_CONTAINER_REGISTRY + "/%s/%s:%s".formatted(TEST_VALID_ORG_NAME, + TEST_VALID_CONTAINER_NAME, + "permission-denied")); + public static final URI TEST_CONTAINER_IMAGE_NOT_SUPPORTED = + URI.create("not.supported" + "/%s/%s:%s".formatted(TEST_VALID_ORG_NAME, + TEST_VALID_CONTAINER_NAME, + TEST_VALID_CONTAINER_TAG)); + public static final String BASE_ARTIFACT_URL = "https://" + TEST_ARTIFACT_REGISTRY; + + public static final String MODEL_ARTIFACTS_URL = BASE_ARTIFACT_URL + MODEL_FILES_URL_WITH_TEAM; + public static final String MODEL_ARTIFACTS_URL_2 = + BASE_ARTIFACT_URL + MODEL_FILES_URL_WITH_TEAM_2; + public static final String MODEL_ARTIFACTS_URL_3 = BASE_ARTIFACT_URL + MODEL_FILES_URL; + public static final String MODEL_ARTIFACTS_URL_4 = + BASE_ARTIFACT_URL + MODEL_FILES_URL_WITH_VERSION; + public static final String MODEL_ARTIFACTS_URL_WITH_CANARY_HOST = + "https://" + TEST_ARTIFACT_REGISTRY_CANARY + MODEL_FILES_URL_WITH_TEAM; + public static final String MODEL_ARTIFACTS_URL_UNKNOWN_REGISTRY_1 = + "https://not-exists" + MODEL_FILES_URL_WITH_TEAM; + public static final String MODEL_ARTIFACTS_URL_MISSING_PROTOCOL_1 = + TEST_ARTIFACT_REGISTRY + MODEL_FILES_URL_WITH_TEAM; + public static final String MODEL_ARTIFACTS_URL_NOT_SUPPORTED_REGISTRY_1 = + "https://not.support.com" + MODEL_FILES_URL_WITH_TEAM; + public static final String MODEL_ARTIFACTS_URL_PERMISSION_DENIED_REGISTRY_1 = + BASE_ARTIFACT_URL + MODEL_FILE_PERMISSION_DENIED_URL; + public static final String MODEL_ARTIFACTS_URL_NOT_EXISTS_1 = + BASE_ARTIFACT_URL + MODEL_FILES_NOT_EXIST_URL; + + + public static final String RESOURCE_ARTIFACTS_URL = + BASE_ARTIFACT_URL + RESOURCE_FILES_URL_WITH_TEAM_2; + public static final String RESOURCE_ARTIFACTS_URL_2 = + BASE_ARTIFACT_URL + RESOURCE_FILES_URL_WITH_TEAM; + public static final String RESOURCE_ARTIFACTS_URL_3 = + BASE_ARTIFACT_URL + RESOURCE_FILES_URL; + public static final String RESOURCE_ARTIFACTS_URL_4 = + BASE_ARTIFACT_URL + RESOURCE_FILES_URL_WITH_VERSION; + public static final String RESOURCE_ARTIFACTS_URL_WITH_CANARY_HOST_1 = + BASE_ARTIFACT_URL + RESOURCE_FILES_URL_WITH_TEAM_2; + public static final String RESOURCE_ARTIFACTS_URL_UNKNOWN_REGISTRY_1 = + "https://not-exists" + RESOURCE_FILES_URL_WITH_TEAM_2; + public static final String RESOURCE_ARTIFACTS_URL_MISSING_PROTOCOL_1 = + TEST_ARTIFACT_REGISTRY + RESOURCE_FILES_URL_WITH_TEAM_2; + public static final String RESOURCE_ARTIFACTS_URL_NOT_SUPPORTED_REGISTRY_1 = + "https://not.support.com" + RESOURCE_FILES_URL_WITH_TEAM_2; + public static final String RESOURCE_ARTIFACTS_URL_PERMISSION_DENIED_REGISTRY_1 = + BASE_ARTIFACT_URL + RESOURCE_FILE_PERMISSION_DENIED_URL_WITH_TEAM; + public static final String RESOURCE_ARTIFACTS_URL_NOT_EXISTS_1 = + BASE_ARTIFACT_URL + RESOURCE_FILE_NOT_EXISTS_URL_WITH_TEAM; + + public static final Set TEST_MODELS = + Set.of(ModelUdt.builder() + .name("model-1").version("1.0") + .url(MODEL_ARTIFACTS_URL) + .build(), + ModelUdt.builder() + .name("model-2").version("2.0") + .url(MODEL_ARTIFACTS_URL_2) + .build()); + + public static final Set TEST_MODELS_2 = + Set.of(ModelUdt.builder() + .name("model-1").version("1.0") + .url(MODEL_ARTIFACTS_URL_2) + .build(), + ModelUdt.builder() + .name("model-2").version("2.0") + .url(MODEL_ARTIFACTS_URL) + .build()); + + public static final Set TEST_RESOURCES = + Set.of(ResourceUdt.builder() + .name("resource-1").version("1.0") + .url(RESOURCE_ARTIFACTS_URL) + .build(), + ResourceUdt.builder() + .name("resource-2").version("2.0") + .url(RESOURCE_ARTIFACTS_URL_2) + .build()); + + public static final Set TEST_MODEL_DTOS = + Set.of(ArtifactDto.builder() + .name("model-1").version("1.0") + .uri(URI.create(MODEL_ARTIFACTS_URL)) + .build(), + ArtifactDto.builder() + .name("model-2").version("2.0") + .uri(URI.create(MODEL_ARTIFACTS_URL_2)) + .build()); + + public static final Set TEST_RESOURCE_DTOS = + Set.of(ArtifactDto.builder() + .name("resource-1").version("1.0") + .uri(URI.create(RESOURCE_ARTIFACTS_URL)) + .build(), + ArtifactDto.builder() + .name("resource-2").version("2.0") + .uri(URI.create(RESOURCE_ARTIFACTS_URL_2)) + .build()); + + public static final List TEST_CONTAINER_ENVIRONMENT = + List.of(ContainerEnvironmentEntryDto.builder().key("KEY_1").value("VALUE_1").build(), + ContainerEnvironmentEntryDto.builder().key("KEY_2").value("VALUE_2").build(), + ContainerEnvironmentEntryDto.builder().key("KEY_3").value("VALUE_3").build()); + public static final Key MD_KEY_AUTHORIZATION = Key.of("authorization", + Metadata.ASCII_STRING_MARSHALLER); + + public static final Set TEST_TAGS = Set.of("tag1", "tag2", "tag3"); + public static final String TEST_DESCRIPTION = "test-description"; + + private static final JsonNode JSON_SECRET_VALUE = OBJECT_MAPPER.createObjectNode() + .put("AWS_REGION", "us-west-2") + .put("AWS_BUCKET", "ov-content") + .put("AWS_ACCESS_KEY_ID", "ov-content-key-id") + .put("AWS_SECRET_ACCESS_KEY", "ov-content-access-key") + .put("AWS_SESSION_TOKEN", "ov-content-session-token"); + public static final Set TEST_SECRETS = Set.of(SecretDto.builder() + .name(NGC_API_KEY) + .value(new StringNode( + "shhh!shhh!")) + .build(), + SecretDto.builder() + .name("secret2") + .value(JSON_SECRET_VALUE) + .build()); + + // Telemetry UUIDs are referred in + // src/test/java/resources/fixtures/nvcf/account-with-telemetries-response.json file. + public static final UUID TEST_TELEMETRY_LOGS_ID = + UUID.fromString("4df8cb5b-94e0-4fcc-ac12-ddb8da2f25aa"); + public static final UUID TEST_TELEMETRY_METRICS_ID = + UUID.fromString("d49695b0-86b1-4a84-9b82-2ea823f51d78"); + public static final UUID TEST_TELEMETRY_TRACES_ID = + UUID.fromString("edc4cd0a-80cd-4a7b-90d9-706b9eae9b4c"); + public static final String TEST_TELEMETRY_ENDPOINT = + "http://example-telemetry.test.com/endpoint"; + public static final String BASE64_CONTAINER_REGISTRY_CRED = + Base64.getEncoder() + .encodeToString("$oauthtoken:nvapi-stg-test-container-registry-cred" + .getBytes(UTF_8)); + public static final String BASE64_HELM_REGISTRY_CRED = + Base64.getEncoder() + .encodeToString("$oauthtoken:nvapi-stg-test-helm-registry-cred" + .getBytes(UTF_8)); + public static final String BASE64_MODEL_REGISTRY_CRED = + Base64.getEncoder() + .encodeToString("$oauthtoken:nvapi-stg-test-model-registry-cred" + .getBytes(UTF_8)); + public static final String BASE64_SIDECAR_REGISTRY_CRED = Base64.getEncoder().encodeToString( + "$oauthtoken:nvapi-stg-test-sidecar-cred".getBytes( + StandardCharsets.UTF_8)); + public static final RegistryCredentialDto TEST_NGC_CONTAINER_REGISTRY = + RegistryCredentialDto.builder() + .artifactTypes(Set.of(ArtifactTypeEnum.CONTAINER)) + .registryHostname(TEST_CONTAINER_REGISTRY) + .secret(SecretDto.builder() + .name("container-registry-cred-for-org1") + .value(new StringNode(BASE64_CONTAINER_REGISTRY_CRED)) + .build()) + .build(); + public static final RegistryCredentialDto TEST_NGC_MODEL_REGISTRY = + RegistryCredentialDto.builder() + .artifactTypes(Set.of(ArtifactTypeEnum.MODEL)) + .registryHostname(TEST_ARTIFACT_REGISTRY) + .secret(SecretDto.builder() + .name("model-registry-cred-for-org1") + .value(new StringNode(BASE64_MODEL_REGISTRY_CRED)) + .build()) + .build(); + public static final RegistryCredentialDto + TEST_NGC_HELM_REGISTRY = RegistryCredentialDto.builder() + .artifactTypes(Set.of(ArtifactTypeEnum.HELM)) + .registryHostname(TEST_HELM_REGISTRY) + .secret(SecretDto.builder() + .name("helm-registry-cred-for-org1") + .value(new StringNode(BASE64_HELM_REGISTRY_CRED)) + .build()) + .build(); + public static final String BASE64_ENCODED_DOCKER_CRED = Base64.getEncoder() + .encodeToString("username:docker-pat-password".getBytes(UTF_8)); + public static final RegistryCredentialDto + TEST_DOCKER_CONTAINER_REGISTRY = RegistryCredentialDto.builder() + .artifactTypes(Set.of(ArtifactTypeEnum.CONTAINER)) + .registryHostname("docker.io") + .secret(SecretDto.builder() + .name("cred-for-docker-acct-foo") + .value(new StringNode(BASE64_ENCODED_DOCKER_CRED)) + .build()) + .build(); + public static final String BASE64_ENCODED_ECR_PRIVATE_CRED = Base64.getEncoder() + .encodeToString("access-key-id-1:secret-access-key-1".getBytes(UTF_8)); + public static final String BASE64_ENCODED_ECR_PUBLIC_CRED = Base64.getEncoder() + .encodeToString("access-key-id-1:secret-access-key-1".getBytes(UTF_8)); + public static final String BASE64_ENCODED_VOLCENGINE_CRED = Base64.getEncoder() + .encodeToString("volcengine-access-key-1:volcengine-secret-key-1".getBytes(UTF_8)); + public static final String BASE64_ENCODED_ACR_CRED = Base64.getEncoder() + .encodeToString("acr-client-id-1:acr-client-secret-1".getBytes(UTF_8)); + public static final String BASE64_ENCODED_HARBOR_CRED = Base64.getEncoder() + .encodeToString("harbor-robot-account:harbor-robot-password".getBytes(UTF_8)); + public static final String BASE64_ENCODED_ARTIFACTORY_CRED = Base64.getEncoder() + .encodeToString("artifactory-username:artifactory-password".getBytes(UTF_8)); + + public static final String TEST_CUSTOM_REGISTRY_NAME_1 = "custom-1"; + public static final String TEST_CUSTOM_REGISTRY_HOST_NAME_1 = "custom-registry-test-1.com"; + public static final URI TEST_CUSTOM_CONTAINER_IMAGE_WITH_TAG_1 = + URI.create(TEST_CUSTOM_REGISTRY_HOST_NAME_1 + "/%s:%s" + .formatted(TEST_VALID_OCI_IMAGE_NAME, TEST_VALID_OCI_IMAGE_TAG_NAME)); + public static final URI TEST_CUSTOM_HELM_CHART_WITH_TAG_1 = + URI.create("oci://" + TEST_CUSTOM_REGISTRY_HOST_NAME_1 + "/%s:%s" + .formatted(TEST_VALID_OCI_HELM_CHART_NAME, TEST_VALID_OCI_HELM_CHART_TAG_NAME)); +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/util/TestRegistryService.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/util/TestRegistryService.java new file mode 100644 index 000000000..c9c88e181 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/util/TestRegistryService.java @@ -0,0 +1,244 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.util; + +import static com.nvidia.boot.mock.BootTestConstants.TEST_ARTIFACTORY_REGISTRY; +import static com.nvidia.boot.mock.BootTestConstants.TEST_HARBOR_REGISTRY; +import static com.nvidia.boot.registries.service.registry.client.acr.AzureRegistryClient.AZURE_REGISTRY_GLOBAL_HOSTNAME; +import static com.nvidia.boot.registries.service.registry.client.ecr.EcrRegistryUtils.ECR_PRIVATE_REGISTRY_GLOBAL_HOSTNAME; +import static com.nvidia.boot.registries.service.registry.client.ecr.EcrRegistryUtils.ECR_PUBLIC_REGISTRY_HOSTNAME; +import static com.nvidia.boot.registries.service.registry.client.volcengine.VolcengineRegistryUtils.VOLCENGINE_REGISTRY_GLOBAL_HOSTNAME; +import static com.nvidia.boot.registries.util.RegistriesConstants.ACR_REGISTRY_NAME; +import static com.nvidia.boot.registries.util.RegistriesConstants.ARTIFACTORY_REGISTRY_NAME; +import static com.nvidia.boot.registries.util.RegistriesConstants.DOCKER_REGISTRY_NAME; +import static com.nvidia.boot.registries.util.RegistriesConstants.ECR_PRIVATE_REGISTRY_NAME; +import static com.nvidia.boot.registries.util.RegistriesConstants.ECR_PUBLIC_REGISTRY_NAME; +import static com.nvidia.boot.registries.util.RegistriesConstants.HARBOR_REGISTRY_NAME; +import static com.nvidia.boot.registries.util.RegistriesConstants.NGC_PRIVATE_REGISTRY_NAME; +import static com.nvidia.boot.registries.util.RegistriesConstants.VOLCENGINE_REGISTRY_NAME; +import static com.nvidia.nvct.util.TestConstants.BASE_ARTIFACT_URL; +import static com.nvidia.nvct.util.TestConstants.TEST_ARTIFACT_REGISTRY; +import static com.nvidia.nvct.util.TestConstants.TEST_CONTAINER_REGISTRY; +import static com.nvidia.nvct.util.TestConstants.TEST_DOCKER_REGISTRY; +import static com.nvidia.nvct.util.TestConstants.TEST_HELM_REGISTRY; + +import com.nvidia.boot.registries.service.registry.RegistryLookupService; +import com.nvidia.boot.registries.service.registry.RegistryMapperService; +import com.nvidia.boot.registries.service.registry.container.ContainerRegistryService; +import com.nvidia.boot.registries.service.registry.helm.HelmRegistryService; +import com.nvidia.boot.registries.service.registry.model.ModelRegistryService; +import com.nvidia.boot.registries.service.registry.resource.ResourceRegistryService; +import java.net.URI; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +@Service +public class TestRegistryService { + + private final ModelRegistryService modelRegistryService; + private final ResourceRegistryService resourceRegistryService; + private final HelmRegistryService helmRegistryService; + private final ContainerRegistryService containerRegistryService; + private final RegistryLookupService registryLookupService; + private final RegistryMapperService registryMapperService; + + public TestRegistryService( + ModelRegistryService modelRegistryService, + ResourceRegistryService resourceRegistryService, + HelmRegistryService helmRegistryService, + ContainerRegistryService containerRegistryService, + RegistryLookupService registryLookupService, + RegistryMapperService registryMapperService, + @Value("${nvct.registries.recognized.container.ngc.hostname}") + String ngcContainerRegistryHostname, + @Value("${nvct.registries.recognized.model.ngc.hostname}") + String casBaseUrl, + @Value("${nvct.registries.recognized.container.docker.hostname}") + String dockerBaseUrl, + @Value("${nvct.registries.recognized.container.ecr.hostname}") + String ecrPrivateHostname, + @Value("${nvct.registries.recognized.container.ecr-public.hostname}") + String ecrPublicHostname, + @Value("${nvct.registries.recognized.container.volcengine.hostname}") + String volcengineHostname, + @Value("${nvct.registries.recognized.container.acr.hostname}") + String acrHostname, + @Value("${nvct.registries.recognized.container.harbor.hostname}") + String harborHostname, + @Value("${nvct.registries.recognized.container.artifactory.hostname}") + String artifactoryHostname) { + this.modelRegistryService = modelRegistryService; + this.resourceRegistryService = resourceRegistryService; + this.helmRegistryService = helmRegistryService; + this.containerRegistryService = containerRegistryService; + this.registryLookupService = registryLookupService; + this.registryMapperService = registryMapperService; + + updateNgcRegistryHostname(ngcContainerRegistryHostname, casBaseUrl); + updateDockerRegistryHostname(dockerBaseUrl); + updateEcrPrivateRegistryHostname(ecrPrivateHostname); + updateEcrPublicRegistryHostname(ecrPublicHostname); + updateVolcengineRegistryHostname(volcengineHostname); + updateAcrRegistryHostname(acrHostname); + updateHarborRegistryHostname(harborHostname); + updateArtifactoryRegistryHostname(artifactoryHostname); + } + + private void updateNgcRegistryHostname(String ngcContainerRegistryHostname, String casBaseUrl) { + modelRegistryService.overwriteRegistryHostnameMap( + URI.create(casBaseUrl).getHost(), + URI.create(BASE_ARTIFACT_URL).getHost()); + resourceRegistryService.overwriteRegistryHostnameMap( + URI.create(casBaseUrl).getHost(), + URI.create(BASE_ARTIFACT_URL).getHost()); + helmRegistryService.overwriteRegistryHostnameMap( + URI.create(casBaseUrl).getHost(), TEST_HELM_REGISTRY); + containerRegistryService.overwriteRegistryHostnameMap( + URI.create(ngcContainerRegistryHostname).getHost(), TEST_CONTAINER_REGISTRY); + registryLookupService.updateContainerRegistryConfigMap( + ngcContainerRegistryHostname, TEST_CONTAINER_REGISTRY); + registryLookupService.updateContainerRegistryMap( + NGC_PRIVATE_REGISTRY_NAME, TEST_CONTAINER_REGISTRY); + registryLookupService.updateHelmRegistryConfigMap( + casBaseUrl, TEST_HELM_REGISTRY); + registryLookupService.updateHelmRegistryMap( + NGC_PRIVATE_REGISTRY_NAME, TEST_HELM_REGISTRY); + registryLookupService.updateModelRegistryConfigMap( + casBaseUrl, TEST_ARTIFACT_REGISTRY); + registryLookupService.updateModelRegistryMap( + NGC_PRIVATE_REGISTRY_NAME, TEST_ARTIFACT_REGISTRY); + registryLookupService.updateResourceRegistryConfigMap( + casBaseUrl, TEST_ARTIFACT_REGISTRY); + registryLookupService.updateResourceRegistryMap( + NGC_PRIVATE_REGISTRY_NAME, TEST_ARTIFACT_REGISTRY); + registryMapperService.updateNgcContainerRegistryHostname(TEST_CONTAINER_REGISTRY); + registryMapperService.updateNgcArtifactRegistryHostname(TEST_ARTIFACT_REGISTRY); + registryMapperService.updateNgcHelmRegistryHostname(TEST_HELM_REGISTRY); + } + + private void updateDockerRegistryHostname(String dockerBaseUrl) { + containerRegistryService.overwriteRegistryHostnameMap( + URI.create(dockerBaseUrl).getHost(), TEST_DOCKER_REGISTRY); + registryLookupService.updateContainerRegistryConfigMap( + dockerBaseUrl, TEST_DOCKER_REGISTRY); + registryLookupService.updateContainerRegistryMap( + DOCKER_REGISTRY_NAME, TEST_DOCKER_REGISTRY); + + helmRegistryService.overwriteRegistryHostnameMap( + URI.create(dockerBaseUrl).getHost(), TEST_DOCKER_REGISTRY); + registryLookupService.updateHelmRegistryConfigMap( + dockerBaseUrl, TEST_DOCKER_REGISTRY); + registryLookupService.updateHelmRegistryMap( + DOCKER_REGISTRY_NAME, TEST_DOCKER_REGISTRY); + } + + private void updateEcrPrivateRegistryHostname(String ecrPrivateHostname) { + containerRegistryService.overwriteRegistryHostnameMap( + URI.create(ecrPrivateHostname).getHost(), ECR_PRIVATE_REGISTRY_GLOBAL_HOSTNAME); + registryLookupService.updateContainerRegistryConfigMap( + ecrPrivateHostname, ECR_PRIVATE_REGISTRY_GLOBAL_HOSTNAME); + registryLookupService.updateContainerRegistryMap( + ECR_PRIVATE_REGISTRY_NAME, ECR_PRIVATE_REGISTRY_GLOBAL_HOSTNAME); + + helmRegistryService.overwriteRegistryHostnameMap( + URI.create(ecrPrivateHostname).getHost(), ECR_PRIVATE_REGISTRY_GLOBAL_HOSTNAME); + registryLookupService.updateHelmRegistryConfigMap( + ecrPrivateHostname, ECR_PRIVATE_REGISTRY_GLOBAL_HOSTNAME); + registryLookupService.updateHelmRegistryMap( + ECR_PRIVATE_REGISTRY_NAME, ECR_PRIVATE_REGISTRY_GLOBAL_HOSTNAME); + } + + private void updateEcrPublicRegistryHostname(String ecrPublicHostname) { + containerRegistryService.overwriteRegistryHostnameMap( + URI.create(ecrPublicHostname).getHost(), ECR_PUBLIC_REGISTRY_HOSTNAME); + registryLookupService.updateContainerRegistryConfigMap( + ecrPublicHostname, ECR_PUBLIC_REGISTRY_HOSTNAME); + registryLookupService.updateContainerRegistryMap( + ECR_PUBLIC_REGISTRY_NAME, ECR_PUBLIC_REGISTRY_HOSTNAME); + + helmRegistryService.overwriteRegistryHostnameMap( + URI.create(ecrPublicHostname).getHost(), ECR_PUBLIC_REGISTRY_HOSTNAME); + registryLookupService.updateHelmRegistryConfigMap( + ecrPublicHostname, ECR_PUBLIC_REGISTRY_HOSTNAME); + registryLookupService.updateHelmRegistryMap( + ECR_PUBLIC_REGISTRY_NAME, ECR_PUBLIC_REGISTRY_HOSTNAME); + } + + private void updateVolcengineRegistryHostname(String volcengineHostname) { + containerRegistryService.overwriteRegistryHostnameMap( + URI.create(volcengineHostname).getHost(), VOLCENGINE_REGISTRY_GLOBAL_HOSTNAME); + registryLookupService.updateContainerRegistryConfigMap( + volcengineHostname, VOLCENGINE_REGISTRY_GLOBAL_HOSTNAME); + registryLookupService.updateContainerRegistryMap( + VOLCENGINE_REGISTRY_NAME, VOLCENGINE_REGISTRY_GLOBAL_HOSTNAME); + + helmRegistryService.overwriteRegistryHostnameMap( + URI.create(volcengineHostname).getHost(), VOLCENGINE_REGISTRY_GLOBAL_HOSTNAME); + registryLookupService.updateHelmRegistryConfigMap( + volcengineHostname, VOLCENGINE_REGISTRY_GLOBAL_HOSTNAME); + registryLookupService.updateHelmRegistryMap( + VOLCENGINE_REGISTRY_NAME, VOLCENGINE_REGISTRY_GLOBAL_HOSTNAME); + } + + private void updateAcrRegistryHostname(String acrHostname) { + containerRegistryService.overwriteRegistryHostnameMap( + URI.create(acrHostname).getHost(), AZURE_REGISTRY_GLOBAL_HOSTNAME); + registryLookupService.updateContainerRegistryConfigMap( + acrHostname, AZURE_REGISTRY_GLOBAL_HOSTNAME); + registryLookupService.updateContainerRegistryMap( + ACR_REGISTRY_NAME, AZURE_REGISTRY_GLOBAL_HOSTNAME); + + helmRegistryService.overwriteRegistryHostnameMap( + URI.create(acrHostname).getHost(), AZURE_REGISTRY_GLOBAL_HOSTNAME); + registryLookupService.updateHelmRegistryConfigMap( + acrHostname, AZURE_REGISTRY_GLOBAL_HOSTNAME); + registryLookupService.updateHelmRegistryMap( + ACR_REGISTRY_NAME, AZURE_REGISTRY_GLOBAL_HOSTNAME); + } + + private void updateHarborRegistryHostname(String harborHostname) { + containerRegistryService.overwriteRegistryHostnameMap( + URI.create(harborHostname).getHost(), TEST_HARBOR_REGISTRY); + registryLookupService.updateContainerRegistryConfigMap( + harborHostname, TEST_HARBOR_REGISTRY); + registryLookupService.updateContainerRegistryMap( + HARBOR_REGISTRY_NAME, TEST_HARBOR_REGISTRY); + + helmRegistryService.overwriteRegistryHostnameMap( + URI.create(harborHostname).getHost(), TEST_HARBOR_REGISTRY); + registryLookupService.updateHelmRegistryConfigMap( + harborHostname, TEST_HARBOR_REGISTRY); + registryLookupService.updateHelmRegistryMap( + HARBOR_REGISTRY_NAME, TEST_HARBOR_REGISTRY); + } + + private void updateArtifactoryRegistryHostname(String artifactoryHostname) { + containerRegistryService.overwriteRegistryHostnameMap( + URI.create(artifactoryHostname).getHost(), TEST_ARTIFACTORY_REGISTRY); + registryLookupService.updateContainerRegistryConfigMap( + artifactoryHostname, TEST_ARTIFACTORY_REGISTRY); + registryLookupService.updateContainerRegistryMap( + ARTIFACTORY_REGISTRY_NAME, TEST_ARTIFACTORY_REGISTRY); + + helmRegistryService.overwriteRegistryHostnameMap( + URI.create(artifactoryHostname).getHost(), TEST_ARTIFACTORY_REGISTRY); + registryLookupService.updateHelmRegistryConfigMap( + artifactoryHostname, TEST_ARTIFACTORY_REGISTRY); + registryLookupService.updateHelmRegistryMap( + ARTIFACTORY_REGISTRY_NAME, TEST_ARTIFACTORY_REGISTRY); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/util/TestUtil.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/util/TestUtil.java new file mode 100644 index 000000000..117bafd04 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/util/TestUtil.java @@ -0,0 +1,194 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct.util; + +import static com.nvidia.nvct.rest.task.dto.ValidationPolicyNameEnum.UNRESTRICTED; +import static com.nvidia.nvct.util.NvctConstants.SCOPE_LIST_TASKS; +import static com.nvidia.nvct.util.TestConstants.TEST_CONTAINER_ARGS; +import static com.nvidia.nvct.util.TestConstants.TEST_CONTAINER_ENVIRONMENT; +import static com.nvidia.nvct.util.TestConstants.TEST_CONTAINER_IMAGE; +import static com.nvidia.nvct.util.TestConstants.TEST_MODELS; +import static com.nvidia.nvct.util.TestConstants.TEST_RESOURCES; +import static com.nvidia.nvct.util.TestConstants.TEST_RESULTS_LOCATION_1; + +import com.nimbusds.jwt.JWTParser; +import com.nvidia.nvct.persistence.task.entity.GpuSpecUdt; +import com.nvidia.nvct.persistence.task.entity.ResultHandlingStrategy; +import com.nvidia.nvct.persistence.task.entity.TaskEntity; +import com.nvidia.nvct.persistence.task.entity.TaskStatus; +import com.nvidia.nvct.rest.task.dto.HealthDto; +import com.nvidia.nvct.rest.task.dto.HelmValidationPolicyDto; +import java.time.Duration; +import java.time.Instant; +import java.util.Base64; +import java.util.List; +import java.util.Optional; +import java.util.Set; +import java.util.UUID; +import java.util.function.Supplier; +import lombok.SneakyThrows; +import org.apache.commons.lang3.StringUtils; +import org.springframework.core.io.ClassPathResource; +import org.testcontainers.containers.ContainerState; +import tools.jackson.databind.json.JsonMapper; + +public class TestUtil { + + @SneakyThrows + public static byte[] readFileAsBytes(String pathToFile) { + return new ClassPathResource(pathToFile).getContentAsByteArray(); + } + + @SneakyThrows + public static String readFileAsString(String pathToFile) { + return new String(readFileAsBytes(pathToFile)); + } + + public static String getContainerUrl(ContainerState containerState, int port) { + return "http://" + containerState.getHost() + ":" + containerState.getMappedPort(port); + } + + + @SneakyThrows + public static boolean isListTasksScopeInToken(String token) { + if (StringUtils.isBlank(token) || token.startsWith("nvapi")) { + return false; + } + + var jwt = JWTParser.parse(token); + var scopes = (List) jwt.getJWTClaimsSet().getClaim("scopes"); + return scopes.stream().anyMatch(scope -> scope.endsWith(SCOPE_LIST_TASKS)); + } + + public static String getToken(Object tokenSupplier) { + if (tokenSupplier instanceof Supplier) { + return (String) ((Supplier) tokenSupplier).get(); + } + return (String) tokenSupplier; + } + + @SneakyThrows + public static TaskEntity createContainerBasedTaskEntity( + UUID id, + String ncaId, + String name, + TaskStatus status, + JsonMapper jsonMapper) { + if (status == null) { + status = TaskStatus.QUEUED; + } + return TaskEntity.builder() + .taskId(id) + .ncaId(ncaId) + .name(name) + .status(status) + .percentComplete(80) + .health(testHealth()) + .createdAt(Instant.now()) + .lastUpdatedAt(Instant.now().plusSeconds(5)) + .lastHeartbeatAt(Instant.now().plusSeconds(10)) + .description("task-description") + .tags(Set.of("tag1", "tag2")) + .containerArgs(TEST_CONTAINER_ARGS) + .containerImage(TEST_CONTAINER_IMAGE.toString()) + .containerEnvironment( + Base64.getEncoder().encodeToString( + jsonMapper.writeValueAsBytes(TEST_CONTAINER_ENVIRONMENT))) + .models(TEST_MODELS) + .resources(TEST_RESOURCES) + .maxRuntimeDuration(Duration.parse("PT7H")) + .maxQueuedDuration(Duration.parse("PT24H")) + .terminalGracePeriodDuration(Duration.parse("PT1H")) + .gpuSpec(GpuSpecUdt.builder() + .backend("GFN").gpu("T10").instanceType("g6.full") + .clusters(Set.of("cluster01", "cluster02")) + .helmValidationPolicy( + jsonMapper.writeValueAsString(buildHelmValidationPolicyDto())) + .build()) + .resultHandlingStrategy(ResultHandlingStrategy.UPLOAD) + .resultsLocation(TEST_RESULTS_LOCATION_1) + .build(); + } + + public static TaskEntity createTaskEntity( + UUID id, + String ncaId, + String name, + JsonMapper jsonMapper) { + return createContainerBasedTaskEntity(id, ncaId, name, null, jsonMapper); + } + + @SneakyThrows + public static TaskEntity createHelmBasedTaskEntity( + UUID id, + String ncaId, + String name, + JsonMapper jsonMapper) { + return TaskEntity.builder() + .taskId(id) + .ncaId(ncaId) + .name(name) + .status(TaskStatus.QUEUED) + .percentComplete(80) + .health(testHealth()) + .createdAt(Instant.now()) + .lastUpdatedAt(Instant.now().plusSeconds(5)) + .lastHeartbeatAt(Instant.now().plusSeconds(10)) + .description("task-description") + .tags(Set.of("tag1", "tag2")) + .helmChart(TestConstants.TEST_HELM_CHART.toString()) + .containerEnvironment( + Base64.getEncoder().encodeToString( + jsonMapper.writeValueAsBytes(TEST_CONTAINER_ENVIRONMENT))) + .models(TEST_MODELS) + .resources(TEST_RESOURCES) + .maxRuntimeDuration(Duration.parse("PT7H")) + .maxQueuedDuration(Duration.parse("PT24H")) + .terminalGracePeriodDuration(Duration.parse("PT1H")) + .gpuSpec(GpuSpecUdt.builder() + .backend("GFN").gpu("T10").instanceType("g6.full") + .clusters(Set.of("cluster01", "cluster02")) + .helmValidationPolicy( + jsonMapper.writeValueAsString(buildHelmValidationPolicyDto())) + .build()) + .resultHandlingStrategy(ResultHandlingStrategy.UPLOAD) + .resultsLocation(TEST_RESULTS_LOCATION_1) + .build(); + } + + public static HelmValidationPolicyDto buildHelmValidationPolicyDto() { + return HelmValidationPolicyDto.builder() + .name(UNRESTRICTED) + .extraKubernetesTypes(List.of( + HelmValidationPolicyDto.KubernetesType.builder() + .group("apps").version("v1").kind("Deployment").build(), + HelmValidationPolicyDto.KubernetesType.builder() + .group("").version("v1").kind("Service").build())) + .build(); + } + + @SneakyThrows + private static String testHealth() { + return Optional.of(new JsonMapper().writeValueAsString(HealthDto.builder() + .backend("GFN") + .gpu("T10") + .instanceType("g6.full") + .error("error-message") + .build())) + .orElseThrow(); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/resources/application-test.yaml b/src/control-plane-services/cloud-tasks/nvct-core/src/test/resources/application-test.yaml new file mode 100644 index 000000000..54575a536 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/resources/application-test.yaml @@ -0,0 +1,350 @@ +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +# +# 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. +spring.main.allow-bean-definition-overriding: true + +# Faster JVM exit after integration tests (avoids Surefire fork exit timeout when many +# @SpringBootTest contexts shut down gRPC + Tomcat + file watchers sequentially). +server: + shutdown: immediate + +grpc: + server: + port: 0 # Random port to avoid BindException when running multiple integration tests + +management: + tracing: + export: + enabled: false + sampling: + probability: 1.0 + opentelemetry: + tracing: + export: + otlp: + endpoint: https://dummy:8282 + endpoints: + web: + base-path: /actuator + exposure: + include: health,metrics,prometheus + endpoint: + health: + cache: + time-to-live: 2s + probes: + enabled: true + show-details: always + group: + readiness: + include: + - readinessState + - cassandra + liveness: + include: + - livenessState + - cassandra + health: + livenessState: + enabled: true + readinessState: + enabled: true + vault: + enabled: false + kubernetes: + enabled: false + metrics: + enable: + all: true + tags: + env: ${spring.application.env} + micro_service: ${spring.application.name} + service_version: ${spring.application.version} + host_id: ${spring.application.host.id} + host_dc: ${spring.application.host.dc} + prometheus: + metrics: + export: + enabled: true + observations: + annotations: + enabled: true + server: + port: 8181 + +spring: + lifecycle: + timeout-per-shutdown-phase: 5s + cassandra: + contact-points: 127.0.0.1 + keyspace-name: nvct + username: ${kv.cassandra.username} + password: ${kv.cassandra.password} + request: + timeout: 30s + security: + oauth2: + resourceserver: + jwt: + issuer-uri: http://localhost:9092 + jwk-set-uri: ${spring.security.oauth2.resourceserver.jwt.issuer-uri}/.well-known/jwks.json + jws-algorithms: ES256 + client: + registration: + # API Keys - used for authorizing requests + api-keys: + provider: api-keys + client-id: ${kv.oauth2.client-id} + client-secret: ${kv.oauth2.client-secret} + authorization-grant-type: client_credentials + scope: pdp-evaluate + # ICMS(Instance and Cluster Management Service) - used for instance and cluster management + icms: + provider: icms + client-id: ${kv.oauth2.client-id} + client-secret: ${kv.oauth2.client-secret} + authorization-grant-type: client_credentials + scope: instance-request,cluster_listing,instance_types,cluster-management + # NVCF API - used for account setup + nvcf: + provider: nvcf + client-id: ${kv.oauth2.client-id} + client-secret: ${kv.oauth2.client-secret} + authorization-grant-type: client_credentials + scope: account_setup + # Notary Service - used for token assertions + notary: + provider: notary + client-id: ${kv.oauth2.client-id} + client-secret: ${kv.oauth2.client-secret} + authorization-grant-type: client_credentials + scope: make-assertion + # ESS (Enterprise Secret Service) - used for secrets management + ess: + provider: ess + client-id: ${kv.oauth2.client-id} + client-secret: ${kv.oauth2.client-secret} + authorization-grant-type: client_credentials + scope: ess:secrets-admin,ess:entities-admin + # Reval Service - used for Helm chart validation + reval: + provider: reval + client-id: ${kv.oauth2.client-id} + client-secret: ${kv.oauth2.client-secret} + authorization-grant-type: client_credentials + scope: helmreval:validate + provider: + api-keys: + token-uri: ${spring.security.oauth2.resourceserver.jwt.issuer-uri}/token + icms: + token-uri: ${spring.security.oauth2.resourceserver.jwt.issuer-uri}/token + nvcf: + token-uri: ${spring.security.oauth2.resourceserver.jwt.issuer-uri}/token + notary: + token-uri: ${spring.security.oauth2.resourceserver.jwt.issuer-uri}/token + ess: + token-uri: ${spring.security.oauth2.resourceserver.jwt.issuer-uri}/token + reval: + token-uri: ${spring.security.oauth2.resourceserver.jwt.issuer-uri}/token + +logging: + level: + root: WARN # To see [AUDIT] logs in stdout, this should be set to INFO + com.nvidia: DEBUG + com.nvidia.nvct.configuration: INFO + com.nvidia.nvct.util: INFO + # Default org.springframework.web: DEBUG would log full MethodArgumentNotValidException text + # (including multi‑KB rejected values) from ExceptionHandlerExceptionResolver. + org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver: INFO + # RestTemplate at DEBUG logs full serialized objects (e.g. CreateTaskRequest with multi‑KB secrets). + org.springframework.web.client.RestTemplate: INFO + # HttpLogging at DEBUG logs request/response bodies (same risk as RestTemplate for tests using testRestTemplate). + org.springframework.web.HttpLogging: INFO + org.springframework.web: DEBUG + org.springframework.data.cassandra.core.cql.CqlTemplate: INFO + +nvct: + fqdn: http://localhost:${server.port} + global-fqdn-grpc: http://localhost:9090 + sidecars: + tracing-key: ${kv.worker-tracing} + hostname: fake.registry.test + image-pull-secret: ${kv.sidecars.image-pull-secret} + init-container: stg.nvcr.io/nv-cf/nvcf-core/nvcf_worker_init:0.7.0 + utils-container: stg.nvcr.io/nv-cf/nvcf-core/nvcf_worker_utils:2.2.1 + otel-container: docker.io/otel/opentelemetry-collector:0.74.0 + ess-agent-container: stg.nvcr.io/nv-cf/nvcf-core/ess-agent:0.0.4 + otel-collector-container: stg.nvcr.io/nv-cf/nvcf-core/byoo-otel-collector:1.2.3 + aws: + region: us-east-1 + ess: + base-url: http://localhost:9098 + notary: + audiences: + ess: dummy-ess-audience + nvct: dummy-nvct-audience + base-url: http://localhost:9097 + jwt: + issuer-uri: ${nvct.notary.base-url} + jwk-set-uri: ${nvct.notary.jwt.issuer-uri}/.well-known/jwks.json + nvcf: + base-url: http://localhost:9119 + cache-ttl: PT1S + reval: + base-url: http://localhost:9099 + icms: + base-url: http://localhost:9096 + allocator: + enabled: true + api-keys: + base-url: http://localhost:9093 + rate-limiters: + account-rate-limiter: + allowed-invocations-per-second: 200 + task-rate-limiter: + allowed-invocations-per-second: 200 + scheduled-routines: + enabled: true + lock-consistency: QUORUM + clean-terminal-tasks-routine: + enabled: false + monitor-launched-tasks-routine: + enabled: false + monitor-queued-tasks-routine: + enabled: false + monitor-worker-heartbeat-routine: + enabled: false + registries: + recognized: + container: + docker: + name: "Docker Hub Registry" + hostname: http://localhost-docker:9101 + call-timeout: PT10S + oauth2: + base-url: http://localhost:9102 + group-scope: pull + ngc: + name: "NGC Private Registry" + hostname: "http://localhost-ngc:9100" + call-timeout: PT60S + read-timeout: PT30S + write-timeout: PT30S + connection-timeout: PT60S + ecr: + name: "AWS ECR Private Registry" + hostname: http://localhost-ecr:9103 + call-timeout: PT10S + ecr-public: + name: "AWS ECR Public Registry" + hostname: http://localhost-ecr-public:9104 + call-timeout: PT10S + volcengine: + name: "Volcano Engine Registry" + hostname: http://localhost-volcengine:9105 + call-timeout: PT10S + acr: + name: "Azure Container Registry" + hostname: http://localhost-acr:9106 + call-timeout: PT10S + oauth2: + base-url: http://localhost-acr:9107 + harbor: + name: "Harbor Registry" + hostname: http://localhost-harbor:9108 + call-timeout: PT10S + oauth2: + base-url: http://localhost:9109 + artifactory: + name: "Artifactory Registry" + hostname: http://localhost-artifactory:9110 + call-timeout: PT10S + oauth2: + base-url: http://localhost-artifactory:9111 + custom-1: + name: "Custom Registry Test 1" + hostname: "custom-registry-test-1.com" + helm: + ngc: + name: "NGC Private Registry" + hostname: "http://localhost-ngc:9094" + call-timeout: PT60S + read-timeout: PT30S + write-timeout: PT30S + connection-timeout: PT60S + oauth2: + base-url: "http://localhost:9095" + group-scope: ngc-stg + docker: + name: "Docker Hub Registry" + hostname: http://localhost-docker:9101 + call-timeout: PT10S + oauth2: + base-url: http://localhost:9102 + group-scope: pull + ecr: + name: "AWS ECR Private Registry" + hostname: http://localhost-ecr:9103 + call-timeout: PT10S + ecr-public: + name: "AWS ECR Public Registry" + hostname: http://localhost-ecr-public:9104 + call-timeout: PT10S + volcengine: + name: "Volcano Engine Registry" + hostname: http://localhost-volcengine:9105 + call-timeout: PT10S + acr: + name: "Azure Container Registry" + hostname: http://localhost-acr:9106 + call-timeout: PT10S + oauth2: + base-url: http://localhost-acr:9107 + harbor: + name: "Harbor Registry" + hostname: http://localhost-harbor:9108 + call-timeout: PT10S + oauth2: + base-url: http://localhost:9109 + artifactory: + name: "JFrog Artifactory" + hostname: http://localhost-artifactory:9110 + call-timeout: PT10S + oauth2: + base-url: http://localhost-artifactory:9111 + custom-1: + name: "Custom Registry Test 1" + hostname: "custom-registry-test-1.com" + model: + ngc: + name: "NGC Private Registry" + hostname: "http://localhost-ngc:9094" + call-timeout: PT60S + read-timeout: PT30S + write-timeout: PT30S + connection-timeout: PT60S + oauth2: + base-url: "http://localhost:9095" + group-scope: ngc-stg + resource: + ngc: + name: "NGC Private Registry" + hostname: "http://localhost-ngc:9094" + call-timeout: PT60S + read-timeout: PT30S + write-timeout: PT30S + connection-timeout: PT60S + oauth2: + base-url: "http://localhost:9095" + group-scope: ngc-stg diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/resources/bootstrap-test.yaml b/src/control-plane-services/cloud-tasks/nvct-core/src/test/resources/bootstrap-test.yaml new file mode 100644 index 000000000..2b328cea2 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/resources/bootstrap-test.yaml @@ -0,0 +1,30 @@ +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +# +# 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. +spring: + application: + name: nvct-core-test + env: test + version: 0.0.1-test + host: + id: local-test-host + dc: local-test-id + cloud: + kubernetes: + config: + enabled: false + +nv-boot: + reloadable-properties: + file: local_env/vault/secrets.json diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/resources/docker-java.properties b/src/control-plane-services/cloud-tasks/nvct-core/src/test/resources/docker-java.properties new file mode 100644 index 000000000..e8b62f3b4 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/resources/docker-java.properties @@ -0,0 +1,16 @@ +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +# +# 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. +# Pin Docker API version to avoid compatibility issues with testcontainers +# api.version=1.44 diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/resources/fixtures/icms/cluster-groups/complete-response.json b/src/control-plane-services/cloud-tasks/nvct-core/src/test/resources/fixtures/icms/cluster-groups/complete-response.json new file mode 100644 index 000000000..2516481cc --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/resources/fixtures/icms/cluster-groups/complete-response.json @@ -0,0 +1,87 @@ +{ + "clusterGroups": [ + { + "id": "a8bc8edc-e7ef-455b-90d7-10645841e234", + "name": "GFN", + "ncaId": "jY_kY8LqzQRKL0J8pqC6avyTLyWGUrlQr4BC-SVYhbo", + "authorizedNcaIds": [ + "*" + ], + "gpus": [ + { + "name": "T10", + "instanceTypes": [ + { + "name": "g6.full", + "value": "g6.full", + "description": "One Nvidia Tensor Core GPU", + "default": true + } + ] + }, + { + "name": "L40G", + "instanceTypes": [ + { + "name": "gl40g_1.br25_2xlarge", + "value": "gl40g_1.br25_2xlarge", + "description": "One Nvidia Ada GPU", + "default": true + } + ] + } + ], + "clusters": [ + { + "k8sVersion": "v1.25.9", + "id": "nvssa-stg-XVZkj_L81QojSxA_6M_ajWajcx56xZEtM2MUR_BAH8M", + "name": "STATIC-ZONE" + } + ] + }, + { + "id": "d6c45d29-2094-4e45-a0f9-f39587da2ecc", + "name": "OCI", + "ncaId": "zK0fuqHAgHZtM8zbcSAlWeOgN3KE2PO3wI6jtjidFhw", + "authorizedNcaIds": [ + "*" + ], + "gpus": [ + { + "name": "A100_80GB", + "instanceTypes": [ + { + "name": "BM.GPU.A100-v2.8", + "value": "BM.GPU.A100-v2.8", + "description": "One Nvidia Tensor Core GPU", + "default": true + }, + { + "name": "BM.GPU.A100-v2.8_8x", + "value": "BM.GPU.A100-v2.8", + "description": "Eight Nvidia Tensor Core GPU" + } + ] + }, + { + "name": "L40G", + "instanceTypes": [ + { + "name": "BM_GPU_L40G-2X", + "value": "BM_GPU_L40G-2XL", + "description": "One Nvidia Ada GPU", + "default": true + } + ] + } + ], + "clusters": [ + { + "k8sVersion": "v1.25.9", + "id": "nvssa-stg-76wrulCe8IWNEOrc2w8MSsJSJme4xoVRUxO-Xck3pqw", + "name": "OCI-STATIC-REGION" + } + ] + } + ] +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/resources/fixtures/icms/cluster-groups/missing-gfn-cluster-group-response.json b/src/control-plane-services/cloud-tasks/nvct-core/src/test/resources/fixtures/icms/cluster-groups/missing-gfn-cluster-group-response.json new file mode 100644 index 000000000..7418c85c8 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/resources/fixtures/icms/cluster-groups/missing-gfn-cluster-group-response.json @@ -0,0 +1,37 @@ +{ + "clusterGroups": [ + { + "id": "d6c45d29-2094-4e45-a0f9-f39587da2ecc", + "name": "OCI", + "ncaId": "zK0fuqHAgHZtM8zbcSAlWeOgN3KE2PO3wI6jtjidFhw", + "authorizedNcaIds": [ + "*" + ], + "gpus": [ + { + "name": "A100_80GB", + "instanceTypes": [ + { + "name": "BM.GPU.A100-v2.8", + "value": "BM.GPU.A100-v2.8", + "description": "One Nvidia Tensor Core GPU", + "default": true + }, + { + "name": "BM.GPU.A100-v2.8_8x", + "value": "BM.GPU.A100-v2.8", + "description": "Eight Nvidia Tensor Core GPU" + } + ] + } + ], + "clusters": [ + { + "k8sVersion": "v1.25.9", + "id": "nvssa-stg-76wrulCe8IWNEOrc2w8MSsJSJme4xoVRUxO-Xck3pqw", + "name": "OCI-STATIC-REGION" + } + ] + } + ] +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/resources/fixtures/icms/cluster-groups/missing-gfn-gpus-response.json b/src/control-plane-services/cloud-tasks/nvct-core/src/test/resources/fixtures/icms/cluster-groups/missing-gfn-gpus-response.json new file mode 100644 index 000000000..31d188952 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/resources/fixtures/icms/cluster-groups/missing-gfn-gpus-response.json @@ -0,0 +1,52 @@ +{ + "clusterGroups": [ + { + "id": "a8bc8edc-e7ef-455b-90d7-10645841e234", + "name": "GFN", + "ncaId": "jY_kY8LqzQRKL0J8pqC6avyTLyWGUrlQr4BC-SVYhbo", + "authorizedNcaIds": [ + "*" + ], + "clusters": [ + { + "k8sVersion": "v1.25.9", + "id": "nvssa-stg-XVZkj_L81QojSxA_6M_ajWajcx56xZEtM2MUR_BAH8M", + "name": "STATIC-ZONE" + } + ] + }, + { + "id": "d6c45d29-2094-4e45-a0f9-f39587da2ecc", + "name": "OCI", + "ncaId": "zK0fuqHAgHZtM8zbcSAlWeOgN3KE2PO3wI6jtjidFhw", + "authorizedNcaIds": [ + "*" + ], + "gpus": [ + { + "name": "A100_80GB", + "instanceTypes": [ + { + "name": "BM.GPU.A100-v2.8", + "value": "BM.GPU.A100-v2.8", + "description": "One Nvidia Tensor Core GPU", + "default": true + }, + { + "name": "BM.GPU.A100-v2.8_8x", + "value": "BM.GPU.A100-v2.8", + "description": "Eight Nvidia Tensor Core GPU" + } + ] + } + ], + "clusters": [ + { + "k8sVersion": "v1.25.9", + "id": "nvssa-stg-76wrulCe8IWNEOrc2w8MSsJSJme4xoVRUxO-Xck3pqw", + "name": "OCI-STATIC-REGION" + } + ] + } + ] +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/resources/fixtures/icms/cluster-groups/missing-t10-gpu-response.json b/src/control-plane-services/cloud-tasks/nvct-core/src/test/resources/fixtures/icms/cluster-groups/missing-t10-gpu-response.json new file mode 100644 index 000000000..6809bcab0 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/resources/fixtures/icms/cluster-groups/missing-t10-gpu-response.json @@ -0,0 +1,65 @@ +{ + "clusterGroups": [ + { + "id": "a8bc8edc-e7ef-455b-90d7-10645841e234", + "name": "GFN", + "ncaId": "jY_kY8LqzQRKL0J8pqC6avyTLyWGUrlQr4BC-SVYhbo", + "authorizedNcaIds": [ + "*" + ], + "gpus": [ + { + "name": "A10G", + "instanceTypes": [ + { + "name": "ga10g_1.br20_2xlarge", + "value": "ga10g_1.br20_2xlarge", + "description": "One Nvidia Ampere GPU", + "default": true + } + ] + } + ], + "clusters": [ + { + "k8sVersion": "v1.25.9", + "id": "nvssa-stg-XVZkj_L81QojSxA_6M_ajWajcx56xZEtM2MUR_BAH8M", + "name": "STATIC-ZONE" + } + ] + }, + { + "id": "d6c45d29-2094-4e45-a0f9-f39587da2ecc", + "name": "OCI", + "ncaId": "zK0fuqHAgHZtM8zbcSAlWeOgN3KE2PO3wI6jtjidFhw", + "authorizedNcaIds": [ + "*" + ], + "gpus": [ + { + "name": "A100_80GB", + "instanceTypes": [ + { + "name": "BM.GPU.A100-v2.8", + "value": "BM.GPU.A100-v2.8", + "description": "One Nvidia Tensor Core GPU", + "default": true + }, + { + "name": "BM.GPU.A100-v2.8_8x", + "value": "BM.GPU.A100-v2.8", + "description": "Eight Nvidia Tensor Core GPU" + } + ] + } + ], + "clusters": [ + { + "k8sVersion": "v1.25.9", + "id": "nvssa-stg-76wrulCe8IWNEOrc2w8MSsJSJme4xoVRUxO-Xck3pqw", + "name": "OCI-STATIC-REGION" + } + ] + } + ] +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/resources/fixtures/icms/cluster-groups/missing-t10-instance-type-default-response.json b/src/control-plane-services/cloud-tasks/nvct-core/src/test/resources/fixtures/icms/cluster-groups/missing-t10-instance-type-default-response.json new file mode 100644 index 000000000..6ae8f5eac --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/resources/fixtures/icms/cluster-groups/missing-t10-instance-type-default-response.json @@ -0,0 +1,64 @@ +{ + "clusterGroups": [ + { + "id": "a8bc8edc-e7ef-455b-90d7-10645841e234", + "name": "GFN", + "ncaId": "jY_kY8LqzQRKL0J8pqC6avyTLyWGUrlQr4BC-SVYhbo", + "authorizedNcaIds": [ + "*" + ], + "gpus": [ + { + "name": "T10", + "instanceTypes": [ + { + "name": "g6.full", + "value": "g6.full", + "description": "One Nvidia Tensor Core GPU" + } + ] + } + ], + "clusters": [ + { + "k8sVersion": "v1.25.9", + "id": "nvssa-stg-XVZkj_L81QojSxA_6M_ajWajcx56xZEtM2MUR_BAH8M", + "name": "STATIC-ZONE" + } + ] + }, + { + "id": "d6c45d29-2094-4e45-a0f9-f39587da2ecc", + "name": "OCI", + "ncaId": "zK0fuqHAgHZtM8zbcSAlWeOgN3KE2PO3wI6jtjidFhw", + "authorizedNcaIds": [ + "*" + ], + "gpus": [ + { + "name": "A100_80GB", + "instanceTypes": [ + { + "name": "BM.GPU.A100-v2.8", + "value": "BM.GPU.A100-v2.8", + "description": "One Nvidia Tensor Core GPU", + "default": true + }, + { + "name": "BM.GPU.A100-v2.8_8x", + "value": "BM.GPU.A100-v2.8", + "description": "Eight Nvidia Tensor Core GPU" + } + ] + } + ], + "clusters": [ + { + "k8sVersion": "v1.25.9", + "id": "nvssa-stg-76wrulCe8IWNEOrc2w8MSsJSJme4xoVRUxO-Xck3pqw", + "name": "OCI-STATIC-REGION" + } + ] + } + ] +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/resources/fixtures/icms/cluster-groups/missing-t10-instance-types-response.json b/src/control-plane-services/cloud-tasks/nvct-core/src/test/resources/fixtures/icms/cluster-groups/missing-t10-instance-types-response.json new file mode 100644 index 000000000..2da39f778 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/resources/fixtures/icms/cluster-groups/missing-t10-instance-types-response.json @@ -0,0 +1,57 @@ +{ + "clusterGroups": [ + { + "id": "a8bc8edc-e7ef-455b-90d7-10645841e234", + "name": "GFN", + "ncaId": "jY_kY8LqzQRKL0J8pqC6avyTLyWGUrlQr4BC-SVYhbo", + "authorizedNcaIds": [ + "*" + ], + "gpus": [ + { + "name": "T10" + } + ], + "clusters": [ + { + "k8sVersion": "v1.25.9", + "id": "nvssa-stg-XVZkj_L81QojSxA_6M_ajWajcx56xZEtM2MUR_BAH8M", + "name": "STATIC-ZONE" + } + ] + }, + { + "id": "d6c45d29-2094-4e45-a0f9-f39587da2ecc", + "name": "OCI", + "ncaId": "zK0fuqHAgHZtM8zbcSAlWeOgN3KE2PO3wI6jtjidFhw", + "authorizedNcaIds": [ + "*" + ], + "gpus": [ + { + "name": "A100_80GB", + "instanceTypes": [ + { + "name": "BM.GPU.A100-v2.8", + "value": "BM.GPU.A100-v2.8", + "description": "One Nvidia Tensor Core GPU", + "default": true + }, + { + "name": "BM.GPU.A100-v2.8_8x", + "value": "BM.GPU.A100-v2.8", + "description": "Eight Nvidia Tensor Core GPU" + } + ] + } + ], + "clusters": [ + { + "k8sVersion": "v1.25.9", + "id": "nvssa-stg-76wrulCe8IWNEOrc2w8MSsJSJme4xoVRUxO-Xck3pqw", + "name": "OCI-STATIC-REGION" + } + ] + } + ] +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/resources/fixtures/icms/clusters/complete-response.json b/src/control-plane-services/cloud-tasks/nvct-core/src/test/resources/fixtures/icms/clusters/complete-response.json new file mode 100644 index 000000000..8dab85e75 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/resources/fixtures/icms/clusters/complete-response.json @@ -0,0 +1,1146 @@ +[ + { + "clusterName": "dgxc-k8saas-forge-az24-ct1", + "clusterGroupName": "dgxc-k8saas-forge-az24-ct1", + "clusterDescription": "", + "ncaId": "CMYBKSNNjtg1TQmSke-gHNGgMlFvA-dCRAI8gcHOBcw", + "authorizedNCAIds": [], + "cloudProvider": "DGX-CLOUD", + "region": "eu-west-1", + "capabilities": [ + "DynamicGPUDiscovery", + "LogPosting" + ], + "attributes": [ + "KataRuntimeIsolation" + ], + "customAttributes": [], + "gpus": [ + { + "name": "AD102GL", + "capacity": 0, + "instanceTypes": [ + { + "cpuCores": 128, + "systemMemory": "1056451716Ki", + "gpuMemory": "1073741824M", + "gpuCount": 2, + "name": "DGX-CLOUD.GPU.AD102GL_2x", + "description": "AD102GL-L40 (undefined family) on a ThinkSystem-SR670-V2 machine (Kata-enabled)", + "value": "DGX-CLOUD.GPU.AD102GL", + "cpuArch": "amd64", + "os": "linux", + "driverVersion": "unknown.unknown.unknown", + "storage": "24.5Gi", + "default": null + }, + { + "cpuCores": 128, + "systemMemory": "1056451716Ki", + "gpuMemory": "4294967296M", + "gpuCount": 8, + "name": "DGX-CLOUD.GPU.AD102GL_8x", + "description": "AD102GL-L40 (undefined family) on a ThinkSystem-SR670-V2 machine (Kata-enabled)", + "value": "DGX-CLOUD.GPU.AD102GL", + "cpuArch": "amd64", + "os": "linux", + "driverVersion": "unknown.unknown.unknown", + "storage": "97.9Gi", + "default": null + }, + { + "cpuCores": 128, + "systemMemory": "1056451716Ki", + "gpuMemory": "2147483648M", + "gpuCount": 4, + "name": "DGX-CLOUD.GPU.AD102GL_4x", + "description": "AD102GL-L40 (undefined family) on a ThinkSystem-SR670-V2 machine (Kata-enabled)", + "value": "DGX-CLOUD.GPU.AD102GL", + "cpuArch": "amd64", + "os": "linux", + "driverVersion": "unknown.unknown.unknown", + "storage": "48.9Gi", + "default": null + }, + { + "cpuCores": 128, + "systemMemory": "1056451716Ki", + "gpuMemory": "536870912M", + "gpuCount": 1, + "name": "DGX-CLOUD.GPU.AD102GL_1x", + "description": "AD102GL-L40 (undefined family) on a ThinkSystem-SR670-V2 machine (Kata-enabled)", + "value": "DGX-CLOUD.GPU.AD102GL", + "cpuArch": "amd64", + "os": "linux", + "driverVersion": "unknown.unknown.unknown", + "storage": "12.2Gi", + "default": true + } + ] + } + ], + "nvcaVersion": "2.37.0", + "ssaClientId": "nvssa-stg-dS7iY1dsI_5qXequTVZL0Zpij-xyFILuxPHs5d7ImdA", + "clusterId": "5942e544-11f9-3d89-9882-a31b959ae54e", + "clusterGroupId": "d6b30d7f-110a-455f-9d37-e7a3d9bfb44a", + "status": "READY", + "nvcaLastConnected": "2024-10-29T18:34:42.413Z", + "k8sVersion": "v1.29.5", + "gpuUsage": null, + "envoyConfig": { + "image": "envoy", + "repository": "docker.io/envoyproxy", + "tag": "v1.26.7" + }, + "vaultConfig": { + "address": "https://stg.vault.nvidia.com:443" + }, + "clusterUpgradeStatus": null + }, + { + "clusterName": "dgxc-k8saas-forge-az24-ct1_unhealthy", + "clusterGroupName": "dgxc-k8saas-forge-az24-ct1_unhealthy", + "clusterDescription": "", + "ncaId": "CMYBKSNNjtg1TQmSke-gHNGgMlFvA-dCRAI8gcHOBcw", + "authorizedNCAIds": [], + "cloudProvider": "DGX-CLOUD", + "region": "eu-west-1", + "capabilities": [ + "DynamicGPUDiscovery", + "LogPosting" + ], + "attributes": [ + "KataRuntimeIsolation" + ], + "customAttributes": [], + "gpus": [ + { + "name": "AD102GL", + "capacity": 0, + "instanceTypes": [ + { + "cpuCores": 128, + "systemMemory": "1056451716Ki", + "gpuMemory": "1073741824M", + "gpuCount": 2, + "name": "DGX-CLOUD.GPU.AD102GL_2x", + "description": "AD102GL-L40 (undefined family) on a ThinkSystem-SR670-V2 machine (Kata-enabled)", + "value": "DGX-CLOUD.GPU.AD102GL", + "cpuArch": "amd64", + "os": "linux", + "driverVersion": "unknown.unknown.unknown", + "storage": "24.5Gi", + "default": null + }, + { + "cpuCores": 128, + "systemMemory": "1056451716Ki", + "gpuMemory": "4294967296M", + "gpuCount": 8, + "name": "DGX-CLOUD.GPU.AD102GL_8x", + "description": "AD102GL-L40 (undefined family) on a ThinkSystem-SR670-V2 machine (Kata-enabled)", + "value": "DGX-CLOUD.GPU.AD102GL", + "cpuArch": "amd64", + "os": "linux", + "driverVersion": "unknown.unknown.unknown", + "storage": "97.9Gi", + "default": null + }, + { + "cpuCores": 128, + "systemMemory": "1056451716Ki", + "gpuMemory": "2147483648M", + "gpuCount": 4, + "name": "DGX-CLOUD.GPU.AD102GL_4x", + "description": "AD102GL-L40 (undefined family) on a ThinkSystem-SR670-V2 machine (Kata-enabled)", + "value": "DGX-CLOUD.GPU.AD102GL", + "cpuArch": "amd64", + "os": "linux", + "driverVersion": "unknown.unknown.unknown", + "storage": "48.9Gi", + "default": null + }, + { + "cpuCores": 128, + "systemMemory": "1056451716Ki", + "gpuMemory": "536870912M", + "gpuCount": 1, + "name": "DGX-CLOUD.GPU.AD102GL_1x", + "description": "AD102GL-L40 (undefined family) on a ThinkSystem-SR670-V2 machine (Kata-enabled)", + "value": "DGX-CLOUD.GPU.AD102GL", + "cpuArch": "amd64", + "os": "linux", + "driverVersion": "unknown.unknown.unknown", + "storage": "12.2Gi", + "default": true + } + ] + } + ], + "nvcaVersion": "2.37.0", + "ssaClientId": "nvssa-stg-dS7iY1dsI_5qXequTVZL0Zpij-xyFILuxPHs5d7ImdA", + "clusterId": "5942e544-11f9-3d89-9882-a31b959ae64e", + "clusterGroupId": "d6b30d7f-110a-455f-9d37-e7a3d9bfb74a", + "status": "UNHEALTHY", + "nvcaLastConnected": "2024-10-29T18:34:42.413Z", + "k8sVersion": "v1.29.5", + "gpuUsage": null, + "envoyConfig": { + "image": "envoy", + "repository": "docker.io/envoyproxy", + "tag": "v1.26.7" + }, + "vaultConfig": { + "address": "https://stg.vault.nvidia.com:443" + }, + "clusterUpgradeStatus": null + }, + { + "clusterName": "dgxc-k8saas-forge-dev2-az24", + "clusterGroupName": "dgxc-k8saas-forge-dev2-az24", + "clusterDescription": "dgxc-k8saas-forge-dev2-az24", + "ncaId": "CMYBKSNNjtg1TQmSke-gHNGgMlFvA-dCRAI8gcHOBcw", + "authorizedNCAIds": [ + "*" + ], + "cloudProvider": "DGX-CLOUD", + "region": "us-west-1", + "capabilities": [ + "DynamicGPUDiscovery", + "LogPosting" + ], + "attributes": [ + "KataRuntimeIsolation" + ], + "customAttributes": [], + "gpus": [ + { + "name": "AD102GL", + "capacity": 0, + "instanceTypes": [ + { + "cpuCores": 128, + "systemMemory": "1056429496Ki", + "gpuMemory": "536870912M", + "gpuCount": 1, + "name": "DGX-CLOUD.GPU.AD102GL_1x", + "description": "AD102GL-L40 (undefined family) on a ThinkSystem-SR670-V2 machine (Kata-enabled)", + "value": "DGX-CLOUD.GPU.AD102GL", + "cpuArch": "amd64", + "os": "linux", + "driverVersion": "unknown.unknown.unknown", + "storage": "879.8Gi", + "default": true + }, + { + "cpuCores": 128, + "systemMemory": "1056429496Ki", + "gpuMemory": "4294967296M", + "gpuCount": 8, + "name": "DGX-CLOUD.GPU.AD102GL_8x", + "description": "AD102GL-L40 (undefined family) on a ThinkSystem-SR670-V2 machine (Kata-enabled)", + "value": "DGX-CLOUD.GPU.AD102GL", + "cpuArch": "amd64", + "os": "linux", + "driverVersion": "unknown.unknown.unknown", + "storage": "6.9Ti", + "default": null + }, + { + "cpuCores": 128, + "systemMemory": "1056429496Ki", + "gpuMemory": "1073741824M", + "gpuCount": 2, + "name": "DGX-CLOUD.GPU.AD102GL_2x", + "description": "AD102GL-L40 (undefined family) on a ThinkSystem-SR670-V2 machine (Kata-enabled)", + "value": "DGX-CLOUD.GPU.AD102GL", + "cpuArch": "amd64", + "os": "linux", + "driverVersion": "unknown.unknown.unknown", + "storage": "1.7Ti", + "default": null + }, + { + "cpuCores": 128, + "systemMemory": "1056429496Ki", + "gpuMemory": "2147483648M", + "gpuCount": 4, + "name": "DGX-CLOUD.GPU.AD102GL_4x", + "description": "AD102GL-L40 (undefined family) on a ThinkSystem-SR670-V2 machine (Kata-enabled)", + "value": "DGX-CLOUD.GPU.AD102GL", + "cpuArch": "amd64", + "os": "linux", + "driverVersion": "unknown.unknown.unknown", + "storage": "3.4Ti", + "default": null + } + ] + } + ], + "nvcaVersion": "2.38.1", + "ssaClientId": "nvssa-stg-UQAYrnW3GDxCOdpk8TCuJO_pbdsufZn9ZRrWqW1gN00", + "clusterId": "fed25eef-ef38-30f5-8059-9872f31b71ab", + "clusterGroupId": "607d4661-2935-4c8f-958e-b25285e787df", + "status": "READY", + "nvcaLastConnected": "2024-11-25T21:49:56.379Z", + "k8sVersion": "v1.29.5", + "gpuUsage": { + "AD102GL": { + "capacity": 16, + "allocated": 0, + "available": 16 + } + }, + "envoyConfig": { + "image": "envoy", + "repository": "docker.io/envoyproxy", + "tag": "v1.26.7" + }, + "vaultConfig": { + "address": "https://stg.vault.nvidia.com:443" + }, + "clusterUpgradeStatus": null + }, + { + "clusterName": "mcamp-test-1", + "clusterGroupName": "mcamp-test-1", + "clusterDescription": "mcamp-test-1", + "ncaId": "CMYBKSNNjtg1TQmSke-gHNGgMlFvA-dCRAI8gcHOBcw", + "authorizedNCAIds": [ + "foo-bar" + ], + "cloudProvider": "ON-PREM", + "region": "us-west-1", + "capabilities": [ + "DynamicGPUDiscovery", + "LogPosting" + ], + "attributes": [], + "customAttributes": [], + "gpus": [], + "nvcaVersion": "2.31.9", + "clusterId": "a2325818-2596-3ee6-9dc1-220740871fd1", + "clusterGroupId": "8f931aa1-5531-4f50-af9e-9aae20ee72c3", + "status": "NOT_READY", + "nvcaLastConnected": null, + "k8sVersion": null, + "gpuUsage": null, + "envoyConfig": { + "image": "envoy", + "repository": "docker.io/envoyproxy", + "tag": "v1.26.7" + }, + "vaultConfig": { + "address": "https://stg.vault.nvidia.com:443" + }, + "clusterUpgradeStatus": null + }, + { + "clusterName": "nvcf-dgxc-k8s-aws-use1-dev1", + "clusterGroupName": "nvcf-dgxc-k8s-aws-use1-dev1", + "clusterDescription": "nvcf-dgxc-k8s-aws-use1-dev1", + "ncaId": "CMYBKSNNjtg1TQmSke-gHNGgMlFvA-dCRAI8gcHOBcw", + "authorizedNCAIds": [], + "cloudProvider": "AWS", + "region": "us-east-1", + "capabilities": [ + "CachingSupport", + "DynamicGPUDiscovery", + "LogPosting" + ], + "attributes": [], + "customAttributes": [], + "gpus": [ + { + "name": "H100", + "capacity": 0, + "instanceTypes": [ + { + "cpuCores": 192, + "systemMemory": "2097112576Ki", + "gpuMemory": "652472M", + "gpuCount": 8, + "name": "AWS.GPU.H100_8x", + "description": "NVIDIA-H100-80GB-HBM3 (hopper family) on a p5.48xlarge machine", + "value": "AWS.GPU.H100", + "cpuArch": "amd64", + "os": "linux", + "driverVersion": "550.90.07", + "storage": "484.4Gi", + "default": null + }, + { + "cpuCores": 192, + "systemMemory": "2097112576Ki", + "gpuMemory": "81559M", + "gpuCount": 1, + "name": "AWS.GPU.H100_1x", + "description": "NVIDIA-H100-80GB-HBM3 (hopper family) on a p5.48xlarge machine", + "value": "AWS.GPU.H100", + "cpuArch": "amd64", + "os": "linux", + "driverVersion": "550.90.07", + "storage": "60.6Gi", + "default": true + }, + { + "cpuCores": 192, + "systemMemory": "2097112576Ki", + "gpuMemory": "163118M", + "gpuCount": 2, + "name": "AWS.GPU.H100_2x", + "description": "NVIDIA-H100-80GB-HBM3 (hopper family) on a p5.48xlarge machine", + "value": "AWS.GPU.H100", + "cpuArch": "amd64", + "os": "linux", + "driverVersion": "550.90.07", + "storage": "121.1Gi", + "default": null + }, + { + "cpuCores": 192, + "systemMemory": "2097112576Ki", + "gpuMemory": "326236M", + "gpuCount": 4, + "name": "AWS.GPU.H100_4x", + "description": "NVIDIA-H100-80GB-HBM3 (hopper family) on a p5.48xlarge machine", + "value": "AWS.GPU.H100", + "cpuArch": "amd64", + "os": "linux", + "driverVersion": "550.90.07", + "storage": "242.2Gi", + "default": null + } + ] + } + ], + "nvcaVersion": "2.34.4", + "clusterId": "c8f1d4a1-c899-3531-ae93-ee9fdac60d03", + "clusterGroupId": "0051c6b3-cac6-486c-b4bd-50f9cfdd4fd1", + "status": "READY", + "nvcaLastConnected": "2024-11-20T01:50:31.330Z", + "k8sVersion": "v1.30.5-eks-ce1d5eb", + "gpuUsage": { + "H100": { + "capacity": 32, + "allocated": 1, + "available": 31 + } + }, + "envoyConfig": { + "image": "envoy", + "repository": "docker.io/envoyproxy", + "tag": "v1.26.7" + }, + "vaultConfig": { + "address": "https://stg.vault.nvidia.com:443" + }, + "clusterUpgradeStatus": null + }, + { + "clusterName": "nvcf-dgxc-k8s-azr-scus-dev1", + "clusterGroupName": "nvcf-dgxc-k8s-azr-scus-dev1", + "clusterDescription": "nvcf-dgxc-k8s-azr-scus-dev1", + "ncaId": "CMYBKSNNjtg1TQmSke-gHNGgMlFvA-dCRAI8gcHOBcw", + "authorizedNCAIds": [], + "cloudProvider": "AZURE", + "region": "us-east-1", + "capabilities": [ + "DynamicGPUDiscovery", + "LogPosting" + ], + "attributes": [], + "customAttributes": [], + "gpus": [ + { + "name": "A100", + "capacity": 0, + "instanceTypes": [ + { + "cpuCores": 96, + "systemMemory": "1857800200Ki", + "gpuMemory": "327680M", + "gpuCount": 4, + "name": "AZURE.GPU.A100_4x", + "description": "NVIDIA-A100-SXM4-80GB (ampere family) on a Virtual-Machine machine", + "value": "AZURE.GPU.A100", + "cpuArch": "amd64", + "os": "linux", + "driverVersion": "550.90.07", + "storage": "992.3Gi", + "default": null + }, + { + "cpuCores": 96, + "systemMemory": "1857800200Ki", + "gpuMemory": "81920M", + "gpuCount": 1, + "name": "AZURE.GPU.A100_1x", + "description": "NVIDIA-A100-SXM4-80GB (ampere family) on a Virtual-Machine machine", + "value": "AZURE.GPU.A100", + "cpuArch": "amd64", + "os": "linux", + "driverVersion": "550.90.07", + "storage": "248.1Gi", + "default": true + }, + { + "cpuCores": 96, + "systemMemory": "1857800200Ki", + "gpuMemory": "163840M", + "gpuCount": 2, + "name": "AZURE.GPU.A100_2x", + "description": "NVIDIA-A100-SXM4-80GB (ampere family) on a Virtual-Machine machine", + "value": "AZURE.GPU.A100", + "cpuArch": "amd64", + "os": "linux", + "driverVersion": "550.90.07", + "storage": "496.2Gi", + "default": null + }, + { + "cpuCores": 96, + "systemMemory": "1857800200Ki", + "gpuMemory": "655360M", + "gpuCount": 8, + "name": "AZURE.GPU.A100_8x", + "description": "NVIDIA-A100-SXM4-80GB (ampere family) on a Virtual-Machine machine", + "value": "AZURE.GPU.A100", + "cpuArch": "amd64", + "os": "linux", + "driverVersion": "550.90.07", + "storage": "1.9Ti", + "default": null + } + ] + } + ], + "nvcaVersion": "2.34.4", + "clusterId": "cfe4f376-db80-3f16-bbcc-61605903be63", + "clusterGroupId": "6c0fe500-20e0-4b9e-977e-2aa79af57b4a", + "status": "READY", + "nvcaLastConnected": "2024-11-20T01:50:16.144Z", + "k8sVersion": "v1.29.9", + "gpuUsage": { + "A100": { + "capacity": 32, + "allocated": 0, + "available": 32 + } + }, + "envoyConfig": { + "image": "envoy", + "repository": "docker.io/envoyproxy", + "tag": "v1.26.7" + }, + "vaultConfig": { + "address": "https://stg.vault.nvidia.com:443" + }, + "clusterUpgradeStatus": null + }, + { + "clusterName": "nvcf-dgxc-k8s-forge-az24-dev5", + "clusterGroupName": "nvcf-dgxc-k8s-forge-az24-dev5", + "clusterDescription": "sensor rtx", + "ncaId": "CMYBKSNNjtg1TQmSke-gHNGgMlFvA-dCRAI8gcHOBcw", + "authorizedNCAIds": [ + "*" + ], + "cloudProvider": "DGX-CLOUD", + "region": "eu-west-1", + "capabilities": [ + "DynamicGPUDiscovery", + "LogPosting" + ], + "attributes": [], + "customAttributes": [], + "gpus": [ + { + "name": "L40", + "capacity": 0, + "instanceTypes": [ + { + "cpuCores": 128, + "systemMemory": "1056451744Ki", + "gpuMemory": "98280M", + "gpuCount": 2, + "name": "DGX-CLOUD.GPU.L40_2x", + "description": "NVIDIA-L40 (ampere family) on a ThinkSystem-SR670-V2 machine", + "value": "DGX-CLOUD.GPU.L40", + "cpuArch": "amd64", + "os": "linux", + "driverVersion": "550.54.15", + "storage": "24.5Gi", + "default": null + }, + { + "cpuCores": 128, + "systemMemory": "1056451744Ki", + "gpuMemory": "393120M", + "gpuCount": 8, + "name": "DGX-CLOUD.GPU.L40_8x", + "description": "NVIDIA-L40 (ampere family) on a ThinkSystem-SR670-V2 machine", + "value": "DGX-CLOUD.GPU.L40", + "cpuArch": "amd64", + "os": "linux", + "driverVersion": "550.54.15", + "storage": "97.9Gi", + "default": null + }, + { + "cpuCores": 128, + "systemMemory": "1056451744Ki", + "gpuMemory": "196560M", + "gpuCount": 4, + "name": "DGX-CLOUD.GPU.L40_4x", + "description": "NVIDIA-L40 (ampere family) on a ThinkSystem-SR670-V2 machine", + "value": "DGX-CLOUD.GPU.L40", + "cpuArch": "amd64", + "os": "linux", + "driverVersion": "550.54.15", + "storage": "48.9Gi", + "default": null + }, + { + "cpuCores": 128, + "systemMemory": "1056451744Ki", + "gpuMemory": "49140M", + "gpuCount": 1, + "name": "DGX-CLOUD.GPU.L40_1x", + "description": "NVIDIA-L40 (ampere family) on a ThinkSystem-SR670-V2 machine", + "value": "DGX-CLOUD.GPU.L40", + "cpuArch": "amd64", + "os": "linux", + "driverVersion": "550.54.15", + "storage": "12.2Gi", + "default": true + } + ] + } + ], + "nvcaVersion": "2.37.0", + "clusterId": "a2934dc7-acea-3416-8e20-25e090dcecd4", + "clusterGroupId": "56f0a210-4394-44e2-95ea-10cd1c755db4", + "status": "UNHEALTHY", + "nvcaLastConnected": "2024-11-19T11:23:43.241Z", + "k8sVersion": "v1.29.7", + "gpuUsage": null, + "envoyConfig": { + "image": "envoy", + "repository": "docker.io/envoyproxy", + "tag": "v1.26.7" + }, + "vaultConfig": { + "address": "https://stg.vault.nvidia.com:443" + }, + "clusterUpgradeStatus": null + }, + { + "clusterName": "nvcf-dgxc-k8s-forge-az24-dev6", + "clusterGroupName": "nvcf-dgxc-k8s-forge-az24-dev6", + "clusterDescription": "nvcf-dgxc-k8s-forge-az24-dev6", + "ncaId": "CMYBKSNNjtg1TQmSke-gHNGgMlFvA-dCRAI8gcHOBcw", + "authorizedNCAIds": [], + "cloudProvider": "DGX-CLOUD", + "region": "us-east-1", + "capabilities": [ + "DynamicGPUDiscovery", + "LogPosting" + ], + "attributes": [ + "KataRuntimeIsolation" + ], + "customAttributes": [], + "gpus": [ + { + "name": "AD102GL", + "capacity": 0, + "instanceTypes": [ + { + "cpuCores": 128, + "systemMemory": "1056451708Ki", + "gpuMemory": "536870912M", + "gpuCount": 1, + "name": "DGX-CLOUD.GPU.AD102GL_1x", + "description": "AD102GL-L40 (undefined family) on a ThinkSystem-SR670-V2 machine (Kata-enabled)", + "value": "DGX-CLOUD.GPU.AD102GL", + "cpuArch": "amd64", + "os": "linux", + "driverVersion": "unknown.unknown.unknown", + "storage": "12.2Gi", + "default": true + }, + { + "cpuCores": 128, + "systemMemory": "1056451708Ki", + "gpuMemory": "2147483648M", + "gpuCount": 4, + "name": "DGX-CLOUD.GPU.AD102GL_4x", + "description": "AD102GL-L40 (undefined family) on a ThinkSystem-SR670-V2 machine (Kata-enabled)", + "value": "DGX-CLOUD.GPU.AD102GL", + "cpuArch": "amd64", + "os": "linux", + "driverVersion": "unknown.unknown.unknown", + "storage": "48.9Gi", + "default": null + }, + { + "cpuCores": 128, + "systemMemory": "1056451708Ki", + "gpuMemory": "1073741824M", + "gpuCount": 2, + "name": "DGX-CLOUD.GPU.AD102GL_2x", + "description": "AD102GL-L40 (undefined family) on a ThinkSystem-SR670-V2 machine (Kata-enabled)", + "value": "DGX-CLOUD.GPU.AD102GL", + "cpuArch": "amd64", + "os": "linux", + "driverVersion": "unknown.unknown.unknown", + "storage": "24.5Gi", + "default": null + }, + { + "cpuCores": 128, + "systemMemory": "1056451708Ki", + "gpuMemory": "4294967296M", + "gpuCount": 8, + "name": "DGX-CLOUD.GPU.AD102GL_8x", + "description": "AD102GL-L40 (undefined family) on a ThinkSystem-SR670-V2 machine (Kata-enabled)", + "value": "DGX-CLOUD.GPU.AD102GL", + "cpuArch": "amd64", + "os": "linux", + "driverVersion": "unknown.unknown.unknown", + "storage": "97.9Gi", + "default": null + } + ] + } + ], + "nvcaVersion": "2.38.1", + "clusterId": "66c46ee9-e427-331b-ba38-168a7e0e1eb7", + "clusterGroupId": "4333d348-9d8e-4da1-ae71-c46b5780b312", + "status": "READY", + "nvcaLastConnected": "2024-11-25T22:20:00.291Z", + "k8sVersion": "v1.29.0", + "gpuUsage": { + "AD102GL": { + "capacity": 16, + "allocated": 1, + "available": 15 + } + }, + "envoyConfig": { + "image": "envoy", + "repository": "docker.io/envoyproxy", + "tag": "v1.26.7" + }, + "vaultConfig": { + "address": "https://stg.vault.nvidia.com:443" + }, + "clusterUpgradeStatus": null + }, + { + "clusterName": "nvcf-dgxc-k8s-oci-iad-dev4", + "clusterGroupName": "nvcf-dgxc-k8s-oci-iad-dev4", + "clusterDescription": "", + "ncaId": "CMYBKSNNjtg1TQmSke-gHNGgMlFvA-dCRAI8gcHOBcw", + "authorizedNCAIds": [], + "cloudProvider": "OCI", + "region": "us-east-1", + "capabilities": [ + "CachingSupport", + "DynamicGPUDiscovery", + "LogPosting" + ], + "attributes": [], + "customAttributes": [], + "gpus": [ + { + "name": "A100", + "capacity": 0, + "instanceTypes": [ + { + "cpuCores": 255, + "systemMemory": "2113521412Ki", + "gpuMemory": "81920M", + "gpuCount": 1, + "name": "OCI.GPU.A100_1x", + "description": "NVIDIA-A100-SXM4-80GB (ampere family) on a ORACLE-SERVER-E4-2c machine", + "value": "OCI.GPU.A100", + "cpuArch": "amd64", + "os": "linux", + "driverVersion": "550.90.07", + "storage": "251.8Gi", + "default": true + }, + { + "cpuCores": 255, + "systemMemory": "2113521412Ki", + "gpuMemory": "655360M", + "gpuCount": 8, + "name": "OCI.GPU.A100_8x", + "description": "NVIDIA-A100-SXM4-80GB (ampere family) on a ORACLE-SERVER-E4-2c machine", + "value": "OCI.GPU.A100", + "cpuArch": "amd64", + "os": "linux", + "driverVersion": "550.90.07", + "storage": "2.0Ti", + "default": null + }, + { + "cpuCores": 255, + "systemMemory": "2113521412Ki", + "gpuMemory": "327680M", + "gpuCount": 4, + "name": "OCI.GPU.A100_4x", + "description": "NVIDIA-A100-SXM4-80GB (ampere family) on a ORACLE-SERVER-E4-2c machine", + "value": "OCI.GPU.A100", + "cpuArch": "amd64", + "os": "linux", + "driverVersion": "550.90.07", + "storage": "1007.4Gi", + "default": null + }, + { + "cpuCores": 255, + "systemMemory": "2113521412Ki", + "gpuMemory": "163840M", + "gpuCount": 2, + "name": "OCI.GPU.A100_2x", + "description": "NVIDIA-A100-SXM4-80GB (ampere family) on a ORACLE-SERVER-E4-2c machine", + "value": "OCI.GPU.A100", + "cpuArch": "amd64", + "os": "linux", + "driverVersion": "550.90.07", + "storage": "503.7Gi", + "default": null + } + ] + } + ], + "nvcaVersion": "2.34.4", + "clusterId": "25138fbc-cb6e-36df-afca-cc40f5a474d6", + "clusterGroupId": "500f216a-9a2a-4211-bac6-7527f94deebf", + "status": "READY", + "nvcaLastConnected": "2024-11-20T01:55:10.676Z", + "k8sVersion": "v1.29.1", + "gpuUsage": { + "A100": { + "capacity": 32, + "allocated": 1, + "available": 31 + } + }, + "envoyConfig": { + "image": "envoy", + "repository": "docker.io/envoyproxy", + "tag": "v1.26.7" + }, + "vaultConfig": { + "address": "https://stg.vault.nvidia.com:443" + }, + "clusterUpgradeStatus": null + }, + { + "clusterName": "nvcf-dgxc-k8s-oci-ord-dev6", + "clusterGroupName": "nvcf-dgxc-k8s-oci-ord-dev6", + "clusterDescription": "nvcf-dgxc-k8s-oci-ord-dev6", + "ncaId": "CMYBKSNNjtg1TQmSke-gHNGgMlFvA-dCRAI8gcHOBcw", + "authorizedNCAIds": [], + "cloudProvider": "OCI", + "region": "us-east-1", + "capabilities": [ + "DynamicGPUDiscovery", + "LogPosting" + ], + "attributes": [], + "customAttributes": [], + "gpus": [ + { + "name": "A100", + "capacity": 0, + "instanceTypes": [ + { + "cpuCores": 255, + "systemMemory": "2113521420Ki", + "gpuMemory": "81920M", + "gpuCount": 1, + "name": "OCI.GPU.A100_1x", + "description": "NVIDIA-A100-SXM4-80GB (ampere family) on a ORACLE-SERVER-E4-2c machine", + "value": "OCI.GPU.A100", + "cpuArch": "amd64", + "os": "linux", + "driverVersion": "550.90.07", + "storage": "251.8Gi", + "default": true + }, + { + "cpuCores": 255, + "systemMemory": "2113521420Ki", + "gpuMemory": "163840M", + "gpuCount": 2, + "name": "OCI.GPU.A100_2x", + "description": "NVIDIA-A100-SXM4-80GB (ampere family) on a ORACLE-SERVER-E4-2c machine", + "value": "OCI.GPU.A100", + "cpuArch": "amd64", + "os": "linux", + "driverVersion": "550.90.07", + "storage": "503.7Gi", + "default": null + }, + { + "cpuCores": 255, + "systemMemory": "2113521420Ki", + "gpuMemory": "327680M", + "gpuCount": 4, + "name": "OCI.GPU.A100_4x", + "description": "NVIDIA-A100-SXM4-80GB (ampere family) on a ORACLE-SERVER-E4-2c machine", + "value": "OCI.GPU.A100", + "cpuArch": "amd64", + "os": "linux", + "driverVersion": "550.90.07", + "storage": "1007.4Gi", + "default": null + }, + { + "cpuCores": 255, + "systemMemory": "2113521420Ki", + "gpuMemory": "655360M", + "gpuCount": 8, + "name": "OCI.GPU.A100_8x", + "description": "NVIDIA-A100-SXM4-80GB (ampere family) on a ORACLE-SERVER-E4-2c machine", + "value": "OCI.GPU.A100", + "cpuArch": "amd64", + "os": "linux", + "driverVersion": "550.90.07", + "storage": "2.0Ti", + "default": null + } + ] + } + ], + "nvcaVersion": "2.34.4", + "clusterId": "cce4164d-a40c-3ff0-998a-0812e3eccf05", + "clusterGroupId": "f5e6b6bc-4adf-4276-ba67-d16234d9adff", + "status": "READY", + "nvcaLastConnected": "2024-11-20T01:51:03.418Z", + "k8sVersion": "v1.29.1", + "gpuUsage": { + "A100": { + "capacity": 8, + "allocated": 0, + "available": 8 + } + }, + "envoyConfig": { + "image": "envoy", + "repository": "docker.io/envoyproxy", + "tag": "v1.26.7" + }, + "vaultConfig": { + "address": "https://stg.vault.nvidia.com:443" + }, + "clusterUpgradeStatus": null + }, + { + "clusterName": "nvcf-stage", + "clusterGroupName": "nvcf-stage", + "clusterDescription": "GCP Stage US Central", + "ncaId": "CMYBKSNNjtg1TQmSke-gHNGgMlFvA-dCRAI8gcHOBcw", + "authorizedNCAIds": [ + "*" + ], + "cloudProvider": "GCP", + "region": "us-east-1", + "capabilities": [ + "CachingSupport", + "DynamicGPUDiscovery", + "LogPosting" + ], + "attributes": [], + "customAttributes": [], + "gpus": [ + { + "name": "H100", + "capacity": 0, + "instanceTypes": [ + { + "cpuCores": 208, + "systemMemory": "1932077732Ki", + "gpuMemory": "163118M", + "gpuCount": 2, + "name": "GCP.GPU.H100_2x", + "description": "NVIDIA-H100-80GB-HBM3 (hopper family) on a Google-Compute-Engine machine", + "value": "GCP.GPU.H100", + "cpuArch": "amd64", + "os": "linux", + "driverVersion": "550.90.12", + "storage": "1.5Ti", + "default": null + }, + { + "cpuCores": 208, + "systemMemory": "1932077732Ki", + "gpuMemory": "326236M", + "gpuCount": 4, + "name": "GCP.GPU.H100_4x", + "description": "NVIDIA-H100-80GB-HBM3 (hopper family) on a Google-Compute-Engine machine", + "value": "GCP.GPU.H100", + "cpuArch": "amd64", + "os": "linux", + "driverVersion": "550.90.12", + "storage": "2.9Ti", + "default": null + }, + { + "cpuCores": 208, + "systemMemory": "1932077732Ki", + "gpuMemory": "652472M", + "gpuCount": 8, + "name": "GCP.GPU.H100_8x", + "description": "NVIDIA-H100-80GB-HBM3 (hopper family) on a Google-Compute-Engine machine", + "value": "GCP.GPU.H100", + "cpuArch": "amd64", + "os": "linux", + "driverVersion": "550.90.12", + "storage": "5.8Ti", + "default": null + }, + { + "cpuCores": 208, + "systemMemory": "1932077732Ki", + "gpuMemory": "81559M", + "gpuCount": 1, + "name": "GCP.GPU.H100_1x", + "description": "NVIDIA-H100-80GB-HBM3 (hopper family) on a Google-Compute-Engine machine", + "value": "GCP.GPU.H100", + "cpuArch": "amd64", + "os": "linux", + "driverVersion": "550.90.12", + "storage": "743.7Gi", + "default": true + } + ] + } + ], + "nvcaVersion": "2.37.0", + "clusterId": "53566955-d7f9-37fb-a782-93560f577f3c", + "clusterGroupId": "98aec553-8b1e-4812-b568-35f5c5bbf01e", + "status": "UNHEALTHY", + "nvcaLastConnected": "2024-09-26T06:42:46.502Z", + "k8sVersion": "v1.29.7-gke.1104000", + "gpuUsage": null, + "envoyConfig": { + "image": "envoy", + "repository": "docker.io/envoyproxy", + "tag": "v1.26.7" + }, + "vaultConfig": { + "address": "https://stg.vault.nvidia.com:443" + }, + "clusterUpgradeStatus": null + }, + { + "clusterName": "picasso-edify-azure-stg", + "clusterGroupName": "AZURE", + "clusterDescription": "Stage cluster for edify Azure", + "ncaId": "CMYBKSNNjtg1TQmSke-gHNGgMlFvA-dCRAI8gcHOBcw", + "authorizedNCAIds": [ + "*" + ], + "cloudProvider": "AZURE", + "region": "us-west-1", + "capabilities": [ + "CachingSupport", + "DynamicGPUDiscovery", + "LogPosting" + ], + "attributes": [], + "customAttributes": [], + "gpus": [ + { + "name": "A100", + "capacity": 0, + "instanceTypes": [ + { + "cpuCores": 96, + "systemMemory": "1857800888Ki", + "gpuMemory": "81920M", + "gpuCount": 1, + "name": "AZURE.GPU.A100_1x", + "description": "NVIDIA-A100-SXM4-80GB (ampere family) on a Virtual-Machine machine", + "value": "AZURE.GPU.A100", + "cpuArch": "amd64", + "os": "linux", + "driverVersion": "535.54.03", + "storage": "248.1Gi", + "default": true + }, + { + "cpuCores": 96, + "systemMemory": "1857800888Ki", + "gpuMemory": "655360M", + "gpuCount": 8, + "name": "AZURE.GPU.A100_8x", + "description": "NVIDIA-A100-SXM4-80GB (ampere family) on a Virtual-Machine machine", + "value": "AZURE.GPU.A100", + "cpuArch": "amd64", + "os": "linux", + "driverVersion": "535.54.03", + "storage": "1.9Ti", + "default": null + }, + { + "cpuCores": 96, + "systemMemory": "1857800888Ki", + "gpuMemory": "163840M", + "gpuCount": 2, + "name": "AZURE.GPU.A100_2x", + "description": "NVIDIA-A100-SXM4-80GB (ampere family) on a Virtual-Machine machine", + "value": "AZURE.GPU.A100", + "cpuArch": "amd64", + "os": "linux", + "driverVersion": "535.54.03", + "storage": "496.2Gi", + "default": null + }, + { + "cpuCores": 96, + "systemMemory": "1857800888Ki", + "gpuMemory": "327680M", + "gpuCount": 4, + "name": "AZURE.GPU.A100_4x", + "description": "NVIDIA-A100-SXM4-80GB (ampere family) on a Virtual-Machine machine", + "value": "AZURE.GPU.A100", + "cpuArch": "amd64", + "os": "linux", + "driverVersion": "535.54.03", + "storage": "992.3Gi", + "default": null + } + ] + } + ], + "nvcaVersion": "2.38.1", + "clusterId": "nvssa-stg-oP6_PUxnMVhYP2IRiPR_rbekw6hcmRpSCslV2BDiFvo", + "clusterGroupId": "1e7fb06a-6a24-4087-a071-35cc603892b6", + "status": "READY", + "nvcaLastConnected": "2024-11-25T21:33:50.149Z", + "k8sVersion": "v1.27.9", + "gpuUsage": { + "A100": { + "capacity": 24, + "allocated": 7, + "available": 17 + } + }, + "envoyConfig": { + "image": "envoy", + "repository": "docker.io/envoyproxy", + "tag": "v1.26.7" + }, + "vaultConfig": { + "address": "https://stg.vault.nvidia.com:443" + }, + "clusterUpgradeStatus": null + } +] \ No newline at end of file diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/resources/fixtures/icms/raw-healthy-instance.json b/src/control-plane-services/cloud-tasks/nvct-core/src/test/resources/fixtures/icms/raw-healthy-instance.json new file mode 100644 index 000000000..219e44c6a --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/resources/fixtures/icms/raw-healthy-instance.json @@ -0,0 +1,25 @@ +{ + "CreateTime": "2023-07-06T07:17:53.282Z", + "InstanceId": "%s", + "LaunchSpecification": { + "InstanceType": "%s", + "ContainerImage": "stg.nvcr.io/nv-cf/guineapig-1/ediffi:0.0.3", + "Placement": null, + "Gpu": "%s", + "Backend": "GFN", + "NcaId": "test-nca-id" + }, + "LaunchedAvailabilityZone": "NP-LAX-03", + "InstanceRequestId": "%s", + "CloudProvider": "GFN", + "State": "active", + "Status": { + "Code": "fulfilled", + "Message": "Your instance request is fulfilled", + "UpdateTime": "2023-07-06T07:57:06.731Z" + }, + "InstanceState": { + "Name": "running" + }, + "InstanceInterruptionBehavior": "terminate" +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/resources/fixtures/icms/raw-no-capacity-instance.json b/src/control-plane-services/cloud-tasks/nvct-core/src/test/resources/fixtures/icms/raw-no-capacity-instance.json new file mode 100644 index 000000000..684f0836a --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/resources/fixtures/icms/raw-no-capacity-instance.json @@ -0,0 +1,31 @@ +{ + "CreateTime": "2024-05-02T19:37:41.687Z", + "InstanceId": "%s", + "LaunchSpecification": { + "InstanceType": "%s", + "ContainerImage": "nvcr.io/whw3rcpsilnj/playground/maxine_vf_server_optimized:0.3", + "Placement": { + "AvailabilityZone": "NP-LAX-03" + }, + "Gpu": "%s", + "Backend": "GFN", + "NcaId": "NVVppkDl81nJZ0GtZORXNeeOoY8h1p1Tfd8vuIPFV18" + }, + "LaunchedAvailabilityZone": "NP-LAX-03", + "InstanceRequestId": "%s", + "CloudProvider": "GFN", + "State": "closed", + "Status": { + "Code": "instance-terminated-no-capacity", + "Message": "Instance status updated to instance-terminated-no-capacity", + "UpdateTime": "2024-05-03T17:23:15.492Z" + }, + "InstanceState": { + "Code": 48, + "Name": "terminated" + }, + "HealthInfo": { + "ErrorLog": "Instance terminated due to to capacity constraint" + }, + "InstanceInterruptionBehavior": "terminate" +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/resources/fixtures/icms/raw-unhealthy-instance.json b/src/control-plane-services/cloud-tasks/nvct-core/src/test/resources/fixtures/icms/raw-unhealthy-instance.json new file mode 100644 index 000000000..e29dabc18 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/resources/fixtures/icms/raw-unhealthy-instance.json @@ -0,0 +1,29 @@ +{ + "CreateTime": "2023-07-06T07:17:53.282Z", + "InstanceId": "%s", + "LaunchSpecification": { + "InstanceType": "%s", + "ContainerImage": "stg.nvcr.io/nv-cf/guineapig-1/ediffi:0.0.3", + "Placement": null, + "Gpu": "%s", + "Backend": "GFN", + "NcaId": "test-nca-id" + }, + "LaunchedAvailabilityZone": null, + "InstanceRequestId": "%s", + "CloudProvider": "GFN", + "State": "closed", + "Status": { + "Code": "instance-terminated-by-service", + "Message": "Your instance request has been terminated", + "UpdateTime": "2023-07-06T07:57:06.731Z" + }, + "InstanceState": { + "Code": 48, + "Name": "terminated" + }, + "HealthInfo": { + "ErrorLog": "%s: Inference container\n is failing\n to come up" + }, + "InstanceInterruptionBehavior": "terminate" +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/resources/fixtures/nvcf/account-response.json b/src/control-plane-services/cloud-tasks/nvct-core/src/test/resources/fixtures/nvcf/account-response.json new file mode 100644 index 000000000..a0542e233 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/resources/fixtures/nvcf/account-response.json @@ -0,0 +1,151 @@ +{ + "account": { + "ncaId": "%s", + "clientIds": [ + "%s" + ], + "name": "%s", + "registryCredentials": [ + { + "registryHostname": "docker.io", + "secret": { + "name": "docker-container-registry-credential", + "value": "dXNlcm5hbWU6ZG9ja2VyLXBhdC1wYXNzd29yZA==" + }, + "artifactTypes": [ + "CONTAINER", + "HELM" + ] + }, + { + "registryHostname": "779846807323.dkr.ecr.us-west-2.amazonaws.com", + "secret": { + "name": "ecr-container-registry-credential", + "value": "YWNjZXNzLWtleS1pZC0xOnNlY3JldC1hY2Nlc3Mta2V5LTE=" + }, + "artifactTypes": [ + "CONTAINER", + "HELM" + ] + }, + { + "registryHostname": "public.ecr.aws", + "secret": { + "name": "ecr-container-registry-credential", + "value": "YWNjZXNzLWtleS1pZC0xOnNlY3JldC1hY2Nlc3Mta2V5LTE=" + }, + "artifactTypes": [ + "CONTAINER", + "HELM" + ] + }, + { + "registryHostname": "test-volcengine-registry-cn-beijing.cr.volces.com", + "secret": { + "name": "ve-registry-credential", + "value": "dm9sY2VuZ2luZS1hY2Nlc3Mta2V5LTE6dm9sY2VuZ2luZS1zZWNyZXQta2V5LTE=" + }, + "artifactTypes": [ + "CONTAINER", + "HELM" + ] + }, + { + "registryHostname": "test1-bmfvajfxgfcrhba5.azurecr.io", + "secret": { + "name": "acr-registry-credential-1", + "value": "YWNyLWNsaWVudC1pZC0xOmFjci1jbGllbnQtc2VjcmV0LTE=" + }, + "artifactTypes": [ + "CONTAINER", + "HELM" + ] + }, + { + "registryHostname": "demo.goharbor.io", + "secret": { + "name": "harbor-registry-credential", + "value": "aGFyYm9yLXJvYm90LWFjY291bnQ6aGFyYm9yLXJvYm90LXBhc3N3b3Jk" + }, + "artifactTypes": [ + "CONTAINER", + "HELM" + ] + }, + { + "registryHostname": "artifactorytest12345.jfrog.io", + "secret": { + "name": "artifactory-registry-credential", + "value": "YXJ0aWZhY3RvcnktdXNlcm5hbWU6YXJ0aWZhY3RvcnktcGFzc3dvcmQ=" + }, + "artifactTypes": [ + "CONTAINER", + "HELM" + ] + }, + { + "registryHostname": "stg.nvcr.io", + "secret": { + "name": "ngc-container-registry-credential", + "value": "JG9hdXRodG9rZW46bnZhcGktc3RnLXRlc3QtY29udGFpbmVyLXJlZ2lzdHJ5LWNyZWQ=" + }, + "artifactTypes": [ + "CONTAINER" + ] + }, + { + "registryHostname": "localhost-ngc", + "secret": { + "name": "ngc-container-registry-credential", + "value": "JG9hdXRodG9rZW46bnZhcGktc3RnLXRlc3QtY29udGFpbmVyLXJlZ2lzdHJ5LWNyZWQ=" + }, + "artifactTypes": [ + "CONTAINER" + ] + }, + { + "registryHostname": "api.stg.ngc.nvidia.com", + "secret": { + "name": "ngc-model-resource-registry-credential", + "value": "JG9hdXRodG9rZW46bnZhcGktc3RnLXRlc3QtbW9kZWwtcmVnaXN0cnktY3JlZA==" + }, + "artifactTypes": [ + "MODEL", + "RESOURCE" + ] + }, + { + "registryHostname": "localhost-ngc", + "secret": { + "name": "ngc-model-resource-registry-credential", + "value": "JG9hdXRodG9rZW46bnZhcGktc3RnLXRlc3QtbW9kZWwtcmVnaXN0cnktY3JlZA==" + }, + "artifactTypes": [ + "MODEL", + "RESOURCE" + ] + }, + { + "registryHostname": "helm.stg.ngc.nvidia.com", + "secret": { + "name": "ngc-helm-registry-credential", + "value": "JG9hdXRodG9rZW46bnZhcGktc3RnLXRlc3QtaGVsbS1yZWdpc3RyeS1jcmVk" + }, + "artifactTypes": [ + "HELM" + ] + }, + { + "registryHostname": "localhost-ngc", + "secret": { + "name": "ngc-helm-registry-credential", + "value": "JG9hdXRodG9rZW46bnZhcGktc3RnLXRlc3QtaGVsbS1yZWdpc3RyeS1jcmVk" + }, + "artifactTypes": [ + "HELM" + ] + } + ], + "maxTasksAllowed": "%d" + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/resources/fixtures/nvcf/account-with-telemetries-response.json b/src/control-plane-services/cloud-tasks/nvct-core/src/test/resources/fixtures/nvcf/account-with-telemetries-response.json new file mode 100644 index 000000000..358c172e0 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/resources/fixtures/nvcf/account-with-telemetries-response.json @@ -0,0 +1,79 @@ +{ + "account": { + "ncaId": "%s", + "clientIds": [ "%s" ], + "name": "%s", + "telemetries": [ + { + "telemetryId": "edc4cd0a-80cd-4a7b-90d9-706b9eae9b4c", + "name": "datadog-prod-traces", + "endpoint": "https://otlp-gateway-prod-us-east-0.grafana.net/otlp", + "protocol": "GRPC", + "provider": "GRAFANA_CLOUD", + "types": [ + "TRACES" + ], + "createdAt": "_instant_" + }, + { + "telemetryId": "4df8cb5b-94e0-4fcc-ac12-ddb8da2f25aa", + "name": "grafana-prod-logs", + "endpoint": "https://otlp-gateway-prod-us-east-0.grafana.net/otlp", + "protocol": "GRPC", + "provider": "GRAFANA_CLOUD", + "types": [ + "LOGS" + ], + "createdAt": "_instant_" + }, + { + "telemetryId": "d49695b0-86b1-4a84-9b82-2ea823f51d78", + "name": "datadog-prod", + "endpoint": "datadoghq.com", + "protocol": "GRPC", + "provider": "DATADOG", + "types": [ + "METRICS" + ], + "createdAt": "_instant_" + } + ], + "registryCredentials": [ + { + "registryHostname": "stg.nvcr.io", + "secret": { + "name": "ngc-container-registry-credential", + "value": "JG9hdXRodG9rZW46bnZhcGktc3RnLXRlc3QtY29udGFpbmVyLXJlZ2lzdHJ5LWNyZWQ=" + }, + "artifactTypes": [ + "CONTAINER" + ] + }, + { + "registryHostname": "api.stg.ngc.nvidia.com", + "secret": { + "name": "ngc-model-resource-registry-credential", + "value": "JG9hdXRodG9rZW46bnZhcGktc3RnLXRlc3QtbW9kZWwtcmVnaXN0cnktY3JlZA==" + }, + "artifactTypes": [ + "MODEL", + "RESOURCE" + ] + }, + { + "registryHostname": "helm.stg.ngc.nvidia.com", + "secret": { + "name": "ngc-helm-registry-credential", + "value": "JG9hdXRodG9rZW46bnZhcGktc3RnLXRlc3QtY29udGFpbmVyLXJlZ2lzdHJ5LWNyZWQ=" + }, + "artifactTypes": [ + "HELM" + ] + } + ], + "maxFunctionsAllowed": 146, + "maxTasksAllowed": "%d", + "currentNumberFunctions": 98, + "lastUpdatedAt": "_instant_" + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/resources/fixtures/nvcf/account-without-registry-credentials-response.json b/src/control-plane-services/cloud-tasks/nvct-core/src/test/resources/fixtures/nvcf/account-without-registry-credentials-response.json new file mode 100644 index 000000000..363f211bf --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/resources/fixtures/nvcf/account-without-registry-credentials-response.json @@ -0,0 +1,10 @@ +{ + "account": { + "ncaId": "%s", + "clientIds": [ + "%s" + ], + "name": "%s", + "maxTasksAllowed": "%d" + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/resources/fixtures/nvcf/client-response.json b/src/control-plane-services/cloud-tasks/nvct-core/src/test/resources/fixtures/nvcf/client-response.json new file mode 100644 index 000000000..e90d5059e --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/resources/fixtures/nvcf/client-response.json @@ -0,0 +1,7 @@ +{ + "client": { + "clientId": "%s", + "ncaId": "%s", + "name": "%s" + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/resources/load-test.js b/src/control-plane-services/cloud-tasks/nvct-core/src/test/resources/load-test.js new file mode 100644 index 000000000..99bc3876b --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/resources/load-test.js @@ -0,0 +1,57 @@ +// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 +// +// 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. +import http from 'k6/http'; + +export default function () { + const url = 'https://stg.api.nvcf.nvidia.com/v1/nvcf'; + const payload = JSON.stringify({ + "requestHeader": { + "functionName": "simple_int8_sre", + "functionId": "7d199eeb-8af6-4588-ba60-3009773cd29d", + "metadata": [{"key": "metadata-key1", "value": "value1"}, + {"key": "metadata-key2", "value": "value2"}] + }, + "requestBody": { + "id": "42", + "inputs": [{ + "name": "INPUT0", + "shape": [1, 16], + "datatype": "INT8", + "data": [5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5] + }, { + "name": "INPUT1", + "shape": [1, 16], + "datatype": "INT8", + "data": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] + }], + "outputs": [{"name": "OUTPUT0"}, {"name": "OUTPUT1"}] + } + }); + const params = { + headers: { + 'Content-Type': 'application/json', + 'Authorization': 'Bearer <>', + }, + }; + const response = http.post(url, payload, params); + if (response.status == 202) { + const requestId = response.json().reqId; + let response_status = 202 + while (response_status == 202) { + const res = http.get(url + '/' + requestId, params); + response_status = res.status; // console.log(response_status) + } + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-service/BUILD.bazel b/src/control-plane-services/cloud-tasks/nvct-service/BUILD.bazel new file mode 100644 index 000000000..69c4b81f1 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-service/BUILD.bazel @@ -0,0 +1,102 @@ +load("@contrib_rules_jvm//java:defs.bzl", "java_junit5_test") +load("//rules/java:defs.bzl", "nvcf_java_library", "nvcf_spring_boot_image") + +package(default_visibility = ["//visibility:public"]) + +# Error Prone runs in the default Bazel Java toolchain; keep the checks the +# service opts out of and enable deprecation lints. --release matches the +# hermetic remotejdk toolchain language level. +NVCT_JAVACOPTS = [ + "--release", + "25", + "-Xep:CheckReturnValue:OFF", + "-Xep:ImpossibleNullComparison:OFF", + "-Xep:OptionalOfRedundantMethod:OFF", + "-Xlint:deprecation", +] + +# nvcf_java_library does not wire Lombok; add the annotation processor plugin +# plus the neverlink annotations jar to every library that compiles Lombok +# sources. Both targets already exist in tools/bazel. +LOMBOK_PLUGINS = ["//src/control-plane-services/cloud-tasks/tools/bazel:lombok_plugin"] + +LOMBOK_DEPS = ["//src/control-plane-services/cloud-tasks/tools/bazel:lombok_annotations"] + +JUNIT5_RUNTIME_DEPS = [ + "@nv_third_party_deps//:org_junit_jupiter_junit_jupiter_engine", + "@nv_third_party_deps//:org_junit_platform_junit_platform_launcher", + "@nv_third_party_deps//:org_junit_platform_junit_platform_reporting", +] + +nvcf_java_library( + name = "app_classes", + srcs = glob(["src/main/java/**/*.java"]), + javacopts = NVCT_JAVACOPTS, + plugins = LOMBOK_PLUGINS, + resource_strip_prefix = "src/control-plane-services/cloud-tasks/nvct-service/src/main/resources", + resources = glob(["src/main/resources/**"]), + deps = [ + "//src/control-plane-services/cloud-tasks/nvct-core:nvct_core", + "@nv_third_party_deps//:org_slf4j_slf4j_api", + "@nv_third_party_deps//:org_springframework_boot_spring_boot", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_autoconfigure", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_loader", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_micrometer_tracing", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_security", + ] + LOMBOK_DEPS, +) + +# Multi-arch OCI image (exploded classpath under /app/lib). Build-only for now: +# no registry = ... is set, so no :image_push target is emitted. :image_index +# carries the amd64 + arm64 manifest. +nvcf_spring_boot_image( + name = "image", + main_class = "com.nvidia.nvct.App", + deps = [":app_classes"], +) + +java_junit5_test( + name = "tests", + size = "large", + srcs = glob(["src/test/java/**/*.java"]), + test_class = "com.nvidia.nvct.NvctServiceIntegrationTest", + javacopts = NVCT_JAVACOPTS, + plugins = LOMBOK_PLUGINS, + resources = glob(["src/test/resources/**"]) + [ + "//src/control-plane-services/cloud-tasks:integration_local_env_files", + ], + data = [ + "//src/control-plane-services/cloud-tasks:integration_local_env", + ], + tags = [ + "exclusive", + "requires-docker", + ], + timeout = "long", + deps = [ + ":app_classes", + "//src/control-plane-services/cloud-tasks/nvct-core:nvct_core", + "//src/control-plane-services/cloud-tasks/nvct-core:nvct_core_test_fixtures", + "//src/libraries/java/nv-boot-parent/nv-boot-mock-servers-test:nv_boot_mock_servers_test", + "@nv_third_party_deps//:io_opentelemetry_opentelemetry_sdk_testing", + "@nv_third_party_deps//:org_assertj_assertj_core", + "@nv_third_party_deps//:org_junit_jupiter_junit_jupiter_api", + "@nv_third_party_deps//:org_junit_jupiter_junit_jupiter_params", + "@nv_third_party_deps//:org_mockito_mockito_core", + "@nv_third_party_deps//:org_mockito_mockito_junit_jupiter", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_test", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_test_autoconfigure", + "@nv_third_party_deps//:org_springframework_spring_test", + "@nv_third_party_deps//:org_springframework_boot_spring_boot", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_restclient", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_resttestclient", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_webmvc_test", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_web_server", + "@nv_third_party_deps//:org_springframework_spring_beans", + "@nv_third_party_deps//:org_springframework_spring_web", + "@nv_third_party_deps//:org_springframework_spring_webmvc", + "@nv_third_party_deps//:org_testcontainers_testcontainers", + "@nv_third_party_deps//:org_testcontainers_testcontainers_cassandra", + ] + LOMBOK_DEPS, + runtime_deps = JUNIT5_RUNTIME_DEPS, +) diff --git a/src/control-plane-services/cloud-tasks/nvct-service/local_env b/src/control-plane-services/cloud-tasks/nvct-service/local_env new file mode 120000 index 000000000..a02c0a7d3 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-service/local_env @@ -0,0 +1 @@ +../local_env \ No newline at end of file diff --git a/src/control-plane-services/cloud-tasks/nvct-service/pom.xml b/src/control-plane-services/cloud-tasks/nvct-service/pom.xml new file mode 100644 index 000000000..3f87f5bfc --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-service/pom.xml @@ -0,0 +1,113 @@ + + + + 4.0.0 + + + com.nvidia.nvct + cloud-tasks + 0.0.1-SNAPSHOT + + + nvct-service-oss + jar + NVCT Service OSS + + NVIDIA Cloud Tasks — OSS executable + + + + com.nvidia.nvct.App + + + + + com.nvidia.nvct + nvct-core + ${project.version} + + + + + com.nvidia.nvct + nvct-core + ${project.version} + test-jar + tests + test + + + + + io.opentelemetry + opentelemetry-sdk-testing + test + + + org.springframework.boot + spring-boot-starter-webmvc-test + test + + + org.springframework.boot + spring-boot-restclient + test + + + org.testcontainers + testcontainers + test + + + org.testcontainers + testcontainers-cassandra + test + + + com.nvidia.boot + nv-boot-mock-servers-test + test + + + + + app + + + src/main/resources + true + + + + + org.springframework.boot + spring-boot-maven-plugin + + + io.github.git-commit-id + git-commit-id-maven-plugin + + ${project.parent.basedir}/.git + + + + + diff --git a/src/control-plane-services/cloud-tasks/nvct-service/src/main/java/com/nvidia/nvct/App.java b/src/control-plane-services/cloud-tasks/nvct-service/src/main/java/com/nvidia/nvct/App.java new file mode 100644 index 000000000..be0b45e4f --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-service/src/main/java/com/nvidia/nvct/App.java @@ -0,0 +1,34 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.micrometer.tracing.autoconfigure.prometheus.PrometheusExemplarsAutoConfiguration; +import org.springframework.boot.security.autoconfigure.ReactiveUserDetailsServiceAutoConfiguration; + +@Slf4j +@SpringBootApplication(exclude = { + ReactiveUserDetailsServiceAutoConfiguration.class, + PrometheusExemplarsAutoConfiguration.class}) +public class App { + + public static void main(String[] args) { + SpringApplication.run(App.class, args); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-service/src/main/resources/application-local.yaml b/src/control-plane-services/cloud-tasks/nvct-service/src/main/resources/application-local.yaml new file mode 100644 index 000000000..431a0e932 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-service/src/main/resources/application-local.yaml @@ -0,0 +1,61 @@ +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +# +# 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. +spring: + cassandra: + contact-points: 127.0.0.1 + # Expect local_env/docker-compose.yml (9042:9042); port defaults from application.yaml. + username: cassandra + password: cassandra + +management: + tracing: + export: + enabled: false + opentelemetry: + tracing: + export: + otlp: + endpoint: https://dummy:8282 + +logging: + level: + com.nvidia: DEBUG + com.nvidia.nvct.configuration: INFO + org.springframework.web: DEBUG + org.springframework.data.cassandra.core.cql.CqlTemplate: DEBUG + +nvct: + aws: + region: us-east-1 + ess: + enabled: false + base-url: http://localhost:9098 + notary: + audiences: + ess: ess-api + nvct: nvct-api + base-url: http://localhost:9097 + nvcf: + base-url: http://localhost:9119 + reval: + base-url: http://localhost:9099 + icms: + allocator: + enabled: false + base-url: http://localhost:9096 + api-keys: + base-url: http://localhost:9093 + scheduled-routines: + enabled: false diff --git a/src/control-plane-services/cloud-tasks/nvct-service/src/main/resources/application-ncp.yaml b/src/control-plane-services/cloud-tasks/nvct-service/src/main/resources/application-ncp.yaml new file mode 100644 index 000000000..36aa4c350 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-service/src/main/resources/application-ncp.yaml @@ -0,0 +1,146 @@ +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +# +# 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. +spring: + cassandra: + contact-points: ${CASSANDRA_CONTACT_POINTS:cassandra.cassandra-system.svc.cluster.local} + keyspace-name: nvct_api + local-datacenter: ${CASSANDRA_DATACENTER:ncp} + username: cassandra + password: cassandra + security: + oauth2: + resourceserver: + jwt: + issuer-uri: http://nvct-api.nvcf.svc.cluster.local + jwk-set-uri: http://openbao-server.vault-system.svc.cluster.local:8200/v1/services/nvct-api/jwt/jwks + client: + registration: + api-keys: + client-id: unused # Override the inherited expression from application.yaml + client-secret: unused + icms: + client-id: unused + client-secret: unused + nvcf: + client-id: unused + client-secret: unused + notary: + # For validating jwt.sub == client-id as Notary Svc signs with sub nvct-api + client-id: nvct-api + client-secret: unused + ess: + client-id: unused + client-secret: unused + reval: + client-id: unused + client-secret: unused + provider: + api-keys: + token-uri: unused + icms: + token-uri: unused + nvcf: + token-uri: unused + notary: + token-uri: unused + ess: + token-uri: unused + reval: + token-uri: unused + +management: + tracing: + export: + enabled: false + opentelemetry: + tracing: + export: + otlp: + endpoint: https://dummy:8282 + headers: + lightstep-access-token: unused + +nvct: + aws: + region: ncp + fqdn: http://nvct-api.nvcf.svc.cluster.local:8080 + global-fqdn-grpc: http://nvct-api.nvcf.svc.cluster.local:9090 + sidecars: + tracing-key: unused + hostname: nvcr.io + repository: nv-cf/nvcf-core + # Sidecar container images are configured in configData in nvct-api-colocated-deploy/nvct-api/values.yaml: + # https://gitlab-master.nvidia.com/ncp/nvcf/application-services/nvct-api-colocated-deploy/-/blob/main/nvct-api/values.yaml + init-container: dummy + utils-container: dummy + otel-container: dummy + ess-agent-container: dummy + otel-collector-container: dummy + scheduled-routines: + lock-consistency: LOCAL_QUORUM + ess: + base-url: http://ess-api.ess.svc.cluster.local:8080 + static: + token: ${kv.tokens.ess} + notary: + audiences: + ess: ess-api + nvct: nvct-api + base-url: http://notary.nvcf.svc.cluster.local:8080 + static: + token: ${kv.tokens.notary} + nvcf: + cache-ttl: PT5M + base-url: http://api.nvcf.svc.cluster.local:8080 + static: + token: ${kv.tokens.nvcf} + reval: + enabled: false + base-url: http://reval.nvcf.svc.cluster.local:8080 + static: + token: ${kv.tokens.reval} + icms: + base-url: http://api.sis.svc.cluster.local:8080 + # base-url: http://api.icms.svc.cluster.local:8080 -- Use when self-hosted stack is ready + static: + token: ${kv.tokens.icms} + api-keys: + base-url: http://api-keys.api-keys.svc.cluster.local:8080 + # base-url: http://api-keys.nvcf.svc.cluster.local:8080 -- Use when self-hosted stack is ready + static: + token: ${kv.tokens.api-keys} + registries: + recognized: + container: + ngc: + hostname: "nvcr.io" + helm: + ngc: + hostname: "helm.ngc.nvidia.com" + oauth2: + base-url: https://authn.nvidia.com + group-scope: ngc + model: + ngc: + hostname: "api.ngc.nvidia.com" + oauth2: + base-url: https://authn.nvidia.com + group-scope: ngc + resource: + ngc: + hostname: "api.ngc.nvidia.com" + oauth2: + base-url: https://authn.nvidia.com + group-scope: ngc diff --git a/src/control-plane-services/cloud-tasks/nvct-service/src/main/resources/application.yaml b/src/control-plane-services/cloud-tasks/nvct-service/src/main/resources/application.yaml new file mode 100644 index 000000000..4138d9e9f --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-service/src/main/resources/application.yaml @@ -0,0 +1,342 @@ +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +# +# 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. +spring: + cassandra: + contact-points: 127.0.0.1 + keyspace-name: nvct + local-datacenter: datacenter1 + advanced: + speculative-execution-policy: + class: ConstantSpeculativeExecutionPolicy + max-executions: 1 + delay: 1500 #milliseconds + connection: + max-requests-per-connection: 10000 + pool: + local: + size: 2 + retry-policy: + class: com.nvidia.boot.cassandra.retry.NextHostRetryPolicy + port: 9042 + password: ${kv.cassandra.password} + username: ${kv.cassandra.username} + compression: lz4 + connection: + connect-timeout: 10s + init-query-timeout: 10s + pool: + heartbeat-interval: 30s + idle-timeout: 60s + request: + consistency: local_quorum + page-size: 5000 + serial-consistency: local_serial + timeout: 10s + session-name: nvct-api-session + session-metrics: + - bytes-sent + - connected-nodes + - cql-requests + node-metrics: + - pool.open-connections + - pool.in-flight + codec: + max-in-memory-size: 10MB + threads: + virtual: + enabled: false + security: + oauth2: + resourceserver: + jwt: + issuer-uri: http://localhost:9092 + jwk-set-uri: ${spring.security.oauth2.resourceserver.jwt.issuer-uri}/.well-known/jwks.json + jws-algorithms: ES256 + client: + registration: + api-keys: + provider: api-keys + client-id: ${kv.oauth2.client-id} + client-secret: ${kv.oauth2.client-secret} + authorization-grant-type: client_credentials + scope: pdp-evaluate + icms: + provider: icms + client-id: ${kv.oauth2.client-id} + client-secret: ${kv.oauth2.client-secret} + authorization-grant-type: client_credentials + scope: instance-request,cluster_listing,instance_types,cluster-management + nvcf: + provider: nvcf + client-id: ${kv.oauth2.client-id} + client-secret: ${kv.oauth2.client-secret} + authorization-grant-type: client_credentials + scope: account_setup + notary: + provider: notary + client-id: ${kv.oauth2.client-id} + client-secret: ${kv.oauth2.client-secret} + authorization-grant-type: client_credentials + scope: make-assertion + ess: + provider: ess + client-id: ${kv.oauth2.client-id} + client-secret: ${kv.oauth2.client-secret} + authorization-grant-type: client_credentials + scope: ess:secrets-admin,ess:entities-admin + reval: + provider: reval + client-id: ${kv.oauth2.client-id} + client-secret: ${kv.oauth2.client-secret} + authorization-grant-type: client_credentials + scope: helmreval:validate + provider: + api-keys: + token-uri: ${spring.security.oauth2.resourceserver.jwt.issuer-uri}/token + icms: + token-uri: ${spring.security.oauth2.resourceserver.jwt.issuer-uri}/token + nvcf: + token-uri: ${spring.security.oauth2.resourceserver.jwt.issuer-uri}/token + notary: + token-uri: ${spring.security.oauth2.resourceserver.jwt.issuer-uri}/token + ess: + token-uri: ${spring.security.oauth2.resourceserver.jwt.issuer-uri}/token + reval: + token-uri: ${spring.security.oauth2.resourceserver.jwt.issuer-uri}/token + +logging: + level: + com.nvidia: INFO + org.springframework.web: INFO + +management: + tracing: + export: + enabled: true + sampling: + probability: 1.0 # Parity with javaagent based tracing + propagation: + type: w3c + opentelemetry: + resource-attributes: # Resource attributes for traces (attached to every span) + cloud.provider: ${CLOUD_PROVIDER:aws} + cloud.region: ${nvct.aws.region} + deployment.profiles: ${spring.profiles.active} + host.dc: ${spring.application.host.dc} + host.id: ${spring.application.host.id} + host.name: ${spring.application.host.id} + service.name: ${spring.application.name} + service.version: ${spring.application.version} + service.namespace: nvct + tracing: + export: + otlp: + endpoint: ${OTEL_EXPORTER_OTLP_ENDPOINT:https://dummy:8282} + compression: gzip + transport: http + timeout: 30s + headers: + lightstep-access-token: ${kv.tracing.accessToken} + endpoints: + web: + base-path: /actuator + exposure: + include: health,metrics,prometheus + endpoint: + health: + cache: + time-to-live: 2s + probes: + enabled: true + show-details: always + group: + readiness: + include: + - readinessState + - cassandra + liveness: + include: + - livenessState + - cassandra + health: + livenessState: + enabled: true + readinessState: + enabled: true + vault: + enabled: false + kubernetes: + enabled: false + metrics: + enable: + all: true + tags: + env: ${spring.application.env} + micro_service: ${spring.application.name} + service_version: ${spring.application.version} + host_id: ${spring.application.host.id} + host_dc: ${spring.application.host.dc} + distribution: + percentiles-histogram: + "[http.server.requests]": true + slo: + "[http.server.requests]": "5ms,10ms,25ms,50ms,75ms,100ms,200ms,300ms,400ms,500ms,750ms,1s,2s,3s,4s,5s,10s,15s,20s,30s" + observations: + annotations: + enabled: true + prometheus: + metrics: + export: + enabled: true + server: + port: 8181 + +server: + port: 8080 + compression: + enabled: true + forward-headers-strategy: framework + +nvct: + fqdn: http://localhost:${server.port} + global-fqdn-grpc: http://localhost:${grpc.server.port} + sidecars: + tracing-key: ${kv.worker-tracing} + hostname: stg.nvcr.io + repository: nv-cf/nvcf-core + image-pull-secret: ${kv.sidecars.image-pull-secret} + init-container: ${nvct.sidecars.hostname}/${nvct.sidecars.repository}/nvcf_worker_init:2.102.0 + utils-container: ${nvct.sidecars.hostname}/${nvct.sidecars.repository}/nvcf_worker_utils:2.101.0 + otel-container: ${nvct.sidecars.hostname}/${nvct.sidecars.repository}/opentelemetry-collector:0.126.0 + ess-agent-container: ${nvct.sidecars.hostname}/${nvct.sidecars.repository}/ess-agent:1.0.5 + otel-collector-container: ${nvct.sidecars.hostname}/${nvct.sidecars.repository}/byoo-otel-collector:0.126.16 + scheduled-routines: + enabled: true + lock-consistency: LOCAL_QUORUM + notary: + jwt: + issuer-uri: ${nvct.notary.base-url} + jwk-set-uri: ${nvct.notary.jwt.issuer-uri}/.well-known/jwks.json + rate-limiters: + account-rate-limiter: + allowed-invocations-per-second: 200 + task-rate-limiter: + allowed-invocations-per-second: 200 + registries: + recognized: + container: + docker: + name: "Docker Hub Registry" + hostname: "docker.io" + call-timeout: PT10S + oauth2: + base-url: https://auth.docker.io/ + group-scope: pull + ngc: + name: "NGC Private Registry" + hostname: "stg.nvcr.io" + call-timeout: PT60S + read-timeout: PT30S + write-timeout: PT30S + connection-timeout: PT60S + ecr: + name: "AWS ECR Private Registry" + hostname: "dkr.ecr.amazonaws.com" + call-timeout: PT10S + ecr-public: + name: "AWS ECR Public Registry" + hostname: "public.ecr.aws" + call-timeout: PT10S + volcengine: + name: "Volcano Engine Registry" + hostname: "cr.volces.com" + call-timeout: PT10S + acr: + name: "Azure Container Registry" + hostname: "azurecr.io" + call-timeout: PT10S + helm: + ngc: + name: "NGC Private Registry" + hostname: "helm.stg.ngc.nvidia.com" + call-timeout: PT60S + read-timeout: PT30S + write-timeout: PT30S + connection-timeout: PT60S + oauth2: + base-url: unused + group-scope: ngc-stg + docker: + name: "Docker Hub Registry" + hostname: "docker.io" + call-timeout: PT10S + oauth2: + base-url: https://auth.docker.io/ + group-scope: pull + ecr: + name: "AWS ECR Private Registry" + hostname: "dkr.ecr.amazonaws.com" + call-timeout: PT10S + ecr-public: + name: "AWS ECR Public Registry" + hostname: "public.ecr.aws" + call-timeout: PT10S + volcengine: + name: "Volcano Engine Registry" + hostname: "cr.volces.com" + call-timeout: PT10S + acr: + name: "Azure Container Registry" + hostname: "azurecr.io" + call-timeout: PT10S + model: + ngc: + name: "NGC Private Registry" + hostname: "api.stg.ngc.nvidia.com" + call-timeout: PT60S + read-timeout: PT30S + write-timeout: PT30S + connection-timeout: PT60S + oauth2: + base-url: unused + group-scope: ngc-stg + resource: + ngc: + name: "NGC Private Registry" + hostname: "api.stg.ngc.nvidia.com" + call-timeout: PT60S + read-timeout: PT30S + write-timeout: PT30S + connection-timeout: PT60S + oauth2: + base-url: unused + group-scope: ngc-stg + +grpc: + server: + port: 9090 + # enable keep alive pings to all live connections with client to check if they are still connected. + enable-keep-alive: true + # frequency of sending keep alive pings. + keep-alive-time: 15m + # duration within which the keep alive ack ping is expected before disconnecting. + keep-alive-timeout: 10s + # worst keep alive pings frequency the client can set. No client can send keep alive pings with frequency lesser than this. + permit-keep-alive-time: 1s + # whether keepalive will be performed when there are no outstanding RPC on a connection + permit-keep-alive-without-calls: true + # support large worker responses + max-inbound-message-size: ${spring.codec.max-in-memory-size} + shutdown-grace-period: 5m diff --git a/src/control-plane-services/cloud-tasks/nvct-service/src/main/resources/bootstrap-local.yaml b/src/control-plane-services/cloud-tasks/nvct-service/src/main/resources/bootstrap-local.yaml new file mode 100644 index 000000000..dc55c6fcb --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-service/src/main/resources/bootstrap-local.yaml @@ -0,0 +1,19 @@ +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +# +# 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. +spring: + application: + env: local + +# debug: true diff --git a/src/control-plane-services/cloud-tasks/nvct-service/src/main/resources/bootstrap-ncp.yaml b/src/control-plane-services/cloud-tasks/nvct-service/src/main/resources/bootstrap-ncp.yaml new file mode 100644 index 000000000..d946dc4b4 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-service/src/main/resources/bootstrap-ncp.yaml @@ -0,0 +1,21 @@ +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +# +# 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. +spring: + application: + env: ncp + +nv-boot: + reloadable-properties: + file: "file:/home/app/vault/secrets.json" diff --git a/src/control-plane-services/cloud-tasks/nvct-service/src/main/resources/bootstrap.yaml b/src/control-plane-services/cloud-tasks/nvct-service/src/main/resources/bootstrap.yaml new file mode 100644 index 000000000..df97f79a2 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-service/src/main/resources/bootstrap.yaml @@ -0,0 +1,44 @@ +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +# +# 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. +spring: + application: + name: nvct-api + env: default + version: ${SPRING_APPLICATION_VERSION:0.0.1-dummy-version} + host: + id: ${HOSTNAME:${spring.application.name}-${random.int}-host} + dc: ${AWS_REGION:${spring.application.name}-${random.uuid}-dc} + cloud: + kubernetes: + config: + enabled: ${REMOTE_CONFIG_ENABLED:false} + name: ${REMOTE_CONFIG_NAME:nvct-api-remote-config} + fail-fast: true + retry: + enabled: true + max-attempts: 6 + reload: + enabled: true + mode: event + strategy: refresh + monitoring-config-maps: true + monitoring-secrets: false + refresh: + # Avoid warning - java.lang.IllegalArgumentException: wrong number of arguments: 0 expected: 27 - during startup + never-refreshable: com.zaxxer.hikari.HikariDataSource,org.springframework.cloud.kubernetes.commons.KubernetesClientProperties + +nv-boot: + reloadable-properties: + file: local_env/vault/secrets.json diff --git a/src/control-plane-services/cloud-tasks/nvct-service/src/test/java/com/nvidia/nvct/NvctServiceIntegrationTest.java b/src/control-plane-services/cloud-tasks/nvct-service/src/test/java/com/nvidia/nvct/NvctServiceIntegrationTest.java new file mode 100644 index 000000000..8483fe77f --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-service/src/test/java/com/nvidia/nvct/NvctServiceIntegrationTest.java @@ -0,0 +1,68 @@ +/* + * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * + * 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.nvidia.nvct; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.net.URI; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.resttestclient.TestRestTemplate; +import org.springframework.boot.resttestclient.autoconfigure.AutoConfigureTestRestTemplate; +import org.springframework.boot.test.web.server.LocalManagementPort; +import org.springframework.http.HttpStatus; +import org.springframework.http.RequestEntity; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.web.client.RestTemplate; + +/** + * OSS executable ({@link App} + {@code nvct-core}) smoke tests. Parallels the managed + * {@code nvct-service} repo integration tests, except this module has no + * {@code NvBootConfiguration} / {@code AuditProperties} wiring. + */ +@SpringBootTest( + classes = {App.class, IntegrationTestConfiguration.class}, + webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, + properties = "spring.profiles.active=test") +@ContextConfiguration(initializers = IntegrationTestConfiguration.Initializer.class) +@AutoConfigureTestRestTemplate +class NvctServiceIntegrationTest { + + @Autowired + private TestRestTemplate testRestTemplate; + + @LocalManagementPort + private int managementPort; + + @Test + void healthEndpointReturnsOk() { + var response = testRestTemplate.exchange( + RequestEntity.get(URI.create("/health")).build(), + String.class); + assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); + } + + @Test + void actuatorHealthReturnsOk() { + var endpoint = URI.create("http://localhost:" + managementPort + "/actuator/health"); + var response = new RestTemplate().exchange(RequestEntity.get(endpoint).build(), String.class); + assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); + assertThat(response.getBody()).isNotNull(); + assertThat(response.getBody()).containsIgnoringCase("status"); + } +} diff --git a/src/control-plane-services/cloud-tasks/nvct-service/src/test/resources/application-test.yaml b/src/control-plane-services/cloud-tasks/nvct-service/src/test/resources/application-test.yaml new file mode 100644 index 000000000..398f3eb69 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-service/src/test/resources/application-test.yaml @@ -0,0 +1,222 @@ +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +# +# 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. +spring.main.allow-bean-definition-overriding: true + +# Faster JVM exit after integration tests (avoids Surefire fork exit timeout when many +# @SpringBootTest contexts shut down gRPC + Tomcat + file watchers sequentially). +server: + shutdown: immediate + +grpc: + server: + port: 0 # Random port to avoid BindException when running multiple integration tests + +spring: + lifecycle: + timeout-per-shutdown-phase: 5s + cassandra: + contact-points: 127.0.0.1 + keyspace-name: nvct + request: + timeout: 30s + security: + oauth2: + resourceserver: + jwt: + issuer-uri: http://localhost:9092 + +management: + tracing: + export: + enabled: false + opentelemetry: + tracing: + export: + otlp: + endpoint: https://dummy:8282 + +logging: + level: + com.nvidia: DEBUG + com.nvidia.nvct.configuration: INFO + com.nvidia.nvct.util: INFO + org.springframework.web.client.RestTemplate: INFO + org.springframework.web.HttpLogging: INFO + org.springframework.web: DEBUG + org.springframework.data.cassandra.core.cql.CqlTemplate: INFO + +nvct: + fqdn: http://localhost:${server.port} + global-fqdn-grpc: http://localhost:9090 + sidecars: + hostname: fake.registry.test + aws: + region: us-east-1 + ess: + base-url: http://localhost:9098 + notary: + audiences: + ess: dummy-ess-audience + nvct: dummy-nvct-audience + base-url: http://localhost:9097 + nvcf: + base-url: http://localhost:9119 + reval: + base-url: http://localhost:9099 + icms: + base-url: http://localhost:9096 + allocator: + enabled: true + api-keys: + base-url: http://localhost:9093 + rate-limiters: + account-rate-limiter: + allowed-invocations-per-second: 200 + task-rate-limiter: + allowed-invocations-per-second: 200 + scheduled-routines: + enabled: true + lock-consistency: QUORUM + clean-terminal-tasks-routine: + enabled: false + monitor-launched-tasks-routine: + enabled: false + monitor-queued-tasks-routine: + enabled: false + monitor-worker-heartbeat-routine: + enabled: false + registries: + recognized: + container: + docker: + name: "Docker Hub Registry" + hostname: http://localhost-docker:9101 + call-timeout: PT10S + oauth2: + base-url: http://localhost:9102 + group-scope: pull + ngc: + name: "NGC Private Registry" + hostname: "http://localhost-ngc:9100" + call-timeout: PT60S + read-timeout: PT30S + write-timeout: PT30S + connection-timeout: PT60S + ecr: + name: "AWS ECR Private Registry" + hostname: http://localhost-ecr:9103 + call-timeout: PT10S + ecr-public: + name: "AWS ECR Public Registry" + hostname: http://localhost-ecr-public:9104 + call-timeout: PT10S + volcengine: + name: "Volcano Engine Registry" + hostname: http://localhost-volcengine:9105 + call-timeout: PT10S + acr: + name: "Azure Container Registry" + hostname: http://localhost-acr:9106 + call-timeout: PT10S + oauth2: + base-url: http://localhost-acr:9107 + harbor: + name: "Harbor Registry" + hostname: http://localhost-harbor:9108 + call-timeout: PT10S + oauth2: + base-url: http://localhost:9109 + artifactory: + name: "Artifactory Registry" + hostname: http://localhost-artifactory:9110 + call-timeout: PT10S + oauth2: + base-url: http://localhost-artifactory:9111 + custom-1: + name: "Custom Registry Test 1" + hostname: "custom-registry-test-1.com" + helm: + ngc: + name: "NGC Private Registry" + hostname: "http://localhost-ngc:9094" + call-timeout: PT60S + read-timeout: PT30S + write-timeout: PT30S + connection-timeout: PT60S + oauth2: + base-url: "http://localhost:9095" + group-scope: ngc-stg + docker: + name: "Docker Hub Registry" + hostname: http://localhost-docker:9101 + call-timeout: PT10S + oauth2: + base-url: http://localhost:9102 + group-scope: pull + ecr: + name: "AWS ECR Private Registry" + hostname: http://localhost-ecr:9103 + call-timeout: PT10S + ecr-public: + name: "AWS ECR Public Registry" + hostname: http://localhost-ecr-public:9104 + call-timeout: PT10S + volcengine: + name: "Volcano Engine Registry" + hostname: http://localhost-volcengine:9105 + call-timeout: PT10S + acr: + name: "Azure Container Registry" + hostname: http://localhost-acr:9106 + call-timeout: PT10S + oauth2: + base-url: http://localhost-acr:9107 + harbor: + name: "Harbor Registry" + hostname: http://localhost-harbor:9108 + call-timeout: PT10S + oauth2: + base-url: http://localhost:9109 + artifactory: + name: "JFrog Artifactory" + hostname: http://localhost-artifactory:9110 + call-timeout: PT10S + oauth2: + base-url: http://localhost-artifactory:9111 + custom-1: + name: "Custom Registry Test 1" + hostname: "custom-registry-test-1.com" + model: + ngc: + name: "NGC Private Registry" + hostname: "http://localhost-ngc:9094" + call-timeout: PT60S + read-timeout: PT30S + write-timeout: PT30S + connection-timeout: PT60S + oauth2: + base-url: "http://localhost:9095" + group-scope: ngc-stg + resource: + ngc: + name: "NGC Private Registry" + hostname: "http://localhost-ngc:9094" + call-timeout: PT60S + read-timeout: PT30S + write-timeout: PT30S + connection-timeout: PT60S + oauth2: + base-url: "http://localhost:9095" + group-scope: ngc-stg diff --git a/src/control-plane-services/cloud-tasks/nvct-service/src/test/resources/bootstrap-test.yaml b/src/control-plane-services/cloud-tasks/nvct-service/src/test/resources/bootstrap-test.yaml new file mode 100644 index 000000000..2b2422d3e --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-service/src/test/resources/bootstrap-test.yaml @@ -0,0 +1,21 @@ +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +# +# 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. +spring: + application: + env: test + +nv-boot: + reloadable-properties: + file: local_env/vault/secrets.json diff --git a/src/control-plane-services/cloud-tasks/pom.xml b/src/control-plane-services/cloud-tasks/pom.xml new file mode 100644 index 000000000..786f3e49e --- /dev/null +++ b/src/control-plane-services/cloud-tasks/pom.xml @@ -0,0 +1,107 @@ + + + + 4.0.0 + + + com.nvidia.boot + nv-boot-parent + 2.0.1 + + + + com.nvidia.nvct + cloud-tasks + 0.0.1-SNAPSHOT + pom + + NVCT API + NVIDIA Cloud Tasks — aggregator for core library and modules. + + + + + nvcf + https://urm.nvidia.com/artifactory/sw-nvcf-maven + + + + + ${project.basedir} + 2.0.1 + + + + + + com.nvidia.boot + nv-boot-bom + ${nv-boot.version} + pom + import + + + + + + nvct-core + nvct-service + + + + + + org.apache.maven.plugins + maven-surefire-plugin + + + + 120 + ${root.dir} + + + + org.jacoco + jacoco-maven-plugin + + + com/nvidia/nvct/proto/** + + + + + + + + + org.codehaus.mojo + license-maven-plugin + + + + test + + ^com\.nvidia\.(nvct|boot) + + + + + diff --git a/src/control-plane-services/cloud-tasks/tools/bazel/BUILD.bazel b/src/control-plane-services/cloud-tasks/tools/bazel/BUILD.bazel new file mode 100644 index 000000000..144f56d8a --- /dev/null +++ b/src/control-plane-services/cloud-tasks/tools/bazel/BUILD.bazel @@ -0,0 +1,40 @@ +load("@rules_java//java:defs.bzl", "java_binary", "java_library", "java_plugin") +load("@rules_proto_grpc//:defs.bzl", "proto_plugin") + +package(default_visibility = ["//visibility:public"]) + +exports_files([ + "jacoco_test_runner.sh", + "notice_metadata.json", +]) + +proto_plugin( + name = "grpc_java_1_63_plugin", + out = "{name}_grpc.jar", + tool = select({ + "@rules_proto_grpc//platforms:darwin_arm64": "@grpc_java_plugin_osx_aarch_64//file:protoc-gen-grpc-java.exe", + "@rules_proto_grpc//platforms:darwin_x86_64": "@grpc_java_plugin_osx_x86_64//file:protoc-gen-grpc-java.exe", + "@rules_proto_grpc//platforms:linux_aarch64": "@grpc_java_plugin_linux_aarch_64//file:protoc-gen-grpc-java.exe", + "@rules_proto_grpc//platforms:linux_x86_64": "@grpc_java_plugin_linux_x86_64//file:protoc-gen-grpc-java.exe", + "@rules_proto_grpc//platforms:windows_x86_64": "@grpc_java_plugin_windows_x86_64//file:protoc-gen-grpc-java.exe", + }), +) + +java_plugin( + name = "lombok_plugin", + generates_api = True, + processor_class = "lombok.launch.AnnotationProcessorHider$AnnotationProcessor", + deps = ["@nv_third_party_deps//:org_projectlombok_lombok"], +) + +java_binary( + name = "jacoco_cli", + main_class = "org.jacoco.cli.internal.Main", + runtime_deps = ["@nv_third_party_deps//:org_jacoco_org_jacoco_cli"], +) + +java_library( + name = "lombok_annotations", + exports = ["@nv_third_party_deps//:org_projectlombok_lombok"], + neverlink = True, +) diff --git a/src/control-plane-services/cloud-tasks/tools/bazel/jacoco_test_runner.sh b/src/control-plane-services/cloud-tasks/tools/bazel/jacoco_test_runner.sh new file mode 100755 index 000000000..7033aeebb --- /dev/null +++ b/src/control-plane-services/cloud-tasks/tools/bazel/jacoco_test_runner.sh @@ -0,0 +1,77 @@ +#!/usr/bin/env bash +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +set -euo pipefail + +if [ "$#" -lt 5 ]; then + echo "Usage: $0 <jacoco-cli> [junit-args...]" >&2 + exit 2 +fi + +absolute_path() { + case "$1" in + /*) printf '%s\n' "$1" ;; + *) printf '%s/%s\n' "${PWD}" "$1" ;; + esac +} + +junit_runner="$(absolute_path "$1")" +classfiles="$(absolute_path "$2")" +source_root="$3" +report_title="$4" +jacoco_cli="$(absolute_path "$5")" +shift 5 + +report_dir="${TEST_UNDECLARED_OUTPUTS_DIR:?TEST_UNDECLARED_OUTPUTS_DIR is required}" +junit_report_dir="${report_dir}/junit" +junit_xml="${junit_report_dir}/TEST-junit-jupiter.xml" +exec_file="${PWD}/jacoco.exec" +sourcefiles="" +if [ -n "${source_root}" ]; then + sourcefiles="${TEST_SRCDIR:?TEST_SRCDIR is required}/${TEST_WORKSPACE:?TEST_WORKSPACE is required}/${source_root}" +fi + +mkdir -p "${report_dir}" "${junit_report_dir}" +rm -f "${exec_file}" + +set +e +"${junit_runner}" "$@" --reports-dir="${junit_report_dir}" +junit_status=$? +set -e + +report_status=0 +if [ ! -s "${junit_xml}" ]; then + echo "ERROR: JUnit did not create ${junit_xml}" >&2 + report_status=1 +fi + +if [ ! -s "${exec_file}" ]; then + echo "ERROR: JaCoCo did not create ${exec_file}" >&2 + report_status=1 +else + cp "${exec_file}" "${report_dir}/jacoco.exec" + report_args=( + report "${report_dir}/jacoco.exec" + --classfiles "${classfiles}" + --html "${report_dir}" + --xml "${report_dir}/jacoco.xml" + --name "${report_title}" + ) + if [ -n "${sourcefiles}" ]; then + report_args+=(--sourcefiles "${sourcefiles}") + fi + + set +e + "${jacoco_cli}" "${report_args[@]}" + jacoco_status=$? + set -e + if [ "${jacoco_status}" -ne 0 ]; then + report_status="${jacoco_status}" + fi +fi + +if [ "${junit_status}" -ne 0 ]; then + exit "${junit_status}" +fi +exit "${report_status}" diff --git a/src/control-plane-services/cloud-tasks/tools/bazel/notice_metadata.json b/src/control-plane-services/cloud-tasks/tools/bazel/notice_metadata.json new file mode 100644 index 000000000..6901a7e48 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/tools/bazel/notice_metadata.json @@ -0,0 +1,1878 @@ +{ + "artifacts": { + "at.yawk.lz4:lz4-java:1.10.3": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "LZ4 Java Compression", + "url": "https://github.com/yawkat/lz4-java" + }, + "ch.qos.logback:logback-classic:1.5.34": { + "licenses": [ + "EPL-2.0", + "LGPL-2.1-only" + ], + "name": "Logback Classic Module", + "url": "http://logback.qos.ch" + }, + "ch.qos.logback:logback-core:1.5.34": { + "licenses": [ + "EPL-2.0", + "LGPL-2.1-only" + ], + "name": "Logback Core Module", + "url": "http://logback.qos.ch" + }, + "com.bucket4j:bucket4j-core:8.10.1": { + "licenses": [ + "The Apache Software License, Version 2.0" + ], + "name": "bucket4j-core", + "url": "http://github.com/bucket4j/bucket4j/bucket4j-core" + }, + "com.bucket4j:bucket4j_jdk17-core:8.19.0": { + "licenses": [ + "The Apache Software License, Version 2.0" + ], + "name": "bucket4j_jdk17-core", + "url": "http://github.com/bucket4j/bucket4j/bucket4j_jdk17-core" + }, + "com.datastax.oss:native-protocol:1.5.2": { + "licenses": [ + "Apache 2" + ], + "name": "An implementation of the Apache Cassandra\u00ae native protocol", + "url": "https://github.com/datastax/native-protocol" + }, + "com.fasterxml.jackson.core:jackson-annotations:2.21": { + "licenses": [ + "The Apache Software License, Version 2.0" + ], + "name": "Jackson-annotations", + "url": "https://github.com/FasterXML/jackson" + }, + "com.fasterxml.jackson.core:jackson-core:2.21.4": { + "licenses": [ + "The Apache Software License, Version 2.0" + ], + "name": "Jackson-core", + "url": "https://github.com/FasterXML/jackson-core" + }, + "com.fasterxml.jackson.core:jackson-databind:2.21.4": { + "licenses": [ + "The Apache Software License, Version 2.0" + ], + "name": "jackson-databind", + "url": "https://github.com/FasterXML/jackson" + }, + "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.21.4": { + "licenses": [ + "The Apache Software License, Version 2.0" + ], + "name": "Jackson-dataformat-YAML", + "url": "https://github.com/FasterXML/jackson-dataformats-text" + }, + "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.21.4": { + "licenses": [ + "The Apache Software License, Version 2.0" + ], + "name": "Jackson datatype: JSR310", + "url": "https://github.com/FasterXML/jackson-modules-java8" + }, + "com.fasterxml:classmate:1.7.3": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "ClassMate", + "url": "https://github.com/FasterXML/java-classmate" + }, + "com.github.ben-manes.caffeine:caffeine:3.2.4": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "Caffeine cache", + "url": "https://github.com/ben-manes/caffeine" + }, + "com.github.ben-manes.caffeine:guava:3.2.4": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "Caffeine cache", + "url": "https://github.com/ben-manes/caffeine" + }, + "com.github.java-json-tools:btf:1.3": { + "licenses": [ + "Lesser General Public License, version 3 or greater", + "Apache Software License, version 2.0" + ], + "name": "btf", + "url": "https://github.com/java-json-tools/btf" + }, + "com.github.java-json-tools:jackson-coreutils:2.0": { + "licenses": [ + "Lesser General Public License, version 3 or greater", + "Apache Software License, version 2.0" + ], + "name": "jackson-coreutils", + "url": "https://github.com/java-json-tools/jackson-coreutils" + }, + "com.github.java-json-tools:json-patch:1.13": { + "licenses": [ + "Lesser General Public License, version 3 or greater", + "Apache Software License, version 2.0" + ], + "name": "json-patch", + "url": "https://github.com/java-json-tools/json-patch" + }, + "com.github.java-json-tools:msg-simple:1.2": { + "licenses": [ + "Lesser General Public License, version 3 or greater", + "Apache Software License, version 2.0" + ], + "name": "msg-simple", + "url": "https://github.com/java-json-tools/msg-simple" + }, + "com.github.jnr:jffi:1.2.16": { + "licenses": [ + "The Apache Software License, Version 2.0" + ], + "name": "jffi", + "url": "http://github.com/jnr/jffi" + }, + "com.github.jnr:jnr-constants:0.10.3": { + "licenses": [ + "The Apache Software License, Version 2.0" + ], + "name": "jnr-constants", + "url": "http://github.com/jnr/jnr-constants" + }, + "com.github.jnr:jnr-ffi:2.1.7": { + "licenses": [ + "The Apache Software License, Version 2.0" + ], + "name": "jnr-ffi", + "url": "http://github.com/jnr/jnr-ffi" + }, + "com.github.jnr:jnr-posix:3.1.15": { + "licenses": [ + "Eclipse Public License - v 2.0", + "GNU General Public License Version 2", + "GNU Lesser General Public License Version 2.1" + ], + "name": "jnr-posix", + "url": "http://nexus.sonatype.org/oss-repository-hosting.html" + }, + "com.github.jnr:jnr-x86asm:1.0.2": { + "licenses": [ + "MIT License" + ], + "name": "jnr-x86asm", + "url": "http://github.com/jnr/jnr-x86asm" + }, + "com.github.stephenc.jcip:jcip-annotations:1.0-1": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "JCIP Annotations under Apache License", + "url": "http://stephenc.github.com/jcip-annotations" + }, + "com.google.android:annotations:4.1.1.4": { + "licenses": [ + "Apache 2.0" + ], + "name": "Google Android Annotations Library", + "url": "http://source.android.com/" + }, + "com.google.api.grpc:proto-google-common-protos:2.29.0": { + "licenses": [ + "Apache-2.0" + ], + "name": "proto-google-common-protos", + "url": "https://github.com/googleapis/sdk-platform-java" + }, + "com.google.api.grpc:proto-google-common-protos:2.51.0": { + "licenses": [ + "Apache-2.0" + ], + "name": "proto-google-common-protos", + "url": "https://github.com/googleapis/sdk-platform-java" + }, + "com.google.code.findbugs:jsr305:3.0.2": { + "licenses": [ + "The Apache Software License, Version 2.0" + ], + "name": "FindBugs-jsr305", + "url": "http://findbugs.sourceforge.net/" + }, + "com.google.code.gson:gson:2.13.2": { + "licenses": [ + "Apache-2.0" + ], + "name": "Gson", + "url": "https://github.com/google/gson" + }, + "com.google.errorprone:error_prone_annotations:2.49.0": { + "licenses": [ + "Apache 2.0" + ], + "name": "error-prone annotations", + "url": "https://errorprone.info" + }, + "com.google.guava:failureaccess:1.0.3": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "Guava InternalFutureFailureAccess and InternalFutures", + "url": "https://github.com/google/guava" + }, + "com.google.guava:guava:33.6.0-jre": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "Guava: Google Core Libraries for Java", + "url": "https://github.com/google/guava" + }, + "com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava": { + "licenses": [ + "The Apache Software License, Version 2.0" + ], + "name": "Guava ListenableFuture only", + "url": "https://github.com/google/guava" + }, + "com.google.j2objc:j2objc-annotations:3.1": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "J2ObjC Annotations", + "url": "https://github.com/google/j2objc/" + }, + "com.google.protobuf:protobuf-java-util:4.33.4": { + "licenses": [ + "BSD-3-Clause" + ], + "name": "Protocol Buffers [Util]", + "url": "https://developers.google.com/protocol-buffers/" + }, + "com.google.protobuf:protobuf-java:4.33.4": { + "licenses": [ + "BSD-3-Clause" + ], + "name": "Protocol Buffers [Core]", + "url": "https://developers.google.com/protocol-buffers/" + }, + "com.nimbusds:content-type:2.3": { + "licenses": [ + "The Apache Software License, Version 2.0" + ], + "name": "Nimbus Content Type", + "url": "https://bitbucket.org/connect2id/nimbus-content-type" + }, + "com.nimbusds:lang-tag:1.7": { + "licenses": [ + "The Apache Software License, Version 2.0" + ], + "name": "Nimbus LangTag", + "url": "https://bitbucket.org/connect2id/nimbus-language-tags" + }, + "com.nimbusds:nimbus-jose-jwt:10.4": { + "licenses": [ + "The Apache Software License, Version 2.0" + ], + "name": "Nimbus JOSE+JWT", + "url": "https://bitbucket.org/connect2id/nimbus-jose-jwt" + }, + "com.nimbusds:oauth2-oidc-sdk:11.26.1": { + "licenses": [ + "Apache License, version 2.0" + ], + "name": "OAuth 2.0 SDK with OpenID Connect extensions", + "url": "https://bitbucket.org/connect2id/oauth-2.0-sdk-with-openid-connect-extensions" + }, + "com.squareup.okhttp3:logging-interceptor:4.12.0": { + "licenses": [ + "The Apache Software License, Version 2.0" + ], + "name": "okhttp-logging-interceptor", + "url": "https://square.github.io/okhttp/" + }, + "com.squareup.okhttp3:okhttp:4.12.0": { + "licenses": [ + "The Apache Software License, Version 2.0" + ], + "name": "okhttp", + "url": "https://square.github.io/okhttp/" + }, + "com.squareup.okio:okio-jvm:3.16.1": { + "licenses": [ + "The Apache Software License, Version 2.0" + ], + "name": "okio", + "url": "https://github.com/square/okio/" + }, + "com.squareup.okio:okio:3.6.0": { + "licenses": [ + "The Apache Software License, Version 2.0" + ], + "name": "okio", + "url": "https://github.com/square/okio/" + }, + "com.typesafe:config:1.4.1": { + "licenses": [ + "Apache-2.0" + ], + "name": "config", + "url": "https://github.com/lightbend/config" + }, + "commons-codec:commons-codec:1.19.0": { + "licenses": [ + "Apache-2.0" + ], + "name": "Apache Commons Codec", + "url": "https://commons.apache.org/proper/commons-codec/" + }, + "commons-io:commons-io:2.20.0": { + "licenses": [ + "Apache-2.0" + ], + "name": "Apache Commons IO", + "url": "https://commons.apache.org/proper/commons-io/" + }, + "commons-logging:commons-logging:1.3.6": { + "licenses": [ + "Apache-2.0" + ], + "name": "Apache Commons Logging", + "url": "https://commons.apache.org/proper/commons-logging/" + }, + "io.dropwizard.metrics:metrics-core:4.1.18": { + "licenses": [ + "Apache License 2.0" + ], + "name": "Metrics Core", + "url": "https://metrics.dropwizard.io" + }, + "io.grpc:grpc-api:1.63.0": { + "licenses": [ + "Apache 2.0" + ], + "name": "io.grpc:grpc-api", + "url": "https://github.com/grpc/grpc-java" + }, + "io.grpc:grpc-api:1.74.0": { + "licenses": [ + "Apache 2.0" + ], + "name": "io.grpc:grpc-api", + "url": "https://github.com/grpc/grpc-java" + }, + "io.grpc:grpc-context:1.63.0": { + "licenses": [ + "Apache 2.0" + ], + "name": "io.grpc:grpc-context", + "url": "https://github.com/grpc/grpc-java" + }, + "io.grpc:grpc-core:1.63.0": { + "licenses": [ + "Apache 2.0" + ], + "name": "io.grpc:grpc-core", + "url": "https://github.com/grpc/grpc-java" + }, + "io.grpc:grpc-inprocess:1.63.0": { + "licenses": [ + "Apache 2.0" + ], + "name": "io.grpc:grpc-inprocess", + "url": "https://github.com/grpc/grpc-java" + }, + "io.grpc:grpc-netty-shaded:1.63.0": { + "licenses": [ + "Apache 2.0" + ], + "name": "io.grpc:grpc-netty-shaded", + "url": "https://github.com/grpc/grpc-java" + }, + "io.grpc:grpc-protobuf-lite:1.63.0": { + "licenses": [ + "Apache 2.0" + ], + "name": "io.grpc:grpc-protobuf-lite", + "url": "https://github.com/grpc/grpc-java" + }, + "io.grpc:grpc-protobuf-lite:1.74.0": { + "licenses": [ + "Apache 2.0" + ], + "name": "io.grpc:grpc-protobuf-lite", + "url": "https://github.com/grpc/grpc-java" + }, + "io.grpc:grpc-protobuf:1.63.0": { + "licenses": [ + "Apache 2.0" + ], + "name": "io.grpc:grpc-protobuf", + "url": "https://github.com/grpc/grpc-java" + }, + "io.grpc:grpc-protobuf:1.74.0": { + "licenses": [ + "Apache 2.0" + ], + "name": "io.grpc:grpc-protobuf", + "url": "https://github.com/grpc/grpc-java" + }, + "io.grpc:grpc-services:1.63.0": { + "licenses": [ + "Apache 2.0" + ], + "name": "io.grpc:grpc-services", + "url": "https://github.com/grpc/grpc-java" + }, + "io.grpc:grpc-stub:1.63.0": { + "licenses": [ + "Apache 2.0" + ], + "name": "io.grpc:grpc-stub", + "url": "https://github.com/grpc/grpc-java" + }, + "io.grpc:grpc-stub:1.74.0": { + "licenses": [ + "Apache 2.0" + ], + "name": "io.grpc:grpc-stub", + "url": "https://github.com/grpc/grpc-java" + }, + "io.grpc:grpc-util:1.63.0": { + "licenses": [ + "Apache 2.0" + ], + "name": "io.grpc:grpc-util", + "url": "https://github.com/grpc/grpc-java" + }, + "io.gsonfire:gson-fire:1.9.0": { + "licenses": [ + "Apache-2.0" + ], + "name": "Gson on Fire!", + "url": "http://gsonfire.io" + }, + "io.kubernetes:client-java-api-fluent:24.0.0": { + "licenses": [ + "The Apache Software License, Version 2.0" + ], + "name": "client-java-fluent", + "url": "https://github.com/kubernetes-client/java" + }, + "io.kubernetes:client-java-api:24.0.0": { + "licenses": [ + "The Apache Software License, Version 2.0" + ], + "name": "client-java-api", + "url": "https://github.com/kubernetes-client/java" + }, + "io.kubernetes:client-java-extended:24.0.0": { + "licenses": [ + "The Apache Software License, Version 2.0" + ], + "name": "client-java-extended", + "url": "https://github.com/kubernetes-client/java" + }, + "io.kubernetes:client-java-proto:24.0.0": { + "licenses": [ + "The Apache Software License, Version 2.0" + ], + "name": "client-java-proto", + "url": "https://github.com/kubernetes-client/java" + }, + "io.kubernetes:client-java:24.0.0": { + "licenses": [ + "The Apache Software License, Version 2.0" + ], + "name": "client-java", + "url": "https://github.com/kubernetes-client/java" + }, + "io.micrometer:context-propagation:1.2.1": { + "licenses": [ + "The Apache Software License, Version 2.0" + ], + "name": "context-propagation", + "url": "https://github.com/micrometer-metrics/context-propagation" + }, + "io.micrometer:micrometer-commons:1.16.6": { + "licenses": [ + "The Apache Software License, Version 2.0" + ], + "name": "micrometer-commons", + "url": "https://github.com/micrometer-metrics/micrometer" + }, + "io.micrometer:micrometer-core:1.16.6": { + "licenses": [ + "The Apache Software License, Version 2.0" + ], + "name": "micrometer-core", + "url": "https://github.com/micrometer-metrics/micrometer" + }, + "io.micrometer:micrometer-jakarta9:1.16.6": { + "licenses": [ + "The Apache Software License, Version 2.0" + ], + "name": "micrometer-jakarta9", + "url": "https://github.com/micrometer-metrics/micrometer" + }, + "io.micrometer:micrometer-observation:1.16.6": { + "licenses": [ + "The Apache Software License, Version 2.0" + ], + "name": "micrometer-observation", + "url": "https://github.com/micrometer-metrics/micrometer" + }, + "io.micrometer:micrometer-registry-prometheus:1.16.6": { + "licenses": [ + "The Apache Software License, Version 2.0" + ], + "name": "micrometer-registry-prometheus", + "url": "https://github.com/micrometer-metrics/micrometer" + }, + "io.micrometer:micrometer-tracing-bridge-otel:1.6.6": { + "licenses": [ + "The Apache Software License, Version 2.0" + ], + "name": "micrometer-tracing-bridge-otel", + "url": "https://github.com/micrometer-metrics/tracing" + }, + "io.micrometer:micrometer-tracing:1.6.6": { + "licenses": [ + "The Apache Software License, Version 2.0" + ], + "name": "micrometer-tracing", + "url": "https://github.com/micrometer-metrics/tracing" + }, + "io.netty:netty-buffer:4.2.15.Final": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "Netty/Buffer", + "url": "https://netty.io/" + }, + "io.netty:netty-codec-base:4.2.15.Final": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "Netty/Codec/Base", + "url": "https://netty.io/" + }, + "io.netty:netty-codec-classes-quic:4.2.15.Final": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "Netty/Codec/Classes/Quic", + "url": "https://netty.io/" + }, + "io.netty:netty-codec-compression:4.2.15.Final": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "Netty/Codec/Compression", + "url": "https://netty.io/" + }, + "io.netty:netty-codec-dns:4.2.15.Final": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "Netty/Codec/DNS", + "url": "https://netty.io/" + }, + "io.netty:netty-codec-http2:4.2.15.Final": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "Netty/Codec/HTTP2", + "url": "https://netty.io/" + }, + "io.netty:netty-codec-http3:4.2.15.Final": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "Netty/Codec/Http3", + "url": "https://netty.io/netty-codec-http3/" + }, + "io.netty:netty-codec-http:4.2.15.Final": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "Netty/Codec/HTTP", + "url": "https://netty.io/" + }, + "io.netty:netty-codec-native-quic:4.2.15.Final": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "Netty/Codec/Native/Quic", + "url": "https://netty.io/" + }, + "io.netty:netty-codec-socks:4.2.15.Final": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "Netty/Codec/Socks", + "url": "https://netty.io/" + }, + "io.netty:netty-common:4.2.15.Final": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "Netty/Common", + "url": "https://netty.io/" + }, + "io.netty:netty-handler-proxy:4.2.15.Final": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "Netty/Handler/Proxy", + "url": "https://netty.io/" + }, + "io.netty:netty-handler:4.2.15.Final": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "Netty/Handler", + "url": "https://netty.io/" + }, + "io.netty:netty-resolver-dns-classes-macos:4.2.15.Final": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "Netty/Resolver/DNS/Classes/MacOS", + "url": "https://netty.io/" + }, + "io.netty:netty-resolver-dns-native-macos:4.2.15.Final": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "Netty/Resolver/DNS/Native/MacOS", + "url": "https://netty.io/" + }, + "io.netty:netty-resolver-dns:4.2.15.Final": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "Netty/Resolver/DNS", + "url": "https://netty.io/" + }, + "io.netty:netty-resolver:4.2.15.Final": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "Netty/Resolver", + "url": "https://netty.io/" + }, + "io.netty:netty-transport-classes-epoll:4.2.15.Final": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "Netty/Transport/Classes/Epoll", + "url": "https://netty.io/" + }, + "io.netty:netty-transport-native-epoll:4.2.15.Final": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "Netty/Transport/Native/Epoll", + "url": "https://netty.io/" + }, + "io.netty:netty-transport-native-unix-common:4.2.15.Final": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "Netty/Transport/Native/Unix/Common", + "url": "https://netty.io/" + }, + "io.netty:netty-transport:4.2.15.Final": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "Netty/Transport", + "url": "https://netty.io/" + }, + "io.opentelemetry.semconv:opentelemetry-semconv:1.37.0": { + "licenses": [ + "The Apache License, Version 2.0" + ], + "name": "OpenTelemetry Semantic Conventions Java", + "url": "https://github.com/open-telemetry/semantic-conventions-java" + }, + "io.opentelemetry:opentelemetry-api:1.55.0": { + "licenses": [ + "The Apache License, Version 2.0" + ], + "name": "OpenTelemetry Java", + "url": "https://github.com/open-telemetry/opentelemetry-java" + }, + "io.opentelemetry:opentelemetry-common:1.55.0": { + "licenses": [ + "The Apache License, Version 2.0" + ], + "name": "OpenTelemetry Java", + "url": "https://github.com/open-telemetry/opentelemetry-java" + }, + "io.opentelemetry:opentelemetry-context:1.55.0": { + "licenses": [ + "The Apache License, Version 2.0" + ], + "name": "OpenTelemetry Java", + "url": "https://github.com/open-telemetry/opentelemetry-java" + }, + "io.opentelemetry:opentelemetry-extension-trace-propagators:1.55.0": { + "licenses": [ + "The Apache License, Version 2.0" + ], + "name": "OpenTelemetry Java", + "url": "https://github.com/open-telemetry/opentelemetry-java" + }, + "io.opentelemetry:opentelemetry-sdk-common:1.55.0": { + "licenses": [ + "The Apache License, Version 2.0" + ], + "name": "OpenTelemetry Java", + "url": "https://github.com/open-telemetry/opentelemetry-java" + }, + "io.opentelemetry:opentelemetry-sdk-logs:1.55.0": { + "licenses": [ + "The Apache License, Version 2.0" + ], + "name": "OpenTelemetry Java", + "url": "https://github.com/open-telemetry/opentelemetry-java" + }, + "io.opentelemetry:opentelemetry-sdk-metrics:1.55.0": { + "licenses": [ + "The Apache License, Version 2.0" + ], + "name": "OpenTelemetry Java", + "url": "https://github.com/open-telemetry/opentelemetry-java" + }, + "io.opentelemetry:opentelemetry-sdk-trace:1.55.0": { + "licenses": [ + "The Apache License, Version 2.0" + ], + "name": "OpenTelemetry Java", + "url": "https://github.com/open-telemetry/opentelemetry-java" + }, + "io.opentelemetry:opentelemetry-sdk:1.55.0": { + "licenses": [ + "The Apache License, Version 2.0" + ], + "name": "OpenTelemetry Java", + "url": "https://github.com/open-telemetry/opentelemetry-java" + }, + "io.perfmark:perfmark-api:0.26.0": { + "licenses": [ + "Apache 2.0" + ], + "name": "perfmark:perfmark-api", + "url": "https://github.com/perfmark/perfmark" + }, + "io.projectreactor.netty:reactor-netty-core:1.3.6": { + "licenses": [ + "The Apache Software License, Version 2.0" + ], + "name": "Core functionality for the Reactor Netty library", + "url": "https://github.com/reactor/reactor-netty" + }, + "io.projectreactor.netty:reactor-netty-http:1.3.6": { + "licenses": [ + "The Apache Software License, Version 2.0" + ], + "name": "HTTP functionality for the Reactor Netty library", + "url": "https://github.com/reactor/reactor-netty" + }, + "io.projectreactor:reactor-core:3.8.6": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "Non-Blocking Reactive Foundation for the JVM", + "url": "https://github.com/reactor/reactor-core" + }, + "io.prometheus:prometheus-metrics-config:1.4.3": { + "licenses": [ + "The Apache Software License, Version 2.0" + ], + "name": "Prometheus Metrics Config", + "url": "http://github.com/prometheus/client_java" + }, + "io.prometheus:prometheus-metrics-core:1.4.3": { + "licenses": [ + "The Apache Software License, Version 2.0" + ], + "name": "Prometheus Metrics Core", + "url": "http://github.com/prometheus/client_java" + }, + "io.prometheus:prometheus-metrics-exposition-formats:1.4.3": { + "licenses": [ + "The Apache Software License, Version 2.0" + ], + "name": "Prometheus Metrics Exposition Formats", + "url": "http://github.com/prometheus/client_java" + }, + "io.prometheus:prometheus-metrics-exposition-textformats:1.4.3": { + "licenses": [ + "The Apache Software License, Version 2.0" + ], + "name": "Prometheus Metrics Exposition Text Formats", + "url": "http://github.com/prometheus/client_java" + }, + "io.prometheus:prometheus-metrics-model:1.4.3": { + "licenses": [ + "The Apache Software License, Version 2.0" + ], + "name": "Prometheus Metrics Model", + "url": "http://github.com/prometheus/client_java" + }, + "io.prometheus:prometheus-metrics-tracer-common:1.4.3": { + "licenses": [ + "The Apache Software License, Version 2.0" + ], + "name": "Prometheus Metrics Tracer Common", + "url": "http://github.com/prometheus/client_java" + }, + "io.swagger.core.v3:swagger-annotations-jakarta:2.2.47": { + "licenses": [ + "Apache License 2.0" + ], + "name": "swagger-annotations-jakarta", + "url": "https://github.com/swagger-api/swagger-core" + }, + "io.swagger.core.v3:swagger-core-jakarta:2.2.47": { + "licenses": [ + "Apache License 2.0" + ], + "name": "swagger-core-jakarta", + "url": "https://github.com/swagger-api/swagger-core" + }, + "io.swagger.core.v3:swagger-models-jakarta:2.2.47": { + "licenses": [ + "Apache License 2.0" + ], + "name": "swagger-models-jakarta", + "url": "https://github.com/swagger-api/swagger-core" + }, + "io.swagger:swagger-annotations:1.6.16": { + "licenses": [ + "Apache License 2.0" + ], + "name": "swagger-annotations", + "url": "https://github.com/swagger-api/swagger-core" + }, + "jakarta.activation:jakarta.activation-api:2.1.4": { + "licenses": [ + "EDL 1.0" + ], + "name": "Jakarta Activation API", + "url": "https://github.com/jakartaee/jaf-api" + }, + "jakarta.annotation:jakarta.annotation-api:3.0.0": { + "licenses": [ + "EPL 2.0", + "GPL2 w/ CPE" + ], + "name": "Jakarta Annotations API", + "url": "https://projects.eclipse.org/projects/ee4j.ca" + }, + "jakarta.servlet:jakarta.servlet-api:6.1.0": { + "licenses": [ + "EPL 2.0", + "GPL2 w/ CPE" + ], + "name": "Jakarta Servlet", + "url": "https://projects.eclipse.org/projects/ee4j.servlet" + }, + "jakarta.validation:jakarta.validation-api:3.1.1": { + "licenses": [ + "Apache License 2.0" + ], + "name": "Jakarta Validation API", + "url": "https://beanvalidation.org" + }, + "jakarta.xml.bind:jakarta.xml.bind-api:4.0.5": { + "licenses": [ + "Eclipse Distribution License - v 1.0" + ], + "name": "Jakarta XML Binding API", + "url": "https://github.com/jakartaee/jaxb-api" + }, + "javax.annotation:javax.annotation-api:1.3.2": { + "licenses": [ + "CDDL + GPLv2 with classpath exception" + ], + "name": "javax.annotation API", + "url": "http://jcp.org/en/jsr/detail?id=250" + }, + "net.devh:grpc-common-spring-boot:3.1.0.RELEASE": { + "licenses": [ + "Apache 2.0" + ], + "name": "gRPC Spring Boot Starter", + "url": "https://github.com/yidongnan/grpc-spring-boot-starter" + }, + "net.devh:grpc-server-spring-boot-starter:3.1.0.RELEASE": { + "licenses": [ + "Apache 2.0" + ], + "name": "gRPC Spring Boot Starter", + "url": "https://github.com/yidongnan/grpc-spring-boot-starter" + }, + "net.javacrumbs.shedlock:shedlock-core:7.7.0": { + "licenses": [ + "The Apache Software License, Version 2.0" + ], + "name": "net.javacrumbs.shedlock:shedlock-core", + "url": "http://nexus.sonatype.org/oss-repository-hosting.html" + }, + "net.javacrumbs.shedlock:shedlock-provider-cassandra:7.7.0": { + "licenses": [ + "The Apache Software License, Version 2.0" + ], + "name": "net.javacrumbs.shedlock:shedlock-provider-cassandra", + "url": "http://nexus.sonatype.org/oss-repository-hosting.html" + }, + "net.javacrumbs.shedlock:shedlock-spring:7.7.0": { + "licenses": [ + "The Apache Software License, Version 2.0" + ], + "name": "net.javacrumbs.shedlock:shedlock-spring", + "url": "http://nexus.sonatype.org/oss-repository-hosting.html" + }, + "net.minidev:accessors-smart:2.6.0": { + "licenses": [ + "The Apache Software License, Version 2.0" + ], + "name": "ASM based accessors helper used by json-smart", + "url": "https://urielch.github.io/" + }, + "net.minidev:json-smart:2.6.0": { + "licenses": [ + "The Apache Software License, Version 2.0" + ], + "name": "JSON Small and Fast Parser", + "url": "https://urielch.github.io/" + }, + "org.apache.cassandra:java-driver-core:4.19.3": { + "licenses": [ + "Apache 2" + ], + "name": "Apache Cassandra Java Driver - core", + "url": "https://github.com/datastax/java-driver" + }, + "org.apache.cassandra:java-driver-guava-shaded:4.19.3": { + "licenses": [ + "Apache 2" + ], + "name": "Apache Cassandra Java Driver - guava shaded dep", + "url": "https://github.com/datastax/java-driver" + }, + "org.apache.cassandra:java-driver-metrics-micrometer:4.19.3": { + "licenses": [ + "Apache 2" + ], + "name": "Apache Cassandra Java Driver - Metrics - Micrometer", + "url": "https://github.com/datastax/java-driver" + }, + "org.apache.cassandra:java-driver-query-builder:4.19.3": { + "licenses": [ + "Apache 2" + ], + "name": "Apache Cassandra Java Driver - query builder", + "url": "https://github.com/datastax/java-driver" + }, + "org.apache.commons:commons-collections4:4.5.0": { + "licenses": [ + "Apache-2.0" + ], + "name": "Apache Commons Collections", + "url": "https://commons.apache.org/proper/commons-collections/" + }, + "org.apache.commons:commons-compress:1.28.0": { + "licenses": [ + "Apache-2.0" + ], + "name": "Apache Commons Compress", + "url": "https://commons.apache.org/proper/commons-compress/" + }, + "org.apache.commons:commons-lang3:3.20.0": { + "licenses": [ + "Apache-2.0" + ], + "name": "Apache Commons Lang", + "url": "https://commons.apache.org/proper/commons-lang/" + }, + "org.apache.logging.log4j:log4j-api:2.25.4": { + "licenses": [ + "Apache-2.0" + ], + "name": "Apache Log4j API", + "url": "https://logging.apache.org/log4j/2.x/" + }, + "org.apache.logging.log4j:log4j-to-slf4j:2.25.4": { + "licenses": [ + "Apache-2.0" + ], + "name": "Log4j API to SLF4J Adapter", + "url": "https://logging.apache.org/log4j/2.x/" + }, + "org.apache.tomcat.embed:tomcat-embed-core:11.0.22": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "tomcat-embed-core", + "url": "https://tomcat.apache.org/" + }, + "org.apache.tomcat.embed:tomcat-embed-el:11.0.22": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "tomcat-embed-el", + "url": "https://tomcat.apache.org/" + }, + "org.apache.tomcat.embed:tomcat-embed-websocket:11.0.22": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "tomcat-embed-websocket", + "url": "https://tomcat.apache.org/" + }, + "org.aspectj:aspectjweaver:1.9.25.1": { + "licenses": [ + "Eclipse Public License - v 2.0" + ], + "name": "AspectJ Weaver", + "url": "https://www.eclipse.org/aspectj/" + }, + "org.bitbucket.b_c:jose4j:0.9.6": { + "licenses": [ + "The Apache Software License, Version 2.0" + ], + "name": "jose4j", + "url": "https://bitbucket.org/b_c/jose4j/" + }, + "org.bouncycastle:bcpkix-jdk18on:1.80": { + "licenses": [ + "Bouncy Castle Licence" + ], + "name": "Bouncy Castle PKIX, CMS, EAC, TSP, PKCS, OCSP, CMP, and CRMF APIs", + "url": "https://www.bouncycastle.org/download/bouncy-castle-java/" + }, + "org.bouncycastle:bcprov-jdk18on:1.84": { + "licenses": [ + "Bouncy Castle Licence" + ], + "name": "Bouncy Castle Provider", + "url": "https://www.bouncycastle.org/download/bouncy-castle-java/" + }, + "org.bouncycastle:bcutil-jdk18on:1.80.2": { + "licenses": [ + "Bouncy Castle Licence" + ], + "name": "Bouncy Castle ASN.1 Extension and Utility APIs", + "url": "https://www.bouncycastle.org/download/bouncy-castle-java/" + }, + "org.codehaus.mojo:animal-sniffer-annotations:1.23": { + "licenses": [ + "MIT license" + ], + "name": "Animal Sniffer Annotations", + "url": "https://www.mojohaus.org/animal-sniffer" + }, + "org.codehaus.mojo:animal-sniffer-annotations:1.24": { + "licenses": [ + "MIT license" + ], + "name": "Animal Sniffer Annotations", + "url": "https://www.mojohaus.org/animal-sniffer" + }, + "org.hdrhistogram:HdrHistogram:2.2.2": { + "licenses": [ + "Public Domain, per Creative Commons CC0", + "BSD-2-Clause" + ], + "name": "HdrHistogram", + "url": "http://hdrhistogram.github.io/HdrHistogram/" + }, + "org.hibernate.validator:hibernate-validator:9.0.1.Final": { + "licenses": [ + "Apache License 2.0" + ], + "name": "Hibernate Validator Engine", + "url": "https://hibernate.org/validator" + }, + "org.jboss.logging:jboss-logging:3.6.3.Final": { + "licenses": [ + "Apache License 2.0" + ], + "name": "JBoss Logging 3", + "url": "https://www.jboss.org" + }, + "org.jetbrains.kotlin:kotlin-stdlib-jdk7:2.2.21": { + "licenses": [ + "Apache-2.0" + ], + "name": "Kotlin Stdlib Jdk7", + "url": "https://kotlinlang.org/" + }, + "org.jetbrains.kotlin:kotlin-stdlib-jdk8:2.2.21": { + "licenses": [ + "Apache-2.0" + ], + "name": "Kotlin Stdlib Jdk8", + "url": "https://kotlinlang.org/" + }, + "org.jetbrains.kotlin:kotlin-stdlib:2.2.21": { + "licenses": [ + "Apache-2.0" + ], + "name": "Kotlin Stdlib", + "url": "https://kotlinlang.org/" + }, + "org.jetbrains:annotations:17.0.0": { + "licenses": [ + "The Apache Software License, Version 2.0" + ], + "name": "JetBrains Java Annotations", + "url": "https://github.com/JetBrains/java-annotations" + }, + "org.jspecify:jspecify:1.0.0": { + "licenses": [ + "The Apache License, Version 2.0" + ], + "name": "JSpecify annotations", + "url": "http://jspecify.org/" + }, + "org.latencyutils:LatencyUtils:2.0.3": { + "licenses": [ + "Public Domain, per Creative Commons CC0" + ], + "name": "LatencyUtils", + "url": "http://latencyutils.github.io/LatencyUtils/" + }, + "org.ow2.asm:asm-analysis:9.9": { + "licenses": [ + "BSD-3-Clause" + ], + "name": "asm-analysis", + "url": "http://asm.ow2.io/" + }, + "org.ow2.asm:asm-commons:9.9": { + "licenses": [ + "BSD-3-Clause" + ], + "name": "asm-commons", + "url": "http://asm.ow2.io/" + }, + "org.ow2.asm:asm-tree:9.9": { + "licenses": [ + "BSD-3-Clause" + ], + "name": "asm-tree", + "url": "http://asm.ow2.io/" + }, + "org.ow2.asm:asm-util:9.9": { + "licenses": [ + "BSD-3-Clause" + ], + "name": "asm-util", + "url": "http://asm.ow2.io/" + }, + "org.ow2.asm:asm:9.9": { + "licenses": [ + "BSD-3-Clause" + ], + "name": "asm", + "url": "http://asm.ow2.io/" + }, + "org.reactivestreams:reactive-streams:1.0.4": { + "licenses": [ + "MIT-0" + ], + "name": "reactive-streams", + "url": "http://www.reactive-streams.org/" + }, + "org.slf4j:jul-to-slf4j:2.0.18": { + "licenses": [ + "MIT" + ], + "name": "JUL to SLF4J bridge", + "url": "http://www.slf4j.org" + }, + "org.slf4j:slf4j-api:2.0.18": { + "licenses": [ + "MIT" + ], + "name": "SLF4J API Module", + "url": "http://www.slf4j.org" + }, + "org.springdoc:springdoc-openapi-starter-common:3.0.3": { + "licenses": [ + "The Apache License, Version 2.0" + ], + "name": "springdoc-openapi-starter-common", + "url": "https://springdoc.org/" + }, + "org.springdoc:springdoc-openapi-starter-webflux-api:3.0.3": { + "licenses": [ + "The Apache License, Version 2.0" + ], + "name": "springdoc-openapi-starter-webflux-api", + "url": "https://springdoc.org/" + }, + "org.springdoc:springdoc-openapi-starter-webmvc-api:3.0.3": { + "licenses": [ + "The Apache License, Version 2.0" + ], + "name": "springdoc-openapi-starter-webmvc-api", + "url": "https://springdoc.org/" + }, + "org.springframework.boot:spring-boot-actuator-autoconfigure:4.0.7": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "spring-boot-actuator-autoconfigure", + "url": "https://spring.io/projects/spring-boot" + }, + "org.springframework.boot:spring-boot-actuator:4.0.7": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "spring-boot-actuator", + "url": "https://spring.io/projects/spring-boot" + }, + "org.springframework.boot:spring-boot-autoconfigure:4.0.7": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "spring-boot-autoconfigure", + "url": "https://spring.io/projects/spring-boot" + }, + "org.springframework.boot:spring-boot-cassandra:4.0.7": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "spring-boot-cassandra", + "url": "https://spring.io/projects/spring-boot" + }, + "org.springframework.boot:spring-boot-data-cassandra:4.0.7": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "spring-boot-data-cassandra", + "url": "https://spring.io/projects/spring-boot" + }, + "org.springframework.boot:spring-boot-data-commons:4.0.7": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "spring-boot-data-commons", + "url": "https://spring.io/projects/spring-boot" + }, + "org.springframework.boot:spring-boot-health:4.0.7": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "spring-boot-health", + "url": "https://spring.io/projects/spring-boot" + }, + "org.springframework.boot:spring-boot-http-client:4.0.7": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "spring-boot-http-client", + "url": "https://spring.io/projects/spring-boot" + }, + "org.springframework.boot:spring-boot-http-codec:4.0.7": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "spring-boot-http-codec", + "url": "https://spring.io/projects/spring-boot" + }, + "org.springframework.boot:spring-boot-http-converter:4.0.7": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "spring-boot-http-converter", + "url": "https://spring.io/projects/spring-boot" + }, + "org.springframework.boot:spring-boot-jackson:4.0.7": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "spring-boot-jackson", + "url": "https://spring.io/projects/spring-boot" + }, + "org.springframework.boot:spring-boot-micrometer-metrics:4.0.7": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "spring-boot-micrometer-metrics", + "url": "https://spring.io/projects/spring-boot" + }, + "org.springframework.boot:spring-boot-micrometer-observation:4.0.7": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "spring-boot-micrometer-observation", + "url": "https://spring.io/projects/spring-boot" + }, + "org.springframework.boot:spring-boot-micrometer-tracing-opentelemetry:4.0.7": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "spring-boot-micrometer-tracing-opentelemetry", + "url": "https://spring.io/projects/spring-boot" + }, + "org.springframework.boot:spring-boot-micrometer-tracing:4.0.7": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "spring-boot-micrometer-tracing", + "url": "https://spring.io/projects/spring-boot" + }, + "org.springframework.boot:spring-boot-opentelemetry:4.0.7": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "spring-boot-opentelemetry", + "url": "https://spring.io/projects/spring-boot" + }, + "org.springframework.boot:spring-boot-persistence:4.0.7": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "spring-boot-persistence", + "url": "https://spring.io/projects/spring-boot" + }, + "org.springframework.boot:spring-boot-security-oauth2-client:4.0.7": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "spring-boot-security-oauth2-client", + "url": "https://spring.io/projects/spring-boot" + }, + "org.springframework.boot:spring-boot-security-oauth2-resource-server:4.0.7": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "spring-boot-security-oauth2-resource-server", + "url": "https://spring.io/projects/spring-boot" + }, + "org.springframework.boot:spring-boot-security:4.0.7": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "spring-boot-security", + "url": "https://spring.io/projects/spring-boot" + }, + "org.springframework.boot:spring-boot-servlet:4.0.7": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "spring-boot-servlet", + "url": "https://spring.io/projects/spring-boot" + }, + "org.springframework.boot:spring-boot-starter-actuator:4.0.7": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "spring-boot-starter-actuator", + "url": "https://spring.io/projects/spring-boot" + }, + "org.springframework.boot:spring-boot-starter-aspectj:4.0.7": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "spring-boot-starter-aspectj", + "url": "https://spring.io/projects/spring-boot" + }, + "org.springframework.boot:spring-boot-starter-data-cassandra:4.0.7": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "spring-boot-starter-data-cassandra", + "url": "https://spring.io/projects/spring-boot" + }, + "org.springframework.boot:spring-boot-starter-jackson:4.0.7": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "spring-boot-starter-jackson", + "url": "https://spring.io/projects/spring-boot" + }, + "org.springframework.boot:spring-boot-starter-logging:4.0.7": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "spring-boot-starter-logging", + "url": "https://spring.io/projects/spring-boot" + }, + "org.springframework.boot:spring-boot-starter-micrometer-metrics:4.0.7": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "spring-boot-starter-micrometer-metrics", + "url": "https://spring.io/projects/spring-boot" + }, + "org.springframework.boot:spring-boot-starter-security-oauth2-client:4.0.7": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "spring-boot-starter-security-oauth2-client", + "url": "https://spring.io/projects/spring-boot" + }, + "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server:4.0.7": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "spring-boot-starter-security-oauth2-resource-server", + "url": "https://spring.io/projects/spring-boot" + }, + "org.springframework.boot:spring-boot-starter-security:4.0.7": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "spring-boot-starter-security", + "url": "https://spring.io/projects/spring-boot" + }, + "org.springframework.boot:spring-boot-starter-tomcat-runtime:4.0.7": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "spring-boot-starter-tomcat-runtime", + "url": "https://spring.io/projects/spring-boot" + }, + "org.springframework.boot:spring-boot-starter-tomcat:4.0.7": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "spring-boot-starter-tomcat", + "url": "https://spring.io/projects/spring-boot" + }, + "org.springframework.boot:spring-boot-starter-validation:4.0.7": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "spring-boot-starter-validation", + "url": "https://spring.io/projects/spring-boot" + }, + "org.springframework.boot:spring-boot-starter-webmvc:4.0.7": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "spring-boot-starter-webmvc", + "url": "https://spring.io/projects/spring-boot" + }, + "org.springframework.boot:spring-boot-starter:4.0.7": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "spring-boot-starter", + "url": "https://spring.io/projects/spring-boot" + }, + "org.springframework.boot:spring-boot-tomcat:4.0.7": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "spring-boot-tomcat", + "url": "https://spring.io/projects/spring-boot" + }, + "org.springframework.boot:spring-boot-validation:4.0.7": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "spring-boot-validation", + "url": "https://spring.io/projects/spring-boot" + }, + "org.springframework.boot:spring-boot-web-server:4.0.7": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "spring-boot-web-server", + "url": "https://spring.io/projects/spring-boot" + }, + "org.springframework.boot:spring-boot-webclient:4.0.7": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "spring-boot-webclient", + "url": "https://spring.io/projects/spring-boot" + }, + "org.springframework.boot:spring-boot-webflux:4.0.7": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "spring-boot-webflux", + "url": "https://spring.io/projects/spring-boot" + }, + "org.springframework.boot:spring-boot-webmvc:4.0.7": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "spring-boot-webmvc", + "url": "https://spring.io/projects/spring-boot" + }, + "org.springframework.boot:spring-boot:4.0.7": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "spring-boot", + "url": "https://spring.io/projects/spring-boot" + }, + "org.springframework.cloud:spring-cloud-commons:5.0.2": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "Spring Cloud Commons", + "url": "https://projects.spring.io/spring-cloud/spring-cloud-commons/" + }, + "org.springframework.cloud:spring-cloud-context:5.0.2": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "Spring Cloud Context", + "url": "https://projects.spring.io/spring-cloud/spring-cloud-context/" + }, + "org.springframework.cloud:spring-cloud-kubernetes-client-autoconfig:5.0.2": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "spring-cloud-kubernetes-client-autoconfig", + "url": "https://cloud.spring.io/spring-cloud-kubernetes-client-autoconfig" + }, + "org.springframework.cloud:spring-cloud-kubernetes-client-config:5.0.2": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "spring-cloud-kubernetes-client-config", + "url": "https://cloud.spring.io/spring-cloud-kubernetes-client-config" + }, + "org.springframework.cloud:spring-cloud-kubernetes-commons:5.0.2": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "spring-cloud-kubernetes-commons", + "url": "https://cloud.spring.io/spring-cloud-kubernetes-commons" + }, + "org.springframework.cloud:spring-cloud-starter-bootstrap:5.0.2": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "spring-cloud-starter-bootstrap", + "url": "https://projects.spring.io/spring-cloud" + }, + "org.springframework.cloud:spring-cloud-starter-kubernetes-client-config:5.0.2": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "Spring Cloud Kubernetes :: Kubernetes Native Starter :: Config", + "url": "https://cloud.spring.io/spring-cloud-starter-kubernetes-client-config" + }, + "org.springframework.cloud:spring-cloud-starter:5.0.2": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "spring-cloud-starter", + "url": "https://projects.spring.io/spring-cloud" + }, + "org.springframework.data:spring-data-cassandra:5.0.6": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "Spring Data for Apache Cassandra Core", + "url": "https://projects.spring.io/spring-data-cassandra/" + }, + "org.springframework.data:spring-data-commons:4.0.6": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "Spring Data Core", + "url": "https://spring.io/projects/spring-data" + }, + "org.springframework.retry:spring-retry:2.0.13": { + "licenses": [ + "Apache 2.0" + ], + "name": "Spring Retry", + "url": "https://github.com/spring-projects/spring-retry" + }, + "org.springframework.security:spring-security-config:7.0.6": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "spring-security-config", + "url": "https://spring.io/projects/spring-security" + }, + "org.springframework.security:spring-security-core:7.0.6": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "spring-security-core", + "url": "https://spring.io/projects/spring-security" + }, + "org.springframework.security:spring-security-crypto:7.0.6": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "spring-security-crypto", + "url": "https://spring.io/projects/spring-security" + }, + "org.springframework.security:spring-security-oauth2-client:7.0.6": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "spring-security-oauth2-client", + "url": "https://spring.io/projects/spring-security" + }, + "org.springframework.security:spring-security-oauth2-core:7.0.6": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "spring-security-oauth2-core", + "url": "https://spring.io/projects/spring-security" + }, + "org.springframework.security:spring-security-oauth2-jose:7.0.6": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "spring-security-oauth2-jose", + "url": "https://spring.io/projects/spring-security" + }, + "org.springframework.security:spring-security-oauth2-resource-server:7.0.6": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "spring-security-oauth2-resource-server", + "url": "https://spring.io/projects/spring-security" + }, + "org.springframework.security:spring-security-web:7.0.6": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "spring-security-web", + "url": "https://spring.io/projects/spring-security" + }, + "org.springframework:spring-aop:7.0.8": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "Spring AOP", + "url": "https://github.com/spring-projects/spring-framework" + }, + "org.springframework:spring-beans:7.0.8": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "Spring Beans", + "url": "https://github.com/spring-projects/spring-framework" + }, + "org.springframework:spring-context-support:7.0.8": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "Spring Context Support", + "url": "https://github.com/spring-projects/spring-framework" + }, + "org.springframework:spring-context:7.0.8": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "Spring Context", + "url": "https://github.com/spring-projects/spring-framework" + }, + "org.springframework:spring-core:7.0.8": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "Spring Core", + "url": "https://github.com/spring-projects/spring-framework" + }, + "org.springframework:spring-expression:7.0.8": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "Spring Expression Language (SpEL)", + "url": "https://github.com/spring-projects/spring-framework" + }, + "org.springframework:spring-tx:7.0.8": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "Spring Transaction", + "url": "https://github.com/spring-projects/spring-framework" + }, + "org.springframework:spring-web:7.0.8": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "Spring Web", + "url": "https://github.com/spring-projects/spring-framework" + }, + "org.springframework:spring-webflux:7.0.8": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "Spring WebFlux", + "url": "https://github.com/spring-projects/spring-framework" + }, + "org.springframework:spring-webmvc:7.0.8": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "Spring Web MVC", + "url": "https://github.com/spring-projects/spring-framework" + }, + "org.yaml:snakeyaml:2.5": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "SnakeYAML", + "url": "https://bitbucket.org/snakeyaml/snakeyaml" + }, + "software.amazon.awssdk:annotations:2.40.1": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "AWS Java SDK :: Annotations", + "url": "https://aws.amazon.com/sdkforjava" + }, + "software.amazon.awssdk:checksums-spi:2.40.1": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "AWS Java SDK :: Checksums SPI", + "url": "https://aws.amazon.com/sdkforjava" + }, + "software.amazon.awssdk:checksums:2.40.1": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "AWS Java SDK :: Checksums", + "url": "https://aws.amazon.com/sdkforjava" + }, + "software.amazon.awssdk:endpoints-spi:2.40.1": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "AWS Java SDK :: Endpoints SPI", + "url": "https://aws.amazon.com/sdkforjava" + }, + "software.amazon.awssdk:http-auth-aws:2.40.1": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "AWS Java SDK :: HTTP Auth AWS", + "url": "https://aws.amazon.com/sdkforjava" + }, + "software.amazon.awssdk:http-auth-spi:2.40.1": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "AWS Java SDK :: HTTP Auth SPI", + "url": "https://aws.amazon.com/sdkforjava" + }, + "software.amazon.awssdk:http-client-spi:2.40.1": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "AWS Java SDK :: HTTP Client Interface", + "url": "https://aws.amazon.com/sdkforjava" + }, + "software.amazon.awssdk:identity-spi:2.40.1": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "AWS Java SDK :: Identity SPI", + "url": "https://aws.amazon.com/sdkforjava" + }, + "software.amazon.awssdk:json-utils:2.40.1": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "AWS Java SDK :: Core :: Protocols :: Json Utils", + "url": "https://aws.amazon.com/sdkforjava" + }, + "software.amazon.awssdk:metrics-spi:2.40.1": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "AWS Java SDK :: Metrics SPI", + "url": "https://aws.amazon.com/sdkforjava" + }, + "software.amazon.awssdk:profiles:2.40.1": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "AWS Java SDK :: Profiles", + "url": "https://aws.amazon.com/sdkforjava" + }, + "software.amazon.awssdk:regions:2.40.1": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "AWS Java SDK :: Regions", + "url": "https://aws.amazon.com/sdkforjava" + }, + "software.amazon.awssdk:retries-spi:2.40.1": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "AWS Java SDK :: Retries API", + "url": "https://aws.amazon.com/sdkforjava" + }, + "software.amazon.awssdk:retries:2.40.1": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "AWS Java SDK :: Retries", + "url": "https://aws.amazon.com/sdkforjava" + }, + "software.amazon.awssdk:sdk-core:2.40.1": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "AWS Java SDK :: SDK Core", + "url": "https://aws.amazon.com/sdkforjava" + }, + "software.amazon.awssdk:third-party-jackson-core:2.40.1": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "AWS Java SDK :: Third Party :: Jackson-core", + "url": "https://aws.amazon.com/sdkforjava" + }, + "software.amazon.awssdk:utils:2.40.1": { + "licenses": [ + "Apache License, Version 2.0" + ], + "name": "AWS Java SDK :: Utilities", + "url": "https://aws.amazon.com/sdkforjava" + }, + "tools.jackson.core:jackson-core:3.1.4": { + "licenses": [ + "The Apache Software License, Version 2.0" + ], + "name": "Jackson-core", + "url": "https://github.com/FasterXML/jackson-core" + }, + "tools.jackson.core:jackson-databind:3.1.4": { + "licenses": [ + "The Apache Software License, Version 2.0" + ], + "name": "jackson-databind", + "url": "https://github.com/FasterXML/jackson" + }, + "tools.jackson.module:jackson-module-blackbird:3.1.4": { + "licenses": [ + "The Apache Software License, Version 2.0" + ], + "name": "Jackson module: Blackbird", + "url": "https://github.com/FasterXML/jackson-modules-base" + } + }, + "generated_by": "tools/bazel/generate_notice.py --update-metadata" +} diff --git a/src/control-plane-services/cloud-tasks/tools/bazel/proto.bzl b/src/control-plane-services/cloud-tasks/tools/bazel/proto.bzl new file mode 100644 index 000000000..1e3c83dc1 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/tools/bazel/proto.bzl @@ -0,0 +1,27 @@ +"""Project protobuf rules whose generator versions match the application runtime.""" + +load( + "@rules_proto_grpc//:defs.bzl", + "ProtoPluginInfo", + "proto_compile_attrs", + "proto_compile_impl", + "proto_compile_toolchains", +) + +# rules_proto_grpc_java does not expose its bundled gRPC plugin as an attribute. +# Keep its proven compile implementation while replacing only that private tool. +nvct_java_grpc_compile = rule( + implementation = proto_compile_impl, + attrs = dict( + proto_compile_attrs, + _plugins = attr.label_list( + providers = [ProtoPluginInfo], + default = [ + Label("@rules_proto_grpc_java//:proto_plugin"), + Label("//src/control-plane-services/cloud-tasks/tools/bazel:grpc_java_1_63_plugin"), + ], + cfg = "exec", + ), + ), + toolchains = proto_compile_toolchains, +) diff --git a/src/control-plane-services/cloud-tasks/tools/bazel/runfiles.bzl b/src/control-plane-services/cloud-tasks/tools/bazel/runfiles.bzl new file mode 100644 index 000000000..71499bc16 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/tools/bazel/runfiles.bzl @@ -0,0 +1,26 @@ +"""Workspace-relative runfiles helper for cloud-tasks integration tests.""" + +def _nvct_workspace_runfiles_impl(ctx): + symlinks = {} + strip_prefix = ctx.attr.strip_prefix + + for src in ctx.files.srcs: + runfiles_path = src.short_path + if strip_prefix: + if not runfiles_path.startswith(strip_prefix): + fail("Expected %s to start with strip_prefix %s" % (runfiles_path, strip_prefix)) + runfiles_path = runfiles_path[len(strip_prefix):] + + if runfiles_path in symlinks: + fail("Duplicate runfiles path: %s" % runfiles_path) + symlinks[runfiles_path] = src + + return [DefaultInfo(runfiles = ctx.runfiles(symlinks = symlinks))] + +nvct_workspace_runfiles = rule( + implementation = _nvct_workspace_runfiles_impl, + attrs = { + "srcs": attr.label_list(allow_files = True), + "strip_prefix": attr.string(), + }, +) diff --git a/src/control-plane-services/cloud-tasks/tools/bazel/workspace_status.sh b/src/control-plane-services/cloud-tasks/tools/bazel/workspace_status.sh new file mode 100755 index 000000000..fe655c43e --- /dev/null +++ b/src/control-plane-services/cloud-tasks/tools/bazel/workspace_status.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash +set -eu + +if git rev-parse --is-inside-work-tree >/dev/null 2>&1; then + full_commit="$(git rev-parse HEAD)" + abbrev_commit="$(git rev-parse --short=7 HEAD)" + tags="$(git tag --points-at HEAD | paste -sd, -)" + closest_tag="$(git describe --tags --abbrev=0 2>/dev/null || true)" +else + full_commit="unknown" + abbrev_commit="unknown" + tags="" + closest_tag="" +fi + +printf 'STABLE_GIT_COMMIT_ID_FULL %s\n' "${full_commit}" +printf 'STABLE_GIT_COMMIT_ID_ABBREV %s\n' "${abbrev_commit}" +printf 'STABLE_GIT_TAGS %s\n' "${tags}" +printf 'STABLE_GIT_CLOSEST_TAG_NAME %s\n' "${closest_tag}" +printf 'STABLE_BUILD_VERSION %s\n' "${NEXT_VERSION:-0.0.1-SNAPSHOT}" From 04e75eb9b41fda7c95d181c70ef0af20e828f3de Mon Sep 17 00:00:00 2001 From: Balaji Ganesan <bganesan@nvidia.com> Date: Wed, 22 Jul 2026 07:23:48 -0700 Subject: [PATCH 04/29] chore(cloud-tasks): drop internal Maven server ref from the public pom The pom.xml <repositories> block pointed at urm.nvidia.com (internal Artifactory) only to resolve the nv-boot parent for a Maven build. The monorepo builds cloud-tasks with Bazel and resolves nv-boot from in-tree source targets, so the Bazel/CI build never touches urm (0 urm URLs in the re-pinned maven_install.json). Remove the internal-server reference so the public GitHub tree does not advertise it; zero build impact. Co-authored-by: Balaji Ganesan <bganesan@nvidia.com> Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --- src/control-plane-services/cloud-tasks/pom.xml | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/control-plane-services/cloud-tasks/pom.xml b/src/control-plane-services/cloud-tasks/pom.xml index 786f3e49e..62047b81f 100644 --- a/src/control-plane-services/cloud-tasks/pom.xml +++ b/src/control-plane-services/cloud-tasks/pom.xml @@ -36,13 +36,12 @@ <name>NVCT API</name> <description>NVIDIA Cloud Tasks — aggregator for core library and modules.</description> - <repositories> - <!-- Resolve parent from here --> - <repository> - <id>nvcf</id> - <url>https://urm.nvidia.com/artifactory/sw-nvcf-maven</url> - </repository> - </repositories> + <!-- + This POM is kept for Maven parity only. In the monorepo the service is + built with Bazel (//rules/java) and its nv-boot parent/BOM resolve from + the in-tree source targets under //src/libraries/java/nv-boot-parent, not + from a Maven repository, so no internal artifact server is referenced here. + --> <properties> <root.dir>${project.basedir}</root.dir> From b5307211988ba0715fee193ef8e1b9f7e6486218 Mon Sep 17 00:00:00 2001 From: Balaji Ganesan <bganesan@nvidia.com> Date: Wed, 22 Jul 2026 09:02:29 -0700 Subject: [PATCH 05/29] fix(cloud-tasks): exclude docker integration tests from CI + index NOTICE Two root-row CI failures from landing cloud-tasks: - nvct-core:tests / nvct-service:tests are Testcontainers/Cassandra integration tests; the root row runs bazel test //... with no tag filter, so they ran on GHA (no Docker) and failed. Tag them "manual" so //... skips them; test sources still compile via :nvct_core_test_fixtures, and they stay runnable on demand in a Docker-capable environment. - Regenerate the root NOTICE (tools/scripts/update-license) to index the new src/control-plane-services/cloud-tasks/NOTICE. Co-authored-by: Balaji Ganesan <bganesan@nvidia.com> Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --- NOTICE | 1 + .../cloud-tasks/nvct-core/BUILD.bazel | 6 ++++++ .../cloud-tasks/nvct-service/BUILD.bazel | 4 ++++ 3 files changed, 11 insertions(+) diff --git a/NOTICE b/NOTICE index d332b19a7..d48fa2ce4 100644 --- a/NOTICE +++ b/NOTICE @@ -306,6 +306,7 @@ The following third-party licenses are included in this repository: src/compute-plane-services/nvca/vendor/sigs.k8s.io/structured-merge-diff/v6/LICENSE src/compute-plane-services/nvca/vendor/sigs.k8s.io/yaml/LICENSE src/compute-plane-services/nvsnap/NOTICE + src/control-plane-services/cloud-tasks/NOTICE src/invocation-plane-services/llm-api-gateway/NOTICE src/invocation-plane-services/ratelimiter/NOTICE src/libraries/go/lib/vendor/cloud.google.com/go/compute/metadata/LICENSE diff --git a/src/control-plane-services/cloud-tasks/nvct-core/BUILD.bazel b/src/control-plane-services/cloud-tasks/nvct-core/BUILD.bazel index 8d65b9b1a..fd3fbb7d4 100644 --- a/src/control-plane-services/cloud-tasks/nvct-core/BUILD.bazel +++ b/src/control-plane-services/cloud-tasks/nvct-core/BUILD.bazel @@ -249,6 +249,12 @@ java_junit5_test( "//src/control-plane-services/cloud-tasks:integration_local_env", ], tags = [ + # Testcontainers/Cassandra integration test: needs a Docker daemon the + # GHA runners do not have. "manual" drops it from the root row's + # `bazel test //...`; the test sources still compile via + # :nvct_core_test_fixtures, and the suite is runnable on demand in a + # Docker-capable environment. + "manual", "exclusive", "requires-docker", ], diff --git a/src/control-plane-services/cloud-tasks/nvct-service/BUILD.bazel b/src/control-plane-services/cloud-tasks/nvct-service/BUILD.bazel index 69c4b81f1..d668ab6c1 100644 --- a/src/control-plane-services/cloud-tasks/nvct-service/BUILD.bazel +++ b/src/control-plane-services/cloud-tasks/nvct-service/BUILD.bazel @@ -69,6 +69,10 @@ java_junit5_test( "//src/control-plane-services/cloud-tasks:integration_local_env", ], tags = [ + # Full Spring context + Testcontainers integration test: needs a Docker + # daemon the GHA runners lack. "manual" drops it from the root row's + # `bazel test //...`; runnable on demand in a Docker-capable environment. + "manual", "exclusive", "requires-docker", ], From 0a9c9bc440f51f0c44206b2bedf12a024f93a1d2 Mon Sep 17 00:00:00 2001 From: Balaji Ganesan <bganesan@nvidia.com> Date: Wed, 22 Jul 2026 09:25:10 -0700 Subject: [PATCH 06/29] ci(bazel): run integration tests in a DinD lane instead of skipping them Testcontainers integration suites cannot run in the containerized bazel matrix (no Docker daemon), and skipping them is not acceptable. Add a dedicated bazel-integration lane that ports the proven GitLab recipe: a docker:dind service, the test process pointed at it via DOCKER_HOST, and Testcontainers told to reach spawned containers at the "docker" alias. - bazel-integration job: runs //... --test_tag_filters=requires-docker with the DinD service; exit 4 (no matching tests) is treated as success. - Fast matrix: excludes requires-docker (--test_tag_filters=-requires-docker); those tests still compile in the build step. - cloud-tasks nvct-core/nvct-service integration tests drop the interim "manual" tag and keep "requires-docker" so the lane runs them. cloud-tasks is the pilot; other services' skips (external / tests_skip) get removed as their suites are verified green in this lane. - bazel-verification gates on the lane's result. Co-authored-by: Balaji Ganesan <bganesan@nvidia.com> Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --- .github/workflows/bazel.yml | 68 ++++++++++++++++++- .../cloud-tasks/nvct-core/BUILD.bazel | 11 ++- .../cloud-tasks/nvct-service/BUILD.bazel | 7 +- 3 files changed, 74 insertions(+), 12 deletions(-) diff --git a/.github/workflows/bazel.yml b/.github/workflows/bazel.yml index 9d9dccedf..79b13356d 100644 --- a/.github/workflows/bazel.yml +++ b/.github/workflows/bazel.yml @@ -457,7 +457,11 @@ jobs: grep -E '^[[:space:]]*-//' "$qfile" | sed -E 's/^[[:space:]]+//' >> "$ttfile" echo "quarantine: subtracted ${n:-0} pattern(s) from the root test set" fi - COMMON=(--flaky_test_attempts=3) + # requires-docker tests (Testcontainers/DinD) run in the dedicated + # bazel-integration lane, not here; this matrix has no Docker daemon. + # They still compile in the build step; only their execution is + # deferred to that lane (see the bazel-integration job). + COMMON=(--flaky_test_attempts=3 --test_tag_filters=-requires-docker) CACHE=(--remote_cache=) if [ "${CACHE_READY:-0}" = "1" ]; then CACHE=(--remote_cache="$CACHE_ENDPOINT" @@ -488,9 +492,62 @@ jobs: bazel test "${COMMON[@]}" --remote_cache= "${TARGETS[@]}" fi + # Docker (DinD) integration lane. Runs only the "requires-docker"-tagged + # tests (Testcontainers suites) that the fast matrix cannot run because it has + # no Docker daemon. This is how integration tests stay ENABLED instead of + # being skipped. Ports the proven GitLab recipe: a docker:dind service, the + # test process pointed at it via DOCKER_HOST, and Testcontainers told to reach + # spawned containers at the "docker" alias rather than localhost. + bazel-integration: + name: bazel integration (docker) + needs: detect + if: needs.detect.outputs.any == 'true' + runs-on: ubuntu-latest + env: + DOCKER_HOST: tcp://docker:2375 + DOCKER_TLS_CERTDIR: "" + TESTCONTAINERS_HOST_OVERRIDE: docker + TESTCONTAINERS_RYUK_DISABLED: "true" + container: + image: ghcr.io/nvidia/nvcf/bazel-ci:0.12.0 + credentials: + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + services: + docker: + image: docker:27-dind + options: --privileged + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: bazel version + run: bazel version + - name: bazel integration tests (requires-docker) + run: | + # Run only the Testcontainers suites across the root workspace. If a + # change touches none, bazel exits 4 (no tests matched) which we treat + # as success. Nested-module subtrees are handled in a later fan-out. + set +e + bazel test //... \ + --build_tests_only \ + --test_tag_filters=requires-docker \ + --test_env=DOCKER_HOST \ + --test_env=TESTCONTAINERS_HOST_OVERRIDE \ + --test_env=TESTCONTAINERS_RYUK_DISABLED \ + --test_output=errors \ + --flaky_test_attempts=2 + rc=$? + set -e + if [ "$rc" -eq 4 ]; then + echo "no requires-docker tests matched; nothing to run" + exit 0 + fi + exit "$rc" + bazel-verification: name: bazel verification - needs: [detect, bazel] + needs: [detect, bazel, bazel-integration] if: ${{ always() }} runs-on: ubuntu-latest steps: @@ -498,6 +555,7 @@ jobs: env: DETECT_RESULT: ${{ needs.detect.result }} BAZEL_RESULT: ${{ needs.bazel.result }} + INTEGRATION_RESULT: ${{ needs.bazel-integration.result }} BAZEL_ANY: ${{ needs.detect.outputs.any }} run: | set -euo pipefail @@ -520,3 +578,9 @@ jobs: echo "one or more Bazel matrix rows failed, were cancelled, or were skipped" exit 1 fi + + echo "integration result: ${INTEGRATION_RESULT}" + if [ "${INTEGRATION_RESULT}" != "success" ] && [ "${INTEGRATION_RESULT}" != "skipped" ]; then + echo "the bazel integration (docker) lane failed or was cancelled" + exit 1 + fi diff --git a/src/control-plane-services/cloud-tasks/nvct-core/BUILD.bazel b/src/control-plane-services/cloud-tasks/nvct-core/BUILD.bazel index fd3fbb7d4..075240aeb 100644 --- a/src/control-plane-services/cloud-tasks/nvct-core/BUILD.bazel +++ b/src/control-plane-services/cloud-tasks/nvct-core/BUILD.bazel @@ -249,12 +249,11 @@ java_junit5_test( "//src/control-plane-services/cloud-tasks:integration_local_env", ], tags = [ - # Testcontainers/Cassandra integration test: needs a Docker daemon the - # GHA runners do not have. "manual" drops it from the root row's - # `bazel test //...`; the test sources still compile via - # :nvct_core_test_fixtures, and the suite is runnable on demand in a - # Docker-capable environment. - "manual", + # Testcontainers/Cassandra integration test. Runs in the dedicated + # Docker (DinD) integration lane, which selects targets by the + # "requires-docker" tag; the fast matrix excludes it via + # --test_tag_filters=-requires-docker. The test sources still compile in + # the build step via :nvct_core_test_fixtures. "exclusive", "requires-docker", ], diff --git a/src/control-plane-services/cloud-tasks/nvct-service/BUILD.bazel b/src/control-plane-services/cloud-tasks/nvct-service/BUILD.bazel index d668ab6c1..68f8cf568 100644 --- a/src/control-plane-services/cloud-tasks/nvct-service/BUILD.bazel +++ b/src/control-plane-services/cloud-tasks/nvct-service/BUILD.bazel @@ -69,10 +69,9 @@ java_junit5_test( "//src/control-plane-services/cloud-tasks:integration_local_env", ], tags = [ - # Full Spring context + Testcontainers integration test: needs a Docker - # daemon the GHA runners lack. "manual" drops it from the root row's - # `bazel test //...`; runnable on demand in a Docker-capable environment. - "manual", + # Full Spring context + Testcontainers integration test. Runs in the + # dedicated Docker (DinD) integration lane (selected by "requires-docker"); + # the fast matrix excludes it via --test_tag_filters=-requires-docker. "exclusive", "requires-docker", ], From db5ec4dcc4bdc61c1443a07b7e48ad61e490ef09 Mon Sep 17 00:00:00 2001 From: Balaji Ganesan <bganesan@nvidia.com> Date: Wed, 22 Jul 2026 09:31:50 -0700 Subject: [PATCH 07/29] ci(bazel): run the integration lane on the bare runner, not container+dind The container+docker:dind combination failed at actions/checkout (a known GHA rough edge with a service container attached to a containerized job). Switch the lane to the bare ubuntu-latest runner, which already has Docker running, so Testcontainers uses the host daemon directly -- no DinD service, no host-override networking, and no container+service checkout fragility. bazelisk reads .bazelversion for the pinned Bazel. Co-authored-by: Balaji Ganesan <bganesan@nvidia.com> Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --- .github/workflows/bazel.yml | 46 +++++++++++++++---------------------- 1 file changed, 18 insertions(+), 28 deletions(-) diff --git a/.github/workflows/bazel.yml b/.github/workflows/bazel.yml index 79b13356d..5450f77bf 100644 --- a/.github/workflows/bazel.yml +++ b/.github/workflows/bazel.yml @@ -492,49 +492,39 @@ jobs: bazel test "${COMMON[@]}" --remote_cache= "${TARGETS[@]}" fi - # Docker (DinD) integration lane. Runs only the "requires-docker"-tagged - # tests (Testcontainers suites) that the fast matrix cannot run because it has - # no Docker daemon. This is how integration tests stay ENABLED instead of - # being skipped. Ports the proven GitLab recipe: a docker:dind service, the - # test process pointed at it via DOCKER_HOST, and Testcontainers told to reach - # spawned containers at the "docker" alias rather than localhost. + # Docker integration lane. Runs only the "requires-docker"-tagged tests + # (Testcontainers suites) that the containerized fast matrix cannot run + # because it has no Docker daemon. This is how integration tests stay ENABLED + # instead of being skipped. Runs on the bare runner (not the bazel-ci + # container) because ubuntu-latest ships Docker running, so Testcontainers + # uses the host daemon directly -- no DinD, no host-override networking, and it + # avoids the container+service checkout fragility. bazelisk reads + # .bazelversion for the pinned Bazel. bazel-integration: name: bazel integration (docker) needs: detect if: needs.detect.outputs.any == 'true' runs-on: ubuntu-latest - env: - DOCKER_HOST: tcp://docker:2375 - DOCKER_TLS_CERTDIR: "" - TESTCONTAINERS_HOST_OVERRIDE: docker - TESTCONTAINERS_RYUK_DISABLED: "true" - container: - image: ghcr.io/nvidia/nvcf/bazel-ci:0.12.0 - credentials: - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - services: - docker: - image: docker:27-dind - options: --privileged steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - - name: bazel version - run: bazel version + - name: Install bazelisk + run: | + sudo curl -fsSLo /usr/local/bin/bazel \ + https://github.com/bazelbuild/bazelisk/releases/download/v1.20.0/bazelisk-linux-amd64 + sudo chmod +x /usr/local/bin/bazel + bazel version - name: bazel integration tests (requires-docker) run: | - # Run only the Testcontainers suites across the root workspace. If a - # change touches none, bazel exits 4 (no tests matched) which we treat - # as success. Nested-module subtrees are handled in a later fan-out. + # Run only the Testcontainers suites across the root workspace against + # the host Docker. If a change touches none, bazel exits 4 (no tests + # matched) which we treat as success. Nested-module subtrees are + # handled in a later fan-out. set +e bazel test //... \ --build_tests_only \ --test_tag_filters=requires-docker \ - --test_env=DOCKER_HOST \ - --test_env=TESTCONTAINERS_HOST_OVERRIDE \ - --test_env=TESTCONTAINERS_RYUK_DISABLED \ --test_output=errors \ --flaky_test_attempts=2 rc=$? From 39ad99a25269913c06db2e7bcc20e3c0b083def4 Mon Sep 17 00:00:00 2001 From: Balaji Ganesan <bganesan@nvidia.com> Date: Wed, 22 Jul 2026 10:39:33 -0700 Subject: [PATCH 08/29] fix(cloud-tasks): materialize compose assets so the Cassandra schema applies The integration tests failed under Bazel with InvalidKeyspaceException: keyspace nvct never got created. Root cause: Bazel test runfiles present local_env/** as symlinks into the build sandbox. The compose bind-mount ./cassandra/schema -> /docker-entrypoint-initdb.d then mounts a directory of dangling symlinks (their targets do not exist inside the Cassandra container), so entrypoint.sh finds no *.cql (log shows 'executing cql scripts' immediately followed by 'init scripts executed' with nothing in between) and the keyspace is never applied. Fix: the two filesystem resolution paths now copy the bundle into a directory of real files (dereferencing symlinks), the same way the JAR/Maven path already does via extractLocalEnvFromJar. The bind mounts then serve real content. No behavior change on a plain checkout (files are already real). Co-authored-by: Balaji Ganesan <bganesan@nvidia.com> Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --- .../nvct/IntegrationTestConfiguration.java | 48 ++++++++++++++++++- 1 file changed, 46 insertions(+), 2 deletions(-) diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/IntegrationTestConfiguration.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/IntegrationTestConfiguration.java index e9d4998d5..519230357 100644 --- a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/IntegrationTestConfiguration.java +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/IntegrationTestConfiguration.java @@ -32,6 +32,7 @@ import java.net.JarURLConnection; import java.net.URISyntaxException; import java.net.URL; +import java.nio.file.FileVisitOption; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardCopyOption; @@ -166,7 +167,7 @@ private static File resolveComposeAssetDirectory() { if (fallbackCompose.isFile()) { File dir = fallbackCompose.getParentFile(); log.info("Using compose bundle from filesystem: {}", dir.getAbsolutePath()); - return dir; + return materializeComposeAssets(dir); } throw new IllegalStateException( "Missing classpath resource " @@ -182,7 +183,7 @@ private static File resolveComposeAssetDirectory() { var dir = composePath.getParent().toFile(); log.debug("Using compose bundle from filesystem (test-classes): {}", dir.getAbsolutePath()); - return dir; + return materializeComposeAssets(dir); } if ("jar".equalsIgnoreCase(composeUrl.getProtocol())) { @@ -240,6 +241,49 @@ private static File extractLocalEnvFromJar(URL composeUrlInsideJar) throws IOExc } } + /** + * Copy a filesystem compose bundle into a directory of real files, dereferencing symlinks. + * + * <p>Under Bazel the test runfiles present {@code local_env/**} as symlinks into the build + * sandbox. Docker bind-mounts of a directory follow the mount but leave those symlinks dangling + * inside the container (their targets do not exist there), so {@code ./cassandra/schema} mounts + * empty: {@code entrypoint.sh} finds no {@code *.cql}, the {@code nvct} keyspace is never + * created, and Spring fails to start with {@code InvalidKeyspaceException}. Materialising to real + * files makes the bind mounts serve actual content, the same way {@link #extractLocalEnvFromJar} + * does for the Maven/JAR path. A no-op-ish copy on a plain checkout (real files already). + */ + private static File materializeComposeAssets(File sourceDir) { + try { + var srcRoot = sourceDir.toPath(); + var extractRoot = createIntegrationExtractDirectory(); + try (var walk = Files.walk(srcRoot, FileVisitOption.FOLLOW_LINKS)) { + for (var src : (Iterable<Path>) walk::iterator) { + var dest = extractRoot.resolve(srcRoot.relativize(src).toString()); + if (Files.isDirectory(src)) { + Files.createDirectories(dest); + continue; + } + Files.createDirectories(dest.getParent()); + Files.copy(src, dest, StandardCopyOption.REPLACE_EXISTING); + if ("entrypoint.sh".equals(src.getFileName().toString())) { + try { + Files.setPosixFilePermissions(dest, + PosixFilePermissions.fromString("rwxr-xr-x")); + } catch (UnsupportedOperationException ignored) { + // Non-POSIX filesystem; Docker still runs the script via bash. + } + } + } + } + log.info("Materialized integration compose bundle from {} to {}", srcRoot, + extractRoot.toAbsolutePath()); + return extractRoot.toFile(); + } catch (IOException e) { + throw new IllegalStateException( + "Failed to materialize compose bundle from " + sourceDir, e); + } + } + /** * Creates a directory for JAR-extracted compose assets, preferring {@code target/} under the * module. Registers recursive deletion on JVM exit (unlike {@link File#deleteOnExit()} on a From 03ee72891f3d8588cad178acbf27e8220899650d Mon Sep 17 00:00:00 2001 From: Balaji Ganesan <bganesan@nvidia.com> Date: Wed, 22 Jul 2026 11:48:04 -0700 Subject: [PATCH 09/29] fix(cloud-tasks): address the two CodeQL alerts - IntegrationTestConfiguration (Zip Slip, high): the JAR-extraction path now normalizes each destination and rejects any entry that resolves outside the extraction root, so a crafted '..' entry can no longer write outside it. - SecurityConfiguration (disabled CSRF, high): this is a stateless (SessionCreationPolicy.STATELESS) OAuth2 resource server authenticated by JWT/api-key bearer tokens with no cookies or sessions, so CSRF does not apply and disabling it is the correct Spring posture. Documented the rationale and added an inline CodeQL suppression rather than re-enabling (which would break the token-only API without adding protection). Co-authored-by: Balaji Ganesan <bganesan@nvidia.com> Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --- .../nvidia/nvct/configuration/SecurityConfiguration.java | 7 ++++++- .../com/nvidia/nvct/IntegrationTestConfiguration.java | 8 +++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/SecurityConfiguration.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/SecurityConfiguration.java index cd4a509b5..055608b06 100644 --- a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/SecurityConfiguration.java +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/configuration/SecurityConfiguration.java @@ -40,7 +40,12 @@ public SecurityFilterChain filterChain( AuthenticationManagerResolver<HttpServletRequest> authenticationManagerResolver, ExceptionHandlerFilter exceptionHandlerFilter) { http - .csrf(csrf -> csrf.disable()) + // CSRF protection is intentionally disabled: this is a stateless + // (SessionCreationPolicy.STATELESS) OAuth2 resource server authenticated by + // JWT / api-key bearer tokens, with no cookies or server-side sessions. CSRF is + // a cookie/session-auth attack and does not apply here; enabling it would break + // the token-only API without adding any protection. + .csrf(csrf -> csrf.disable()) // codeql[java/spring-disabled-csrf-protection] .sessionManagement(session -> session.sessionCreationPolicy(STATELESS)) // Reuse the ValidationAwareExceptionHandler to handle the exception inside // the filters,especially for the custom authentication resolver exceptions. diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/IntegrationTestConfiguration.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/IntegrationTestConfiguration.java index 519230357..ae9b9f798 100644 --- a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/IntegrationTestConfiguration.java +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/IntegrationTestConfiguration.java @@ -218,7 +218,13 @@ private static File extractLocalEnvFromJar(URL composeUrlInsideJar) throws IOExc continue; } - var dest = extractRoot.resolve(name.substring(prefix.length())); + var dest = extractRoot.resolve(name.substring(prefix.length())).normalize(); + // Zip-slip guard: a crafted entry name (e.g. containing "..") must + // never resolve outside the extraction root. + if (!dest.startsWith(extractRoot)) { + throw new IOException( + "Refusing to extract entry outside the target directory: " + name); + } Files.createDirectories(dest.getParent()); try (var in = jarFile.getInputStream(entry)) { Files.copy(in, dest, StandardCopyOption.REPLACE_EXISTING); From 4368ee2084ea93f267d5cf5cdb2c09df1eb4f4b9 Mon Sep 17 00:00:00 2001 From: Balaji Ganesan <bganesan@nvidia.com> Date: Wed, 22 Jul 2026 20:41:43 -0700 Subject: [PATCH 10/29] fix(cloud-tasks): sync OpenAPI schema annotations from upstream 4c6f57c9 Pull the SpringDoc/OpenAPI 3.1 schema annotation fixes from the upstream nvct/cloud-tasks feat/bazel branch (4c6f57c9) so the import tracks current upstream. The DTOs declare explicit schema types (types={"object"}), implementation, additionalProperties, and requiredMode so the generated OpenAPI document is well-formed; MiscEndpointsTest asserts the affected component schemas are objects. Source-only sync: the monorepo's Bazel/OSS/CodeQL changes to SecurityConfiguration.java and IntegrationTestConfiguration.java are strictly ahead of upstream and are preserved untouched. Co-authored-by: Balaji Ganesan <bganesan@nvidia.com> --- .../nvct/rest/result/dto/ResultDto.java | 9 ++-- .../nvct/rest/task/dto/CreateTaskRequest.java | 2 +- .../rest/task/dto/GpuSpecificationDto.java | 9 ++-- .../nvidia/nvct/rest/task/dto/HealthDto.java | 2 +- .../task/dto/HelmValidationPolicyDto.java | 3 +- .../nvidia/nvct/rest/task/dto/SecretDto.java | 9 +++- .../service/telemetry/dto/TelemetriesDto.java | 2 +- .../nvct/rest/misc/MiscEndpointsTest.java | 52 +++++++++++++++++++ 8 files changed, 76 insertions(+), 12 deletions(-) diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/result/dto/ResultDto.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/result/dto/ResultDto.java index 17d5d1ad3..6c175d2b6 100644 --- a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/result/dto/ResultDto.java +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/result/dto/ResultDto.java @@ -16,15 +16,15 @@ */ package com.nvidia.nvct.rest.result.dto; -import tools.jackson.databind.node.ObjectNode; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.validation.constraints.NotNull; import java.time.Instant; import java.util.UUID; import lombok.Builder; +import tools.jackson.databind.node.ObjectNode; @Builder(toBuilder = true) -@Schema(description = "Data Transfer Object(DTO) representing a Result") +@Schema(types = {"object"}, description = "Data Transfer Object(DTO) representing a Result") public record ResultDto( @Schema(description = "Result id") @NotNull UUID resultId, @@ -38,7 +38,10 @@ public record ResultDto( @Schema(description = "Result name") @NotNull String name, - @Schema(description = "Result metadata") + @Schema(description = "Result metadata", + types = {"object"}, + implementation = Object.class, + additionalProperties = Schema.AdditionalPropertiesValue.TRUE) @NotNull ObjectNode metadata, @Schema(description = "Result creation timestamp") diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/CreateTaskRequest.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/CreateTaskRequest.java index 2cba2b36e..04cc457a3 100644 --- a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/CreateTaskRequest.java +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/CreateTaskRequest.java @@ -49,7 +49,7 @@ @Slf4j @Builder(toBuilder = true) -@Schema(description = "Request payload to create a Task") +@Schema(types = {"object"}, description = "Request payload to create a Task") public record CreateTaskRequest( @Schema(description = "Task name must start with lowercase/uppercase/digit and can " + "only contain lowercase, uppercase, digit, hyphen, and underscore characters.") diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/GpuSpecificationDto.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/GpuSpecificationDto.java index 3c4d211e8..e853d3f39 100644 --- a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/GpuSpecificationDto.java +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/GpuSpecificationDto.java @@ -16,16 +16,16 @@ */ package com.nvidia.nvct.rest.task.dto; -import tools.jackson.databind.node.ObjectNode; import io.swagger.v3.oas.annotations.media.Schema; import jakarta.annotation.Nullable; import jakarta.validation.Valid; import jakarta.validation.constraints.NotBlank; import java.util.Set; import lombok.Builder; +import tools.jackson.databind.node.ObjectNode; @Builder -@Schema(description = "Data Transfer Object(DTO) representing GPU specification for a Task.") +@Schema(types = {"object"}, description = "Data Transfer Object(DTO) representing GPU specification for a Task.") public record GpuSpecificationDto( @Schema(description = "GPU name from the cluster") @NotBlank String gpu, @@ -43,7 +43,10 @@ public record GpuSpecificationDto( @NotBlank String instanceType, @Schema(description = "Optional configuration field typically used with Helm Charts " + - "to substitute placeholders in values.yaml") + "to substitute placeholders in values.yaml", + types = {"object"}, + implementation = Object.class, + additionalProperties = Schema.AdditionalPropertiesValue.TRUE) @Nullable ObjectNode configuration, @Schema(description = "Helm validation policy cluster attributes") diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/HealthDto.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/HealthDto.java index 2ea2a7659..db8201810 100644 --- a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/HealthDto.java +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/HealthDto.java @@ -22,7 +22,7 @@ import lombok.Builder; @Builder -@Schema(description = "Data Transfer Object(DTO) representing instance health") +@Schema(types = {"object"}, description = "Data Transfer Object(DTO) representing instance health") public record HealthDto( @Schema(description = "GPU Type as per SDD") @NotBlank String gpu, diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/HelmValidationPolicyDto.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/HelmValidationPolicyDto.java index c22f8c1d7..9d74e6665 100644 --- a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/HelmValidationPolicyDto.java +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/HelmValidationPolicyDto.java @@ -26,7 +26,7 @@ import lombok.Builder; @Builder -@Schema(description = "Data Transfer Object(DTO) representing Helm validation policy") +@Schema(types = {"object"}, description = "Data Transfer Object(DTO) representing Helm validation policy") public record HelmValidationPolicyDto ( @Schema(description = "Helm validation policy name.") @NotNull @@ -41,6 +41,7 @@ public record HelmValidationPolicyDto ( List<@NotNull KubernetesType> extraKubernetesTypes) { @Builder + @Schema(types = {"object"}) public record KubernetesType( @Schema(description = "Name of API Group") @NotBlank diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/SecretDto.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/SecretDto.java index 47a4709ca..d618f3241 100644 --- a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/SecretDto.java +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/rest/task/dto/SecretDto.java @@ -41,14 +41,19 @@ @Builder @Schema(description = "Data Transfer Object(DTO) representing secret name/value pair") public record SecretDto( - @Schema(description = "Secret name") + @Schema(description = "Secret name", + requiredMode = Schema.RequiredMode.REQUIRED) @Pattern(regexp = SECRET_NAME_REGEX, message = "Invalid secret name: Must conform to regex " + SECRET_NAME_REGEX) @Size(min = 1, max = MAX_SECRET_NAME_LENGTH, message = "Invalid secret name: must be 1 - " + MAX_SECRET_NAME_LENGTH + " chars long") @NonNull @NotBlank String name, - @Schema(description = "Secret value must be 1 - " + MAX_SECRET_VALUE_LENGTH + " chars long") + @Schema(description = "Secret value must be a string or JSON object and 1 - " + + MAX_SECRET_VALUE_LENGTH + " chars long", + types = {"string", "object"}, + implementation = Object.class, + requiredMode = Schema.RequiredMode.REQUIRED) @NonNull @ValidSecretValueLength JsonNode value) { private static final String MESG_INVALID_SECRET_VALUE = diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/telemetry/dto/TelemetriesDto.java b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/telemetry/dto/TelemetriesDto.java index 49de091b3..0ca9595be 100644 --- a/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/telemetry/dto/TelemetriesDto.java +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/main/java/com/nvidia/nvct/service/telemetry/dto/TelemetriesDto.java @@ -22,7 +22,7 @@ import lombok.Builder; @Builder -@Schema(description = "Telemetry configuration for logs, metrics, and traces.") +@Schema(types = {"object"}, description = "Telemetry configuration for logs, metrics, and traces.") public record TelemetriesDto( @Nullable @Schema(description = "UUID representing the logs telemetry.") diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/misc/MiscEndpointsTest.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/misc/MiscEndpointsTest.java index 2a51a919e..b40250356 100644 --- a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/misc/MiscEndpointsTest.java +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/misc/MiscEndpointsTest.java @@ -25,6 +25,9 @@ import com.nvidia.nvct.IntegrationTestConfiguration; import com.nvidia.nvct.NvctTestApp; import java.net.URI; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; import java.util.stream.Stream; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; @@ -43,6 +46,8 @@ import org.springframework.http.RequestEntity; import org.springframework.test.context.ContextConfiguration; import org.springframework.web.cors.CorsConfiguration; +import tools.jackson.databind.JsonNode; +import tools.jackson.databind.json.JsonMapper; @Slf4j @TestInstance(Lifecycle.PER_CLASS) @@ -54,6 +59,16 @@ @AutoConfigureTestRestTemplate class MiscEndpointsTest { + private static final JsonMapper JSON_MAPPER = JsonMapper.builder().build(); + private static final Set<String> OBJECT_COMPONENT_SCHEMAS = Set.of( + "CreateTaskRequest", + "HealthDto", + "HelmValidationPolicyDto", + "KubernetesType", + "TelemetriesDto", + "ResultDto", + "GpuSpecificationDto"); + @Autowired private TestRestTemplate testRestTemplate; @@ -75,6 +90,7 @@ void testHealth() { assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK); } + @SneakyThrows @Test void testOpenApiDocs() { var requestEntity = RequestEntity.get(URI.create("/v3/openapi")).build(); @@ -82,6 +98,30 @@ void testOpenApiDocs() { var responseBody = responseEntity.getBody(); assertThat(responseEntity.getStatusCode()).isEqualTo(HttpStatus.OK); assertThat(responseBody).isNotNull(); + + var spec = JSON_MAPPER.readTree(responseBody); + var componentSchemas = spec.at("/components/schemas"); + var nullOnlySchemas = componentSchemas.properties().stream() + .filter(entry -> entry.getValue().path("type").isString()) + .filter(entry -> "null".equals(entry.getValue().path("type").asString())) + .map(entry -> entry.getKey()) + .toList(); + assertThat(nullOnlySchemas).isEmpty(); + + OBJECT_COMPONENT_SCHEMAS.forEach(schemaName -> + assertThat(schema(spec, schemaName).path("type").asString()).isEqualTo("object")); + assertThat(componentSchemas.has("JsonNode")).isFalse(); + assertThat(schema(spec, "CreateTaskRequest").path("properties") + .has("gpuSpecification")).isTrue(); + assertThat(schema(spec, "GpuSpecificationDto").path("properties").has("gpu")).isTrue(); + assertThat(schema(spec, "GpuSpecificationDto").at("/properties/configuration/type") + .asString()).isEqualTo("object"); + var secretSchema = schema(spec, "SecretDto"); + assertThat(secretSchema.at("/properties/value").has("$ref")).isFalse(); + assertThat(jsonStringValues(secretSchema.path("required"))) + .containsExactlyInAnyOrder("name", "value"); + assertThat(jsonStringValues(secretSchema.at("/properties/value/type"))) + .containsExactly("string", "object"); } @ParameterizedTest @@ -112,4 +152,16 @@ private static Stream<String> getRecognizedOrigins() { "foo.bar.baz", "*"); } + + private static JsonNode schema(JsonNode spec, String schemaName) { + return spec.path("components").path("schemas").path(schemaName); + } + + private static List<String> jsonStringValues(JsonNode arrayNode) { + var values = new ArrayList<String>(); + for (var node : arrayNode) { + values.add(node.asString()); + } + return values; + } } From 5994724c4d2466951e119150f15c40d32cf709b9 Mon Sep 17 00:00:00 2001 From: Balaji Ganesan <bganesan@nvidia.com> Date: Wed, 22 Jul 2026 21:20:58 -0700 Subject: [PATCH 11/29] test(cloud-tasks): normalize extraction base so the zip-slip guard is recognized The integration test's jar-extraction guard compared a normalized dest path against a non-normalized extraction root, which CodeQL does not recognize as a zip-slip sanitizer. Normalize the base once at definition so the dest.startsWith(base) check is the canonical normalized-to-normalized form. Behavior is unchanged (the extraction root has no `..`/symlink components); this only makes the existing guard statically provable and clears the CodeQL finding. Co-authored-by: Balaji Ganesan <bganesan@nvidia.com> --- .../test/java/com/nvidia/nvct/IntegrationTestConfiguration.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/IntegrationTestConfiguration.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/IntegrationTestConfiguration.java index ae9b9f798..3955136c5 100644 --- a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/IntegrationTestConfiguration.java +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/IntegrationTestConfiguration.java @@ -207,7 +207,7 @@ private static File extractLocalEnvFromJar(URL composeUrlInsideJar) throws IOExc JarURLConnection connection = (JarURLConnection) composeUrlInsideJar.openConnection(); try (var jarFile = connection.getJarFile()) { - var extractRoot = createIntegrationExtractDirectory(); + var extractRoot = createIntegrationExtractDirectory().normalize(); var prefix = LOCAL_ENV_CLASSPATH_PREFIX + "/"; Enumeration<JarEntry> entries = jarFile.entries(); From 7436dec6c5ac87f3384eab0b20a002d67334c33a Mon Sep 17 00:00:00 2001 From: Balaji Ganesan <bganesan@nvidia.com> Date: Wed, 22 Jul 2026 21:17:26 -0700 Subject: [PATCH 12/29] feat(java): standalone nvcf_java_rules + nv_boot_parent Bazel modules Move the Java tree off the shared root Maven hub and onto independent Bazel modules, so every Java library and service builds, tests, and pins its own dependencies from its own directory with no reference to the repo root. This brings Java to parity with the Go and Rust services, which are already self-contained nested modules with their own MODULE.bazel and CI matrix row. Modules created: - rules/java -> nvcf_java_rules: shared macros (nvcf_java_library, nvcf_spring_boot_image), platform.bzl (SPRING_BOOT_BOM, MAVEN_REPOSITORIES, version constants), a vendored self-contained create_oci_image (drops the //rules/oci dependency), and bom_alignment_test. - src/libraries/java/nv-boot-parent -> nv_boot_parent: the Spring platform library, its own @maven hub + maven_install.json, notice tooling repointed at the module-local lockfile. - src/control-plane-services/cloud-tasks -> nvct_cloud_tasks: the service, its own @maven hub (incl. gRPC codegen), depends on nvcf_java_rules + nv_boot_parent. - examples/java-spring-boot-service -> nvcf_java_example: the reference/template service, its own @maven hub. Migrated because it also consumed //rules/java and @nv_third_party_deps and would otherwise break the root build. Maven BOM alignment: load() is forbidden in MODULE.bazel, so each module inlines the canonical BOM list and guards it with bom_alignment_test, which fails the build if a module's boms drift from SPRING_BOOT_BOM in platform.bzl. This keeps the independent per-module resolutions in agreement without a shared hub. Root wiring: the four Java module paths (except rules/java, which declares no root-referencing targets) are added to .bazelignore; cloud-tasks is dropped from ROOT_GLOBS and src/libraries/ is narrowed to src/libraries/go/ so Java no longer rides the root row. bazel.yml gains nv-boot-parent, cloud-tasks, and java-spring-boot-service matrix rows (build + test); like all non-root rows they get EC2 Buildbarn cache hits via the workflow's remote-cache injection. CI image: ci/Dockerfile.bazel gains an additive remotejdk_25 + Bazel 9.1.1 pre-warm so the Java rows start warm; bazel-ci-image.yml bumps to 0.13.0 (builds on this PR, publishes on merge). The bazel.yml consumer ref stays at 0.12.0 until 0.13.0 is published, to keep the matrix from pinning an unpublished image. Maven jars are not baked (per-subtree actions/cache for now; see #373). Verified standalone from each module directory: nvcf_java_rules builds; nv_boot_parent builds + 17 non-docker tests pass (incl. bom_alignment_test, notice_check_test); nvct_cloud_tasks builds (gRPC codegen + nv_boot_parent consumed as a module) + bom_alignment_test passes; nvcf_java_example builds + 3 tests pass. Root workspace analyzes clean with the Java dirs ignored. Refs: NVIDIA/nvcf#372 Co-authored-by: Balaji Ganesan <bganesan@nvidia.com> --- .bazelignore | 10 + .github/workflows/bazel-ci-image.yml | 8 +- .github/workflows/bazel.yml | 26 +- ci/Dockerfile.bazel | 27 +- docs/bazel-java-architecture.md | 285 + examples/java-spring-boot-service/.bazelrc | 47 + examples/java-spring-boot-service/.gitignore | 1 + examples/java-spring-boot-service/AGENTS.md | 25 + examples/java-spring-boot-service/BUILD.bazel | 45 +- examples/java-spring-boot-service/CLAUDE.md | 1 + .../java-spring-boot-service/MODULE.bazel | 69 + .../MODULE.bazel.lock | 1236 ++ .../maven_install.json | 2589 ++++ rules/java/.bazelrc | 47 + rules/java/.gitignore | 1 + rules/java/AGENTS.md | 47 + rules/java/CLAUDE.md | 1 + rules/java/MODULE.bazel | 71 + rules/java/MODULE.bazel.lock | 296 + rules/java/bom_alignment.bzl | 55 + rules/java/defs.bzl | 2 +- rules/java/platform.bzl | 53 + rules/java/platforms/BUILD.bazel | 32 + rules/java/private/oci.bzl | 162 + rules/java/private/spring_boot.bzl | 2 +- rules/java/scripts/BUILD.bazel | 18 + rules/java/scripts/check_bom_alignment.sh | 31 + .../cloud-tasks/.bazelrc | 52 + .../cloud-tasks/.gitignore | 1 + .../cloud-tasks/AGENTS.md | 39 + .../cloud-tasks/BUILD.bazel | 14 +- .../cloud-tasks/CLAUDE.md | 1 + .../cloud-tasks/MODULE.bazel | 253 + .../cloud-tasks/MODULE.bazel.lock | 1313 ++ .../cloud-tasks/maven_install.json | 11900 ++++++++++++++++ .../cloud-tasks/nvct-core/BUILD.bazel | 322 +- .../cloud-tasks/nvct-service/BUILD.bazel | 76 +- .../cloud-tasks/tools/bazel/BUILD.bazel | 6 +- .../cloud-tasks/tools/bazel/proto.bzl | 2 +- src/libraries/java/nv-boot-parent/.bazelrc | 47 + src/libraries/java/nv-boot-parent/AGENTS.md | 47 + src/libraries/java/nv-boot-parent/BUILD.bazel | 33 +- src/libraries/java/nv-boot-parent/CLAUDE.md | 1 + .../java/nv-boot-parent/MODULE.bazel | 143 + .../java/nv-boot-parent/MODULE.bazel.lock | 1221 ++ src/libraries/java/nv-boot-parent/NOTICE | 11 +- .../java/nv-boot-parent/maven_install.json | 10215 +++++++++++++ .../nv-boot-mock-servers-test/BUILD.bazel | 34 +- .../nv-boot-starter-audit/BUILD.bazel | 54 +- .../nv-boot-starter-cassandra/BUILD.bazel | 80 +- .../nv-boot-starter-core/BUILD.bazel | 60 +- .../BUILD.bazel | 42 +- .../nv-boot-starter-exceptions/BUILD.bazel | 34 +- .../nv-boot-starter-jwt/BUILD.bazel | 54 +- .../nv-boot-starter-observability/BUILD.bazel | 100 +- .../nv-boot-starter-registries/BUILD.bazel | 96 +- .../BUILD.bazel | 40 +- .../nv-boot-starter-telemetry/BUILD.bazel | 60 +- .../nv-boot-parent/tools/bazel/BUILD.bazel | 8 +- .../java/nv-boot-parent/tools/bazel/java.bzl | 32 +- .../tools/bazel/notice_check_test.sh | 8 +- 61 files changed, 30986 insertions(+), 600 deletions(-) create mode 100644 docs/bazel-java-architecture.md create mode 100644 examples/java-spring-boot-service/.bazelrc create mode 100644 examples/java-spring-boot-service/.gitignore create mode 100644 examples/java-spring-boot-service/AGENTS.md create mode 100644 examples/java-spring-boot-service/CLAUDE.md create mode 100644 examples/java-spring-boot-service/MODULE.bazel create mode 100644 examples/java-spring-boot-service/MODULE.bazel.lock create mode 100755 examples/java-spring-boot-service/maven_install.json create mode 100644 rules/java/.bazelrc create mode 100644 rules/java/.gitignore create mode 100644 rules/java/AGENTS.md create mode 100644 rules/java/CLAUDE.md create mode 100644 rules/java/MODULE.bazel create mode 100644 rules/java/MODULE.bazel.lock create mode 100644 rules/java/bom_alignment.bzl create mode 100644 rules/java/platform.bzl create mode 100644 rules/java/platforms/BUILD.bazel create mode 100644 rules/java/private/oci.bzl create mode 100644 rules/java/scripts/BUILD.bazel create mode 100755 rules/java/scripts/check_bom_alignment.sh create mode 100644 src/control-plane-services/cloud-tasks/.bazelrc create mode 100644 src/control-plane-services/cloud-tasks/.gitignore create mode 100644 src/control-plane-services/cloud-tasks/AGENTS.md create mode 100644 src/control-plane-services/cloud-tasks/CLAUDE.md create mode 100644 src/control-plane-services/cloud-tasks/MODULE.bazel create mode 100644 src/control-plane-services/cloud-tasks/MODULE.bazel.lock create mode 100755 src/control-plane-services/cloud-tasks/maven_install.json create mode 100644 src/libraries/java/nv-boot-parent/.bazelrc create mode 100644 src/libraries/java/nv-boot-parent/AGENTS.md create mode 100644 src/libraries/java/nv-boot-parent/CLAUDE.md create mode 100644 src/libraries/java/nv-boot-parent/MODULE.bazel create mode 100644 src/libraries/java/nv-boot-parent/MODULE.bazel.lock create mode 100644 src/libraries/java/nv-boot-parent/maven_install.json diff --git a/.bazelignore b/.bazelignore index b566f9400..e69d486e2 100644 --- a/.bazelignore +++ b/.bazelignore @@ -49,6 +49,16 @@ infra migrations tools +# Standalone Java modules. Each has its own MODULE.bazel, @maven hub, and CI +# matrix row in .github/workflows/bazel.yml; their BUILD files reference +# module-local repos (@maven, @nvcf_java_rules, @nv_boot_parent) that the root +# module does not define, so the root build must not recurse into them. rules/java +# (module nvcf_java_rules) is intentionally NOT listed: its BUILD files declare no +# targets that reference the root workspace, so it stays loadable at the root. +src/libraries/java/nv-boot-parent +src/control-plane-services/cloud-tasks +examples/java-spring-boot-service + # Vendored dependencies inside the two Phase 1 subtrees. Bazel resolves these # from MODULE.bazel via Gazelle's go_deps extension, not from on-disk vendor. src/libraries/go/lib/vendor diff --git a/.github/workflows/bazel-ci-image.yml b/.github/workflows/bazel-ci-image.yml index 6c169a123..48cd1fa45 100644 --- a/.github/workflows/bazel-ci-image.yml +++ b/.github/workflows/bazel-ci-image.yml @@ -38,7 +38,13 @@ permissions: env: # Keep in lockstep with BAZEL_CI_VERSION in .gitlab-ci.yml and the # container.image tag in .github/workflows/bazel.yml. - BAZEL_CI_VERSION: "0.8.0" + # + # 0.13.0 adds the remotejdk_25 + Bazel 9.1.1 pre-warm for the standalone Java + # modules (see ci/Dockerfile.bazel). This workflow builds (and, on merge to + # main, publishes) the tag; .github/workflows/bazel.yml is bumped to 0.13.0 in + # a fast-follow once the tag is published, so the bazel matrix never pins an + # unpublished image. Tracked in NVIDIA/nvcf#372. + BAZEL_CI_VERSION: "0.13.0" IMAGE: ghcr.io/nvidia/nvcf/bazel-ci jobs: diff --git a/.github/workflows/bazel.yml b/.github/workflows/bazel.yml index 5450f77bf..c7fccb322 100644 --- a/.github/workflows/bazel.yml +++ b/.github/workflows/bazel.yml @@ -114,10 +114,22 @@ jobs: worker-task|src/compute-plane-services/worker-task|false worker-utils|src/compute-plane-services/worker-utils|false function-autoscaler|src/control-plane-services/function-autoscaler|false - helm-reval|src/control-plane-services/helm-reval|false' - # Paths that affect the root-module workspace build (native - # root subtrees, Go and Java, plus the shared Bazel scaffold). - ROOT_GLOBS=(MODULE.bazel .bazelrc .bazelversion BUILD.bazel rules/ platforms/ tools/ ci/ src/clis/ src/libraries/ src/control-plane-services/cloud-tasks/ .github/bazel-root-test-quarantine.txt) + helm-reval|src/control-plane-services/helm-reval|false + nv-boot-parent|src/libraries/java/nv-boot-parent|false + cloud-tasks|src/control-plane-services/cloud-tasks|false + java-spring-boot-service|examples/java-spring-boot-service|false' + # Standalone Java modules. Each has its own MODULE.bazel and @maven + # hub, so it builds+tests in its own module dir. Like every non-root + # row they do NOT set --config=remote; the build/test steps below + # inject --remote_cache/--tls_certificate/--remote_header from the + # EC2 Buildbarn secrets, so these rows warm from and hit that shared + # cache rather than cold-building (see NVIDIA/nvcf#372). + # Paths that affect the root-module workspace build (native root + # subtrees plus the shared Bazel scaffold). Java no longer rides the + # root row: nv-boot-parent, cloud-tasks, and the example are their own + # modules (src/libraries/ is narrowed to src/libraries/go/ and + # cloud-tasks is dropped here). + ROOT_GLOBS=(MODULE.bazel .bazelrc .bazelversion BUILD.bazel rules/ platforms/ tools/ ci/ src/clis/ src/libraries/go/ .github/bazel-root-test-quarantine.txt) run_all=false changed="" @@ -198,6 +210,12 @@ jobs: CACHE_TOKEN: ${{ secrets.BAZEL_REMOTE_CACHE_TOKEN }} CACHE_ENDPOINT: ${{ vars.BAZEL_REMOTE_CACHE_ENDPOINT }} container: + # Staged bump: ci/Dockerfile.bazel + bazel-ci-image.yml move to 0.13.0 + # (adds the remotejdk_25 / Bazel 9.1.1 pre-warm the Java module rows use). + # 0.13.0 publishes only on merge to main, so this consumer ref stays at + # 0.12.0 until then to keep the matrix from pinning an unpublished image; + # a fast-follow bumps it to 0.13.0. The Java rows still work on 0.12.0 (they + # cold-fetch the JDK once, then reuse it via actions/cache). See #372. image: ghcr.io/nvidia/nvcf/bazel-ci:0.12.0 credentials: username: ${{ github.actor }} diff --git a/ci/Dockerfile.bazel b/ci/Dockerfile.bazel index 849d84551..c1d1d5973 100644 --- a/ci/Dockerfile.bazel +++ b/ci/Dockerfile.bazel @@ -130,4 +130,29 @@ RUN mkdir /tmp/warmup && cd /tmp/warmup \ && bazel version \ && rm -rf /tmp/warmup -LABEL description="NVCF monorepo Bazel CI image - Ubuntu 24.04 + Bazel ${BAZEL_VERSION} + kubebuilder-tools ${KUBEBUILDER_TOOLS_VERSION}" +# Pre-warm the hermetic JDK the standalone Java modules build against. The +# nvcf_java_rules / nv_boot_parent / cloud-tasks / java-spring-boot-service +# modules pin Bazel ${JAVA_MODULE_BAZEL_VERSION} and compile against +# remotejdk_${JAVA_MODULE_JDK_VERSION} (fetched hermetically by rules_java), +# both re-downloaded on a cold runner. Compiling a throwaway class with those +# pins fills the shared Bazel repository cache (the JDK archive) and bazelisk's +# ${JAVA_MODULE_BAZEL_VERSION} binary, so the Java matrix rows start warm instead +# of cold-fetching the JDK. Additive: it only populates caches the Java rows +# reuse; no other subtree row's inputs change. Maven jars are intentionally not +# baked (see .github/workflows/bazel.yml and NVIDIA/nvcf#373). +ARG JAVA_MODULE_BAZEL_VERSION=9.1.1 +ARG JAVA_MODULE_JDK_VERSION=25 +RUN mkdir /tmp/jdkwarm && cd /tmp/jdkwarm \ + && echo "${JAVA_MODULE_BAZEL_VERSION}" > .bazelversion \ + && echo 'bazel_dep(name = "rules_java", version = "9.3.0")' > MODULE.bazel \ + && printf 'load("@rules_java//java:defs.bzl", "java_library")\njava_library(name = "warm", srcs = ["Warm.java"])\n' > BUILD.bazel \ + && echo 'public class Warm {}' > Warm.java \ + && bazel build //:warm \ + --java_language_version="${JAVA_MODULE_JDK_VERSION}" \ + --java_runtime_version="remotejdk_${JAVA_MODULE_JDK_VERSION}" \ + --tool_java_language_version="${JAVA_MODULE_JDK_VERSION}" \ + --tool_java_runtime_version="remotejdk_${JAVA_MODULE_JDK_VERSION}" \ + --java_header_compilation=false \ + && rm -rf /tmp/jdkwarm + +LABEL description="NVCF monorepo Bazel CI image - Ubuntu 24.04 + Bazel ${BAZEL_VERSION} + kubebuilder-tools ${KUBEBUILDER_TOOLS_VERSION} + remotejdk_${JAVA_MODULE_JDK_VERSION} prewarm" diff --git a/docs/bazel-java-architecture.md b/docs/bazel-java-architecture.md new file mode 100644 index 000000000..0014f8326 --- /dev/null +++ b/docs/bazel-java-architecture.md @@ -0,0 +1,285 @@ +# Java in the NVCF Monorepo: Target Bazel Architecture + +Status: target architecture. Supersedes the interim root-workspace setup where +all Java code shared one root Maven hub and one lockfile. + +## Goals + +- Every Java library and service is an independent Bazel module. Each builds, + tests, and pins its dependencies on its own: `cd <module> && bazel build //...` + works with no reference to the repo root. +- A service can be consumed from outside the monorepo by module name, pulling + only its subtree, via `git_override` with `strip_prefix`. +- One shared source of truth for the Spring Boot platform (BOM plus common + starters) so 10+ services do not each re-declare and drift on versions. +- Parity with the rest of the repo: Go and Rust services are already + self-contained nested modules with their own `MODULE.bazel` and CI matrix + row. Java stops being the exception. + +## Non-goals + +- No shared root Maven hub. `@nv_third_party_deps` at the root and the root + `//:maven_install.json` are retired for Java. +- No cross-module dependence through absolute source labels + (`//src/libraries/java/nv-boot-parent/...`). Cross-module edges go through + `bazel_dep`. + +## Topology + +``` +rules/java/ module: nvcf_java_rules (shared macros) + MODULE.bazel + defs.bzl nvcf_java_library, nvcf_spring_boot_image, + platform.bzl java_junit5_test, SPRING_BOOT_BOM, versions +src/libraries/java/ + nv-boot-parent/ module: nv_boot_parent (platform library) + MODULE.bazel owns the Spring BOM + shared starters + maven_install.json its own lockfile + nv-boot-*/BUILD.bazel java_library targets, public +src/control-plane-services/ + cloud-tasks/ module: nvct_cloud_tasks (service) + MODULE.bazel bazel_dep nv_boot_parent + nvcf_java_rules + maven_install.json its own lockfile: service-only deltas + nvct-core/BUILD.bazel + nvct-service/BUILD.bazel nvcf_spring_boot_image -> OCI image + <next java service>/ same shape, one per service +``` + +Three module kinds: + +- Rules module (`nvcf_java_rules`, at `rules/java`). Holds the macros and the + single versions/BOM definition. No application code. Consumed by every Java + module via `bazel_dep` + `local_path_override`. This mirrors how + `rules/oci-destinations` (module `nvcf_nvcr_destinations`) is already + consumed by infra/cassandra. +- Platform library module (`nv_boot_parent`). Owns the canonical Spring Boot + BOM and the shared `nv-boot-*` starters as `java_library` targets. It has its + own Maven hub. Services depend on it, not on raw Spring coordinates it + already provides. +- Service modules (`nvct_cloud_tasks`, and each future service). One image per + service via `nvcf_spring_boot_image`. Depends on `nv_boot_parent` and + `nvcf_java_rules`. Declares only the Maven coordinates it uses directly and + that the platform does not already export. + +## Dependency edges + +In-monorepo builds resolve cross-module edges with `local_path_override`, so +local source always wins over any registry copy. Paths are relative to the +consuming module directory. + +`rules/java/MODULE.bazel`: + +```python +module(name = "nvcf_java_rules", version = "0.1.0") +bazel_dep(name = "rules_java", version = "9.3.0") +bazel_dep(name = "rules_jvm_external", version = "7.0") +bazel_dep(name = "contrib_rules_jvm", version = "0.27.0") +bazel_dep(name = "rules_oci", version = "2.2.7") +bazel_dep(name = "rules_pkg", version = "1.2.0") +``` + +`src/libraries/java/nv-boot-parent/MODULE.bazel`: + +```python +module(name = "nv_boot_parent", version = "1.4.1") + +bazel_dep(name = "nvcf_java_rules", version = "0.1.0") +local_path_override(module_name = "nvcf_java_rules", path = "../../../../rules/java") + +bazel_dep(name = "rules_java", version = "9.3.0") +bazel_dep(name = "rules_jvm_external", version = "7.0") + +maven = use_extension("@rules_jvm_external//:extensions.bzl", "maven") +maven.install( + name = "maven", + lock_file = "//:maven_install.json", + # load() is forbidden in MODULE.bazel, so the BOM cannot reference + # SPRING_BOOT_BOM here. The list is inlined verbatim and guarded by + # //:bom_alignment_test, which fails if it drifts from platform.bzl. + boms = [ + "org.springframework.boot:spring-boot-dependencies:4.0.7", + "org.springframework.cloud:spring-cloud-dependencies:2025.1.2", + "org.testcontainers:testcontainers-bom:2.0.5", + "net.javacrumbs.shedlock:shedlock-bom:7.7.0", + ], + artifacts = [ ... shared starter coordinates ... ], + repositories = [ ... same two public Central mirrors ... ], +) +use_repo(maven, "maven") +``` + +`src/control-plane-services/cloud-tasks/MODULE.bazel`: + +```python +module(name = "nvct_cloud_tasks", version = "1.1.0") + +bazel_dep(name = "nvcf_java_rules", version = "0.1.0") +local_path_override(module_name = "nvcf_java_rules", path = "../../../rules/java") + +bazel_dep(name = "nv_boot_parent", version = "1.4.1") +local_path_override(module_name = "nv_boot_parent", path = "../../libraries/java/nv-boot-parent") + +maven = use_extension("@rules_jvm_external//:extensions.bzl", "maven") +maven.install( + name = "maven", + lock_file = "//:maven_install.json", + # Same inlined BOM list as every other Java module (see the note above); + # //:bom_alignment_test keeps it aligned with platform.bzl. + boms = [ ... the four canonical BOMs ... ], + artifacts = [ ... only coordinates cloud-tasks uses directly ... ], + repositories = [ ... same two public Central mirrors ... ], +) +use_repo(maven, "maven") +``` + +Service BUILD files then reference `@nv_boot_parent//nv-boot-registries:...` +for platform targets and `@maven//:...` for the service's own deps. The old +`@nv_third_party_deps//:...` labels are replaced by the module-local `@maven`. + +## Maven strategy: one BOM, many hubs + +Each module resolves its own Maven graph and writes its own +`maven_install.json`. That is what makes a module independently buildable. The +risk is version drift: two modules pinning different Spring versions put two +copies on a transitive classpath. + +Rule: the Spring Boot BOM and any other shared BOMs are defined once, in +`@nvcf_java_rules//:platform.bzl`, as a loadable list: + +```python +# rules/java/platform.bzl +SPRING_BOOT_VERSION = "3.5.11" +SPRING_BOOT_BOM = ["org.springframework.boot:spring-boot-dependencies:%s" % SPRING_BOOT_VERSION] +MAVEN_REPOSITORIES = [ + "https://repo1.maven.org/maven2", + # internal mirrors appended by the private overlay, never in the OSS tree +] +``` + +`load()` is forbidden in `MODULE.bazel`, so a module cannot write +`boms = SPRING_BOOT_BOM` directly. Instead every Java module inlines the same +literal BOM list in its `maven.install` and lists BOM-managed coordinates +without a version. The alignment is enforced, not trusted: each module calls +`bom_alignment_test` (from `@nvcf_java_rules//:bom_alignment.bzl`), which +materializes `SPRING_BOOT_BOM` from `platform.bzl` and fails the build if any +canonical coordinate is missing from that module's `MODULE.bazel`. Bumping Spring +is then a one-line change in `platform.bzl`, the matching edit to each module's +inlined list, and a re-pin; a module left un-aligned fails its own test. Because +the BOM is identical everywhere, the independent resolutions agree. + +The platform module (`nv_boot_parent`) additionally exports the common +starters as `java_library` targets. A service that depends on +`@nv_boot_parent//nv-boot-web:...` gets those starters and their transitive +Maven deps without re-declaring them. A service only lists a coordinate in its +own `maven.install` when it uses that library directly and the platform does +not already export it. + +## Independent build contract + +For every Java module: + +- `MODULE.bazel` at the module root, with a unique `module(name=...)`. +- Committed `maven_install.json` (or `<name>_install.json`) lockfile. +- `.bazelrc` with the Java toolchain (`--java_language_version=21`, + `--java_runtime_version=remotejdk_21`) and a `build:release` config. +- `bazel build //...` and `bazel test //...` pass from the module directory + with no `--override_module` flags on the command line. +- The repo root lists the module path in `.bazelignore` so the root workspace + does not recurse into it (same as `infra/cassandra`, stargate, + function-autoscaler). + +## CI: one matrix row per module + +`.github/workflows/bazel.yml` derives a matrix row from each nested +`MODULE.bazel`. After migration: + +- `bazel (nv-boot-parent)`, `bazel (cloud-tasks)`, and one row per future + service, each running `bazel build //... && bazel test //...` in the module + directory. +- Java paths are removed from `ROOT_GLOBS`. Java no longer rides the + `bazel (root)` row. +- Add each module to the ROWS list: + `nv-boot-parent|src/libraries/java/nv-boot-parent|false`, + `cloud-tasks|src/control-plane-services/cloud-tasks|false`. + +Isolated rows mean a failing service does not block the others, and build time +scales out instead of piling onto one root job. + +## External and managed-side consumption + +Because `nv_boot_parent` is a real module rooted at its own subtree, an +out-of-tree Bazel workspace consumes it without vendoring the monorepo: + +```python +bazel_dep(name = "nv_boot_parent", version = "1.4.1") +git_override( + module_name = "nv_boot_parent", + remote = "https://github.com/NVIDIA/nvcf.git", + commit = "<pinned sha>", + strip_prefix = "src/libraries/java/nv-boot-parent", +) +``` + +`strip_prefix` requires `MODULE.bazel` at that subdirectory. The platform +library only needs public BCR modules (`rules_java`, `rules_jvm_external`) plus +its Maven hub, so it resolves for external consumers with no access to internal +rules. Services are consumable the same way when needed. + +For in-monorepo builds the same modules use `local_path_override` instead of +`git_override`, so local edits are always authoritative and no network fetch of +the monorepo occurs. + +## Versioning and pinning + +- `module(version=...)` tracks the artifact version. `git_override` and + `local_path_override` ignore it (they pin by commit or path), so it is + informational for in-tree builds and meaningful only if a module is ever + published to a registry. +- Re-pin a module after changing its `maven.install`: + `REPIN=1 bazel run @maven//:pin` from the module directory. Commit the + updated lockfile. +- Bumping a shared version (Spring, JUnit) is a change in + `@nvcf_java_rules//:platform.bzl` followed by a re-pin of every Java module. + CI catches any module left un-repinned. + +## NOTICE and license + +Each module generates its NOTICE from its own lockfile. The `nv-boot-parent` +notice tooling that currently reads the root `//:maven_install.json` is +repointed at the module-local lockfile. Services generate their own NOTICE the +same way. There is no root aggregate lockfile for Java to depend on. + +## Adding a new Java service + +1. Create the module directory with `MODULE.bazel` + (`module(name = "nvct_<svc>", ...)`), `bazel_dep` + `local_path_override` + for `nvcf_java_rules` and `nv_boot_parent`, and a `maven.install` loading + `SPRING_BOOT_BOM` plus only the service's direct coordinates. +2. Add `.bazelrc` (Java toolchain + `build:release`) and a `CLAUDE.md` + (`@AGENTS.md`) plus `AGENTS.md` for the subtree. +3. Write `BUILD.bazel` using `nvcf_java_library`, `nvcf_spring_boot_image`, and + `java_junit5_test` from `@nvcf_java_rules//rules/java:defs.bzl`. +4. `REPIN=1 bazel run @maven//:pin`; commit `maven_install.json`. +5. Add the module path to root `.bazelignore` and to the `bazel.yml` ROWS list. +6. `cd <module> && bazel build //... && bazel test //...` must pass. + +## Migration from the interim setup + +Order matters: the rules module and platform must land before services can +point at them. + +1. `rules/java`: add `MODULE.bazel` (`nvcf_java_rules`) and `platform.bzl` + (`SPRING_BOOT_BOM`, `MAVEN_REPOSITORIES`, shared version constants). +2. `nv-boot-parent`: add `MODULE.bazel` (`nv_boot_parent`) and its own + `maven.install` seeded from the shared coordinates it owns; re-pin; move its + notice tooling to the module-local lockfile. Verify + `cd src/libraries/java/nv-boot-parent && bazel build //...`. +3. `cloud-tasks`: add `MODULE.bazel` (`nvct_cloud_tasks`), replace + `@nv_third_party_deps//:...` with `@maven//:...`, replace + `//src/libraries/java/nv-boot-parent/...` source labels with + `@nv_boot_parent//...`, re-pin. Verify standalone build and image target. +4. Remove Java coordinates from the root `MODULE.bazel` `nv_third_party_deps` + hub and the root `//:maven_install.json`; drop Java from `ROOT_GLOBS`; add + the two module rows to `.bazelignore` and `bazel.yml`. +5. Repeat step 3 for each remaining Java service as it onboards. +``` diff --git a/examples/java-spring-boot-service/.bazelrc b/examples/java-spring-boot-service/.bazelrc new file mode 100644 index 000000000..3dcfdd132 --- /dev/null +++ b/examples/java-spring-boot-service/.bazelrc @@ -0,0 +1,47 @@ +# SPDX-FileCopyrightText: Copyright (c) NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +# +# 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. + +# Standalone module .bazelrc. `cd rules/java && bazel build //...` must work with +# no reference to the repo root. The caller supplies any remote cache endpoint; +# no cache config is baked in (parity with the other nested modules). + +common --enable_bzlmod +common --enable_platform_specific_config +build --incompatible_strict_action_env + +# Route public Maven Central through an internal Artifactory mirror on internal +# builds only. The target host lives in an un-mirrored internal bazelrc, so +# public builds go straight to Maven Central (try-import is a no-op when absent). +try-import %workspace%/tools/bazel/internal.bazelrc + +# Java: hermetic remotejdk 25 regardless of the host JDK, matching the root +# module so builds are reproducible everywhere. +build --java_language_version=25 +build --java_runtime_version=remotejdk_25 +build --tool_java_language_version=25 +build --tool_java_runtime_version=remotejdk_25 +build --java_header_compilation=false + +test --test_output=errors +test --test_env=HOME=/tmp +test --test_env=XDG_CACHE_HOME=/tmp/.cache + +startup --host_jvm_args=-Xmx4g + +build:release --compilation_mode=opt +build:release --strip=always + +try-import %workspace%/user.bazelrc +try-import %user.home%/.bazelrc.user diff --git a/examples/java-spring-boot-service/.gitignore b/examples/java-spring-boot-service/.gitignore new file mode 100644 index 000000000..a6ef824c1 --- /dev/null +++ b/examples/java-spring-boot-service/.gitignore @@ -0,0 +1 @@ +/bazel-* diff --git a/examples/java-spring-boot-service/AGENTS.md b/examples/java-spring-boot-service/AGENTS.md new file mode 100644 index 000000000..2a1f2af99 --- /dev/null +++ b/examples/java-spring-boot-service/AGENTS.md @@ -0,0 +1,25 @@ +# AGENTS.md - nvcf_java_example + +Reference Spring Boot service, as a standalone Bazel module +(`module(name = "nvcf_java_example")`). The copy-me template for a new NVCF Java +service module. + +## Build and test (from this directory) + +``` +cd examples/java-spring-boot-service +bazel build //... +bazel test //... +``` + +Depends only on `nvcf_java_rules` (macros + multi-arch image helper) via +`bazel_dep` + `local_path_override`, plus its own `@maven` hub and committed +`maven_install.json`. A real service additionally `bazel_dep`s `nv_boot_parent` +and adds the internal Maven overlay. Re-pin after editing `maven.install`: + +``` +REPIN=1 bazel run @maven//:pin +``` + +The `boms` list must stay identical to `SPRING_BOOT_BOM` in +`@nvcf_java_rules//:platform.bzl`; `//:bom_alignment_test` enforces it. diff --git a/examples/java-spring-boot-service/BUILD.bazel b/examples/java-spring-boot-service/BUILD.bazel index e82da8bac..e3732c605 100644 --- a/examples/java-spring-boot-service/BUILD.bazel +++ b/examples/java-spring-boot-service/BUILD.bazel @@ -21,7 +21,16 @@ # wiring a real service adds. load("@contrib_rules_jvm//java:defs.bzl", "java_junit5_test") -load("//rules/java:defs.bzl", "nvcf_java_library", "nvcf_spring_boot_image") +load("@nvcf_java_rules//:bom_alignment.bzl", "bom_alignment_test") +load("@nvcf_java_rules//:defs.bzl", "nvcf_java_library", "nvcf_spring_boot_image") + +exports_files(["MODULE.bazel"]) + +# Fails the build if this module's inlined maven.install boms drift from the +# canonical SPRING_BOOT_BOM in @nvcf_java_rules//:platform.bzl. +bom_alignment_test( + name = "bom_alignment_test", +) nvcf_java_library( name = "example_lib", @@ -31,10 +40,10 @@ nvcf_java_library( # the concrete artifacts below are the ones the code imports directly, so # the strict-deps header compiler sees them on the direct classpath. deps = [ - "@nv_third_party_deps//:org_springframework_boot_spring_boot", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_autoconfigure", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_web", - "@nv_third_party_deps//:org_springframework_spring_web", + "@maven//:org_springframework_boot_spring_boot", + "@maven//:org_springframework_boot_spring_boot_autoconfigure", + "@maven//:org_springframework_boot_spring_boot_starter_web", + "@maven//:org_springframework_spring_web", ], ) @@ -54,13 +63,13 @@ java_junit5_test( srcs = ["src/test/java/com/nvidia/nvcf/example/HelloControllerTest.java"], test_class = "com.nvidia.nvcf.example.HelloControllerTest", runtime_deps = [ - "@nv_third_party_deps//:org_junit_jupiter_junit_jupiter_engine", - "@nv_third_party_deps//:org_junit_platform_junit_platform_launcher", - "@nv_third_party_deps//:org_junit_platform_junit_platform_reporting", + "@maven//:org_junit_jupiter_junit_jupiter_engine", + "@maven//:org_junit_platform_junit_platform_launcher", + "@maven//:org_junit_platform_junit_platform_reporting", ], deps = [ ":example_lib", - "@nv_third_party_deps//:org_junit_jupiter_junit_jupiter_api", + "@maven//:org_junit_jupiter_junit_jupiter_api", ], ) @@ -73,17 +82,17 @@ java_junit5_test( srcs = ["src/test/java/com/nvidia/nvcf/example/HelloControllerWebTest.java"], test_class = "com.nvidia.nvcf.example.HelloControllerWebTest", runtime_deps = [ - "@nv_third_party_deps//:org_junit_jupiter_junit_jupiter_engine", - "@nv_third_party_deps//:org_junit_platform_junit_platform_launcher", - "@nv_third_party_deps//:org_junit_platform_junit_platform_reporting", + "@maven//:org_junit_jupiter_junit_jupiter_engine", + "@maven//:org_junit_platform_junit_platform_launcher", + "@maven//:org_junit_platform_junit_platform_reporting", ], deps = [ ":example_lib", - "@nv_third_party_deps//:org_junit_jupiter_junit_jupiter_api", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_test", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_test_autoconfigure", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_webmvc_test", - "@nv_third_party_deps//:org_springframework_spring_beans", - "@nv_third_party_deps//:org_springframework_spring_test", + "@maven//:org_junit_jupiter_junit_jupiter_api", + "@maven//:org_springframework_boot_spring_boot_test", + "@maven//:org_springframework_boot_spring_boot_test_autoconfigure", + "@maven//:org_springframework_boot_spring_boot_webmvc_test", + "@maven//:org_springframework_spring_beans", + "@maven//:org_springframework_spring_test", ], ) diff --git a/examples/java-spring-boot-service/CLAUDE.md b/examples/java-spring-boot-service/CLAUDE.md new file mode 100644 index 000000000..43c994c2d --- /dev/null +++ b/examples/java-spring-boot-service/CLAUDE.md @@ -0,0 +1 @@ +@AGENTS.md diff --git a/examples/java-spring-boot-service/MODULE.bazel b/examples/java-spring-boot-service/MODULE.bazel new file mode 100644 index 000000000..1c462b3c9 --- /dev/null +++ b/examples/java-spring-boot-service/MODULE.bazel @@ -0,0 +1,69 @@ +# SPDX-FileCopyrightText: Copyright (c) NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +# +# 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. + +"""nvcf_java_example: reference Spring Boot service, as a standalone module. + +The copy-me template for a new NVCF Java service module: bazel_dep on +nvcf_java_rules, a java_library for the app, nvcf_spring_boot_image for the +multi-arch container, and JUnit 5 tests. A real service also bazel_deps +nv_boot_parent and adds the internal Maven overlay; see README.md. +""" + +module( + name = "nvcf_java_example", + version = "4.0.7", +) + +bazel_dep(name = "nvcf_java_rules", version = "0.1.0") +local_path_override( + module_name = "nvcf_java_rules", + path = "../../rules/java", +) + +bazel_dep(name = "rules_java", version = "9.3.0") +bazel_dep(name = "rules_jvm_external", version = "7.0") +bazel_dep(name = "contrib_rules_jvm", version = "0.33.0") + +maven = use_extension("@rules_jvm_external//:extensions.bzl", "maven") +maven.install( + name = "maven", + artifacts = [ + "org.springframework.boot:spring-boot-starter-web", + "org.springframework.boot:spring-boot-starter-test", + "org.springframework.boot:spring-boot-webmvc-test", + "org.junit.jupiter:junit-jupiter-api", + "org.junit.jupiter:junit-jupiter-engine", + "org.junit.platform:junit-platform-launcher", + "org.junit.platform:junit-platform-reporting", + ], + boms = [ + # Keep identical to SPRING_BOOT_BOM in @nvcf_java_rules//:platform.bzl. + # //:bom_alignment_test fails the build if these drift. + "org.springframework.boot:spring-boot-dependencies:4.0.7", + "org.springframework.cloud:spring-cloud-dependencies:2025.1.2", + "org.testcontainers:testcontainers-bom:2.0.5", + "net.javacrumbs.shedlock:shedlock-bom:7.7.0", + ], + fail_on_missing_checksum = True, + fetch_sources = True, + known_contributing_modules = ["protobuf"], + lock_file = "//:maven_install.json", + repositories = [ + "https://maven-central.storage-download.googleapis.com/maven2", + "https://repo.maven.apache.org/maven2", + ], + resolver = "maven", +) +use_repo(maven, "maven") diff --git a/examples/java-spring-boot-service/MODULE.bazel.lock b/examples/java-spring-boot-service/MODULE.bazel.lock new file mode 100644 index 000000000..3a653bd7d --- /dev/null +++ b/examples/java-spring-boot-service/MODULE.bazel.lock @@ -0,0 +1,1236 @@ +{ + "lockFileVersion": 28, + "registryFileHashes": { + "https://bcr.bazel.build/bazel_registry.json": "8a28e4aff06ee60aed2a8c281907fb8bcbf3b753c91fb5a5c57da3215d5b3497", + "https://bcr.bazel.build/modules/abseil-cpp/20210324.2/MODULE.bazel": "7cd0312e064fde87c8d1cd79ba06c876bd23630c83466e9500321be55c96ace2", + "https://bcr.bazel.build/modules/abseil-cpp/20211102.0/MODULE.bazel": "70390338f7a5106231d20620712f7cccb659cd0e9d073d1991c038eb9fc57589", + "https://bcr.bazel.build/modules/abseil-cpp/20230125.1/MODULE.bazel": "89047429cb0207707b2dface14ba7f8df85273d484c2572755be4bab7ce9c3a0", + "https://bcr.bazel.build/modules/abseil-cpp/20230802.0.bcr.1/MODULE.bazel": "1c8cec495288dccd14fdae6e3f95f772c1c91857047a098fad772034264cc8cb", + "https://bcr.bazel.build/modules/abseil-cpp/20230802.0/MODULE.bazel": "d253ae36a8bd9ee3c5955384096ccb6baf16a1b1e93e858370da0a3b94f77c16", + "https://bcr.bazel.build/modules/abseil-cpp/20230802.1/MODULE.bazel": "fa92e2eb41a04df73cdabeec37107316f7e5272650f81d6cc096418fe647b915", + "https://bcr.bazel.build/modules/abseil-cpp/20240116.1/MODULE.bazel": "37bcdb4440fbb61df6a1c296ae01b327f19e9bb521f9b8e26ec854b6f97309ed", + "https://bcr.bazel.build/modules/abseil-cpp/20240116.2/MODULE.bazel": "73939767a4686cd9a520d16af5ab440071ed75cec1a876bf2fcfaf1f71987a16", + "https://bcr.bazel.build/modules/abseil-cpp/20250127.0/MODULE.bazel": "d1086e248cda6576862b4b3fe9ad76a214e08c189af5b42557a6e1888812c5d5", + "https://bcr.bazel.build/modules/abseil-cpp/20250127.1/MODULE.bazel": "c4a89e7ceb9bf1e25cf84a9f830ff6b817b72874088bf5141b314726e46a57c1", + "https://bcr.bazel.build/modules/abseil-cpp/20250512.1/MODULE.bazel": "d209fdb6f36ffaf61c509fcc81b19e81b411a999a934a032e10cd009a0226215", + "https://bcr.bazel.build/modules/abseil-cpp/20250814.1/MODULE.bazel": "51f2312901470cdab0dbdf3b88c40cd21c62a7ed58a3de45b365ddc5b11bcab2", + "https://bcr.bazel.build/modules/abseil-cpp/20250814.1/source.json": "cea3901d7e299da7320700abbaafe57a65d039f10d0d7ea601c4a66938ea4b0c", + "https://bcr.bazel.build/modules/abseil-py/2.1.0/MODULE.bazel": "5ebe5bf853769c65707e5c28f216798f7a4b1042015e6a36e6d03094d94bec8a", + "https://bcr.bazel.build/modules/abseil-py/2.1.0/source.json": "0e8fc4f088ce07099c1cd6594c20c7ddbb48b4b3c0849b7d94ba94be88ff042b", + "https://bcr.bazel.build/modules/apple_rules_lint/0.4.0/MODULE.bazel": "c59831c3a5389430516203777816527f257329a5da363994e1d62b9ae6729f71", + "https://bcr.bazel.build/modules/apple_rules_lint/0.4.0/source.json": "105883202602181f43f109372e1b9ea19e89bbe3bce4bc1fe9bb0baa51eb61ae", + "https://bcr.bazel.build/modules/apple_support/1.11.1/MODULE.bazel": "1843d7cd8a58369a444fc6000e7304425fba600ff641592161d9f15b179fb896", + "https://bcr.bazel.build/modules/apple_support/1.15.1/MODULE.bazel": "a0556fefca0b1bb2de8567b8827518f94db6a6e7e7d632b4c48dc5f865bc7c85", + "https://bcr.bazel.build/modules/apple_support/1.21.0/MODULE.bazel": "ac1824ed5edf17dee2fdd4927ada30c9f8c3b520be1b5fd02a5da15bc10bff3e", + "https://bcr.bazel.build/modules/apple_support/1.21.1/MODULE.bazel": "5809fa3efab15d1f3c3c635af6974044bac8a4919c62238cce06acee8a8c11f1", + "https://bcr.bazel.build/modules/apple_support/1.24.2/MODULE.bazel": "0e62471818affb9f0b26f128831d5c40b074d32e6dda5a0d3852847215a41ca4", + "https://bcr.bazel.build/modules/apple_support/1.24.2/source.json": "2c22c9827093250406c5568da6c54e6fdf0ef06238def3d99c71b12feb057a8d", + "https://bcr.bazel.build/modules/aspect_bazel_lib/2.14.0/MODULE.bazel": "2b31ffcc9bdc8295b2167e07a757dbbc9ac8906e7028e5170a3708cecaac119f", + "https://bcr.bazel.build/modules/aspect_bazel_lib/2.19.3/MODULE.bazel": "253d739ba126f62a5767d832765b12b59e9f8d2bc88cc1572f4a73e46eb298ca", + "https://bcr.bazel.build/modules/aspect_bazel_lib/2.19.3/source.json": "ffab9254c65ba945f8369297ad97ca0dec213d3adc6e07877e23a48624a8b456", + "https://bcr.bazel.build/modules/aspect_bazel_lib/2.7.2/MODULE.bazel": "780d1a6522b28f5edb7ea09630748720721dfe27690d65a2d33aa7509de77e07", + "https://bcr.bazel.build/modules/aspect_bazel_lib/2.8.1/MODULE.bazel": "812d2dd42f65dca362152101fbec418029cc8fd34cbad1a2fde905383d705838", + "https://bcr.bazel.build/modules/bazel_features/1.1.0/MODULE.bazel": "cfd42ff3b815a5f39554d97182657f8c4b9719568eb7fded2b9135f084bf760b", + "https://bcr.bazel.build/modules/bazel_features/1.1.1/MODULE.bazel": "27b8c79ef57efe08efccbd9dd6ef70d61b4798320b8d3c134fd571f78963dbcd", + "https://bcr.bazel.build/modules/bazel_features/1.10.0/MODULE.bazel": "f75e8807570484a99be90abcd52b5e1f390362c258bcb73106f4544957a48101", + "https://bcr.bazel.build/modules/bazel_features/1.11.0/MODULE.bazel": "f9382337dd5a474c3b7d334c2f83e50b6eaedc284253334cf823044a26de03e8", + "https://bcr.bazel.build/modules/bazel_features/1.13.0/MODULE.bazel": "c14c33c7c3c730612bdbe14ebbb5e61936b6f11322ea95a6e91cd1ba962f94df", + "https://bcr.bazel.build/modules/bazel_features/1.15.0/MODULE.bazel": "d38ff6e517149dc509406aca0db3ad1efdd890a85e049585b7234d04238e2a4d", + "https://bcr.bazel.build/modules/bazel_features/1.17.0/MODULE.bazel": "039de32d21b816b47bd42c778e0454217e9c9caac4a3cf8e15c7231ee3ddee4d", + "https://bcr.bazel.build/modules/bazel_features/1.18.0/MODULE.bazel": "1be0ae2557ab3a72a57aeb31b29be347bcdc5d2b1eb1e70f39e3851a7e97041a", + "https://bcr.bazel.build/modules/bazel_features/1.19.0/MODULE.bazel": "59adcdf28230d220f0067b1f435b8537dd033bfff8db21335ef9217919c7fb58", + "https://bcr.bazel.build/modules/bazel_features/1.21.0/MODULE.bazel": "675642261665d8eea09989aa3b8afb5c37627f1be178382c320d1b46afba5e3b", + "https://bcr.bazel.build/modules/bazel_features/1.23.0/MODULE.bazel": "fd1ac84bc4e97a5a0816b7fd7d4d4f6d837b0047cf4cbd81652d616af3a6591a", + "https://bcr.bazel.build/modules/bazel_features/1.25.0/MODULE.bazel": "e2e60a10a6da64bbf533f15ca652bf61a033e41c2ed734d79a9a08ba87f68c1a", + "https://bcr.bazel.build/modules/bazel_features/1.27.0/MODULE.bazel": "621eeee06c4458a9121d1f104efb80f39d34deff4984e778359c60eaf1a8cb65", + "https://bcr.bazel.build/modules/bazel_features/1.28.0/MODULE.bazel": "4b4200e6cbf8fa335b2c3f43e1d6ef3e240319c33d43d60cc0fbd4b87ece299d", + "https://bcr.bazel.build/modules/bazel_features/1.3.0/MODULE.bazel": "cdcafe83ec318cda34e02948e81d790aab8df7a929cec6f6969f13a489ccecd9", + "https://bcr.bazel.build/modules/bazel_features/1.30.0/MODULE.bazel": "a14b62d05969a293b80257e72e597c2da7f717e1e69fa8b339703ed6731bec87", + "https://bcr.bazel.build/modules/bazel_features/1.33.0/MODULE.bazel": "8b8dc9d2a4c88609409c3191165bccec0e4cb044cd7a72ccbe826583303459f6", + "https://bcr.bazel.build/modules/bazel_features/1.4.1/MODULE.bazel": "e45b6bb2350aff3e442ae1111c555e27eac1d915e77775f6fdc4b351b758b5d7", + "https://bcr.bazel.build/modules/bazel_features/1.42.1/MODULE.bazel": "275a59b5406ff18c01739860aa70ad7ccb3cfb474579411decca11c93b951080", + "https://bcr.bazel.build/modules/bazel_features/1.42.1/source.json": "fcd4396b2df85f64f2b3bb436ad870793ecf39180f1d796f913cc9276d355309", + "https://bcr.bazel.build/modules/bazel_features/1.9.0/MODULE.bazel": "885151d58d90d8d9c811eb75e3288c11f850e1d6b481a8c9f766adee4712358b", + "https://bcr.bazel.build/modules/bazel_features/1.9.1/MODULE.bazel": "8f679097876a9b609ad1f60249c49d68bfab783dd9be012faf9d82547b14815a", + "https://bcr.bazel.build/modules/bazel_lib/3.0.0/MODULE.bazel": "22b70b80ac89ad3f3772526cd9feee2fa412c2b01933fea7ed13238a448d370d", + "https://bcr.bazel.build/modules/bazel_lib/3.0.0/source.json": "895f21909c6fba01d7c17914bb6c8e135982275a1b18cdaa4e62272217ef1751", + "https://bcr.bazel.build/modules/bazel_skylib/1.0.3/MODULE.bazel": "bcb0fd896384802d1ad283b4e4eb4d718eebd8cb820b0a2c3a347fb971afd9d8", + "https://bcr.bazel.build/modules/bazel_skylib/1.1.1/MODULE.bazel": "1add3e7d93ff2e6998f9e118022c84d163917d912f5afafb3058e3d2f1545b5e", + "https://bcr.bazel.build/modules/bazel_skylib/1.2.0/MODULE.bazel": "44fe84260e454ed94ad326352a698422dbe372b21a1ac9f3eab76eb531223686", + "https://bcr.bazel.build/modules/bazel_skylib/1.2.1/MODULE.bazel": "f35baf9da0efe45fa3da1696ae906eea3d615ad41e2e3def4aeb4e8bc0ef9a7a", + "https://bcr.bazel.build/modules/bazel_skylib/1.3.0/MODULE.bazel": "20228b92868bf5cfc41bda7afc8a8ba2a543201851de39d990ec957b513579c5", + "https://bcr.bazel.build/modules/bazel_skylib/1.4.1/MODULE.bazel": "a0dcb779424be33100dcae821e9e27e4f2901d9dfd5333efe5ac6a8d7ab75e1d", + "https://bcr.bazel.build/modules/bazel_skylib/1.4.2/MODULE.bazel": "3bd40978e7a1fac911d5989e6b09d8f64921865a45822d8b09e815eaa726a651", + "https://bcr.bazel.build/modules/bazel_skylib/1.5.0/MODULE.bazel": "32880f5e2945ce6a03d1fbd588e9198c0a959bb42297b2cfaf1685b7bc32e138", + "https://bcr.bazel.build/modules/bazel_skylib/1.6.1/MODULE.bazel": "8fdee2dbaace6c252131c00e1de4b165dc65af02ea278476187765e1a617b917", + "https://bcr.bazel.build/modules/bazel_skylib/1.7.0/MODULE.bazel": "0db596f4563de7938de764cc8deeabec291f55e8ec15299718b93c4423e9796d", + "https://bcr.bazel.build/modules/bazel_skylib/1.7.1/MODULE.bazel": "3120d80c5861aa616222ec015332e5f8d3171e062e3e804a2a0253e1be26e59b", + "https://bcr.bazel.build/modules/bazel_skylib/1.8.1/MODULE.bazel": "88ade7293becda963e0e3ea33e7d54d3425127e0a326e0d17da085a5f1f03ff6", + "https://bcr.bazel.build/modules/bazel_skylib/1.8.2/MODULE.bazel": "69ad6927098316848b34a9142bcc975e018ba27f08c4ff403f50c1b6e646ca67", + "https://bcr.bazel.build/modules/bazel_skylib/1.8.2/source.json": "34a3c8bcf233b835eb74be9d628899bb32999d3e0eadef1947a0a562a2b16ffb", + "https://bcr.bazel.build/modules/bazel_worker_api/0.0.1/MODULE.bazel": "02a13b77321773b2042e70ee5e4c5e099c8ddee4cf2da9cd420442c36938d4bd", + "https://bcr.bazel.build/modules/bazel_worker_api/0.0.4/MODULE.bazel": "460aa12d01231a80cce03c548287b433b321d205b0028ae596728c35e5ee442e", + "https://bcr.bazel.build/modules/bazel_worker_api/0.0.8/MODULE.bazel": "396c1ef53835aafe3d42ce6619080531ee770648303731f16cfaa33fa056bf0c", + "https://bcr.bazel.build/modules/bazel_worker_api/0.0.8/source.json": "abaf8ac9d2ab2f47bda9af4c0c080ff7907378888e1f4bc62a0539dd13ba61e8", + "https://bcr.bazel.build/modules/bazel_worker_java/0.0.4/MODULE.bazel": "82494a01018bb7ef06d4a17ec4cd7a758721f10eb8b6c820a818e70d669500db", + "https://bcr.bazel.build/modules/bazel_worker_java/0.0.8/MODULE.bazel": "e76479eae70bd4e8f5f4c2dfc5d03ab971cfb18750246c7b3f3454c5c2ee6629", + "https://bcr.bazel.build/modules/bazel_worker_java/0.0.8/source.json": "9395c4679444bc47bf7e51a710366a4480aa371c6f6bed01868e2fabcf11acec", + "https://bcr.bazel.build/modules/buildozer/8.5.1/MODULE.bazel": "a35d9561b3fc5b18797c330793e99e3b834a473d5fbd3d7d7634aafc9bdb6f8f", + "https://bcr.bazel.build/modules/buildozer/8.5.1/source.json": "e3386e6ff4529f2442800dee47ad28d3e6487f36a1f75ae39ae56c70f0cd2fbd", + "https://bcr.bazel.build/modules/contrib_rules_jvm/0.33.0/MODULE.bazel": "1aba514585748372ee392484b2645f0bbcb13ad4271d5b7cace018280f15bae1", + "https://bcr.bazel.build/modules/contrib_rules_jvm/0.33.0/source.json": "e52d62ce2a2b8a513d6afe9178acc06a4349c9b0b4c0934d59085ed9df4b4de0", + "https://bcr.bazel.build/modules/gazelle/0.32.0/MODULE.bazel": "b499f58a5d0d3537f3cf5b76d8ada18242f64ec474d8391247438bf04f58c7b8", + "https://bcr.bazel.build/modules/gazelle/0.33.0/MODULE.bazel": "a13a0f279b462b784fb8dd52a4074526c4a2afe70e114c7d09066097a46b3350", + "https://bcr.bazel.build/modules/gazelle/0.34.0/MODULE.bazel": "abdd8ce4d70978933209db92e436deb3a8b737859e9354fb5fd11fb5c2004c8a", + "https://bcr.bazel.build/modules/gazelle/0.36.0/MODULE.bazel": "e375d5d6e9a6ca59b0cb38b0540bc9a05b6aa926d322f2de268ad267a2ee74c0", + "https://bcr.bazel.build/modules/gazelle/0.40.0/MODULE.bazel": "42ba5378ebe845fca43989a53186ab436d956db498acde790685fe0e8f9c6146", + "https://bcr.bazel.build/modules/gazelle/0.42.0/MODULE.bazel": "fa140a7c019f3a22779ba7c6132ffff9d2d10a51dba2f3304dee61523d11fef4", + "https://bcr.bazel.build/modules/gazelle/0.47.0/MODULE.bazel": "b61bb007c4efad134aa30ee7f4a8e2a39b22aa5685f005edaa022fbd1de43ebc", + "https://bcr.bazel.build/modules/gazelle/0.47.0/source.json": "aeb2e5df14b7fb298625d75d08b9c65bdb0b56014c5eb89da9e5dd0572280ae6", + "https://bcr.bazel.build/modules/google_benchmark/1.8.2/MODULE.bazel": "a70cf1bba851000ba93b58ae2f6d76490a9feb74192e57ab8e8ff13c34ec50cb", + "https://bcr.bazel.build/modules/googletest/1.11.0/MODULE.bazel": "3a83f095183f66345ca86aa13c58b59f9f94a2f81999c093d4eeaa2d262d12f4", + "https://bcr.bazel.build/modules/googletest/1.14.0.bcr.1/MODULE.bazel": "22c31a561553727960057361aa33bf20fb2e98584bc4fec007906e27053f80c6", + "https://bcr.bazel.build/modules/googletest/1.14.0/MODULE.bazel": "cfbcbf3e6eac06ef9d85900f64424708cc08687d1b527f0ef65aa7517af8118f", + "https://bcr.bazel.build/modules/googletest/1.15.2/MODULE.bazel": "6de1edc1d26cafb0ea1a6ab3f4d4192d91a312fd2d360b63adaa213cd00b2108", + "https://bcr.bazel.build/modules/googletest/1.17.0/MODULE.bazel": "dbec758171594a705933a29fcf69293d2468c49ec1f2ebca65c36f504d72df46", + "https://bcr.bazel.build/modules/googletest/1.17.0/source.json": "38e4454b25fc30f15439c0378e57909ab1fd0a443158aa35aec685da727cd713", + "https://bcr.bazel.build/modules/jq.bzl/0.1.0/MODULE.bazel": "2ce69b1af49952cd4121a9c3055faa679e748ce774c7f1fda9657f936cae902f", + "https://bcr.bazel.build/modules/jq.bzl/0.1.0/source.json": "746bf13cac0860f091df5e4911d0c593971cd8796b5ad4e809b2f8e133eee3d5", + "https://bcr.bazel.build/modules/jsoncpp/1.9.5/MODULE.bazel": "31271aedc59e815656f5736f282bb7509a97c7ecb43e927ac1a37966e0578075", + "https://bcr.bazel.build/modules/jsoncpp/1.9.6/MODULE.bazel": "2f8d20d3b7d54143213c4dfc3d98225c42de7d666011528dc8fe91591e2e17b0", + "https://bcr.bazel.build/modules/jsoncpp/1.9.6/source.json": "a04756d367a2126c3541682864ecec52f92cdee80a35735a3cb249ce015ca000", + "https://bcr.bazel.build/modules/libpfm/4.11.0/MODULE.bazel": "45061ff025b301940f1e30d2c16bea596c25b176c8b6b3087e92615adbd52902", + "https://bcr.bazel.build/modules/nlohmann_json/3.6.1/MODULE.bazel": "6f7b417dcc794d9add9e556673ad25cb3ba835224290f4f848f8e2db1e1fca74", + "https://bcr.bazel.build/modules/nlohmann_json/3.6.1/source.json": "f448c6e8963fdfa7eb831457df83ad63d3d6355018f6574fb017e8169deb43a9", + "https://bcr.bazel.build/modules/package_metadata/0.0.2/MODULE.bazel": "fb8d25550742674d63d7b250063d4580ca530499f045d70748b1b142081ebb92", + "https://bcr.bazel.build/modules/package_metadata/0.0.3/MODULE.bazel": "77890552ecea9e284b5424c9de827a58099348763a4359e975c359a83d4faa83", + "https://bcr.bazel.build/modules/package_metadata/0.0.5/MODULE.bazel": "ef4f9439e3270fdd6b9fd4dbc3d2f29d13888e44c529a1b243f7a31dfbc2e8e4", + "https://bcr.bazel.build/modules/package_metadata/0.0.7/MODULE.bazel": "7adb03933fc8401f495800cf4eafcff0edc6da0ff55c7db223ef69d19f689486", + "https://bcr.bazel.build/modules/package_metadata/0.0.7/source.json": "50639625e937b56115012674c797cca7a05a96b4878c87d803c13dc2b31de8a0", + "https://bcr.bazel.build/modules/platforms/0.0.10/MODULE.bazel": "8cb8efaf200bdeb2150d93e162c40f388529a25852b332cec879373771e48ed5", + "https://bcr.bazel.build/modules/platforms/0.0.11/MODULE.bazel": "0daefc49732e227caa8bfa834d65dc52e8cc18a2faf80df25e8caea151a9413f", + "https://bcr.bazel.build/modules/platforms/0.0.4/MODULE.bazel": "9b328e31ee156f53f3c416a64f8491f7eb731742655a47c9eec4703a71644aee", + "https://bcr.bazel.build/modules/platforms/0.0.5/MODULE.bazel": "5733b54ea419d5eaf7997054bb55f6a1d0b5ff8aedf0176fef9eea44f3acda37", + "https://bcr.bazel.build/modules/platforms/0.0.6/MODULE.bazel": "ad6eeef431dc52aefd2d77ed20a4b353f8ebf0f4ecdd26a807d2da5aa8cd0615", + "https://bcr.bazel.build/modules/platforms/0.0.7/MODULE.bazel": "72fd4a0ede9ee5c021f6a8dd92b503e089f46c227ba2813ff183b71616034814", + "https://bcr.bazel.build/modules/platforms/0.0.8/MODULE.bazel": "9f142c03e348f6d263719f5074b21ef3adf0b139ee4c5133e2aa35664da9eb2d", + "https://bcr.bazel.build/modules/platforms/0.0.9/MODULE.bazel": "4a87a60c927b56ddd67db50c89acaa62f4ce2a1d2149ccb63ffd871d5ce29ebc", + "https://bcr.bazel.build/modules/platforms/1.0.0/MODULE.bazel": "f05feb42b48f1b3c225e4ccf351f367be0371411a803198ec34a389fb22aa580", + "https://bcr.bazel.build/modules/platforms/1.0.0/source.json": "f4ff1fd412e0246fd38c82328eb209130ead81d62dcd5a9e40910f867f733d96", + "https://bcr.bazel.build/modules/protobuf/21.7/MODULE.bazel": "a5a29bb89544f9b97edce05642fac225a808b5b7be74038ea3640fae2f8e66a7", + "https://bcr.bazel.build/modules/protobuf/23.1/MODULE.bazel": "88b393b3eb4101d18129e5db51847cd40a5517a53e81216144a8c32dfeeca52a", + "https://bcr.bazel.build/modules/protobuf/24.4/MODULE.bazel": "7bc7ce5f2abf36b3b7b7c8218d3acdebb9426aeb35c2257c96445756f970eb12", + "https://bcr.bazel.build/modules/protobuf/27.0/MODULE.bazel": "7873b60be88844a0a1d8f80b9d5d20cfbd8495a689b8763e76c6372998d3f64c", + "https://bcr.bazel.build/modules/protobuf/27.1/MODULE.bazel": "703a7b614728bb06647f965264967a8ef1c39e09e8f167b3ca0bb1fd80449c0d", + "https://bcr.bazel.build/modules/protobuf/27.2/MODULE.bazel": "32450b50673882e4c8c3d10a83f3bc82161b213ed2f80d17e38bece8f165c295", + "https://bcr.bazel.build/modules/protobuf/29.0-rc2.bcr.1/MODULE.bazel": "52f4126f63a2f0bbf36b99c2a87648f08467a4eaf92ba726bc7d6a500bbf770c", + "https://bcr.bazel.build/modules/protobuf/29.0-rc2/MODULE.bazel": "6241d35983510143049943fc0d57937937122baf1b287862f9dc8590fc4c37df", + "https://bcr.bazel.build/modules/protobuf/29.0-rc3/MODULE.bazel": "33c2dfa286578573afc55a7acaea3cada4122b9631007c594bf0729f41c8de92", + "https://bcr.bazel.build/modules/protobuf/29.0/MODULE.bazel": "319dc8bf4c679ff87e71b1ccfb5a6e90a6dbc4693501d471f48662ac46d04e4e", + "https://bcr.bazel.build/modules/protobuf/29.1/MODULE.bazel": "557c3457560ff49e122ed76c0bc3397a64af9574691cb8201b4e46d4ab2ecb95", + "https://bcr.bazel.build/modules/protobuf/29.3/MODULE.bazel": "77480eea5fb5541903e49683f24dc3e09f4a79e0eea247414887bb9fc0066e94", + "https://bcr.bazel.build/modules/protobuf/3.19.0/MODULE.bazel": "6b5fbb433f760a99a22b18b6850ed5784ef0e9928a72668b66e4d7ccd47db9b0", + "https://bcr.bazel.build/modules/protobuf/3.19.2/MODULE.bazel": "532ffe5f2186b69fdde039efe6df13ba726ff338c6bc82275ad433013fa10573", + "https://bcr.bazel.build/modules/protobuf/3.19.6/MODULE.bazel": "9233edc5e1f2ee276a60de3eaa47ac4132302ef9643238f23128fea53ea12858", + "https://bcr.bazel.build/modules/protobuf/31.1/MODULE.bazel": "379a389bb330b7b8c1cdf331cc90bf3e13de5614799b3b52cdb7c6f389f6b38e", + "https://bcr.bazel.build/modules/protobuf/32.1/MODULE.bazel": "89cd2866a9cb07fee9ff74c41ceace11554f32e0d849de4e23ac55515cfada4d", + "https://bcr.bazel.build/modules/protobuf/33.4/MODULE.bazel": "114775b816b38b6d0ca620450d6b02550c60ceedfdc8d9a229833b34a223dc42", + "https://bcr.bazel.build/modules/protobuf/33.4/source.json": "555f8686b4c7d6b5ba731fbea13bf656b4bfd9a7ff629c1d9d3f6e1d6155de79", + "https://bcr.bazel.build/modules/pybind11_bazel/2.11.1/MODULE.bazel": "88af1c246226d87e65be78ed49ecd1e6f5e98648558c14ce99176da041dc378e", + "https://bcr.bazel.build/modules/pybind11_bazel/2.12.0/MODULE.bazel": "e6f4c20442eaa7c90d7190d8dc539d0ab422f95c65a57cc59562170c58ae3d34", + "https://bcr.bazel.build/modules/pybind11_bazel/2.12.0/source.json": "6900fdc8a9e95866b8c0d4ad4aba4d4236317b5c1cd04c502df3f0d33afed680", + "https://bcr.bazel.build/modules/re2/2023-09-01/MODULE.bazel": "cb3d511531b16cfc78a225a9e2136007a48cf8a677e4264baeab57fe78a80206", + "https://bcr.bazel.build/modules/re2/2024-07-02.bcr.1/MODULE.bazel": "b4963dda9b31080be1905ef085ecd7dd6cd47c05c79b9cdf83ade83ab2ab271a", + "https://bcr.bazel.build/modules/re2/2024-07-02.bcr.1/source.json": "2ff292be6ef3340325ce8a045ecc326e92cbfab47c7cbab4bd85d28971b97ac4", + "https://bcr.bazel.build/modules/re2/2024-07-02/MODULE.bazel": "0eadc4395959969297cbcf31a249ff457f2f1d456228c67719480205aa306daa", + "https://bcr.bazel.build/modules/rules_android/0.1.1/MODULE.bazel": "48809ab0091b07ad0182defb787c4c5328bd3a278938415c00a7b69b50c4d3a8", + "https://bcr.bazel.build/modules/rules_android/0.6.4/MODULE.bazel": "b4cde12d506dd65d82b2be39761f49f5797303343a3d5b4ee191c0cdf9ef387c", + "https://bcr.bazel.build/modules/rules_android/0.6.6/MODULE.bazel": "b0fb569752aab65ab1a9db0a8f6cfaf5aa1754965e17e95dcf0e4d88e192a68d", + "https://bcr.bazel.build/modules/rules_android/0.7.1/MODULE.bazel": "a806fc382a774252f228a40e3b11b9fcc6276f8778c7fb33e9f72937c6258363", + "https://bcr.bazel.build/modules/rules_android/0.7.1/source.json": "151440aed3f0f73a00d4ed5cec5d31f63a6fef9b95d8fab1eb1810150fa525f2", + "https://bcr.bazel.build/modules/rules_apple/3.16.0/MODULE.bazel": "0d1caf0b8375942ce98ea944be754a18874041e4e0459401d925577624d3a54a", + "https://bcr.bazel.build/modules/rules_apple/4.1.0/MODULE.bazel": "76e10fd4a48038d3fc7c5dc6e63b7063bbf5304a2e3bd42edda6ec660eebea68", + "https://bcr.bazel.build/modules/rules_apple/4.1.0/source.json": "8ee81e1708756f81b343a5eb2b2f0b953f1d25c4ab3d4a68dc02754872e80715", + "https://bcr.bazel.build/modules/rules_cc/0.0.1/MODULE.bazel": "cb2aa0747f84c6c3a78dad4e2049c154f08ab9d166b1273835a8174940365647", + "https://bcr.bazel.build/modules/rules_cc/0.0.10/MODULE.bazel": "ec1705118f7eaedd6e118508d3d26deba2a4e76476ada7e0e3965211be012002", + "https://bcr.bazel.build/modules/rules_cc/0.0.13/MODULE.bazel": "0e8529ed7b323dad0775ff924d2ae5af7640b23553dfcd4d34344c7e7a867191", + "https://bcr.bazel.build/modules/rules_cc/0.0.15/MODULE.bazel": "6704c35f7b4a72502ee81f61bf88706b54f06b3cbe5558ac17e2e14666cd5dcc", + "https://bcr.bazel.build/modules/rules_cc/0.0.16/MODULE.bazel": "7661303b8fc1b4d7f532e54e9d6565771fea666fbdf839e0a86affcd02defe87", + "https://bcr.bazel.build/modules/rules_cc/0.0.17/MODULE.bazel": "2ae1d8f4238ec67d7185d8861cb0a2cdf4bc608697c331b95bf990e69b62e64a", + "https://bcr.bazel.build/modules/rules_cc/0.0.2/MODULE.bazel": "6915987c90970493ab97393024c156ea8fb9f3bea953b2f3ec05c34f19b5695c", + "https://bcr.bazel.build/modules/rules_cc/0.0.6/MODULE.bazel": "abf360251023dfe3efcef65ab9d56beefa8394d4176dd29529750e1c57eaa33f", + "https://bcr.bazel.build/modules/rules_cc/0.0.8/MODULE.bazel": "964c85c82cfeb6f3855e6a07054fdb159aced38e99a5eecf7bce9d53990afa3e", + "https://bcr.bazel.build/modules/rules_cc/0.0.9/MODULE.bazel": "836e76439f354b89afe6a911a7adf59a6b2518fafb174483ad78a2a2fde7b1c5", + "https://bcr.bazel.build/modules/rules_cc/0.1.1/MODULE.bazel": "2f0222a6f229f0bf44cd711dc13c858dad98c62d52bd51d8fc3a764a83125513", + "https://bcr.bazel.build/modules/rules_cc/0.1.2/MODULE.bazel": "557ddc3a96858ec0d465a87c0a931054d7dcfd6583af2c7ed3baf494407fd8d0", + "https://bcr.bazel.build/modules/rules_cc/0.1.5/MODULE.bazel": "88dfc9361e8b5ae1008ac38f7cdfd45ad738e4fa676a3ad67d19204f045a1fd8", + "https://bcr.bazel.build/modules/rules_cc/0.2.0/MODULE.bazel": "b5c17f90458caae90d2ccd114c81970062946f49f355610ed89bebf954f5783c", + "https://bcr.bazel.build/modules/rules_cc/0.2.13/MODULE.bazel": "eecdd666eda6be16a8d9dc15e44b5c75133405e820f620a234acc4b1fdc5aa37", + "https://bcr.bazel.build/modules/rules_cc/0.2.14/MODULE.bazel": "353c99ed148887ee89c54a17d4100ae7e7e436593d104b668476019023b58df8", + "https://bcr.bazel.build/modules/rules_cc/0.2.17/MODULE.bazel": "1849602c86cb60da8613d2de887f9566a6d354a6df6d7009f9d04a14402f9a84", + "https://bcr.bazel.build/modules/rules_cc/0.2.17/source.json": "3832f45d145354049137c0090df04629d9c2b5493dc5c2bf46f1834040133a07", + "https://bcr.bazel.build/modules/rules_cc/0.2.8/MODULE.bazel": "f1df20f0bf22c28192a794f29b501ee2018fa37a3862a1a2132ae2940a23a642", + "https://bcr.bazel.build/modules/rules_foreign_cc/0.9.0/MODULE.bazel": "c9e8c682bf75b0e7c704166d79b599f93b72cfca5ad7477df596947891feeef6", + "https://bcr.bazel.build/modules/rules_fuzzing/0.5.2/MODULE.bazel": "40c97d1144356f52905566c55811f13b299453a14ac7769dfba2ac38192337a8", + "https://bcr.bazel.build/modules/rules_go/0.41.0/MODULE.bazel": "55861d8e8bb0e62cbd2896f60ff303f62ffcb0eddb74ecb0e5c0cbe36fc292c8", + "https://bcr.bazel.build/modules/rules_go/0.42.0/MODULE.bazel": "8cfa875b9aa8c6fce2b2e5925e73c1388173ea3c32a0db4d2b4804b453c14270", + "https://bcr.bazel.build/modules/rules_go/0.46.0/MODULE.bazel": "3477df8bdcc49e698b9d25f734c4f3a9f5931ff34ee48a2c662be168f5f2d3fd", + "https://bcr.bazel.build/modules/rules_go/0.50.1/MODULE.bazel": "b91a308dc5782bb0a8021ad4330c81fea5bda77f96b9e4c117b9b9c8f6665ee0", + "https://bcr.bazel.build/modules/rules_go/0.51.0-rc2/MODULE.bazel": "edfc3a9cea7bedb0eaaff37b0d7817c1a4bf72b3c615580b0ffcee6c52690fd4", + "https://bcr.bazel.build/modules/rules_go/0.52.0/MODULE.bazel": "0cf080a2706aa8fc9abf64286cee60fdf0238db37b7f1793b0f7d550d59ea3ae", + "https://bcr.bazel.build/modules/rules_go/0.53.0/MODULE.bazel": "a4ed760d3ac0dbc0d7b967631a9a3fd9100d28f7d9fcf214b4df87d4bfff5f9a", + "https://bcr.bazel.build/modules/rules_go/0.59.0/MODULE.bazel": "b7e43e7414a3139a7547d1b4909b29085fbe5182b6c58cbe1ed4c6272815aeae", + "https://bcr.bazel.build/modules/rules_go/0.59.0/source.json": "1df17bb7865cfc029492c30163cee891d0dd8658ea0d5bfdf252c4b6db5c1ef6", + "https://bcr.bazel.build/modules/rules_java/4.0.0/MODULE.bazel": "5a78a7ae82cd1a33cef56dc578c7d2a46ed0dca12643ee45edbb8417899e6f74", + "https://bcr.bazel.build/modules/rules_java/5.3.5/MODULE.bazel": "a4ec4f2db570171e3e5eb753276ee4b389bae16b96207e9d3230895c99644b86", + "https://bcr.bazel.build/modules/rules_java/6.3.0/MODULE.bazel": "a97c7678c19f236a956ad260d59c86e10a463badb7eb2eda787490f4c969b963", + "https://bcr.bazel.build/modules/rules_java/6.5.2/MODULE.bazel": "1d440d262d0e08453fa0c4d8f699ba81609ed0e9a9a0f02cd10b3e7942e61e31", + "https://bcr.bazel.build/modules/rules_java/7.1.0/MODULE.bazel": "30d9135a2b6561c761bd67bd4990da591e6bdc128790ce3e7afd6a3558b2fb64", + "https://bcr.bazel.build/modules/rules_java/7.10.0/MODULE.bazel": "530c3beb3067e870561739f1144329a21c851ff771cd752a49e06e3dc9c2e71a", + "https://bcr.bazel.build/modules/rules_java/7.12.2/MODULE.bazel": "579c505165ee757a4280ef83cda0150eea193eed3bef50b1004ba88b99da6de6", + "https://bcr.bazel.build/modules/rules_java/7.2.0/MODULE.bazel": "06c0334c9be61e6cef2c8c84a7800cef502063269a5af25ceb100b192453d4ab", + "https://bcr.bazel.build/modules/rules_java/7.4.0/MODULE.bazel": "a592852f8a3dd539e82ee6542013bf2cadfc4c6946be8941e189d224500a8934", + "https://bcr.bazel.build/modules/rules_java/7.6.1/MODULE.bazel": "2f14b7e8a1aa2f67ae92bc69d1ec0fa8d9f827c4e17ff5e5f02e91caa3b2d0fe", + "https://bcr.bazel.build/modules/rules_java/8.13.0/MODULE.bazel": "0444ebf737d144cf2bb2ccb368e7f1cce735264285f2a3711785827c1686625e", + "https://bcr.bazel.build/modules/rules_java/8.15.2/MODULE.bazel": "5cc6698c822b2f9ef90ca5558599851bed8c3b13f1f8eb140d9bfec638d2acb4", + "https://bcr.bazel.build/modules/rules_java/8.3.2/MODULE.bazel": "7336d5511ad5af0b8615fdc7477535a2e4e723a357b6713af439fe8cf0195017", + "https://bcr.bazel.build/modules/rules_java/8.5.1/MODULE.bazel": "d8a9e38cc5228881f7055a6079f6f7821a073df3744d441978e7a43e20226939", + "https://bcr.bazel.build/modules/rules_java/8.6.0/MODULE.bazel": "9c064c434606d75a086f15ade5edb514308cccd1544c2b2a89bbac4310e41c71", + "https://bcr.bazel.build/modules/rules_java/8.6.1/MODULE.bazel": "f4808e2ab5b0197f094cabce9f4b006a27766beb6a9975931da07099560ca9c2", + "https://bcr.bazel.build/modules/rules_java/8.6.3/MODULE.bazel": "e90505b7a931d194245ffcfb6ff4ca8ef9d46b4e830d12e64817752e0198e2ed", + "https://bcr.bazel.build/modules/rules_java/8.9.0/MODULE.bazel": "e17c876cb53dcd817b7b7f0d2985b710610169729e8c371b2221cacdcd3dce4a", + "https://bcr.bazel.build/modules/rules_java/9.1.0/MODULE.bazel": "ee63f27e36a3fada80342869361182f120a9819c74320e8e65b1e04ba0cd7a9d", + "https://bcr.bazel.build/modules/rules_java/9.3.0/MODULE.bazel": "f657c72d65ac449caae9abf2e68e66c0d36f9416848c4c4903d0b3234229e7f2", + "https://bcr.bazel.build/modules/rules_java/9.3.0/source.json": "59ae7e662c3c7042b88bbb42ad12483523e234c65ebe4c51611baa43e85cb248", + "https://bcr.bazel.build/modules/rules_jvm_external/4.4.2/MODULE.bazel": "a56b85e418c83eb1839819f0b515c431010160383306d13ec21959ac412d2fe7", + "https://bcr.bazel.build/modules/rules_jvm_external/5.1/MODULE.bazel": "33f6f999e03183f7d088c9be518a63467dfd0be94a11d0055fe2d210f89aa909", + "https://bcr.bazel.build/modules/rules_jvm_external/5.2/MODULE.bazel": "d9351ba35217ad0de03816ef3ed63f89d411349353077348a45348b096615036", + "https://bcr.bazel.build/modules/rules_jvm_external/6.10/MODULE.bazel": "33e636ca6bc9ee0fa090a38aa33c631ded2d8cf6fead4124181d1b35dc474f7c", + "https://bcr.bazel.build/modules/rules_jvm_external/6.2/MODULE.bazel": "36a6e52487a855f33cb960724eb56547fa87e2c98a0474c3acad94339d7f8e99", + "https://bcr.bazel.build/modules/rules_jvm_external/6.3/MODULE.bazel": "c998e060b85f71e00de5ec552019347c8bca255062c990ac02d051bb80a38df0", + "https://bcr.bazel.build/modules/rules_jvm_external/6.6/MODULE.bazel": "153042249c7060536dc95b6bb9f9bb8063b8a0b0cb7acdb381bddbc2374aed55", + "https://bcr.bazel.build/modules/rules_jvm_external/6.7/MODULE.bazel": "e717beabc4d091ecb2c803c2d341b88590e9116b8bf7947915eeb33aab4f96dd", + "https://bcr.bazel.build/modules/rules_jvm_external/6.9/MODULE.bazel": "07c5db05527db7744a54fcffd653e1550d40e0540207a7f7e6d0a4de5bef8274", + "https://bcr.bazel.build/modules/rules_jvm_external/7.0/MODULE.bazel": "421482bdbcf05709f933c96b867a599deb517f2804ceb3e74511880610cfbf71", + "https://bcr.bazel.build/modules/rules_jvm_external/7.0/source.json": "714cd003eadf5be5c83268311fe8e951db39f802babeaddc536b3560dc8f6faf", + "https://bcr.bazel.build/modules/rules_kotlin/1.9.5/MODULE.bazel": "043a16a572f610558ec2030db3ff0c9938574e7dd9f58bded1bb07c0192ef025", + "https://bcr.bazel.build/modules/rules_kotlin/1.9.6/MODULE.bazel": "d269a01a18ee74d0335450b10f62c9ed81f2321d7958a2934e44272fe82dcef3", + "https://bcr.bazel.build/modules/rules_kotlin/2.1.3/MODULE.bazel": "ce7def6d576aa8d3a9c6d10e13b4d157296229674371f67dbf788dae0afae3d5", + "https://bcr.bazel.build/modules/rules_kotlin/2.2.2/MODULE.bazel": "00d39c5e0fa78cd86193946265bb849e7878c24e44260f9525108428852b315c", + "https://bcr.bazel.build/modules/rules_kotlin/2.2.2/source.json": "7a32c2259c79ae0c9a036121f120de825e3ba5f0f3a209ffbbdccf4dc62489b9", + "https://bcr.bazel.build/modules/rules_license/0.0.3/MODULE.bazel": "627e9ab0247f7d1e05736b59dbb1b6871373de5ad31c3011880b4133cafd4bd0", + "https://bcr.bazel.build/modules/rules_license/0.0.7/MODULE.bazel": "088fbeb0b6a419005b89cf93fe62d9517c0a2b8bb56af3244af65ecfe37e7d5d", + "https://bcr.bazel.build/modules/rules_license/1.0.0/MODULE.bazel": "a7fda60eefdf3d8c827262ba499957e4df06f659330bbe6cdbdb975b768bb65c", + "https://bcr.bazel.build/modules/rules_license/1.0.0/source.json": "a52c89e54cc311196e478f8382df91c15f7a2bfdf4c6cd0e2675cc2ff0b56efb", + "https://bcr.bazel.build/modules/rules_oci/2.2.7/MODULE.bazel": "f6150e4b224d459f7f6523ef65967464ca4efdd266c7fbf2f5a2a51011957e0c", + "https://bcr.bazel.build/modules/rules_oci/2.2.7/source.json": "b099f02af330f47f19dc67fc9300ef6e1937a8c86882690db0e7a2fcea8c7f6b", + "https://bcr.bazel.build/modules/rules_pkg/0.7.0/MODULE.bazel": "df99f03fc7934a4737122518bb87e667e62d780b610910f0447665a7e2be62dc", + "https://bcr.bazel.build/modules/rules_pkg/1.0.1/MODULE.bazel": "5b1df97dbc29623bccdf2b0dcd0f5cb08e2f2c9050aab1092fd39a41e82686ff", + "https://bcr.bazel.build/modules/rules_pkg/1.2.0/MODULE.bazel": "c7db3c2b407e673c7a39e3625dc05dc9f12d6682cbd82a3a5924a13b491eda7e", + "https://bcr.bazel.build/modules/rules_pkg/1.2.0/source.json": "9062e00845bf91a4247465d371baa837adf9b6ff44c542f73ba084f07667e1dc", + "https://bcr.bazel.build/modules/rules_proto/4.0.0/MODULE.bazel": "a7a7b6ce9bee418c1a760b3d84f83a299ad6952f9903c67f19e4edd964894e06", + "https://bcr.bazel.build/modules/rules_proto/5.3.0-21.7/MODULE.bazel": "e8dff86b0971688790ae75528fe1813f71809b5afd57facb44dad9e8eca631b7", + "https://bcr.bazel.build/modules/rules_proto/6.0.0-rc1/MODULE.bazel": "1e5b502e2e1a9e825eef74476a5a1ee524a92297085015a052510b09a1a09483", + "https://bcr.bazel.build/modules/rules_proto/6.0.0/MODULE.bazel": "b531d7f09f58dce456cd61b4579ce8c86b38544da75184eadaf0a7cb7966453f", + "https://bcr.bazel.build/modules/rules_proto/6.0.2/MODULE.bazel": "ce916b775a62b90b61888052a416ccdda405212b6aaeb39522f7dc53431a5e73", + "https://bcr.bazel.build/modules/rules_proto/7.0.2/MODULE.bazel": "bf81793bd6d2ad89a37a40693e56c61b0ee30f7a7fdbaf3eabbf5f39de47dea2", + "https://bcr.bazel.build/modules/rules_proto/7.1.0/MODULE.bazel": "002d62d9108f75bb807cd56245d45648f38275cb3a99dcd45dfb864c5d74cb96", + "https://bcr.bazel.build/modules/rules_proto/7.1.0/source.json": "39f89066c12c24097854e8f57ab8558929f9c8d474d34b2c00ac04630ad8940e", + "https://bcr.bazel.build/modules/rules_python/0.10.2/MODULE.bazel": "cc82bc96f2997baa545ab3ce73f196d040ffb8756fd2d66125a530031cd90e5f", + "https://bcr.bazel.build/modules/rules_python/0.23.1/MODULE.bazel": "49ffccf0511cb8414de28321f5fcf2a31312b47c40cc21577144b7447f2bf300", + "https://bcr.bazel.build/modules/rules_python/0.25.0/MODULE.bazel": "72f1506841c920a1afec76975b35312410eea3aa7b63267436bfb1dd91d2d382", + "https://bcr.bazel.build/modules/rules_python/0.28.0/MODULE.bazel": "cba2573d870babc976664a912539b320cbaa7114cd3e8f053c720171cde331ed", + "https://bcr.bazel.build/modules/rules_python/0.31.0/MODULE.bazel": "93a43dc47ee570e6ec9f5779b2e64c1476a6ce921c48cc9a1678a91dd5f8fd58", + "https://bcr.bazel.build/modules/rules_python/0.33.2/MODULE.bazel": "3e036c4ad8d804a4dad897d333d8dce200d943df4827cb849840055be8d2e937", + "https://bcr.bazel.build/modules/rules_python/0.37.1/MODULE.bazel": "3faeb2d9fa0a81f8980643ee33f212308f4d93eea4b9ce6f36d0b742e71e9500", + "https://bcr.bazel.build/modules/rules_python/0.37.2/MODULE.bazel": "b5ffde91410745750b6c13be1c5dc4555ef5bc50562af4a89fd77807fdde626a", + "https://bcr.bazel.build/modules/rules_python/0.4.0/MODULE.bazel": "9208ee05fd48bf09ac60ed269791cf17fb343db56c8226a720fbb1cdf467166c", + "https://bcr.bazel.build/modules/rules_python/1.0.0/MODULE.bazel": "898a3d999c22caa585eb062b600f88654bf92efb204fa346fb55f6f8edffca43", + "https://bcr.bazel.build/modules/rules_python/1.3.0/MODULE.bazel": "8361d57eafb67c09b75bf4bbe6be360e1b8f4f18118ab48037f2bd50aa2ccb13", + "https://bcr.bazel.build/modules/rules_python/1.4.1/MODULE.bazel": "8991ad45bdc25018301d6b7e1d3626afc3c8af8aaf4bc04f23d0b99c938b73a6", + "https://bcr.bazel.build/modules/rules_python/1.6.0/MODULE.bazel": "7e04ad8f8d5bea40451cf80b1bd8262552aa73f841415d20db96b7241bd027d8", + "https://bcr.bazel.build/modules/rules_python/1.7.0/MODULE.bazel": "d01f995ecd137abf30238ad9ce97f8fc3ac57289c8b24bd0bf53324d937a14f8", + "https://bcr.bazel.build/modules/rules_python/1.7.0/source.json": "028a084b65dcf8f4dc4f82f8778dbe65df133f234b316828a82e060d81bdce32", + "https://bcr.bazel.build/modules/rules_robolectric/4.14.1.2/MODULE.bazel": "d44fec647d0aeb67b9f3b980cf68ba634976f3ae7ccd6c07d790b59b87a4f251", + "https://bcr.bazel.build/modules/rules_robolectric/4.14.1.2/source.json": "37c10335f2361c337c5c1f34ed36d2da70534c23088062b33a8bdaab68aa9dea", + "https://bcr.bazel.build/modules/rules_shell/0.1.2/MODULE.bazel": "66e4ca3ce084b04af0b9ff05ff14cab4e5df7503973818bb91cbc6cda08d32fc", + "https://bcr.bazel.build/modules/rules_shell/0.2.0/MODULE.bazel": "fda8a652ab3c7d8fee214de05e7a9916d8b28082234e8d2c0094505c5268ed3c", + "https://bcr.bazel.build/modules/rules_shell/0.3.0/MODULE.bazel": "de4402cd12f4cc8fda2354fce179fdb068c0b9ca1ec2d2b17b3e21b24c1a937b", + "https://bcr.bazel.build/modules/rules_shell/0.4.1/MODULE.bazel": "00e501db01bbf4e3e1dd1595959092c2fadf2087b2852d3f553b5370f5633592", + "https://bcr.bazel.build/modules/rules_shell/0.6.1/MODULE.bazel": "72e76b0eea4e81611ef5452aa82b3da34caca0c8b7b5c0c9584338aa93bae26b", + "https://bcr.bazel.build/modules/rules_shell/0.8.0/MODULE.bazel": "f6a89f1d6a669a26f28fe814503857055d76306b79cfc11d12399af08d0b80ae", + "https://bcr.bazel.build/modules/rules_shell/0.8.0/source.json": "eb53cc815bc503c6683c5fe12d943f98883f81fc22f51403ec8a95610cba4195", + "https://bcr.bazel.build/modules/rules_swift/1.16.0/MODULE.bazel": "4a09f199545a60d09895e8281362b1ff3bb08bbde69c6fc87aff5b92fcc916ca", + "https://bcr.bazel.build/modules/rules_swift/2.1.1/MODULE.bazel": "494900a80f944fc7aa61500c2073d9729dff0b764f0e89b824eb746959bc1046", + "https://bcr.bazel.build/modules/rules_swift/2.4.0/MODULE.bazel": "1639617eb1ede28d774d967a738b4a68b0accb40650beadb57c21846beab5efd", + "https://bcr.bazel.build/modules/rules_swift/3.1.2/MODULE.bazel": "72c8f5cf9d26427cee6c76c8e3853eb46ce6b0412a081b2b6db6e8ad56267400", + "https://bcr.bazel.build/modules/rules_swift/3.1.2/source.json": "e85761f3098a6faf40b8187695e3de6d97944e98abd0d8ce579cb2daf6319a66", + "https://bcr.bazel.build/modules/stardoc/0.5.1/MODULE.bazel": "1a05d92974d0c122f5ccf09291442580317cdd859f07a8655f1db9a60374f9f8", + "https://bcr.bazel.build/modules/stardoc/0.5.3/MODULE.bazel": "c7f6948dae6999bf0db32c1858ae345f112cacf98f174c7a8bb707e41b974f1c", + "https://bcr.bazel.build/modules/stardoc/0.5.4/MODULE.bazel": "6569966df04610b8520957cb8e97cf2e9faac2c0309657c537ab51c16c18a2a4", + "https://bcr.bazel.build/modules/stardoc/0.6.2/MODULE.bazel": "7060193196395f5dd668eda046ccbeacebfd98efc77fed418dbe2b82ffaa39fd", + "https://bcr.bazel.build/modules/stardoc/0.7.0/MODULE.bazel": "05e3d6d30c099b6770e97da986c53bd31844d7f13d41412480ea265ac9e8079c", + "https://bcr.bazel.build/modules/stardoc/0.7.2/MODULE.bazel": "fc152419aa2ea0f51c29583fab1e8c99ddefd5b3778421845606ee628629e0e5", + "https://bcr.bazel.build/modules/stardoc/0.7.2/source.json": "58b029e5e901d6802967754adf0a9056747e8176f017cfe3607c0851f4d42216", + "https://bcr.bazel.build/modules/swift_argument_parser/1.3.1.1/MODULE.bazel": "5e463fbfba7b1701d957555ed45097d7f984211330106ccd1352c6e0af0dcf91", + "https://bcr.bazel.build/modules/swift_argument_parser/1.3.1.2/MODULE.bazel": "75aab2373a4bbe2a1260b9bf2a1ebbdbf872d3bd36f80bff058dccd82e89422f", + "https://bcr.bazel.build/modules/swift_argument_parser/1.3.1.2/source.json": "5fba48bbe0ba48761f9e9f75f92876cafb5d07c0ce059cc7a8027416de94a05b", + "https://bcr.bazel.build/modules/tar.bzl/0.2.1/MODULE.bazel": "52d1c00a80a8cc67acbd01649e83d8dd6a9dc426a6c0b754a04fe8c219c76468", + "https://bcr.bazel.build/modules/tar.bzl/0.2.1/source.json": "600ac6ff61744667a439e7b814ae59c1f29632c3984fccf8000c64c9db8d7bb6", + "https://bcr.bazel.build/modules/toml.bzl/0.3.0/MODULE.bazel": "5016e5dd1ad2200e119a4b28b2b3935e276c4b480f2fe3e952bea7eeba88f578", + "https://bcr.bazel.build/modules/toml.bzl/0.3.0/source.json": "0cf7c878c419b37ddb55f3dd93dd7c0c409bd7c4efacb3da504e0748780b2fa9", + "https://bcr.bazel.build/modules/upb/0.0.0-20220923-a547704/MODULE.bazel": "7298990c00040a0e2f121f6c32544bab27d4452f80d9ce51349b1a28f3005c43", + "https://bcr.bazel.build/modules/upb/0.0.0-20230516-61a97ef/MODULE.bazel": "c0df5e35ad55e264160417fd0875932ee3c9dda63d9fccace35ac62f45e1b6f9", + "https://bcr.bazel.build/modules/yq.bzl/0.1.1/MODULE.bazel": "9039681f9bcb8958ee2c87ffc74bdafba9f4369096a2b5634b88abc0eaefa072", + "https://bcr.bazel.build/modules/yq.bzl/0.1.1/source.json": "2d2bad780a9f2b9195a4a370314d2c17ae95eaa745cefc2e12fbc49759b15aa3", + "https://bcr.bazel.build/modules/zlib/1.2.11/MODULE.bazel": "07b389abc85fdbca459b69e2ec656ae5622873af3f845e1c9d80fe179f3effa0", + "https://bcr.bazel.build/modules/zlib/1.2.12/MODULE.bazel": "3b1a8834ada2a883674be8cbd36ede1b6ec481477ada359cd2d3ddc562340b27", + "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.5/MODULE.bazel": "eec517b5bbe5492629466e11dae908d043364302283de25581e3eb944326c4ca", + "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.5/source.json": "22bc55c47af97246cfc093d0acf683a7869377de362b5d1c552c2c2e16b7a806", + "https://bcr.bazel.build/modules/zlib/1.3.1/MODULE.bazel": "751c9940dcfe869f5f7274e1295422a34623555916eb98c174c1e945594bf198" + }, + "selectedYankedVersions": {}, + "moduleExtensions": { + "@@apple_rules_lint+//lint:extensions.bzl%linter": { + "general": { + "bzlTransitiveDigest": "g7izj5kLCmsajh8IospHh4ZQ35dyM0FIrA8D4HapAsM=", + "usagesDigest": "4RWlIKR/sSQ9MqPQRCROVLeGPbvTKmkbEpxkI3mbaCI=", + "recordedInputs": [], + "generatedRepoSpecs": { + "apple_linters": { + "repoRuleId": "@@apple_rules_lint+//lint/private:register_linters.bzl%register_linters", + "attributes": { + "linters": {} + } + } + } + } + }, + "@@rules_android+//rules/android_sdk_repository:rule.bzl%android_sdk_repository_extension": { + "general": { + "bzlTransitiveDigest": "+rMrzIrv7sImYmkbXJYv+gFpTJQ79X3MpwwMLI2A+oA=", + "usagesDigest": "iEGI2aNDMkHt9LXCdViLNUUOslpiVj2DrevWWXZEFnU=", + "recordedInputs": [], + "generatedRepoSpecs": { + "androidsdk": { + "repoRuleId": "@@rules_android+//rules/android_sdk_repository:rule.bzl%_android_sdk_repository", + "attributes": {} + } + } + } + }, + "@@rules_oci+//oci:extensions.bzl%oci": { + "general": { + "bzlTransitiveDigest": "pt4oC5w4SZXivjOVNAFM5W2NyEaU5cCGwrSOmM0x9wQ=", + "usagesDigest": "YV/my4HWfeIYZH762GR/gbfyrtmoU6x5X9/fNcX4Ioo=", + "recordedInputs": [ + "REPO_MAPPING:aspect_bazel_lib+,bazel_tools bazel_tools", + "REPO_MAPPING:bazel_features+,bazel_tools bazel_tools", + "REPO_MAPPING:rules_oci+,aspect_bazel_lib aspect_bazel_lib+", + "REPO_MAPPING:rules_oci+,bazel_features bazel_features+", + "REPO_MAPPING:rules_oci+,bazel_skylib bazel_skylib+" + ], + "generatedRepoSpecs": { + "temurin_jre_linux_arm64_v8": { + "repoRuleId": "@@rules_oci+//oci/private:pull.bzl%oci_pull", + "attributes": { + "www_authenticate_challenges": {}, + "scheme": "https", + "registry": "public.ecr.aws", + "repository": "docker/library/eclipse-temurin", + "identifier": "21-jre", + "platform": "linux/arm64/v8", + "target_name": "temurin_jre_linux_arm64_v8", + "bazel_tags": [] + } + }, + "temurin_jre_linux_amd64": { + "repoRuleId": "@@rules_oci+//oci/private:pull.bzl%oci_pull", + "attributes": { + "www_authenticate_challenges": {}, + "scheme": "https", + "registry": "public.ecr.aws", + "repository": "docker/library/eclipse-temurin", + "identifier": "21-jre", + "platform": "linux/amd64", + "target_name": "temurin_jre_linux_amd64", + "bazel_tags": [] + } + }, + "temurin_jre": { + "repoRuleId": "@@rules_oci+//oci/private:pull.bzl%oci_alias", + "attributes": { + "target_name": "temurin_jre", + "www_authenticate_challenges": {}, + "scheme": "https", + "registry": "public.ecr.aws", + "repository": "docker/library/eclipse-temurin", + "identifier": "21-jre", + "platforms": { + "@@platforms//cpu:arm64": "@temurin_jre_linux_arm64_v8", + "@@platforms//cpu:x86_64": "@temurin_jre_linux_amd64" + }, + "bzlmod_repository": "temurin_jre", + "reproducible": true + } + }, + "ubuntu_noble_linux_arm64_v8": { + "repoRuleId": "@@rules_oci+//oci/private:pull.bzl%oci_pull", + "attributes": { + "www_authenticate_challenges": {}, + "scheme": "https", + "registry": "public.ecr.aws", + "repository": "ubuntu/ubuntu", + "identifier": "sha256:ef59d9e82939bbce08973bdffb8761b025f75369fb7d2882cdc4938b5a9e992e", + "platform": "linux/arm64/v8", + "target_name": "ubuntu_noble_linux_arm64_v8", + "bazel_tags": [] + } + }, + "ubuntu_noble_linux_amd64": { + "repoRuleId": "@@rules_oci+//oci/private:pull.bzl%oci_pull", + "attributes": { + "www_authenticate_challenges": {}, + "scheme": "https", + "registry": "public.ecr.aws", + "repository": "ubuntu/ubuntu", + "identifier": "sha256:ef59d9e82939bbce08973bdffb8761b025f75369fb7d2882cdc4938b5a9e992e", + "platform": "linux/amd64", + "target_name": "ubuntu_noble_linux_amd64", + "bazel_tags": [] + } + }, + "ubuntu_noble": { + "repoRuleId": "@@rules_oci+//oci/private:pull.bzl%oci_alias", + "attributes": { + "target_name": "ubuntu_noble", + "www_authenticate_challenges": {}, + "scheme": "https", + "registry": "public.ecr.aws", + "repository": "ubuntu/ubuntu", + "identifier": "sha256:ef59d9e82939bbce08973bdffb8761b025f75369fb7d2882cdc4938b5a9e992e", + "platforms": { + "@@platforms//cpu:arm64": "@ubuntu_noble_linux_arm64_v8", + "@@platforms//cpu:x86_64": "@ubuntu_noble_linux_amd64" + }, + "bzlmod_repository": "ubuntu_noble", + "reproducible": true + } + }, + "oci_crane_darwin_amd64": { + "repoRuleId": "@@rules_oci+//oci:repositories.bzl%crane_repositories", + "attributes": { + "platform": "darwin_amd64", + "crane_version": "v0.18.0" + } + }, + "oci_crane_darwin_arm64": { + "repoRuleId": "@@rules_oci+//oci:repositories.bzl%crane_repositories", + "attributes": { + "platform": "darwin_arm64", + "crane_version": "v0.18.0" + } + }, + "oci_crane_linux_arm64": { + "repoRuleId": "@@rules_oci+//oci:repositories.bzl%crane_repositories", + "attributes": { + "platform": "linux_arm64", + "crane_version": "v0.18.0" + } + }, + "oci_crane_linux_armv6": { + "repoRuleId": "@@rules_oci+//oci:repositories.bzl%crane_repositories", + "attributes": { + "platform": "linux_armv6", + "crane_version": "v0.18.0" + } + }, + "oci_crane_linux_i386": { + "repoRuleId": "@@rules_oci+//oci:repositories.bzl%crane_repositories", + "attributes": { + "platform": "linux_i386", + "crane_version": "v0.18.0" + } + }, + "oci_crane_linux_s390x": { + "repoRuleId": "@@rules_oci+//oci:repositories.bzl%crane_repositories", + "attributes": { + "platform": "linux_s390x", + "crane_version": "v0.18.0" + } + }, + "oci_crane_linux_amd64": { + "repoRuleId": "@@rules_oci+//oci:repositories.bzl%crane_repositories", + "attributes": { + "platform": "linux_amd64", + "crane_version": "v0.18.0" + } + }, + "oci_crane_windows_armv6": { + "repoRuleId": "@@rules_oci+//oci:repositories.bzl%crane_repositories", + "attributes": { + "platform": "windows_armv6", + "crane_version": "v0.18.0" + } + }, + "oci_crane_windows_amd64": { + "repoRuleId": "@@rules_oci+//oci:repositories.bzl%crane_repositories", + "attributes": { + "platform": "windows_amd64", + "crane_version": "v0.18.0" + } + }, + "oci_crane_toolchains": { + "repoRuleId": "@@rules_oci+//oci/private:toolchains_repo.bzl%toolchains_repo", + "attributes": { + "toolchain_type": "@rules_oci//oci:crane_toolchain_type", + "toolchain": "@oci_crane_{platform}//:crane_toolchain" + } + }, + "oci_regctl_darwin_amd64": { + "repoRuleId": "@@rules_oci+//oci:repositories.bzl%regctl_repositories", + "attributes": { + "platform": "darwin_amd64" + } + }, + "oci_regctl_darwin_arm64": { + "repoRuleId": "@@rules_oci+//oci:repositories.bzl%regctl_repositories", + "attributes": { + "platform": "darwin_arm64" + } + }, + "oci_regctl_linux_arm64": { + "repoRuleId": "@@rules_oci+//oci:repositories.bzl%regctl_repositories", + "attributes": { + "platform": "linux_arm64" + } + }, + "oci_regctl_linux_s390x": { + "repoRuleId": "@@rules_oci+//oci:repositories.bzl%regctl_repositories", + "attributes": { + "platform": "linux_s390x" + } + }, + "oci_regctl_linux_amd64": { + "repoRuleId": "@@rules_oci+//oci:repositories.bzl%regctl_repositories", + "attributes": { + "platform": "linux_amd64" + } + }, + "oci_regctl_windows_amd64": { + "repoRuleId": "@@rules_oci+//oci:repositories.bzl%regctl_repositories", + "attributes": { + "platform": "windows_amd64" + } + }, + "oci_regctl_toolchains": { + "repoRuleId": "@@rules_oci+//oci/private:toolchains_repo.bzl%toolchains_repo", + "attributes": { + "toolchain_type": "@rules_oci//oci:regctl_toolchain_type", + "toolchain": "@oci_regctl_{platform}//:regctl_toolchain" + } + } + }, + "moduleExtensionMetadata": { + "explicitRootModuleDirectDeps": [], + "explicitRootModuleDirectDevDeps": [], + "useAllRepos": "NO", + "reproducible": false + } + } + }, + "@@rules_python+//python/extensions:config.bzl%config": { + "general": { + "bzlTransitiveDigest": "dzD8Q2YmrP3fz8saWLHPmlwPLO91ImtTmP/c9JKTStM=", + "usagesDigest": "ZVSXMAGpD+xzVNPuvF1IoLBkty7TROO0+akMapt1pAg=", + "recordedInputs": [ + "REPO_MAPPING:rules_python+,bazel_tools bazel_tools", + "REPO_MAPPING:rules_python+,pypi__build rules_python++config+pypi__build", + "REPO_MAPPING:rules_python+,pypi__click rules_python++config+pypi__click", + "REPO_MAPPING:rules_python+,pypi__colorama rules_python++config+pypi__colorama", + "REPO_MAPPING:rules_python+,pypi__importlib_metadata rules_python++config+pypi__importlib_metadata", + "REPO_MAPPING:rules_python+,pypi__installer rules_python++config+pypi__installer", + "REPO_MAPPING:rules_python+,pypi__more_itertools rules_python++config+pypi__more_itertools", + "REPO_MAPPING:rules_python+,pypi__packaging rules_python++config+pypi__packaging", + "REPO_MAPPING:rules_python+,pypi__pep517 rules_python++config+pypi__pep517", + "REPO_MAPPING:rules_python+,pypi__pip rules_python++config+pypi__pip", + "REPO_MAPPING:rules_python+,pypi__pip_tools rules_python++config+pypi__pip_tools", + "REPO_MAPPING:rules_python+,pypi__pyproject_hooks rules_python++config+pypi__pyproject_hooks", + "REPO_MAPPING:rules_python+,pypi__setuptools rules_python++config+pypi__setuptools", + "REPO_MAPPING:rules_python+,pypi__tomli rules_python++config+pypi__tomli", + "REPO_MAPPING:rules_python+,pypi__wheel rules_python++config+pypi__wheel", + "REPO_MAPPING:rules_python+,pypi__zipp rules_python++config+pypi__zipp" + ], + "generatedRepoSpecs": { + "rules_python_internal": { + "repoRuleId": "@@rules_python+//python/private:internal_config_repo.bzl%internal_config_repo", + "attributes": { + "transition_setting_generators": {}, + "transition_settings": [] + } + }, + "pypi__build": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/e2/03/f3c8ba0a6b6e30d7d18c40faab90807c9bb5e9a1e3b2fe2008af624a9c97/build-1.2.1-py3-none-any.whl", + "sha256": "75e10f767a433d9a86e50d83f418e83efc18ede923ee5ff7df93b6cb0306c5d4", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__click": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/00/2e/d53fa4befbf2cfa713304affc7ca780ce4fc1fd8710527771b58311a3229/click-8.1.7-py3-none-any.whl", + "sha256": "ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__colorama": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", + "sha256": "4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__importlib_metadata": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/2d/0a/679461c511447ffaf176567d5c496d1de27cbe34a87df6677d7171b2fbd4/importlib_metadata-7.1.0-py3-none-any.whl", + "sha256": "30962b96c0c223483ed6cc7280e7f0199feb01a0e40cfae4d4450fc6fab1f570", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__installer": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/e5/ca/1172b6638d52f2d6caa2dd262ec4c811ba59eee96d54a7701930726bce18/installer-0.7.0-py3-none-any.whl", + "sha256": "05d1933f0a5ba7d8d6296bb6d5018e7c94fa473ceb10cf198a92ccea19c27b53", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__more_itertools": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/50/e2/8e10e465ee3987bb7c9ab69efb91d867d93959095f4807db102d07995d94/more_itertools-10.2.0-py3-none-any.whl", + "sha256": "686b06abe565edfab151cb8fd385a05651e1fdf8f0a14191e4439283421f8684", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__packaging": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/49/df/1fceb2f8900f8639e278b056416d49134fb8d84c5942ffaa01ad34782422/packaging-24.0-py3-none-any.whl", + "sha256": "2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__pep517": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/25/6e/ca4a5434eb0e502210f591b97537d322546e4833dcb4d470a48c375c5540/pep517-0.13.1-py3-none-any.whl", + "sha256": "31b206f67165b3536dd577c5c3f1518e8fbaf38cbc57efff8369a392feff1721", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__pip": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/8a/6a/19e9fe04fca059ccf770861c7d5721ab4c2aebc539889e97c7977528a53b/pip-24.0-py3-none-any.whl", + "sha256": "ba0d021a166865d2265246961bec0152ff124de910c5cc39f1156ce3fa7c69dc", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__pip_tools": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/0d/dc/38f4ce065e92c66f058ea7a368a9c5de4e702272b479c0992059f7693941/pip_tools-7.4.1-py3-none-any.whl", + "sha256": "4c690e5fbae2f21e87843e89c26191f0d9454f362d8acdbd695716493ec8b3a9", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__pyproject_hooks": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/ae/f3/431b9d5fe7d14af7a32340792ef43b8a714e7726f1d7b69cc4e8e7a3f1d7/pyproject_hooks-1.1.0-py3-none-any.whl", + "sha256": "7ceeefe9aec63a1064c18d939bdc3adf2d8aa1988a510afec15151578b232aa2", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__setuptools": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/90/99/158ad0609729111163fc1f674a5a42f2605371a4cf036d0441070e2f7455/setuptools-78.1.1-py3-none-any.whl", + "sha256": "c3a9c4211ff4c309edb8b8c4f1cbfa7ae324c4ba9f91ff254e3d305b9fd54561", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__tomli": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/97/75/10a9ebee3fd790d20926a90a2547f0bf78f371b2f13aa822c759680ca7b9/tomli-2.0.1-py3-none-any.whl", + "sha256": "939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__wheel": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/7d/cd/d7460c9a869b16c3dd4e1e403cce337df165368c71d6af229a74699622ce/wheel-0.43.0-py3-none-any.whl", + "sha256": "55c570405f142630c6b9f72fe09d9b67cf1477fcf543ae5b8dcb1f5b7377da81", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__zipp": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/da/55/a03fd7240714916507e1fcf7ae355bd9d9ed2e6db492595f1a67f61681be/zipp-3.18.2-py3-none-any.whl", + "sha256": "dce197b859eb796242b0622af1b8beb0a722d52aa2f57133ead08edd5bf5374e", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + } + } + } + }, + "@@rules_python+//python/uv:uv.bzl%uv": { + "general": { + "bzlTransitiveDigest": "ijW9KS7qsIY+yBVvJ+Nr1mzwQox09j13DnE3iIwaeTM=", + "usagesDigest": "H8dQoNZcoqP+Mu0tHZTi4KHATzvNkM5ePuEqoQdklIU=", + "recordedInputs": [ + "REPO_MAPPING:rules_python+,bazel_tools bazel_tools", + "REPO_MAPPING:rules_python+,platforms platforms" + ], + "generatedRepoSpecs": { + "uv": { + "repoRuleId": "@@rules_python+//python/uv/private:uv_toolchains_repo.bzl%uv_toolchains_repo", + "attributes": { + "toolchain_type": "'@@rules_python+//python/uv:uv_toolchain_type'", + "toolchain_names": [ + "none" + ], + "toolchain_implementations": { + "none": "'@@rules_python+//python:none'" + }, + "toolchain_compatible_with": { + "none": [ + "@platforms//:incompatible" + ] + }, + "toolchain_target_settings": {} + } + } + } + } + } + }, + "facts": { + "@@rules_go+//go:extensions.bzl%go_sdk": { + "1.22.4": { + "aix_ppc64": [ + "go1.22.4.aix-ppc64.tar.gz", + "b9647fa9fc83a0cc5d4f092a19eaeaecf45f063a5aa7d4962fde65aeb7ae6ce1" + ], + "darwin_amd64": [ + "go1.22.4.darwin-amd64.tar.gz", + "c95967f50aa4ace34af0c236cbdb49a9a3e80ee2ad09d85775cb4462a5c19ed3" + ], + "darwin_arm64": [ + "go1.22.4.darwin-arm64.tar.gz", + "242b78dc4c8f3d5435d28a0d2cec9b4c1aa999b601fb8aa59fb4e5a1364bf827" + ], + "dragonfly_amd64": [ + "go1.22.4.dragonfly-amd64.tar.gz", + "f2fbb51af4719d3616efb482d6ed2b96579b474156f85a7ddc6f126764feec4b" + ], + "freebsd_386": [ + "go1.22.4.freebsd-386.tar.gz", + "7c54884bb9f274884651d41e61d1bc12738863ad1497e97ea19ad0e9aa6bf7b5" + ], + "freebsd_amd64": [ + "go1.22.4.freebsd-amd64.tar.gz", + "88d44500e1701dd35797619774d6dd51bf60f45a8338b0a82ddc018e4e63fb78" + ], + "freebsd_arm64": [ + "go1.22.4.freebsd-arm64.tar.gz", + "726dc093cf020277be45debf03c3b02b43c2efb3e2a5d4fba8f52579d65327dc" + ], + "freebsd_armv6l": [ + "go1.22.4.freebsd-arm.tar.gz", + "3d9efe47db142a22679aba46b1772e3900b0d87ae13bd2b3bc80dbf2ac0b2cd6" + ], + "freebsd_riscv64": [ + "go1.22.4.freebsd-riscv64.tar.gz", + "5f6b67e5e32f1d6ccb2d4dcb44934a5e2e870a877ba7443d86ec43cfc28afa71" + ], + "illumos_amd64": [ + "go1.22.4.illumos-amd64.tar.gz", + "d56ecc2f85b6418a21ef83879594d0c42ab4f65391a676bb12254870e6690d63" + ], + "linux_386": [ + "go1.22.4.linux-386.tar.gz", + "47a2a8d249a91eb8605c33bceec63aedda0441a43eac47b4721e3975ff916cec" + ], + "linux_amd64": [ + "go1.22.4.linux-amd64.tar.gz", + "ba79d4526102575196273416239cca418a651e049c2b099f3159db85e7bade7d" + ], + "linux_arm64": [ + "go1.22.4.linux-arm64.tar.gz", + "a8e177c354d2e4a1b61020aca3562e27ea3e8f8247eca3170e3fa1e0c2f9e771" + ], + "linux_armv6l": [ + "go1.22.4.linux-armv6l.tar.gz", + "e2b143fbacbc9cbd448e9ef41ac3981f0488ce849af1cf37e2341d09670661de" + ], + "linux_loong64": [ + "go1.22.4.linux-loong64.tar.gz", + "e2ff9436e4b34bf6926b06d97916e26d67a909a2effec17967245900f0816f1d" + ], + "linux_mips": [ + "go1.22.4.linux-mips.tar.gz", + "73f0dcc60458c4770593b05a7bc01cc0d31fc98f948c0c2334812c7a1f2fc3f1" + ], + "linux_mips64": [ + "go1.22.4.linux-mips64.tar.gz", + "417af97fc2630a647052375768be4c38adcc5af946352ea5b28613ea81ca5d45" + ], + "linux_mips64le": [ + "go1.22.4.linux-mips64le.tar.gz", + "7486e2d7dd8c98eb44df815ace35a7fe7f30b7c02326e3741bd934077508139b" + ], + "linux_mipsle": [ + "go1.22.4.linux-mipsle.tar.gz", + "69479c8aad301e459a8365b40cad1074a0dbba5defb9291669f94809c4c4be6e" + ], + "linux_ppc64": [ + "go1.22.4.linux-ppc64.tar.gz", + "dd238847e65bc3e2745caca475a5db6522a2fcf85cf6c38fc36a06642b19efd7" + ], + "linux_ppc64le": [ + "go1.22.4.linux-ppc64le.tar.gz", + "a3e5834657ef92523f570f798fed42f1f87bc18222a16815ec76b84169649ec4" + ], + "linux_riscv64": [ + "go1.22.4.linux-riscv64.tar.gz", + "56a827ff7dc6245bcd7a1e9288dffaa1d8b0fd7468562264c1523daf3b4f1b4a" + ], + "linux_s390x": [ + "go1.22.4.linux-s390x.tar.gz", + "7590c3e278e2dc6040aae0a39da3ca1eb2e3921673a7304cc34d588c45889eec" + ], + "netbsd_386": [ + "go1.22.4.netbsd-386.tar.gz", + "ddd2eebe34471a2502de6c5dad04ab27c9fc80cbde7a9ad5b3c66ecec4504e1d" + ], + "netbsd_amd64": [ + "go1.22.4.netbsd-amd64.tar.gz", + "33af79f6f935f6fbacc5d23876450b3567b79348fc065beef8e64081127dd234" + ], + "netbsd_arm64": [ + "go1.22.4.netbsd-arm64.tar.gz", + "c9a2971dec9f6d320c6f2b049b2353c6d0a2d35e87b8a4b2d78a2f0d62545f8e" + ], + "netbsd_armv6l": [ + "go1.22.4.netbsd-arm.tar.gz", + "fa3550ebd5375a70b3bcd342b5a71f4bd271dcbbfaf4eabefa2144ab5d8924b6" + ], + "openbsd_386": [ + "go1.22.4.openbsd-386.tar.gz", + "d21af022331bfdc2b5b161d616c3a1a4573d33cf7a30416ee509a8f3641deb47" + ], + "openbsd_amd64": [ + "go1.22.4.openbsd-amd64.tar.gz", + "72c0094c43f7e5722ec49c2a3e9dfa7a1123ac43a5f3a63eecf3e3795d3ff0ae" + ], + "openbsd_arm64": [ + "go1.22.4.openbsd-arm64.tar.gz", + "a7ab8d4e0b02bf06ed144ba42c61c0e93ee00f2b433415dfd4ad4b6e79f31650" + ], + "openbsd_armv6l": [ + "go1.22.4.openbsd-arm.tar.gz", + "1096831ea3c5ea3ca57d14251d9eda3786889531eb40d7d6775dcaa324d4b065" + ], + "openbsd_ppc64": [ + "go1.22.4.openbsd-ppc64.tar.gz", + "9716327c8a628358798898dc5148c49dbbeb5196bf2cbf088e550721a6e4f60b" + ], + "plan9_386": [ + "go1.22.4.plan9-386.tar.gz", + "a8dd4503c95c32a502a616ab78870a19889c9325fe9bd31eb16dd69346e4bfa8" + ], + "plan9_amd64": [ + "go1.22.4.plan9-amd64.tar.gz", + "5423a25808d76fe5aca8607a2e5ac5673abf45446b168cb5e9d8519ee9fe39a1" + ], + "plan9_armv6l": [ + "go1.22.4.plan9-arm.tar.gz", + "6af939ad583f5c85c09c53728ab7d38c3cc2b39167562d6c18a07c5c6608b370" + ], + "solaris_amd64": [ + "go1.22.4.solaris-amd64.tar.gz", + "e8cabe69c03085725afdb32a6f9998191a3e55a747b270d835fd05000d56abba" + ], + "windows_386": [ + "go1.22.4.windows-386.zip", + "aca4e2c37278a10f1c70dd0df142f7d66b50334fcee48978d409202d308d6d25" + ], + "windows_amd64": [ + "go1.22.4.windows-amd64.zip", + "26321c4d945a0035d8a5bc4a1965b0df401ff8ceac66ce2daadabf9030419a98" + ], + "windows_arm64": [ + "go1.22.4.windows-arm64.zip", + "8a2daa9ea28cbdafddc6171aefed384f4e5b6e714fb52116fe9ed25a132f37ed" + ], + "windows_armv6l": [ + "go1.22.4.windows-arm.zip", + "5fcd0671a49cecf39b41021621ee1b6e7aa1370f37122b72e80d4fd4185833b6" + ] + }, + "1.23.6": { + "aix_ppc64": [ + "go1.23.6.aix-ppc64.tar.gz", + "adec10f4ba56591f523aa04851f7f6900b1c61508dfa6b80e62717a8e6684a5c" + ], + "darwin_amd64": [ + "go1.23.6.darwin-amd64.tar.gz", + "782da50ce8ec5e98fac2cd3cdc6a1d7130d093294fc310038f651444232a3fb0" + ], + "darwin_arm64": [ + "go1.23.6.darwin-arm64.tar.gz", + "5cae2450a1708aeb0333237a155640d5562abaf195defebc4306054565536221" + ], + "dragonfly_amd64": [ + "go1.23.6.dragonfly-amd64.tar.gz", + "d52efb3020d9332477ade98163c03d2f2fe3e051b0e7e01f0e167412c66de0cb" + ], + "freebsd_386": [ + "go1.23.6.freebsd-386.tar.gz", + "d3287706b5823712ac6cf7dff684a556cff98163ef60e7b275abe3388c17aac7" + ], + "freebsd_amd64": [ + "go1.23.6.freebsd-amd64.tar.gz", + "ebb4c6a9b0673dbdabc439877779ed6add16575e21bd0a7955c33f692789aef6" + ], + "freebsd_arm": [ + "go1.23.6.freebsd-arm.tar.gz", + "b7241584afb0b161c09148f8fde16171bb743e47b99d451fbc5f5217ec7a88b6" + ], + "freebsd_arm64": [ + "go1.23.6.freebsd-arm64.tar.gz", + "004718b53cedd7955d1b1dc4053539fcd1053c031f5f3374334a22befd1f8310" + ], + "freebsd_riscv64": [ + "go1.23.6.freebsd-riscv64.tar.gz", + "ca026ec8a30dd0c18164f40e1ce21bd725e2445f11699177d05815189a38de7a" + ], + "illumos_amd64": [ + "go1.23.6.illumos-amd64.tar.gz", + "7db973efa3fb2e48e45059b855721550fce8e90803e7373d3efd37b88dd821e8" + ], + "linux_386": [ + "go1.23.6.linux-386.tar.gz", + "e61f87693169c0bbcc43363128f1e929b9dff0b7f448573f1bdd4e4a0b9687ba" + ], + "linux_amd64": [ + "go1.23.6.linux-amd64.tar.gz", + "9379441ea310de000f33a4dc767bd966e72ab2826270e038e78b2c53c2e7802d" + ], + "linux_arm64": [ + "go1.23.6.linux-arm64.tar.gz", + "561c780e8f4a8955d32bf72e46af0b5ee5e0debe1e4633df9a03781878219202" + ], + "linux_armv6l": [ + "go1.23.6.linux-armv6l.tar.gz", + "27a4611010c16b8c4f37ade3aada55bd5781998f02f348b164302fd5eea4eb74" + ], + "linux_loong64": [ + "go1.23.6.linux-loong64.tar.gz", + "c459226424372abc2b35957cc8955dad348330714f7605093325dbb73e33c750" + ], + "linux_mips": [ + "go1.23.6.linux-mips.tar.gz", + "e2a0aff70b958a3463a7d47132a2d0238369f64578d4f7f95e679e3a5af05622" + ], + "linux_mips64": [ + "go1.23.6.linux-mips64.tar.gz", + "7d30ec7db056311d420bf930c16abcae13c0f41c26a202868f279721ec3c2f2f" + ], + "linux_mips64le": [ + "go1.23.6.linux-mips64le.tar.gz", + "74ca7bc475bcc084c6718b74df024d7de9612932cea8a6dc75e29d3a5315a23a" + ], + "linux_mipsle": [ + "go1.23.6.linux-mipsle.tar.gz", + "09bf935a14e9f59a20499989438b1655453480016bdbcb10406acf4df2678ccb" + ], + "linux_ppc64": [ + "go1.23.6.linux-ppc64.tar.gz", + "5cb2f6a5090276c72c5eda8a55896f5a3d6ea0f28d10fa1a50e8318640f02d6c" + ], + "linux_ppc64le": [ + "go1.23.6.linux-ppc64le.tar.gz", + "0f817201e83d78ddbfa27f5f78d9b72450b92cc21d5e045145efacd0d3244a99" + ], + "linux_riscv64": [ + "go1.23.6.linux-riscv64.tar.gz", + "f95f7f817ab22ecab4503d0704d6449ea1aa26a595f57bf9b9f94ddf2aa7c1f3" + ], + "linux_s390x": [ + "go1.23.6.linux-s390x.tar.gz", + "321e7ed0d5416f731479c52fa7610b52b8079a8061967bd48cec6d66f671a60e" + ], + "netbsd_386": [ + "go1.23.6.netbsd-386.tar.gz", + "92d678fb8e1eeeb8c6af6f22e4e5494652dcbb4a320113fc08325cb9956a2d4c" + ], + "netbsd_amd64": [ + "go1.23.6.netbsd-amd64.tar.gz", + "86ba51e7bb26b30ea6a8d88ddb79d8e8c83b4116200040ecb7a5a44cf90a8c5c" + ], + "netbsd_arm": [ + "go1.23.6.netbsd-arm.tar.gz", + "4b974c35345100f0be6ea66afab2781de91ee9882117314126eaf0ae90fd3816" + ], + "netbsd_arm64": [ + "go1.23.6.netbsd-arm64.tar.gz", + "53e3589fc38e787a493ea038961f8e40803714dbb42754c1713b00099c12e9b9" + ], + "openbsd_386": [ + "go1.23.6.openbsd-386.tar.gz", + "6d2317b3a8505ccebff8f72d943f2ac9b82c115632e54a53a786eff24ced56d9" + ], + "openbsd_amd64": [ + "go1.23.6.openbsd-amd64.tar.gz", + "f699e707d95a984fcc00361d91aecdb413d3c75e18235156ffba7a89edf68aae" + ], + "openbsd_arm": [ + "go1.23.6.openbsd-arm.tar.gz", + "3c1cf6ab893657d0bf1942e40ce115acfd27cbce1ccb9bc88fd9cd21ca3d489f" + ], + "openbsd_arm64": [ + "go1.23.6.openbsd-arm64.tar.gz", + "cc0875535d14001f2da23ae9af89025b28c466e8f4f4c63f991ebb6f4b02f66c" + ], + "openbsd_ppc64": [ + "go1.23.6.openbsd-ppc64.tar.gz", + "64de80e29ca66cb566cbf8be030bf8599953af4e48402eab724cbe0a08b40602" + ], + "openbsd_riscv64": [ + "go1.23.6.openbsd-riscv64.tar.gz", + "c398a6b43c569f34bb4a2d16b52f8010eaac9a2a82ecac0602b4338e35cef377" + ], + "plan9_386": [ + "go1.23.6.plan9-386.tar.gz", + "10998b6b130bb7b542b407f0db42b86a913b111f8fa86d44394beaace4d45f01" + ], + "plan9_amd64": [ + "go1.23.6.plan9-amd64.tar.gz", + "9fbe8065436d8d12c02f19f64f51c9107da3a7a4ac46ab5777e182e9fe88c32f" + ], + "plan9_arm": [ + "go1.23.6.plan9-arm.tar.gz", + "8e3c826b884daee2de37e3b070d7eac4cea5d68edab8db09910e22201c75db83" + ], + "solaris_amd64": [ + "go1.23.6.solaris-amd64.tar.gz", + "b619eff63fec86daaea92ca170559e448a58b8ba0b92eef1971bc14e92ea86a7" + ], + "windows_386": [ + "go1.23.6.windows-386.zip", + "96820c0f5d464dd694543329e9b4d413b17c821c03a055717a29e6735b44c2d8" + ], + "windows_amd64": [ + "go1.23.6.windows-amd64.zip", + "53fec1586850b2cf5ad6438341ff7adc5f6700dd3ec1cfa3f5e8b141df190243" + ], + "windows_arm": [ + "go1.23.6.windows-arm.zip", + "22c2518c45c20018afa20d5376dc9fd7a7e74367240ed7b5209e79a30b5c4218" + ], + "windows_arm64": [ + "go1.23.6.windows-arm64.zip", + "a2d2ec1b3759552bdd9cdf58858f91dfbfd6ab3a472f00b5255acbed30b1aa41" + ] + }, + "1.25.0": { + "aix_ppc64": [ + "go1.25.0.aix-ppc64.tar.gz", + "e5234a7dac67bc86c528fe9752fc9d63557918627707a733ab4cac1a6faed2d4" + ], + "darwin_amd64": [ + "go1.25.0.darwin-amd64.tar.gz", + "5bd60e823037062c2307c71e8111809865116714d6f6b410597cf5075dfd80ef" + ], + "darwin_arm64": [ + "go1.25.0.darwin-arm64.tar.gz", + "544932844156d8172f7a28f77f2ac9c15a23046698b6243f633b0a0b00c0749c" + ], + "dragonfly_amd64": [ + "go1.25.0.dragonfly-amd64.tar.gz", + "5ed3cf9a810a1483822538674f1336c06b51aa1b94d6d545a1a0319a48177120" + ], + "freebsd_386": [ + "go1.25.0.freebsd-386.tar.gz", + "abea5d5c6697e6b5c224731f2158fe87c602996a2a233ac0c4730cd57bf8374e" + ], + "freebsd_amd64": [ + "go1.25.0.freebsd-amd64.tar.gz", + "86e6fe0a29698d7601c4442052dac48bd58d532c51cccb8f1917df648138730b" + ], + "freebsd_arm": [ + "go1.25.0.freebsd-arm.tar.gz", + "d90b78e41921f72f30e8bbc81d9dec2cff7ff384a33d8d8debb24053e4336bfe" + ], + "freebsd_arm64": [ + "go1.25.0.freebsd-arm64.tar.gz", + "451d0da1affd886bfb291b7c63a6018527b269505db21ce6e14724f22ab0662e" + ], + "freebsd_riscv64": [ + "go1.25.0.freebsd-riscv64.tar.gz", + "7b565f76bd8bda46549eeaaefe0e53b251e644c230577290c0f66b1ecdb3cdbe" + ], + "illumos_amd64": [ + "go1.25.0.illumos-amd64.tar.gz", + "b1e1fdaab1ad25aa1c08d7a36c97d45d74b98b89c3f78c6d2145f77face54a2c" + ], + "linux_386": [ + "go1.25.0.linux-386.tar.gz", + "8c602dd9d99bc9453b3995d20ce4baf382cc50855900a0ece5de9929df4a993a" + ], + "linux_amd64": [ + "go1.25.0.linux-amd64.tar.gz", + "2852af0cb20a13139b3448992e69b868e50ed0f8a1e5940ee1de9e19a123b613" + ], + "linux_arm64": [ + "go1.25.0.linux-arm64.tar.gz", + "05de75d6994a2783699815ee553bd5a9327d8b79991de36e38b66862782f54ae" + ], + "linux_armv6l": [ + "go1.25.0.linux-armv6l.tar.gz", + "a5a8f8198fcf00e1e485b8ecef9ee020778bf32a408a4e8873371bfce458cd09" + ], + "linux_loong64": [ + "go1.25.0.linux-loong64.tar.gz", + "cab86b1cf761b1cb3bac86a8877cfc92e7b036fc0d3084123d77013d61432afc" + ], + "linux_mips": [ + "go1.25.0.linux-mips.tar.gz", + "d66b6fb74c3d91b9829dc95ec10ca1f047ef5e89332152f92e136cf0e2da5be1" + ], + "linux_mips64": [ + "go1.25.0.linux-mips64.tar.gz", + "4082e4381a8661bc2a839ff94ba3daf4f6cde20f8fb771b5b3d4762dc84198a2" + ], + "linux_mips64le": [ + "go1.25.0.linux-mips64le.tar.gz", + "70002c299ec7f7175ac2ef673b1b347eecfa54ae11f34416a6053c17f855afcc" + ], + "linux_mipsle": [ + "go1.25.0.linux-mipsle.tar.gz", + "b00a3a39eff099f6df9f1c7355bf28e4589d0586f42d7d4a394efb763d145a73" + ], + "linux_ppc64": [ + "go1.25.0.linux-ppc64.tar.gz", + "df166f33bd98160662560a72ff0b4ba731f969a80f088922bddcf566a88c1ec1" + ], + "linux_ppc64le": [ + "go1.25.0.linux-ppc64le.tar.gz", + "0f18a89e7576cf2c5fa0b487a1635d9bcbf843df5f110e9982c64df52a983ad0" + ], + "linux_riscv64": [ + "go1.25.0.linux-riscv64.tar.gz", + "c018ff74a2c48d55c8ca9b07c8e24163558ffec8bea08b326d6336905d956b67" + ], + "linux_s390x": [ + "go1.25.0.linux-s390x.tar.gz", + "34e5a2e19f2292fbaf8783e3a241e6e49689276aef6510a8060ea5ef54eee408" + ], + "netbsd_386": [ + "go1.25.0.netbsd-386.tar.gz", + "f8586cdb7aa855657609a5c5f6dbf523efa00c2bbd7c76d3936bec80aa6c0aba" + ], + "netbsd_amd64": [ + "go1.25.0.netbsd-amd64.tar.gz", + "ae8dc1469385b86a157a423bb56304ba45730de8a897615874f57dd096db2c2a" + ], + "netbsd_arm": [ + "go1.25.0.netbsd-arm.tar.gz", + "1ff7e4cc764425fc9dd6825eaee79d02b3c7cafffbb3691687c8d672ade76cb7" + ], + "netbsd_arm64": [ + "go1.25.0.netbsd-arm64.tar.gz", + "e1b310739f26724216aa6d7d7208c4031f9ff54c9b5b9a796ddc8bebcb4a5f16" + ], + "openbsd_386": [ + "go1.25.0.openbsd-386.tar.gz", + "4802a9b20e533da91adb84aab42e94aa56cfe3e5475d0550bed3385b182e69d8" + ], + "openbsd_amd64": [ + "go1.25.0.openbsd-amd64.tar.gz", + "c016cd984bebe317b19a4f297c4f50def120dc9788490540c89f28e42f1dabe1" + ], + "openbsd_arm": [ + "go1.25.0.openbsd-arm.tar.gz", + "a1e31d0bf22172ddde42edf5ec811ef81be43433df0948ece52fecb247ccfd8d" + ], + "openbsd_arm64": [ + "go1.25.0.openbsd-arm64.tar.gz", + "343ea8edd8c218196e15a859c6072d0dd3246fbbb168481ab665eb4c4140458d" + ], + "openbsd_ppc64": [ + "go1.25.0.openbsd-ppc64.tar.gz", + "694c14da1bcaeb5e3332d49bdc2b6d155067648f8fe1540c5de8f3cf8e157154" + ], + "openbsd_riscv64": [ + "go1.25.0.openbsd-riscv64.tar.gz", + "aa510ad25cf54c06cd9c70b6d80ded69cb20188ac6e1735655eef29ff7e7885f" + ], + "plan9_386": [ + "go1.25.0.plan9-386.tar.gz", + "46f8cef02086cf04bf186c5912776b56535178d4cb319cd19c9fdbdd29231986" + ], + "plan9_amd64": [ + "go1.25.0.plan9-amd64.tar.gz", + "29b34391d84095e44608a228f63f2f88113a37b74a79781353ec043dfbcb427b" + ], + "plan9_arm": [ + "go1.25.0.plan9-arm.tar.gz", + "0a047107d13ebe7943aaa6d54b1d7bbd2e45e68ce449b52915a818da715799c2" + ], + "solaris_amd64": [ + "go1.25.0.solaris-amd64.tar.gz", + "9977f9e4351984364a3b2b78f8b88bfd1d339812356d5237678514594b7d3611" + ], + "windows_386": [ + "go1.25.0.windows-386.zip", + "df9f39db82a803af0db639e3613a36681ab7a42866b1384b3f3a1045663961a7" + ], + "windows_amd64": [ + "go1.25.0.windows-amd64.zip", + "89efb4f9b30812eee083cc1770fdd2913c14d301064f6454851428f9707d190b" + ], + "windows_arm64": [ + "go1.25.0.windows-arm64.zip", + "27bab004c72b3d7bd05a69b6ec0fc54a309b4b78cc569dd963d8b3ec28bfdb8c" + ] + } + } + }, + "factsVersions": {} +} diff --git a/examples/java-spring-boot-service/maven_install.json b/examples/java-spring-boot-service/maven_install.json new file mode 100755 index 000000000..8e559f14a --- /dev/null +++ b/examples/java-spring-boot-service/maven_install.json @@ -0,0 +1,2589 @@ +{ + "__AUTOGENERATED_FILE_DO_NOT_MODIFY_THIS_FILE_MANUALLY": "THERE_IS_NO_DATA_ONLY_ZUUL", + "__INPUT_ARTIFACTS_HASH": { + "com.google.code.findbugs:jsr305": 495355163, + "com.google.code.gson:gson": 597770368, + "com.google.errorprone:error_prone_annotations": -1035138750, + "com.google.guava:guava": 1943808618, + "com.google.j2objc:j2objc-annotations": 2003271689, + "net.javacrumbs.shedlock:shedlock-bom": -1406345450, + "org.junit.jupiter:junit-jupiter-api": 194920406, + "org.junit.jupiter:junit-jupiter-engine": -1886863302, + "org.junit.platform:junit-platform-launcher": -354104948, + "org.junit.platform:junit-platform-reporting": 1896713402, + "org.springframework.boot:spring-boot-dependencies": 70164638, + "org.springframework.boot:spring-boot-starter-test": -1561809354, + "org.springframework.boot:spring-boot-starter-web": -1905796688, + "org.springframework.boot:spring-boot-webmvc-test": -490892141, + "org.springframework.cloud:spring-cloud-dependencies": 46341733, + "org.testcontainers:testcontainers-bom": 483223872, + "repositories": -1624298853 + }, + "__RESOLVED_ARTIFACTS_HASH": { + "ch.qos.logback:logback-classic": -619930806, + "ch.qos.logback:logback-classic:jar:sources": -390128445, + "ch.qos.logback:logback-core": -1554021729, + "ch.qos.logback:logback-core:jar:sources": 77538609, + "com.fasterxml.jackson.core:jackson-annotations": 1407322119, + "com.fasterxml.jackson.core:jackson-annotations:jar:sources": -1408285999, + "com.google.code.findbugs:jsr305": -1038659426, + "com.google.code.findbugs:jsr305:jar:sources": -1300148931, + "com.google.code.gson:gson": 1618556651, + "com.google.code.gson:gson:jar:sources": 389178860, + "com.google.errorprone:error_prone_annotations": 492382488, + "com.google.errorprone:error_prone_annotations:jar:sources": 456515251, + "com.google.guava:failureaccess": -268223546, + "com.google.guava:failureaccess:jar:sources": 2053502918, + "com.google.guava:guava": 1240305771, + "com.google.guava:guava:jar:sources": 1591586943, + "com.google.guava:listenablefuture": 1588902908, + "com.google.j2objc:j2objc-annotations": -596695707, + "com.google.j2objc:j2objc-annotations:jar:sources": 900785715, + "com.jayway.jsonpath:json-path": -317990331, + "com.jayway.jsonpath:json-path:jar:sources": -343427302, + "com.vaadin.external.google:android-json": -1531950165, + "com.vaadin.external.google:android-json:jar:sources": -116078240, + "commons-logging:commons-logging": 1061992981, + "commons-logging:commons-logging:jar:sources": 1867783947, + "io.micrometer:micrometer-commons": 326693391, + "io.micrometer:micrometer-commons:jar:sources": -57818626, + "io.micrometer:micrometer-observation": -319705914, + "io.micrometer:micrometer-observation:jar:sources": 1279306785, + "jakarta.activation:jakarta.activation-api": -1560267684, + "jakarta.activation:jakarta.activation-api:jar:sources": 759160467, + "jakarta.annotation:jakarta.annotation-api": -1904975463, + "jakarta.annotation:jakarta.annotation-api:jar:sources": -247204066, + "jakarta.xml.bind:jakarta.xml.bind-api": 1157993223, + "jakarta.xml.bind:jakarta.xml.bind-api:jar:sources": -945798747, + "net.bytebuddy:byte-buddy": 383637760, + "net.bytebuddy:byte-buddy-agent": -1380713096, + "net.bytebuddy:byte-buddy-agent:jar:sources": 564051985, + "net.bytebuddy:byte-buddy:jar:sources": -1360611642, + "net.minidev:accessors-smart": 826413906, + "net.minidev:accessors-smart:jar:sources": -124254155, + "net.minidev:json-smart": 656696918, + "net.minidev:json-smart:jar:sources": -1084786431, + "org.apache.logging.log4j:log4j-api": 191755139, + "org.apache.logging.log4j:log4j-api:jar:sources": 1226633672, + "org.apache.logging.log4j:log4j-to-slf4j": 357996538, + "org.apache.logging.log4j:log4j-to-slf4j:jar:sources": -1847454236, + "org.apache.tomcat.embed:tomcat-embed-core": -2079786590, + "org.apache.tomcat.embed:tomcat-embed-core:jar:sources": -745705587, + "org.apache.tomcat.embed:tomcat-embed-el": -727131551, + "org.apache.tomcat.embed:tomcat-embed-el:jar:sources": 1938415424, + "org.apache.tomcat.embed:tomcat-embed-websocket": 1876889190, + "org.apache.tomcat.embed:tomcat-embed-websocket:jar:sources": -1809736441, + "org.apiguardian:apiguardian-api": -1579303244, + "org.apiguardian:apiguardian-api:jar:sources": 768152577, + "org.assertj:assertj-core": -536770136, + "org.assertj:assertj-core:jar:sources": -1826278818, + "org.awaitility:awaitility": 755971515, + "org.awaitility:awaitility:jar:sources": -1322650242, + "org.checkerframework:checker-qual": -2018582244, + "org.checkerframework:checker-qual:jar:sources": 2110417205, + "org.hamcrest:hamcrest": 1116842741, + "org.hamcrest:hamcrest:jar:sources": -996443755, + "org.jspecify:jspecify": -1402924792, + "org.jspecify:jspecify:jar:sources": -841008091, + "org.junit.jupiter:junit-jupiter": -313198921, + "org.junit.jupiter:junit-jupiter-api": 80944698, + "org.junit.jupiter:junit-jupiter-api:jar:sources": -1650654944, + "org.junit.jupiter:junit-jupiter-engine": 730848020, + "org.junit.jupiter:junit-jupiter-engine:jar:sources": 1805473715, + "org.junit.jupiter:junit-jupiter-params": -1923494954, + "org.junit.jupiter:junit-jupiter-params:jar:sources": 1561682205, + "org.junit.jupiter:junit-jupiter:jar:sources": 1809716175, + "org.junit.platform:junit-platform-commons": -1304725543, + "org.junit.platform:junit-platform-commons:jar:sources": -139331649, + "org.junit.platform:junit-platform-engine": -748595950, + "org.junit.platform:junit-platform-engine:jar:sources": -191078126, + "org.junit.platform:junit-platform-launcher": 1722101087, + "org.junit.platform:junit-platform-launcher:jar:sources": -717285440, + "org.junit.platform:junit-platform-reporting": 1847654060, + "org.junit.platform:junit-platform-reporting:jar:sources": -1771745730, + "org.mockito:mockito-core": 734095861, + "org.mockito:mockito-core:jar:sources": 1757924088, + "org.mockito:mockito-junit-jupiter": -501680015, + "org.mockito:mockito-junit-jupiter:jar:sources": -1281757309, + "org.objenesis:objenesis": 1083875484, + "org.objenesis:objenesis:jar:sources": 703772823, + "org.opentest4j.reporting:open-test-reporting-tooling-spi": -1639379357, + "org.opentest4j.reporting:open-test-reporting-tooling-spi:jar:sources": 1632689314, + "org.opentest4j:opentest4j": 793813175, + "org.opentest4j:opentest4j:jar:sources": 1210936723, + "org.ow2.asm:asm": -1193893588, + "org.ow2.asm:asm:jar:sources": 95374349, + "org.skyscreamer:jsonassert": -1571197746, + "org.skyscreamer:jsonassert:jar:sources": -392658057, + "org.slf4j:jul-to-slf4j": -911724984, + "org.slf4j:jul-to-slf4j:jar:sources": -662175280, + "org.slf4j:slf4j-api": -1249720338, + "org.slf4j:slf4j-api:jar:sources": -297247278, + "org.springframework.boot:spring-boot": -1519545366, + "org.springframework.boot:spring-boot-autoconfigure": -491644458, + "org.springframework.boot:spring-boot-autoconfigure:jar:sources": 562322138, + "org.springframework.boot:spring-boot-http-converter": -1456188332, + "org.springframework.boot:spring-boot-http-converter:jar:sources": 678862764, + "org.springframework.boot:spring-boot-jackson": -886310726, + "org.springframework.boot:spring-boot-jackson:jar:sources": -928970153, + "org.springframework.boot:spring-boot-servlet": -1040246830, + "org.springframework.boot:spring-boot-servlet:jar:sources": 1162002660, + "org.springframework.boot:spring-boot-starter": 191814674, + "org.springframework.boot:spring-boot-starter-jackson": 211326145, + "org.springframework.boot:spring-boot-starter-jackson:jar:sources": 1689728463, + "org.springframework.boot:spring-boot-starter-logging": 51215582, + "org.springframework.boot:spring-boot-starter-logging:jar:sources": 1271111015, + "org.springframework.boot:spring-boot-starter-test": -1546680330, + "org.springframework.boot:spring-boot-starter-test:jar:sources": -480189945, + "org.springframework.boot:spring-boot-starter-tomcat": -521361670, + "org.springframework.boot:spring-boot-starter-tomcat-runtime": -1912812722, + "org.springframework.boot:spring-boot-starter-tomcat-runtime:jar:sources": 1011838045, + "org.springframework.boot:spring-boot-starter-tomcat:jar:sources": 1319064174, + "org.springframework.boot:spring-boot-starter-web": 1122240419, + "org.springframework.boot:spring-boot-starter-web:jar:sources": -768709610, + "org.springframework.boot:spring-boot-starter:jar:sources": 1138639700, + "org.springframework.boot:spring-boot-test": -927444958, + "org.springframework.boot:spring-boot-test-autoconfigure": -669950838, + "org.springframework.boot:spring-boot-test-autoconfigure:jar:sources": 392165449, + "org.springframework.boot:spring-boot-test:jar:sources": -1764708648, + "org.springframework.boot:spring-boot-tomcat": -1113349252, + "org.springframework.boot:spring-boot-tomcat:jar:sources": -1529683395, + "org.springframework.boot:spring-boot-web-server": 285708094, + "org.springframework.boot:spring-boot-web-server:jar:sources": 990724443, + "org.springframework.boot:spring-boot-webmvc": -2104103221, + "org.springframework.boot:spring-boot-webmvc-test": 749235095, + "org.springframework.boot:spring-boot-webmvc-test:jar:sources": 444837917, + "org.springframework.boot:spring-boot-webmvc:jar:sources": -1895028417, + "org.springframework.boot:spring-boot:jar:sources": 580880564, + "org.springframework:spring-aop": -819786825, + "org.springframework:spring-aop:jar:sources": 1924976574, + "org.springframework:spring-beans": -698130853, + "org.springframework:spring-beans:jar:sources": -2147408778, + "org.springframework:spring-context": -846077202, + "org.springframework:spring-context:jar:sources": -1263444176, + "org.springframework:spring-core": -253727183, + "org.springframework:spring-core:jar:sources": -173347576, + "org.springframework:spring-expression": 1724609785, + "org.springframework:spring-expression:jar:sources": 1135225455, + "org.springframework:spring-test": -279979944, + "org.springframework:spring-test:jar:sources": -6017836, + "org.springframework:spring-web": 2084009704, + "org.springframework:spring-web:jar:sources": 1608360284, + "org.springframework:spring-webmvc": 56813816, + "org.springframework:spring-webmvc:jar:sources": -837106767, + "org.xmlunit:xmlunit-core": 1938864481, + "org.xmlunit:xmlunit-core:jar:sources": -54376142, + "org.yaml:snakeyaml": -1432706414, + "org.yaml:snakeyaml:jar:sources": 393768628, + "tools.jackson.core:jackson-core": -1258054011, + "tools.jackson.core:jackson-core:jar:sources": -1689479769, + "tools.jackson.core:jackson-databind": 1443518747, + "tools.jackson.core:jackson-databind:jar:sources": -871567409 + }, + "artifacts": { + "ch.qos.logback:logback-classic": { + "shasums": { + "jar": "b65e05076a5c1aadb659b4fe4bc5fee31cb26cd70390292eb03e4a7a24cff10f", + "sources": "c2e39cb4d6d9b8c2343c6da2469e21e1d6aef2dde16c2227762c084d549ad0a0" + }, + "version": "1.5.34" + }, + "ch.qos.logback:logback-core": { + "shasums": { + "jar": "42eda264c0c650c2bec59e66151a88b708a8663dc1b49d788202d53e78b8caae", + "sources": "6a9f217ef206caf2880810c505e057fd2bb90a6024013906815e9513c6e488c5" + }, + "version": "1.5.34" + }, + "com.fasterxml.jackson.core:jackson-annotations": { + "shasums": { + "jar": "53ca085f4a150f703f49e1aabd935bd03b43e1ea3d55d135438292af22cef56b", + "sources": "71fe6323d91b16d5d1007fd1e1533fa06bb369abde74f68a42a68c0f8f061a8b" + }, + "version": "2.21" + }, + "com.google.code.findbugs:jsr305": { + "shasums": { + "jar": "766ad2a0783f2687962c8ad74ceecc38a28b9f72a2d085ee438b7813e928d0c7", + "sources": "1c9e85e272d0708c6a591dc74828c71603053b48cc75ae83cce56912a2aa063b" + }, + "version": "3.0.2" + }, + "com.google.code.gson:gson": { + "shasums": { + "jar": "d3999291855de495c94c743761b8ab5176cfeabe281a5ab0d8e8d45326fd703e", + "sources": "ba5bddb1a89eb721fcca39f3b34294532060f851e2407a82d82134a41eec4719" + }, + "version": "2.8.9" + }, + "com.google.errorprone:error_prone_annotations": { + "shasums": { + "jar": "ff80626baaf12a09342befd4e84cba9d50662f5fcd7f7a9b3490a6b7cf87e66c", + "sources": "bf08616e340f5e2ef50aaa84aea8baa086fd7bb2ad310501ff4e88ec77f8f31a" + }, + "version": "2.5.1" + }, + "com.google.guava:failureaccess": { + "shasums": { + "jar": "a171ee4c734dd2da837e4b16be9df4661afab72a41adaf31eb84dfdaf936ca26", + "sources": "092346eebbb1657b51aa7485a246bf602bb464cc0b0e2e1c7e7201fadce1e98f" + }, + "version": "1.0.1" + }, + "com.google.guava:guava": { + "shasums": { + "jar": "bd7fa227591fb8509677d0d1122cf95158f3b8a9f45653f58281d879f6dc48c5", + "sources": "9105dfc522fb440b39ff8da07cc56aacf65a9f765044c7803a9f32e36e05a22b" + }, + "version": "32.0.1-jre" + }, + "com.google.guava:listenablefuture": { + "shasums": { + "jar": "b372a037d4230aa57fbeffdef30fd6123f9c0c2db85d0aced00c91b974f33f99" + }, + "version": "9999.0-empty-to-avoid-conflict-with-guava" + }, + "com.google.j2objc:j2objc-annotations": { + "shasums": { + "jar": "f02a95fa1a5e95edb3ed859fd0fb7df709d121a35290eff8b74dce2ab7f4d6ed", + "sources": "7413eed41f111453a08837f5ac680edded7faed466cbd35745e402e13f4cc3f5" + }, + "version": "2.8" + }, + "com.jayway.jsonpath:json-path": { + "shasums": { + "jar": "890daa95dd3892d34d9fabc27cd5153656e6f369358625c88f4dc7b79cbd6c5a", + "sources": "357f1c52217497c4251fae715ba8ef76ae310b1aae77ea319260bf4c6ad61440" + }, + "version": "2.10.0" + }, + "com.vaadin.external.google:android-json": { + "shasums": { + "jar": "dfb7bae2f404cfe0b72b4d23944698cb716b7665171812a0a4d0f5926c0fac79", + "sources": "54c781eea645c450cbbc4a5a1b5a474745465452cec1354cb567b781ea6622c3" + }, + "version": "0.0.20131108.vaadin1" + }, + "commons-logging:commons-logging": { + "shasums": { + "jar": "f8ead8943401081dea0aa824b5b1ba40a0e4ed297a572a0f02258150a0b62357", + "sources": "6e821e03cfc64e509cc162d428af84697b6c4188eb14c0b137c75b69649976ef" + }, + "version": "1.3.6" + }, + "io.micrometer:micrometer-commons": { + "shasums": { + "jar": "45aff76226830db257f4bc39a5bcff83d633e572fee9dc4e45cfa12af9a0a49a", + "sources": "0e4a336c7bca50bfa6cbea274ea681e42d86bfdac1038af3041301c8454f76ff" + }, + "version": "1.16.6" + }, + "io.micrometer:micrometer-observation": { + "shasums": { + "jar": "4c0826d5e7c8522a8e111470b4e77f77b0a10f520eb5502ddd143fdbcedb2340", + "sources": "ff5525482df358e7502d4c8680fb654ec700e3b01341149d870bd6cfd8ce04c0" + }, + "version": "1.16.6" + }, + "jakarta.activation:jakarta.activation-api": { + "shasums": { + "jar": "c9db52100ce6c8aac95cc39075f95720d2e561b11f8051b81c121ad4effd7004", + "sources": "2aa5a3ba55059b778a3b467269404d7ac3b9485ed4a23ad26d2e63aa769ec35f" + }, + "version": "2.1.4" + }, + "jakarta.annotation:jakarta.annotation-api": { + "shasums": { + "jar": "b01f55552284cfb149411e64eabca75e942d26d2e1786b32914250e4330afaa2", + "sources": "142dfd2343429df2aac3e1cfacfacc21c8393112c0e0280d3628648d9b612470" + }, + "version": "3.0.0" + }, + "jakarta.xml.bind:jakarta.xml.bind-api": { + "shasums": { + "jar": "5e489b6c874c4119e003ff1403db523ee3a8959ec499f3de29e77245efccf216", + "sources": "5bcf811e6719582ab2be21c84bc48f963ba377dfe1dae5ecb2673c1efa00e422" + }, + "version": "4.0.5" + }, + "net.bytebuddy:byte-buddy": { + "shasums": { + "jar": "2b5ddc8c1f4234bdb7cb45338a8e10a13e0e3ca473e91d5d821d681127ea8ba1", + "sources": "5211140f46c380a5e9630a86b2c07b396a9c374128fa603ca1d321b3c7da7449" + }, + "version": "1.17.8" + }, + "net.bytebuddy:byte-buddy-agent": { + "shasums": { + "jar": "5b17113e66e77ca6f8af07ff367c216df964a980f0e9f11e3b1aa793253aa64f", + "sources": "a205437d772e3edaf4a7a1a709e9d59c666e8a05218d0e000deb5651c52de2d2" + }, + "version": "1.17.8" + }, + "net.minidev:accessors-smart": { + "shasums": { + "jar": "222c9f547bb20a99fc486403a398352d1306fb671b38abd7ecab6401df170e61", + "sources": "10880e44ed732de27ae424a9698a041c398102098b5b1bae3cc597ec62dac43e" + }, + "version": "2.6.0" + }, + "net.minidev:json-smart": { + "shasums": { + "jar": "1ae4b561458afb540be8ec5c6dbb4f2e715a319a7ae64854998aaf924770d61b", + "sources": "a4af3f3773286fe3f76f94d38d977611fd2493685f589466b76dd25cf70b400c" + }, + "version": "2.6.0" + }, + "org.apache.logging.log4j:log4j-api": { + "shasums": { + "jar": "c4b642a7f047275215de117e0e3847eb2c7711d84a0aa7433e7b3c096daf341d", + "sources": "b86680bcf8ffa25897b6114cae508bb8e6ecac8081a0fc8985e0c00e27d4f4ec" + }, + "version": "2.25.4" + }, + "org.apache.logging.log4j:log4j-to-slf4j": { + "shasums": { + "jar": "d7b78fc0aaaa5e8ada388b29d718b0ab187e512965bed0b259bb4ab299f13db2", + "sources": "ca9159da173bf88fb621adf745fe1d313ba4074f4c66576ae70f5dd99eab89c9" + }, + "version": "2.25.4" + }, + "org.apache.tomcat.embed:tomcat-embed-core": { + "shasums": { + "jar": "78cd7cd7c104b6b87142c1b0bd902e1ce005b0245c3cefa8a06759148947200b", + "sources": "0bfbdc27e60d4db5b83e0f51193bae5f4bd02ac270fd78b06945e219fc473359" + }, + "version": "11.0.22" + }, + "org.apache.tomcat.embed:tomcat-embed-el": { + "shasums": { + "jar": "1b34c33b858c141df36c501b4d809e68036c406bca3671a86facae297917c7de", + "sources": "da3724004575f5c8fa7e45649f2900ec53e7ecfb502b6ce227ca9cf86b36a156" + }, + "version": "11.0.22" + }, + "org.apache.tomcat.embed:tomcat-embed-websocket": { + "shasums": { + "jar": "210e0c7ab194a76cc7283df0be365276091b042369dae125fb477828ba67e922", + "sources": "711f09af528ac5af172c664244bcba4748eac00811ef7c6b52ddd6836b5a4a28" + }, + "version": "11.0.22" + }, + "org.apiguardian:apiguardian-api": { + "shasums": { + "jar": "b509448ac506d607319f182537f0b35d71007582ec741832a1f111e5b5b70b38", + "sources": "277a7a4315412817beb6655b324dc7276621e95ebff00b8bf65e17a27b685e2d" + }, + "version": "1.1.2" + }, + "org.assertj:assertj-core": { + "shasums": { + "jar": "c4a445426c3c2861666863b842cc4ec7bbb1c4226fefd370b6d2fe83d6c4ff0f", + "sources": "5ba6de05730cf76021001f8437f35db4cb5b513465d4ace8c3a6fcd68d9a19ee" + }, + "version": "3.27.7" + }, + "org.awaitility:awaitility": { + "shasums": { + "jar": "ee58568ea5945dcf988551501655183dc184e23e45a8e013fdfd9036194e6f7b", + "sources": "92d209bd0135b04ca6bb7689c6b921819896ec2d517a5357760f598faafee46c" + }, + "version": "4.3.0" + }, + "org.checkerframework:checker-qual": { + "shasums": { + "jar": "e316255bbfcd9fe50d165314b85abb2b33cb2a66a93c491db648e498a82c2de1", + "sources": "443fa6151982bb4c6ce62e2938f53660085b13a7dceb517202777b87d0dea2c7" + }, + "version": "3.33.0" + }, + "org.hamcrest:hamcrest": { + "shasums": { + "jar": "5d66b6a4a680755cb6ed7cb104fa7835ef644667586ff0737adeb977c39ecdbc", + "sources": "7a4050b1898f7e1aa395cf2be78fb6683f9e2766fcb8e1507926b204fa24d1bf" + }, + "version": "3.0" + }, + "org.jspecify:jspecify": { + "shasums": { + "jar": "1fad6e6be7557781e4d33729d49ae1cdc8fdda6fe477bb0cc68ce351eafdfbab", + "sources": "adf0898191d55937fb3192ba971826f4f294292c4a960740f3c27310e7b70296" + }, + "version": "1.0.0" + }, + "org.junit.jupiter:junit-jupiter": { + "shasums": { + "jar": "784b65815f479a0c99a9d3a573b142e2a525efb6025d97f751b19e72f90aeda3", + "sources": "402f86a4fdce930bb68b592f2ed5a9d57dc4d1b2747aa2d66c0b3cb7a2adceeb" + }, + "version": "6.0.3" + }, + "org.junit.jupiter:junit-jupiter-api": { + "shasums": { + "jar": "d655d7e6f0c7ae07f10a2f3bbaaebb6d30e9b26204a068ad9e9b3950aa28792c", + "sources": "8266d8da51d0c7d6a2ed4895a3cb76e0ec22194907f24364f2a4f3efd05f00a5" + }, + "version": "6.0.3" + }, + "org.junit.jupiter:junit-jupiter-engine": { + "shasums": { + "jar": "1e2fab61ad27ea08fc7c70dd9677cf8c6d1ae5434d42dcfdd633b12c7e7c04d0", + "sources": "35706a9edf1b580bf22d6eca9d6a9165f478f75b0108840ad6f31481cd662d6c" + }, + "version": "6.0.3" + }, + "org.junit.jupiter:junit-jupiter-params": { + "shasums": { + "jar": "cf2947e2302b9f8c8a059259a277881c1cadae8fbc2514c16a925cfeb7beb2e5", + "sources": "f0dcf217100b06b98cd36c2e74fb919c74e3024faad868bac9eba6ff00c7c263" + }, + "version": "6.0.3" + }, + "org.junit.platform:junit-platform-commons": { + "shasums": { + "jar": "39f262d09c3d52719fe0b77f080e90a3695e285d779a41b232e17963ae5da200", + "sources": "06cbe4a4bbd79339c3817983510cf3adc3d6a88a8a556c80c5b84eeb1ebd13dc" + }, + "version": "6.0.3" + }, + "org.junit.platform:junit-platform-engine": { + "shasums": { + "jar": "491e9e4f745f161b8a8e4186a1a7c6a450ea12c70930c9aedae427215301d947", + "sources": "89a893566a97557dbbcb0706d9b5565c4e7a402050841753dc527f3e9139c9ac" + }, + "version": "6.0.3" + }, + "org.junit.platform:junit-platform-launcher": { + "shasums": { + "jar": "315608372e4dc44bca0ccb3ae8a07ecc206b3367033fa05748a03ccd563f1301", + "sources": "4fcbdb81cc882c0c3e73f742878db5884d3d2f86facc08369ca953e32796d144" + }, + "version": "6.0.3" + }, + "org.junit.platform:junit-platform-reporting": { + "shasums": { + "jar": "f19c5be871c37ebed493f3152b67a909f89a44dff67c2db8016dfe34167d5730", + "sources": "bbdda2b9c002dbd1b05cfec144bab91e8cca46ed8d58525f51b547f3a0a84a7d" + }, + "version": "6.0.3" + }, + "org.mockito:mockito-core": { + "shasums": { + "jar": "d1a96d252128d3a4247cfd8a2e76412efa3cc103977be17933c942117a24f374", + "sources": "dcde489c1db6449c162f05105ace4c172850d3dc7f6633bb4f54d47a16a0fd1b" + }, + "version": "5.20.0" + }, + "org.mockito:mockito-junit-jupiter": { + "shasums": { + "jar": "fd6c703c2b00b914f3adbc27b18077a708f3d6992f19242c444e737c6cce024e", + "sources": "3c199479a2319db4395fd9fd209946ecc4530f48fe5cdeed7677c285bf70fbb5" + }, + "version": "5.20.0" + }, + "org.objenesis:objenesis": { + "shasums": { + "jar": "02dfd0b0439a5591e35b708ed2f5474eb0948f53abf74637e959b8e4ef69bfeb", + "sources": "d06164f8ca002c8ef193cef2d682822014dd330505616af93a3fb64226fc131d" + }, + "version": "3.3" + }, + "org.opentest4j.reporting:open-test-reporting-tooling-spi": { + "shasums": { + "jar": "04ac4ecfcaf60abe0e6d5b18e8306320aec7cd9cbf15e59eeac54fa9faa16902", + "sources": "efe9672e74111726c0ff85a2508a0bc78be611a7cbe460560dc7cd429ee0a4ce" + }, + "version": "0.2.4" + }, + "org.opentest4j:opentest4j": { + "shasums": { + "jar": "48e2df636cab6563ced64dcdff8abb2355627cb236ef0bf37598682ddf742f1b", + "sources": "724a24e3a68267d5ebac9411389a15638a71e50c62448ffa58f59c34d5c1ebb2" + }, + "version": "1.3.0" + }, + "org.ow2.asm:asm": { + "shasums": { + "jar": "8cadd43ac5eb6d09de05faecca38b917a040bb9139c7edeb4cc81c740b713281", + "sources": "22e9507b0c494daaedb33b8148c30cd618c6dacc3992be8b50eaaafeb6a8ba8d" + }, + "version": "9.7.1" + }, + "org.skyscreamer:jsonassert": { + "shasums": { + "jar": "719095c07d4203961320da593441d8b3b643c18eb1d81aa98ea933bb7eb351ba", + "sources": "a825c29f8cc40f85ea4e7a431a55d4278a785c34acdeef4cd1be7367f70ea6bb" + }, + "version": "1.5.3" + }, + "org.slf4j:jul-to-slf4j": { + "shasums": { + "jar": "cbb7d1aaaa9e871eb1a06594abd911bf97027152976edf1edc315be75239204e", + "sources": "b6dd2138f3e83d876bf07206d09f2b48ca655bc36a8e80b0c2a32ad19ab8f1d5" + }, + "version": "2.0.18" + }, + "org.slf4j:slf4j-api": { + "shasums": { + "jar": "44508fd1576500688c790b190acdd16fec4f8c79a3e0b900afd70503cf055f55", + "sources": "192e007cf7f2be41d40574e44521fc0b7ce55e01f13dbe0fa8707c8ae3329075" + }, + "version": "2.0.18" + }, + "org.springframework.boot:spring-boot": { + "shasums": { + "jar": "edb984d0bc80d209bed271e6d334fbfbfcf11cc4c1ef5059adc31c5bde7b1d7c", + "sources": "850ec7c91b0ff92c46797e0adcf1f47369d64a0cf4a8427d01b4834df129d0d4" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-autoconfigure": { + "shasums": { + "jar": "1e8a953294fe76727965970de31e3bb08fba2b65e3ca0ee9b8bca492d0818d10", + "sources": "477e9834d7982b080b485c7baeb27ea399fca324d0442dc2f694a473b6a394fd" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-http-converter": { + "shasums": { + "jar": "9f620c36cb98103ef664a9fccad4173ae20120d1abc790b795130be4e02dbb90", + "sources": "9f4378bcb3caa6696d8fe340c519bd673287f2c046098607cbe079ba9aa98874" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-jackson": { + "shasums": { + "jar": "0cdbadd10bcc3b23d32dffd419caceda4a4ed6b3da0262617f543732e9105ece", + "sources": "efe6e9f38861e94fbf36045bb23d23076407d26fed5752efb852ad2accaea3bb" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-servlet": { + "shasums": { + "jar": "fb1af769617daa2808a82921d98ca94efde8cb20fcefc55e71b2e0bf93de1423", + "sources": "172a6736933d75bdeeee725078769e27d8142a826e811940c595aea815913512" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-starter": { + "shasums": { + "jar": "d70f5f300c9e7af18813799bffce38974398f6429c578c825822a32560c4b202", + "sources": "d70f5f300c9e7af18813799bffce38974398f6429c578c825822a32560c4b202" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-starter-jackson": { + "shasums": { + "jar": "bd042218bf291c4ee821d7ec3e86f7f747223d32cd87066aa5e3730a2dd5c3b6", + "sources": "bd042218bf291c4ee821d7ec3e86f7f747223d32cd87066aa5e3730a2dd5c3b6" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-starter-logging": { + "shasums": { + "jar": "b5f1d01cd179ffc24b125a6ce971854b7b141c4e19e9c050a0b82d514983b1f6", + "sources": "b5f1d01cd179ffc24b125a6ce971854b7b141c4e19e9c050a0b82d514983b1f6" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-starter-test": { + "shasums": { + "jar": "e4844ae2375d569711af218763620993ea434b4836d3463cf26d9f6b6e589340", + "sources": "e4844ae2375d569711af218763620993ea434b4836d3463cf26d9f6b6e589340" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-starter-tomcat": { + "shasums": { + "jar": "f4a81ce616baa9c715be0dc0735210d770aa67301f92d3b11942f780056fc7ad", + "sources": "f4a81ce616baa9c715be0dc0735210d770aa67301f92d3b11942f780056fc7ad" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-starter-tomcat-runtime": { + "shasums": { + "jar": "8d0c7cbd6bd43d47e664a9127f70ceddab952828797f20e2b0b93848796d82f2", + "sources": "8d0c7cbd6bd43d47e664a9127f70ceddab952828797f20e2b0b93848796d82f2" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-starter-web": { + "shasums": { + "jar": "1ac009b240450c089df7ef1e5cc9b63df292bea22393ed5c7deca42c85944e3c", + "sources": "1ac009b240450c089df7ef1e5cc9b63df292bea22393ed5c7deca42c85944e3c" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-test": { + "shasums": { + "jar": "8879b4a336972eb498ca6606266e6ecdae911964c0a480d3f4bf37a6c2455b33", + "sources": "4dc67a1a332d75fa3dcf517f4b6dc66ed146793307aa9d23c0ebb5f4b399850a" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-test-autoconfigure": { + "shasums": { + "jar": "99ca7ab8be0dde10fa6c03e1026969619e826fcc914b6bc0d09090e75ba17cb4", + "sources": "f94cf34c24539cc3752fae1a0bf182282086452e9c83cfae5241574f20951eb3" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-tomcat": { + "shasums": { + "jar": "ad7c6527319f5cac0b5638a28820847f64d21282147fb98daaaa1f515ee17323", + "sources": "2388d2eaeb9d413d3d7525983fe14030d3b48bc0cca1530c8c7e9dc73e05e8b5" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-web-server": { + "shasums": { + "jar": "26a13c73ee85e7a851b73eb2d683ed4d3b7a4ca581b608dfd627bd4551997cf2", + "sources": "41e1dddf6e1be5fc35c4849f51639c097e7a8eb9c6627a780791a1d9e430c311" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-webmvc": { + "shasums": { + "jar": "95250948bda9a0a1e1f2ad3f413bd23e36dfedefb89fe59d309d447c6c4c5010", + "sources": "26a04367e170092463c619c886f4f8b688644eecc4a6c91c18d17c242a8f4211" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-webmvc-test": { + "shasums": { + "jar": "06180d3ee7f9019880b0528cc93164f8f038e35007bd99a40fbe52892d96a955", + "sources": "4c5b614a96d50a44fce7c3269b82f26fed6d3d04933140ecf52db5e4d32e2480" + }, + "version": "4.0.7" + }, + "org.springframework:spring-aop": { + "shasums": { + "jar": "1178f039e087884174e2affc46e484f4a8bd7f2a4e011d33dd9137709f740f80", + "sources": "580610d9e5e2418ea48f64850673ed1d1fdc2d9c8e5cf6e9cfaece1e61b70522" + }, + "version": "7.0.8" + }, + "org.springframework:spring-beans": { + "shasums": { + "jar": "6ec2e361a8872a71d8b1ff66f1bcb8cfa29fcc437931998919da7cecfb59b45b", + "sources": "d75bdcfe142b1576f72356748292cad5c21872a52be2c7f2920a9795bb3c52a5" + }, + "version": "7.0.8" + }, + "org.springframework:spring-context": { + "shasums": { + "jar": "1eb7d552414ebac00e30ab3e809138d810785f6d2c4271db77cdf0181f308f19", + "sources": "a28b30679b51bcf8aac7f06cb564a379cc2d6c4891b2e2dfc738ddd750c6278e" + }, + "version": "7.0.8" + }, + "org.springframework:spring-core": { + "shasums": { + "jar": "726ba2a5130833644bdf267a55ff26e1f52e8dcc9aa1ffa06904ca9c14619f25", + "sources": "3cbdaed9f2b1eea10d8ac27148ac5e6407d2861fa2d373253a09a1220a232919" + }, + "version": "7.0.8" + }, + "org.springframework:spring-expression": { + "shasums": { + "jar": "3c97c38ab59c77ee886e08ccf8096f6bb58a1245f68dfed7a40e93f41c435f9a", + "sources": "35517249c504d1d4550186808665587c8bb5be953cb6cbbb3856804194e790e9" + }, + "version": "7.0.8" + }, + "org.springframework:spring-test": { + "shasums": { + "jar": "6ffb7796075a204915edc4bb9e54dc420183cecb520d753004f660f153763c8e", + "sources": "7bc670e2e1c9cc902da5557a857dde0a4d8089c267ccfcc1bb554cbf2a8c5a05" + }, + "version": "7.0.8" + }, + "org.springframework:spring-web": { + "shasums": { + "jar": "4d4ed7ecb0453d25d735ea27d025ea36b003c3d29cb7d006bedd6d5188a2f5c0", + "sources": "281cbbd965844cdf2e08396924eacd8a369cd38f56fdfb9519c7492217d8b411" + }, + "version": "7.0.8" + }, + "org.springframework:spring-webmvc": { + "shasums": { + "jar": "48f7e1e2d0d46e98ed3fa30d5a64cb1f7ed2aa339a82edcd87289ed8ff216f04", + "sources": "6dcbc3dc4d5222121f83d1eb0d30807e389771b8d233be38b8e413b92b88a106" + }, + "version": "7.0.8" + }, + "org.xmlunit:xmlunit-core": { + "shasums": { + "jar": "208e0cee82aedd9183937e4b9ae44b83884179f724a706bef5795477acfcca91", + "sources": "bb8dba65e8bc1ade346e4bfd98d7f620f51ae8b9034e9758cd6f3031838e79fd" + }, + "version": "2.10.4" + }, + "org.yaml:snakeyaml": { + "shasums": { + "jar": "e6682acf1ace77508ef13649cbf4f8d09d2cf5457bdb61d25ffb6ac0233d78dd", + "sources": "7a7d307ca9fe1663219a60045a8e5a113a69331566f9ebbe1d3b12c6781909ac" + }, + "version": "2.5" + }, + "tools.jackson.core:jackson-core": { + "shasums": { + "jar": "3bda1cd6eff0a8d47bdfcaeae7c2bd5311d6c8ed494ef5f3e51029bb44aa9bdf", + "sources": "5aa481c1c120505fc1d204510ec201a40c2bb0bb6bdea24560e0b5fb66484e60" + }, + "version": "3.1.4" + }, + "tools.jackson.core:jackson-databind": { + "shasums": { + "jar": "14034bfdf392b6ebec1b4bb6c1de29d604f0aa97251259a19d5f19af8719bb20", + "sources": "109baa39968ff6fdcc4389dd4249f04d2edcab7387421ea17bfb51bf18e24189" + }, + "version": "3.1.4" + } + }, + "dependencies": { + "ch.qos.logback:logback-classic": [ + "ch.qos.logback:logback-core", + "org.slf4j:slf4j-api" + ], + "com.google.guava:guava": [ + "com.google.code.findbugs:jsr305", + "com.google.errorprone:error_prone_annotations", + "com.google.guava:failureaccess", + "com.google.guava:listenablefuture", + "com.google.j2objc:j2objc-annotations", + "org.checkerframework:checker-qual" + ], + "com.jayway.jsonpath:json-path": [ + "net.minidev:json-smart", + "org.slf4j:slf4j-api" + ], + "io.micrometer:micrometer-commons": [ + "org.jspecify:jspecify" + ], + "io.micrometer:micrometer-observation": [ + "io.micrometer:micrometer-commons", + "org.jspecify:jspecify" + ], + "jakarta.xml.bind:jakarta.xml.bind-api": [ + "jakarta.activation:jakarta.activation-api" + ], + "net.minidev:accessors-smart": [ + "org.ow2.asm:asm" + ], + "net.minidev:json-smart": [ + "net.minidev:accessors-smart" + ], + "org.apache.logging.log4j:log4j-to-slf4j": [ + "org.apache.logging.log4j:log4j-api", + "org.slf4j:slf4j-api" + ], + "org.apache.tomcat.embed:tomcat-embed-websocket": [ + "org.apache.tomcat.embed:tomcat-embed-core" + ], + "org.assertj:assertj-core": [ + "net.bytebuddy:byte-buddy" + ], + "org.awaitility:awaitility": [ + "org.hamcrest:hamcrest" + ], + "org.junit.jupiter:junit-jupiter": [ + "org.junit.jupiter:junit-jupiter-api", + "org.junit.jupiter:junit-jupiter-engine", + "org.junit.jupiter:junit-jupiter-params" + ], + "org.junit.jupiter:junit-jupiter-api": [ + "org.apiguardian:apiguardian-api", + "org.jspecify:jspecify", + "org.junit.platform:junit-platform-commons", + "org.opentest4j:opentest4j" + ], + "org.junit.jupiter:junit-jupiter-engine": [ + "org.apiguardian:apiguardian-api", + "org.jspecify:jspecify", + "org.junit.jupiter:junit-jupiter-api", + "org.junit.platform:junit-platform-engine" + ], + "org.junit.jupiter:junit-jupiter-params": [ + "org.apiguardian:apiguardian-api", + "org.jspecify:jspecify", + "org.junit.jupiter:junit-jupiter-api" + ], + "org.junit.platform:junit-platform-commons": [ + "org.apiguardian:apiguardian-api", + "org.jspecify:jspecify" + ], + "org.junit.platform:junit-platform-engine": [ + "org.apiguardian:apiguardian-api", + "org.jspecify:jspecify", + "org.junit.platform:junit-platform-commons", + "org.opentest4j:opentest4j" + ], + "org.junit.platform:junit-platform-launcher": [ + "org.apiguardian:apiguardian-api", + "org.jspecify:jspecify", + "org.junit.platform:junit-platform-engine" + ], + "org.junit.platform:junit-platform-reporting": [ + "org.apiguardian:apiguardian-api", + "org.jspecify:jspecify", + "org.junit.platform:junit-platform-launcher", + "org.opentest4j.reporting:open-test-reporting-tooling-spi" + ], + "org.mockito:mockito-core": [ + "net.bytebuddy:byte-buddy", + "net.bytebuddy:byte-buddy-agent", + "org.objenesis:objenesis" + ], + "org.mockito:mockito-junit-jupiter": [ + "org.junit.jupiter:junit-jupiter-api", + "org.mockito:mockito-core" + ], + "org.opentest4j.reporting:open-test-reporting-tooling-spi": [ + "org.apiguardian:apiguardian-api" + ], + "org.skyscreamer:jsonassert": [ + "com.vaadin.external.google:android-json" + ], + "org.slf4j:jul-to-slf4j": [ + "org.slf4j:slf4j-api" + ], + "org.springframework.boot:spring-boot": [ + "org.springframework:spring-context", + "org.springframework:spring-core" + ], + "org.springframework.boot:spring-boot-autoconfigure": [ + "org.springframework.boot:spring-boot" + ], + "org.springframework.boot:spring-boot-http-converter": [ + "org.springframework.boot:spring-boot", + "org.springframework:spring-web" + ], + "org.springframework.boot:spring-boot-jackson": [ + "org.springframework.boot:spring-boot", + "tools.jackson.core:jackson-databind" + ], + "org.springframework.boot:spring-boot-servlet": [ + "org.springframework.boot:spring-boot", + "org.springframework:spring-web" + ], + "org.springframework.boot:spring-boot-starter": [ + "jakarta.annotation:jakarta.annotation-api", + "org.springframework.boot:spring-boot-autoconfigure", + "org.springframework.boot:spring-boot-starter-logging", + "org.yaml:snakeyaml" + ], + "org.springframework.boot:spring-boot-starter-jackson": [ + "org.springframework.boot:spring-boot-jackson", + "org.springframework.boot:spring-boot-starter" + ], + "org.springframework.boot:spring-boot-starter-logging": [ + "ch.qos.logback:logback-classic", + "org.apache.logging.log4j:log4j-to-slf4j", + "org.slf4j:jul-to-slf4j" + ], + "org.springframework.boot:spring-boot-starter-test": [ + "com.jayway.jsonpath:json-path", + "jakarta.xml.bind:jakarta.xml.bind-api", + "net.minidev:json-smart", + "org.assertj:assertj-core", + "org.awaitility:awaitility", + "org.hamcrest:hamcrest", + "org.junit.jupiter:junit-jupiter", + "org.mockito:mockito-core", + "org.mockito:mockito-junit-jupiter", + "org.skyscreamer:jsonassert", + "org.springframework.boot:spring-boot-starter", + "org.springframework.boot:spring-boot-test", + "org.springframework.boot:spring-boot-test-autoconfigure", + "org.springframework:spring-core", + "org.springframework:spring-test", + "org.xmlunit:xmlunit-core" + ], + "org.springframework.boot:spring-boot-starter-tomcat": [ + "org.springframework.boot:spring-boot-starter", + "org.springframework.boot:spring-boot-starter-tomcat-runtime", + "org.springframework.boot:spring-boot-tomcat" + ], + "org.springframework.boot:spring-boot-starter-tomcat-runtime": [ + "jakarta.annotation:jakarta.annotation-api", + "org.apache.tomcat.embed:tomcat-embed-core", + "org.apache.tomcat.embed:tomcat-embed-el", + "org.apache.tomcat.embed:tomcat-embed-websocket", + "org.springframework.boot:spring-boot-tomcat", + "org.springframework.boot:spring-boot-web-server" + ], + "org.springframework.boot:spring-boot-starter-web": [ + "org.springframework.boot:spring-boot-http-converter", + "org.springframework.boot:spring-boot-starter-jackson", + "org.springframework.boot:spring-boot-starter-tomcat", + "org.springframework.boot:spring-boot-webmvc" + ], + "org.springframework.boot:spring-boot-test": [ + "org.springframework.boot:spring-boot", + "org.springframework:spring-test" + ], + "org.springframework.boot:spring-boot-test-autoconfigure": [ + "org.springframework.boot:spring-boot-test" + ], + "org.springframework.boot:spring-boot-tomcat": [ + "jakarta.annotation:jakarta.annotation-api", + "org.apache.tomcat.embed:tomcat-embed-core", + "org.springframework.boot:spring-boot-web-server" + ], + "org.springframework.boot:spring-boot-web-server": [ + "org.springframework.boot:spring-boot", + "org.springframework:spring-web" + ], + "org.springframework.boot:spring-boot-webmvc": [ + "org.springframework.boot:spring-boot-http-converter", + "org.springframework.boot:spring-boot-servlet", + "org.springframework:spring-web", + "org.springframework:spring-webmvc" + ], + "org.springframework.boot:spring-boot-webmvc-test": [ + "org.springframework.boot:spring-boot-http-converter", + "org.springframework.boot:spring-boot-test-autoconfigure", + "org.springframework.boot:spring-boot-web-server", + "org.springframework.boot:spring-boot-webmvc" + ], + "org.springframework:spring-aop": [ + "org.springframework:spring-beans", + "org.springframework:spring-core" + ], + "org.springframework:spring-beans": [ + "org.springframework:spring-core" + ], + "org.springframework:spring-context": [ + "io.micrometer:micrometer-observation", + "org.springframework:spring-aop", + "org.springframework:spring-beans", + "org.springframework:spring-core", + "org.springframework:spring-expression" + ], + "org.springframework:spring-core": [ + "commons-logging:commons-logging", + "org.jspecify:jspecify" + ], + "org.springframework:spring-expression": [ + "org.springframework:spring-core" + ], + "org.springframework:spring-test": [ + "org.springframework:spring-core" + ], + "org.springframework:spring-web": [ + "io.micrometer:micrometer-observation", + "org.springframework:spring-beans", + "org.springframework:spring-core" + ], + "org.springframework:spring-webmvc": [ + "org.springframework:spring-aop", + "org.springframework:spring-beans", + "org.springframework:spring-context", + "org.springframework:spring-core", + "org.springframework:spring-expression", + "org.springframework:spring-web" + ], + "org.xmlunit:xmlunit-core": [ + "jakarta.xml.bind:jakarta.xml.bind-api" + ], + "tools.jackson.core:jackson-databind": [ + "com.fasterxml.jackson.core:jackson-annotations", + "tools.jackson.core:jackson-core" + ] + }, + "packages": { + "ch.qos.logback:logback-classic": [ + "ch.qos.logback.classic", + "ch.qos.logback.classic.boolex", + "ch.qos.logback.classic.encoder", + "ch.qos.logback.classic.filter", + "ch.qos.logback.classic.helpers", + "ch.qos.logback.classic.html", + "ch.qos.logback.classic.joran", + "ch.qos.logback.classic.joran.action", + "ch.qos.logback.classic.joran.sanity", + "ch.qos.logback.classic.joran.serializedModel", + "ch.qos.logback.classic.jul", + "ch.qos.logback.classic.layout", + "ch.qos.logback.classic.log4j", + "ch.qos.logback.classic.model", + "ch.qos.logback.classic.model.processor", + "ch.qos.logback.classic.model.util", + "ch.qos.logback.classic.net", + "ch.qos.logback.classic.net.server", + "ch.qos.logback.classic.pattern", + "ch.qos.logback.classic.pattern.color", + "ch.qos.logback.classic.selector", + "ch.qos.logback.classic.selector.servlet", + "ch.qos.logback.classic.servlet", + "ch.qos.logback.classic.sift", + "ch.qos.logback.classic.spi", + "ch.qos.logback.classic.turbo", + "ch.qos.logback.classic.tyler", + "ch.qos.logback.classic.util" + ], + "ch.qos.logback:logback-core": [ + "ch.qos.logback.core", + "ch.qos.logback.core.boolex", + "ch.qos.logback.core.encoder", + "ch.qos.logback.core.filter", + "ch.qos.logback.core.helpers", + "ch.qos.logback.core.hook", + "ch.qos.logback.core.html", + "ch.qos.logback.core.joran", + "ch.qos.logback.core.joran.action", + "ch.qos.logback.core.joran.conditional", + "ch.qos.logback.core.joran.event", + "ch.qos.logback.core.joran.sanity", + "ch.qos.logback.core.joran.spi", + "ch.qos.logback.core.joran.util", + "ch.qos.logback.core.joran.util.beans", + "ch.qos.logback.core.layout", + "ch.qos.logback.core.model", + "ch.qos.logback.core.model.conditional", + "ch.qos.logback.core.model.processor", + "ch.qos.logback.core.model.processor.conditional", + "ch.qos.logback.core.model.util", + "ch.qos.logback.core.net", + "ch.qos.logback.core.net.ssl", + "ch.qos.logback.core.pattern", + "ch.qos.logback.core.pattern.color", + "ch.qos.logback.core.pattern.parser", + "ch.qos.logback.core.pattern.util", + "ch.qos.logback.core.property", + "ch.qos.logback.core.read", + "ch.qos.logback.core.recovery", + "ch.qos.logback.core.rolling", + "ch.qos.logback.core.rolling.helper", + "ch.qos.logback.core.sift", + "ch.qos.logback.core.spi", + "ch.qos.logback.core.status", + "ch.qos.logback.core.subst", + "ch.qos.logback.core.testUtil", + "ch.qos.logback.core.util" + ], + "com.fasterxml.jackson.core:jackson-annotations": [ + "com.fasterxml.jackson.annotation" + ], + "com.google.code.findbugs:jsr305": [ + "javax.annotation", + "javax.annotation.concurrent", + "javax.annotation.meta" + ], + "com.google.code.gson:gson": [ + "com.google.gson", + "com.google.gson.annotations", + "com.google.gson.internal", + "com.google.gson.internal.bind", + "com.google.gson.internal.bind.util", + "com.google.gson.internal.reflect", + "com.google.gson.internal.sql", + "com.google.gson.reflect", + "com.google.gson.stream" + ], + "com.google.errorprone:error_prone_annotations": [ + "com.google.errorprone.annotations", + "com.google.errorprone.annotations.concurrent" + ], + "com.google.guava:failureaccess": [ + "com.google.common.util.concurrent.internal" + ], + "com.google.guava:guava": [ + "com.google.common.annotations", + "com.google.common.base", + "com.google.common.base.internal", + "com.google.common.cache", + "com.google.common.collect", + "com.google.common.escape", + "com.google.common.eventbus", + "com.google.common.graph", + "com.google.common.hash", + "com.google.common.html", + "com.google.common.io", + "com.google.common.math", + "com.google.common.net", + "com.google.common.primitives", + "com.google.common.reflect", + "com.google.common.util.concurrent", + "com.google.common.xml", + "com.google.thirdparty.publicsuffix" + ], + "com.google.j2objc:j2objc-annotations": [ + "com.google.j2objc.annotations" + ], + "com.jayway.jsonpath:json-path": [ + "com.jayway.jsonpath", + "com.jayway.jsonpath.internal", + "com.jayway.jsonpath.internal.filter", + "com.jayway.jsonpath.internal.function", + "com.jayway.jsonpath.internal.function.json", + "com.jayway.jsonpath.internal.function.latebinding", + "com.jayway.jsonpath.internal.function.numeric", + "com.jayway.jsonpath.internal.function.sequence", + "com.jayway.jsonpath.internal.function.text", + "com.jayway.jsonpath.internal.path", + "com.jayway.jsonpath.spi.cache", + "com.jayway.jsonpath.spi.json", + "com.jayway.jsonpath.spi.mapper" + ], + "com.vaadin.external.google:android-json": [ + "org.json" + ], + "commons-logging:commons-logging": [ + "org.apache.commons.logging", + "org.apache.commons.logging.impl" + ], + "io.micrometer:micrometer-commons": [ + "io.micrometer.common", + "io.micrometer.common.annotation", + "io.micrometer.common.docs", + "io.micrometer.common.lang", + "io.micrometer.common.lang.internal", + "io.micrometer.common.util", + "io.micrometer.common.util.internal.logging" + ], + "io.micrometer:micrometer-observation": [ + "io.micrometer.observation", + "io.micrometer.observation.annotation", + "io.micrometer.observation.aop", + "io.micrometer.observation.contextpropagation", + "io.micrometer.observation.docs", + "io.micrometer.observation.transport" + ], + "jakarta.activation:jakarta.activation-api": [ + "jakarta.activation", + "jakarta.activation.spi" + ], + "jakarta.annotation:jakarta.annotation-api": [ + "jakarta.annotation", + "jakarta.annotation.security", + "jakarta.annotation.sql" + ], + "jakarta.xml.bind:jakarta.xml.bind-api": [ + "jakarta.xml.bind", + "jakarta.xml.bind.annotation", + "jakarta.xml.bind.annotation.adapters", + "jakarta.xml.bind.attachment", + "jakarta.xml.bind.helpers", + "jakarta.xml.bind.util" + ], + "net.bytebuddy:byte-buddy": [ + "net.bytebuddy", + "net.bytebuddy.agent.builder", + "net.bytebuddy.asm", + "net.bytebuddy.build", + "net.bytebuddy.description", + "net.bytebuddy.description.annotation", + "net.bytebuddy.description.enumeration", + "net.bytebuddy.description.field", + "net.bytebuddy.description.method", + "net.bytebuddy.description.modifier", + "net.bytebuddy.description.type", + "net.bytebuddy.dynamic", + "net.bytebuddy.dynamic.loading", + "net.bytebuddy.dynamic.scaffold", + "net.bytebuddy.dynamic.scaffold.inline", + "net.bytebuddy.dynamic.scaffold.subclass", + "net.bytebuddy.implementation", + "net.bytebuddy.implementation.attribute", + "net.bytebuddy.implementation.auxiliary", + "net.bytebuddy.implementation.bind", + "net.bytebuddy.implementation.bind.annotation", + "net.bytebuddy.implementation.bytecode", + "net.bytebuddy.implementation.bytecode.assign", + "net.bytebuddy.implementation.bytecode.assign.primitive", + "net.bytebuddy.implementation.bytecode.assign.reference", + "net.bytebuddy.implementation.bytecode.collection", + "net.bytebuddy.implementation.bytecode.constant", + "net.bytebuddy.implementation.bytecode.member", + "net.bytebuddy.jar.asm", + "net.bytebuddy.jar.asm.commons", + "net.bytebuddy.jar.asm.signature", + "net.bytebuddy.jar.asmjdkbridge", + "net.bytebuddy.matcher", + "net.bytebuddy.pool", + "net.bytebuddy.utility", + "net.bytebuddy.utility.dispatcher", + "net.bytebuddy.utility.nullability", + "net.bytebuddy.utility.privilege", + "net.bytebuddy.utility.visitor" + ], + "net.bytebuddy:byte-buddy-agent": [ + "net.bytebuddy.agent", + "net.bytebuddy.agent.utility.nullability" + ], + "net.minidev:accessors-smart": [ + "net.minidev.asm", + "net.minidev.asm.ex" + ], + "net.minidev:json-smart": [ + "net.minidev.json", + "net.minidev.json.annotate", + "net.minidev.json.parser", + "net.minidev.json.reader", + "net.minidev.json.writer" + ], + "org.apache.logging.log4j:log4j-api": [ + "org.apache.logging.log4j", + "org.apache.logging.log4j.internal", + "org.apache.logging.log4j.internal.annotation", + "org.apache.logging.log4j.internal.map", + "org.apache.logging.log4j.message", + "org.apache.logging.log4j.simple", + "org.apache.logging.log4j.simple.internal", + "org.apache.logging.log4j.spi", + "org.apache.logging.log4j.status", + "org.apache.logging.log4j.util", + "org.apache.logging.log4j.util.internal" + ], + "org.apache.logging.log4j:log4j-to-slf4j": [ + "org.apache.logging.slf4j" + ], + "org.apache.tomcat.embed:tomcat-embed-core": [ + "jakarta.security.auth.message", + "jakarta.security.auth.message.callback", + "jakarta.security.auth.message.config", + "jakarta.security.auth.message.module", + "jakarta.servlet", + "jakarta.servlet.annotation", + "jakarta.servlet.descriptor", + "jakarta.servlet.http", + "org.apache.catalina", + "org.apache.catalina.authenticator", + "org.apache.catalina.authenticator.jaspic", + "org.apache.catalina.connector", + "org.apache.catalina.core", + "org.apache.catalina.deploy", + "org.apache.catalina.filters", + "org.apache.catalina.loader", + "org.apache.catalina.manager", + "org.apache.catalina.manager.host", + "org.apache.catalina.manager.util", + "org.apache.catalina.mapper", + "org.apache.catalina.mbeans", + "org.apache.catalina.realm", + "org.apache.catalina.security", + "org.apache.catalina.servlets", + "org.apache.catalina.session", + "org.apache.catalina.startup", + "org.apache.catalina.users", + "org.apache.catalina.util", + "org.apache.catalina.valves", + "org.apache.catalina.valves.rewrite", + "org.apache.catalina.webresources", + "org.apache.catalina.webresources.war", + "org.apache.coyote", + "org.apache.coyote.ajp", + "org.apache.coyote.http11", + "org.apache.coyote.http11.filters", + "org.apache.coyote.http11.upgrade", + "org.apache.coyote.http2", + "org.apache.juli", + "org.apache.juli.logging", + "org.apache.naming", + "org.apache.naming.factory", + "org.apache.naming.java", + "org.apache.tomcat", + "org.apache.tomcat.jni", + "org.apache.tomcat.util", + "org.apache.tomcat.util.bcel", + "org.apache.tomcat.util.bcel.classfile", + "org.apache.tomcat.util.buf", + "org.apache.tomcat.util.collections", + "org.apache.tomcat.util.compat", + "org.apache.tomcat.util.concurrent", + "org.apache.tomcat.util.descriptor", + "org.apache.tomcat.util.descriptor.tagplugin", + "org.apache.tomcat.util.descriptor.web", + "org.apache.tomcat.util.digester", + "org.apache.tomcat.util.file", + "org.apache.tomcat.util.http", + "org.apache.tomcat.util.http.fileupload", + "org.apache.tomcat.util.http.fileupload.disk", + "org.apache.tomcat.util.http.fileupload.impl", + "org.apache.tomcat.util.http.fileupload.servlet", + "org.apache.tomcat.util.http.fileupload.util", + "org.apache.tomcat.util.http.fileupload.util.mime", + "org.apache.tomcat.util.http.parser", + "org.apache.tomcat.util.json", + "org.apache.tomcat.util.log", + "org.apache.tomcat.util.modeler", + "org.apache.tomcat.util.modeler.modules", + "org.apache.tomcat.util.net", + "org.apache.tomcat.util.net.jsse", + "org.apache.tomcat.util.net.openssl", + "org.apache.tomcat.util.net.openssl.ciphers", + "org.apache.tomcat.util.res", + "org.apache.tomcat.util.scan", + "org.apache.tomcat.util.security", + "org.apache.tomcat.util.threads" + ], + "org.apache.tomcat.embed:tomcat-embed-el": [ + "jakarta.el", + "org.apache.el", + "org.apache.el.lang", + "org.apache.el.parser", + "org.apache.el.stream", + "org.apache.el.util" + ], + "org.apache.tomcat.embed:tomcat-embed-websocket": [ + "jakarta.websocket", + "jakarta.websocket.server", + "org.apache.tomcat.websocket", + "org.apache.tomcat.websocket.pojo", + "org.apache.tomcat.websocket.server" + ], + "org.apiguardian:apiguardian-api": [ + "org.apiguardian.api" + ], + "org.assertj:assertj-core": [ + "org.assertj.core.annotation", + "org.assertj.core.annotations", + "org.assertj.core.api", + "org.assertj.core.api.exception", + "org.assertj.core.api.filter", + "org.assertj.core.api.iterable", + "org.assertj.core.api.junit.jupiter", + "org.assertj.core.api.recursive", + "org.assertj.core.api.recursive.assertion", + "org.assertj.core.api.recursive.comparison", + "org.assertj.core.condition", + "org.assertj.core.configuration", + "org.assertj.core.data", + "org.assertj.core.description", + "org.assertj.core.error", + "org.assertj.core.error.array2d", + "org.assertj.core.error.future", + "org.assertj.core.error.uri", + "org.assertj.core.extractor", + "org.assertj.core.groups", + "org.assertj.core.internal", + "org.assertj.core.internal.annotation", + "org.assertj.core.matcher", + "org.assertj.core.presentation", + "org.assertj.core.util", + "org.assertj.core.util.diff", + "org.assertj.core.util.diff.myers", + "org.assertj.core.util.introspection", + "org.assertj.core.util.xml" + ], + "org.awaitility:awaitility": [ + "org.awaitility", + "org.awaitility.classpath", + "org.awaitility.constraint", + "org.awaitility.core", + "org.awaitility.pollinterval", + "org.awaitility.reflect", + "org.awaitility.reflect.exception", + "org.awaitility.spi" + ], + "org.checkerframework:checker-qual": [ + "org.checkerframework.checker.builder.qual", + "org.checkerframework.checker.calledmethods.qual", + "org.checkerframework.checker.compilermsgs.qual", + "org.checkerframework.checker.fenum.qual", + "org.checkerframework.checker.formatter.qual", + "org.checkerframework.checker.guieffect.qual", + "org.checkerframework.checker.i18n.qual", + "org.checkerframework.checker.i18nformatter.qual", + "org.checkerframework.checker.index.qual", + "org.checkerframework.checker.initialization.qual", + "org.checkerframework.checker.interning.qual", + "org.checkerframework.checker.lock.qual", + "org.checkerframework.checker.mustcall.qual", + "org.checkerframework.checker.nullness.qual", + "org.checkerframework.checker.optional.qual", + "org.checkerframework.checker.propkey.qual", + "org.checkerframework.checker.regex.qual", + "org.checkerframework.checker.signature.qual", + "org.checkerframework.checker.signedness.qual", + "org.checkerframework.checker.tainting.qual", + "org.checkerframework.checker.units.qual", + "org.checkerframework.common.aliasing.qual", + "org.checkerframework.common.initializedfields.qual", + "org.checkerframework.common.reflection.qual", + "org.checkerframework.common.returnsreceiver.qual", + "org.checkerframework.common.subtyping.qual", + "org.checkerframework.common.util.report.qual", + "org.checkerframework.common.value.qual", + "org.checkerframework.dataflow.qual", + "org.checkerframework.framework.qual" + ], + "org.hamcrest:hamcrest": [ + "org.hamcrest", + "org.hamcrest.beans", + "org.hamcrest.collection", + "org.hamcrest.comparator", + "org.hamcrest.core", + "org.hamcrest.internal", + "org.hamcrest.io", + "org.hamcrest.number", + "org.hamcrest.object", + "org.hamcrest.text", + "org.hamcrest.xml" + ], + "org.jspecify:jspecify": [ + "org.jspecify.annotations" + ], + "org.junit.jupiter:junit-jupiter-api": [ + "org.junit.jupiter.api", + "org.junit.jupiter.api.condition", + "org.junit.jupiter.api.extension", + "org.junit.jupiter.api.extension.support", + "org.junit.jupiter.api.function", + "org.junit.jupiter.api.io", + "org.junit.jupiter.api.parallel", + "org.junit.jupiter.api.util" + ], + "org.junit.jupiter:junit-jupiter-engine": [ + "org.junit.jupiter.engine", + "org.junit.jupiter.engine.config", + "org.junit.jupiter.engine.descriptor", + "org.junit.jupiter.engine.discovery", + "org.junit.jupiter.engine.discovery.predicates", + "org.junit.jupiter.engine.execution", + "org.junit.jupiter.engine.extension", + "org.junit.jupiter.engine.support" + ], + "org.junit.jupiter:junit-jupiter-params": [ + "org.junit.jupiter.params", + "org.junit.jupiter.params.aggregator", + "org.junit.jupiter.params.converter", + "org.junit.jupiter.params.provider", + "org.junit.jupiter.params.shadow.de.siegmar.fastcsv.reader", + "org.junit.jupiter.params.shadow.de.siegmar.fastcsv.util", + "org.junit.jupiter.params.shadow.de.siegmar.fastcsv.writer", + "org.junit.jupiter.params.support" + ], + "org.junit.platform:junit-platform-commons": [ + "org.junit.platform.commons", + "org.junit.platform.commons.annotation", + "org.junit.platform.commons.function", + "org.junit.platform.commons.io", + "org.junit.platform.commons.logging", + "org.junit.platform.commons.support", + "org.junit.platform.commons.support.conversion", + "org.junit.platform.commons.support.scanning", + "org.junit.platform.commons.util" + ], + "org.junit.platform:junit-platform-engine": [ + "org.junit.platform.engine", + "org.junit.platform.engine.discovery", + "org.junit.platform.engine.reporting", + "org.junit.platform.engine.support.config", + "org.junit.platform.engine.support.descriptor", + "org.junit.platform.engine.support.discovery", + "org.junit.platform.engine.support.hierarchical", + "org.junit.platform.engine.support.store" + ], + "org.junit.platform:junit-platform-launcher": [ + "org.junit.platform.launcher", + "org.junit.platform.launcher.core", + "org.junit.platform.launcher.jfr", + "org.junit.platform.launcher.listeners", + "org.junit.platform.launcher.listeners.discovery", + "org.junit.platform.launcher.listeners.session", + "org.junit.platform.launcher.tagexpression" + ], + "org.junit.platform:junit-platform-reporting": [ + "org.junit.platform.reporting", + "org.junit.platform.reporting.legacy", + "org.junit.platform.reporting.legacy.xml", + "org.junit.platform.reporting.open.xml", + "org.junit.platform.reporting.shadow.org.opentest4j.reporting.events.api", + "org.junit.platform.reporting.shadow.org.opentest4j.reporting.events.core", + "org.junit.platform.reporting.shadow.org.opentest4j.reporting.events.git", + "org.junit.platform.reporting.shadow.org.opentest4j.reporting.events.java", + "org.junit.platform.reporting.shadow.org.opentest4j.reporting.events.root", + "org.junit.platform.reporting.shadow.org.opentest4j.reporting.schema" + ], + "org.mockito:mockito-core": [ + "org.mockito", + "org.mockito.configuration", + "org.mockito.creation.instance", + "org.mockito.exceptions.base", + "org.mockito.exceptions.misusing", + "org.mockito.exceptions.stacktrace", + "org.mockito.exceptions.verification", + "org.mockito.exceptions.verification.junit", + "org.mockito.exceptions.verification.opentest4j", + "org.mockito.hamcrest", + "org.mockito.internal", + "org.mockito.internal.configuration", + "org.mockito.internal.configuration.injection", + "org.mockito.internal.configuration.injection.filter", + "org.mockito.internal.configuration.injection.scanner", + "org.mockito.internal.configuration.plugins", + "org.mockito.internal.creation", + "org.mockito.internal.creation.bytebuddy", + "org.mockito.internal.creation.bytebuddy.access", + "org.mockito.internal.creation.bytebuddy.codegen", + "org.mockito.internal.creation.instance", + "org.mockito.internal.creation.proxy", + "org.mockito.internal.creation.settings", + "org.mockito.internal.creation.util", + "org.mockito.internal.debugging", + "org.mockito.internal.exceptions", + "org.mockito.internal.exceptions.stacktrace", + "org.mockito.internal.exceptions.util", + "org.mockito.internal.framework", + "org.mockito.internal.hamcrest", + "org.mockito.internal.handler", + "org.mockito.internal.invocation", + "org.mockito.internal.invocation.finder", + "org.mockito.internal.invocation.mockref", + "org.mockito.internal.junit", + "org.mockito.internal.listeners", + "org.mockito.internal.matchers", + "org.mockito.internal.matchers.apachecommons", + "org.mockito.internal.matchers.text", + "org.mockito.internal.progress", + "org.mockito.internal.reporting", + "org.mockito.internal.runners", + "org.mockito.internal.runners.util", + "org.mockito.internal.session", + "org.mockito.internal.stubbing", + "org.mockito.internal.stubbing.answers", + "org.mockito.internal.stubbing.defaultanswers", + "org.mockito.internal.util", + "org.mockito.internal.util.collections", + "org.mockito.internal.util.concurrent", + "org.mockito.internal.util.io", + "org.mockito.internal.util.reflection", + "org.mockito.internal.verification", + "org.mockito.internal.verification.api", + "org.mockito.internal.verification.argumentmatching", + "org.mockito.internal.verification.checkers", + "org.mockito.invocation", + "org.mockito.junit", + "org.mockito.listeners", + "org.mockito.mock", + "org.mockito.plugins", + "org.mockito.quality", + "org.mockito.session", + "org.mockito.stubbing", + "org.mockito.verification" + ], + "org.mockito:mockito-junit-jupiter": [ + "org.mockito.junit.jupiter", + "org.mockito.junit.jupiter.resolver" + ], + "org.objenesis:objenesis": [ + "org.objenesis", + "org.objenesis.instantiator", + "org.objenesis.instantiator.android", + "org.objenesis.instantiator.annotations", + "org.objenesis.instantiator.basic", + "org.objenesis.instantiator.gcj", + "org.objenesis.instantiator.perc", + "org.objenesis.instantiator.sun", + "org.objenesis.instantiator.util", + "org.objenesis.strategy" + ], + "org.opentest4j.reporting:open-test-reporting-tooling-spi": [ + "org.opentest4j.reporting.tooling.spi.htmlreport" + ], + "org.opentest4j:opentest4j": [ + "org.opentest4j" + ], + "org.ow2.asm:asm": [ + "org.objectweb.asm", + "org.objectweb.asm.signature" + ], + "org.skyscreamer:jsonassert": [ + "org.json", + "org.skyscreamer.jsonassert", + "org.skyscreamer.jsonassert.comparator" + ], + "org.slf4j:jul-to-slf4j": [ + "org.slf4j.bridge" + ], + "org.slf4j:slf4j-api": [ + "org.slf4j", + "org.slf4j.event", + "org.slf4j.helpers", + "org.slf4j.spi" + ], + "org.springframework.boot:spring-boot": [ + "org.springframework.boot", + "org.springframework.boot.admin", + "org.springframework.boot.ansi", + "org.springframework.boot.availability", + "org.springframework.boot.bootstrap", + "org.springframework.boot.builder", + "org.springframework.boot.cloud", + "org.springframework.boot.context", + "org.springframework.boot.context.annotation", + "org.springframework.boot.context.config", + "org.springframework.boot.context.event", + "org.springframework.boot.context.logging", + "org.springframework.boot.context.metrics.buffering", + "org.springframework.boot.context.properties", + "org.springframework.boot.context.properties.bind", + "org.springframework.boot.context.properties.bind.handler", + "org.springframework.boot.context.properties.bind.validation", + "org.springframework.boot.context.properties.source", + "org.springframework.boot.convert", + "org.springframework.boot.diagnostics", + "org.springframework.boot.diagnostics.analyzer", + "org.springframework.boot.env", + "org.springframework.boot.info", + "org.springframework.boot.io", + "org.springframework.boot.json", + "org.springframework.boot.logging", + "org.springframework.boot.logging.java", + "org.springframework.boot.logging.log4j2", + "org.springframework.boot.logging.logback", + "org.springframework.boot.logging.structured", + "org.springframework.boot.origin", + "org.springframework.boot.retry", + "org.springframework.boot.ssl", + "org.springframework.boot.ssl.jks", + "org.springframework.boot.ssl.pem", + "org.springframework.boot.support", + "org.springframework.boot.system", + "org.springframework.boot.task", + "org.springframework.boot.thread", + "org.springframework.boot.util", + "org.springframework.boot.validation", + "org.springframework.boot.validation.beanvalidation", + "org.springframework.boot.web.context.reactive", + "org.springframework.boot.web.context.servlet", + "org.springframework.boot.web.error", + "org.springframework.boot.web.servlet", + "org.springframework.boot.web.servlet.support" + ], + "org.springframework.boot:spring-boot-autoconfigure": [ + "org.springframework.boot.autoconfigure", + "org.springframework.boot.autoconfigure.admin", + "org.springframework.boot.autoconfigure.aop", + "org.springframework.boot.autoconfigure.availability", + "org.springframework.boot.autoconfigure.cache", + "org.springframework.boot.autoconfigure.condition", + "org.springframework.boot.autoconfigure.container", + "org.springframework.boot.autoconfigure.context", + "org.springframework.boot.autoconfigure.data", + "org.springframework.boot.autoconfigure.diagnostics.analyzer", + "org.springframework.boot.autoconfigure.info", + "org.springframework.boot.autoconfigure.jmx", + "org.springframework.boot.autoconfigure.logging", + "org.springframework.boot.autoconfigure.preinitialize", + "org.springframework.boot.autoconfigure.service.connection", + "org.springframework.boot.autoconfigure.ssl", + "org.springframework.boot.autoconfigure.task", + "org.springframework.boot.autoconfigure.template", + "org.springframework.boot.autoconfigure.web", + "org.springframework.boot.autoconfigure.web.format" + ], + "org.springframework.boot:spring-boot-http-converter": [ + "org.springframework.boot.http.converter.autoconfigure" + ], + "org.springframework.boot:spring-boot-jackson": [ + "org.springframework.boot.jackson", + "org.springframework.boot.jackson.autoconfigure" + ], + "org.springframework.boot:spring-boot-servlet": [ + "org.springframework.boot.servlet", + "org.springframework.boot.servlet.actuate.web.exchanges", + "org.springframework.boot.servlet.actuate.web.mappings", + "org.springframework.boot.servlet.autoconfigure", + "org.springframework.boot.servlet.autoconfigure.actuate.web", + "org.springframework.boot.servlet.autoconfigure.actuate.web.exchanges", + "org.springframework.boot.servlet.autoconfigure.actuate.web.mappings", + "org.springframework.boot.servlet.filter" + ], + "org.springframework.boot:spring-boot-test": [ + "org.springframework.boot.test.context", + "org.springframework.boot.test.context.assertj", + "org.springframework.boot.test.context.filter", + "org.springframework.boot.test.context.filter.annotation", + "org.springframework.boot.test.context.runner", + "org.springframework.boot.test.http.client", + "org.springframework.boot.test.http.server", + "org.springframework.boot.test.json", + "org.springframework.boot.test.mock.web", + "org.springframework.boot.test.system", + "org.springframework.boot.test.util", + "org.springframework.boot.test.web.htmlunit", + "org.springframework.boot.test.web.server" + ], + "org.springframework.boot:spring-boot-test-autoconfigure": [ + "org.springframework.boot.test.autoconfigure", + "org.springframework.boot.test.autoconfigure.jdbc", + "org.springframework.boot.test.autoconfigure.json" + ], + "org.springframework.boot:spring-boot-tomcat": [ + "org.springframework.boot.tomcat", + "org.springframework.boot.tomcat.autoconfigure", + "org.springframework.boot.tomcat.autoconfigure.actuate.web.server", + "org.springframework.boot.tomcat.autoconfigure.metrics", + "org.springframework.boot.tomcat.autoconfigure.reactive", + "org.springframework.boot.tomcat.autoconfigure.servlet", + "org.springframework.boot.tomcat.metrics", + "org.springframework.boot.tomcat.reactive", + "org.springframework.boot.tomcat.servlet" + ], + "org.springframework.boot:spring-boot-web-server": [ + "org.springframework.boot.web.server", + "org.springframework.boot.web.server.autoconfigure", + "org.springframework.boot.web.server.autoconfigure.reactive", + "org.springframework.boot.web.server.autoconfigure.servlet", + "org.springframework.boot.web.server.context", + "org.springframework.boot.web.server.reactive", + "org.springframework.boot.web.server.reactive.context", + "org.springframework.boot.web.server.servlet", + "org.springframework.boot.web.server.servlet.context" + ], + "org.springframework.boot:spring-boot-webmvc": [ + "org.springframework.boot.webmvc", + "org.springframework.boot.webmvc.actuate.endpoint.web", + "org.springframework.boot.webmvc.actuate.web.mappings", + "org.springframework.boot.webmvc.autoconfigure", + "org.springframework.boot.webmvc.autoconfigure.actuate.endpoint.web", + "org.springframework.boot.webmvc.autoconfigure.actuate.web", + "org.springframework.boot.webmvc.autoconfigure.actuate.web.mappings", + "org.springframework.boot.webmvc.autoconfigure.error", + "org.springframework.boot.webmvc.error" + ], + "org.springframework.boot:spring-boot-webmvc-test": [ + "org.springframework.boot.webmvc.test.autoconfigure" + ], + "org.springframework:spring-aop": [ + "org.aopalliance", + "org.aopalliance.aop", + "org.aopalliance.intercept", + "org.springframework.aop", + "org.springframework.aop.aspectj", + "org.springframework.aop.aspectj.annotation", + "org.springframework.aop.aspectj.autoproxy", + "org.springframework.aop.config", + "org.springframework.aop.framework", + "org.springframework.aop.framework.adapter", + "org.springframework.aop.framework.autoproxy", + "org.springframework.aop.framework.autoproxy.target", + "org.springframework.aop.interceptor", + "org.springframework.aop.scope", + "org.springframework.aop.support", + "org.springframework.aop.support.annotation", + "org.springframework.aop.target", + "org.springframework.aop.target.dynamic" + ], + "org.springframework:spring-beans": [ + "org.springframework.beans", + "org.springframework.beans.factory", + "org.springframework.beans.factory.annotation", + "org.springframework.beans.factory.aot", + "org.springframework.beans.factory.config", + "org.springframework.beans.factory.groovy", + "org.springframework.beans.factory.parsing", + "org.springframework.beans.factory.serviceloader", + "org.springframework.beans.factory.support", + "org.springframework.beans.factory.wiring", + "org.springframework.beans.factory.xml", + "org.springframework.beans.propertyeditors", + "org.springframework.beans.support" + ], + "org.springframework:spring-context": [ + "org.springframework.cache", + "org.springframework.cache.annotation", + "org.springframework.cache.concurrent", + "org.springframework.cache.config", + "org.springframework.cache.interceptor", + "org.springframework.cache.support", + "org.springframework.context", + "org.springframework.context.annotation", + "org.springframework.context.aot", + "org.springframework.context.config", + "org.springframework.context.event", + "org.springframework.context.expression", + "org.springframework.context.i18n", + "org.springframework.context.index", + "org.springframework.context.support", + "org.springframework.context.weaving", + "org.springframework.ejb.config", + "org.springframework.format", + "org.springframework.format.annotation", + "org.springframework.format.datetime", + "org.springframework.format.datetime.standard", + "org.springframework.format.number", + "org.springframework.format.number.money", + "org.springframework.format.support", + "org.springframework.instrument.classloading", + "org.springframework.instrument.classloading.glassfish", + "org.springframework.instrument.classloading.jboss", + "org.springframework.instrument.classloading.tomcat", + "org.springframework.jmx", + "org.springframework.jmx.access", + "org.springframework.jmx.export", + "org.springframework.jmx.export.annotation", + "org.springframework.jmx.export.assembler", + "org.springframework.jmx.export.metadata", + "org.springframework.jmx.export.naming", + "org.springframework.jmx.export.notification", + "org.springframework.jmx.support", + "org.springframework.jndi", + "org.springframework.jndi.support", + "org.springframework.resilience", + "org.springframework.resilience.annotation", + "org.springframework.resilience.retry", + "org.springframework.scheduling", + "org.springframework.scheduling.annotation", + "org.springframework.scheduling.concurrent", + "org.springframework.scheduling.config", + "org.springframework.scheduling.support", + "org.springframework.scripting", + "org.springframework.scripting.bsh", + "org.springframework.scripting.config", + "org.springframework.scripting.groovy", + "org.springframework.scripting.support", + "org.springframework.stereotype", + "org.springframework.ui", + "org.springframework.validation", + "org.springframework.validation.annotation", + "org.springframework.validation.beanvalidation", + "org.springframework.validation.method", + "org.springframework.validation.support" + ], + "org.springframework:spring-core": [ + "org.springframework.aot", + "org.springframework.aot.generate", + "org.springframework.aot.hint", + "org.springframework.aot.hint.annotation", + "org.springframework.aot.hint.predicate", + "org.springframework.aot.hint.support", + "org.springframework.aot.nativex", + "org.springframework.aot.nativex.feature", + "org.springframework.asm", + "org.springframework.cglib", + "org.springframework.cglib.beans", + "org.springframework.cglib.core", + "org.springframework.cglib.core.internal", + "org.springframework.cglib.proxy", + "org.springframework.cglib.reflect", + "org.springframework.cglib.transform", + "org.springframework.cglib.transform.impl", + "org.springframework.cglib.util", + "org.springframework.core", + "org.springframework.core.annotation", + "org.springframework.core.codec", + "org.springframework.core.convert", + "org.springframework.core.convert.converter", + "org.springframework.core.convert.support", + "org.springframework.core.env", + "org.springframework.core.io", + "org.springframework.core.io.buffer", + "org.springframework.core.io.support", + "org.springframework.core.log", + "org.springframework.core.metrics", + "org.springframework.core.metrics.jfr", + "org.springframework.core.retry", + "org.springframework.core.retry.support", + "org.springframework.core.serializer", + "org.springframework.core.serializer.support", + "org.springframework.core.style", + "org.springframework.core.task", + "org.springframework.core.task.support", + "org.springframework.core.type", + "org.springframework.core.type.classreading", + "org.springframework.core.type.filter", + "org.springframework.javapoet", + "org.springframework.lang", + "org.springframework.objenesis", + "org.springframework.objenesis.instantiator", + "org.springframework.objenesis.instantiator.android", + "org.springframework.objenesis.instantiator.annotations", + "org.springframework.objenesis.instantiator.basic", + "org.springframework.objenesis.instantiator.gcj", + "org.springframework.objenesis.instantiator.perc", + "org.springframework.objenesis.instantiator.sun", + "org.springframework.objenesis.instantiator.util", + "org.springframework.objenesis.strategy", + "org.springframework.util", + "org.springframework.util.backoff", + "org.springframework.util.comparator", + "org.springframework.util.concurrent", + "org.springframework.util.function", + "org.springframework.util.unit", + "org.springframework.util.xml" + ], + "org.springframework:spring-expression": [ + "org.springframework.expression", + "org.springframework.expression.common", + "org.springframework.expression.spel", + "org.springframework.expression.spel.ast", + "org.springframework.expression.spel.standard", + "org.springframework.expression.spel.support" + ], + "org.springframework:spring-test": [ + "org.springframework.mock.env", + "org.springframework.mock.http", + "org.springframework.mock.http.client", + "org.springframework.mock.http.client.reactive", + "org.springframework.mock.http.server.reactive", + "org.springframework.mock.web", + "org.springframework.mock.web.reactive.function.server", + "org.springframework.mock.web.server", + "org.springframework.test.annotation", + "org.springframework.test.context", + "org.springframework.test.context.aot", + "org.springframework.test.context.bean.override", + "org.springframework.test.context.bean.override.convention", + "org.springframework.test.context.bean.override.mockito", + "org.springframework.test.context.cache", + "org.springframework.test.context.event", + "org.springframework.test.context.event.annotation", + "org.springframework.test.context.hint", + "org.springframework.test.context.jdbc", + "org.springframework.test.context.junit.jupiter", + "org.springframework.test.context.junit.jupiter.web", + "org.springframework.test.context.junit4", + "org.springframework.test.context.junit4.rules", + "org.springframework.test.context.junit4.statements", + "org.springframework.test.context.observation", + "org.springframework.test.context.support", + "org.springframework.test.context.testng", + "org.springframework.test.context.transaction", + "org.springframework.test.context.util", + "org.springframework.test.context.web", + "org.springframework.test.context.web.socket", + "org.springframework.test.http", + "org.springframework.test.jdbc", + "org.springframework.test.json", + "org.springframework.test.util", + "org.springframework.test.validation", + "org.springframework.test.web", + "org.springframework.test.web.client", + "org.springframework.test.web.client.match", + "org.springframework.test.web.client.response", + "org.springframework.test.web.reactive.server", + "org.springframework.test.web.reactive.server.assertj", + "org.springframework.test.web.servlet", + "org.springframework.test.web.servlet.assertj", + "org.springframework.test.web.servlet.client", + "org.springframework.test.web.servlet.client.assertj", + "org.springframework.test.web.servlet.htmlunit", + "org.springframework.test.web.servlet.htmlunit.webdriver", + "org.springframework.test.web.servlet.request", + "org.springframework.test.web.servlet.result", + "org.springframework.test.web.servlet.setup", + "org.springframework.test.web.support" + ], + "org.springframework:spring-web": [ + "org.springframework.http", + "org.springframework.http.client", + "org.springframework.http.client.observation", + "org.springframework.http.client.reactive", + "org.springframework.http.client.support", + "org.springframework.http.codec", + "org.springframework.http.codec.cbor", + "org.springframework.http.codec.json", + "org.springframework.http.codec.multipart", + "org.springframework.http.codec.protobuf", + "org.springframework.http.codec.smile", + "org.springframework.http.codec.support", + "org.springframework.http.codec.xml", + "org.springframework.http.converter", + "org.springframework.http.converter.cbor", + "org.springframework.http.converter.feed", + "org.springframework.http.converter.json", + "org.springframework.http.converter.protobuf", + "org.springframework.http.converter.smile", + "org.springframework.http.converter.support", + "org.springframework.http.converter.xml", + "org.springframework.http.converter.yaml", + "org.springframework.http.server", + "org.springframework.http.server.observation", + "org.springframework.http.server.reactive", + "org.springframework.http.server.reactive.observation", + "org.springframework.http.support", + "org.springframework.web", + "org.springframework.web.accept", + "org.springframework.web.bind", + "org.springframework.web.bind.annotation", + "org.springframework.web.bind.support", + "org.springframework.web.client", + "org.springframework.web.client.support", + "org.springframework.web.context", + "org.springframework.web.context.annotation", + "org.springframework.web.context.request", + "org.springframework.web.context.request.async", + "org.springframework.web.context.support", + "org.springframework.web.cors", + "org.springframework.web.cors.reactive", + "org.springframework.web.filter", + "org.springframework.web.filter.reactive", + "org.springframework.web.jsf", + "org.springframework.web.jsf.el", + "org.springframework.web.method", + "org.springframework.web.method.annotation", + "org.springframework.web.method.support", + "org.springframework.web.multipart", + "org.springframework.web.multipart.support", + "org.springframework.web.server", + "org.springframework.web.server.adapter", + "org.springframework.web.server.handler", + "org.springframework.web.server.i18n", + "org.springframework.web.server.session", + "org.springframework.web.service", + "org.springframework.web.service.annotation", + "org.springframework.web.service.invoker", + "org.springframework.web.service.registry", + "org.springframework.web.util", + "org.springframework.web.util.pattern" + ], + "org.springframework:spring-webmvc": [ + "org.springframework.web.servlet", + "org.springframework.web.servlet.config", + "org.springframework.web.servlet.config.annotation", + "org.springframework.web.servlet.function", + "org.springframework.web.servlet.function.support", + "org.springframework.web.servlet.handler", + "org.springframework.web.servlet.i18n", + "org.springframework.web.servlet.mvc", + "org.springframework.web.servlet.mvc.annotation", + "org.springframework.web.servlet.mvc.condition", + "org.springframework.web.servlet.mvc.method", + "org.springframework.web.servlet.mvc.method.annotation", + "org.springframework.web.servlet.mvc.support", + "org.springframework.web.servlet.resource", + "org.springframework.web.servlet.support", + "org.springframework.web.servlet.tags", + "org.springframework.web.servlet.tags.form", + "org.springframework.web.servlet.view", + "org.springframework.web.servlet.view.document", + "org.springframework.web.servlet.view.feed", + "org.springframework.web.servlet.view.freemarker", + "org.springframework.web.servlet.view.groovy", + "org.springframework.web.servlet.view.json", + "org.springframework.web.servlet.view.script", + "org.springframework.web.servlet.view.xml", + "org.springframework.web.servlet.view.xslt" + ], + "org.xmlunit:xmlunit-core": [ + "org.xmlunit", + "org.xmlunit.builder", + "org.xmlunit.builder.javax_jaxb", + "org.xmlunit.diff", + "org.xmlunit.input", + "org.xmlunit.transform", + "org.xmlunit.util", + "org.xmlunit.validation", + "org.xmlunit.xpath" + ], + "org.yaml:snakeyaml": [ + "org.yaml.snakeyaml", + "org.yaml.snakeyaml.comments", + "org.yaml.snakeyaml.composer", + "org.yaml.snakeyaml.constructor", + "org.yaml.snakeyaml.emitter", + "org.yaml.snakeyaml.env", + "org.yaml.snakeyaml.error", + "org.yaml.snakeyaml.events", + "org.yaml.snakeyaml.extensions.compactnotation", + "org.yaml.snakeyaml.external.com.google.gdata.util.common.base", + "org.yaml.snakeyaml.inspector", + "org.yaml.snakeyaml.internal", + "org.yaml.snakeyaml.introspector", + "org.yaml.snakeyaml.nodes", + "org.yaml.snakeyaml.parser", + "org.yaml.snakeyaml.reader", + "org.yaml.snakeyaml.representer", + "org.yaml.snakeyaml.resolver", + "org.yaml.snakeyaml.scanner", + "org.yaml.snakeyaml.serializer", + "org.yaml.snakeyaml.tokens", + "org.yaml.snakeyaml.util" + ], + "tools.jackson.core:jackson-core": [ + "tools.jackson.core", + "tools.jackson.core.async", + "tools.jackson.core.base", + "tools.jackson.core.exc", + "tools.jackson.core.filter", + "tools.jackson.core.internal.shaded.fdp", + "tools.jackson.core.internal.shaded.fdp.bte", + "tools.jackson.core.internal.shaded.fdp.chr", + "tools.jackson.core.io", + "tools.jackson.core.io.schubfach", + "tools.jackson.core.json", + "tools.jackson.core.json.async", + "tools.jackson.core.sym", + "tools.jackson.core.tree", + "tools.jackson.core.type", + "tools.jackson.core.util" + ], + "tools.jackson.core:jackson-databind": [ + "tools.jackson.databind", + "tools.jackson.databind.annotation", + "tools.jackson.databind.cfg", + "tools.jackson.databind.deser", + "tools.jackson.databind.deser.bean", + "tools.jackson.databind.deser.impl", + "tools.jackson.databind.deser.jackson", + "tools.jackson.databind.deser.jdk", + "tools.jackson.databind.deser.std", + "tools.jackson.databind.exc", + "tools.jackson.databind.ext", + "tools.jackson.databind.ext.beans", + "tools.jackson.databind.ext.javatime", + "tools.jackson.databind.ext.javatime.deser", + "tools.jackson.databind.ext.javatime.deser.key", + "tools.jackson.databind.ext.javatime.ser", + "tools.jackson.databind.ext.javatime.ser.key", + "tools.jackson.databind.ext.javatime.util", + "tools.jackson.databind.ext.jdk8", + "tools.jackson.databind.ext.sql", + "tools.jackson.databind.introspect", + "tools.jackson.databind.json", + "tools.jackson.databind.jsonFormatVisitors", + "tools.jackson.databind.jsontype", + "tools.jackson.databind.jsontype.impl", + "tools.jackson.databind.module", + "tools.jackson.databind.node", + "tools.jackson.databind.ser", + "tools.jackson.databind.ser.bean", + "tools.jackson.databind.ser.impl", + "tools.jackson.databind.ser.jackson", + "tools.jackson.databind.ser.jdk", + "tools.jackson.databind.ser.std", + "tools.jackson.databind.type", + "tools.jackson.databind.util", + "tools.jackson.databind.util.internal" + ] + }, + "repositories": { + "https://maven-central.storage-download.googleapis.com/maven2/": [ + "ch.qos.logback:logback-classic", + "ch.qos.logback:logback-classic:jar:sources", + "ch.qos.logback:logback-core", + "ch.qos.logback:logback-core:jar:sources", + "com.fasterxml.jackson.core:jackson-annotations", + "com.fasterxml.jackson.core:jackson-annotations:jar:sources", + "com.google.code.findbugs:jsr305", + "com.google.code.findbugs:jsr305:jar:sources", + "com.google.code.gson:gson", + "com.google.code.gson:gson:jar:sources", + "com.google.errorprone:error_prone_annotations", + "com.google.errorprone:error_prone_annotations:jar:sources", + "com.google.guava:failureaccess", + "com.google.guava:failureaccess:jar:sources", + "com.google.guava:guava", + "com.google.guava:guava:jar:sources", + "com.google.guava:listenablefuture", + "com.google.j2objc:j2objc-annotations", + "com.google.j2objc:j2objc-annotations:jar:sources", + "com.jayway.jsonpath:json-path", + "com.jayway.jsonpath:json-path:jar:sources", + "com.vaadin.external.google:android-json", + "com.vaadin.external.google:android-json:jar:sources", + "commons-logging:commons-logging", + "commons-logging:commons-logging:jar:sources", + "io.micrometer:micrometer-commons", + "io.micrometer:micrometer-commons:jar:sources", + "io.micrometer:micrometer-observation", + "io.micrometer:micrometer-observation:jar:sources", + "jakarta.activation:jakarta.activation-api", + "jakarta.activation:jakarta.activation-api:jar:sources", + "jakarta.annotation:jakarta.annotation-api", + "jakarta.annotation:jakarta.annotation-api:jar:sources", + "jakarta.xml.bind:jakarta.xml.bind-api", + "jakarta.xml.bind:jakarta.xml.bind-api:jar:sources", + "net.bytebuddy:byte-buddy", + "net.bytebuddy:byte-buddy-agent", + "net.bytebuddy:byte-buddy-agent:jar:sources", + "net.bytebuddy:byte-buddy:jar:sources", + "net.minidev:accessors-smart", + "net.minidev:accessors-smart:jar:sources", + "net.minidev:json-smart", + "net.minidev:json-smart:jar:sources", + "org.apache.logging.log4j:log4j-api", + "org.apache.logging.log4j:log4j-api:jar:sources", + "org.apache.logging.log4j:log4j-to-slf4j", + "org.apache.logging.log4j:log4j-to-slf4j:jar:sources", + "org.apache.tomcat.embed:tomcat-embed-core", + "org.apache.tomcat.embed:tomcat-embed-core:jar:sources", + "org.apache.tomcat.embed:tomcat-embed-el", + "org.apache.tomcat.embed:tomcat-embed-el:jar:sources", + "org.apache.tomcat.embed:tomcat-embed-websocket", + "org.apache.tomcat.embed:tomcat-embed-websocket:jar:sources", + "org.apiguardian:apiguardian-api", + "org.apiguardian:apiguardian-api:jar:sources", + "org.assertj:assertj-core", + "org.assertj:assertj-core:jar:sources", + "org.awaitility:awaitility", + "org.awaitility:awaitility:jar:sources", + "org.checkerframework:checker-qual", + "org.checkerframework:checker-qual:jar:sources", + "org.hamcrest:hamcrest", + "org.hamcrest:hamcrest:jar:sources", + "org.jspecify:jspecify", + "org.jspecify:jspecify:jar:sources", + "org.junit.jupiter:junit-jupiter", + "org.junit.jupiter:junit-jupiter-api", + "org.junit.jupiter:junit-jupiter-api:jar:sources", + "org.junit.jupiter:junit-jupiter-engine", + "org.junit.jupiter:junit-jupiter-engine:jar:sources", + "org.junit.jupiter:junit-jupiter-params", + "org.junit.jupiter:junit-jupiter-params:jar:sources", + "org.junit.jupiter:junit-jupiter:jar:sources", + "org.junit.platform:junit-platform-commons", + "org.junit.platform:junit-platform-commons:jar:sources", + "org.junit.platform:junit-platform-engine", + "org.junit.platform:junit-platform-engine:jar:sources", + "org.junit.platform:junit-platform-launcher", + "org.junit.platform:junit-platform-launcher:jar:sources", + "org.junit.platform:junit-platform-reporting", + "org.junit.platform:junit-platform-reporting:jar:sources", + "org.mockito:mockito-core", + "org.mockito:mockito-core:jar:sources", + "org.mockito:mockito-junit-jupiter", + "org.mockito:mockito-junit-jupiter:jar:sources", + "org.objenesis:objenesis", + "org.objenesis:objenesis:jar:sources", + "org.opentest4j.reporting:open-test-reporting-tooling-spi", + "org.opentest4j.reporting:open-test-reporting-tooling-spi:jar:sources", + "org.opentest4j:opentest4j", + "org.opentest4j:opentest4j:jar:sources", + "org.ow2.asm:asm", + "org.ow2.asm:asm:jar:sources", + "org.skyscreamer:jsonassert", + "org.skyscreamer:jsonassert:jar:sources", + "org.slf4j:jul-to-slf4j", + "org.slf4j:jul-to-slf4j:jar:sources", + "org.slf4j:slf4j-api", + "org.slf4j:slf4j-api:jar:sources", + "org.springframework.boot:spring-boot", + "org.springframework.boot:spring-boot-autoconfigure", + "org.springframework.boot:spring-boot-autoconfigure:jar:sources", + "org.springframework.boot:spring-boot-http-converter", + "org.springframework.boot:spring-boot-http-converter:jar:sources", + "org.springframework.boot:spring-boot-jackson", + "org.springframework.boot:spring-boot-jackson:jar:sources", + "org.springframework.boot:spring-boot-servlet", + "org.springframework.boot:spring-boot-servlet:jar:sources", + "org.springframework.boot:spring-boot-starter", + "org.springframework.boot:spring-boot-starter-jackson", + "org.springframework.boot:spring-boot-starter-jackson:jar:sources", + "org.springframework.boot:spring-boot-starter-logging", + "org.springframework.boot:spring-boot-starter-logging:jar:sources", + "org.springframework.boot:spring-boot-starter-test", + "org.springframework.boot:spring-boot-starter-test:jar:sources", + "org.springframework.boot:spring-boot-starter-tomcat", + "org.springframework.boot:spring-boot-starter-tomcat-runtime", + "org.springframework.boot:spring-boot-starter-tomcat-runtime:jar:sources", + "org.springframework.boot:spring-boot-starter-tomcat:jar:sources", + "org.springframework.boot:spring-boot-starter-web", + "org.springframework.boot:spring-boot-starter-web:jar:sources", + "org.springframework.boot:spring-boot-starter:jar:sources", + "org.springframework.boot:spring-boot-test", + "org.springframework.boot:spring-boot-test-autoconfigure", + "org.springframework.boot:spring-boot-test-autoconfigure:jar:sources", + "org.springframework.boot:spring-boot-test:jar:sources", + "org.springframework.boot:spring-boot-tomcat", + "org.springframework.boot:spring-boot-tomcat:jar:sources", + "org.springframework.boot:spring-boot-web-server", + "org.springframework.boot:spring-boot-web-server:jar:sources", + "org.springframework.boot:spring-boot-webmvc", + "org.springframework.boot:spring-boot-webmvc-test", + "org.springframework.boot:spring-boot-webmvc-test:jar:sources", + "org.springframework.boot:spring-boot-webmvc:jar:sources", + "org.springframework.boot:spring-boot:jar:sources", + "org.springframework:spring-aop", + "org.springframework:spring-aop:jar:sources", + "org.springframework:spring-beans", + "org.springframework:spring-beans:jar:sources", + "org.springframework:spring-context", + "org.springframework:spring-context:jar:sources", + "org.springframework:spring-core", + "org.springframework:spring-core:jar:sources", + "org.springframework:spring-expression", + "org.springframework:spring-expression:jar:sources", + "org.springframework:spring-test", + "org.springframework:spring-test:jar:sources", + "org.springframework:spring-web", + "org.springframework:spring-web:jar:sources", + "org.springframework:spring-webmvc", + "org.springframework:spring-webmvc:jar:sources", + "org.xmlunit:xmlunit-core", + "org.xmlunit:xmlunit-core:jar:sources", + "org.yaml:snakeyaml", + "org.yaml:snakeyaml:jar:sources", + "tools.jackson.core:jackson-core", + "tools.jackson.core:jackson-core:jar:sources", + "tools.jackson.core:jackson-databind", + "tools.jackson.core:jackson-databind:jar:sources" + ], + "https://repo.maven.apache.org/maven2/": [ + "ch.qos.logback:logback-classic", + "ch.qos.logback:logback-classic:jar:sources", + "ch.qos.logback:logback-core", + "ch.qos.logback:logback-core:jar:sources", + "com.fasterxml.jackson.core:jackson-annotations", + "com.fasterxml.jackson.core:jackson-annotations:jar:sources", + "com.google.code.findbugs:jsr305", + "com.google.code.findbugs:jsr305:jar:sources", + "com.google.code.gson:gson", + "com.google.code.gson:gson:jar:sources", + "com.google.errorprone:error_prone_annotations", + "com.google.errorprone:error_prone_annotations:jar:sources", + "com.google.guava:failureaccess", + "com.google.guava:failureaccess:jar:sources", + "com.google.guava:guava", + "com.google.guava:guava:jar:sources", + "com.google.guava:listenablefuture", + "com.google.j2objc:j2objc-annotations", + "com.google.j2objc:j2objc-annotations:jar:sources", + "com.jayway.jsonpath:json-path", + "com.jayway.jsonpath:json-path:jar:sources", + "com.vaadin.external.google:android-json", + "com.vaadin.external.google:android-json:jar:sources", + "commons-logging:commons-logging", + "commons-logging:commons-logging:jar:sources", + "io.micrometer:micrometer-commons", + "io.micrometer:micrometer-commons:jar:sources", + "io.micrometer:micrometer-observation", + "io.micrometer:micrometer-observation:jar:sources", + "jakarta.activation:jakarta.activation-api", + "jakarta.activation:jakarta.activation-api:jar:sources", + "jakarta.annotation:jakarta.annotation-api", + "jakarta.annotation:jakarta.annotation-api:jar:sources", + "jakarta.xml.bind:jakarta.xml.bind-api", + "jakarta.xml.bind:jakarta.xml.bind-api:jar:sources", + "net.bytebuddy:byte-buddy", + "net.bytebuddy:byte-buddy-agent", + "net.bytebuddy:byte-buddy-agent:jar:sources", + "net.bytebuddy:byte-buddy:jar:sources", + "net.minidev:accessors-smart", + "net.minidev:accessors-smart:jar:sources", + "net.minidev:json-smart", + "net.minidev:json-smart:jar:sources", + "org.apache.logging.log4j:log4j-api", + "org.apache.logging.log4j:log4j-api:jar:sources", + "org.apache.logging.log4j:log4j-to-slf4j", + "org.apache.logging.log4j:log4j-to-slf4j:jar:sources", + "org.apache.tomcat.embed:tomcat-embed-core", + "org.apache.tomcat.embed:tomcat-embed-core:jar:sources", + "org.apache.tomcat.embed:tomcat-embed-el", + "org.apache.tomcat.embed:tomcat-embed-el:jar:sources", + "org.apache.tomcat.embed:tomcat-embed-websocket", + "org.apache.tomcat.embed:tomcat-embed-websocket:jar:sources", + "org.apiguardian:apiguardian-api", + "org.apiguardian:apiguardian-api:jar:sources", + "org.assertj:assertj-core", + "org.assertj:assertj-core:jar:sources", + "org.awaitility:awaitility", + "org.awaitility:awaitility:jar:sources", + "org.checkerframework:checker-qual", + "org.checkerframework:checker-qual:jar:sources", + "org.hamcrest:hamcrest", + "org.hamcrest:hamcrest:jar:sources", + "org.jspecify:jspecify", + "org.jspecify:jspecify:jar:sources", + "org.junit.jupiter:junit-jupiter", + "org.junit.jupiter:junit-jupiter-api", + "org.junit.jupiter:junit-jupiter-api:jar:sources", + "org.junit.jupiter:junit-jupiter-engine", + "org.junit.jupiter:junit-jupiter-engine:jar:sources", + "org.junit.jupiter:junit-jupiter-params", + "org.junit.jupiter:junit-jupiter-params:jar:sources", + "org.junit.jupiter:junit-jupiter:jar:sources", + "org.junit.platform:junit-platform-commons", + "org.junit.platform:junit-platform-commons:jar:sources", + "org.junit.platform:junit-platform-engine", + "org.junit.platform:junit-platform-engine:jar:sources", + "org.junit.platform:junit-platform-launcher", + "org.junit.platform:junit-platform-launcher:jar:sources", + "org.junit.platform:junit-platform-reporting", + "org.junit.platform:junit-platform-reporting:jar:sources", + "org.mockito:mockito-core", + "org.mockito:mockito-core:jar:sources", + "org.mockito:mockito-junit-jupiter", + "org.mockito:mockito-junit-jupiter:jar:sources", + "org.objenesis:objenesis", + "org.objenesis:objenesis:jar:sources", + "org.opentest4j.reporting:open-test-reporting-tooling-spi", + "org.opentest4j.reporting:open-test-reporting-tooling-spi:jar:sources", + "org.opentest4j:opentest4j", + "org.opentest4j:opentest4j:jar:sources", + "org.ow2.asm:asm", + "org.ow2.asm:asm:jar:sources", + "org.skyscreamer:jsonassert", + "org.skyscreamer:jsonassert:jar:sources", + "org.slf4j:jul-to-slf4j", + "org.slf4j:jul-to-slf4j:jar:sources", + "org.slf4j:slf4j-api", + "org.slf4j:slf4j-api:jar:sources", + "org.springframework.boot:spring-boot", + "org.springframework.boot:spring-boot-autoconfigure", + "org.springframework.boot:spring-boot-autoconfigure:jar:sources", + "org.springframework.boot:spring-boot-http-converter", + "org.springframework.boot:spring-boot-http-converter:jar:sources", + "org.springframework.boot:spring-boot-jackson", + "org.springframework.boot:spring-boot-jackson:jar:sources", + "org.springframework.boot:spring-boot-servlet", + "org.springframework.boot:spring-boot-servlet:jar:sources", + "org.springframework.boot:spring-boot-starter", + "org.springframework.boot:spring-boot-starter-jackson", + "org.springframework.boot:spring-boot-starter-jackson:jar:sources", + "org.springframework.boot:spring-boot-starter-logging", + "org.springframework.boot:spring-boot-starter-logging:jar:sources", + "org.springframework.boot:spring-boot-starter-test", + "org.springframework.boot:spring-boot-starter-test:jar:sources", + "org.springframework.boot:spring-boot-starter-tomcat", + "org.springframework.boot:spring-boot-starter-tomcat-runtime", + "org.springframework.boot:spring-boot-starter-tomcat-runtime:jar:sources", + "org.springframework.boot:spring-boot-starter-tomcat:jar:sources", + "org.springframework.boot:spring-boot-starter-web", + "org.springframework.boot:spring-boot-starter-web:jar:sources", + "org.springframework.boot:spring-boot-starter:jar:sources", + "org.springframework.boot:spring-boot-test", + "org.springframework.boot:spring-boot-test-autoconfigure", + "org.springframework.boot:spring-boot-test-autoconfigure:jar:sources", + "org.springframework.boot:spring-boot-test:jar:sources", + "org.springframework.boot:spring-boot-tomcat", + "org.springframework.boot:spring-boot-tomcat:jar:sources", + "org.springframework.boot:spring-boot-web-server", + "org.springframework.boot:spring-boot-web-server:jar:sources", + "org.springframework.boot:spring-boot-webmvc", + "org.springframework.boot:spring-boot-webmvc-test", + "org.springframework.boot:spring-boot-webmvc-test:jar:sources", + "org.springframework.boot:spring-boot-webmvc:jar:sources", + "org.springframework.boot:spring-boot:jar:sources", + "org.springframework:spring-aop", + "org.springframework:spring-aop:jar:sources", + "org.springframework:spring-beans", + "org.springframework:spring-beans:jar:sources", + "org.springframework:spring-context", + "org.springframework:spring-context:jar:sources", + "org.springframework:spring-core", + "org.springframework:spring-core:jar:sources", + "org.springframework:spring-expression", + "org.springframework:spring-expression:jar:sources", + "org.springframework:spring-test", + "org.springframework:spring-test:jar:sources", + "org.springframework:spring-web", + "org.springframework:spring-web:jar:sources", + "org.springframework:spring-webmvc", + "org.springframework:spring-webmvc:jar:sources", + "org.xmlunit:xmlunit-core", + "org.xmlunit:xmlunit-core:jar:sources", + "org.yaml:snakeyaml", + "org.yaml:snakeyaml:jar:sources", + "tools.jackson.core:jackson-core", + "tools.jackson.core:jackson-core:jar:sources", + "tools.jackson.core:jackson-databind", + "tools.jackson.core:jackson-databind:jar:sources" + ] + }, + "services": { + "ch.qos.logback:logback-classic": { + "jakarta.servlet.ServletContainerInitializer": [ + "ch.qos.logback.classic.servlet.LogbackServletContainerInitializer" + ], + "org.slf4j.spi.SLF4JServiceProvider": [ + "ch.qos.logback.classic.spi.LogbackServiceProvider" + ] + }, + "io.micrometer:micrometer-observation": { + "io.micrometer.context.ThreadLocalAccessor": [ + "io.micrometer.observation.contextpropagation.ObservationThreadLocalAccessor" + ] + }, + "org.apache.logging.log4j:log4j-api": { + "org.apache.logging.log4j.util.PropertySource": [ + "org.apache.logging.log4j.util.EnvironmentPropertySource", + "org.apache.logging.log4j.util.SystemPropertiesPropertySource" + ] + }, + "org.apache.logging.log4j:log4j-to-slf4j": { + "org.apache.logging.log4j.spi.Provider": [ + "org.apache.logging.slf4j.SLF4JProvider" + ] + }, + "org.apache.tomcat.embed:tomcat-embed-el": { + "jakarta.el.ExpressionFactory": [ + "org.apache.el.ExpressionFactoryImpl" + ] + }, + "org.apache.tomcat.embed:tomcat-embed-websocket": { + "jakarta.servlet.ServletContainerInitializer": [ + "org.apache.tomcat.websocket.server.WsSci" + ], + "jakarta.websocket.ContainerProvider": [ + "org.apache.tomcat.websocket.WsContainerProvider" + ], + "jakarta.websocket.server.ServerEndpointConfig$Configurator": [ + "org.apache.tomcat.websocket.server.DefaultServerEndpointConfigurator" + ] + }, + "org.junit.jupiter:junit-jupiter-engine": { + "org.junit.platform.engine.TestEngine": [ + "org.junit.jupiter.engine.JupiterTestEngine" + ] + }, + "org.junit.platform:junit-platform-engine": { + "org.junit.platform.engine.discovery.DiscoverySelectorIdentifierParser": [ + "org.junit.platform.engine.discovery.ClassSelector$IdentifierParser", + "org.junit.platform.engine.discovery.ClasspathResourceSelector$IdentifierParser", + "org.junit.platform.engine.discovery.ClasspathRootSelector$IdentifierParser", + "org.junit.platform.engine.discovery.DirectorySelector$IdentifierParser", + "org.junit.platform.engine.discovery.FileSelector$IdentifierParser", + "org.junit.platform.engine.discovery.IterationSelector$IdentifierParser", + "org.junit.platform.engine.discovery.MethodSelector$IdentifierParser", + "org.junit.platform.engine.discovery.ModuleSelector$IdentifierParser", + "org.junit.platform.engine.discovery.NestedClassSelector$IdentifierParser", + "org.junit.platform.engine.discovery.NestedMethodSelector$IdentifierParser", + "org.junit.platform.engine.discovery.PackageSelector$IdentifierParser", + "org.junit.platform.engine.discovery.UniqueIdSelector$IdentifierParser", + "org.junit.platform.engine.discovery.UriSelector$IdentifierParser" + ] + }, + "org.junit.platform:junit-platform-launcher": { + "org.junit.platform.launcher.TestExecutionListener": [ + "org.junit.platform.launcher.listeners.UniqueIdTrackingListener" + ] + }, + "org.junit.platform:junit-platform-reporting": { + "org.junit.platform.launcher.TestExecutionListener": [ + "org.junit.platform.reporting.open.xml.OpenTestReportGeneratingListener" + ], + "org.opentest4j.reporting.tooling.spi.htmlreport.Contributor": [ + "org.junit.platform.reporting.open.xml.JUnitContributor" + ] + }, + "org.springframework.boot:spring-boot": { + "ch.qos.logback.classic.spi.Configurator": [ + "org.springframework.boot.logging.logback.RootLogLevelConfigurator" + ], + "org.apache.logging.log4j.util.PropertySource": [ + "org.springframework.boot.logging.log4j2.SpringBootPropertySource" + ] + }, + "org.springframework:spring-core": { + "reactor.blockhound.integration.BlockHoundIntegration": [ + "org.springframework.core.ReactiveAdapterRegistry$SpringCoreBlockHoundIntegration" + ] + }, + "org.springframework:spring-web": { + "jakarta.servlet.ServletContainerInitializer": [ + "org.springframework.web.SpringServletContainerInitializer" + ], + "reactor.blockhound.integration.BlockHoundIntegration": [ + "org.springframework.web.server.adapter.WebHttpHandlerBuilder$SpringWebBlockHoundIntegration" + ] + }, + "tools.jackson.core:jackson-core": { + "tools.jackson.core.TokenStreamFactory": [ + "tools.jackson.core.json.JsonFactory" + ] + }, + "tools.jackson.core:jackson-databind": { + "tools.jackson.databind.ObjectMapper": [ + "tools.jackson.databind.json.JsonMapper" + ] + } + }, + "skipped": [], + "version": "3" +} diff --git a/rules/java/.bazelrc b/rules/java/.bazelrc new file mode 100644 index 000000000..3dcfdd132 --- /dev/null +++ b/rules/java/.bazelrc @@ -0,0 +1,47 @@ +# SPDX-FileCopyrightText: Copyright (c) NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +# +# 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. + +# Standalone module .bazelrc. `cd rules/java && bazel build //...` must work with +# no reference to the repo root. The caller supplies any remote cache endpoint; +# no cache config is baked in (parity with the other nested modules). + +common --enable_bzlmod +common --enable_platform_specific_config +build --incompatible_strict_action_env + +# Route public Maven Central through an internal Artifactory mirror on internal +# builds only. The target host lives in an un-mirrored internal bazelrc, so +# public builds go straight to Maven Central (try-import is a no-op when absent). +try-import %workspace%/tools/bazel/internal.bazelrc + +# Java: hermetic remotejdk 25 regardless of the host JDK, matching the root +# module so builds are reproducible everywhere. +build --java_language_version=25 +build --java_runtime_version=remotejdk_25 +build --tool_java_language_version=25 +build --tool_java_runtime_version=remotejdk_25 +build --java_header_compilation=false + +test --test_output=errors +test --test_env=HOME=/tmp +test --test_env=XDG_CACHE_HOME=/tmp/.cache + +startup --host_jvm_args=-Xmx4g + +build:release --compilation_mode=opt +build:release --strip=always + +try-import %workspace%/user.bazelrc +try-import %user.home%/.bazelrc.user diff --git a/rules/java/.gitignore b/rules/java/.gitignore new file mode 100644 index 000000000..a6ef824c1 --- /dev/null +++ b/rules/java/.gitignore @@ -0,0 +1 @@ +/bazel-* diff --git a/rules/java/AGENTS.md b/rules/java/AGENTS.md new file mode 100644 index 000000000..7b8c5f23b --- /dev/null +++ b/rules/java/AGENTS.md @@ -0,0 +1,47 @@ +# AGENTS.md - nvcf_java_rules + +Standalone Bazel module (`module(name = "nvcf_java_rules")`) holding the shared +Java build macros and platform constants for every NVCF Java module. No +application code lives here. + +## What this module provides + +- `//:defs.bzl` - `nvcf_java_library`, `nvcf_spring_boot_image`. +- `//:platform.bzl` - `SPRING_BOOT_BOM`, `MAVEN_REPOSITORIES`, and the Spring / + Spring Cloud / Testcontainers / ShedLock version constants. Single source of + truth for the platform. +- `//:bom_alignment.bzl` - `bom_alignment_test`, the guard that keeps each + consuming module's inlined `boms` list identical to `SPRING_BOOT_BOM`. +- `//private:oci.bzl` - vendored `create_oci_image` (multi-arch), so this module + does not depend on the root workspace's `//rules/oci`. +- `//platforms:linux_arm64`, `//platforms:linux_x86_64`. + +## How modules consume it + +A Java module adds, in its `MODULE.bazel`: + +```python +bazel_dep(name = "nvcf_java_rules", version = "0.1.0") +local_path_override(module_name = "nvcf_java_rules", path = "<relpath>/rules/java") +``` + +and inlines the same literal BOM list `SPRING_BOOT_BOM` exposes (load() is +forbidden in MODULE.bazel), guarded by `bom_alignment_test`. + +## BOM / version bumps + +Bumping Spring, Spring Cloud, Testcontainers, or ShedLock is a one-line edit in +`//:platform.bzl`, the matching edit to every Java module's inlined `boms`, then +a re-pin (`REPIN=1 bazel run @maven//:pin`) of each module. `bom_alignment_test` +fails any module left un-aligned. + +## Build + +``` +cd rules/java && bazel build //... +``` + +The module resolves only public BCR modules plus its OCI bases, so it builds on +the public mirror. It is not in the root `.bazelignore` because its BUILD files +declare no targets that reference the root workspace; the root never loads its +`.bzl` files once Java services are their own modules. diff --git a/rules/java/CLAUDE.md b/rules/java/CLAUDE.md new file mode 100644 index 000000000..43c994c2d --- /dev/null +++ b/rules/java/CLAUDE.md @@ -0,0 +1 @@ +@AGENTS.md diff --git a/rules/java/MODULE.bazel b/rules/java/MODULE.bazel new file mode 100644 index 000000000..84a13cc25 --- /dev/null +++ b/rules/java/MODULE.bazel @@ -0,0 +1,71 @@ +# SPDX-FileCopyrightText: Copyright (c) NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +# +# 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. + +"""nvcf_java_rules: shared Bazel macros and platform constants for NVCF Java. + +Standalone module. Holds no application code. Every Java library and service +module consumes it via bazel_dep + local_path_override, loads the shared Spring +Boot BOM and version constants from //:platform.bzl, and builds images with the +nvcf_spring_boot_image macro. See //:platform.bzl for the single source of truth +on Spring/Cloud/Testcontainers versions. +""" + +module( + name = "nvcf_java_rules", + version = "0.1.0", +) + +bazel_dep(name = "rules_java", version = "9.3.0") +bazel_dep(name = "rules_jvm_external", version = "7.0") +bazel_dep(name = "contrib_rules_jvm", version = "0.33.0") +bazel_dep(name = "rules_oci", version = "2.2.7") +bazel_dep(name = "rules_pkg", version = "1.2.0") +bazel_dep(name = "aspect_bazel_lib", version = "2.19.3") +bazel_dep(name = "rules_shell", version = "0.8.0") +bazel_dep(name = "platforms", version = "1.0.0") + +# OCI base images for the vendored create_oci_image helper (used by the +# nvcf_spring_boot_image macro). These are declared here so a consuming Java +# service module inherits them transitively and does not re-pin the bases. +# Both mirror the root module's pins: the AWS public ECR mirrors avoid Docker +# Hub anonymous pull limits and resolve on the public GitHub mirror. +oci = use_extension("@rules_oci//oci:extensions.bzl", "oci") +oci.pull( + name = "temurin_jre", + image = "public.ecr.aws/docker/library/eclipse-temurin", + platforms = [ + "linux/arm64/v8", + "linux/amd64", + ], + tag = "21-jre", +) +oci.pull( + name = "ubuntu_noble", + digest = "sha256:ef59d9e82939bbce08973bdffb8761b025f75369fb7d2882cdc4938b5a9e992e", + image = "public.ecr.aws/ubuntu/ubuntu", + platforms = [ + "linux/arm64/v8", + "linux/amd64", + ], +) +use_repo( + oci, + "temurin_jre", + "temurin_jre_linux_amd64", + "temurin_jre_linux_arm64_v8", + "ubuntu_noble", + "ubuntu_noble_linux_amd64", + "ubuntu_noble_linux_arm64_v8", +) diff --git a/rules/java/MODULE.bazel.lock b/rules/java/MODULE.bazel.lock new file mode 100644 index 000000000..41ddc67af --- /dev/null +++ b/rules/java/MODULE.bazel.lock @@ -0,0 +1,296 @@ +{ + "lockFileVersion": 28, + "registryFileHashes": { + "https://bcr.bazel.build/bazel_registry.json": "8a28e4aff06ee60aed2a8c281907fb8bcbf3b753c91fb5a5c57da3215d5b3497", + "https://bcr.bazel.build/modules/abseil-cpp/20210324.2/MODULE.bazel": "7cd0312e064fde87c8d1cd79ba06c876bd23630c83466e9500321be55c96ace2", + "https://bcr.bazel.build/modules/abseil-cpp/20211102.0/MODULE.bazel": "70390338f7a5106231d20620712f7cccb659cd0e9d073d1991c038eb9fc57589", + "https://bcr.bazel.build/modules/abseil-cpp/20230125.1/MODULE.bazel": "89047429cb0207707b2dface14ba7f8df85273d484c2572755be4bab7ce9c3a0", + "https://bcr.bazel.build/modules/abseil-cpp/20230802.0.bcr.1/MODULE.bazel": "1c8cec495288dccd14fdae6e3f95f772c1c91857047a098fad772034264cc8cb", + "https://bcr.bazel.build/modules/abseil-cpp/20230802.0/MODULE.bazel": "d253ae36a8bd9ee3c5955384096ccb6baf16a1b1e93e858370da0a3b94f77c16", + "https://bcr.bazel.build/modules/abseil-cpp/20230802.1/MODULE.bazel": "fa92e2eb41a04df73cdabeec37107316f7e5272650f81d6cc096418fe647b915", + "https://bcr.bazel.build/modules/abseil-cpp/20240116.1/MODULE.bazel": "37bcdb4440fbb61df6a1c296ae01b327f19e9bb521f9b8e26ec854b6f97309ed", + "https://bcr.bazel.build/modules/abseil-cpp/20240116.2/MODULE.bazel": "73939767a4686cd9a520d16af5ab440071ed75cec1a876bf2fcfaf1f71987a16", + "https://bcr.bazel.build/modules/abseil-cpp/20250127.0/MODULE.bazel": "d1086e248cda6576862b4b3fe9ad76a214e08c189af5b42557a6e1888812c5d5", + "https://bcr.bazel.build/modules/abseil-cpp/20250127.1/MODULE.bazel": "c4a89e7ceb9bf1e25cf84a9f830ff6b817b72874088bf5141b314726e46a57c1", + "https://bcr.bazel.build/modules/abseil-cpp/20250512.1/MODULE.bazel": "d209fdb6f36ffaf61c509fcc81b19e81b411a999a934a032e10cd009a0226215", + "https://bcr.bazel.build/modules/abseil-cpp/20250814.1/MODULE.bazel": "51f2312901470cdab0dbdf3b88c40cd21c62a7ed58a3de45b365ddc5b11bcab2", + "https://bcr.bazel.build/modules/abseil-cpp/20250814.1/source.json": "cea3901d7e299da7320700abbaafe57a65d039f10d0d7ea601c4a66938ea4b0c", + "https://bcr.bazel.build/modules/abseil-py/2.1.0/MODULE.bazel": "5ebe5bf853769c65707e5c28f216798f7a4b1042015e6a36e6d03094d94bec8a", + "https://bcr.bazel.build/modules/abseil-py/2.1.0/source.json": "0e8fc4f088ce07099c1cd6594c20c7ddbb48b4b3c0849b7d94ba94be88ff042b", + "https://bcr.bazel.build/modules/apple_rules_lint/0.4.0/MODULE.bazel": "c59831c3a5389430516203777816527f257329a5da363994e1d62b9ae6729f71", + "https://bcr.bazel.build/modules/apple_rules_lint/0.4.0/source.json": "105883202602181f43f109372e1b9ea19e89bbe3bce4bc1fe9bb0baa51eb61ae", + "https://bcr.bazel.build/modules/apple_support/1.11.1/MODULE.bazel": "1843d7cd8a58369a444fc6000e7304425fba600ff641592161d9f15b179fb896", + "https://bcr.bazel.build/modules/apple_support/1.15.1/MODULE.bazel": "a0556fefca0b1bb2de8567b8827518f94db6a6e7e7d632b4c48dc5f865bc7c85", + "https://bcr.bazel.build/modules/apple_support/1.21.0/MODULE.bazel": "ac1824ed5edf17dee2fdd4927ada30c9f8c3b520be1b5fd02a5da15bc10bff3e", + "https://bcr.bazel.build/modules/apple_support/1.21.1/MODULE.bazel": "5809fa3efab15d1f3c3c635af6974044bac8a4919c62238cce06acee8a8c11f1", + "https://bcr.bazel.build/modules/apple_support/1.24.2/MODULE.bazel": "0e62471818affb9f0b26f128831d5c40b074d32e6dda5a0d3852847215a41ca4", + "https://bcr.bazel.build/modules/apple_support/1.24.2/source.json": "2c22c9827093250406c5568da6c54e6fdf0ef06238def3d99c71b12feb057a8d", + "https://bcr.bazel.build/modules/aspect_bazel_lib/2.14.0/MODULE.bazel": "2b31ffcc9bdc8295b2167e07a757dbbc9ac8906e7028e5170a3708cecaac119f", + "https://bcr.bazel.build/modules/aspect_bazel_lib/2.19.3/MODULE.bazel": "253d739ba126f62a5767d832765b12b59e9f8d2bc88cc1572f4a73e46eb298ca", + "https://bcr.bazel.build/modules/aspect_bazel_lib/2.19.3/source.json": "ffab9254c65ba945f8369297ad97ca0dec213d3adc6e07877e23a48624a8b456", + "https://bcr.bazel.build/modules/aspect_bazel_lib/2.7.2/MODULE.bazel": "780d1a6522b28f5edb7ea09630748720721dfe27690d65a2d33aa7509de77e07", + "https://bcr.bazel.build/modules/aspect_bazel_lib/2.8.1/MODULE.bazel": "812d2dd42f65dca362152101fbec418029cc8fd34cbad1a2fde905383d705838", + "https://bcr.bazel.build/modules/bazel_features/1.1.0/MODULE.bazel": "cfd42ff3b815a5f39554d97182657f8c4b9719568eb7fded2b9135f084bf760b", + "https://bcr.bazel.build/modules/bazel_features/1.1.1/MODULE.bazel": "27b8c79ef57efe08efccbd9dd6ef70d61b4798320b8d3c134fd571f78963dbcd", + "https://bcr.bazel.build/modules/bazel_features/1.10.0/MODULE.bazel": "f75e8807570484a99be90abcd52b5e1f390362c258bcb73106f4544957a48101", + "https://bcr.bazel.build/modules/bazel_features/1.11.0/MODULE.bazel": "f9382337dd5a474c3b7d334c2f83e50b6eaedc284253334cf823044a26de03e8", + "https://bcr.bazel.build/modules/bazel_features/1.13.0/MODULE.bazel": "c14c33c7c3c730612bdbe14ebbb5e61936b6f11322ea95a6e91cd1ba962f94df", + "https://bcr.bazel.build/modules/bazel_features/1.15.0/MODULE.bazel": "d38ff6e517149dc509406aca0db3ad1efdd890a85e049585b7234d04238e2a4d", + "https://bcr.bazel.build/modules/bazel_features/1.17.0/MODULE.bazel": "039de32d21b816b47bd42c778e0454217e9c9caac4a3cf8e15c7231ee3ddee4d", + "https://bcr.bazel.build/modules/bazel_features/1.18.0/MODULE.bazel": "1be0ae2557ab3a72a57aeb31b29be347bcdc5d2b1eb1e70f39e3851a7e97041a", + "https://bcr.bazel.build/modules/bazel_features/1.19.0/MODULE.bazel": "59adcdf28230d220f0067b1f435b8537dd033bfff8db21335ef9217919c7fb58", + "https://bcr.bazel.build/modules/bazel_features/1.21.0/MODULE.bazel": "675642261665d8eea09989aa3b8afb5c37627f1be178382c320d1b46afba5e3b", + "https://bcr.bazel.build/modules/bazel_features/1.23.0/MODULE.bazel": "fd1ac84bc4e97a5a0816b7fd7d4d4f6d837b0047cf4cbd81652d616af3a6591a", + "https://bcr.bazel.build/modules/bazel_features/1.25.0/MODULE.bazel": "e2e60a10a6da64bbf533f15ca652bf61a033e41c2ed734d79a9a08ba87f68c1a", + "https://bcr.bazel.build/modules/bazel_features/1.27.0/MODULE.bazel": "621eeee06c4458a9121d1f104efb80f39d34deff4984e778359c60eaf1a8cb65", + "https://bcr.bazel.build/modules/bazel_features/1.28.0/MODULE.bazel": "4b4200e6cbf8fa335b2c3f43e1d6ef3e240319c33d43d60cc0fbd4b87ece299d", + "https://bcr.bazel.build/modules/bazel_features/1.3.0/MODULE.bazel": "cdcafe83ec318cda34e02948e81d790aab8df7a929cec6f6969f13a489ccecd9", + "https://bcr.bazel.build/modules/bazel_features/1.30.0/MODULE.bazel": "a14b62d05969a293b80257e72e597c2da7f717e1e69fa8b339703ed6731bec87", + "https://bcr.bazel.build/modules/bazel_features/1.33.0/MODULE.bazel": "8b8dc9d2a4c88609409c3191165bccec0e4cb044cd7a72ccbe826583303459f6", + "https://bcr.bazel.build/modules/bazel_features/1.4.1/MODULE.bazel": "e45b6bb2350aff3e442ae1111c555e27eac1d915e77775f6fdc4b351b758b5d7", + "https://bcr.bazel.build/modules/bazel_features/1.42.1/MODULE.bazel": "275a59b5406ff18c01739860aa70ad7ccb3cfb474579411decca11c93b951080", + "https://bcr.bazel.build/modules/bazel_features/1.42.1/source.json": "fcd4396b2df85f64f2b3bb436ad870793ecf39180f1d796f913cc9276d355309", + "https://bcr.bazel.build/modules/bazel_features/1.9.0/MODULE.bazel": "885151d58d90d8d9c811eb75e3288c11f850e1d6b481a8c9f766adee4712358b", + "https://bcr.bazel.build/modules/bazel_features/1.9.1/MODULE.bazel": "8f679097876a9b609ad1f60249c49d68bfab783dd9be012faf9d82547b14815a", + "https://bcr.bazel.build/modules/bazel_lib/3.0.0/MODULE.bazel": "22b70b80ac89ad3f3772526cd9feee2fa412c2b01933fea7ed13238a448d370d", + "https://bcr.bazel.build/modules/bazel_lib/3.0.0/source.json": "895f21909c6fba01d7c17914bb6c8e135982275a1b18cdaa4e62272217ef1751", + "https://bcr.bazel.build/modules/bazel_skylib/1.0.3/MODULE.bazel": "bcb0fd896384802d1ad283b4e4eb4d718eebd8cb820b0a2c3a347fb971afd9d8", + "https://bcr.bazel.build/modules/bazel_skylib/1.1.1/MODULE.bazel": "1add3e7d93ff2e6998f9e118022c84d163917d912f5afafb3058e3d2f1545b5e", + "https://bcr.bazel.build/modules/bazel_skylib/1.2.0/MODULE.bazel": "44fe84260e454ed94ad326352a698422dbe372b21a1ac9f3eab76eb531223686", + "https://bcr.bazel.build/modules/bazel_skylib/1.2.1/MODULE.bazel": "f35baf9da0efe45fa3da1696ae906eea3d615ad41e2e3def4aeb4e8bc0ef9a7a", + "https://bcr.bazel.build/modules/bazel_skylib/1.3.0/MODULE.bazel": "20228b92868bf5cfc41bda7afc8a8ba2a543201851de39d990ec957b513579c5", + "https://bcr.bazel.build/modules/bazel_skylib/1.4.1/MODULE.bazel": "a0dcb779424be33100dcae821e9e27e4f2901d9dfd5333efe5ac6a8d7ab75e1d", + "https://bcr.bazel.build/modules/bazel_skylib/1.4.2/MODULE.bazel": "3bd40978e7a1fac911d5989e6b09d8f64921865a45822d8b09e815eaa726a651", + "https://bcr.bazel.build/modules/bazel_skylib/1.5.0/MODULE.bazel": "32880f5e2945ce6a03d1fbd588e9198c0a959bb42297b2cfaf1685b7bc32e138", + "https://bcr.bazel.build/modules/bazel_skylib/1.6.1/MODULE.bazel": "8fdee2dbaace6c252131c00e1de4b165dc65af02ea278476187765e1a617b917", + "https://bcr.bazel.build/modules/bazel_skylib/1.7.0/MODULE.bazel": "0db596f4563de7938de764cc8deeabec291f55e8ec15299718b93c4423e9796d", + "https://bcr.bazel.build/modules/bazel_skylib/1.7.1/MODULE.bazel": "3120d80c5861aa616222ec015332e5f8d3171e062e3e804a2a0253e1be26e59b", + "https://bcr.bazel.build/modules/bazel_skylib/1.8.1/MODULE.bazel": "88ade7293becda963e0e3ea33e7d54d3425127e0a326e0d17da085a5f1f03ff6", + "https://bcr.bazel.build/modules/bazel_skylib/1.8.2/MODULE.bazel": "69ad6927098316848b34a9142bcc975e018ba27f08c4ff403f50c1b6e646ca67", + "https://bcr.bazel.build/modules/bazel_skylib/1.8.2/source.json": "34a3c8bcf233b835eb74be9d628899bb32999d3e0eadef1947a0a562a2b16ffb", + "https://bcr.bazel.build/modules/bazel_worker_api/0.0.1/MODULE.bazel": "02a13b77321773b2042e70ee5e4c5e099c8ddee4cf2da9cd420442c36938d4bd", + "https://bcr.bazel.build/modules/bazel_worker_api/0.0.4/MODULE.bazel": "460aa12d01231a80cce03c548287b433b321d205b0028ae596728c35e5ee442e", + "https://bcr.bazel.build/modules/bazel_worker_api/0.0.8/MODULE.bazel": "396c1ef53835aafe3d42ce6619080531ee770648303731f16cfaa33fa056bf0c", + "https://bcr.bazel.build/modules/bazel_worker_api/0.0.8/source.json": "abaf8ac9d2ab2f47bda9af4c0c080ff7907378888e1f4bc62a0539dd13ba61e8", + "https://bcr.bazel.build/modules/bazel_worker_java/0.0.4/MODULE.bazel": "82494a01018bb7ef06d4a17ec4cd7a758721f10eb8b6c820a818e70d669500db", + "https://bcr.bazel.build/modules/bazel_worker_java/0.0.8/MODULE.bazel": "e76479eae70bd4e8f5f4c2dfc5d03ab971cfb18750246c7b3f3454c5c2ee6629", + "https://bcr.bazel.build/modules/bazel_worker_java/0.0.8/source.json": "9395c4679444bc47bf7e51a710366a4480aa371c6f6bed01868e2fabcf11acec", + "https://bcr.bazel.build/modules/buildozer/8.5.1/MODULE.bazel": "a35d9561b3fc5b18797c330793e99e3b834a473d5fbd3d7d7634aafc9bdb6f8f", + "https://bcr.bazel.build/modules/buildozer/8.5.1/source.json": "e3386e6ff4529f2442800dee47ad28d3e6487f36a1f75ae39ae56c70f0cd2fbd", + "https://bcr.bazel.build/modules/contrib_rules_jvm/0.33.0/MODULE.bazel": "1aba514585748372ee392484b2645f0bbcb13ad4271d5b7cace018280f15bae1", + "https://bcr.bazel.build/modules/contrib_rules_jvm/0.33.0/source.json": "e52d62ce2a2b8a513d6afe9178acc06a4349c9b0b4c0934d59085ed9df4b4de0", + "https://bcr.bazel.build/modules/gazelle/0.32.0/MODULE.bazel": "b499f58a5d0d3537f3cf5b76d8ada18242f64ec474d8391247438bf04f58c7b8", + "https://bcr.bazel.build/modules/gazelle/0.33.0/MODULE.bazel": "a13a0f279b462b784fb8dd52a4074526c4a2afe70e114c7d09066097a46b3350", + "https://bcr.bazel.build/modules/gazelle/0.34.0/MODULE.bazel": "abdd8ce4d70978933209db92e436deb3a8b737859e9354fb5fd11fb5c2004c8a", + "https://bcr.bazel.build/modules/gazelle/0.36.0/MODULE.bazel": "e375d5d6e9a6ca59b0cb38b0540bc9a05b6aa926d322f2de268ad267a2ee74c0", + "https://bcr.bazel.build/modules/gazelle/0.40.0/MODULE.bazel": "42ba5378ebe845fca43989a53186ab436d956db498acde790685fe0e8f9c6146", + "https://bcr.bazel.build/modules/gazelle/0.42.0/MODULE.bazel": "fa140a7c019f3a22779ba7c6132ffff9d2d10a51dba2f3304dee61523d11fef4", + "https://bcr.bazel.build/modules/gazelle/0.47.0/MODULE.bazel": "b61bb007c4efad134aa30ee7f4a8e2a39b22aa5685f005edaa022fbd1de43ebc", + "https://bcr.bazel.build/modules/gazelle/0.47.0/source.json": "aeb2e5df14b7fb298625d75d08b9c65bdb0b56014c5eb89da9e5dd0572280ae6", + "https://bcr.bazel.build/modules/google_benchmark/1.8.2/MODULE.bazel": "a70cf1bba851000ba93b58ae2f6d76490a9feb74192e57ab8e8ff13c34ec50cb", + "https://bcr.bazel.build/modules/googletest/1.11.0/MODULE.bazel": "3a83f095183f66345ca86aa13c58b59f9f94a2f81999c093d4eeaa2d262d12f4", + "https://bcr.bazel.build/modules/googletest/1.14.0.bcr.1/MODULE.bazel": "22c31a561553727960057361aa33bf20fb2e98584bc4fec007906e27053f80c6", + "https://bcr.bazel.build/modules/googletest/1.14.0/MODULE.bazel": "cfbcbf3e6eac06ef9d85900f64424708cc08687d1b527f0ef65aa7517af8118f", + "https://bcr.bazel.build/modules/googletest/1.15.2/MODULE.bazel": "6de1edc1d26cafb0ea1a6ab3f4d4192d91a312fd2d360b63adaa213cd00b2108", + "https://bcr.bazel.build/modules/googletest/1.17.0/MODULE.bazel": "dbec758171594a705933a29fcf69293d2468c49ec1f2ebca65c36f504d72df46", + "https://bcr.bazel.build/modules/googletest/1.17.0/source.json": "38e4454b25fc30f15439c0378e57909ab1fd0a443158aa35aec685da727cd713", + "https://bcr.bazel.build/modules/jq.bzl/0.1.0/MODULE.bazel": "2ce69b1af49952cd4121a9c3055faa679e748ce774c7f1fda9657f936cae902f", + "https://bcr.bazel.build/modules/jq.bzl/0.1.0/source.json": "746bf13cac0860f091df5e4911d0c593971cd8796b5ad4e809b2f8e133eee3d5", + "https://bcr.bazel.build/modules/jsoncpp/1.9.5/MODULE.bazel": "31271aedc59e815656f5736f282bb7509a97c7ecb43e927ac1a37966e0578075", + "https://bcr.bazel.build/modules/jsoncpp/1.9.6/MODULE.bazel": "2f8d20d3b7d54143213c4dfc3d98225c42de7d666011528dc8fe91591e2e17b0", + "https://bcr.bazel.build/modules/jsoncpp/1.9.6/source.json": "a04756d367a2126c3541682864ecec52f92cdee80a35735a3cb249ce015ca000", + "https://bcr.bazel.build/modules/libpfm/4.11.0/MODULE.bazel": "45061ff025b301940f1e30d2c16bea596c25b176c8b6b3087e92615adbd52902", + "https://bcr.bazel.build/modules/nlohmann_json/3.6.1/MODULE.bazel": "6f7b417dcc794d9add9e556673ad25cb3ba835224290f4f848f8e2db1e1fca74", + "https://bcr.bazel.build/modules/nlohmann_json/3.6.1/source.json": "f448c6e8963fdfa7eb831457df83ad63d3d6355018f6574fb017e8169deb43a9", + "https://bcr.bazel.build/modules/package_metadata/0.0.2/MODULE.bazel": "fb8d25550742674d63d7b250063d4580ca530499f045d70748b1b142081ebb92", + "https://bcr.bazel.build/modules/package_metadata/0.0.3/MODULE.bazel": "77890552ecea9e284b5424c9de827a58099348763a4359e975c359a83d4faa83", + "https://bcr.bazel.build/modules/package_metadata/0.0.5/MODULE.bazel": "ef4f9439e3270fdd6b9fd4dbc3d2f29d13888e44c529a1b243f7a31dfbc2e8e4", + "https://bcr.bazel.build/modules/package_metadata/0.0.7/MODULE.bazel": "7adb03933fc8401f495800cf4eafcff0edc6da0ff55c7db223ef69d19f689486", + "https://bcr.bazel.build/modules/package_metadata/0.0.7/source.json": "50639625e937b56115012674c797cca7a05a96b4878c87d803c13dc2b31de8a0", + "https://bcr.bazel.build/modules/platforms/0.0.10/MODULE.bazel": "8cb8efaf200bdeb2150d93e162c40f388529a25852b332cec879373771e48ed5", + "https://bcr.bazel.build/modules/platforms/0.0.11/MODULE.bazel": "0daefc49732e227caa8bfa834d65dc52e8cc18a2faf80df25e8caea151a9413f", + "https://bcr.bazel.build/modules/platforms/0.0.4/MODULE.bazel": "9b328e31ee156f53f3c416a64f8491f7eb731742655a47c9eec4703a71644aee", + "https://bcr.bazel.build/modules/platforms/0.0.5/MODULE.bazel": "5733b54ea419d5eaf7997054bb55f6a1d0b5ff8aedf0176fef9eea44f3acda37", + "https://bcr.bazel.build/modules/platforms/0.0.6/MODULE.bazel": "ad6eeef431dc52aefd2d77ed20a4b353f8ebf0f4ecdd26a807d2da5aa8cd0615", + "https://bcr.bazel.build/modules/platforms/0.0.7/MODULE.bazel": "72fd4a0ede9ee5c021f6a8dd92b503e089f46c227ba2813ff183b71616034814", + "https://bcr.bazel.build/modules/platforms/0.0.8/MODULE.bazel": "9f142c03e348f6d263719f5074b21ef3adf0b139ee4c5133e2aa35664da9eb2d", + "https://bcr.bazel.build/modules/platforms/0.0.9/MODULE.bazel": "4a87a60c927b56ddd67db50c89acaa62f4ce2a1d2149ccb63ffd871d5ce29ebc", + "https://bcr.bazel.build/modules/platforms/1.0.0/MODULE.bazel": "f05feb42b48f1b3c225e4ccf351f367be0371411a803198ec34a389fb22aa580", + "https://bcr.bazel.build/modules/platforms/1.0.0/source.json": "f4ff1fd412e0246fd38c82328eb209130ead81d62dcd5a9e40910f867f733d96", + "https://bcr.bazel.build/modules/protobuf/21.7/MODULE.bazel": "a5a29bb89544f9b97edce05642fac225a808b5b7be74038ea3640fae2f8e66a7", + "https://bcr.bazel.build/modules/protobuf/23.1/MODULE.bazel": "88b393b3eb4101d18129e5db51847cd40a5517a53e81216144a8c32dfeeca52a", + "https://bcr.bazel.build/modules/protobuf/24.4/MODULE.bazel": "7bc7ce5f2abf36b3b7b7c8218d3acdebb9426aeb35c2257c96445756f970eb12", + "https://bcr.bazel.build/modules/protobuf/27.0/MODULE.bazel": "7873b60be88844a0a1d8f80b9d5d20cfbd8495a689b8763e76c6372998d3f64c", + "https://bcr.bazel.build/modules/protobuf/27.1/MODULE.bazel": "703a7b614728bb06647f965264967a8ef1c39e09e8f167b3ca0bb1fd80449c0d", + "https://bcr.bazel.build/modules/protobuf/27.2/MODULE.bazel": "32450b50673882e4c8c3d10a83f3bc82161b213ed2f80d17e38bece8f165c295", + "https://bcr.bazel.build/modules/protobuf/29.0-rc2.bcr.1/MODULE.bazel": "52f4126f63a2f0bbf36b99c2a87648f08467a4eaf92ba726bc7d6a500bbf770c", + "https://bcr.bazel.build/modules/protobuf/29.0-rc2/MODULE.bazel": "6241d35983510143049943fc0d57937937122baf1b287862f9dc8590fc4c37df", + "https://bcr.bazel.build/modules/protobuf/29.0-rc3/MODULE.bazel": "33c2dfa286578573afc55a7acaea3cada4122b9631007c594bf0729f41c8de92", + "https://bcr.bazel.build/modules/protobuf/29.0/MODULE.bazel": "319dc8bf4c679ff87e71b1ccfb5a6e90a6dbc4693501d471f48662ac46d04e4e", + "https://bcr.bazel.build/modules/protobuf/29.1/MODULE.bazel": "557c3457560ff49e122ed76c0bc3397a64af9574691cb8201b4e46d4ab2ecb95", + "https://bcr.bazel.build/modules/protobuf/29.3/MODULE.bazel": "77480eea5fb5541903e49683f24dc3e09f4a79e0eea247414887bb9fc0066e94", + "https://bcr.bazel.build/modules/protobuf/3.19.0/MODULE.bazel": "6b5fbb433f760a99a22b18b6850ed5784ef0e9928a72668b66e4d7ccd47db9b0", + "https://bcr.bazel.build/modules/protobuf/3.19.2/MODULE.bazel": "532ffe5f2186b69fdde039efe6df13ba726ff338c6bc82275ad433013fa10573", + "https://bcr.bazel.build/modules/protobuf/3.19.6/MODULE.bazel": "9233edc5e1f2ee276a60de3eaa47ac4132302ef9643238f23128fea53ea12858", + "https://bcr.bazel.build/modules/protobuf/31.1/MODULE.bazel": "379a389bb330b7b8c1cdf331cc90bf3e13de5614799b3b52cdb7c6f389f6b38e", + "https://bcr.bazel.build/modules/protobuf/32.1/MODULE.bazel": "89cd2866a9cb07fee9ff74c41ceace11554f32e0d849de4e23ac55515cfada4d", + "https://bcr.bazel.build/modules/protobuf/33.4/MODULE.bazel": "114775b816b38b6d0ca620450d6b02550c60ceedfdc8d9a229833b34a223dc42", + "https://bcr.bazel.build/modules/protobuf/33.4/source.json": "555f8686b4c7d6b5ba731fbea13bf656b4bfd9a7ff629c1d9d3f6e1d6155de79", + "https://bcr.bazel.build/modules/pybind11_bazel/2.11.1/MODULE.bazel": "88af1c246226d87e65be78ed49ecd1e6f5e98648558c14ce99176da041dc378e", + "https://bcr.bazel.build/modules/pybind11_bazel/2.12.0/MODULE.bazel": "e6f4c20442eaa7c90d7190d8dc539d0ab422f95c65a57cc59562170c58ae3d34", + "https://bcr.bazel.build/modules/pybind11_bazel/2.12.0/source.json": "6900fdc8a9e95866b8c0d4ad4aba4d4236317b5c1cd04c502df3f0d33afed680", + "https://bcr.bazel.build/modules/re2/2023-09-01/MODULE.bazel": "cb3d511531b16cfc78a225a9e2136007a48cf8a677e4264baeab57fe78a80206", + "https://bcr.bazel.build/modules/re2/2024-07-02.bcr.1/MODULE.bazel": "b4963dda9b31080be1905ef085ecd7dd6cd47c05c79b9cdf83ade83ab2ab271a", + "https://bcr.bazel.build/modules/re2/2024-07-02.bcr.1/source.json": "2ff292be6ef3340325ce8a045ecc326e92cbfab47c7cbab4bd85d28971b97ac4", + "https://bcr.bazel.build/modules/re2/2024-07-02/MODULE.bazel": "0eadc4395959969297cbcf31a249ff457f2f1d456228c67719480205aa306daa", + "https://bcr.bazel.build/modules/rules_android/0.1.1/MODULE.bazel": "48809ab0091b07ad0182defb787c4c5328bd3a278938415c00a7b69b50c4d3a8", + "https://bcr.bazel.build/modules/rules_android/0.6.4/MODULE.bazel": "b4cde12d506dd65d82b2be39761f49f5797303343a3d5b4ee191c0cdf9ef387c", + "https://bcr.bazel.build/modules/rules_android/0.6.6/MODULE.bazel": "b0fb569752aab65ab1a9db0a8f6cfaf5aa1754965e17e95dcf0e4d88e192a68d", + "https://bcr.bazel.build/modules/rules_android/0.7.1/MODULE.bazel": "a806fc382a774252f228a40e3b11b9fcc6276f8778c7fb33e9f72937c6258363", + "https://bcr.bazel.build/modules/rules_android/0.7.1/source.json": "151440aed3f0f73a00d4ed5cec5d31f63a6fef9b95d8fab1eb1810150fa525f2", + "https://bcr.bazel.build/modules/rules_apple/3.16.0/MODULE.bazel": "0d1caf0b8375942ce98ea944be754a18874041e4e0459401d925577624d3a54a", + "https://bcr.bazel.build/modules/rules_apple/4.1.0/MODULE.bazel": "76e10fd4a48038d3fc7c5dc6e63b7063bbf5304a2e3bd42edda6ec660eebea68", + "https://bcr.bazel.build/modules/rules_apple/4.1.0/source.json": "8ee81e1708756f81b343a5eb2b2f0b953f1d25c4ab3d4a68dc02754872e80715", + "https://bcr.bazel.build/modules/rules_cc/0.0.1/MODULE.bazel": "cb2aa0747f84c6c3a78dad4e2049c154f08ab9d166b1273835a8174940365647", + "https://bcr.bazel.build/modules/rules_cc/0.0.10/MODULE.bazel": "ec1705118f7eaedd6e118508d3d26deba2a4e76476ada7e0e3965211be012002", + "https://bcr.bazel.build/modules/rules_cc/0.0.13/MODULE.bazel": "0e8529ed7b323dad0775ff924d2ae5af7640b23553dfcd4d34344c7e7a867191", + "https://bcr.bazel.build/modules/rules_cc/0.0.15/MODULE.bazel": "6704c35f7b4a72502ee81f61bf88706b54f06b3cbe5558ac17e2e14666cd5dcc", + "https://bcr.bazel.build/modules/rules_cc/0.0.16/MODULE.bazel": "7661303b8fc1b4d7f532e54e9d6565771fea666fbdf839e0a86affcd02defe87", + "https://bcr.bazel.build/modules/rules_cc/0.0.17/MODULE.bazel": "2ae1d8f4238ec67d7185d8861cb0a2cdf4bc608697c331b95bf990e69b62e64a", + "https://bcr.bazel.build/modules/rules_cc/0.0.2/MODULE.bazel": "6915987c90970493ab97393024c156ea8fb9f3bea953b2f3ec05c34f19b5695c", + "https://bcr.bazel.build/modules/rules_cc/0.0.6/MODULE.bazel": "abf360251023dfe3efcef65ab9d56beefa8394d4176dd29529750e1c57eaa33f", + "https://bcr.bazel.build/modules/rules_cc/0.0.8/MODULE.bazel": "964c85c82cfeb6f3855e6a07054fdb159aced38e99a5eecf7bce9d53990afa3e", + "https://bcr.bazel.build/modules/rules_cc/0.0.9/MODULE.bazel": "836e76439f354b89afe6a911a7adf59a6b2518fafb174483ad78a2a2fde7b1c5", + "https://bcr.bazel.build/modules/rules_cc/0.1.1/MODULE.bazel": "2f0222a6f229f0bf44cd711dc13c858dad98c62d52bd51d8fc3a764a83125513", + "https://bcr.bazel.build/modules/rules_cc/0.1.2/MODULE.bazel": "557ddc3a96858ec0d465a87c0a931054d7dcfd6583af2c7ed3baf494407fd8d0", + "https://bcr.bazel.build/modules/rules_cc/0.1.5/MODULE.bazel": "88dfc9361e8b5ae1008ac38f7cdfd45ad738e4fa676a3ad67d19204f045a1fd8", + "https://bcr.bazel.build/modules/rules_cc/0.2.0/MODULE.bazel": "b5c17f90458caae90d2ccd114c81970062946f49f355610ed89bebf954f5783c", + "https://bcr.bazel.build/modules/rules_cc/0.2.13/MODULE.bazel": "eecdd666eda6be16a8d9dc15e44b5c75133405e820f620a234acc4b1fdc5aa37", + "https://bcr.bazel.build/modules/rules_cc/0.2.14/MODULE.bazel": "353c99ed148887ee89c54a17d4100ae7e7e436593d104b668476019023b58df8", + "https://bcr.bazel.build/modules/rules_cc/0.2.17/MODULE.bazel": "1849602c86cb60da8613d2de887f9566a6d354a6df6d7009f9d04a14402f9a84", + "https://bcr.bazel.build/modules/rules_cc/0.2.17/source.json": "3832f45d145354049137c0090df04629d9c2b5493dc5c2bf46f1834040133a07", + "https://bcr.bazel.build/modules/rules_cc/0.2.8/MODULE.bazel": "f1df20f0bf22c28192a794f29b501ee2018fa37a3862a1a2132ae2940a23a642", + "https://bcr.bazel.build/modules/rules_foreign_cc/0.9.0/MODULE.bazel": "c9e8c682bf75b0e7c704166d79b599f93b72cfca5ad7477df596947891feeef6", + "https://bcr.bazel.build/modules/rules_fuzzing/0.5.2/MODULE.bazel": "40c97d1144356f52905566c55811f13b299453a14ac7769dfba2ac38192337a8", + "https://bcr.bazel.build/modules/rules_go/0.41.0/MODULE.bazel": "55861d8e8bb0e62cbd2896f60ff303f62ffcb0eddb74ecb0e5c0cbe36fc292c8", + "https://bcr.bazel.build/modules/rules_go/0.42.0/MODULE.bazel": "8cfa875b9aa8c6fce2b2e5925e73c1388173ea3c32a0db4d2b4804b453c14270", + "https://bcr.bazel.build/modules/rules_go/0.46.0/MODULE.bazel": "3477df8bdcc49e698b9d25f734c4f3a9f5931ff34ee48a2c662be168f5f2d3fd", + "https://bcr.bazel.build/modules/rules_go/0.50.1/MODULE.bazel": "b91a308dc5782bb0a8021ad4330c81fea5bda77f96b9e4c117b9b9c8f6665ee0", + "https://bcr.bazel.build/modules/rules_go/0.51.0-rc2/MODULE.bazel": "edfc3a9cea7bedb0eaaff37b0d7817c1a4bf72b3c615580b0ffcee6c52690fd4", + "https://bcr.bazel.build/modules/rules_go/0.52.0/MODULE.bazel": "0cf080a2706aa8fc9abf64286cee60fdf0238db37b7f1793b0f7d550d59ea3ae", + "https://bcr.bazel.build/modules/rules_go/0.53.0/MODULE.bazel": "a4ed760d3ac0dbc0d7b967631a9a3fd9100d28f7d9fcf214b4df87d4bfff5f9a", + "https://bcr.bazel.build/modules/rules_go/0.59.0/MODULE.bazel": "b7e43e7414a3139a7547d1b4909b29085fbe5182b6c58cbe1ed4c6272815aeae", + "https://bcr.bazel.build/modules/rules_go/0.59.0/source.json": "1df17bb7865cfc029492c30163cee891d0dd8658ea0d5bfdf252c4b6db5c1ef6", + "https://bcr.bazel.build/modules/rules_java/4.0.0/MODULE.bazel": "5a78a7ae82cd1a33cef56dc578c7d2a46ed0dca12643ee45edbb8417899e6f74", + "https://bcr.bazel.build/modules/rules_java/5.3.5/MODULE.bazel": "a4ec4f2db570171e3e5eb753276ee4b389bae16b96207e9d3230895c99644b86", + "https://bcr.bazel.build/modules/rules_java/6.3.0/MODULE.bazel": "a97c7678c19f236a956ad260d59c86e10a463badb7eb2eda787490f4c969b963", + "https://bcr.bazel.build/modules/rules_java/6.5.2/MODULE.bazel": "1d440d262d0e08453fa0c4d8f699ba81609ed0e9a9a0f02cd10b3e7942e61e31", + "https://bcr.bazel.build/modules/rules_java/7.1.0/MODULE.bazel": "30d9135a2b6561c761bd67bd4990da591e6bdc128790ce3e7afd6a3558b2fb64", + "https://bcr.bazel.build/modules/rules_java/7.10.0/MODULE.bazel": "530c3beb3067e870561739f1144329a21c851ff771cd752a49e06e3dc9c2e71a", + "https://bcr.bazel.build/modules/rules_java/7.12.2/MODULE.bazel": "579c505165ee757a4280ef83cda0150eea193eed3bef50b1004ba88b99da6de6", + "https://bcr.bazel.build/modules/rules_java/7.2.0/MODULE.bazel": "06c0334c9be61e6cef2c8c84a7800cef502063269a5af25ceb100b192453d4ab", + "https://bcr.bazel.build/modules/rules_java/7.4.0/MODULE.bazel": "a592852f8a3dd539e82ee6542013bf2cadfc4c6946be8941e189d224500a8934", + "https://bcr.bazel.build/modules/rules_java/7.6.1/MODULE.bazel": "2f14b7e8a1aa2f67ae92bc69d1ec0fa8d9f827c4e17ff5e5f02e91caa3b2d0fe", + "https://bcr.bazel.build/modules/rules_java/8.13.0/MODULE.bazel": "0444ebf737d144cf2bb2ccb368e7f1cce735264285f2a3711785827c1686625e", + "https://bcr.bazel.build/modules/rules_java/8.15.2/MODULE.bazel": "5cc6698c822b2f9ef90ca5558599851bed8c3b13f1f8eb140d9bfec638d2acb4", + "https://bcr.bazel.build/modules/rules_java/8.3.2/MODULE.bazel": "7336d5511ad5af0b8615fdc7477535a2e4e723a357b6713af439fe8cf0195017", + "https://bcr.bazel.build/modules/rules_java/8.5.1/MODULE.bazel": "d8a9e38cc5228881f7055a6079f6f7821a073df3744d441978e7a43e20226939", + "https://bcr.bazel.build/modules/rules_java/8.6.0/MODULE.bazel": "9c064c434606d75a086f15ade5edb514308cccd1544c2b2a89bbac4310e41c71", + "https://bcr.bazel.build/modules/rules_java/8.6.1/MODULE.bazel": "f4808e2ab5b0197f094cabce9f4b006a27766beb6a9975931da07099560ca9c2", + "https://bcr.bazel.build/modules/rules_java/8.6.3/MODULE.bazel": "e90505b7a931d194245ffcfb6ff4ca8ef9d46b4e830d12e64817752e0198e2ed", + "https://bcr.bazel.build/modules/rules_java/8.9.0/MODULE.bazel": "e17c876cb53dcd817b7b7f0d2985b710610169729e8c371b2221cacdcd3dce4a", + "https://bcr.bazel.build/modules/rules_java/9.1.0/MODULE.bazel": "ee63f27e36a3fada80342869361182f120a9819c74320e8e65b1e04ba0cd7a9d", + "https://bcr.bazel.build/modules/rules_java/9.3.0/MODULE.bazel": "f657c72d65ac449caae9abf2e68e66c0d36f9416848c4c4903d0b3234229e7f2", + "https://bcr.bazel.build/modules/rules_java/9.3.0/source.json": "59ae7e662c3c7042b88bbb42ad12483523e234c65ebe4c51611baa43e85cb248", + "https://bcr.bazel.build/modules/rules_jvm_external/4.4.2/MODULE.bazel": "a56b85e418c83eb1839819f0b515c431010160383306d13ec21959ac412d2fe7", + "https://bcr.bazel.build/modules/rules_jvm_external/5.1/MODULE.bazel": "33f6f999e03183f7d088c9be518a63467dfd0be94a11d0055fe2d210f89aa909", + "https://bcr.bazel.build/modules/rules_jvm_external/5.2/MODULE.bazel": "d9351ba35217ad0de03816ef3ed63f89d411349353077348a45348b096615036", + "https://bcr.bazel.build/modules/rules_jvm_external/6.10/MODULE.bazel": "33e636ca6bc9ee0fa090a38aa33c631ded2d8cf6fead4124181d1b35dc474f7c", + "https://bcr.bazel.build/modules/rules_jvm_external/6.2/MODULE.bazel": "36a6e52487a855f33cb960724eb56547fa87e2c98a0474c3acad94339d7f8e99", + "https://bcr.bazel.build/modules/rules_jvm_external/6.3/MODULE.bazel": "c998e060b85f71e00de5ec552019347c8bca255062c990ac02d051bb80a38df0", + "https://bcr.bazel.build/modules/rules_jvm_external/6.6/MODULE.bazel": "153042249c7060536dc95b6bb9f9bb8063b8a0b0cb7acdb381bddbc2374aed55", + "https://bcr.bazel.build/modules/rules_jvm_external/6.7/MODULE.bazel": "e717beabc4d091ecb2c803c2d341b88590e9116b8bf7947915eeb33aab4f96dd", + "https://bcr.bazel.build/modules/rules_jvm_external/6.9/MODULE.bazel": "07c5db05527db7744a54fcffd653e1550d40e0540207a7f7e6d0a4de5bef8274", + "https://bcr.bazel.build/modules/rules_jvm_external/7.0/MODULE.bazel": "421482bdbcf05709f933c96b867a599deb517f2804ceb3e74511880610cfbf71", + "https://bcr.bazel.build/modules/rules_jvm_external/7.0/source.json": "714cd003eadf5be5c83268311fe8e951db39f802babeaddc536b3560dc8f6faf", + "https://bcr.bazel.build/modules/rules_kotlin/1.9.5/MODULE.bazel": "043a16a572f610558ec2030db3ff0c9938574e7dd9f58bded1bb07c0192ef025", + "https://bcr.bazel.build/modules/rules_kotlin/1.9.6/MODULE.bazel": "d269a01a18ee74d0335450b10f62c9ed81f2321d7958a2934e44272fe82dcef3", + "https://bcr.bazel.build/modules/rules_kotlin/2.1.3/MODULE.bazel": "ce7def6d576aa8d3a9c6d10e13b4d157296229674371f67dbf788dae0afae3d5", + "https://bcr.bazel.build/modules/rules_kotlin/2.2.2/MODULE.bazel": "00d39c5e0fa78cd86193946265bb849e7878c24e44260f9525108428852b315c", + "https://bcr.bazel.build/modules/rules_kotlin/2.2.2/source.json": "7a32c2259c79ae0c9a036121f120de825e3ba5f0f3a209ffbbdccf4dc62489b9", + "https://bcr.bazel.build/modules/rules_license/0.0.3/MODULE.bazel": "627e9ab0247f7d1e05736b59dbb1b6871373de5ad31c3011880b4133cafd4bd0", + "https://bcr.bazel.build/modules/rules_license/0.0.7/MODULE.bazel": "088fbeb0b6a419005b89cf93fe62d9517c0a2b8bb56af3244af65ecfe37e7d5d", + "https://bcr.bazel.build/modules/rules_license/1.0.0/MODULE.bazel": "a7fda60eefdf3d8c827262ba499957e4df06f659330bbe6cdbdb975b768bb65c", + "https://bcr.bazel.build/modules/rules_license/1.0.0/source.json": "a52c89e54cc311196e478f8382df91c15f7a2bfdf4c6cd0e2675cc2ff0b56efb", + "https://bcr.bazel.build/modules/rules_oci/2.2.7/MODULE.bazel": "f6150e4b224d459f7f6523ef65967464ca4efdd266c7fbf2f5a2a51011957e0c", + "https://bcr.bazel.build/modules/rules_oci/2.2.7/source.json": "b099f02af330f47f19dc67fc9300ef6e1937a8c86882690db0e7a2fcea8c7f6b", + "https://bcr.bazel.build/modules/rules_pkg/0.7.0/MODULE.bazel": "df99f03fc7934a4737122518bb87e667e62d780b610910f0447665a7e2be62dc", + "https://bcr.bazel.build/modules/rules_pkg/1.0.1/MODULE.bazel": "5b1df97dbc29623bccdf2b0dcd0f5cb08e2f2c9050aab1092fd39a41e82686ff", + "https://bcr.bazel.build/modules/rules_pkg/1.2.0/MODULE.bazel": "c7db3c2b407e673c7a39e3625dc05dc9f12d6682cbd82a3a5924a13b491eda7e", + "https://bcr.bazel.build/modules/rules_pkg/1.2.0/source.json": "9062e00845bf91a4247465d371baa837adf9b6ff44c542f73ba084f07667e1dc", + "https://bcr.bazel.build/modules/rules_proto/4.0.0/MODULE.bazel": "a7a7b6ce9bee418c1a760b3d84f83a299ad6952f9903c67f19e4edd964894e06", + "https://bcr.bazel.build/modules/rules_proto/5.3.0-21.7/MODULE.bazel": "e8dff86b0971688790ae75528fe1813f71809b5afd57facb44dad9e8eca631b7", + "https://bcr.bazel.build/modules/rules_proto/6.0.0-rc1/MODULE.bazel": "1e5b502e2e1a9e825eef74476a5a1ee524a92297085015a052510b09a1a09483", + "https://bcr.bazel.build/modules/rules_proto/6.0.0/MODULE.bazel": "b531d7f09f58dce456cd61b4579ce8c86b38544da75184eadaf0a7cb7966453f", + "https://bcr.bazel.build/modules/rules_proto/6.0.2/MODULE.bazel": "ce916b775a62b90b61888052a416ccdda405212b6aaeb39522f7dc53431a5e73", + "https://bcr.bazel.build/modules/rules_proto/7.0.2/MODULE.bazel": "bf81793bd6d2ad89a37a40693e56c61b0ee30f7a7fdbaf3eabbf5f39de47dea2", + "https://bcr.bazel.build/modules/rules_proto/7.1.0/MODULE.bazel": "002d62d9108f75bb807cd56245d45648f38275cb3a99dcd45dfb864c5d74cb96", + "https://bcr.bazel.build/modules/rules_proto/7.1.0/source.json": "39f89066c12c24097854e8f57ab8558929f9c8d474d34b2c00ac04630ad8940e", + "https://bcr.bazel.build/modules/rules_python/0.10.2/MODULE.bazel": "cc82bc96f2997baa545ab3ce73f196d040ffb8756fd2d66125a530031cd90e5f", + "https://bcr.bazel.build/modules/rules_python/0.23.1/MODULE.bazel": "49ffccf0511cb8414de28321f5fcf2a31312b47c40cc21577144b7447f2bf300", + "https://bcr.bazel.build/modules/rules_python/0.25.0/MODULE.bazel": "72f1506841c920a1afec76975b35312410eea3aa7b63267436bfb1dd91d2d382", + "https://bcr.bazel.build/modules/rules_python/0.28.0/MODULE.bazel": "cba2573d870babc976664a912539b320cbaa7114cd3e8f053c720171cde331ed", + "https://bcr.bazel.build/modules/rules_python/0.31.0/MODULE.bazel": "93a43dc47ee570e6ec9f5779b2e64c1476a6ce921c48cc9a1678a91dd5f8fd58", + "https://bcr.bazel.build/modules/rules_python/0.33.2/MODULE.bazel": "3e036c4ad8d804a4dad897d333d8dce200d943df4827cb849840055be8d2e937", + "https://bcr.bazel.build/modules/rules_python/0.37.1/MODULE.bazel": "3faeb2d9fa0a81f8980643ee33f212308f4d93eea4b9ce6f36d0b742e71e9500", + "https://bcr.bazel.build/modules/rules_python/0.37.2/MODULE.bazel": "b5ffde91410745750b6c13be1c5dc4555ef5bc50562af4a89fd77807fdde626a", + "https://bcr.bazel.build/modules/rules_python/0.4.0/MODULE.bazel": "9208ee05fd48bf09ac60ed269791cf17fb343db56c8226a720fbb1cdf467166c", + "https://bcr.bazel.build/modules/rules_python/1.0.0/MODULE.bazel": "898a3d999c22caa585eb062b600f88654bf92efb204fa346fb55f6f8edffca43", + "https://bcr.bazel.build/modules/rules_python/1.3.0/MODULE.bazel": "8361d57eafb67c09b75bf4bbe6be360e1b8f4f18118ab48037f2bd50aa2ccb13", + "https://bcr.bazel.build/modules/rules_python/1.4.1/MODULE.bazel": "8991ad45bdc25018301d6b7e1d3626afc3c8af8aaf4bc04f23d0b99c938b73a6", + "https://bcr.bazel.build/modules/rules_python/1.6.0/MODULE.bazel": "7e04ad8f8d5bea40451cf80b1bd8262552aa73f841415d20db96b7241bd027d8", + "https://bcr.bazel.build/modules/rules_python/1.7.0/MODULE.bazel": "d01f995ecd137abf30238ad9ce97f8fc3ac57289c8b24bd0bf53324d937a14f8", + "https://bcr.bazel.build/modules/rules_python/1.7.0/source.json": "028a084b65dcf8f4dc4f82f8778dbe65df133f234b316828a82e060d81bdce32", + "https://bcr.bazel.build/modules/rules_robolectric/4.14.1.2/MODULE.bazel": "d44fec647d0aeb67b9f3b980cf68ba634976f3ae7ccd6c07d790b59b87a4f251", + "https://bcr.bazel.build/modules/rules_robolectric/4.14.1.2/source.json": "37c10335f2361c337c5c1f34ed36d2da70534c23088062b33a8bdaab68aa9dea", + "https://bcr.bazel.build/modules/rules_shell/0.1.2/MODULE.bazel": "66e4ca3ce084b04af0b9ff05ff14cab4e5df7503973818bb91cbc6cda08d32fc", + "https://bcr.bazel.build/modules/rules_shell/0.2.0/MODULE.bazel": "fda8a652ab3c7d8fee214de05e7a9916d8b28082234e8d2c0094505c5268ed3c", + "https://bcr.bazel.build/modules/rules_shell/0.3.0/MODULE.bazel": "de4402cd12f4cc8fda2354fce179fdb068c0b9ca1ec2d2b17b3e21b24c1a937b", + "https://bcr.bazel.build/modules/rules_shell/0.4.1/MODULE.bazel": "00e501db01bbf4e3e1dd1595959092c2fadf2087b2852d3f553b5370f5633592", + "https://bcr.bazel.build/modules/rules_shell/0.6.1/MODULE.bazel": "72e76b0eea4e81611ef5452aa82b3da34caca0c8b7b5c0c9584338aa93bae26b", + "https://bcr.bazel.build/modules/rules_shell/0.8.0/MODULE.bazel": "f6a89f1d6a669a26f28fe814503857055d76306b79cfc11d12399af08d0b80ae", + "https://bcr.bazel.build/modules/rules_shell/0.8.0/source.json": "eb53cc815bc503c6683c5fe12d943f98883f81fc22f51403ec8a95610cba4195", + "https://bcr.bazel.build/modules/rules_swift/1.16.0/MODULE.bazel": "4a09f199545a60d09895e8281362b1ff3bb08bbde69c6fc87aff5b92fcc916ca", + "https://bcr.bazel.build/modules/rules_swift/2.1.1/MODULE.bazel": "494900a80f944fc7aa61500c2073d9729dff0b764f0e89b824eb746959bc1046", + "https://bcr.bazel.build/modules/rules_swift/2.4.0/MODULE.bazel": "1639617eb1ede28d774d967a738b4a68b0accb40650beadb57c21846beab5efd", + "https://bcr.bazel.build/modules/rules_swift/3.1.2/MODULE.bazel": "72c8f5cf9d26427cee6c76c8e3853eb46ce6b0412a081b2b6db6e8ad56267400", + "https://bcr.bazel.build/modules/rules_swift/3.1.2/source.json": "e85761f3098a6faf40b8187695e3de6d97944e98abd0d8ce579cb2daf6319a66", + "https://bcr.bazel.build/modules/stardoc/0.5.1/MODULE.bazel": "1a05d92974d0c122f5ccf09291442580317cdd859f07a8655f1db9a60374f9f8", + "https://bcr.bazel.build/modules/stardoc/0.5.3/MODULE.bazel": "c7f6948dae6999bf0db32c1858ae345f112cacf98f174c7a8bb707e41b974f1c", + "https://bcr.bazel.build/modules/stardoc/0.5.4/MODULE.bazel": "6569966df04610b8520957cb8e97cf2e9faac2c0309657c537ab51c16c18a2a4", + "https://bcr.bazel.build/modules/stardoc/0.6.2/MODULE.bazel": "7060193196395f5dd668eda046ccbeacebfd98efc77fed418dbe2b82ffaa39fd", + "https://bcr.bazel.build/modules/stardoc/0.7.0/MODULE.bazel": "05e3d6d30c099b6770e97da986c53bd31844d7f13d41412480ea265ac9e8079c", + "https://bcr.bazel.build/modules/stardoc/0.7.2/MODULE.bazel": "fc152419aa2ea0f51c29583fab1e8c99ddefd5b3778421845606ee628629e0e5", + "https://bcr.bazel.build/modules/stardoc/0.7.2/source.json": "58b029e5e901d6802967754adf0a9056747e8176f017cfe3607c0851f4d42216", + "https://bcr.bazel.build/modules/swift_argument_parser/1.3.1.1/MODULE.bazel": "5e463fbfba7b1701d957555ed45097d7f984211330106ccd1352c6e0af0dcf91", + "https://bcr.bazel.build/modules/swift_argument_parser/1.3.1.2/MODULE.bazel": "75aab2373a4bbe2a1260b9bf2a1ebbdbf872d3bd36f80bff058dccd82e89422f", + "https://bcr.bazel.build/modules/swift_argument_parser/1.3.1.2/source.json": "5fba48bbe0ba48761f9e9f75f92876cafb5d07c0ce059cc7a8027416de94a05b", + "https://bcr.bazel.build/modules/tar.bzl/0.2.1/MODULE.bazel": "52d1c00a80a8cc67acbd01649e83d8dd6a9dc426a6c0b754a04fe8c219c76468", + "https://bcr.bazel.build/modules/tar.bzl/0.2.1/source.json": "600ac6ff61744667a439e7b814ae59c1f29632c3984fccf8000c64c9db8d7bb6", + "https://bcr.bazel.build/modules/toml.bzl/0.3.0/MODULE.bazel": "5016e5dd1ad2200e119a4b28b2b3935e276c4b480f2fe3e952bea7eeba88f578", + "https://bcr.bazel.build/modules/toml.bzl/0.3.0/source.json": "0cf7c878c419b37ddb55f3dd93dd7c0c409bd7c4efacb3da504e0748780b2fa9", + "https://bcr.bazel.build/modules/upb/0.0.0-20220923-a547704/MODULE.bazel": "7298990c00040a0e2f121f6c32544bab27d4452f80d9ce51349b1a28f3005c43", + "https://bcr.bazel.build/modules/upb/0.0.0-20230516-61a97ef/MODULE.bazel": "c0df5e35ad55e264160417fd0875932ee3c9dda63d9fccace35ac62f45e1b6f9", + "https://bcr.bazel.build/modules/yq.bzl/0.1.1/MODULE.bazel": "9039681f9bcb8958ee2c87ffc74bdafba9f4369096a2b5634b88abc0eaefa072", + "https://bcr.bazel.build/modules/yq.bzl/0.1.1/source.json": "2d2bad780a9f2b9195a4a370314d2c17ae95eaa745cefc2e12fbc49759b15aa3", + "https://bcr.bazel.build/modules/zlib/1.2.11/MODULE.bazel": "07b389abc85fdbca459b69e2ec656ae5622873af3f845e1c9d80fe179f3effa0", + "https://bcr.bazel.build/modules/zlib/1.2.12/MODULE.bazel": "3b1a8834ada2a883674be8cbd36ede1b6ec481477ada359cd2d3ddc562340b27", + "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.5/MODULE.bazel": "eec517b5bbe5492629466e11dae908d043364302283de25581e3eb944326c4ca", + "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.5/source.json": "22bc55c47af97246cfc093d0acf683a7869377de362b5d1c552c2c2e16b7a806", + "https://bcr.bazel.build/modules/zlib/1.3.1/MODULE.bazel": "751c9940dcfe869f5f7274e1295422a34623555916eb98c174c1e945594bf198" + }, + "selectedYankedVersions": {}, + "moduleExtensions": {}, + "facts": {}, + "factsVersions": {} +} diff --git a/rules/java/bom_alignment.bzl b/rules/java/bom_alignment.bzl new file mode 100644 index 000000000..30bc60bae --- /dev/null +++ b/rules/java/bom_alignment.bzl @@ -0,0 +1,55 @@ +# SPDX-FileCopyrightText: Copyright (c) NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +# +# 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. + +"""bom_alignment_test: guard that a Java module's inlined BOMs match platform.bzl. + +load() is forbidden in MODULE.bazel, so a module cannot write +`boms = SPRING_BOOT_BOM` and must inline the literal coordinates. This macro +closes that gap: it materializes the canonical SPRING_BOOT_BOM from platform.bzl +into a file and runs a shell test that asserts every canonical coordinate is +present in the consuming module's MODULE.bazel. If someone bumps Spring in +platform.bzl but forgets a module, or edits one module's boms out of step, this +test fails. +""" + +load("@rules_shell//shell:sh_test.bzl", "sh_test") +load("//:platform.bzl", "SPRING_BOOT_BOM") + +def bom_alignment_test(name, module_bazel = "//:MODULE.bazel", boms = SPRING_BOOT_BOM): + """Assert the module's MODULE.bazel inlines exactly the canonical BOM set. + + Args: + name: test target name. + module_bazel: label of the module's MODULE.bazel (default //:MODULE.bazel). + boms: canonical BOM list (default the shared SPRING_BOOT_BOM). + """ + canonical = name + "_canonical" + native.genrule( + name = canonical, + outs = [name + "_canonical.txt"], + cmd = "cat > $@ <<'BOMS'\n" + "\n".join(boms) + "\nBOMS", + ) + sh_test( + name = name, + srcs = ["@nvcf_java_rules//scripts:check_bom_alignment.sh"], + args = [ + "$(location %s)" % module_bazel, + "$(location :%s.txt)" % canonical, + ], + data = [ + module_bazel, + ":%s.txt" % canonical, + ], + ) diff --git a/rules/java/defs.bzl b/rules/java/defs.bzl index 290a633e1..19d534d25 100644 --- a/rules/java/defs.bzl +++ b/rules/java/defs.bzl @@ -16,7 +16,7 @@ "Public Java build rules for NVCF services." load( - "//rules/java/private:spring_boot.bzl", + "//private:spring_boot.bzl", _nvcf_java_library = "nvcf_java_library", _nvcf_spring_boot_image = "nvcf_spring_boot_image", ) diff --git a/rules/java/platform.bzl b/rules/java/platform.bzl new file mode 100644 index 000000000..7ad8d7a27 --- /dev/null +++ b/rules/java/platform.bzl @@ -0,0 +1,53 @@ +# SPDX-FileCopyrightText: Copyright (c) NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +# +# 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. + +"""Single source of truth for the NVCF Java platform. + +Every Java module resolves its own Maven graph and writes its own +maven_install.json, which is what makes each module independently buildable. The +risk of independent resolution is version drift: two modules pinning different +Spring versions put two copies on a transitive classpath. + +To keep resolutions in agreement, the shared BOM set and version constants live +here, loadable from any BUILD or .bzl file. load() is forbidden in MODULE.bazel, +so a module cannot reference SPRING_BOOT_BOM directly in its maven.install. Each +module instead inlines the same literal BOM list in its MODULE.bazel and guards +it with bom_alignment_test (see //:bom_alignment.bzl), which fails the build if a +module's boms drift from this canonical list. Bumping a shared version is a +one-line change here plus a re-pin of every Java module. +""" + +SPRING_BOOT_VERSION = "4.0.7" +SPRING_CLOUD_VERSION = "2025.1.2" +TESTCONTAINERS_VERSION = "2.0.5" +SHEDLOCK_VERSION = "7.7.0" + +# Canonical shared BOM set. Keep this list, and the literal boms list in every +# Java module's MODULE.bazel, identical. bom_alignment_test enforces it. +SPRING_BOOT_BOM = [ + "org.springframework.boot:spring-boot-dependencies:%s" % SPRING_BOOT_VERSION, + "org.springframework.cloud:spring-cloud-dependencies:%s" % SPRING_CLOUD_VERSION, + "org.testcontainers:testcontainers-bom:%s" % TESTCONTAINERS_VERSION, + "net.javacrumbs.shedlock:shedlock-bom:%s" % SHEDLOCK_VERSION, +] + +# Public Central mirrors only, so the platform resolves anywhere including the +# public GitHub mirror. The Google-hosted mirror is primary (not IP-rate-limited +# like repo1.maven.org); Maven Central is the fallback. Internal builds that need +# NVIDIA artifacts prepend the Artifactory virtual repo in their own overlay. +MAVEN_REPOSITORIES = [ + "https://maven-central.storage-download.googleapis.com/maven2", + "https://repo.maven.apache.org/maven2", +] diff --git a/rules/java/platforms/BUILD.bazel b/rules/java/platforms/BUILD.bazel new file mode 100644 index 000000000..4cc09b2d0 --- /dev/null +++ b/rules/java/platforms/BUILD.bazel @@ -0,0 +1,32 @@ +# SPDX-FileCopyrightText: Copyright (c) NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +# +# 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(default_visibility = ["//visibility:public"]) + +platform( + name = "linux_arm64", + constraint_values = [ + "@platforms//os:linux", + "@platforms//cpu:aarch64", + ], +) + +platform( + name = "linux_x86_64", + constraint_values = [ + "@platforms//os:linux", + "@platforms//cpu:x86_64", + ], +) diff --git a/rules/java/private/oci.bzl b/rules/java/private/oci.bzl new file mode 100644 index 000000000..0ac9467d6 --- /dev/null +++ b/rules/java/private/oci.bzl @@ -0,0 +1,162 @@ +# SPDX-FileCopyrightText: Copyright (c) NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +# +# 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. + +"""Self-contained OCI image helper for the Java rules module. + +Vendored from //rules/oci so nvcf_java_rules is a standalone Bazel module with +no dependency on the root workspace's //rules/oci package. Kept behavior-for- +behavior identical to the shared helper: multi-arch (amd64 + arm64) images with +platform transitions and a registry push target. If the shared helper changes, +re-vendor this copy. +""" + +load("@aspect_bazel_lib//lib:expand_template.bzl", "expand_template") +load("@aspect_bazel_lib//lib:transitions.bzl", "platform_transition_filegroup") +load("@rules_oci//oci:defs.bzl", "oci_image", "oci_image_index", "oci_load", "oci_push") + +DEFAULT_BASE = "@ubuntu_noble" +DEFAULT_PLATFORMS = [ + "//platforms:linux_arm64", + "//platforms:linux_x86_64", +] + +COMMON_LAYERS = [] + +def _multiarch_transition(settings, attr): + return [ + {"//command_line_option:platforms": str(platform)} + for platform in attr.platforms + ] + +multiarch_transition = transition( + implementation = _multiarch_transition, + inputs = [], + outputs = ["//command_line_option:platforms"], +) + +def _multi_arch_impl(ctx): + return DefaultInfo(files = depset(ctx.files.image)) + +multi_arch = rule( + implementation = _multi_arch_impl, + attrs = { + "image": attr.label(cfg = multiarch_transition), + "platforms": attr.label_list(), + "_allowlist_function_transition": attr.label( + default = "@bazel_tools//tools/allowlists/function_transition_allowlist", + ), + }, +) + +def create_oci_image( + name, + tars, + base, + entrypoint, + visibility, + registry = None, + tags = None): + """Creates OCI image targets with platform transitions and tarball output. + + Generates: + - {name}: Platform-transitioned OCI image (for local builds) + - {name}_index: Multi-arch image index (amd64 + arm64) + - {name}_load: Local docker load target + - {name}.tar: Tarball filegroup + - {name}_push: Push to registry (if registry is set) + """ + all_tags = ["manual"] + (tags or []) + + pre_transitioned = name + "_pre_transitioned" + oci_image( + name = pre_transitioned, + base = base, + tars = tars + COMMON_LAYERS, + entrypoint = entrypoint, + visibility = ["//visibility:private"], + tags = all_tags, + ) + + platform_transition_filegroup( + name = name, + srcs = [pre_transitioned], + target_platform = select({ + "@platforms//cpu:arm64": "//platforms:linux_arm64", + "@platforms//cpu:x86_64": "//platforms:linux_x86_64", + }), + visibility = visibility, + tags = all_tags, + ) + + multi_arch_name = name + "_multi_arch" + multi_arch( + name = multi_arch_name, + image = pre_transitioned, + platforms = DEFAULT_PLATFORMS, + visibility = ["//visibility:private"], + tags = all_tags, + ) + + oci_image_index( + name = name + "_index", + images = [multi_arch_name], + visibility = visibility, + tags = all_tags, + ) + + load_name = name + "_load" + oci_load( + name = load_name, + image = name, + repo_tags = [native.package_name() + ":latest"], + visibility = visibility, + tags = all_tags, + ) + + native.filegroup( + name = name + ".tar", + srcs = [load_name], + output_group = "tarball", + visibility = visibility, + tags = all_tags, + ) + + if registry: + stamped_tags = name + "_stamped_tags" + expand_template( + name = stamped_tags, + out = name + "_tags.txt", + stamp_substitutions = { + "{VERSION}": "{{STABLE_VERSION}}", + "{OCI_TAG}": "{{STABLE_OCI_TAG}}", + "{COMMIT}": "{{STABLE_GIT_COMMIT}}", + }, + template = [ + "latest", + "{VERSION}", + "{OCI_TAG}", + "{COMMIT}", + ], + visibility = ["//visibility:private"], + ) + + oci_push( + name = name + "_push", + image = name + "_index", + remote_tags = stamped_tags, + repository = registry, + visibility = visibility, + tags = all_tags, + ) diff --git a/rules/java/private/spring_boot.bzl b/rules/java/private/spring_boot.bzl index b3fddf947..232d6a07d 100644 --- a/rules/java/private/spring_boot.bzl +++ b/rules/java/private/spring_boot.bzl @@ -19,7 +19,7 @@ load("@rules_java//java:defs.bzl", "java_library") load("@rules_java//java/common:java_info.bzl", "JavaInfo") load("@rules_pkg//pkg:mappings.bzl", "pkg_files", "strip_prefix") load("@rules_pkg//pkg:tar.bzl", "pkg_tar") -load("//rules/oci/private:common.bzl", "create_oci_image") +load("//private:oci.bzl", "create_oci_image") DEFAULT_JAVA_BASE = "@temurin_jre" diff --git a/rules/java/scripts/BUILD.bazel b/rules/java/scripts/BUILD.bazel new file mode 100644 index 000000000..c52269c1d --- /dev/null +++ b/rules/java/scripts/BUILD.bazel @@ -0,0 +1,18 @@ +# SPDX-FileCopyrightText: Copyright (c) NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +# +# 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(default_visibility = ["//visibility:public"]) + +exports_files(["check_bom_alignment.sh"]) diff --git a/rules/java/scripts/check_bom_alignment.sh b/rules/java/scripts/check_bom_alignment.sh new file mode 100755 index 000000000..a31bee8f7 --- /dev/null +++ b/rules/java/scripts/check_bom_alignment.sh @@ -0,0 +1,31 @@ +#!/usr/bin/env bash +# SPDX-FileCopyrightText: Copyright (c) NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +# +# Asserts that every canonical Spring BOM coordinate (from platform.bzl, passed +# as a newline-delimited file) appears verbatim in the consuming module's +# MODULE.bazel. Keeps each Java module's inlined boms list aligned with the +# single source of truth, since load() cannot be used in MODULE.bazel. +set -euo pipefail + +module_bazel="$1" +canonical="$2" + +missing=0 +while IFS= read -r coord; do + [ -z "$coord" ] && continue + if ! grep -qF -- "$coord" "$module_bazel"; then + echo "BOM drift: canonical coordinate not found in MODULE.bazel:" >&2 + echo " $coord" >&2 + missing=1 + fi +done < "$canonical" + +if [ "$missing" -ne 0 ]; then + echo >&2 + echo "Every coordinate in @nvcf_java_rules//:platform.bzl SPRING_BOOT_BOM must" >&2 + echo "be inlined in this module's maven.install boms list. Re-align and re-pin." >&2 + exit 1 +fi + +echo "BOM alignment OK: $(grep -c . "$canonical") canonical coordinate(s) present." diff --git a/src/control-plane-services/cloud-tasks/.bazelrc b/src/control-plane-services/cloud-tasks/.bazelrc new file mode 100644 index 000000000..5d096451a --- /dev/null +++ b/src/control-plane-services/cloud-tasks/.bazelrc @@ -0,0 +1,52 @@ +# SPDX-FileCopyrightText: Copyright (c) NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +# +# 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. + +# Standalone module .bazelrc. `cd rules/java && bazel build //...` must work with +# no reference to the repo root. The caller supplies any remote cache endpoint; +# no cache config is baked in (parity with the other nested modules). + +common --enable_bzlmod +common --enable_platform_specific_config +build --incompatible_strict_action_env + +# Route public Maven Central through an internal Artifactory mirror on internal +# builds only. The target host lives in an un-mirrored internal bazelrc, so +# public builds go straight to Maven Central (try-import is a no-op when absent). +try-import %workspace%/tools/bazel/internal.bazelrc + +# Java: hermetic remotejdk 25 regardless of the host JDK, matching the root +# module so builds are reproducible everywhere. +build --java_language_version=25 +build --java_runtime_version=remotejdk_25 +build --tool_java_language_version=25 +build --tool_java_runtime_version=remotejdk_25 +build --java_header_compilation=false + +test --test_output=errors +test --test_env=HOME=/tmp +test --test_env=XDG_CACHE_HOME=/tmp/.cache + +startup --host_jvm_args=-Xmx4g + +build:release --compilation_mode=opt +build:release --strip=always + +try-import %workspace%/user.bazelrc +try-import %user.home%/.bazelrc.user + +# gRPC/proto: register the prebuilt protoc toolchain instead of compiling the +# C++ protobuf compiler; allow the 33.0-vs-33.4 protoc skew (wire-compatible). +common --incompatible_enable_proto_toolchain_resolution +common --@com_google_protobuf//bazel/toolchains:allow_nonstandard_protoc diff --git a/src/control-plane-services/cloud-tasks/.gitignore b/src/control-plane-services/cloud-tasks/.gitignore new file mode 100644 index 000000000..a6ef824c1 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/.gitignore @@ -0,0 +1 @@ +/bazel-* diff --git a/src/control-plane-services/cloud-tasks/AGENTS.md b/src/control-plane-services/cloud-tasks/AGENTS.md new file mode 100644 index 000000000..6977ca467 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/AGENTS.md @@ -0,0 +1,39 @@ +# AGENTS.md - nvct_cloud_tasks + +The NVCF cloud-tasks Java (Spring Boot) service, as a standalone Bazel module +(`module(name = "nvct_cloud_tasks")`). Depends on `nvcf_java_rules` (shared +macros + multi-arch image helper) and `nv_boot_parent` (the Spring platform +starters), both via `bazel_dep` + `local_path_override`. + +## Build and test (from this directory) + +``` +cd src/control-plane-services/cloud-tasks +bazel build //... +bazel test //... --test_tag_filters=-requires-docker +``` + +The module builds on its own with no reference to the repo root. The Spring + +Testcontainers integration tests are tagged `requires-docker` (and `exclusive`) +and run in the dedicated Docker integration lane, not the default fast matrix. + +## Maven dependencies + +Own `@maven` hub and own committed `maven_install.json`. After editing +`maven.install` in `MODULE.bazel`, re-pin and commit: + +``` +REPIN=1 bazel run @maven//:pin +``` + +The `boms` list must stay identical to `SPRING_BOOT_BOM` in +`@nvcf_java_rules//:platform.bzl`; `//:bom_alignment_test` enforces it. + +## Layout + +- `nvct-core/` - service library plus the gRPC `nvct.proto` codegen + (`nvct_java_grpc_compile` in `tools/bazel/proto.bzl`, driven by the + `protoc-gen-grpc-java` native plugins declared in `MODULE.bazel`). +- `nvct-service/` - the `@SpringBootApplication` entry point and the + `nvcf_spring_boot_image` multi-arch OCI image target (`:image_index`). +- `tools/bazel/` - Lombok wiring, the gRPC plugin `proto_plugin`, JaCoCo runner. diff --git a/src/control-plane-services/cloud-tasks/BUILD.bazel b/src/control-plane-services/cloud-tasks/BUILD.bazel index a8c3b41d5..a7dffab12 100644 --- a/src/control-plane-services/cloud-tasks/BUILD.bazel +++ b/src/control-plane-services/cloud-tasks/BUILD.bazel @@ -1,11 +1,19 @@ -load("//src/control-plane-services/cloud-tasks/tools/bazel:runfiles.bzl", "nvct_workspace_runfiles") +load("@nvcf_java_rules//:bom_alignment.bzl", "bom_alignment_test") +load("//tools/bazel:runfiles.bzl", "nvct_workspace_runfiles") package(default_visibility = ["//visibility:public"]) exports_files([ + "MODULE.bazel", "NOTICE", ]) +# Fails the build if this module's inlined maven.install boms drift from the +# canonical SPRING_BOOT_BOM in @nvcf_java_rules//:platform.bzl. +bom_alignment_test( + name = "bom_alignment_test", +) + filegroup( name = "integration_local_env_files", srcs = [ @@ -22,13 +30,13 @@ nvct_workspace_runfiles( # After the umbrella relocation the runfiles short_path carries the subtree # prefix; strip it so integration tests still resolve local_env/... relative # to the runfiles root (test config references local_env/vault/secrets.json). - strip_prefix = "src/control-plane-services/cloud-tasks/", + strip_prefix = "", ) # NOTE: THIRD_PARTY_NOTICE generation (the former notice genrule, generate # binary, and tools/bazel notice check) read the Spring fat jar # (nvct-service app jar, BOOT-INF/lib/external/... layout). Converging onto -# //rules/java's exploded-classpath image removes that fat jar, so the fat-jar +# @nvcf_java_rules's exploded-classpath image removes that fat jar, so the fat-jar # NOTICE mechanism no longer has an input. Reworking NOTICE generation for the # exploded classpath is tracked as follow-up; it needs a change to the shared # nv-boot generate_notice.py, which is out of scope for this build-wiring diff --git a/src/control-plane-services/cloud-tasks/CLAUDE.md b/src/control-plane-services/cloud-tasks/CLAUDE.md new file mode 100644 index 000000000..43c994c2d --- /dev/null +++ b/src/control-plane-services/cloud-tasks/CLAUDE.md @@ -0,0 +1 @@ +@AGENTS.md diff --git a/src/control-plane-services/cloud-tasks/MODULE.bazel b/src/control-plane-services/cloud-tasks/MODULE.bazel new file mode 100644 index 000000000..3bb5eb33b --- /dev/null +++ b/src/control-plane-services/cloud-tasks/MODULE.bazel @@ -0,0 +1,253 @@ +# SPDX-FileCopyrightText: Copyright (c) NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +# +# 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. + +"""nvct_cloud_tasks: the NVCF cloud-tasks Java service, as a standalone module. + +Depends on nvcf_java_rules (shared macros + image helper) and nv_boot_parent +(the Spring platform starters), both via bazel_dep + local_path_override in-tree. +Resolves its own @maven graph into its own committed maven_install.json and +builds on its own: `cd src/control-plane-services/cloud-tasks && bazel build //...`. + +The boms list in maven.install is inlined (load() is forbidden in MODULE.bazel) +and must stay identical to SPRING_BOOT_BOM in @nvcf_java_rules//:platform.bzl; +//:bom_alignment_test enforces that. +""" + +module( + name = "nvct_cloud_tasks", + version = "1.0.0", +) + +bazel_dep(name = "nvcf_java_rules", version = "0.1.0") +local_path_override( + module_name = "nvcf_java_rules", + path = "../../../rules/java", +) + +bazel_dep(name = "nv_boot_parent", version = "4.0.7") +local_path_override( + module_name = "nv_boot_parent", + path = "../../libraries/java/nv-boot-parent", +) + +bazel_dep(name = "rules_java", version = "9.3.0") +bazel_dep(name = "rules_jvm_external", version = "7.0") +bazel_dep(name = "contrib_rules_jvm", version = "0.33.0") + +# gRPC-Java codegen: rules_proto_grpc_java drives protoc-gen-grpc-java (fetched +# as native binaries below) to generate the nvct.proto stubs. protobuf provides +# the well-known types; toolchains_protoc registers a prebuilt protoc so the +# proto_library does not compile the C++ protobuf compiler from source. +bazel_dep(name = "protobuf", version = "33.4", repo_name = "com_google_protobuf") +bazel_dep(name = "toolchains_protoc", version = "0.6.1") +bazel_dep(name = "rules_proto_grpc", version = "5.8.0") +bazel_dep(name = "rules_proto_grpc_java", version = "5.8.0") + +protoc = use_extension("@toolchains_protoc//protoc:extensions.bzl", "protoc") +protoc.toolchain( + google_protobuf = "com_google_protobuf", + version = "v33.0", +) + +GRPC_VERSION = "1.63.0" + +http_file = use_repo_rule( + "@bazel_tools//tools/build_defs/repo:http.bzl", + "http_file", +) + +http_file( + name = "grpc_java_plugin_linux_aarch_64", + downloaded_file_path = "protoc-gen-grpc-java.exe", + executable = True, + sha256 = "471427565ad82b3caac5e19dba2d15fb75b81042503ea32357630312d1f074b4", + urls = [ + "https://maven-central.storage-download.googleapis.com/maven2/io/grpc/protoc-gen-grpc-java/%s/protoc-gen-grpc-java-%s-linux-aarch_64.exe" % (GRPC_VERSION, GRPC_VERSION), + "https://repo.maven.apache.org/maven2/io/grpc/protoc-gen-grpc-java/%s/protoc-gen-grpc-java-%s-linux-aarch_64.exe" % (GRPC_VERSION, GRPC_VERSION), + ], +) + +http_file( + name = "grpc_java_plugin_linux_x86_64", + downloaded_file_path = "protoc-gen-grpc-java.exe", + executable = True, + sha256 = "0e3e8db80ba1fbddeed97ea3220b52cfaa95764ff8bf00716df7322883ce47e8", + urls = [ + "https://maven-central.storage-download.googleapis.com/maven2/io/grpc/protoc-gen-grpc-java/%s/protoc-gen-grpc-java-%s-linux-x86_64.exe" % (GRPC_VERSION, GRPC_VERSION), + "https://repo.maven.apache.org/maven2/io/grpc/protoc-gen-grpc-java/%s/protoc-gen-grpc-java-%s-linux-x86_64.exe" % (GRPC_VERSION, GRPC_VERSION), + ], +) + +http_file( + name = "grpc_java_plugin_osx_aarch_64", + downloaded_file_path = "protoc-gen-grpc-java.exe", + executable = True, + sha256 = "28290117a2ee9ea60f50f94273ab139dc2b3be4b8f2a557bef7e6efefee5b363", + urls = [ + "https://maven-central.storage-download.googleapis.com/maven2/io/grpc/protoc-gen-grpc-java/%s/protoc-gen-grpc-java-%s-osx-aarch_64.exe" % (GRPC_VERSION, GRPC_VERSION), + "https://repo.maven.apache.org/maven2/io/grpc/protoc-gen-grpc-java/%s/protoc-gen-grpc-java-%s-osx-aarch_64.exe" % (GRPC_VERSION, GRPC_VERSION), + ], +) + +http_file( + name = "grpc_java_plugin_osx_x86_64", + downloaded_file_path = "protoc-gen-grpc-java.exe", + executable = True, + sha256 = "28290117a2ee9ea60f50f94273ab139dc2b3be4b8f2a557bef7e6efefee5b363", + urls = [ + "https://maven-central.storage-download.googleapis.com/maven2/io/grpc/protoc-gen-grpc-java/%s/protoc-gen-grpc-java-%s-osx-x86_64.exe" % (GRPC_VERSION, GRPC_VERSION), + "https://repo.maven.apache.org/maven2/io/grpc/protoc-gen-grpc-java/%s/protoc-gen-grpc-java-%s-osx-x86_64.exe" % (GRPC_VERSION, GRPC_VERSION), + ], +) + +http_file( + name = "grpc_java_plugin_windows_x86_64", + downloaded_file_path = "protoc-gen-grpc-java.exe", + executable = True, + sha256 = "c3e9aaefd825a6ea9a252e153e0998d7ef36a7b27c2156867a98c71edf9c18a1", + urls = [ + "https://maven-central.storage-download.googleapis.com/maven2/io/grpc/protoc-gen-grpc-java/%s/protoc-gen-grpc-java-%s-windows-x86_64.exe" % (GRPC_VERSION, GRPC_VERSION), + "https://repo.maven.apache.org/maven2/io/grpc/protoc-gen-grpc-java/%s/protoc-gen-grpc-java-%s-windows-x86_64.exe" % (GRPC_VERSION, GRPC_VERSION), + ], +) + +maven = use_extension("@rules_jvm_external//:extensions.bzl", "maven") +maven.install( + name = "maven", + artifacts = [ + # nv-boot-parent third-party closure (Spring Boot 4 / Spring Cloud / + # OTel / Cassandra / Testcontainers). Root coordinates only: BOM-managed + # starters/modules, parent-owned explicit pins, and build/test tools. + "at.yawk.lz4:lz4-java:1.10.3", + "com.github.ben-manes.caffeine:guava", + "com.github.java-json-tools:json-patch:1.13", + "commons-codec:commons-codec", + "io.cloudevents:cloudevents-core:4.1.1", + "io.cloudevents:cloudevents-json-jackson:4.1.1", + "io.micrometer:micrometer-tracing-bridge-otel", + "io.nats:jnats:2.23.0", + "io.opentelemetry:opentelemetry-exporter-otlp", + "io.opentelemetry:opentelemetry-sdk-testing", + "jakarta.servlet:jakarta.servlet-api", + "org.apache.cassandra:java-driver-metrics-micrometer", + "org.apache.commons:commons-lang3:3.20.0", + "org.bouncycastle:bcprov-jdk18on:1.84", + "org.jacoco:org.jacoco.agent:jar:runtime:0.8.14", + "org.jacoco:org.jacoco.cli:0.8.14", + "org.junit.platform:junit-platform-console-standalone:6.0.3", + "org.ow2.asm:asm-analysis:9.9", + "org.ow2.asm:asm-util:9.9", + "org.projectlombok:lombok", + "org.springdoc:springdoc-openapi-starter-webflux-api:3.0.3", + "org.springdoc:springdoc-openapi-starter-webmvc-api:3.0.3", + "org.springframework.boot:spring-boot-micrometer-tracing-opentelemetry", + "org.springframework.boot:spring-boot-restclient", + "org.springframework.boot:spring-boot-starter", + "org.springframework.boot:spring-boot-starter-actuator", + "org.springframework.boot:spring-boot-starter-actuator-test", + "org.springframework.boot:spring-boot-starter-data-cassandra", + "org.springframework.boot:spring-boot-starter-data-cassandra-test", + "org.springframework.boot:spring-boot-starter-jackson", + "org.springframework.boot:spring-boot-starter-security-oauth2-client", + "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server", + "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server-test", + "org.springframework.boot:spring-boot-starter-test", + "org.springframework.boot:spring-boot-starter-validation", + "org.springframework.boot:spring-boot-starter-webflux", + "org.springframework.boot:spring-boot-starter-webflux-test", + "org.springframework.boot:spring-boot-starter-webmvc-test", + "org.springframework.boot:spring-boot-webclient", + "org.springframework.cloud:spring-cloud-commons", + "org.springframework.cloud:spring-cloud-context", + "org.springframework.cloud:spring-cloud-starter-bootstrap", + "org.springframework.security:spring-security-test", + "org.testcontainers:testcontainers-cassandra", + "org.testcontainers:testcontainers-junit-jupiter", + "org.wiremock:wiremock-standalone:3.13.2", + "software.amazon.awssdk:regions:2.40.1", + "tools.jackson.module:jackson-module-blackbird", + # examples/java-spring-boot-service (versions from the Spring Boot BOM). + "org.springframework.boot:spring-boot-starter-web", + "org.junit.jupiter:junit-jupiter-api", + "org.junit.jupiter:junit-jupiter-engine", + "org.junit.platform:junit-platform-launcher", + "org.junit.platform:junit-platform-reporting", + # cloud-tasks service closure. Version-less coordinates are managed by + # the BOMs above (spring-boot 4.0.7 / spring-cloud 2025.1.2 / + # testcontainers 2.0.5 / shedlock 7.7.0). Explicit versions match the + # cloud-tasks standalone module; io.grpc pins track GRPC_VERSION. + "com.bucket4j:bucket4j_jdk17-core:8.19.0", + "com.github.ben-manes.caffeine:caffeine", + "com.google.protobuf:protobuf-java:4.33.4", + "com.google.protobuf:protobuf-java-util:4.33.4", + "io.grpc:grpc-api:%s" % GRPC_VERSION, + "io.grpc:grpc-protobuf:%s" % GRPC_VERSION, + "io.grpc:grpc-stub:%s" % GRPC_VERSION, + "io.micrometer:micrometer-registry-prometheus", + "io.projectreactor.netty:reactor-netty-core", + "io.projectreactor.netty:reactor-netty-http", + "javax.annotation:javax.annotation-api:1.3.2", + "net.devh:grpc-server-spring-boot-starter:3.1.0.RELEASE", + "net.javacrumbs.shedlock:shedlock-provider-cassandra", + "net.javacrumbs.shedlock:shedlock-spring", + "org.assertj:assertj-core", + "org.awaitility:awaitility", + "org.junit.jupiter:junit-jupiter-params", + "org.mockito:mockito-core", + "org.mockito:mockito-junit-jupiter", + "org.ow2.asm:asm:9.9", + "org.ow2.asm:asm-commons:9.9", + "org.ow2.asm:asm-tree:9.9", + "org.springframework:spring-context-support", + "org.springframework:spring-webflux", + "org.springframework.boot:spring-boot-actuator", + "org.springframework.boot:spring-boot-loader", + "org.springframework.boot:spring-boot-micrometer-metrics", + "org.springframework.boot:spring-boot-micrometer-tracing", + "org.springframework.boot:spring-boot-opentelemetry", + "org.springframework.boot:spring-boot-starter-aspectj", + "org.springframework.boot:spring-boot-starter-security", + "org.springframework.boot:spring-boot-starter-webmvc", + "org.springframework.cloud:spring-cloud-starter-kubernetes-client-config", + "org.springframework.retry:spring-retry", + "org.testcontainers:testcontainers", + "org.testcontainers:testcontainers-localstack", + ], + boms = [ + "net.javacrumbs.shedlock:shedlock-bom:7.7.0", + "org.springframework.boot:spring-boot-dependencies:4.0.7", + "org.springframework.cloud:spring-cloud-dependencies:2025.1.2", + "org.testcontainers:testcontainers-bom:2.0.5", + ], + fail_on_missing_checksum = True, + fetch_sources = True, + known_contributing_modules = [ + "protobuf", + "rules_proto_grpc_java", + ], + lock_file = "//:maven_install.json", + repositories = [ + # Public Central mirrors only. This is the public GitHub mirror; its + # hosted runners cannot resolve the internal Artifactory host, so the + # pinned closure must fetch from public repositories. The Google-hosted + # Central mirror is primary (not IP-rate-limited like repo1.maven.org); + # Maven Central is the fallback. Internal builds that need NVIDIA + # artifacts add the Artifactory virtual repo in their own overlay. + "https://maven-central.storage-download.googleapis.com/maven2", + "https://repo.maven.apache.org/maven2", + ], + resolver = "maven", +) +use_repo(maven, "maven") diff --git a/src/control-plane-services/cloud-tasks/MODULE.bazel.lock b/src/control-plane-services/cloud-tasks/MODULE.bazel.lock new file mode 100644 index 000000000..2683917c6 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/MODULE.bazel.lock @@ -0,0 +1,1313 @@ +{ + "lockFileVersion": 28, + "registryFileHashes": { + "https://bcr.bazel.build/bazel_registry.json": "8a28e4aff06ee60aed2a8c281907fb8bcbf3b753c91fb5a5c57da3215d5b3497", + "https://bcr.bazel.build/modules/abseil-cpp/20210324.2/MODULE.bazel": "7cd0312e064fde87c8d1cd79ba06c876bd23630c83466e9500321be55c96ace2", + "https://bcr.bazel.build/modules/abseil-cpp/20211102.0/MODULE.bazel": "70390338f7a5106231d20620712f7cccb659cd0e9d073d1991c038eb9fc57589", + "https://bcr.bazel.build/modules/abseil-cpp/20230125.1/MODULE.bazel": "89047429cb0207707b2dface14ba7f8df85273d484c2572755be4bab7ce9c3a0", + "https://bcr.bazel.build/modules/abseil-cpp/20230802.0.bcr.1/MODULE.bazel": "1c8cec495288dccd14fdae6e3f95f772c1c91857047a098fad772034264cc8cb", + "https://bcr.bazel.build/modules/abseil-cpp/20230802.0/MODULE.bazel": "d253ae36a8bd9ee3c5955384096ccb6baf16a1b1e93e858370da0a3b94f77c16", + "https://bcr.bazel.build/modules/abseil-cpp/20230802.1/MODULE.bazel": "fa92e2eb41a04df73cdabeec37107316f7e5272650f81d6cc096418fe647b915", + "https://bcr.bazel.build/modules/abseil-cpp/20240116.1/MODULE.bazel": "37bcdb4440fbb61df6a1c296ae01b327f19e9bb521f9b8e26ec854b6f97309ed", + "https://bcr.bazel.build/modules/abseil-cpp/20240116.2/MODULE.bazel": "73939767a4686cd9a520d16af5ab440071ed75cec1a876bf2fcfaf1f71987a16", + "https://bcr.bazel.build/modules/abseil-cpp/20250127.0/MODULE.bazel": "d1086e248cda6576862b4b3fe9ad76a214e08c189af5b42557a6e1888812c5d5", + "https://bcr.bazel.build/modules/abseil-cpp/20250127.1/MODULE.bazel": "c4a89e7ceb9bf1e25cf84a9f830ff6b817b72874088bf5141b314726e46a57c1", + "https://bcr.bazel.build/modules/abseil-cpp/20250512.1/MODULE.bazel": "d209fdb6f36ffaf61c509fcc81b19e81b411a999a934a032e10cd009a0226215", + "https://bcr.bazel.build/modules/abseil-cpp/20250814.1/MODULE.bazel": "51f2312901470cdab0dbdf3b88c40cd21c62a7ed58a3de45b365ddc5b11bcab2", + "https://bcr.bazel.build/modules/abseil-cpp/20250814.1/source.json": "cea3901d7e299da7320700abbaafe57a65d039f10d0d7ea601c4a66938ea4b0c", + "https://bcr.bazel.build/modules/abseil-py/2.1.0/MODULE.bazel": "5ebe5bf853769c65707e5c28f216798f7a4b1042015e6a36e6d03094d94bec8a", + "https://bcr.bazel.build/modules/abseil-py/2.1.0/source.json": "0e8fc4f088ce07099c1cd6594c20c7ddbb48b4b3c0849b7d94ba94be88ff042b", + "https://bcr.bazel.build/modules/apple_rules_lint/0.4.0/MODULE.bazel": "c59831c3a5389430516203777816527f257329a5da363994e1d62b9ae6729f71", + "https://bcr.bazel.build/modules/apple_rules_lint/0.4.0/source.json": "105883202602181f43f109372e1b9ea19e89bbe3bce4bc1fe9bb0baa51eb61ae", + "https://bcr.bazel.build/modules/apple_support/1.11.1/MODULE.bazel": "1843d7cd8a58369a444fc6000e7304425fba600ff641592161d9f15b179fb896", + "https://bcr.bazel.build/modules/apple_support/1.15.1/MODULE.bazel": "a0556fefca0b1bb2de8567b8827518f94db6a6e7e7d632b4c48dc5f865bc7c85", + "https://bcr.bazel.build/modules/apple_support/1.21.0/MODULE.bazel": "ac1824ed5edf17dee2fdd4927ada30c9f8c3b520be1b5fd02a5da15bc10bff3e", + "https://bcr.bazel.build/modules/apple_support/1.21.1/MODULE.bazel": "5809fa3efab15d1f3c3c635af6974044bac8a4919c62238cce06acee8a8c11f1", + "https://bcr.bazel.build/modules/apple_support/1.23.0/MODULE.bazel": "317d47e3f65b580e7fb4221c160797fda48e32f07d2dfff63d754ef2316dcd25", + "https://bcr.bazel.build/modules/apple_support/1.24.2/MODULE.bazel": "0e62471818affb9f0b26f128831d5c40b074d32e6dda5a0d3852847215a41ca4", + "https://bcr.bazel.build/modules/apple_support/1.24.2/source.json": "2c22c9827093250406c5568da6c54e6fdf0ef06238def3d99c71b12feb057a8d", + "https://bcr.bazel.build/modules/aspect_bazel_lib/2.14.0/MODULE.bazel": "2b31ffcc9bdc8295b2167e07a757dbbc9ac8906e7028e5170a3708cecaac119f", + "https://bcr.bazel.build/modules/aspect_bazel_lib/2.19.3/MODULE.bazel": "253d739ba126f62a5767d832765b12b59e9f8d2bc88cc1572f4a73e46eb298ca", + "https://bcr.bazel.build/modules/aspect_bazel_lib/2.21.2/MODULE.bazel": "276347663a25b0d5bd6cad869252bea3e160c4d980e764b15f3bae7f80b30624", + "https://bcr.bazel.build/modules/aspect_bazel_lib/2.21.2/source.json": "f42051fa42629f0e59b7ac2adf0a55749144b11f1efcd8c697f0ee247181e526", + "https://bcr.bazel.build/modules/aspect_bazel_lib/2.7.2/MODULE.bazel": "780d1a6522b28f5edb7ea09630748720721dfe27690d65a2d33aa7509de77e07", + "https://bcr.bazel.build/modules/aspect_bazel_lib/2.8.1/MODULE.bazel": "812d2dd42f65dca362152101fbec418029cc8fd34cbad1a2fde905383d705838", + "https://bcr.bazel.build/modules/bazel_features/1.1.0/MODULE.bazel": "cfd42ff3b815a5f39554d97182657f8c4b9719568eb7fded2b9135f084bf760b", + "https://bcr.bazel.build/modules/bazel_features/1.1.1/MODULE.bazel": "27b8c79ef57efe08efccbd9dd6ef70d61b4798320b8d3c134fd571f78963dbcd", + "https://bcr.bazel.build/modules/bazel_features/1.10.0/MODULE.bazel": "f75e8807570484a99be90abcd52b5e1f390362c258bcb73106f4544957a48101", + "https://bcr.bazel.build/modules/bazel_features/1.11.0/MODULE.bazel": "f9382337dd5a474c3b7d334c2f83e50b6eaedc284253334cf823044a26de03e8", + "https://bcr.bazel.build/modules/bazel_features/1.13.0/MODULE.bazel": "c14c33c7c3c730612bdbe14ebbb5e61936b6f11322ea95a6e91cd1ba962f94df", + "https://bcr.bazel.build/modules/bazel_features/1.15.0/MODULE.bazel": "d38ff6e517149dc509406aca0db3ad1efdd890a85e049585b7234d04238e2a4d", + "https://bcr.bazel.build/modules/bazel_features/1.17.0/MODULE.bazel": "039de32d21b816b47bd42c778e0454217e9c9caac4a3cf8e15c7231ee3ddee4d", + "https://bcr.bazel.build/modules/bazel_features/1.18.0/MODULE.bazel": "1be0ae2557ab3a72a57aeb31b29be347bcdc5d2b1eb1e70f39e3851a7e97041a", + "https://bcr.bazel.build/modules/bazel_features/1.19.0/MODULE.bazel": "59adcdf28230d220f0067b1f435b8537dd033bfff8db21335ef9217919c7fb58", + "https://bcr.bazel.build/modules/bazel_features/1.21.0/MODULE.bazel": "675642261665d8eea09989aa3b8afb5c37627f1be178382c320d1b46afba5e3b", + "https://bcr.bazel.build/modules/bazel_features/1.23.0/MODULE.bazel": "fd1ac84bc4e97a5a0816b7fd7d4d4f6d837b0047cf4cbd81652d616af3a6591a", + "https://bcr.bazel.build/modules/bazel_features/1.25.0/MODULE.bazel": "e2e60a10a6da64bbf533f15ca652bf61a033e41c2ed734d79a9a08ba87f68c1a", + "https://bcr.bazel.build/modules/bazel_features/1.27.0/MODULE.bazel": "621eeee06c4458a9121d1f104efb80f39d34deff4984e778359c60eaf1a8cb65", + "https://bcr.bazel.build/modules/bazel_features/1.28.0/MODULE.bazel": "4b4200e6cbf8fa335b2c3f43e1d6ef3e240319c33d43d60cc0fbd4b87ece299d", + "https://bcr.bazel.build/modules/bazel_features/1.3.0/MODULE.bazel": "cdcafe83ec318cda34e02948e81d790aab8df7a929cec6f6969f13a489ccecd9", + "https://bcr.bazel.build/modules/bazel_features/1.30.0/MODULE.bazel": "a14b62d05969a293b80257e72e597c2da7f717e1e69fa8b339703ed6731bec87", + "https://bcr.bazel.build/modules/bazel_features/1.32.0/MODULE.bazel": "095d67022a58cb20f7e20e1aefecfa65257a222c18a938e2914fd257b5f1ccdc", + "https://bcr.bazel.build/modules/bazel_features/1.33.0/MODULE.bazel": "8b8dc9d2a4c88609409c3191165bccec0e4cb044cd7a72ccbe826583303459f6", + "https://bcr.bazel.build/modules/bazel_features/1.4.1/MODULE.bazel": "e45b6bb2350aff3e442ae1111c555e27eac1d915e77775f6fdc4b351b758b5d7", + "https://bcr.bazel.build/modules/bazel_features/1.42.1/MODULE.bazel": "275a59b5406ff18c01739860aa70ad7ccb3cfb474579411decca11c93b951080", + "https://bcr.bazel.build/modules/bazel_features/1.42.1/source.json": "fcd4396b2df85f64f2b3bb436ad870793ecf39180f1d796f913cc9276d355309", + "https://bcr.bazel.build/modules/bazel_features/1.9.0/MODULE.bazel": "885151d58d90d8d9c811eb75e3288c11f850e1d6b481a8c9f766adee4712358b", + "https://bcr.bazel.build/modules/bazel_features/1.9.1/MODULE.bazel": "8f679097876a9b609ad1f60249c49d68bfab783dd9be012faf9d82547b14815a", + "https://bcr.bazel.build/modules/bazel_lib/3.0.0/MODULE.bazel": "22b70b80ac89ad3f3772526cd9feee2fa412c2b01933fea7ed13238a448d370d", + "https://bcr.bazel.build/modules/bazel_lib/3.0.0/source.json": "895f21909c6fba01d7c17914bb6c8e135982275a1b18cdaa4e62272217ef1751", + "https://bcr.bazel.build/modules/bazel_skylib/1.0.3/MODULE.bazel": "bcb0fd896384802d1ad283b4e4eb4d718eebd8cb820b0a2c3a347fb971afd9d8", + "https://bcr.bazel.build/modules/bazel_skylib/1.1.1/MODULE.bazel": "1add3e7d93ff2e6998f9e118022c84d163917d912f5afafb3058e3d2f1545b5e", + "https://bcr.bazel.build/modules/bazel_skylib/1.2.0/MODULE.bazel": "44fe84260e454ed94ad326352a698422dbe372b21a1ac9f3eab76eb531223686", + "https://bcr.bazel.build/modules/bazel_skylib/1.2.1/MODULE.bazel": "f35baf9da0efe45fa3da1696ae906eea3d615ad41e2e3def4aeb4e8bc0ef9a7a", + "https://bcr.bazel.build/modules/bazel_skylib/1.3.0/MODULE.bazel": "20228b92868bf5cfc41bda7afc8a8ba2a543201851de39d990ec957b513579c5", + "https://bcr.bazel.build/modules/bazel_skylib/1.4.1/MODULE.bazel": "a0dcb779424be33100dcae821e9e27e4f2901d9dfd5333efe5ac6a8d7ab75e1d", + "https://bcr.bazel.build/modules/bazel_skylib/1.4.2/MODULE.bazel": "3bd40978e7a1fac911d5989e6b09d8f64921865a45822d8b09e815eaa726a651", + "https://bcr.bazel.build/modules/bazel_skylib/1.5.0/MODULE.bazel": "32880f5e2945ce6a03d1fbd588e9198c0a959bb42297b2cfaf1685b7bc32e138", + "https://bcr.bazel.build/modules/bazel_skylib/1.6.1/MODULE.bazel": "8fdee2dbaace6c252131c00e1de4b165dc65af02ea278476187765e1a617b917", + "https://bcr.bazel.build/modules/bazel_skylib/1.7.0/MODULE.bazel": "0db596f4563de7938de764cc8deeabec291f55e8ec15299718b93c4423e9796d", + "https://bcr.bazel.build/modules/bazel_skylib/1.7.1/MODULE.bazel": "3120d80c5861aa616222ec015332e5f8d3171e062e3e804a2a0253e1be26e59b", + "https://bcr.bazel.build/modules/bazel_skylib/1.8.1/MODULE.bazel": "88ade7293becda963e0e3ea33e7d54d3425127e0a326e0d17da085a5f1f03ff6", + "https://bcr.bazel.build/modules/bazel_skylib/1.8.2/MODULE.bazel": "69ad6927098316848b34a9142bcc975e018ba27f08c4ff403f50c1b6e646ca67", + "https://bcr.bazel.build/modules/bazel_skylib/1.8.2/source.json": "34a3c8bcf233b835eb74be9d628899bb32999d3e0eadef1947a0a562a2b16ffb", + "https://bcr.bazel.build/modules/bazel_worker_api/0.0.1/MODULE.bazel": "02a13b77321773b2042e70ee5e4c5e099c8ddee4cf2da9cd420442c36938d4bd", + "https://bcr.bazel.build/modules/bazel_worker_api/0.0.4/MODULE.bazel": "460aa12d01231a80cce03c548287b433b321d205b0028ae596728c35e5ee442e", + "https://bcr.bazel.build/modules/bazel_worker_api/0.0.8/MODULE.bazel": "396c1ef53835aafe3d42ce6619080531ee770648303731f16cfaa33fa056bf0c", + "https://bcr.bazel.build/modules/bazel_worker_api/0.0.8/source.json": "abaf8ac9d2ab2f47bda9af4c0c080ff7907378888e1f4bc62a0539dd13ba61e8", + "https://bcr.bazel.build/modules/bazel_worker_java/0.0.4/MODULE.bazel": "82494a01018bb7ef06d4a17ec4cd7a758721f10eb8b6c820a818e70d669500db", + "https://bcr.bazel.build/modules/bazel_worker_java/0.0.8/MODULE.bazel": "e76479eae70bd4e8f5f4c2dfc5d03ab971cfb18750246c7b3f3454c5c2ee6629", + "https://bcr.bazel.build/modules/bazel_worker_java/0.0.8/source.json": "9395c4679444bc47bf7e51a710366a4480aa371c6f6bed01868e2fabcf11acec", + "https://bcr.bazel.build/modules/buildozer/8.5.1/MODULE.bazel": "a35d9561b3fc5b18797c330793e99e3b834a473d5fbd3d7d7634aafc9bdb6f8f", + "https://bcr.bazel.build/modules/buildozer/8.5.1/source.json": "e3386e6ff4529f2442800dee47ad28d3e6487f36a1f75ae39ae56c70f0cd2fbd", + "https://bcr.bazel.build/modules/contrib_rules_jvm/0.33.0/MODULE.bazel": "1aba514585748372ee392484b2645f0bbcb13ad4271d5b7cace018280f15bae1", + "https://bcr.bazel.build/modules/contrib_rules_jvm/0.33.0/source.json": "e52d62ce2a2b8a513d6afe9178acc06a4349c9b0b4c0934d59085ed9df4b4de0", + "https://bcr.bazel.build/modules/gawk/5.3.2.bcr.1/MODULE.bazel": "cdf8cbe5ee750db04b78878c9633cc76e80dcf4416cbe982ac3a9222f80713c8", + "https://bcr.bazel.build/modules/gawk/5.3.2.bcr.1/source.json": "fa7b512dfcb5eafd90ce3959cf42a2a6fe96144ebbb4b3b3928054895f2afac2", + "https://bcr.bazel.build/modules/gazelle/0.32.0/MODULE.bazel": "b499f58a5d0d3537f3cf5b76d8ada18242f64ec474d8391247438bf04f58c7b8", + "https://bcr.bazel.build/modules/gazelle/0.33.0/MODULE.bazel": "a13a0f279b462b784fb8dd52a4074526c4a2afe70e114c7d09066097a46b3350", + "https://bcr.bazel.build/modules/gazelle/0.34.0/MODULE.bazel": "abdd8ce4d70978933209db92e436deb3a8b737859e9354fb5fd11fb5c2004c8a", + "https://bcr.bazel.build/modules/gazelle/0.36.0/MODULE.bazel": "e375d5d6e9a6ca59b0cb38b0540bc9a05b6aa926d322f2de268ad267a2ee74c0", + "https://bcr.bazel.build/modules/gazelle/0.40.0/MODULE.bazel": "42ba5378ebe845fca43989a53186ab436d956db498acde790685fe0e8f9c6146", + "https://bcr.bazel.build/modules/gazelle/0.42.0/MODULE.bazel": "fa140a7c019f3a22779ba7c6132ffff9d2d10a51dba2f3304dee61523d11fef4", + "https://bcr.bazel.build/modules/gazelle/0.47.0/MODULE.bazel": "b61bb007c4efad134aa30ee7f4a8e2a39b22aa5685f005edaa022fbd1de43ebc", + "https://bcr.bazel.build/modules/gazelle/0.47.0/source.json": "aeb2e5df14b7fb298625d75d08b9c65bdb0b56014c5eb89da9e5dd0572280ae6", + "https://bcr.bazel.build/modules/google_benchmark/1.8.2/MODULE.bazel": "a70cf1bba851000ba93b58ae2f6d76490a9feb74192e57ab8e8ff13c34ec50cb", + "https://bcr.bazel.build/modules/googletest/1.11.0/MODULE.bazel": "3a83f095183f66345ca86aa13c58b59f9f94a2f81999c093d4eeaa2d262d12f4", + "https://bcr.bazel.build/modules/googletest/1.14.0.bcr.1/MODULE.bazel": "22c31a561553727960057361aa33bf20fb2e98584bc4fec007906e27053f80c6", + "https://bcr.bazel.build/modules/googletest/1.14.0/MODULE.bazel": "cfbcbf3e6eac06ef9d85900f64424708cc08687d1b527f0ef65aa7517af8118f", + "https://bcr.bazel.build/modules/googletest/1.15.2/MODULE.bazel": "6de1edc1d26cafb0ea1a6ab3f4d4192d91a312fd2d360b63adaa213cd00b2108", + "https://bcr.bazel.build/modules/googletest/1.17.0/MODULE.bazel": "dbec758171594a705933a29fcf69293d2468c49ec1f2ebca65c36f504d72df46", + "https://bcr.bazel.build/modules/googletest/1.17.0/source.json": "38e4454b25fc30f15439c0378e57909ab1fd0a443158aa35aec685da727cd713", + "https://bcr.bazel.build/modules/jq.bzl/0.1.0/MODULE.bazel": "2ce69b1af49952cd4121a9c3055faa679e748ce774c7f1fda9657f936cae902f", + "https://bcr.bazel.build/modules/jq.bzl/0.1.0/source.json": "746bf13cac0860f091df5e4911d0c593971cd8796b5ad4e809b2f8e133eee3d5", + "https://bcr.bazel.build/modules/jsoncpp/1.9.5/MODULE.bazel": "31271aedc59e815656f5736f282bb7509a97c7ecb43e927ac1a37966e0578075", + "https://bcr.bazel.build/modules/jsoncpp/1.9.6/MODULE.bazel": "2f8d20d3b7d54143213c4dfc3d98225c42de7d666011528dc8fe91591e2e17b0", + "https://bcr.bazel.build/modules/jsoncpp/1.9.6/source.json": "a04756d367a2126c3541682864ecec52f92cdee80a35735a3cb249ce015ca000", + "https://bcr.bazel.build/modules/libpfm/4.11.0/MODULE.bazel": "45061ff025b301940f1e30d2c16bea596c25b176c8b6b3087e92615adbd52902", + "https://bcr.bazel.build/modules/nlohmann_json/3.6.1/MODULE.bazel": "6f7b417dcc794d9add9e556673ad25cb3ba835224290f4f848f8e2db1e1fca74", + "https://bcr.bazel.build/modules/nlohmann_json/3.6.1/source.json": "f448c6e8963fdfa7eb831457df83ad63d3d6355018f6574fb017e8169deb43a9", + "https://bcr.bazel.build/modules/package_metadata/0.0.2/MODULE.bazel": "fb8d25550742674d63d7b250063d4580ca530499f045d70748b1b142081ebb92", + "https://bcr.bazel.build/modules/package_metadata/0.0.3/MODULE.bazel": "77890552ecea9e284b5424c9de827a58099348763a4359e975c359a83d4faa83", + "https://bcr.bazel.build/modules/package_metadata/0.0.5/MODULE.bazel": "ef4f9439e3270fdd6b9fd4dbc3d2f29d13888e44c529a1b243f7a31dfbc2e8e4", + "https://bcr.bazel.build/modules/package_metadata/0.0.7/MODULE.bazel": "7adb03933fc8401f495800cf4eafcff0edc6da0ff55c7db223ef69d19f689486", + "https://bcr.bazel.build/modules/package_metadata/0.0.7/source.json": "50639625e937b56115012674c797cca7a05a96b4878c87d803c13dc2b31de8a0", + "https://bcr.bazel.build/modules/platforms/0.0.10/MODULE.bazel": "8cb8efaf200bdeb2150d93e162c40f388529a25852b332cec879373771e48ed5", + "https://bcr.bazel.build/modules/platforms/0.0.11/MODULE.bazel": "0daefc49732e227caa8bfa834d65dc52e8cc18a2faf80df25e8caea151a9413f", + "https://bcr.bazel.build/modules/platforms/0.0.4/MODULE.bazel": "9b328e31ee156f53f3c416a64f8491f7eb731742655a47c9eec4703a71644aee", + "https://bcr.bazel.build/modules/platforms/0.0.5/MODULE.bazel": "5733b54ea419d5eaf7997054bb55f6a1d0b5ff8aedf0176fef9eea44f3acda37", + "https://bcr.bazel.build/modules/platforms/0.0.6/MODULE.bazel": "ad6eeef431dc52aefd2d77ed20a4b353f8ebf0f4ecdd26a807d2da5aa8cd0615", + "https://bcr.bazel.build/modules/platforms/0.0.7/MODULE.bazel": "72fd4a0ede9ee5c021f6a8dd92b503e089f46c227ba2813ff183b71616034814", + "https://bcr.bazel.build/modules/platforms/0.0.8/MODULE.bazel": "9f142c03e348f6d263719f5074b21ef3adf0b139ee4c5133e2aa35664da9eb2d", + "https://bcr.bazel.build/modules/platforms/0.0.9/MODULE.bazel": "4a87a60c927b56ddd67db50c89acaa62f4ce2a1d2149ccb63ffd871d5ce29ebc", + "https://bcr.bazel.build/modules/platforms/1.0.0/MODULE.bazel": "f05feb42b48f1b3c225e4ccf351f367be0371411a803198ec34a389fb22aa580", + "https://bcr.bazel.build/modules/platforms/1.0.0/source.json": "f4ff1fd412e0246fd38c82328eb209130ead81d62dcd5a9e40910f867f733d96", + "https://bcr.bazel.build/modules/protobuf/21.7/MODULE.bazel": "a5a29bb89544f9b97edce05642fac225a808b5b7be74038ea3640fae2f8e66a7", + "https://bcr.bazel.build/modules/protobuf/23.1/MODULE.bazel": "88b393b3eb4101d18129e5db51847cd40a5517a53e81216144a8c32dfeeca52a", + "https://bcr.bazel.build/modules/protobuf/24.4/MODULE.bazel": "7bc7ce5f2abf36b3b7b7c8218d3acdebb9426aeb35c2257c96445756f970eb12", + "https://bcr.bazel.build/modules/protobuf/27.0/MODULE.bazel": "7873b60be88844a0a1d8f80b9d5d20cfbd8495a689b8763e76c6372998d3f64c", + "https://bcr.bazel.build/modules/protobuf/27.1/MODULE.bazel": "703a7b614728bb06647f965264967a8ef1c39e09e8f167b3ca0bb1fd80449c0d", + "https://bcr.bazel.build/modules/protobuf/27.2/MODULE.bazel": "32450b50673882e4c8c3d10a83f3bc82161b213ed2f80d17e38bece8f165c295", + "https://bcr.bazel.build/modules/protobuf/29.0-rc2.bcr.1/MODULE.bazel": "52f4126f63a2f0bbf36b99c2a87648f08467a4eaf92ba726bc7d6a500bbf770c", + "https://bcr.bazel.build/modules/protobuf/29.0-rc2/MODULE.bazel": "6241d35983510143049943fc0d57937937122baf1b287862f9dc8590fc4c37df", + "https://bcr.bazel.build/modules/protobuf/29.0-rc3/MODULE.bazel": "33c2dfa286578573afc55a7acaea3cada4122b9631007c594bf0729f41c8de92", + "https://bcr.bazel.build/modules/protobuf/29.0/MODULE.bazel": "319dc8bf4c679ff87e71b1ccfb5a6e90a6dbc4693501d471f48662ac46d04e4e", + "https://bcr.bazel.build/modules/protobuf/29.1/MODULE.bazel": "557c3457560ff49e122ed76c0bc3397a64af9574691cb8201b4e46d4ab2ecb95", + "https://bcr.bazel.build/modules/protobuf/29.3/MODULE.bazel": "77480eea5fb5541903e49683f24dc3e09f4a79e0eea247414887bb9fc0066e94", + "https://bcr.bazel.build/modules/protobuf/3.19.0/MODULE.bazel": "6b5fbb433f760a99a22b18b6850ed5784ef0e9928a72668b66e4d7ccd47db9b0", + "https://bcr.bazel.build/modules/protobuf/3.19.2/MODULE.bazel": "532ffe5f2186b69fdde039efe6df13ba726ff338c6bc82275ad433013fa10573", + "https://bcr.bazel.build/modules/protobuf/3.19.6/MODULE.bazel": "9233edc5e1f2ee276a60de3eaa47ac4132302ef9643238f23128fea53ea12858", + "https://bcr.bazel.build/modules/protobuf/31.1/MODULE.bazel": "379a389bb330b7b8c1cdf331cc90bf3e13de5614799b3b52cdb7c6f389f6b38e", + "https://bcr.bazel.build/modules/protobuf/32.1/MODULE.bazel": "89cd2866a9cb07fee9ff74c41ceace11554f32e0d849de4e23ac55515cfada4d", + "https://bcr.bazel.build/modules/protobuf/33.4/MODULE.bazel": "114775b816b38b6d0ca620450d6b02550c60ceedfdc8d9a229833b34a223dc42", + "https://bcr.bazel.build/modules/protobuf/33.4/source.json": "555f8686b4c7d6b5ba731fbea13bf656b4bfd9a7ff629c1d9d3f6e1d6155de79", + "https://bcr.bazel.build/modules/pybind11_bazel/2.11.1/MODULE.bazel": "88af1c246226d87e65be78ed49ecd1e6f5e98648558c14ce99176da041dc378e", + "https://bcr.bazel.build/modules/pybind11_bazel/2.12.0/MODULE.bazel": "e6f4c20442eaa7c90d7190d8dc539d0ab422f95c65a57cc59562170c58ae3d34", + "https://bcr.bazel.build/modules/pybind11_bazel/2.12.0/source.json": "6900fdc8a9e95866b8c0d4ad4aba4d4236317b5c1cd04c502df3f0d33afed680", + "https://bcr.bazel.build/modules/re2/2023-09-01/MODULE.bazel": "cb3d511531b16cfc78a225a9e2136007a48cf8a677e4264baeab57fe78a80206", + "https://bcr.bazel.build/modules/re2/2024-07-02.bcr.1/MODULE.bazel": "b4963dda9b31080be1905ef085ecd7dd6cd47c05c79b9cdf83ade83ab2ab271a", + "https://bcr.bazel.build/modules/re2/2024-07-02.bcr.1/source.json": "2ff292be6ef3340325ce8a045ecc326e92cbfab47c7cbab4bd85d28971b97ac4", + "https://bcr.bazel.build/modules/re2/2024-07-02/MODULE.bazel": "0eadc4395959969297cbcf31a249ff457f2f1d456228c67719480205aa306daa", + "https://bcr.bazel.build/modules/rules_android/0.1.1/MODULE.bazel": "48809ab0091b07ad0182defb787c4c5328bd3a278938415c00a7b69b50c4d3a8", + "https://bcr.bazel.build/modules/rules_android/0.6.4/MODULE.bazel": "b4cde12d506dd65d82b2be39761f49f5797303343a3d5b4ee191c0cdf9ef387c", + "https://bcr.bazel.build/modules/rules_android/0.6.6/MODULE.bazel": "b0fb569752aab65ab1a9db0a8f6cfaf5aa1754965e17e95dcf0e4d88e192a68d", + "https://bcr.bazel.build/modules/rules_android/0.7.1/MODULE.bazel": "a806fc382a774252f228a40e3b11b9fcc6276f8778c7fb33e9f72937c6258363", + "https://bcr.bazel.build/modules/rules_android/0.7.1/source.json": "151440aed3f0f73a00d4ed5cec5d31f63a6fef9b95d8fab1eb1810150fa525f2", + "https://bcr.bazel.build/modules/rules_apple/3.16.0/MODULE.bazel": "0d1caf0b8375942ce98ea944be754a18874041e4e0459401d925577624d3a54a", + "https://bcr.bazel.build/modules/rules_apple/4.1.0/MODULE.bazel": "76e10fd4a48038d3fc7c5dc6e63b7063bbf5304a2e3bd42edda6ec660eebea68", + "https://bcr.bazel.build/modules/rules_apple/4.1.0/source.json": "8ee81e1708756f81b343a5eb2b2f0b953f1d25c4ab3d4a68dc02754872e80715", + "https://bcr.bazel.build/modules/rules_cc/0.0.1/MODULE.bazel": "cb2aa0747f84c6c3a78dad4e2049c154f08ab9d166b1273835a8174940365647", + "https://bcr.bazel.build/modules/rules_cc/0.0.10/MODULE.bazel": "ec1705118f7eaedd6e118508d3d26deba2a4e76476ada7e0e3965211be012002", + "https://bcr.bazel.build/modules/rules_cc/0.0.13/MODULE.bazel": "0e8529ed7b323dad0775ff924d2ae5af7640b23553dfcd4d34344c7e7a867191", + "https://bcr.bazel.build/modules/rules_cc/0.0.15/MODULE.bazel": "6704c35f7b4a72502ee81f61bf88706b54f06b3cbe5558ac17e2e14666cd5dcc", + "https://bcr.bazel.build/modules/rules_cc/0.0.16/MODULE.bazel": "7661303b8fc1b4d7f532e54e9d6565771fea666fbdf839e0a86affcd02defe87", + "https://bcr.bazel.build/modules/rules_cc/0.0.17/MODULE.bazel": "2ae1d8f4238ec67d7185d8861cb0a2cdf4bc608697c331b95bf990e69b62e64a", + "https://bcr.bazel.build/modules/rules_cc/0.0.2/MODULE.bazel": "6915987c90970493ab97393024c156ea8fb9f3bea953b2f3ec05c34f19b5695c", + "https://bcr.bazel.build/modules/rules_cc/0.0.6/MODULE.bazel": "abf360251023dfe3efcef65ab9d56beefa8394d4176dd29529750e1c57eaa33f", + "https://bcr.bazel.build/modules/rules_cc/0.0.8/MODULE.bazel": "964c85c82cfeb6f3855e6a07054fdb159aced38e99a5eecf7bce9d53990afa3e", + "https://bcr.bazel.build/modules/rules_cc/0.0.9/MODULE.bazel": "836e76439f354b89afe6a911a7adf59a6b2518fafb174483ad78a2a2fde7b1c5", + "https://bcr.bazel.build/modules/rules_cc/0.1.1/MODULE.bazel": "2f0222a6f229f0bf44cd711dc13c858dad98c62d52bd51d8fc3a764a83125513", + "https://bcr.bazel.build/modules/rules_cc/0.1.2/MODULE.bazel": "557ddc3a96858ec0d465a87c0a931054d7dcfd6583af2c7ed3baf494407fd8d0", + "https://bcr.bazel.build/modules/rules_cc/0.1.5/MODULE.bazel": "88dfc9361e8b5ae1008ac38f7cdfd45ad738e4fa676a3ad67d19204f045a1fd8", + "https://bcr.bazel.build/modules/rules_cc/0.2.0/MODULE.bazel": "b5c17f90458caae90d2ccd114c81970062946f49f355610ed89bebf954f5783c", + "https://bcr.bazel.build/modules/rules_cc/0.2.13/MODULE.bazel": "eecdd666eda6be16a8d9dc15e44b5c75133405e820f620a234acc4b1fdc5aa37", + "https://bcr.bazel.build/modules/rules_cc/0.2.14/MODULE.bazel": "353c99ed148887ee89c54a17d4100ae7e7e436593d104b668476019023b58df8", + "https://bcr.bazel.build/modules/rules_cc/0.2.17/MODULE.bazel": "1849602c86cb60da8613d2de887f9566a6d354a6df6d7009f9d04a14402f9a84", + "https://bcr.bazel.build/modules/rules_cc/0.2.17/source.json": "3832f45d145354049137c0090df04629d9c2b5493dc5c2bf46f1834040133a07", + "https://bcr.bazel.build/modules/rules_cc/0.2.4/MODULE.bazel": "1ff1223dfd24f3ecf8f028446d4a27608aa43c3f41e346d22838a4223980b8cc", + "https://bcr.bazel.build/modules/rules_cc/0.2.8/MODULE.bazel": "f1df20f0bf22c28192a794f29b501ee2018fa37a3862a1a2132ae2940a23a642", + "https://bcr.bazel.build/modules/rules_foreign_cc/0.9.0/MODULE.bazel": "c9e8c682bf75b0e7c704166d79b599f93b72cfca5ad7477df596947891feeef6", + "https://bcr.bazel.build/modules/rules_fuzzing/0.5.2/MODULE.bazel": "40c97d1144356f52905566c55811f13b299453a14ac7769dfba2ac38192337a8", + "https://bcr.bazel.build/modules/rules_go/0.41.0/MODULE.bazel": "55861d8e8bb0e62cbd2896f60ff303f62ffcb0eddb74ecb0e5c0cbe36fc292c8", + "https://bcr.bazel.build/modules/rules_go/0.42.0/MODULE.bazel": "8cfa875b9aa8c6fce2b2e5925e73c1388173ea3c32a0db4d2b4804b453c14270", + "https://bcr.bazel.build/modules/rules_go/0.46.0/MODULE.bazel": "3477df8bdcc49e698b9d25f734c4f3a9f5931ff34ee48a2c662be168f5f2d3fd", + "https://bcr.bazel.build/modules/rules_go/0.50.1/MODULE.bazel": "b91a308dc5782bb0a8021ad4330c81fea5bda77f96b9e4c117b9b9c8f6665ee0", + "https://bcr.bazel.build/modules/rules_go/0.51.0-rc2/MODULE.bazel": "edfc3a9cea7bedb0eaaff37b0d7817c1a4bf72b3c615580b0ffcee6c52690fd4", + "https://bcr.bazel.build/modules/rules_go/0.52.0/MODULE.bazel": "0cf080a2706aa8fc9abf64286cee60fdf0238db37b7f1793b0f7d550d59ea3ae", + "https://bcr.bazel.build/modules/rules_go/0.53.0/MODULE.bazel": "a4ed760d3ac0dbc0d7b967631a9a3fd9100d28f7d9fcf214b4df87d4bfff5f9a", + "https://bcr.bazel.build/modules/rules_go/0.59.0/MODULE.bazel": "b7e43e7414a3139a7547d1b4909b29085fbe5182b6c58cbe1ed4c6272815aeae", + "https://bcr.bazel.build/modules/rules_go/0.59.0/source.json": "1df17bb7865cfc029492c30163cee891d0dd8658ea0d5bfdf252c4b6db5c1ef6", + "https://bcr.bazel.build/modules/rules_java/4.0.0/MODULE.bazel": "5a78a7ae82cd1a33cef56dc578c7d2a46ed0dca12643ee45edbb8417899e6f74", + "https://bcr.bazel.build/modules/rules_java/5.3.5/MODULE.bazel": "a4ec4f2db570171e3e5eb753276ee4b389bae16b96207e9d3230895c99644b86", + "https://bcr.bazel.build/modules/rules_java/6.0.0/MODULE.bazel": "8a43b7df601a7ec1af61d79345c17b31ea1fedc6711fd4abfd013ea612978e39", + "https://bcr.bazel.build/modules/rules_java/6.3.0/MODULE.bazel": "a97c7678c19f236a956ad260d59c86e10a463badb7eb2eda787490f4c969b963", + "https://bcr.bazel.build/modules/rules_java/6.4.0/MODULE.bazel": "e986a9fe25aeaa84ac17ca093ef13a4637f6107375f64667a15999f77db6c8f6", + "https://bcr.bazel.build/modules/rules_java/6.5.2/MODULE.bazel": "1d440d262d0e08453fa0c4d8f699ba81609ed0e9a9a0f02cd10b3e7942e61e31", + "https://bcr.bazel.build/modules/rules_java/7.1.0/MODULE.bazel": "30d9135a2b6561c761bd67bd4990da591e6bdc128790ce3e7afd6a3558b2fb64", + "https://bcr.bazel.build/modules/rules_java/7.10.0/MODULE.bazel": "530c3beb3067e870561739f1144329a21c851ff771cd752a49e06e3dc9c2e71a", + "https://bcr.bazel.build/modules/rules_java/7.12.2/MODULE.bazel": "579c505165ee757a4280ef83cda0150eea193eed3bef50b1004ba88b99da6de6", + "https://bcr.bazel.build/modules/rules_java/7.2.0/MODULE.bazel": "06c0334c9be61e6cef2c8c84a7800cef502063269a5af25ceb100b192453d4ab", + "https://bcr.bazel.build/modules/rules_java/7.3.2/MODULE.bazel": "50dece891cfdf1741ea230d001aa9c14398062f2b7c066470accace78e412bc2", + "https://bcr.bazel.build/modules/rules_java/7.4.0/MODULE.bazel": "a592852f8a3dd539e82ee6542013bf2cadfc4c6946be8941e189d224500a8934", + "https://bcr.bazel.build/modules/rules_java/7.6.1/MODULE.bazel": "2f14b7e8a1aa2f67ae92bc69d1ec0fa8d9f827c4e17ff5e5f02e91caa3b2d0fe", + "https://bcr.bazel.build/modules/rules_java/8.13.0/MODULE.bazel": "0444ebf737d144cf2bb2ccb368e7f1cce735264285f2a3711785827c1686625e", + "https://bcr.bazel.build/modules/rules_java/8.15.2/MODULE.bazel": "5cc6698c822b2f9ef90ca5558599851bed8c3b13f1f8eb140d9bfec638d2acb4", + "https://bcr.bazel.build/modules/rules_java/8.3.2/MODULE.bazel": "7336d5511ad5af0b8615fdc7477535a2e4e723a357b6713af439fe8cf0195017", + "https://bcr.bazel.build/modules/rules_java/8.5.1/MODULE.bazel": "d8a9e38cc5228881f7055a6079f6f7821a073df3744d441978e7a43e20226939", + "https://bcr.bazel.build/modules/rules_java/8.6.0/MODULE.bazel": "9c064c434606d75a086f15ade5edb514308cccd1544c2b2a89bbac4310e41c71", + "https://bcr.bazel.build/modules/rules_java/8.6.1/MODULE.bazel": "f4808e2ab5b0197f094cabce9f4b006a27766beb6a9975931da07099560ca9c2", + "https://bcr.bazel.build/modules/rules_java/8.6.3/MODULE.bazel": "e90505b7a931d194245ffcfb6ff4ca8ef9d46b4e830d12e64817752e0198e2ed", + "https://bcr.bazel.build/modules/rules_java/8.9.0/MODULE.bazel": "e17c876cb53dcd817b7b7f0d2985b710610169729e8c371b2221cacdcd3dce4a", + "https://bcr.bazel.build/modules/rules_java/9.1.0/MODULE.bazel": "ee63f27e36a3fada80342869361182f120a9819c74320e8e65b1e04ba0cd7a9d", + "https://bcr.bazel.build/modules/rules_java/9.3.0/MODULE.bazel": "f657c72d65ac449caae9abf2e68e66c0d36f9416848c4c4903d0b3234229e7f2", + "https://bcr.bazel.build/modules/rules_java/9.3.0/source.json": "59ae7e662c3c7042b88bbb42ad12483523e234c65ebe4c51611baa43e85cb248", + "https://bcr.bazel.build/modules/rules_jvm_external/4.4.2/MODULE.bazel": "a56b85e418c83eb1839819f0b515c431010160383306d13ec21959ac412d2fe7", + "https://bcr.bazel.build/modules/rules_jvm_external/5.1/MODULE.bazel": "33f6f999e03183f7d088c9be518a63467dfd0be94a11d0055fe2d210f89aa909", + "https://bcr.bazel.build/modules/rules_jvm_external/5.2/MODULE.bazel": "d9351ba35217ad0de03816ef3ed63f89d411349353077348a45348b096615036", + "https://bcr.bazel.build/modules/rules_jvm_external/5.3/MODULE.bazel": "bf93870767689637164657731849fb887ad086739bd5d360d90007a581d5527d", + "https://bcr.bazel.build/modules/rules_jvm_external/6.1/MODULE.bazel": "75b5fec090dbd46cf9b7d8ea08cf84a0472d92ba3585b476f44c326eda8059c4", + "https://bcr.bazel.build/modules/rules_jvm_external/6.10/MODULE.bazel": "33e636ca6bc9ee0fa090a38aa33c631ded2d8cf6fead4124181d1b35dc474f7c", + "https://bcr.bazel.build/modules/rules_jvm_external/6.2/MODULE.bazel": "36a6e52487a855f33cb960724eb56547fa87e2c98a0474c3acad94339d7f8e99", + "https://bcr.bazel.build/modules/rules_jvm_external/6.3/MODULE.bazel": "c998e060b85f71e00de5ec552019347c8bca255062c990ac02d051bb80a38df0", + "https://bcr.bazel.build/modules/rules_jvm_external/6.6/MODULE.bazel": "153042249c7060536dc95b6bb9f9bb8063b8a0b0cb7acdb381bddbc2374aed55", + "https://bcr.bazel.build/modules/rules_jvm_external/6.7/MODULE.bazel": "e717beabc4d091ecb2c803c2d341b88590e9116b8bf7947915eeb33aab4f96dd", + "https://bcr.bazel.build/modules/rules_jvm_external/6.8/MODULE.bazel": "b5afe861e867e4c8e5b88e401cb7955bd35924258f97b1862cc966cbcf4f1a62", + "https://bcr.bazel.build/modules/rules_jvm_external/6.9/MODULE.bazel": "07c5db05527db7744a54fcffd653e1550d40e0540207a7f7e6d0a4de5bef8274", + "https://bcr.bazel.build/modules/rules_jvm_external/7.0/MODULE.bazel": "421482bdbcf05709f933c96b867a599deb517f2804ceb3e74511880610cfbf71", + "https://bcr.bazel.build/modules/rules_jvm_external/7.0/source.json": "714cd003eadf5be5c83268311fe8e951db39f802babeaddc536b3560dc8f6faf", + "https://bcr.bazel.build/modules/rules_kotlin/1.9.0/MODULE.bazel": "ef85697305025e5a61f395d4eaede272a5393cee479ace6686dba707de804d59", + "https://bcr.bazel.build/modules/rules_kotlin/1.9.5/MODULE.bazel": "043a16a572f610558ec2030db3ff0c9938574e7dd9f58bded1bb07c0192ef025", + "https://bcr.bazel.build/modules/rules_kotlin/1.9.6/MODULE.bazel": "d269a01a18ee74d0335450b10f62c9ed81f2321d7958a2934e44272fe82dcef3", + "https://bcr.bazel.build/modules/rules_kotlin/2.1.3/MODULE.bazel": "ce7def6d576aa8d3a9c6d10e13b4d157296229674371f67dbf788dae0afae3d5", + "https://bcr.bazel.build/modules/rules_kotlin/2.2.2/MODULE.bazel": "00d39c5e0fa78cd86193946265bb849e7878c24e44260f9525108428852b315c", + "https://bcr.bazel.build/modules/rules_kotlin/2.2.2/source.json": "7a32c2259c79ae0c9a036121f120de825e3ba5f0f3a209ffbbdccf4dc62489b9", + "https://bcr.bazel.build/modules/rules_license/0.0.3/MODULE.bazel": "627e9ab0247f7d1e05736b59dbb1b6871373de5ad31c3011880b4133cafd4bd0", + "https://bcr.bazel.build/modules/rules_license/0.0.7/MODULE.bazel": "088fbeb0b6a419005b89cf93fe62d9517c0a2b8bb56af3244af65ecfe37e7d5d", + "https://bcr.bazel.build/modules/rules_license/1.0.0/MODULE.bazel": "a7fda60eefdf3d8c827262ba499957e4df06f659330bbe6cdbdb975b768bb65c", + "https://bcr.bazel.build/modules/rules_license/1.0.0/source.json": "a52c89e54cc311196e478f8382df91c15f7a2bfdf4c6cd0e2675cc2ff0b56efb", + "https://bcr.bazel.build/modules/rules_oci/2.2.7/MODULE.bazel": "f6150e4b224d459f7f6523ef65967464ca4efdd266c7fbf2f5a2a51011957e0c", + "https://bcr.bazel.build/modules/rules_oci/2.2.7/source.json": "b099f02af330f47f19dc67fc9300ef6e1937a8c86882690db0e7a2fcea8c7f6b", + "https://bcr.bazel.build/modules/rules_pkg/0.7.0/MODULE.bazel": "df99f03fc7934a4737122518bb87e667e62d780b610910f0447665a7e2be62dc", + "https://bcr.bazel.build/modules/rules_pkg/1.0.1/MODULE.bazel": "5b1df97dbc29623bccdf2b0dcd0f5cb08e2f2c9050aab1092fd39a41e82686ff", + "https://bcr.bazel.build/modules/rules_pkg/1.2.0/MODULE.bazel": "c7db3c2b407e673c7a39e3625dc05dc9f12d6682cbd82a3a5924a13b491eda7e", + "https://bcr.bazel.build/modules/rules_pkg/1.2.0/source.json": "9062e00845bf91a4247465d371baa837adf9b6ff44c542f73ba084f07667e1dc", + "https://bcr.bazel.build/modules/rules_proto/4.0.0/MODULE.bazel": "a7a7b6ce9bee418c1a760b3d84f83a299ad6952f9903c67f19e4edd964894e06", + "https://bcr.bazel.build/modules/rules_proto/5.3.0-21.7/MODULE.bazel": "e8dff86b0971688790ae75528fe1813f71809b5afd57facb44dad9e8eca631b7", + "https://bcr.bazel.build/modules/rules_proto/6.0.0-rc1/MODULE.bazel": "1e5b502e2e1a9e825eef74476a5a1ee524a92297085015a052510b09a1a09483", + "https://bcr.bazel.build/modules/rules_proto/6.0.0/MODULE.bazel": "b531d7f09f58dce456cd61b4579ce8c86b38544da75184eadaf0a7cb7966453f", + "https://bcr.bazel.build/modules/rules_proto/6.0.2/MODULE.bazel": "ce916b775a62b90b61888052a416ccdda405212b6aaeb39522f7dc53431a5e73", + "https://bcr.bazel.build/modules/rules_proto/7.0.2/MODULE.bazel": "bf81793bd6d2ad89a37a40693e56c61b0ee30f7a7fdbaf3eabbf5f39de47dea2", + "https://bcr.bazel.build/modules/rules_proto/7.1.0/MODULE.bazel": "002d62d9108f75bb807cd56245d45648f38275cb3a99dcd45dfb864c5d74cb96", + "https://bcr.bazel.build/modules/rules_proto/7.1.0/source.json": "39f89066c12c24097854e8f57ab8558929f9c8d474d34b2c00ac04630ad8940e", + "https://bcr.bazel.build/modules/rules_proto_grpc/5.8.0/MODULE.bazel": "38e2acb9aa480a04c780fa4b11bfaae0fa16e05f85f6d8fc32e044bad683ed86", + "https://bcr.bazel.build/modules/rules_proto_grpc/5.8.0/source.json": "142d5c5dd650d0f817936835738daa7df2256dfb33c247163b600ab28cba31d1", + "https://bcr.bazel.build/modules/rules_proto_grpc_java/5.8.0/MODULE.bazel": "0e24d1d4716b017afa6c85649bee47144066310057fbce7bdb5661aecd525571", + "https://bcr.bazel.build/modules/rules_proto_grpc_java/5.8.0/source.json": "965a546920ecf67e8cbb9e060f35d7f87a6fcd4319db0cf47cbc66c30327b1ee", + "https://bcr.bazel.build/modules/rules_python/0.10.2/MODULE.bazel": "cc82bc96f2997baa545ab3ce73f196d040ffb8756fd2d66125a530031cd90e5f", + "https://bcr.bazel.build/modules/rules_python/0.23.1/MODULE.bazel": "49ffccf0511cb8414de28321f5fcf2a31312b47c40cc21577144b7447f2bf300", + "https://bcr.bazel.build/modules/rules_python/0.25.0/MODULE.bazel": "72f1506841c920a1afec76975b35312410eea3aa7b63267436bfb1dd91d2d382", + "https://bcr.bazel.build/modules/rules_python/0.28.0/MODULE.bazel": "cba2573d870babc976664a912539b320cbaa7114cd3e8f053c720171cde331ed", + "https://bcr.bazel.build/modules/rules_python/0.31.0/MODULE.bazel": "93a43dc47ee570e6ec9f5779b2e64c1476a6ce921c48cc9a1678a91dd5f8fd58", + "https://bcr.bazel.build/modules/rules_python/0.33.2/MODULE.bazel": "3e036c4ad8d804a4dad897d333d8dce200d943df4827cb849840055be8d2e937", + "https://bcr.bazel.build/modules/rules_python/0.37.1/MODULE.bazel": "3faeb2d9fa0a81f8980643ee33f212308f4d93eea4b9ce6f36d0b742e71e9500", + "https://bcr.bazel.build/modules/rules_python/0.37.2/MODULE.bazel": "b5ffde91410745750b6c13be1c5dc4555ef5bc50562af4a89fd77807fdde626a", + "https://bcr.bazel.build/modules/rules_python/0.4.0/MODULE.bazel": "9208ee05fd48bf09ac60ed269791cf17fb343db56c8226a720fbb1cdf467166c", + "https://bcr.bazel.build/modules/rules_python/1.0.0/MODULE.bazel": "898a3d999c22caa585eb062b600f88654bf92efb204fa346fb55f6f8edffca43", + "https://bcr.bazel.build/modules/rules_python/1.3.0/MODULE.bazel": "8361d57eafb67c09b75bf4bbe6be360e1b8f4f18118ab48037f2bd50aa2ccb13", + "https://bcr.bazel.build/modules/rules_python/1.4.1/MODULE.bazel": "8991ad45bdc25018301d6b7e1d3626afc3c8af8aaf4bc04f23d0b99c938b73a6", + "https://bcr.bazel.build/modules/rules_python/1.6.0/MODULE.bazel": "7e04ad8f8d5bea40451cf80b1bd8262552aa73f841415d20db96b7241bd027d8", + "https://bcr.bazel.build/modules/rules_python/1.7.0/MODULE.bazel": "d01f995ecd137abf30238ad9ce97f8fc3ac57289c8b24bd0bf53324d937a14f8", + "https://bcr.bazel.build/modules/rules_python/1.7.0/source.json": "028a084b65dcf8f4dc4f82f8778dbe65df133f234b316828a82e060d81bdce32", + "https://bcr.bazel.build/modules/rules_robolectric/4.14.1.2/MODULE.bazel": "d44fec647d0aeb67b9f3b980cf68ba634976f3ae7ccd6c07d790b59b87a4f251", + "https://bcr.bazel.build/modules/rules_robolectric/4.14.1.2/source.json": "37c10335f2361c337c5c1f34ed36d2da70534c23088062b33a8bdaab68aa9dea", + "https://bcr.bazel.build/modules/rules_rust/0.66.0/MODULE.bazel": "86ef763a582f4739a27029bdcc6c562258ed0ea6f8d58294b049e215ceb251b3", + "https://bcr.bazel.build/modules/rules_rust/0.66.0/source.json": "5c2252a61ccc19b4e420c7c06429c8f51d8edd7b743dcb4b60571e7d40b5aa57", + "https://bcr.bazel.build/modules/rules_shell/0.1.2/MODULE.bazel": "66e4ca3ce084b04af0b9ff05ff14cab4e5df7503973818bb91cbc6cda08d32fc", + "https://bcr.bazel.build/modules/rules_shell/0.2.0/MODULE.bazel": "fda8a652ab3c7d8fee214de05e7a9916d8b28082234e8d2c0094505c5268ed3c", + "https://bcr.bazel.build/modules/rules_shell/0.3.0/MODULE.bazel": "de4402cd12f4cc8fda2354fce179fdb068c0b9ca1ec2d2b17b3e21b24c1a937b", + "https://bcr.bazel.build/modules/rules_shell/0.4.0/MODULE.bazel": "0f8f11bb3cd11755f0b48c1de0bbcf62b4b34421023aa41a2fc74ef68d9584f0", + "https://bcr.bazel.build/modules/rules_shell/0.4.1/MODULE.bazel": "00e501db01bbf4e3e1dd1595959092c2fadf2087b2852d3f553b5370f5633592", + "https://bcr.bazel.build/modules/rules_shell/0.6.1/MODULE.bazel": "72e76b0eea4e81611ef5452aa82b3da34caca0c8b7b5c0c9584338aa93bae26b", + "https://bcr.bazel.build/modules/rules_shell/0.8.0/MODULE.bazel": "f6a89f1d6a669a26f28fe814503857055d76306b79cfc11d12399af08d0b80ae", + "https://bcr.bazel.build/modules/rules_shell/0.8.0/source.json": "eb53cc815bc503c6683c5fe12d943f98883f81fc22f51403ec8a95610cba4195", + "https://bcr.bazel.build/modules/rules_swift/1.16.0/MODULE.bazel": "4a09f199545a60d09895e8281362b1ff3bb08bbde69c6fc87aff5b92fcc916ca", + "https://bcr.bazel.build/modules/rules_swift/2.1.1/MODULE.bazel": "494900a80f944fc7aa61500c2073d9729dff0b764f0e89b824eb746959bc1046", + "https://bcr.bazel.build/modules/rules_swift/2.4.0/MODULE.bazel": "1639617eb1ede28d774d967a738b4a68b0accb40650beadb57c21846beab5efd", + "https://bcr.bazel.build/modules/rules_swift/3.1.2/MODULE.bazel": "72c8f5cf9d26427cee6c76c8e3853eb46ce6b0412a081b2b6db6e8ad56267400", + "https://bcr.bazel.build/modules/rules_swift/3.1.2/source.json": "e85761f3098a6faf40b8187695e3de6d97944e98abd0d8ce579cb2daf6319a66", + "https://bcr.bazel.build/modules/stardoc/0.5.1/MODULE.bazel": "1a05d92974d0c122f5ccf09291442580317cdd859f07a8655f1db9a60374f9f8", + "https://bcr.bazel.build/modules/stardoc/0.5.3/MODULE.bazel": "c7f6948dae6999bf0db32c1858ae345f112cacf98f174c7a8bb707e41b974f1c", + "https://bcr.bazel.build/modules/stardoc/0.5.4/MODULE.bazel": "6569966df04610b8520957cb8e97cf2e9faac2c0309657c537ab51c16c18a2a4", + "https://bcr.bazel.build/modules/stardoc/0.5.6/MODULE.bazel": "c43dabc564990eeab55e25ed61c07a1aadafe9ece96a4efabb3f8bf9063b71ef", + "https://bcr.bazel.build/modules/stardoc/0.6.2/MODULE.bazel": "7060193196395f5dd668eda046ccbeacebfd98efc77fed418dbe2b82ffaa39fd", + "https://bcr.bazel.build/modules/stardoc/0.7.0/MODULE.bazel": "05e3d6d30c099b6770e97da986c53bd31844d7f13d41412480ea265ac9e8079c", + "https://bcr.bazel.build/modules/stardoc/0.7.1/MODULE.bazel": "3548faea4ee5dda5580f9af150e79d0f6aea934fc60c1cc50f4efdd9420759e7", + "https://bcr.bazel.build/modules/stardoc/0.7.2/MODULE.bazel": "fc152419aa2ea0f51c29583fab1e8c99ddefd5b3778421845606ee628629e0e5", + "https://bcr.bazel.build/modules/stardoc/0.7.2/source.json": "58b029e5e901d6802967754adf0a9056747e8176f017cfe3607c0851f4d42216", + "https://bcr.bazel.build/modules/swift_argument_parser/1.3.1.1/MODULE.bazel": "5e463fbfba7b1701d957555ed45097d7f984211330106ccd1352c6e0af0dcf91", + "https://bcr.bazel.build/modules/swift_argument_parser/1.3.1.2/MODULE.bazel": "75aab2373a4bbe2a1260b9bf2a1ebbdbf872d3bd36f80bff058dccd82e89422f", + "https://bcr.bazel.build/modules/swift_argument_parser/1.3.1.2/source.json": "5fba48bbe0ba48761f9e9f75f92876cafb5d07c0ce059cc7a8027416de94a05b", + "https://bcr.bazel.build/modules/tar.bzl/0.2.1/MODULE.bazel": "52d1c00a80a8cc67acbd01649e83d8dd6a9dc426a6c0b754a04fe8c219c76468", + "https://bcr.bazel.build/modules/tar.bzl/0.5.1/MODULE.bazel": "7c2eb3dcfc53b0f3d6f9acdfd911ca803eaf92aadf54f8ca6e4c1f3aee288351", + "https://bcr.bazel.build/modules/tar.bzl/0.5.1/source.json": "deed3094f7cc779ed1d37a68403847b0e38d9dd9d931e03cb90825f3368b515f", + "https://bcr.bazel.build/modules/toml.bzl/0.3.0/MODULE.bazel": "5016e5dd1ad2200e119a4b28b2b3935e276c4b480f2fe3e952bea7eeba88f578", + "https://bcr.bazel.build/modules/toml.bzl/0.3.0/source.json": "0cf7c878c419b37ddb55f3dd93dd7c0c409bd7c4efacb3da504e0748780b2fa9", + "https://bcr.bazel.build/modules/toolchains_protoc/0.5.0/MODULE.bazel": "e649dcd74790d8b186517588c827a777dfa67acfc4cbd733721c4be143ea107f", + "https://bcr.bazel.build/modules/toolchains_protoc/0.6.1/MODULE.bazel": "377cbb438118f413c3361a1dd363da8a42077018473fcdc71a19c203aaf94b17", + "https://bcr.bazel.build/modules/toolchains_protoc/0.6.1/source.json": "b14b0b38c8309691bee7a0ab46113678b8675e04e8999294c58e68b036b8dbff", + "https://bcr.bazel.build/modules/upb/0.0.0-20220923-a547704/MODULE.bazel": "7298990c00040a0e2f121f6c32544bab27d4452f80d9ce51349b1a28f3005c43", + "https://bcr.bazel.build/modules/upb/0.0.0-20230516-61a97ef/MODULE.bazel": "c0df5e35ad55e264160417fd0875932ee3c9dda63d9fccace35ac62f45e1b6f9", + "https://bcr.bazel.build/modules/yq.bzl/0.1.1/MODULE.bazel": "9039681f9bcb8958ee2c87ffc74bdafba9f4369096a2b5634b88abc0eaefa072", + "https://bcr.bazel.build/modules/yq.bzl/0.1.1/source.json": "2d2bad780a9f2b9195a4a370314d2c17ae95eaa745cefc2e12fbc49759b15aa3", + "https://bcr.bazel.build/modules/zlib/1.2.11/MODULE.bazel": "07b389abc85fdbca459b69e2ec656ae5622873af3f845e1c9d80fe179f3effa0", + "https://bcr.bazel.build/modules/zlib/1.2.12/MODULE.bazel": "3b1a8834ada2a883674be8cbd36ede1b6ec481477ada359cd2d3ddc562340b27", + "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.5/MODULE.bazel": "eec517b5bbe5492629466e11dae908d043364302283de25581e3eb944326c4ca", + "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.5/source.json": "22bc55c47af97246cfc093d0acf683a7869377de362b5d1c552c2c2e16b7a806", + "https://bcr.bazel.build/modules/zlib/1.3.1/MODULE.bazel": "751c9940dcfe869f5f7274e1295422a34623555916eb98c174c1e945594bf198" + }, + "selectedYankedVersions": {}, + "moduleExtensions": { + "@@apple_rules_lint+//lint:extensions.bzl%linter": { + "general": { + "bzlTransitiveDigest": "g7izj5kLCmsajh8IospHh4ZQ35dyM0FIrA8D4HapAsM=", + "usagesDigest": "4RWlIKR/sSQ9MqPQRCROVLeGPbvTKmkbEpxkI3mbaCI=", + "recordedInputs": [], + "generatedRepoSpecs": { + "apple_linters": { + "repoRuleId": "@@apple_rules_lint+//lint/private:register_linters.bzl%register_linters", + "attributes": { + "linters": {} + } + } + } + } + }, + "@@rules_android+//rules/android_sdk_repository:rule.bzl%android_sdk_repository_extension": { + "general": { + "bzlTransitiveDigest": "+rMrzIrv7sImYmkbXJYv+gFpTJQ79X3MpwwMLI2A+oA=", + "usagesDigest": "iEGI2aNDMkHt9LXCdViLNUUOslpiVj2DrevWWXZEFnU=", + "recordedInputs": [], + "generatedRepoSpecs": { + "androidsdk": { + "repoRuleId": "@@rules_android+//rules/android_sdk_repository:rule.bzl%_android_sdk_repository", + "attributes": {} + } + } + } + }, + "@@rules_oci+//oci:extensions.bzl%oci": { + "general": { + "bzlTransitiveDigest": "x9tW7bULjt2O48GRYAc+uOtpAZMGSBvKch9MgZbvG/w=", + "usagesDigest": "YV/my4HWfeIYZH762GR/gbfyrtmoU6x5X9/fNcX4Ioo=", + "recordedInputs": [ + "REPO_MAPPING:aspect_bazel_lib+,bazel_tools bazel_tools", + "REPO_MAPPING:bazel_features+,bazel_tools bazel_tools", + "REPO_MAPPING:rules_oci+,aspect_bazel_lib aspect_bazel_lib+", + "REPO_MAPPING:rules_oci+,bazel_features bazel_features+", + "REPO_MAPPING:rules_oci+,bazel_skylib bazel_skylib+" + ], + "generatedRepoSpecs": { + "temurin_jre_linux_arm64_v8": { + "repoRuleId": "@@rules_oci+//oci/private:pull.bzl%oci_pull", + "attributes": { + "www_authenticate_challenges": {}, + "scheme": "https", + "registry": "public.ecr.aws", + "repository": "docker/library/eclipse-temurin", + "identifier": "21-jre", + "platform": "linux/arm64/v8", + "target_name": "temurin_jre_linux_arm64_v8", + "bazel_tags": [] + } + }, + "temurin_jre_linux_amd64": { + "repoRuleId": "@@rules_oci+//oci/private:pull.bzl%oci_pull", + "attributes": { + "www_authenticate_challenges": {}, + "scheme": "https", + "registry": "public.ecr.aws", + "repository": "docker/library/eclipse-temurin", + "identifier": "21-jre", + "platform": "linux/amd64", + "target_name": "temurin_jre_linux_amd64", + "bazel_tags": [] + } + }, + "temurin_jre": { + "repoRuleId": "@@rules_oci+//oci/private:pull.bzl%oci_alias", + "attributes": { + "target_name": "temurin_jre", + "www_authenticate_challenges": {}, + "scheme": "https", + "registry": "public.ecr.aws", + "repository": "docker/library/eclipse-temurin", + "identifier": "21-jre", + "platforms": { + "@@platforms//cpu:arm64": "@temurin_jre_linux_arm64_v8", + "@@platforms//cpu:x86_64": "@temurin_jre_linux_amd64" + }, + "bzlmod_repository": "temurin_jre", + "reproducible": true + } + }, + "ubuntu_noble_linux_arm64_v8": { + "repoRuleId": "@@rules_oci+//oci/private:pull.bzl%oci_pull", + "attributes": { + "www_authenticate_challenges": {}, + "scheme": "https", + "registry": "public.ecr.aws", + "repository": "ubuntu/ubuntu", + "identifier": "sha256:ef59d9e82939bbce08973bdffb8761b025f75369fb7d2882cdc4938b5a9e992e", + "platform": "linux/arm64/v8", + "target_name": "ubuntu_noble_linux_arm64_v8", + "bazel_tags": [] + } + }, + "ubuntu_noble_linux_amd64": { + "repoRuleId": "@@rules_oci+//oci/private:pull.bzl%oci_pull", + "attributes": { + "www_authenticate_challenges": {}, + "scheme": "https", + "registry": "public.ecr.aws", + "repository": "ubuntu/ubuntu", + "identifier": "sha256:ef59d9e82939bbce08973bdffb8761b025f75369fb7d2882cdc4938b5a9e992e", + "platform": "linux/amd64", + "target_name": "ubuntu_noble_linux_amd64", + "bazel_tags": [] + } + }, + "ubuntu_noble": { + "repoRuleId": "@@rules_oci+//oci/private:pull.bzl%oci_alias", + "attributes": { + "target_name": "ubuntu_noble", + "www_authenticate_challenges": {}, + "scheme": "https", + "registry": "public.ecr.aws", + "repository": "ubuntu/ubuntu", + "identifier": "sha256:ef59d9e82939bbce08973bdffb8761b025f75369fb7d2882cdc4938b5a9e992e", + "platforms": { + "@@platforms//cpu:arm64": "@ubuntu_noble_linux_arm64_v8", + "@@platforms//cpu:x86_64": "@ubuntu_noble_linux_amd64" + }, + "bzlmod_repository": "ubuntu_noble", + "reproducible": true + } + }, + "oci_crane_darwin_amd64": { + "repoRuleId": "@@rules_oci+//oci:repositories.bzl%crane_repositories", + "attributes": { + "platform": "darwin_amd64", + "crane_version": "v0.18.0" + } + }, + "oci_crane_darwin_arm64": { + "repoRuleId": "@@rules_oci+//oci:repositories.bzl%crane_repositories", + "attributes": { + "platform": "darwin_arm64", + "crane_version": "v0.18.0" + } + }, + "oci_crane_linux_arm64": { + "repoRuleId": "@@rules_oci+//oci:repositories.bzl%crane_repositories", + "attributes": { + "platform": "linux_arm64", + "crane_version": "v0.18.0" + } + }, + "oci_crane_linux_armv6": { + "repoRuleId": "@@rules_oci+//oci:repositories.bzl%crane_repositories", + "attributes": { + "platform": "linux_armv6", + "crane_version": "v0.18.0" + } + }, + "oci_crane_linux_i386": { + "repoRuleId": "@@rules_oci+//oci:repositories.bzl%crane_repositories", + "attributes": { + "platform": "linux_i386", + "crane_version": "v0.18.0" + } + }, + "oci_crane_linux_s390x": { + "repoRuleId": "@@rules_oci+//oci:repositories.bzl%crane_repositories", + "attributes": { + "platform": "linux_s390x", + "crane_version": "v0.18.0" + } + }, + "oci_crane_linux_amd64": { + "repoRuleId": "@@rules_oci+//oci:repositories.bzl%crane_repositories", + "attributes": { + "platform": "linux_amd64", + "crane_version": "v0.18.0" + } + }, + "oci_crane_windows_armv6": { + "repoRuleId": "@@rules_oci+//oci:repositories.bzl%crane_repositories", + "attributes": { + "platform": "windows_armv6", + "crane_version": "v0.18.0" + } + }, + "oci_crane_windows_amd64": { + "repoRuleId": "@@rules_oci+//oci:repositories.bzl%crane_repositories", + "attributes": { + "platform": "windows_amd64", + "crane_version": "v0.18.0" + } + }, + "oci_crane_toolchains": { + "repoRuleId": "@@rules_oci+//oci/private:toolchains_repo.bzl%toolchains_repo", + "attributes": { + "toolchain_type": "@rules_oci//oci:crane_toolchain_type", + "toolchain": "@oci_crane_{platform}//:crane_toolchain" + } + }, + "oci_regctl_darwin_amd64": { + "repoRuleId": "@@rules_oci+//oci:repositories.bzl%regctl_repositories", + "attributes": { + "platform": "darwin_amd64" + } + }, + "oci_regctl_darwin_arm64": { + "repoRuleId": "@@rules_oci+//oci:repositories.bzl%regctl_repositories", + "attributes": { + "platform": "darwin_arm64" + } + }, + "oci_regctl_linux_arm64": { + "repoRuleId": "@@rules_oci+//oci:repositories.bzl%regctl_repositories", + "attributes": { + "platform": "linux_arm64" + } + }, + "oci_regctl_linux_s390x": { + "repoRuleId": "@@rules_oci+//oci:repositories.bzl%regctl_repositories", + "attributes": { + "platform": "linux_s390x" + } + }, + "oci_regctl_linux_amd64": { + "repoRuleId": "@@rules_oci+//oci:repositories.bzl%regctl_repositories", + "attributes": { + "platform": "linux_amd64" + } + }, + "oci_regctl_windows_amd64": { + "repoRuleId": "@@rules_oci+//oci:repositories.bzl%regctl_repositories", + "attributes": { + "platform": "windows_amd64" + } + }, + "oci_regctl_toolchains": { + "repoRuleId": "@@rules_oci+//oci/private:toolchains_repo.bzl%toolchains_repo", + "attributes": { + "toolchain_type": "@rules_oci//oci:regctl_toolchain_type", + "toolchain": "@oci_regctl_{platform}//:regctl_toolchain" + } + } + }, + "moduleExtensionMetadata": { + "explicitRootModuleDirectDeps": [], + "explicitRootModuleDirectDevDeps": [], + "useAllRepos": "NO", + "reproducible": false + } + } + }, + "@@rules_python+//python/extensions:config.bzl%config": { + "general": { + "bzlTransitiveDigest": "dzD8Q2YmrP3fz8saWLHPmlwPLO91ImtTmP/c9JKTStM=", + "usagesDigest": "ZVSXMAGpD+xzVNPuvF1IoLBkty7TROO0+akMapt1pAg=", + "recordedInputs": [ + "REPO_MAPPING:rules_python+,bazel_tools bazel_tools", + "REPO_MAPPING:rules_python+,pypi__build rules_python++config+pypi__build", + "REPO_MAPPING:rules_python+,pypi__click rules_python++config+pypi__click", + "REPO_MAPPING:rules_python+,pypi__colorama rules_python++config+pypi__colorama", + "REPO_MAPPING:rules_python+,pypi__importlib_metadata rules_python++config+pypi__importlib_metadata", + "REPO_MAPPING:rules_python+,pypi__installer rules_python++config+pypi__installer", + "REPO_MAPPING:rules_python+,pypi__more_itertools rules_python++config+pypi__more_itertools", + "REPO_MAPPING:rules_python+,pypi__packaging rules_python++config+pypi__packaging", + "REPO_MAPPING:rules_python+,pypi__pep517 rules_python++config+pypi__pep517", + "REPO_MAPPING:rules_python+,pypi__pip rules_python++config+pypi__pip", + "REPO_MAPPING:rules_python+,pypi__pip_tools rules_python++config+pypi__pip_tools", + "REPO_MAPPING:rules_python+,pypi__pyproject_hooks rules_python++config+pypi__pyproject_hooks", + "REPO_MAPPING:rules_python+,pypi__setuptools rules_python++config+pypi__setuptools", + "REPO_MAPPING:rules_python+,pypi__tomli rules_python++config+pypi__tomli", + "REPO_MAPPING:rules_python+,pypi__wheel rules_python++config+pypi__wheel", + "REPO_MAPPING:rules_python+,pypi__zipp rules_python++config+pypi__zipp" + ], + "generatedRepoSpecs": { + "rules_python_internal": { + "repoRuleId": "@@rules_python+//python/private:internal_config_repo.bzl%internal_config_repo", + "attributes": { + "transition_setting_generators": {}, + "transition_settings": [] + } + }, + "pypi__build": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/e2/03/f3c8ba0a6b6e30d7d18c40faab90807c9bb5e9a1e3b2fe2008af624a9c97/build-1.2.1-py3-none-any.whl", + "sha256": "75e10f767a433d9a86e50d83f418e83efc18ede923ee5ff7df93b6cb0306c5d4", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__click": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/00/2e/d53fa4befbf2cfa713304affc7ca780ce4fc1fd8710527771b58311a3229/click-8.1.7-py3-none-any.whl", + "sha256": "ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__colorama": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", + "sha256": "4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__importlib_metadata": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/2d/0a/679461c511447ffaf176567d5c496d1de27cbe34a87df6677d7171b2fbd4/importlib_metadata-7.1.0-py3-none-any.whl", + "sha256": "30962b96c0c223483ed6cc7280e7f0199feb01a0e40cfae4d4450fc6fab1f570", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__installer": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/e5/ca/1172b6638d52f2d6caa2dd262ec4c811ba59eee96d54a7701930726bce18/installer-0.7.0-py3-none-any.whl", + "sha256": "05d1933f0a5ba7d8d6296bb6d5018e7c94fa473ceb10cf198a92ccea19c27b53", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__more_itertools": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/50/e2/8e10e465ee3987bb7c9ab69efb91d867d93959095f4807db102d07995d94/more_itertools-10.2.0-py3-none-any.whl", + "sha256": "686b06abe565edfab151cb8fd385a05651e1fdf8f0a14191e4439283421f8684", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__packaging": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/49/df/1fceb2f8900f8639e278b056416d49134fb8d84c5942ffaa01ad34782422/packaging-24.0-py3-none-any.whl", + "sha256": "2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__pep517": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/25/6e/ca4a5434eb0e502210f591b97537d322546e4833dcb4d470a48c375c5540/pep517-0.13.1-py3-none-any.whl", + "sha256": "31b206f67165b3536dd577c5c3f1518e8fbaf38cbc57efff8369a392feff1721", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__pip": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/8a/6a/19e9fe04fca059ccf770861c7d5721ab4c2aebc539889e97c7977528a53b/pip-24.0-py3-none-any.whl", + "sha256": "ba0d021a166865d2265246961bec0152ff124de910c5cc39f1156ce3fa7c69dc", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__pip_tools": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/0d/dc/38f4ce065e92c66f058ea7a368a9c5de4e702272b479c0992059f7693941/pip_tools-7.4.1-py3-none-any.whl", + "sha256": "4c690e5fbae2f21e87843e89c26191f0d9454f362d8acdbd695716493ec8b3a9", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__pyproject_hooks": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/ae/f3/431b9d5fe7d14af7a32340792ef43b8a714e7726f1d7b69cc4e8e7a3f1d7/pyproject_hooks-1.1.0-py3-none-any.whl", + "sha256": "7ceeefe9aec63a1064c18d939bdc3adf2d8aa1988a510afec15151578b232aa2", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__setuptools": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/90/99/158ad0609729111163fc1f674a5a42f2605371a4cf036d0441070e2f7455/setuptools-78.1.1-py3-none-any.whl", + "sha256": "c3a9c4211ff4c309edb8b8c4f1cbfa7ae324c4ba9f91ff254e3d305b9fd54561", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__tomli": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/97/75/10a9ebee3fd790d20926a90a2547f0bf78f371b2f13aa822c759680ca7b9/tomli-2.0.1-py3-none-any.whl", + "sha256": "939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__wheel": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/7d/cd/d7460c9a869b16c3dd4e1e403cce337df165368c71d6af229a74699622ce/wheel-0.43.0-py3-none-any.whl", + "sha256": "55c570405f142630c6b9f72fe09d9b67cf1477fcf543ae5b8dcb1f5b7377da81", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__zipp": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/da/55/a03fd7240714916507e1fcf7ae355bd9d9ed2e6db492595f1a67f61681be/zipp-3.18.2-py3-none-any.whl", + "sha256": "dce197b859eb796242b0622af1b8beb0a722d52aa2f57133ead08edd5bf5374e", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + } + } + } + }, + "@@rules_python+//python/uv:uv.bzl%uv": { + "general": { + "bzlTransitiveDigest": "ijW9KS7qsIY+yBVvJ+Nr1mzwQox09j13DnE3iIwaeTM=", + "usagesDigest": "H8dQoNZcoqP+Mu0tHZTi4KHATzvNkM5ePuEqoQdklIU=", + "recordedInputs": [ + "REPO_MAPPING:rules_python+,bazel_tools bazel_tools", + "REPO_MAPPING:rules_python+,platforms platforms" + ], + "generatedRepoSpecs": { + "uv": { + "repoRuleId": "@@rules_python+//python/uv/private:uv_toolchains_repo.bzl%uv_toolchains_repo", + "attributes": { + "toolchain_type": "'@@rules_python+//python/uv:uv_toolchain_type'", + "toolchain_names": [ + "none" + ], + "toolchain_implementations": { + "none": "'@@rules_python+//python:none'" + }, + "toolchain_compatible_with": { + "none": [ + "@platforms//:incompatible" + ] + }, + "toolchain_target_settings": {} + } + } + } + } + }, + "@@tar.bzl+//tar:extensions.bzl%toolchains": { + "general": { + "bzlTransitiveDigest": "/2afh6fPjq/rcyE/jztQDK3ierehmFFngfvmqyRv72M=", + "usagesDigest": "maF8qsAIqeH1ey8pxP0gNZbvJt34kLZvTFeQ0ntrJVA=", + "recordedInputs": [], + "generatedRepoSpecs": { + "bsd_tar_toolchains": { + "repoRuleId": "@@tar.bzl+//tar/toolchain:toolchain.bzl%tar_toolchains_repo", + "attributes": { + "user_repository_name": "bsd_tar_toolchains" + } + }, + "bsd_tar_toolchains_darwin_amd64": { + "repoRuleId": "@@tar.bzl+//tar/toolchain:platforms.bzl%bsdtar_binary_repo", + "attributes": { + "platform": "darwin_amd64" + } + }, + "bsd_tar_toolchains_darwin_arm64": { + "repoRuleId": "@@tar.bzl+//tar/toolchain:platforms.bzl%bsdtar_binary_repo", + "attributes": { + "platform": "darwin_arm64" + } + }, + "bsd_tar_toolchains_linux_amd64": { + "repoRuleId": "@@tar.bzl+//tar/toolchain:platforms.bzl%bsdtar_binary_repo", + "attributes": { + "platform": "linux_amd64" + } + }, + "bsd_tar_toolchains_linux_arm64": { + "repoRuleId": "@@tar.bzl+//tar/toolchain:platforms.bzl%bsdtar_binary_repo", + "attributes": { + "platform": "linux_arm64" + } + }, + "bsd_tar_toolchains_windows_amd64": { + "repoRuleId": "@@tar.bzl+//tar/toolchain:platforms.bzl%bsdtar_binary_repo", + "attributes": { + "platform": "windows_amd64" + } + }, + "bsd_tar_toolchains_windows_arm64": { + "repoRuleId": "@@tar.bzl+//tar/toolchain:platforms.bzl%bsdtar_binary_repo", + "attributes": { + "platform": "windows_arm64" + } + } + } + } + } + }, + "facts": { + "@@rules_go+//go:extensions.bzl%go_sdk": { + "1.22.4": { + "aix_ppc64": [ + "go1.22.4.aix-ppc64.tar.gz", + "b9647fa9fc83a0cc5d4f092a19eaeaecf45f063a5aa7d4962fde65aeb7ae6ce1" + ], + "darwin_amd64": [ + "go1.22.4.darwin-amd64.tar.gz", + "c95967f50aa4ace34af0c236cbdb49a9a3e80ee2ad09d85775cb4462a5c19ed3" + ], + "darwin_arm64": [ + "go1.22.4.darwin-arm64.tar.gz", + "242b78dc4c8f3d5435d28a0d2cec9b4c1aa999b601fb8aa59fb4e5a1364bf827" + ], + "dragonfly_amd64": [ + "go1.22.4.dragonfly-amd64.tar.gz", + "f2fbb51af4719d3616efb482d6ed2b96579b474156f85a7ddc6f126764feec4b" + ], + "freebsd_386": [ + "go1.22.4.freebsd-386.tar.gz", + "7c54884bb9f274884651d41e61d1bc12738863ad1497e97ea19ad0e9aa6bf7b5" + ], + "freebsd_amd64": [ + "go1.22.4.freebsd-amd64.tar.gz", + "88d44500e1701dd35797619774d6dd51bf60f45a8338b0a82ddc018e4e63fb78" + ], + "freebsd_arm64": [ + "go1.22.4.freebsd-arm64.tar.gz", + "726dc093cf020277be45debf03c3b02b43c2efb3e2a5d4fba8f52579d65327dc" + ], + "freebsd_armv6l": [ + "go1.22.4.freebsd-arm.tar.gz", + "3d9efe47db142a22679aba46b1772e3900b0d87ae13bd2b3bc80dbf2ac0b2cd6" + ], + "freebsd_riscv64": [ + "go1.22.4.freebsd-riscv64.tar.gz", + "5f6b67e5e32f1d6ccb2d4dcb44934a5e2e870a877ba7443d86ec43cfc28afa71" + ], + "illumos_amd64": [ + "go1.22.4.illumos-amd64.tar.gz", + "d56ecc2f85b6418a21ef83879594d0c42ab4f65391a676bb12254870e6690d63" + ], + "linux_386": [ + "go1.22.4.linux-386.tar.gz", + "47a2a8d249a91eb8605c33bceec63aedda0441a43eac47b4721e3975ff916cec" + ], + "linux_amd64": [ + "go1.22.4.linux-amd64.tar.gz", + "ba79d4526102575196273416239cca418a651e049c2b099f3159db85e7bade7d" + ], + "linux_arm64": [ + "go1.22.4.linux-arm64.tar.gz", + "a8e177c354d2e4a1b61020aca3562e27ea3e8f8247eca3170e3fa1e0c2f9e771" + ], + "linux_armv6l": [ + "go1.22.4.linux-armv6l.tar.gz", + "e2b143fbacbc9cbd448e9ef41ac3981f0488ce849af1cf37e2341d09670661de" + ], + "linux_loong64": [ + "go1.22.4.linux-loong64.tar.gz", + "e2ff9436e4b34bf6926b06d97916e26d67a909a2effec17967245900f0816f1d" + ], + "linux_mips": [ + "go1.22.4.linux-mips.tar.gz", + "73f0dcc60458c4770593b05a7bc01cc0d31fc98f948c0c2334812c7a1f2fc3f1" + ], + "linux_mips64": [ + "go1.22.4.linux-mips64.tar.gz", + "417af97fc2630a647052375768be4c38adcc5af946352ea5b28613ea81ca5d45" + ], + "linux_mips64le": [ + "go1.22.4.linux-mips64le.tar.gz", + "7486e2d7dd8c98eb44df815ace35a7fe7f30b7c02326e3741bd934077508139b" + ], + "linux_mipsle": [ + "go1.22.4.linux-mipsle.tar.gz", + "69479c8aad301e459a8365b40cad1074a0dbba5defb9291669f94809c4c4be6e" + ], + "linux_ppc64": [ + "go1.22.4.linux-ppc64.tar.gz", + "dd238847e65bc3e2745caca475a5db6522a2fcf85cf6c38fc36a06642b19efd7" + ], + "linux_ppc64le": [ + "go1.22.4.linux-ppc64le.tar.gz", + "a3e5834657ef92523f570f798fed42f1f87bc18222a16815ec76b84169649ec4" + ], + "linux_riscv64": [ + "go1.22.4.linux-riscv64.tar.gz", + "56a827ff7dc6245bcd7a1e9288dffaa1d8b0fd7468562264c1523daf3b4f1b4a" + ], + "linux_s390x": [ + "go1.22.4.linux-s390x.tar.gz", + "7590c3e278e2dc6040aae0a39da3ca1eb2e3921673a7304cc34d588c45889eec" + ], + "netbsd_386": [ + "go1.22.4.netbsd-386.tar.gz", + "ddd2eebe34471a2502de6c5dad04ab27c9fc80cbde7a9ad5b3c66ecec4504e1d" + ], + "netbsd_amd64": [ + "go1.22.4.netbsd-amd64.tar.gz", + "33af79f6f935f6fbacc5d23876450b3567b79348fc065beef8e64081127dd234" + ], + "netbsd_arm64": [ + "go1.22.4.netbsd-arm64.tar.gz", + "c9a2971dec9f6d320c6f2b049b2353c6d0a2d35e87b8a4b2d78a2f0d62545f8e" + ], + "netbsd_armv6l": [ + "go1.22.4.netbsd-arm.tar.gz", + "fa3550ebd5375a70b3bcd342b5a71f4bd271dcbbfaf4eabefa2144ab5d8924b6" + ], + "openbsd_386": [ + "go1.22.4.openbsd-386.tar.gz", + "d21af022331bfdc2b5b161d616c3a1a4573d33cf7a30416ee509a8f3641deb47" + ], + "openbsd_amd64": [ + "go1.22.4.openbsd-amd64.tar.gz", + "72c0094c43f7e5722ec49c2a3e9dfa7a1123ac43a5f3a63eecf3e3795d3ff0ae" + ], + "openbsd_arm64": [ + "go1.22.4.openbsd-arm64.tar.gz", + "a7ab8d4e0b02bf06ed144ba42c61c0e93ee00f2b433415dfd4ad4b6e79f31650" + ], + "openbsd_armv6l": [ + "go1.22.4.openbsd-arm.tar.gz", + "1096831ea3c5ea3ca57d14251d9eda3786889531eb40d7d6775dcaa324d4b065" + ], + "openbsd_ppc64": [ + "go1.22.4.openbsd-ppc64.tar.gz", + "9716327c8a628358798898dc5148c49dbbeb5196bf2cbf088e550721a6e4f60b" + ], + "plan9_386": [ + "go1.22.4.plan9-386.tar.gz", + "a8dd4503c95c32a502a616ab78870a19889c9325fe9bd31eb16dd69346e4bfa8" + ], + "plan9_amd64": [ + "go1.22.4.plan9-amd64.tar.gz", + "5423a25808d76fe5aca8607a2e5ac5673abf45446b168cb5e9d8519ee9fe39a1" + ], + "plan9_armv6l": [ + "go1.22.4.plan9-arm.tar.gz", + "6af939ad583f5c85c09c53728ab7d38c3cc2b39167562d6c18a07c5c6608b370" + ], + "solaris_amd64": [ + "go1.22.4.solaris-amd64.tar.gz", + "e8cabe69c03085725afdb32a6f9998191a3e55a747b270d835fd05000d56abba" + ], + "windows_386": [ + "go1.22.4.windows-386.zip", + "aca4e2c37278a10f1c70dd0df142f7d66b50334fcee48978d409202d308d6d25" + ], + "windows_amd64": [ + "go1.22.4.windows-amd64.zip", + "26321c4d945a0035d8a5bc4a1965b0df401ff8ceac66ce2daadabf9030419a98" + ], + "windows_arm64": [ + "go1.22.4.windows-arm64.zip", + "8a2daa9ea28cbdafddc6171aefed384f4e5b6e714fb52116fe9ed25a132f37ed" + ], + "windows_armv6l": [ + "go1.22.4.windows-arm.zip", + "5fcd0671a49cecf39b41021621ee1b6e7aa1370f37122b72e80d4fd4185833b6" + ] + }, + "1.23.6": { + "aix_ppc64": [ + "go1.23.6.aix-ppc64.tar.gz", + "adec10f4ba56591f523aa04851f7f6900b1c61508dfa6b80e62717a8e6684a5c" + ], + "darwin_amd64": [ + "go1.23.6.darwin-amd64.tar.gz", + "782da50ce8ec5e98fac2cd3cdc6a1d7130d093294fc310038f651444232a3fb0" + ], + "darwin_arm64": [ + "go1.23.6.darwin-arm64.tar.gz", + "5cae2450a1708aeb0333237a155640d5562abaf195defebc4306054565536221" + ], + "dragonfly_amd64": [ + "go1.23.6.dragonfly-amd64.tar.gz", + "d52efb3020d9332477ade98163c03d2f2fe3e051b0e7e01f0e167412c66de0cb" + ], + "freebsd_386": [ + "go1.23.6.freebsd-386.tar.gz", + "d3287706b5823712ac6cf7dff684a556cff98163ef60e7b275abe3388c17aac7" + ], + "freebsd_amd64": [ + "go1.23.6.freebsd-amd64.tar.gz", + "ebb4c6a9b0673dbdabc439877779ed6add16575e21bd0a7955c33f692789aef6" + ], + "freebsd_arm": [ + "go1.23.6.freebsd-arm.tar.gz", + "b7241584afb0b161c09148f8fde16171bb743e47b99d451fbc5f5217ec7a88b6" + ], + "freebsd_arm64": [ + "go1.23.6.freebsd-arm64.tar.gz", + "004718b53cedd7955d1b1dc4053539fcd1053c031f5f3374334a22befd1f8310" + ], + "freebsd_riscv64": [ + "go1.23.6.freebsd-riscv64.tar.gz", + "ca026ec8a30dd0c18164f40e1ce21bd725e2445f11699177d05815189a38de7a" + ], + "illumos_amd64": [ + "go1.23.6.illumos-amd64.tar.gz", + "7db973efa3fb2e48e45059b855721550fce8e90803e7373d3efd37b88dd821e8" + ], + "linux_386": [ + "go1.23.6.linux-386.tar.gz", + "e61f87693169c0bbcc43363128f1e929b9dff0b7f448573f1bdd4e4a0b9687ba" + ], + "linux_amd64": [ + "go1.23.6.linux-amd64.tar.gz", + "9379441ea310de000f33a4dc767bd966e72ab2826270e038e78b2c53c2e7802d" + ], + "linux_arm64": [ + "go1.23.6.linux-arm64.tar.gz", + "561c780e8f4a8955d32bf72e46af0b5ee5e0debe1e4633df9a03781878219202" + ], + "linux_armv6l": [ + "go1.23.6.linux-armv6l.tar.gz", + "27a4611010c16b8c4f37ade3aada55bd5781998f02f348b164302fd5eea4eb74" + ], + "linux_loong64": [ + "go1.23.6.linux-loong64.tar.gz", + "c459226424372abc2b35957cc8955dad348330714f7605093325dbb73e33c750" + ], + "linux_mips": [ + "go1.23.6.linux-mips.tar.gz", + "e2a0aff70b958a3463a7d47132a2d0238369f64578d4f7f95e679e3a5af05622" + ], + "linux_mips64": [ + "go1.23.6.linux-mips64.tar.gz", + "7d30ec7db056311d420bf930c16abcae13c0f41c26a202868f279721ec3c2f2f" + ], + "linux_mips64le": [ + "go1.23.6.linux-mips64le.tar.gz", + "74ca7bc475bcc084c6718b74df024d7de9612932cea8a6dc75e29d3a5315a23a" + ], + "linux_mipsle": [ + "go1.23.6.linux-mipsle.tar.gz", + "09bf935a14e9f59a20499989438b1655453480016bdbcb10406acf4df2678ccb" + ], + "linux_ppc64": [ + "go1.23.6.linux-ppc64.tar.gz", + "5cb2f6a5090276c72c5eda8a55896f5a3d6ea0f28d10fa1a50e8318640f02d6c" + ], + "linux_ppc64le": [ + "go1.23.6.linux-ppc64le.tar.gz", + "0f817201e83d78ddbfa27f5f78d9b72450b92cc21d5e045145efacd0d3244a99" + ], + "linux_riscv64": [ + "go1.23.6.linux-riscv64.tar.gz", + "f95f7f817ab22ecab4503d0704d6449ea1aa26a595f57bf9b9f94ddf2aa7c1f3" + ], + "linux_s390x": [ + "go1.23.6.linux-s390x.tar.gz", + "321e7ed0d5416f731479c52fa7610b52b8079a8061967bd48cec6d66f671a60e" + ], + "netbsd_386": [ + "go1.23.6.netbsd-386.tar.gz", + "92d678fb8e1eeeb8c6af6f22e4e5494652dcbb4a320113fc08325cb9956a2d4c" + ], + "netbsd_amd64": [ + "go1.23.6.netbsd-amd64.tar.gz", + "86ba51e7bb26b30ea6a8d88ddb79d8e8c83b4116200040ecb7a5a44cf90a8c5c" + ], + "netbsd_arm": [ + "go1.23.6.netbsd-arm.tar.gz", + "4b974c35345100f0be6ea66afab2781de91ee9882117314126eaf0ae90fd3816" + ], + "netbsd_arm64": [ + "go1.23.6.netbsd-arm64.tar.gz", + "53e3589fc38e787a493ea038961f8e40803714dbb42754c1713b00099c12e9b9" + ], + "openbsd_386": [ + "go1.23.6.openbsd-386.tar.gz", + "6d2317b3a8505ccebff8f72d943f2ac9b82c115632e54a53a786eff24ced56d9" + ], + "openbsd_amd64": [ + "go1.23.6.openbsd-amd64.tar.gz", + "f699e707d95a984fcc00361d91aecdb413d3c75e18235156ffba7a89edf68aae" + ], + "openbsd_arm": [ + "go1.23.6.openbsd-arm.tar.gz", + "3c1cf6ab893657d0bf1942e40ce115acfd27cbce1ccb9bc88fd9cd21ca3d489f" + ], + "openbsd_arm64": [ + "go1.23.6.openbsd-arm64.tar.gz", + "cc0875535d14001f2da23ae9af89025b28c466e8f4f4c63f991ebb6f4b02f66c" + ], + "openbsd_ppc64": [ + "go1.23.6.openbsd-ppc64.tar.gz", + "64de80e29ca66cb566cbf8be030bf8599953af4e48402eab724cbe0a08b40602" + ], + "openbsd_riscv64": [ + "go1.23.6.openbsd-riscv64.tar.gz", + "c398a6b43c569f34bb4a2d16b52f8010eaac9a2a82ecac0602b4338e35cef377" + ], + "plan9_386": [ + "go1.23.6.plan9-386.tar.gz", + "10998b6b130bb7b542b407f0db42b86a913b111f8fa86d44394beaace4d45f01" + ], + "plan9_amd64": [ + "go1.23.6.plan9-amd64.tar.gz", + "9fbe8065436d8d12c02f19f64f51c9107da3a7a4ac46ab5777e182e9fe88c32f" + ], + "plan9_arm": [ + "go1.23.6.plan9-arm.tar.gz", + "8e3c826b884daee2de37e3b070d7eac4cea5d68edab8db09910e22201c75db83" + ], + "solaris_amd64": [ + "go1.23.6.solaris-amd64.tar.gz", + "b619eff63fec86daaea92ca170559e448a58b8ba0b92eef1971bc14e92ea86a7" + ], + "windows_386": [ + "go1.23.6.windows-386.zip", + "96820c0f5d464dd694543329e9b4d413b17c821c03a055717a29e6735b44c2d8" + ], + "windows_amd64": [ + "go1.23.6.windows-amd64.zip", + "53fec1586850b2cf5ad6438341ff7adc5f6700dd3ec1cfa3f5e8b141df190243" + ], + "windows_arm": [ + "go1.23.6.windows-arm.zip", + "22c2518c45c20018afa20d5376dc9fd7a7e74367240ed7b5209e79a30b5c4218" + ], + "windows_arm64": [ + "go1.23.6.windows-arm64.zip", + "a2d2ec1b3759552bdd9cdf58858f91dfbfd6ab3a472f00b5255acbed30b1aa41" + ] + }, + "1.25.0": { + "aix_ppc64": [ + "go1.25.0.aix-ppc64.tar.gz", + "e5234a7dac67bc86c528fe9752fc9d63557918627707a733ab4cac1a6faed2d4" + ], + "darwin_amd64": [ + "go1.25.0.darwin-amd64.tar.gz", + "5bd60e823037062c2307c71e8111809865116714d6f6b410597cf5075dfd80ef" + ], + "darwin_arm64": [ + "go1.25.0.darwin-arm64.tar.gz", + "544932844156d8172f7a28f77f2ac9c15a23046698b6243f633b0a0b00c0749c" + ], + "dragonfly_amd64": [ + "go1.25.0.dragonfly-amd64.tar.gz", + "5ed3cf9a810a1483822538674f1336c06b51aa1b94d6d545a1a0319a48177120" + ], + "freebsd_386": [ + "go1.25.0.freebsd-386.tar.gz", + "abea5d5c6697e6b5c224731f2158fe87c602996a2a233ac0c4730cd57bf8374e" + ], + "freebsd_amd64": [ + "go1.25.0.freebsd-amd64.tar.gz", + "86e6fe0a29698d7601c4442052dac48bd58d532c51cccb8f1917df648138730b" + ], + "freebsd_arm": [ + "go1.25.0.freebsd-arm.tar.gz", + "d90b78e41921f72f30e8bbc81d9dec2cff7ff384a33d8d8debb24053e4336bfe" + ], + "freebsd_arm64": [ + "go1.25.0.freebsd-arm64.tar.gz", + "451d0da1affd886bfb291b7c63a6018527b269505db21ce6e14724f22ab0662e" + ], + "freebsd_riscv64": [ + "go1.25.0.freebsd-riscv64.tar.gz", + "7b565f76bd8bda46549eeaaefe0e53b251e644c230577290c0f66b1ecdb3cdbe" + ], + "illumos_amd64": [ + "go1.25.0.illumos-amd64.tar.gz", + "b1e1fdaab1ad25aa1c08d7a36c97d45d74b98b89c3f78c6d2145f77face54a2c" + ], + "linux_386": [ + "go1.25.0.linux-386.tar.gz", + "8c602dd9d99bc9453b3995d20ce4baf382cc50855900a0ece5de9929df4a993a" + ], + "linux_amd64": [ + "go1.25.0.linux-amd64.tar.gz", + "2852af0cb20a13139b3448992e69b868e50ed0f8a1e5940ee1de9e19a123b613" + ], + "linux_arm64": [ + "go1.25.0.linux-arm64.tar.gz", + "05de75d6994a2783699815ee553bd5a9327d8b79991de36e38b66862782f54ae" + ], + "linux_armv6l": [ + "go1.25.0.linux-armv6l.tar.gz", + "a5a8f8198fcf00e1e485b8ecef9ee020778bf32a408a4e8873371bfce458cd09" + ], + "linux_loong64": [ + "go1.25.0.linux-loong64.tar.gz", + "cab86b1cf761b1cb3bac86a8877cfc92e7b036fc0d3084123d77013d61432afc" + ], + "linux_mips": [ + "go1.25.0.linux-mips.tar.gz", + "d66b6fb74c3d91b9829dc95ec10ca1f047ef5e89332152f92e136cf0e2da5be1" + ], + "linux_mips64": [ + "go1.25.0.linux-mips64.tar.gz", + "4082e4381a8661bc2a839ff94ba3daf4f6cde20f8fb771b5b3d4762dc84198a2" + ], + "linux_mips64le": [ + "go1.25.0.linux-mips64le.tar.gz", + "70002c299ec7f7175ac2ef673b1b347eecfa54ae11f34416a6053c17f855afcc" + ], + "linux_mipsle": [ + "go1.25.0.linux-mipsle.tar.gz", + "b00a3a39eff099f6df9f1c7355bf28e4589d0586f42d7d4a394efb763d145a73" + ], + "linux_ppc64": [ + "go1.25.0.linux-ppc64.tar.gz", + "df166f33bd98160662560a72ff0b4ba731f969a80f088922bddcf566a88c1ec1" + ], + "linux_ppc64le": [ + "go1.25.0.linux-ppc64le.tar.gz", + "0f18a89e7576cf2c5fa0b487a1635d9bcbf843df5f110e9982c64df52a983ad0" + ], + "linux_riscv64": [ + "go1.25.0.linux-riscv64.tar.gz", + "c018ff74a2c48d55c8ca9b07c8e24163558ffec8bea08b326d6336905d956b67" + ], + "linux_s390x": [ + "go1.25.0.linux-s390x.tar.gz", + "34e5a2e19f2292fbaf8783e3a241e6e49689276aef6510a8060ea5ef54eee408" + ], + "netbsd_386": [ + "go1.25.0.netbsd-386.tar.gz", + "f8586cdb7aa855657609a5c5f6dbf523efa00c2bbd7c76d3936bec80aa6c0aba" + ], + "netbsd_amd64": [ + "go1.25.0.netbsd-amd64.tar.gz", + "ae8dc1469385b86a157a423bb56304ba45730de8a897615874f57dd096db2c2a" + ], + "netbsd_arm": [ + "go1.25.0.netbsd-arm.tar.gz", + "1ff7e4cc764425fc9dd6825eaee79d02b3c7cafffbb3691687c8d672ade76cb7" + ], + "netbsd_arm64": [ + "go1.25.0.netbsd-arm64.tar.gz", + "e1b310739f26724216aa6d7d7208c4031f9ff54c9b5b9a796ddc8bebcb4a5f16" + ], + "openbsd_386": [ + "go1.25.0.openbsd-386.tar.gz", + "4802a9b20e533da91adb84aab42e94aa56cfe3e5475d0550bed3385b182e69d8" + ], + "openbsd_amd64": [ + "go1.25.0.openbsd-amd64.tar.gz", + "c016cd984bebe317b19a4f297c4f50def120dc9788490540c89f28e42f1dabe1" + ], + "openbsd_arm": [ + "go1.25.0.openbsd-arm.tar.gz", + "a1e31d0bf22172ddde42edf5ec811ef81be43433df0948ece52fecb247ccfd8d" + ], + "openbsd_arm64": [ + "go1.25.0.openbsd-arm64.tar.gz", + "343ea8edd8c218196e15a859c6072d0dd3246fbbb168481ab665eb4c4140458d" + ], + "openbsd_ppc64": [ + "go1.25.0.openbsd-ppc64.tar.gz", + "694c14da1bcaeb5e3332d49bdc2b6d155067648f8fe1540c5de8f3cf8e157154" + ], + "openbsd_riscv64": [ + "go1.25.0.openbsd-riscv64.tar.gz", + "aa510ad25cf54c06cd9c70b6d80ded69cb20188ac6e1735655eef29ff7e7885f" + ], + "plan9_386": [ + "go1.25.0.plan9-386.tar.gz", + "46f8cef02086cf04bf186c5912776b56535178d4cb319cd19c9fdbdd29231986" + ], + "plan9_amd64": [ + "go1.25.0.plan9-amd64.tar.gz", + "29b34391d84095e44608a228f63f2f88113a37b74a79781353ec043dfbcb427b" + ], + "plan9_arm": [ + "go1.25.0.plan9-arm.tar.gz", + "0a047107d13ebe7943aaa6d54b1d7bbd2e45e68ce449b52915a818da715799c2" + ], + "solaris_amd64": [ + "go1.25.0.solaris-amd64.tar.gz", + "9977f9e4351984364a3b2b78f8b88bfd1d339812356d5237678514594b7d3611" + ], + "windows_386": [ + "go1.25.0.windows-386.zip", + "df9f39db82a803af0db639e3613a36681ab7a42866b1384b3f3a1045663961a7" + ], + "windows_amd64": [ + "go1.25.0.windows-amd64.zip", + "89efb4f9b30812eee083cc1770fdd2913c14d301064f6454851428f9707d190b" + ], + "windows_arm64": [ + "go1.25.0.windows-arm64.zip", + "27bab004c72b3d7bd05a69b6ec0fc54a309b4b78cc569dd963d8b3ec28bfdb8c" + ] + } + } + }, + "factsVersions": {} +} diff --git a/src/control-plane-services/cloud-tasks/maven_install.json b/src/control-plane-services/cloud-tasks/maven_install.json new file mode 100755 index 000000000..ed26396a1 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/maven_install.json @@ -0,0 +1,11900 @@ +{ + "__AUTOGENERATED_FILE_DO_NOT_MODIFY_THIS_FILE_MANUALLY": "THERE_IS_NO_DATA_ONLY_ZUUL", + "__INPUT_ARTIFACTS_HASH": { + "at.yawk.lz4:lz4-java": 1725015399, + "com.bucket4j:bucket4j_jdk17-core": -1409600715, + "com.github.ben-manes.caffeine:caffeine": 1100418982, + "com.github.ben-manes.caffeine:guava": 1054685015, + "com.github.java-json-tools:json-patch": -1031005245, + "com.google.code.findbugs:jsr305": 495355163, + "com.google.code.gson:gson": 597770368, + "com.google.errorprone:error_prone_annotations": -1035138750, + "com.google.guava:guava": 1943808618, + "com.google.j2objc:j2objc-annotations": 2003271689, + "com.google.protobuf:protobuf-java": 1906581597, + "com.google.protobuf:protobuf-java-util": -1626074784, + "commons-codec:commons-codec": -1269462382, + "io.cloudevents:cloudevents-core": -2103567774, + "io.cloudevents:cloudevents-json-jackson": -1197487309, + "io.grpc:grpc-api": 1424099231, + "io.grpc:grpc-netty": -904974271, + "io.grpc:grpc-protobuf": 1036850648, + "io.grpc:grpc-stub": -26097747, + "io.micrometer:micrometer-registry-prometheus": 1865600799, + "io.micrometer:micrometer-tracing-bridge-otel": -754588172, + "io.nats:jnats": 572014237, + "io.opentelemetry:opentelemetry-exporter-otlp": -12806658, + "io.opentelemetry:opentelemetry-sdk-testing": -32635354, + "io.projectreactor.netty:reactor-netty-core": -2096527644, + "io.projectreactor.netty:reactor-netty-http": 131695323, + "jakarta.servlet:jakarta.servlet-api": 2120044853, + "javax.annotation:javax.annotation-api": 1286517389, + "net.devh:grpc-server-spring-boot-starter": -1304967214, + "net.javacrumbs.shedlock:shedlock-bom": -1406345450, + "net.javacrumbs.shedlock:shedlock-provider-cassandra": -1200872, + "net.javacrumbs.shedlock:shedlock-spring": -326290089, + "org.apache.cassandra:java-driver-metrics-micrometer": -465267397, + "org.apache.commons:commons-lang3": -278168457, + "org.assertj:assertj-core": 1863574844, + "org.awaitility:awaitility": -1630939750, + "org.bouncycastle:bcprov-jdk18on": -1405390253, + "org.jacoco:org.jacoco.agent": -2069397525, + "org.jacoco:org.jacoco.cli": -1856875155, + "org.junit.jupiter:junit-jupiter-api": 194920406, + "org.junit.jupiter:junit-jupiter-engine": -1886863302, + "org.junit.jupiter:junit-jupiter-params": 1082310006, + "org.junit.platform:junit-platform-console-standalone": -1481831078, + "org.junit.platform:junit-platform-launcher": -354104948, + "org.junit.platform:junit-platform-reporting": 1896713402, + "org.mockito:mockito-core": -554630660, + "org.mockito:mockito-junit-jupiter": -1104541639, + "org.ow2.asm:asm": -221905796, + "org.ow2.asm:asm-analysis": -1027574299, + "org.ow2.asm:asm-commons": 1525995351, + "org.ow2.asm:asm-tree": -242459737, + "org.ow2.asm:asm-util": -307204853, + "org.projectlombok:lombok": -2073039513, + "org.springdoc:springdoc-openapi-starter-webflux-api": 1102747448, + "org.springdoc:springdoc-openapi-starter-webmvc-api": 655186513, + "org.springframework.boot:spring-boot-actuator": 763411999, + "org.springframework.boot:spring-boot-dependencies": 70164638, + "org.springframework.boot:spring-boot-loader": 1745496505, + "org.springframework.boot:spring-boot-micrometer-metrics": -782059807, + "org.springframework.boot:spring-boot-micrometer-tracing": -2099172128, + "org.springframework.boot:spring-boot-micrometer-tracing-opentelemetry": 238152322, + "org.springframework.boot:spring-boot-opentelemetry": -396622647, + "org.springframework.boot:spring-boot-restclient": 525086533, + "org.springframework.boot:spring-boot-starter": 1358725161, + "org.springframework.boot:spring-boot-starter-actuator": -1082017891, + "org.springframework.boot:spring-boot-starter-actuator-test": 536870722, + "org.springframework.boot:spring-boot-starter-aspectj": -1960483986, + "org.springframework.boot:spring-boot-starter-data-cassandra": 699136521, + "org.springframework.boot:spring-boot-starter-data-cassandra-test": -667262890, + "org.springframework.boot:spring-boot-starter-jackson": -1899095121, + "org.springframework.boot:spring-boot-starter-security": 1168390884, + "org.springframework.boot:spring-boot-starter-security-oauth2-client": -1248590284, + "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server": 185843737, + "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server-test": -1173625786, + "org.springframework.boot:spring-boot-starter-test": -1561809354, + "org.springframework.boot:spring-boot-starter-validation": 113118493, + "org.springframework.boot:spring-boot-starter-web": -1905796688, + "org.springframework.boot:spring-boot-starter-webflux": 1788530073, + "org.springframework.boot:spring-boot-starter-webflux-test": 5326534, + "org.springframework.boot:spring-boot-starter-webmvc": 338400426, + "org.springframework.boot:spring-boot-starter-webmvc-test": -2111356331, + "org.springframework.boot:spring-boot-webclient": -1835278023, + "org.springframework.cloud:spring-cloud-commons": -673836000, + "org.springframework.cloud:spring-cloud-context": -1724959431, + "org.springframework.cloud:spring-cloud-dependencies": 46341733, + "org.springframework.cloud:spring-cloud-starter-bootstrap": -213001704, + "org.springframework.cloud:spring-cloud-starter-kubernetes-client-config": -2108580045, + "org.springframework.retry:spring-retry": -815156811, + "org.springframework.security:spring-security-test": 1317137564, + "org.springframework:spring-context-support": 43813702, + "org.springframework:spring-webflux": 11421498, + "org.testcontainers:testcontainers": -258185670, + "org.testcontainers:testcontainers-bom": 483223872, + "org.testcontainers:testcontainers-cassandra": -1027104267, + "org.testcontainers:testcontainers-junit-jupiter": -918230293, + "org.testcontainers:testcontainers-localstack": 1146768038, + "org.wiremock:wiremock-standalone": -1242936487, + "repositories": -1624298853, + "software.amazon.awssdk:regions": -1274787064, + "tools.jackson.module:jackson-module-blackbird": -423541381 + }, + "__RESOLVED_ARTIFACTS_HASH": { + "aopalliance:aopalliance": -1763688673, + "aopalliance:aopalliance:jar:sources": 758113234, + "args4j:args4j": -572028113, + "args4j:args4j:jar:sources": 74047526, + "at.yawk.lz4:lz4-java": -1985362494, + "at.yawk.lz4:lz4-java:jar:sources": -2141970549, + "ch.qos.logback:logback-classic": -619930806, + "ch.qos.logback:logback-classic:jar:sources": -390128445, + "ch.qos.logback:logback-core": -1554021729, + "ch.qos.logback:logback-core:jar:sources": 77538609, + "com.bucket4j:bucket4j-core": -332288989, + "com.bucket4j:bucket4j-core:jar:sources": -559201191, + "com.bucket4j:bucket4j_jdk17-core": -1244833112, + "com.bucket4j:bucket4j_jdk17-core:jar:sources": -2075602285, + "com.datastax.cassandra:cassandra-driver-core": 197829386, + "com.datastax.cassandra:cassandra-driver-core:jar:sources": -2045236197, + "com.datastax.oss:native-protocol": 447263174, + "com.datastax.oss:native-protocol:jar:sources": 396473389, + "com.fasterxml.jackson.core:jackson-annotations": 1407322119, + "com.fasterxml.jackson.core:jackson-annotations:jar:sources": -1408285999, + "com.fasterxml.jackson.core:jackson-core": -1715692416, + "com.fasterxml.jackson.core:jackson-core:jar:sources": 1404881423, + "com.fasterxml.jackson.core:jackson-databind": -1922910990, + "com.fasterxml.jackson.core:jackson-databind:jar:sources": -802304801, + "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml": 2129087476, + "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:jar:sources": -175522790, + "com.fasterxml.jackson.datatype:jackson-datatype-jsr310": 1940996847, + "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:jar:sources": 1241536710, + "com.fasterxml:classmate": -1468141616, + "com.fasterxml:classmate:jar:sources": -179492269, + "com.github.ben-manes.caffeine:caffeine": 1925806502, + "com.github.ben-manes.caffeine:caffeine:jar:sources": -967473790, + "com.github.ben-manes.caffeine:guava": 2074933175, + "com.github.ben-manes.caffeine:guava:jar:sources": 1956210603, + "com.github.docker-java:docker-java-api": 1857041788, + "com.github.docker-java:docker-java-api:jar:sources": 300128277, + "com.github.docker-java:docker-java-transport": 689281477, + "com.github.docker-java:docker-java-transport-zerodep": -1848983763, + "com.github.docker-java:docker-java-transport-zerodep:jar:sources": 1882881505, + "com.github.docker-java:docker-java-transport:jar:sources": 864522470, + "com.github.java-json-tools:btf": 204024567, + "com.github.java-json-tools:btf:jar:sources": 1539011915, + "com.github.java-json-tools:jackson-coreutils": 1585779168, + "com.github.java-json-tools:jackson-coreutils:jar:sources": 323093438, + "com.github.java-json-tools:json-patch": 388171991, + "com.github.java-json-tools:json-patch:jar:sources": -1320375757, + "com.github.java-json-tools:msg-simple": -285204120, + "com.github.java-json-tools:msg-simple:jar:sources": 1013495835, + "com.github.jnr:jffi": 1952487985, + "com.github.jnr:jffi:jar:native": 1426144838, + "com.github.jnr:jffi:jar:sources": -252446498, + "com.github.jnr:jnr-constants": 1522135714, + "com.github.jnr:jnr-constants:jar:sources": -1920781516, + "com.github.jnr:jnr-ffi": 1663045836, + "com.github.jnr:jnr-ffi:jar:sources": -150631029, + "com.github.jnr:jnr-posix": 1594911544, + "com.github.jnr:jnr-posix:jar:sources": -992203730, + "com.github.jnr:jnr-x86asm": 1097235222, + "com.github.jnr:jnr-x86asm:jar:sources": -1784079536, + "com.github.stephenc.jcip:jcip-annotations": -121928928, + "com.github.stephenc.jcip:jcip-annotations:jar:sources": -2051941468, + "com.google.android:annotations": 769933135, + "com.google.android:annotations:jar:sources": 215169100, + "com.google.api.grpc:proto-google-common-protos": -1208329413, + "com.google.api.grpc:proto-google-common-protos:jar:sources": 944916609, + "com.google.code.findbugs:jsr305": -1038659426, + "com.google.code.findbugs:jsr305:jar:sources": -1300148931, + "com.google.code.gson:gson": 1618556651, + "com.google.code.gson:gson:jar:sources": 389178860, + "com.google.errorprone:error_prone_annotations": 492382488, + "com.google.errorprone:error_prone_annotations:jar:sources": 456515251, + "com.google.guava:failureaccess": -268223546, + "com.google.guava:failureaccess:jar:sources": 2053502918, + "com.google.guava:guava": 1240305771, + "com.google.guava:guava:jar:sources": 1591586943, + "com.google.guava:listenablefuture": 1588902908, + "com.google.j2objc:j2objc-annotations": -596695707, + "com.google.j2objc:j2objc-annotations:jar:sources": 900785715, + "com.google.protobuf:protobuf-java": 1139989641, + "com.google.protobuf:protobuf-java-util": -1990628174, + "com.google.protobuf:protobuf-java-util:jar:sources": 1216176261, + "com.google.protobuf:protobuf-java:jar:sources": -718827633, + "com.jayway.jsonpath:json-path": 626712679, + "com.jayway.jsonpath:json-path:jar:sources": -343427302, + "com.nimbusds:content-type": -444977683, + "com.nimbusds:content-type:jar:sources": -634646164, + "com.nimbusds:lang-tag": -694347345, + "com.nimbusds:lang-tag:jar:sources": 266930896, + "com.nimbusds:nimbus-jose-jwt": -286981492, + "com.nimbusds:nimbus-jose-jwt:jar:sources": 24935039, + "com.nimbusds:oauth2-oidc-sdk": -498816278, + "com.nimbusds:oauth2-oidc-sdk:jar:sources": 1276926642, + "com.squareup.okhttp3:logging-interceptor": -2002563184, + "com.squareup.okhttp3:logging-interceptor:jar:sources": 524942179, + "com.squareup.okhttp3:okhttp": -2047906849, + "com.squareup.okhttp3:okhttp-jvm": -314031254, + "com.squareup.okhttp3:okhttp-jvm:jar:sources": 447067750, + "com.squareup.okhttp3:okhttp:jar:sources": -967779406, + "com.squareup.okio:okio": -11775483, + "com.squareup.okio:okio-jvm": -391120506, + "com.squareup.okio:okio-jvm:jar:sources": 1375453359, + "com.squareup.okio:okio:jar:sources": -1339925226, + "com.typesafe:config": 96906638, + "com.typesafe:config:jar:sources": -892423283, + "com.vaadin.external.google:android-json": -1531950165, + "com.vaadin.external.google:android-json:jar:sources": -116078240, + "commons-codec:commons-codec": -835030550, + "commons-codec:commons-codec:jar:sources": 990790236, + "commons-io:commons-io": -1021273518, + "commons-io:commons-io:jar:sources": 2066085027, + "commons-logging:commons-logging": 1061992981, + "commons-logging:commons-logging:jar:sources": 1867783947, + "io.cloudevents:cloudevents-api": -617548735, + "io.cloudevents:cloudevents-api:jar:sources": 924762007, + "io.cloudevents:cloudevents-core": -688560325, + "io.cloudevents:cloudevents-core:jar:sources": 223693387, + "io.cloudevents:cloudevents-json-jackson": -807987873, + "io.cloudevents:cloudevents-json-jackson:jar:sources": -166751855, + "io.dropwizard.metrics:metrics-core": 1029463962, + "io.dropwizard.metrics:metrics-core:jar:sources": 1607397396, + "io.grpc:grpc-api": 1731222191, + "io.grpc:grpc-api:jar:sources": 234601049, + "io.grpc:grpc-context": 1511740056, + "io.grpc:grpc-context:jar:sources": -1094751930, + "io.grpc:grpc-core": 831039331, + "io.grpc:grpc-core:jar:sources": 691468151, + "io.grpc:grpc-inprocess": -1501508632, + "io.grpc:grpc-inprocess:jar:sources": -676994554, + "io.grpc:grpc-netty": 1825797901, + "io.grpc:grpc-netty-shaded": -345312471, + "io.grpc:grpc-netty-shaded:jar:sources": 1478851124, + "io.grpc:grpc-netty:jar:sources": -231652768, + "io.grpc:grpc-protobuf": 45290816, + "io.grpc:grpc-protobuf-lite": 63739651, + "io.grpc:grpc-protobuf-lite:jar:sources": -1659538303, + "io.grpc:grpc-protobuf:jar:sources": -1849103116, + "io.grpc:grpc-services": -1598479097, + "io.grpc:grpc-services:jar:sources": 2062893709, + "io.grpc:grpc-stub": 1646600797, + "io.grpc:grpc-stub:jar:sources": -1596678046, + "io.grpc:grpc-util": 1123291627, + "io.grpc:grpc-util:jar:sources": 661341860, + "io.gsonfire:gson-fire": -839915556, + "io.gsonfire:gson-fire:jar:sources": -237239617, + "io.kubernetes:client-java": -1707157006, + "io.kubernetes:client-java-api": -2039476626, + "io.kubernetes:client-java-api-fluent": 178640861, + "io.kubernetes:client-java-api-fluent:jar:sources": -1413457658, + "io.kubernetes:client-java-api:jar:sources": -1450077171, + "io.kubernetes:client-java-extended": 1201157788, + "io.kubernetes:client-java-extended:jar:sources": -483537505, + "io.kubernetes:client-java-proto": -533144525, + "io.kubernetes:client-java-proto:jar:sources": 396874650, + "io.kubernetes:client-java:jar:sources": -1422160339, + "io.micrometer:context-propagation": -1130727419, + "io.micrometer:context-propagation:jar:sources": -1135393170, + "io.micrometer:micrometer-commons": 326693391, + "io.micrometer:micrometer-commons:jar:sources": -57818626, + "io.micrometer:micrometer-core": 829567043, + "io.micrometer:micrometer-core:jar:sources": 265175165, + "io.micrometer:micrometer-jakarta9": -15933884, + "io.micrometer:micrometer-jakarta9:jar:sources": 1275065742, + "io.micrometer:micrometer-observation": -319705914, + "io.micrometer:micrometer-observation-test": -1818068529, + "io.micrometer:micrometer-observation-test:jar:sources": 117373145, + "io.micrometer:micrometer-observation:jar:sources": 1279306785, + "io.micrometer:micrometer-registry-prometheus": -104964751, + "io.micrometer:micrometer-registry-prometheus:jar:sources": 769452823, + "io.micrometer:micrometer-tracing": -109714346, + "io.micrometer:micrometer-tracing-bridge-otel": 975863312, + "io.micrometer:micrometer-tracing-bridge-otel:jar:sources": 1300289348, + "io.micrometer:micrometer-tracing:jar:sources": 266031561, + "io.nats:jnats": 1273546329, + "io.nats:jnats:jar:sources": 194791155, + "io.netty:netty-buffer": -1740802869, + "io.netty:netty-buffer:jar:sources": 622468392, + "io.netty:netty-codec-base": -1042304993, + "io.netty:netty-codec-base:jar:sources": -612797714, + "io.netty:netty-codec-classes-quic": -702276906, + "io.netty:netty-codec-classes-quic:jar:sources": 1548159851, + "io.netty:netty-codec-compression": -789209831, + "io.netty:netty-codec-compression:jar:sources": -1402960067, + "io.netty:netty-codec-dns": 81169397, + "io.netty:netty-codec-dns:jar:sources": -1086447458, + "io.netty:netty-codec-http": -95764323, + "io.netty:netty-codec-http2": 544878123, + "io.netty:netty-codec-http2:jar:sources": -83820759, + "io.netty:netty-codec-http3": -194972071, + "io.netty:netty-codec-http3:jar:sources": 1699772273, + "io.netty:netty-codec-http:jar:sources": -116842177, + "io.netty:netty-codec-native-quic:jar:linux-aarch_64": -2075260519, + "io.netty:netty-codec-native-quic:jar:linux-x86_64": -1982796133, + "io.netty:netty-codec-native-quic:jar:osx-aarch_64": -632727283, + "io.netty:netty-codec-native-quic:jar:osx-x86_64": 1253945631, + "io.netty:netty-codec-native-quic:jar:sources": -986328940, + "io.netty:netty-codec-native-quic:jar:windows-x86_64": -115110822, + "io.netty:netty-codec-socks": 336734625, + "io.netty:netty-codec-socks:jar:sources": -1241946572, + "io.netty:netty-common": -1557278455, + "io.netty:netty-common:jar:sources": -467395659, + "io.netty:netty-handler": -1757690436, + "io.netty:netty-handler-proxy": -892232184, + "io.netty:netty-handler-proxy:jar:sources": -216040607, + "io.netty:netty-handler:jar:sources": -1379156289, + "io.netty:netty-resolver": -1571627366, + "io.netty:netty-resolver-dns": 954988644, + "io.netty:netty-resolver-dns-classes-macos": -441663783, + "io.netty:netty-resolver-dns-classes-macos:jar:sources": 776580055, + "io.netty:netty-resolver-dns-native-macos:jar:osx-x86_64": -354533951, + "io.netty:netty-resolver-dns-native-macos:jar:sources": -120739665, + "io.netty:netty-resolver-dns:jar:sources": 1652413066, + "io.netty:netty-resolver:jar:sources": 2084403340, + "io.netty:netty-transport": 44555455, + "io.netty:netty-transport-classes-epoll": -588470325, + "io.netty:netty-transport-classes-epoll:jar:sources": -1697662320, + "io.netty:netty-transport-native-epoll:jar:linux-x86_64": -563523863, + "io.netty:netty-transport-native-epoll:jar:sources": -1040259378, + "io.netty:netty-transport-native-unix-common": -166041147, + "io.netty:netty-transport-native-unix-common:jar:sources": -1674017507, + "io.netty:netty-transport:jar:sources": -820889350, + "io.opentelemetry.semconv:opentelemetry-semconv": 1195624836, + "io.opentelemetry.semconv:opentelemetry-semconv:jar:sources": -893534237, + "io.opentelemetry:opentelemetry-api": 885391408, + "io.opentelemetry:opentelemetry-api:jar:sources": -1404426315, + "io.opentelemetry:opentelemetry-common": 676580228, + "io.opentelemetry:opentelemetry-common:jar:sources": 1797051654, + "io.opentelemetry:opentelemetry-context": 747746024, + "io.opentelemetry:opentelemetry-context:jar:sources": 560193252, + "io.opentelemetry:opentelemetry-exporter-common": 42591217, + "io.opentelemetry:opentelemetry-exporter-common:jar:sources": 2032641450, + "io.opentelemetry:opentelemetry-exporter-otlp": 1346623356, + "io.opentelemetry:opentelemetry-exporter-otlp-common": -2043450521, + "io.opentelemetry:opentelemetry-exporter-otlp-common:jar:sources": -1909225648, + "io.opentelemetry:opentelemetry-exporter-otlp:jar:sources": -1536215787, + "io.opentelemetry:opentelemetry-exporter-sender-okhttp": -2026614746, + "io.opentelemetry:opentelemetry-exporter-sender-okhttp:jar:sources": -1387239258, + "io.opentelemetry:opentelemetry-extension-trace-propagators": -480191373, + "io.opentelemetry:opentelemetry-extension-trace-propagators:jar:sources": 517135536, + "io.opentelemetry:opentelemetry-sdk": -369820209, + "io.opentelemetry:opentelemetry-sdk-common": -1049102876, + "io.opentelemetry:opentelemetry-sdk-common:jar:sources": -1004050981, + "io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi": -928104061, + "io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi:jar:sources": -1626691242, + "io.opentelemetry:opentelemetry-sdk-logs": -1310291573, + "io.opentelemetry:opentelemetry-sdk-logs:jar:sources": 1572252989, + "io.opentelemetry:opentelemetry-sdk-metrics": -2038069517, + "io.opentelemetry:opentelemetry-sdk-metrics:jar:sources": -323022280, + "io.opentelemetry:opentelemetry-sdk-testing": 19519171, + "io.opentelemetry:opentelemetry-sdk-testing:jar:sources": -578292790, + "io.opentelemetry:opentelemetry-sdk-trace": 2083919234, + "io.opentelemetry:opentelemetry-sdk-trace:jar:sources": 818630467, + "io.opentelemetry:opentelemetry-sdk:jar:sources": -1478160490, + "io.perfmark:perfmark-api": -752483303, + "io.perfmark:perfmark-api:jar:sources": 1421329924, + "io.projectreactor.netty:reactor-netty-core": -1310988391, + "io.projectreactor.netty:reactor-netty-core:jar:sources": 160926198, + "io.projectreactor.netty:reactor-netty-http": -1289714469, + "io.projectreactor.netty:reactor-netty-http:jar:sources": 1066415166, + "io.projectreactor:reactor-core": -745004757, + "io.projectreactor:reactor-core:jar:sources": -717353230, + "io.projectreactor:reactor-test": 947112823, + "io.projectreactor:reactor-test:jar:sources": 383025302, + "io.prometheus:prometheus-metrics-config": 2090275681, + "io.prometheus:prometheus-metrics-config:jar:sources": -594166944, + "io.prometheus:prometheus-metrics-core": 786050810, + "io.prometheus:prometheus-metrics-core:jar:sources": 832360457, + "io.prometheus:prometheus-metrics-exposition-formats": 968068623, + "io.prometheus:prometheus-metrics-exposition-formats:jar:sources": -438412972, + "io.prometheus:prometheus-metrics-exposition-textformats": 620169553, + "io.prometheus:prometheus-metrics-exposition-textformats:jar:sources": 1866131456, + "io.prometheus:prometheus-metrics-model": -1472396605, + "io.prometheus:prometheus-metrics-model:jar:sources": 2095315251, + "io.prometheus:prometheus-metrics-tracer-common": -1148816462, + "io.prometheus:prometheus-metrics-tracer-common:jar:sources": 2121978274, + "io.swagger.core.v3:swagger-annotations-jakarta": -842428034, + "io.swagger.core.v3:swagger-annotations-jakarta:jar:sources": 133934665, + "io.swagger.core.v3:swagger-core-jakarta": -439612282, + "io.swagger.core.v3:swagger-core-jakarta:jar:sources": 449241668, + "io.swagger.core.v3:swagger-models-jakarta": -1439553498, + "io.swagger.core.v3:swagger-models-jakarta:jar:sources": 2092063988, + "io.swagger:swagger-annotations": 1839493157, + "io.swagger:swagger-annotations:jar:sources": 686356574, + "jakarta.activation:jakarta.activation-api": -1560267684, + "jakarta.activation:jakarta.activation-api:jar:sources": 759160467, + "jakarta.annotation:jakarta.annotation-api": -1904975463, + "jakarta.annotation:jakarta.annotation-api:jar:sources": -247204066, + "jakarta.servlet:jakarta.servlet-api": 972614879, + "jakarta.servlet:jakarta.servlet-api:jar:sources": 2070183472, + "jakarta.validation:jakarta.validation-api": 666686261, + "jakarta.validation:jakarta.validation-api:jar:sources": -131796339, + "jakarta.xml.bind:jakarta.xml.bind-api": 1157993223, + "jakarta.xml.bind:jakarta.xml.bind-api:jar:sources": -945798747, + "javax.annotation:javax.annotation-api": 193132517, + "javax.annotation:javax.annotation-api:jar:sources": -1766532873, + "net.bytebuddy:byte-buddy": 383637760, + "net.bytebuddy:byte-buddy-agent": -1380713096, + "net.bytebuddy:byte-buddy-agent:jar:sources": 564051985, + "net.bytebuddy:byte-buddy:jar:sources": -1360611642, + "net.devh:grpc-common-spring-boot": -552555366, + "net.devh:grpc-common-spring-boot:jar:sources": 1655513026, + "net.devh:grpc-server-spring-boot-starter": 265787149, + "net.devh:grpc-server-spring-boot-starter:jar:sources": 1954333860, + "net.java.dev.jna:jna": -1951542637, + "net.java.dev.jna:jna:jar:sources": -545183654, + "net.javacrumbs.shedlock:shedlock-core": 672475327, + "net.javacrumbs.shedlock:shedlock-core:jar:sources": 69227555, + "net.javacrumbs.shedlock:shedlock-provider-cassandra": -460637299, + "net.javacrumbs.shedlock:shedlock-provider-cassandra:jar:sources": 1860167, + "net.javacrumbs.shedlock:shedlock-spring": 2008414309, + "net.javacrumbs.shedlock:shedlock-spring:jar:sources": 875349683, + "net.minidev:accessors-smart": -325667575, + "net.minidev:accessors-smart:jar:sources": -124254155, + "net.minidev:json-smart": 1673421716, + "net.minidev:json-smart:jar:sources": -1084786431, + "org.apache.cassandra:java-driver-core": 42196324, + "org.apache.cassandra:java-driver-core:jar:sources": -1508814165, + "org.apache.cassandra:java-driver-guava-shaded": 568990261, + "org.apache.cassandra:java-driver-guava-shaded:jar:sources": 1291502230, + "org.apache.cassandra:java-driver-metrics-micrometer": -93817708, + "org.apache.cassandra:java-driver-metrics-micrometer:jar:sources": -2019023443, + "org.apache.cassandra:java-driver-query-builder": 303143232, + "org.apache.cassandra:java-driver-query-builder:jar:sources": -1665027563, + "org.apache.commons:commons-collections4": -321403372, + "org.apache.commons:commons-collections4:jar:sources": -620214302, + "org.apache.commons:commons-compress": -134181577, + "org.apache.commons:commons-compress:jar:sources": -1845261624, + "org.apache.commons:commons-lang3": 759645435, + "org.apache.commons:commons-lang3:jar:sources": 1890991939, + "org.apache.logging.log4j:log4j-api": 191755139, + "org.apache.logging.log4j:log4j-api:jar:sources": 1226633672, + "org.apache.logging.log4j:log4j-to-slf4j": 357996538, + "org.apache.logging.log4j:log4j-to-slf4j:jar:sources": -1847454236, + "org.apache.tomcat.embed:tomcat-embed-core": -2079786590, + "org.apache.tomcat.embed:tomcat-embed-core:jar:sources": -745705587, + "org.apache.tomcat.embed:tomcat-embed-el": -727131551, + "org.apache.tomcat.embed:tomcat-embed-el:jar:sources": 1938415424, + "org.apache.tomcat.embed:tomcat-embed-websocket": 1876889190, + "org.apache.tomcat.embed:tomcat-embed-websocket:jar:sources": -1809736441, + "org.apiguardian:apiguardian-api": -1579303244, + "org.apiguardian:apiguardian-api:jar:sources": 768152577, + "org.aspectj:aspectjweaver": -278059941, + "org.aspectj:aspectjweaver:jar:sources": 2235676, + "org.assertj:assertj-core": -536770136, + "org.assertj:assertj-core:jar:sources": -1826278818, + "org.awaitility:awaitility": 755971515, + "org.awaitility:awaitility:jar:sources": -1322650242, + "org.bitbucket.b_c:jose4j": 1319068658, + "org.bitbucket.b_c:jose4j:jar:sources": 969109778, + "org.bouncycastle:bcpkix-jdk18on": 755215182, + "org.bouncycastle:bcpkix-jdk18on:jar:sources": -167831728, + "org.bouncycastle:bcprov-jdk18on": -709136978, + "org.bouncycastle:bcprov-jdk18on:jar:sources": 106463766, + "org.bouncycastle:bcprov-lts8on": 973431866, + "org.bouncycastle:bcprov-lts8on:jar:sources": -196135755, + "org.bouncycastle:bcutil-jdk18on": 686883151, + "org.bouncycastle:bcutil-jdk18on:jar:sources": 1665148152, + "org.checkerframework:checker-qual": -2018582244, + "org.checkerframework:checker-qual:jar:sources": 2110417205, + "org.codehaus.mojo:animal-sniffer-annotations": -284157962, + "org.codehaus.mojo:animal-sniffer-annotations:jar:sources": 1440193403, + "org.hamcrest:hamcrest": 1116842741, + "org.hamcrest:hamcrest:jar:sources": -996443755, + "org.hdrhistogram:HdrHistogram": 1379183334, + "org.hdrhistogram:HdrHistogram:jar:sources": -1235434218, + "org.hibernate.validator:hibernate-validator": 1976561513, + "org.hibernate.validator:hibernate-validator:jar:sources": 367698734, + "org.jacoco:org.jacoco.agent:jar:runtime": -111724801, + "org.jacoco:org.jacoco.agent:jar:sources": 1432778515, + "org.jacoco:org.jacoco.cli": 2021870981, + "org.jacoco:org.jacoco.cli:jar:sources": 47843733, + "org.jacoco:org.jacoco.core": 579589309, + "org.jacoco:org.jacoco.core:jar:sources": -458393909, + "org.jacoco:org.jacoco.report": -1287135579, + "org.jacoco:org.jacoco.report:jar:sources": -2068401168, + "org.jboss.logging:jboss-logging": -2136063667, + "org.jboss.logging:jboss-logging:jar:sources": 2066441551, + "org.jetbrains.kotlin:kotlin-stdlib": -570435334, + "org.jetbrains.kotlin:kotlin-stdlib-jdk7": -1527302391, + "org.jetbrains.kotlin:kotlin-stdlib-jdk7:jar:sources": 197696244, + "org.jetbrains.kotlin:kotlin-stdlib-jdk8": 1920837701, + "org.jetbrains.kotlin:kotlin-stdlib-jdk8:jar:sources": -680289057, + "org.jetbrains.kotlin:kotlin-stdlib:jar:sources": 1404576391, + "org.jetbrains:annotations": 643765179, + "org.jetbrains:annotations:jar:sources": 1009912224, + "org.jspecify:jspecify": -1402924792, + "org.jspecify:jspecify:jar:sources": -841008091, + "org.junit.jupiter:junit-jupiter": -313198921, + "org.junit.jupiter:junit-jupiter-api": 80944698, + "org.junit.jupiter:junit-jupiter-api:jar:sources": -1650654944, + "org.junit.jupiter:junit-jupiter-engine": 730848020, + "org.junit.jupiter:junit-jupiter-engine:jar:sources": 1805473715, + "org.junit.jupiter:junit-jupiter-params": -1923494954, + "org.junit.jupiter:junit-jupiter-params:jar:sources": 1561682205, + "org.junit.jupiter:junit-jupiter:jar:sources": 1809716175, + "org.junit.platform:junit-platform-commons": -1304725543, + "org.junit.platform:junit-platform-commons:jar:sources": -139331649, + "org.junit.platform:junit-platform-console-standalone": -406221538, + "org.junit.platform:junit-platform-console-standalone:jar:sources": -103511349, + "org.junit.platform:junit-platform-engine": -748595950, + "org.junit.platform:junit-platform-engine:jar:sources": -191078126, + "org.junit.platform:junit-platform-launcher": 1722101087, + "org.junit.platform:junit-platform-launcher:jar:sources": -717285440, + "org.junit.platform:junit-platform-reporting": 1847654060, + "org.junit.platform:junit-platform-reporting:jar:sources": -1771745730, + "org.latencyutils:LatencyUtils": 1082471286, + "org.latencyutils:LatencyUtils:jar:sources": 1894864087, + "org.mockito:mockito-core": 734095861, + "org.mockito:mockito-core:jar:sources": 1757924088, + "org.mockito:mockito-junit-jupiter": -501680015, + "org.mockito:mockito-junit-jupiter:jar:sources": -1281757309, + "org.objenesis:objenesis": 1083875484, + "org.objenesis:objenesis:jar:sources": 703772823, + "org.opentest4j.reporting:open-test-reporting-tooling-spi": -1639379357, + "org.opentest4j.reporting:open-test-reporting-tooling-spi:jar:sources": 1632689314, + "org.opentest4j:opentest4j": 793813175, + "org.opentest4j:opentest4j:jar:sources": 1210936723, + "org.ow2.asm:asm": 716467505, + "org.ow2.asm:asm-analysis": 129370658, + "org.ow2.asm:asm-analysis:jar:sources": -2126326860, + "org.ow2.asm:asm-commons": 530868933, + "org.ow2.asm:asm-commons:jar:sources": 1248498766, + "org.ow2.asm:asm-tree": 369430530, + "org.ow2.asm:asm-tree:jar:sources": -1850601298, + "org.ow2.asm:asm-util": -803635337, + "org.ow2.asm:asm-util:jar:sources": 51483494, + "org.ow2.asm:asm:jar:sources": -947428423, + "org.projectlombok:lombok": -1095750717, + "org.projectlombok:lombok:jar:sources": 1834083797, + "org.reactivestreams:reactive-streams": -1996658890, + "org.reactivestreams:reactive-streams:jar:sources": -258070571, + "org.rnorth.duct-tape:duct-tape": 615461963, + "org.rnorth.duct-tape:duct-tape:jar:sources": 427419407, + "org.skyscreamer:jsonassert": -1571197746, + "org.skyscreamer:jsonassert:jar:sources": -392658057, + "org.slf4j:jul-to-slf4j": -911724984, + "org.slf4j:jul-to-slf4j:jar:sources": -662175280, + "org.slf4j:slf4j-api": -1249720338, + "org.slf4j:slf4j-api:jar:sources": -297247278, + "org.springdoc:springdoc-openapi-starter-common": -50810541, + "org.springdoc:springdoc-openapi-starter-common:jar:sources": 776689800, + "org.springdoc:springdoc-openapi-starter-webflux-api": -2128144311, + "org.springdoc:springdoc-openapi-starter-webflux-api:jar:sources": -1775632648, + "org.springdoc:springdoc-openapi-starter-webmvc-api": 479427887, + "org.springdoc:springdoc-openapi-starter-webmvc-api:jar:sources": -1201450538, + "org.springframework.boot:spring-boot": -1519545366, + "org.springframework.boot:spring-boot-actuator": 1868004981, + "org.springframework.boot:spring-boot-actuator-autoconfigure": 437017470, + "org.springframework.boot:spring-boot-actuator-autoconfigure:jar:sources": 1090885133, + "org.springframework.boot:spring-boot-actuator:jar:sources": 1545596535, + "org.springframework.boot:spring-boot-autoconfigure": -491644458, + "org.springframework.boot:spring-boot-autoconfigure:jar:sources": 562322138, + "org.springframework.boot:spring-boot-cassandra": 1880514148, + "org.springframework.boot:spring-boot-cassandra:jar:sources": -285158244, + "org.springframework.boot:spring-boot-data-cassandra": -1136414714, + "org.springframework.boot:spring-boot-data-cassandra-test": 1687171774, + "org.springframework.boot:spring-boot-data-cassandra-test:jar:sources": -601584645, + "org.springframework.boot:spring-boot-data-cassandra:jar:sources": 73983427, + "org.springframework.boot:spring-boot-data-commons": 1096447250, + "org.springframework.boot:spring-boot-data-commons:jar:sources": 867332098, + "org.springframework.boot:spring-boot-health": 988376788, + "org.springframework.boot:spring-boot-health:jar:sources": 1156692002, + "org.springframework.boot:spring-boot-http-client": -294534102, + "org.springframework.boot:spring-boot-http-client:jar:sources": 881974750, + "org.springframework.boot:spring-boot-http-codec": 434302862, + "org.springframework.boot:spring-boot-http-codec:jar:sources": 585983495, + "org.springframework.boot:spring-boot-http-converter": -1456188332, + "org.springframework.boot:spring-boot-http-converter:jar:sources": 678862764, + "org.springframework.boot:spring-boot-jackson": -886310726, + "org.springframework.boot:spring-boot-jackson:jar:sources": -928970153, + "org.springframework.boot:spring-boot-loader": 1516185416, + "org.springframework.boot:spring-boot-loader:jar:sources": 499181734, + "org.springframework.boot:spring-boot-micrometer-metrics": -971815116, + "org.springframework.boot:spring-boot-micrometer-metrics-test": 1059861465, + "org.springframework.boot:spring-boot-micrometer-metrics-test:jar:sources": 539702709, + "org.springframework.boot:spring-boot-micrometer-metrics:jar:sources": -1326033951, + "org.springframework.boot:spring-boot-micrometer-observation": -515345138, + "org.springframework.boot:spring-boot-micrometer-observation:jar:sources": -1374159176, + "org.springframework.boot:spring-boot-micrometer-tracing": -1769177987, + "org.springframework.boot:spring-boot-micrometer-tracing-opentelemetry": 686601187, + "org.springframework.boot:spring-boot-micrometer-tracing-opentelemetry:jar:sources": 2058843242, + "org.springframework.boot:spring-boot-micrometer-tracing:jar:sources": -531678236, + "org.springframework.boot:spring-boot-netty": -1868279944, + "org.springframework.boot:spring-boot-netty:jar:sources": 2079852054, + "org.springframework.boot:spring-boot-opentelemetry": -1423093456, + "org.springframework.boot:spring-boot-opentelemetry:jar:sources": 1840051882, + "org.springframework.boot:spring-boot-persistence": -1485790991, + "org.springframework.boot:spring-boot-persistence:jar:sources": -1027448649, + "org.springframework.boot:spring-boot-reactor": 1298372962, + "org.springframework.boot:spring-boot-reactor-netty": 1434335970, + "org.springframework.boot:spring-boot-reactor-netty:jar:sources": -732886702, + "org.springframework.boot:spring-boot-reactor:jar:sources": -1373689055, + "org.springframework.boot:spring-boot-restclient": -67067992, + "org.springframework.boot:spring-boot-restclient:jar:sources": -1554622109, + "org.springframework.boot:spring-boot-resttestclient": 1078416021, + "org.springframework.boot:spring-boot-resttestclient:jar:sources": 1128597445, + "org.springframework.boot:spring-boot-security": -528218864, + "org.springframework.boot:spring-boot-security-oauth2-client": 1972725629, + "org.springframework.boot:spring-boot-security-oauth2-client:jar:sources": -1211778370, + "org.springframework.boot:spring-boot-security-oauth2-resource-server": -1021125134, + "org.springframework.boot:spring-boot-security-oauth2-resource-server:jar:sources": 1301519418, + "org.springframework.boot:spring-boot-security-test": -1810341741, + "org.springframework.boot:spring-boot-security-test:jar:sources": -311791400, + "org.springframework.boot:spring-boot-security:jar:sources": -1644906067, + "org.springframework.boot:spring-boot-servlet": -1040246830, + "org.springframework.boot:spring-boot-servlet:jar:sources": 1162002660, + "org.springframework.boot:spring-boot-starter": 191814674, + "org.springframework.boot:spring-boot-starter-actuator": 1761935967, + "org.springframework.boot:spring-boot-starter-actuator-test": 910069034, + "org.springframework.boot:spring-boot-starter-actuator-test:jar:sources": 314973026, + "org.springframework.boot:spring-boot-starter-actuator:jar:sources": -2079433447, + "org.springframework.boot:spring-boot-starter-aspectj": 740892542, + "org.springframework.boot:spring-boot-starter-aspectj:jar:sources": 1957689077, + "org.springframework.boot:spring-boot-starter-data-cassandra": -1305411192, + "org.springframework.boot:spring-boot-starter-data-cassandra-test": 1049224325, + "org.springframework.boot:spring-boot-starter-data-cassandra-test:jar:sources": 464889083, + "org.springframework.boot:spring-boot-starter-data-cassandra:jar:sources": 62860247, + "org.springframework.boot:spring-boot-starter-jackson": 211326145, + "org.springframework.boot:spring-boot-starter-jackson-test": 538761659, + "org.springframework.boot:spring-boot-starter-jackson-test:jar:sources": 1211585483, + "org.springframework.boot:spring-boot-starter-jackson:jar:sources": 1689728463, + "org.springframework.boot:spring-boot-starter-logging": 51215582, + "org.springframework.boot:spring-boot-starter-logging:jar:sources": 1271111015, + "org.springframework.boot:spring-boot-starter-micrometer-metrics": 546085162, + "org.springframework.boot:spring-boot-starter-micrometer-metrics-test": -835747019, + "org.springframework.boot:spring-boot-starter-micrometer-metrics-test:jar:sources": 1830581000, + "org.springframework.boot:spring-boot-starter-micrometer-metrics:jar:sources": -1130818080, + "org.springframework.boot:spring-boot-starter-reactor-netty": 812139334, + "org.springframework.boot:spring-boot-starter-reactor-netty:jar:sources": 1164956430, + "org.springframework.boot:spring-boot-starter-security": 1058973423, + "org.springframework.boot:spring-boot-starter-security-oauth2-client": -1355057519, + "org.springframework.boot:spring-boot-starter-security-oauth2-client:jar:sources": 1707609356, + "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server": -265511875, + "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server-test": -17384836, + "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server-test:jar:sources": -746940353, + "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server:jar:sources": 2136275088, + "org.springframework.boot:spring-boot-starter-security-test": 1690721902, + "org.springframework.boot:spring-boot-starter-security-test:jar:sources": 468207576, + "org.springframework.boot:spring-boot-starter-security:jar:sources": -1720617031, + "org.springframework.boot:spring-boot-starter-test": -1087542039, + "org.springframework.boot:spring-boot-starter-test:jar:sources": -480189945, + "org.springframework.boot:spring-boot-starter-tomcat": -521361670, + "org.springframework.boot:spring-boot-starter-tomcat-runtime": -1912812722, + "org.springframework.boot:spring-boot-starter-tomcat-runtime:jar:sources": 1011838045, + "org.springframework.boot:spring-boot-starter-tomcat:jar:sources": 1319064174, + "org.springframework.boot:spring-boot-starter-validation": -321633530, + "org.springframework.boot:spring-boot-starter-validation:jar:sources": -1002865328, + "org.springframework.boot:spring-boot-starter-web": 1122240419, + "org.springframework.boot:spring-boot-starter-web:jar:sources": -768709610, + "org.springframework.boot:spring-boot-starter-webflux": -818164168, + "org.springframework.boot:spring-boot-starter-webflux-test": -415179163, + "org.springframework.boot:spring-boot-starter-webflux-test:jar:sources": -1654084055, + "org.springframework.boot:spring-boot-starter-webflux:jar:sources": 1008425882, + "org.springframework.boot:spring-boot-starter-webmvc": 170962824, + "org.springframework.boot:spring-boot-starter-webmvc-test": -1343848488, + "org.springframework.boot:spring-boot-starter-webmvc-test:jar:sources": -1751111514, + "org.springframework.boot:spring-boot-starter-webmvc:jar:sources": -2120956724, + "org.springframework.boot:spring-boot-starter:jar:sources": 1138639700, + "org.springframework.boot:spring-boot-test": -927444958, + "org.springframework.boot:spring-boot-test-autoconfigure": -669950838, + "org.springframework.boot:spring-boot-test-autoconfigure:jar:sources": 392165449, + "org.springframework.boot:spring-boot-test:jar:sources": -1764708648, + "org.springframework.boot:spring-boot-tomcat": -1113349252, + "org.springframework.boot:spring-boot-tomcat:jar:sources": -1529683395, + "org.springframework.boot:spring-boot-validation": 1270368638, + "org.springframework.boot:spring-boot-validation:jar:sources": -1684576067, + "org.springframework.boot:spring-boot-web-server": 285708094, + "org.springframework.boot:spring-boot-web-server:jar:sources": 990724443, + "org.springframework.boot:spring-boot-webclient": -507647, + "org.springframework.boot:spring-boot-webclient:jar:sources": 71538120, + "org.springframework.boot:spring-boot-webflux": -231291542, + "org.springframework.boot:spring-boot-webflux-test": 1600114323, + "org.springframework.boot:spring-boot-webflux-test:jar:sources": 1452173744, + "org.springframework.boot:spring-boot-webflux:jar:sources": -1118813321, + "org.springframework.boot:spring-boot-webmvc": -2104103221, + "org.springframework.boot:spring-boot-webmvc-test": 749235095, + "org.springframework.boot:spring-boot-webmvc-test:jar:sources": 444837917, + "org.springframework.boot:spring-boot-webmvc:jar:sources": -1895028417, + "org.springframework.boot:spring-boot-webtestclient": -705991472, + "org.springframework.boot:spring-boot-webtestclient:jar:sources": -542316343, + "org.springframework.boot:spring-boot:jar:sources": 580880564, + "org.springframework.cloud:spring-cloud-commons": -788453967, + "org.springframework.cloud:spring-cloud-commons:jar:sources": 1320616004, + "org.springframework.cloud:spring-cloud-context": 1118197933, + "org.springframework.cloud:spring-cloud-context:jar:sources": -1413797918, + "org.springframework.cloud:spring-cloud-kubernetes-client-autoconfig": -1665956951, + "org.springframework.cloud:spring-cloud-kubernetes-client-autoconfig:jar:sources": 758022911, + "org.springframework.cloud:spring-cloud-kubernetes-client-config": -325837469, + "org.springframework.cloud:spring-cloud-kubernetes-client-config:jar:sources": -251471561, + "org.springframework.cloud:spring-cloud-kubernetes-commons": -500725348, + "org.springframework.cloud:spring-cloud-kubernetes-commons:jar:sources": -325491963, + "org.springframework.cloud:spring-cloud-starter": -1812063683, + "org.springframework.cloud:spring-cloud-starter-bootstrap": -1263482746, + "org.springframework.cloud:spring-cloud-starter-bootstrap:jar:sources": 1965832056, + "org.springframework.cloud:spring-cloud-starter-kubernetes-client-config": -710796001, + "org.springframework.data:spring-data-cassandra": -1548120966, + "org.springframework.data:spring-data-cassandra:jar:sources": -1628107854, + "org.springframework.data:spring-data-commons": 1312199320, + "org.springframework.data:spring-data-commons:jar:sources": 544548950, + "org.springframework.retry:spring-retry": -2038056656, + "org.springframework.retry:spring-retry:jar:sources": -870799349, + "org.springframework.security:spring-security-config": 2001744589, + "org.springframework.security:spring-security-config:jar:sources": -756968726, + "org.springframework.security:spring-security-core": -1251894794, + "org.springframework.security:spring-security-core:jar:sources": 1285888871, + "org.springframework.security:spring-security-crypto": 424824057, + "org.springframework.security:spring-security-crypto:jar:sources": 1862561396, + "org.springframework.security:spring-security-oauth2-client": -1975050683, + "org.springframework.security:spring-security-oauth2-client:jar:sources": 1833974239, + "org.springframework.security:spring-security-oauth2-core": -1658804453, + "org.springframework.security:spring-security-oauth2-core:jar:sources": -948845785, + "org.springframework.security:spring-security-oauth2-jose": 502613895, + "org.springframework.security:spring-security-oauth2-jose:jar:sources": 17294361, + "org.springframework.security:spring-security-oauth2-resource-server": -1894007153, + "org.springframework.security:spring-security-oauth2-resource-server:jar:sources": -1508178760, + "org.springframework.security:spring-security-test": 1672796517, + "org.springframework.security:spring-security-test:jar:sources": -1326480212, + "org.springframework.security:spring-security-web": -1696304083, + "org.springframework.security:spring-security-web:jar:sources": 1443816202, + "org.springframework:spring-aop": -819786825, + "org.springframework:spring-aop:jar:sources": 1924976574, + "org.springframework:spring-beans": -698130853, + "org.springframework:spring-beans:jar:sources": -2147408778, + "org.springframework:spring-context": -846077202, + "org.springframework:spring-context-support": 427709038, + "org.springframework:spring-context-support:jar:sources": -410245914, + "org.springframework:spring-context:jar:sources": -1263444176, + "org.springframework:spring-core": -253727183, + "org.springframework:spring-core:jar:sources": -173347576, + "org.springframework:spring-expression": 1724609785, + "org.springframework:spring-expression:jar:sources": 1135225455, + "org.springframework:spring-test": -279979944, + "org.springframework:spring-test:jar:sources": -6017836, + "org.springframework:spring-tx": 1899606770, + "org.springframework:spring-tx:jar:sources": -1007028336, + "org.springframework:spring-web": 2084009704, + "org.springframework:spring-web:jar:sources": 1608360284, + "org.springframework:spring-webflux": 1763806581, + "org.springframework:spring-webflux:jar:sources": -1419709374, + "org.springframework:spring-webmvc": 56813816, + "org.springframework:spring-webmvc:jar:sources": -837106767, + "org.testcontainers:testcontainers": 450183679, + "org.testcontainers:testcontainers-cassandra": 584880112, + "org.testcontainers:testcontainers-cassandra:jar:sources": 2024290088, + "org.testcontainers:testcontainers-database-commons": -1213526598, + "org.testcontainers:testcontainers-database-commons:jar:sources": 315333060, + "org.testcontainers:testcontainers-junit-jupiter": -1827576744, + "org.testcontainers:testcontainers-junit-jupiter:jar:sources": 975697823, + "org.testcontainers:testcontainers-localstack": 744979553, + "org.testcontainers:testcontainers-localstack:jar:sources": 311852137, + "org.testcontainers:testcontainers:jar:sources": 76092129, + "org.wiremock:wiremock-standalone": -1817681233, + "org.wiremock:wiremock-standalone:jar:sources": 695361099, + "org.xmlunit:xmlunit-core": 1938864481, + "org.xmlunit:xmlunit-core:jar:sources": -54376142, + "org.yaml:snakeyaml": -1432706414, + "org.yaml:snakeyaml:jar:sources": 393768628, + "software.amazon.awssdk:annotations": -647669452, + "software.amazon.awssdk:annotations:jar:sources": -277384386, + "software.amazon.awssdk:checksums": 573213413, + "software.amazon.awssdk:checksums-spi": -720493267, + "software.amazon.awssdk:checksums-spi:jar:sources": -650776626, + "software.amazon.awssdk:checksums:jar:sources": -241565759, + "software.amazon.awssdk:endpoints-spi": 1412926322, + "software.amazon.awssdk:endpoints-spi:jar:sources": -1092637607, + "software.amazon.awssdk:http-auth-aws": -589182304, + "software.amazon.awssdk:http-auth-aws:jar:sources": -993506252, + "software.amazon.awssdk:http-auth-spi": -45686548, + "software.amazon.awssdk:http-auth-spi:jar:sources": -1486999869, + "software.amazon.awssdk:http-client-spi": 1386281563, + "software.amazon.awssdk:http-client-spi:jar:sources": 541891925, + "software.amazon.awssdk:identity-spi": -969758372, + "software.amazon.awssdk:identity-spi:jar:sources": -1418587191, + "software.amazon.awssdk:json-utils": -1666742251, + "software.amazon.awssdk:json-utils:jar:sources": 1618084806, + "software.amazon.awssdk:metrics-spi": -500500368, + "software.amazon.awssdk:metrics-spi:jar:sources": -1496041869, + "software.amazon.awssdk:profiles": 1556987661, + "software.amazon.awssdk:profiles:jar:sources": 517790158, + "software.amazon.awssdk:regions": 1394259783, + "software.amazon.awssdk:regions:jar:sources": 927040140, + "software.amazon.awssdk:retries": 1273159411, + "software.amazon.awssdk:retries-spi": 1857446587, + "software.amazon.awssdk:retries-spi:jar:sources": -974151310, + "software.amazon.awssdk:retries:jar:sources": 1826499536, + "software.amazon.awssdk:sdk-core": 1641186658, + "software.amazon.awssdk:sdk-core:jar:sources": -769872481, + "software.amazon.awssdk:third-party-jackson-core": -1062653941, + "software.amazon.awssdk:third-party-jackson-core:jar:sources": -230379012, + "software.amazon.awssdk:utils": 1497168994, + "software.amazon.awssdk:utils:jar:sources": 249477790, + "tools.jackson.core:jackson-core": -1258054011, + "tools.jackson.core:jackson-core:jar:sources": -1689479769, + "tools.jackson.core:jackson-databind": 1443518747, + "tools.jackson.core:jackson-databind:jar:sources": -871567409, + "tools.jackson.module:jackson-module-blackbird": 1038981586, + "tools.jackson.module:jackson-module-blackbird:jar:sources": -9825245 + }, + "artifacts": { + "aopalliance:aopalliance": { + "shasums": { + "jar": "0addec670fedcd3f113c5c8091d783280d23f75e3acb841b61a9cdb079376a08", + "sources": "e6ef91d439ada9045f419c77543ebe0416c3cdfc5b063448343417a3e4a72123" + }, + "version": "1.0" + }, + "args4j:args4j": { + "shasums": { + "jar": "11b029a602e787e2bc08eb3b77eda1a4f5e8b263d22e3c5d6220cd5c51f30b18", + "sources": "ec1eb6aa4859b9b4fd9da4d58efb28b2eb629a4c14919e9078054879540243b7" + }, + "version": "2.0.28" + }, + "at.yawk.lz4:lz4-java": { + "shasums": { + "jar": "49753ae8a9b7dc3ce48cb2989cc6605e43eb8269748ad3466251836ec4cd02a8", + "sources": "3b9a0590c53a4f4e45b204695af0e480dbd4f3a589913c6a36f7c2c3d31b0eaa" + }, + "version": "1.10.3" + }, + "ch.qos.logback:logback-classic": { + "shasums": { + "jar": "b65e05076a5c1aadb659b4fe4bc5fee31cb26cd70390292eb03e4a7a24cff10f", + "sources": "c2e39cb4d6d9b8c2343c6da2469e21e1d6aef2dde16c2227762c084d549ad0a0" + }, + "version": "1.5.34" + }, + "ch.qos.logback:logback-core": { + "shasums": { + "jar": "42eda264c0c650c2bec59e66151a88b708a8663dc1b49d788202d53e78b8caae", + "sources": "6a9f217ef206caf2880810c505e057fd2bb90a6024013906815e9513c6e488c5" + }, + "version": "1.5.34" + }, + "com.bucket4j:bucket4j-core": { + "shasums": { + "jar": "c274208e4961855e8e341bcb74434af8771ce98a494aec48997028efeb4909f2", + "sources": "fb9270f4aef9d0688e12f9b83553fe2bc1fa0c15bd98894579c3f19b489ef4dc" + }, + "version": "8.10.1" + }, + "com.bucket4j:bucket4j_jdk17-core": { + "shasums": { + "jar": "603885663799e203f7e17394315fdbdc584fe021643614d8a34b49b53e618c74", + "sources": "e68a40186a9ef6f80e05db48ac76d7beca94b8d5bd635fb22aeab784ad16a520" + }, + "version": "8.19.0" + }, + "com.datastax.cassandra:cassandra-driver-core": { + "shasums": { + "jar": "09c4d54009e942e3afb8755c5fd51abac8ba721e407b61dcb22f435d1a33c1a1", + "sources": "b0e1d20dd052986f1cc1511fee039801ebb1ae3474a14f0708bedf9b6278083d" + }, + "version": "3.10.0" + }, + "com.datastax.oss:native-protocol": { + "shasums": { + "jar": "190dc40f3c63d6d803c48f90d457e06c65e6c5d955e47d4735dc9954a6743655", + "sources": "6029f3fd12ebe066826642d42f0efb63108b051577828458b66a8637847e88c9" + }, + "version": "1.5.2" + }, + "com.fasterxml.jackson.core:jackson-annotations": { + "shasums": { + "jar": "53ca085f4a150f703f49e1aabd935bd03b43e1ea3d55d135438292af22cef56b", + "sources": "71fe6323d91b16d5d1007fd1e1533fa06bb369abde74f68a42a68c0f8f061a8b" + }, + "version": "2.21" + }, + "com.fasterxml.jackson.core:jackson-core": { + "shasums": { + "jar": "4b40a06396f239f8de2da57419adde6e94e5edc18a2171d471ea05eeed4e5c2d", + "sources": "90ccada55626ce4f00a81bde235af0a942ec2bc4c701fcc86a93af1be9b3e08d" + }, + "version": "2.21.4" + }, + "com.fasterxml.jackson.core:jackson-databind": { + "shasums": { + "jar": "3888e9e69ab66fbacaacc9aea0e9ffbf15368288e4aca468b024dba11c09fbf9", + "sources": "23188e78e912c9866367bf038fb7f729e79f1c2724174ca66e0a00915de70e61" + }, + "version": "2.21.4" + }, + "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml": { + "shasums": { + "jar": "055eb4c008ab12f0cb63e93a6454463d032fde0fca85943d69f8dc7469489e4b", + "sources": "164cef68956eb2797e421dd6cf74bfd648581965a8df2389c260bb363d1f3baa" + }, + "version": "2.21.4" + }, + "com.fasterxml.jackson.datatype:jackson-datatype-jsr310": { + "shasums": { + "jar": "d1ac4b98b70304e56448423589fde5e775b100889643ad1ead62cc7811633684", + "sources": "884a8812af289bb56f38f09a4b3b7b73b4a16dbc184ae735fbe6c4aa1089161f" + }, + "version": "2.21.4" + }, + "com.fasterxml:classmate": { + "shasums": { + "jar": "75fbda45456f123fb6e2028a6189442d8d0730b357adce4c0a6d7e789f70669b", + "sources": "b0690a771dc54865c3d0ad9ab6abb319633b6b88849900a28f719e792c15fc68" + }, + "version": "1.7.3" + }, + "com.github.ben-manes.caffeine:caffeine": { + "shasums": { + "jar": "9d9d2cfd681fd9272ded3d27c9930db12f89f732345975aa113ebc223bbf1224", + "sources": "5079e1b327d79e2fc8ae3f5927587e59c968603e63785fb33479acd8b732211d" + }, + "version": "3.2.4" + }, + "com.github.ben-manes.caffeine:guava": { + "shasums": { + "jar": "7819335459a43b3d2d501bd19b6cf880041a1ad47a9a118d018d89c432357358", + "sources": "2de42779d0ee1807262065382a9302715b2d8daa186f9b39aca1043c10681ab5" + }, + "version": "3.2.4" + }, + "com.github.docker-java:docker-java-api": { + "shasums": { + "jar": "dad153d484b1f4ef009e2fdbad27e07aeb3191122da52b8985507ac504300081", + "sources": "57c9b5bc37d48c256a2a0de556095158f363b10eec58052e58f299c542cf9391" + }, + "version": "3.7.1" + }, + "com.github.docker-java:docker-java-transport": { + "shasums": { + "jar": "d15eec8034bf0f92c2a48ca9172691804048115c96dc853272f9486fa2695c3c", + "sources": "131ed62714d94125f89a3c3ad966e517c8ad48fbbc1905b08bcdafc0d6e9de45" + }, + "version": "3.7.1" + }, + "com.github.docker-java:docker-java-transport-zerodep": { + "shasums": { + "jar": "b89bdb1754160323597f9ea32a7fe7a4a3aa8f5b3b43b88e8d71fff3b267ab21", + "sources": "f4d1457f9e2e151d19713e46cf2b49796887d5a9744664a15a4ce07c76660883" + }, + "version": "3.7.1" + }, + "com.github.java-json-tools:btf": { + "shasums": { + "jar": "67c3e462eb50807f4e0a5f4dee304bbf17cd986a42ee5eb0b2f4c9bf64d130d9", + "sources": "97f8bfb9a8876534bf2832a5be4b913b695d72c6ff6f9c8c6719bd38fd4aeb73" + }, + "version": "1.3" + }, + "com.github.java-json-tools:jackson-coreutils": { + "shasums": { + "jar": "16b3aabd3a9eb25655dda433e35f9bd9c7c1aa7991427702f5f11f000813dbb0", + "sources": "6f39b6beed5b000702ade7014be2ca21f895a0b70ab6c199f6ca5bebc1807080" + }, + "version": "2.0" + }, + "com.github.java-json-tools:json-patch": { + "shasums": { + "jar": "1f794d256965b53ef37e70b55505e2ed00ddc0184d44e2e8e1fdce5a3cacc7de", + "sources": "f4ba54ca57611123fe972f05537d44d4b61fd8ed6f71541b3ca37e09a6e3e318" + }, + "version": "1.13" + }, + "com.github.java-json-tools:msg-simple": { + "shasums": { + "jar": "bef4111b993a5b3e6148d8f585621cceac2a1889cdbc34448b11632e0d8a9a8f", + "sources": "eeb0ecd504611cec75f261a6d282bb8b80214e473ef235481c8067b6b121f1cd" + }, + "version": "1.2" + }, + "com.github.jnr:jffi": { + "shasums": { + "jar": "7a616bb7dc6e10531a28a098078f8184df9b008d5231bdc5f1c131839385335f", + "native": "ef78953e3dbf47fab94469190bc2a6d601566a21d4651f73c822bad1c02b64fe", + "sources": "45ad89d2774e9d03de89905cf990d49d5821ce8012a841faddf23dca02538d72" + }, + "version": "1.2.16" + }, + "com.github.jnr:jnr-constants": { + "shasums": { + "jar": "a617b0d8463d3ea36435bd1611113dedb3749157afd2269908ab306c992aefed", + "sources": "9406718df04cd893a94933213b370d99c613d94d80e23119e2cf8dc51394ea12" + }, + "version": "0.10.3" + }, + "com.github.jnr:jnr-ffi": { + "shasums": { + "jar": "2ed1bedf59935cd3cc0964bac5cd91638b2e966a82041fe0a6c85f52279c9b34", + "sources": "61842708c7e617ae2ca3a389931142f506f854104392fa6f7aaac6f51c93cf58" + }, + "version": "2.1.7" + }, + "com.github.jnr:jnr-posix": { + "shasums": { + "jar": "c38ecfccd24e5f21f17a62e45d5bd454842c5db17ed42b01b868f9206d0e99e7", + "sources": "abfff56a7628d223ba86c3ccb3bcb5101aeefdeedbe58c3c52b1917a92d7e332" + }, + "version": "3.1.15" + }, + "com.github.jnr:jnr-x86asm": { + "shasums": { + "jar": "39f3675b910e6e9b93825f8284bec9f4ad3044cd20a6f7c8ff9e2f8695ebf21e", + "sources": "3c983efd496f95ea5382ca014f96613786826136e0ce13d5c1cbc3097ea92ca0" + }, + "version": "1.0.2" + }, + "com.github.stephenc.jcip:jcip-annotations": { + "shasums": { + "jar": "4fccff8382aafc589962c4edb262f6aa595e34f1e11e61057d1c6a96e8fc7323", + "sources": "d60bb3bf4e03a5e405f9b16f4c2625de86089d6ce4f999bcc2548dcac090ae19" + }, + "version": "1.0-1" + }, + "com.google.android:annotations": { + "shasums": { + "jar": "ba734e1e84c09d615af6a09d33034b4f0442f8772dec120efb376d86a565ae15", + "sources": "e9b667aa958df78ea1ad115f7bbac18a5869c3128b1d5043feb360b0cfce9d40" + }, + "version": "4.1.1.4" + }, + "com.google.api.grpc:proto-google-common-protos": { + "shasums": { + "jar": "ee9c751f06b112e92b37f75e4f73a17d03ef2c3302c6e8d986adbcc721b63cb0", + "sources": "fe7831089c20c097ef540b61ff90d12cfe0fbc57c2bbe21a3e8fa96bb0085d99" + }, + "version": "2.29.0" + }, + "com.google.code.findbugs:jsr305": { + "shasums": { + "jar": "766ad2a0783f2687962c8ad74ceecc38a28b9f72a2d085ee438b7813e928d0c7", + "sources": "1c9e85e272d0708c6a591dc74828c71603053b48cc75ae83cce56912a2aa063b" + }, + "version": "3.0.2" + }, + "com.google.code.gson:gson": { + "shasums": { + "jar": "d3999291855de495c94c743761b8ab5176cfeabe281a5ab0d8e8d45326fd703e", + "sources": "ba5bddb1a89eb721fcca39f3b34294532060f851e2407a82d82134a41eec4719" + }, + "version": "2.8.9" + }, + "com.google.errorprone:error_prone_annotations": { + "shasums": { + "jar": "ff80626baaf12a09342befd4e84cba9d50662f5fcd7f7a9b3490a6b7cf87e66c", + "sources": "bf08616e340f5e2ef50aaa84aea8baa086fd7bb2ad310501ff4e88ec77f8f31a" + }, + "version": "2.5.1" + }, + "com.google.guava:failureaccess": { + "shasums": { + "jar": "a171ee4c734dd2da837e4b16be9df4661afab72a41adaf31eb84dfdaf936ca26", + "sources": "092346eebbb1657b51aa7485a246bf602bb464cc0b0e2e1c7e7201fadce1e98f" + }, + "version": "1.0.1" + }, + "com.google.guava:guava": { + "shasums": { + "jar": "bd7fa227591fb8509677d0d1122cf95158f3b8a9f45653f58281d879f6dc48c5", + "sources": "9105dfc522fb440b39ff8da07cc56aacf65a9f765044c7803a9f32e36e05a22b" + }, + "version": "32.0.1-jre" + }, + "com.google.guava:listenablefuture": { + "shasums": { + "jar": "b372a037d4230aa57fbeffdef30fd6123f9c0c2db85d0aced00c91b974f33f99" + }, + "version": "9999.0-empty-to-avoid-conflict-with-guava" + }, + "com.google.j2objc:j2objc-annotations": { + "shasums": { + "jar": "f02a95fa1a5e95edb3ed859fd0fb7df709d121a35290eff8b74dce2ab7f4d6ed", + "sources": "7413eed41f111453a08837f5ac680edded7faed466cbd35745e402e13f4cc3f5" + }, + "version": "2.8" + }, + "com.google.protobuf:protobuf-java": { + "shasums": { + "jar": "3ca892fd6ea8b37d01bb6917dbc0bf2637548b756753f65a28d4f1d4d982347f", + "sources": "ed30fe6a51c7c15a6f123448304c97185f2039f2aeca9d5e3b4f53de3a4c813c" + }, + "version": "4.33.4" + }, + "com.google.protobuf:protobuf-java-util": { + "shasums": { + "jar": "6f02f04c5ca088e74b68dbbaf118f1ffa9d587958e637f893e0f8a1899a61342", + "sources": "4bf8ae758fdaae56220796e651cf5fbc3f7ce99bdc42b7048c2604f757592f8a" + }, + "version": "4.33.4" + }, + "com.jayway.jsonpath:json-path": { + "shasums": { + "jar": "890daa95dd3892d34d9fabc27cd5153656e6f369358625c88f4dc7b79cbd6c5a", + "sources": "357f1c52217497c4251fae715ba8ef76ae310b1aae77ea319260bf4c6ad61440" + }, + "version": "2.10.0" + }, + "com.nimbusds:content-type": { + "shasums": { + "jar": "60349793e006fba96b532cb0c21e10e969fe0db8d87f91c3b9eaf82ba2998895", + "sources": "9a154c802659594d8745a0e364bd2e6b418e010268467cd222354445dd77d626" + }, + "version": "2.3" + }, + "com.nimbusds:lang-tag": { + "shasums": { + "jar": "e8c1c594e2425bdbea2d860de55c69b69fc5d59454452449a0f0913c2a5b8a31", + "sources": "8d37da312db366d702bd7254df6bceca0a7814e18da9c32db9cc1d8ca038c468" + }, + "version": "1.7" + }, + "com.nimbusds:nimbus-jose-jwt": { + "shasums": { + "jar": "6f13f3480ddc53d820d276f582f54843cff1daf5c6e35e534947e9de7723b46b", + "sources": "b3fd3b569013246fb9a1ac6b43ff3e3033065bce16de92ecf4c971d14875eb30" + }, + "version": "10.4" + }, + "com.nimbusds:oauth2-oidc-sdk": { + "shasums": { + "jar": "648494b00da090a4df23aa6a05e4dc03f6e8603b29dd807a4491f33d586f7f78", + "sources": "e4de2ef818fbb57aa3731b65e2f5edc1a40dc1e3f6e6541306ca9f45490aed2a" + }, + "version": "11.26.1" + }, + "com.squareup.okhttp3:logging-interceptor": { + "shasums": { + "jar": "f3e8d5f0903c250c2b55d2f47fcfe008e80634385da8385161c7a63aaed0c74c", + "sources": "967335783f8af3fca7819f9f343f753243f2877c5480099e2084fe493af7da82" + }, + "version": "4.12.0" + }, + "com.squareup.okhttp3:okhttp": { + "shasums": { + "jar": "b1050081b14bb7a3a7e55a4d3ef01b5dcfabc453b4573a4fc019767191d5f4e0", + "sources": "d91a769a4140e542cddbac4e67fcf279299614e8bfd53bd23b85e60c2861341c" + }, + "version": "4.12.0" + }, + "com.squareup.okhttp3:okhttp-jvm": { + "shasums": { + "jar": "9632c08567dbb21c569b13d793107834c8580d44e4eea74b2eae0722f0506179", + "sources": "9fa32be62c7a46ffe70cdb1bf7e195f5ee3fc885999379292cb636b5aa311704" + }, + "version": "5.2.1" + }, + "com.squareup.okio:okio": { + "shasums": { + "jar": "8e63292e5c53bb93c4a6b0c213e79f15990fed250c1340f1c343880e1c9c39b5", + "sources": "64d5b6667f064511dd93100173f735b2d5052a1c926858f4b6a05b84e825ef94" + }, + "version": "3.6.0" + }, + "com.squareup.okio:okio-jvm": { + "shasums": { + "jar": "31f48e6463ec587d6d262d042c91da00659c983b6ad20d5982bf31e85222693c", + "sources": "b29b5f4ad1adfd7cbfb3d388f7bf29d1702f0b85be1b6c61b0185ce7e2b2e6dc" + }, + "version": "3.16.1" + }, + "com.typesafe:config": { + "shasums": { + "jar": "4c0aa7e223c75c8840c41fc183d4cd3118140a1ee503e3e08ce66ed2794c948f", + "sources": "89af318a607f7e2b2691ed1ef4b4890bd37ea17d6986b0aec50dd4d5f889520c" + }, + "version": "1.4.1" + }, + "com.vaadin.external.google:android-json": { + "shasums": { + "jar": "dfb7bae2f404cfe0b72b4d23944698cb716b7665171812a0a4d0f5926c0fac79", + "sources": "54c781eea645c450cbbc4a5a1b5a474745465452cec1354cb567b781ea6622c3" + }, + "version": "0.0.20131108.vaadin1" + }, + "commons-codec:commons-codec": { + "shasums": { + "jar": "5c3881e4f556855e9c532927ee0c9dfde94cc66760d5805c031a59887070af5f", + "sources": "b0462142585d45fc15bc8091b7b02f1e3a85c83595068659548c82cac9cdc7a2" + }, + "version": "1.19.0" + }, + "commons-io:commons-io": { + "shasums": { + "jar": "df90bba0fe3cb586b7f164e78fe8f8f4da3f2dd5c27fa645f888100ccc25dd72", + "sources": "7a87277538cce40da6389a7163a4d9458bc7a9c39937a329881b91d144be8e0d" + }, + "version": "2.20.0" + }, + "commons-logging:commons-logging": { + "shasums": { + "jar": "f8ead8943401081dea0aa824b5b1ba40a0e4ed297a572a0f02258150a0b62357", + "sources": "6e821e03cfc64e509cc162d428af84697b6c4188eb14c0b137c75b69649976ef" + }, + "version": "1.3.6" + }, + "io.cloudevents:cloudevents-api": { + "shasums": { + "jar": "95751500be617f0c795ea3cd7c370fa712459da500fbd22bb8b7f69fcba46e97", + "sources": "962306ae4d9c9aaea5958a3e5e837c895bc683098c2da7f2fa8e972dfea82ebd" + }, + "version": "4.1.1" + }, + "io.cloudevents:cloudevents-core": { + "shasums": { + "jar": "25c3756d184eebf20aceadbd2357cd48516938ca458a1b77a3ebdc09f8dfc592", + "sources": "869ae88ca9b7f7e62af3f34ae6269e7c816b58d08ef371040530164e2aaea02a" + }, + "version": "4.1.1" + }, + "io.cloudevents:cloudevents-json-jackson": { + "shasums": { + "jar": "28aa328c61ae1783cecb430f7b51880e365ea8678628eca416e12654eafbb66d", + "sources": "b4ee1b7db2dfa50101a9fa7a3beef610b6931546be1bc5a61ae28cc929473406" + }, + "version": "4.1.1" + }, + "io.dropwizard.metrics:metrics-core": { + "shasums": { + "jar": "5c6f685e41664d10c70c65837cba9e58d39ff3896811e3b5707a934b11c85ad0", + "sources": "773164a026ea78df51d14608def3a746a2270f630e9a2f5f6f99d6e155ad5bcf" + }, + "version": "3.2.2" + }, + "io.grpc:grpc-api": { + "shasums": { + "jar": "21d747911e1e5931004f1b058417f3c3f72f1fbf8aea16f5fc6af7a3f0caf35a", + "sources": "7ff367383a7e67241d72404f584a73d47d8f0a6b4c0bdf8aca4170f6475e58a3" + }, + "version": "1.63.0" + }, + "io.grpc:grpc-context": { + "shasums": { + "jar": "fec0773020404a1f9b9610168692c8ed47fb77181c2ba37cc842ba7664bfc6b0", + "sources": "0a45ca2dc3452783be72412c0e75e0a57c276e76d29d778a22e331279f08d5c0" + }, + "version": "1.74.0" + }, + "io.grpc:grpc-core": { + "shasums": { + "jar": "5175e6223ee1f0a63cf93049aabe7bd5b675cc739b286fe3b320a88fa90c320e", + "sources": "2c7a8d053a2bfa7c423ca01f1b6462bf402ff710aea8c49a73c2d0d73ba8e358" + }, + "version": "1.74.0" + }, + "io.grpc:grpc-inprocess": { + "shasums": { + "jar": "5386e23de85651bf868c3565bfa4f1af1bb9c888d8de5ae4350e010064041336", + "sources": "55a86f1a031e1c7dfe4bae6b6350ff561003e0395ca2c3af5114a3aab8afaa22" + }, + "version": "1.63.0" + }, + "io.grpc:grpc-netty": { + "shasums": { + "jar": "8ead962173ff44752a1970b6e567225e1e9aeebb5c74af1e33e7786a45c9d620", + "sources": "cc8b33cf89f7ab51c14c8ac5eae47ffccb9836216ecd0bbe311f8e774f3aac86" + }, + "version": "1.74.0" + }, + "io.grpc:grpc-netty-shaded": { + "shasums": { + "jar": "4d170c599e47214f35c8955cda3edd7cdb8171229b45795d4d61eb43dfa76402", + "sources": "a9032f8d2f795247bef60b45ee5fc3eb4693c705c05818cc12e9ed1deba440d4" + }, + "version": "1.63.0" + }, + "io.grpc:grpc-protobuf": { + "shasums": { + "jar": "260e0abaf8ac72fc71deec9f88d2beeb163e6d19494bbabe45676a4b4ce87087", + "sources": "e44785571580c4bfc25582a739f66acacf4af030bb6d58d8459532d4570225a6" + }, + "version": "1.63.0" + }, + "io.grpc:grpc-protobuf-lite": { + "shasums": { + "jar": "5e7f36c03600c7cfa8e10d2d0321f0ba8c32d74cd044873f44b026704f355fb7", + "sources": "0464b0b77b4360c0f9916477859abbbf22457a9d18c343743635e7247c2af684" + }, + "version": "1.63.0" + }, + "io.grpc:grpc-services": { + "shasums": { + "jar": "5258358c47d5afb1dc8fd6bc869c93b02bce686c156f5e0a1aab5d39b1d8e0a5", + "sources": "d265c23748ecd5c15142978d38798e8db4a2cd146cf7fe6f8cb535f202219561" + }, + "version": "1.63.0" + }, + "io.grpc:grpc-stub": { + "shasums": { + "jar": "a92fc7c7f1ac9d580c5e3df5825b977c842f442874794663b78db22b27d649e0", + "sources": "77cf1024d4612bf7ec085ff330456eb49cdbaa93e21559396f07b063ea289238" + }, + "version": "1.63.0" + }, + "io.grpc:grpc-util": { + "shasums": { + "jar": "296dc07438c43454afc1a7f2736086550feb1fc783f9547337ad2ae721e24350", + "sources": "ba7b02ef3f3a7ed93881c1c37db8b7372458215c7e2e7d57d1a7fc91725d94e1" + }, + "version": "1.74.0" + }, + "io.gsonfire:gson-fire": { + "shasums": { + "jar": "73f56642ef43381efda085befb1e6cb51ce906af426d8db19632d396a5bb7a91", + "sources": "40d8500f33c7309515782d5381593a9d6c42699fc3fe38df0055ec4e08055f59" + }, + "version": "1.9.0" + }, + "io.kubernetes:client-java": { + "shasums": { + "jar": "8facf414f052bd39176703f0a5e923e3ed945fa736eb4a00cc685e633eaeb286", + "sources": "f4982edc9570241d940971b6f9a93a60976596584feba462e94c58263b234abe" + }, + "version": "24.0.0" + }, + "io.kubernetes:client-java-api": { + "shasums": { + "jar": "580bf0c6c7ab498cb53d16d975ee6fab8183e90c8993f39a9e739e100bb432d3", + "sources": "0248c50909280447729c9ab996abf41b96bcf54e1d7c9567b49dcddfae78fa67" + }, + "version": "24.0.0" + }, + "io.kubernetes:client-java-api-fluent": { + "shasums": { + "jar": "abd85f46b6a8d81032e25129dcc04a04e3efe414057255b91593e1a08aff0be5", + "sources": "febf43923730c43335aecb9bf8e16618cf9d6d35fef6acbd3b11579cf4e6cf75" + }, + "version": "24.0.0" + }, + "io.kubernetes:client-java-extended": { + "shasums": { + "jar": "5c7089ef93a08714f6b63142579cf7a9f7c2bde62bdf530174351ba390002281", + "sources": "127e271c85091a8a4f563cea1a7a4e16051b3db77b0b824ae1e51a2aada57787" + }, + "version": "24.0.0" + }, + "io.kubernetes:client-java-proto": { + "shasums": { + "jar": "ffe88472b1bac61e08fa19e8a3af53f5a4ee314913f77313f0a1beff7ca228b1", + "sources": "b954e41c5b45105699d1ee179f4e6fb6b0c707a9f3fe52a418989070194232d2" + }, + "version": "24.0.0" + }, + "io.micrometer:context-propagation": { + "shasums": { + "jar": "5b69e2100640879ccf4b20673ced86de560b8e217b55542f85a53d3563b72aaa", + "sources": "719639b819c3ecc76f2b3d4da4b17ca7a8ed6c73b93a770c69aa9d86276f8bf2" + }, + "version": "1.2.1" + }, + "io.micrometer:micrometer-commons": { + "shasums": { + "jar": "45aff76226830db257f4bc39a5bcff83d633e572fee9dc4e45cfa12af9a0a49a", + "sources": "0e4a336c7bca50bfa6cbea274ea681e42d86bfdac1038af3041301c8454f76ff" + }, + "version": "1.16.6" + }, + "io.micrometer:micrometer-core": { + "shasums": { + "jar": "1957ef2deaffbc1fb98cebfd0f5b3109ecf19c994d7e5378598c20747ba8d68b", + "sources": "f85d566a76d98891cdecd54c106b7ad7f8948cddad3b393debe341ecfba18bce" + }, + "version": "1.16.6" + }, + "io.micrometer:micrometer-jakarta9": { + "shasums": { + "jar": "987722add6461c5a4c796be11e7452e8813fba341f2cc067b1d283eef2bd4f40", + "sources": "83fa1c6356611b3381d6309a6159b2739c9c29446c8b52183b2111fb13ce5301" + }, + "version": "1.16.6" + }, + "io.micrometer:micrometer-observation": { + "shasums": { + "jar": "4c0826d5e7c8522a8e111470b4e77f77b0a10f520eb5502ddd143fdbcedb2340", + "sources": "ff5525482df358e7502d4c8680fb654ec700e3b01341149d870bd6cfd8ce04c0" + }, + "version": "1.16.6" + }, + "io.micrometer:micrometer-observation-test": { + "shasums": { + "jar": "e69bf8df81458f4ad6f6027a7310d75c8ca8d11df2e95d44dd4616f8637069ad", + "sources": "1ebcdbf4e14e6a4dcec4ad188bc4227ebd5ce0a3f361f5f0ed6df2bebb10cfb2" + }, + "version": "1.16.6" + }, + "io.micrometer:micrometer-registry-prometheus": { + "shasums": { + "jar": "0e9c7a32dffea3745f2ebff41a4cfeddc5269ca0fd6d98d6e3bafc7b5e35375d", + "sources": "76668b6182ad39e92ddc48ee7815d32cd84ceea4c6751ee13f076a86a37c8136" + }, + "version": "1.16.6" + }, + "io.micrometer:micrometer-tracing": { + "shasums": { + "jar": "b335096393e4d070dfda4fb30808f8488d31d43811b93b2d7496703c5f1315ef", + "sources": "a089a2bcc462d6ced28d7f67b01a9f54baf6c52984cd13f3ed713f2fda0810c6" + }, + "version": "1.6.6" + }, + "io.micrometer:micrometer-tracing-bridge-otel": { + "shasums": { + "jar": "581b6908d46ed2df6b9bb8167df4c44deddc5c2567c430c73bca66326138f661", + "sources": "2aa7115e2f0562e3c50149e77d6fc41340b20d5111b737ea443e0b8bf53a75b3" + }, + "version": "1.6.6" + }, + "io.nats:jnats": { + "shasums": { + "jar": "a5705531ff8fc96657d99d2fc4436178c04463df6a216ba6b5528a5d5228f240", + "sources": "40d6500a369ad57822074fa2a838367e4818ac61eba5c038c95b54772c4ef96f" + }, + "version": "2.23.0" + }, + "io.netty:netty-buffer": { + "shasums": { + "jar": "1361fd9c9ba85b9831cf54a1b2e45ddc3ce34a768931726c099d3f5ef0efe4a3", + "sources": "13259b636c4a91c0f34a8536d621178fba302f9ba61f3e4aaec3a17ca291dc2a" + }, + "version": "4.2.15.Final" + }, + "io.netty:netty-codec-base": { + "shasums": { + "jar": "2c6d39d7270628b8cfc3166fbd7a93d595958e59c461bc32ddb383c8c91bf811", + "sources": "029bea433dfc710c640338954c7403cc7ac31cc5bf4c192904c837b0ebda5fb2" + }, + "version": "4.2.15.Final" + }, + "io.netty:netty-codec-classes-quic": { + "shasums": { + "jar": "ec1d5da906ea0139741cd8c570907c399df5995e48a2b07fe3155272e0be21a6", + "sources": "edfbbece45f21e8f214c0f08f33666ef09ae4580322ffa27020633b5fdee6250" + }, + "version": "4.2.15.Final" + }, + "io.netty:netty-codec-compression": { + "shasums": { + "jar": "4adaa5cdd4d2e9b50b23e4c3eff42e73de6eb40848718b3aa84cd5b454da6ce8", + "sources": "58d61aa4f781657f955a196f17e28fcd9b02e21658b996571e4604a2dadbd8af" + }, + "version": "4.2.15.Final" + }, + "io.netty:netty-codec-dns": { + "shasums": { + "jar": "c5e2c05b4faeba3cf374cc6af29d6f4a7e969d7ca222be958e0800c79a02ee4e", + "sources": "f10017539ab2816efee10b70b47b262c04b881fca685327769d576dd8b222b47" + }, + "version": "4.2.15.Final" + }, + "io.netty:netty-codec-http": { + "shasums": { + "jar": "76ae57e87af37b3c4107140f50b9244b1456163a6a225510838f7c5a4458ec22", + "sources": "76b25b4884e7bec78cd310415b068204e67da5a87162774abfad9a0e6c7a0e78" + }, + "version": "4.2.15.Final" + }, + "io.netty:netty-codec-http2": { + "shasums": { + "jar": "4a9b052bd815c765d9c05e27b32abbd32a2c7c3e3364ccb992ce71da1a26bc0d", + "sources": "01f8ad714e5abb989b0e782da9ec467068821299cd17d80c2db833a6472507f6" + }, + "version": "4.2.15.Final" + }, + "io.netty:netty-codec-http3": { + "shasums": { + "jar": "f2f96b7557317c1378dd8d84b4d9b1865db285c5e665b1220ea519e9f868929d", + "sources": "3a35802b80f536b5693d53d6dfbf4102e94edd0e7b26b3b8d8ab400a12d0f9e0" + }, + "version": "4.2.15.Final" + }, + "io.netty:netty-codec-native-quic": { + "shasums": { + "linux-aarch_64": "59a8e59aa9d3a886cd7fae30fb3d3a18ebee40fa9dc08b83eb88bee58cf46774", + "linux-x86_64": "850ed59fac6679b5e205bf53187b45dbaf2d105ee5f669440645d2acd89524ec", + "osx-aarch_64": "ce18ffeccef21adb3caca5534061c921ef750662f29028fdde62d65196d63a9d", + "osx-x86_64": "10999923bf08ff5e3a75106bd8dbc5b5e4d06b5e614f8c135981ecb4377c944a", + "sources": "d9772d6d7d0eb6fdf82ccaeb9558f88b5600c6f0696a724f5e067b67bdc049f3", + "windows-x86_64": "40adba6df605302bf98a4a462bb002c4697f60958cea7cfec38f0fab6331eb7a" + }, + "version": "4.2.15.Final" + }, + "io.netty:netty-codec-socks": { + "shasums": { + "jar": "4230d43481241e49382a83da2fa9d5980c5702668fc5aa5a980346ce03d30828", + "sources": "f126a6f94589b56b1c056a5dbbda4e76e4e749cec1591a3e878e4d6854144a43" + }, + "version": "4.2.15.Final" + }, + "io.netty:netty-common": { + "shasums": { + "jar": "78206aa7f6d197caa926291408c01889b6b910ca0f74017d3fcbdaccf9562959", + "sources": "de720a128534ba1072b354c863d671ab1999900a8fddaadc4a68ee74c2e33fd6" + }, + "version": "4.2.15.Final" + }, + "io.netty:netty-handler": { + "shasums": { + "jar": "99b59e4bea72220d2aed52df8baf37d97431b06ade0b135226cdf73168975eab", + "sources": "68306697d15d870e7bb29ab9ce725d121ac3170428e8a5d7a33767c5fb0ffa0e" + }, + "version": "4.2.15.Final" + }, + "io.netty:netty-handler-proxy": { + "shasums": { + "jar": "a06aaaaa1a2e6eb26824e53566bfd020ba930a9390d57a1f0bbf57316e357373", + "sources": "91fa7fc64aaa39982b30cc19974f80021090c91023d1d5f6a8e4179aa3a5056b" + }, + "version": "4.2.15.Final" + }, + "io.netty:netty-resolver": { + "shasums": { + "jar": "24318497f2a3a645964fed418f48879ba11365cab8e1f8d66c47fa7da15ef19a", + "sources": "c87b295c43265b34c749331e12ee667f7d43329338618bee2a08027b839220d2" + }, + "version": "4.2.15.Final" + }, + "io.netty:netty-resolver-dns": { + "shasums": { + "jar": "2e8dd2d861775483d689329ab2546045647c8f8bf5ae3ed2dd48eefbb748952d", + "sources": "4db838a89ec84479476e71956d59c67a957779dc5f9781f1a9964f9a6b607c29" + }, + "version": "4.2.15.Final" + }, + "io.netty:netty-resolver-dns-classes-macos": { + "shasums": { + "jar": "dc91d81e0f6c8987ed34f6ca005b4b97cc6032f933a49f7500940e846ade7c43", + "sources": "00067617cc0927d804091590f9ea5041e39c4f907357e3c969c45078fe10be3d" + }, + "version": "4.2.15.Final" + }, + "io.netty:netty-resolver-dns-native-macos": { + "shasums": { + "osx-x86_64": "a1115fb0fd88fe50209fbd645cbfe09e41fe2d264bb1854dc545f44a1bd020cf", + "sources": "87a85f239a73c9a4e7dde8ca31e0a8dea711b3b5e3cff9df18b8c07f31f5dc50" + }, + "version": "4.2.15.Final" + }, + "io.netty:netty-transport": { + "shasums": { + "jar": "9fb671e96651066cf1a28dad3f1382c7c99df5b8326d4a214d9a375b311f8dc1", + "sources": "e17c0a4c7324a93fa01f00bc6ddd2bf2f6eb94702ad8de7af777dec87f89eaf8" + }, + "version": "4.2.15.Final" + }, + "io.netty:netty-transport-classes-epoll": { + "shasums": { + "jar": "be509407fd71a4b83378567c613420db544d659bb522df7b253a1dbe8ca297fe", + "sources": "bb095191a070714f769bff1dd0e5d2496305d10bd566bdc16dbca5773df48b4e" + }, + "version": "4.2.15.Final" + }, + "io.netty:netty-transport-native-epoll": { + "shasums": { + "linux-x86_64": "5440e38f5ca2858fee8d7898e65291e05b665736c9e8a14c832e707511f5dba6", + "sources": "d48e8de50b0994842bec4e65725a7f8e9734144dd4f08b78ffe5396a70ab06b6" + }, + "version": "4.2.15.Final" + }, + "io.netty:netty-transport-native-unix-common": { + "shasums": { + "jar": "b9ea9fc5ad5eba04e99afdff75b2eb97b5ddfb2ad772e2f2ef5d8f277f3cbd76", + "sources": "2b82c54d1b2b9908ec0104664edf58ded4848ae5b34266ee1cf90707efc420ab" + }, + "version": "4.2.15.Final" + }, + "io.opentelemetry.semconv:opentelemetry-semconv": { + "shasums": { + "jar": "693ad6f04f29b4b593a04adef5f575d28b3a91ea3449ab5b1e1e2e5c6efc6cdc", + "sources": "186f9e009d914ebe31f5994d42ff67c5dba8e0893569a4f0f0eeb7958b956d4f" + }, + "version": "1.37.0" + }, + "io.opentelemetry:opentelemetry-api": { + "shasums": { + "jar": "387b4bf98631fc2ede9470879a8ff28dd8c5cb2d3dcf5b6ef77f5ee2bdb7b4f1", + "sources": "3abc57abcaaff4521a5fb2b89593031da5feca24aa54816ec58a8d08ab71fd4a" + }, + "version": "1.55.0" + }, + "io.opentelemetry:opentelemetry-common": { + "shasums": { + "jar": "fca14bb87309d1193347d179b91c63045fa05a856f1fbeec6ef61c4a7f81b227", + "sources": "4219708637e60172c347e48b677b71f5ad97ab8e4850cfda2f85ed59da74e250" + }, + "version": "1.55.0" + }, + "io.opentelemetry:opentelemetry-context": { + "shasums": { + "jar": "f34a4718b70446ec462703ced5cc2c9ad4c9b7c69dcb41d0f032ba51c625a3dd", + "sources": "e0b63b17ccb407f6208a89a180ad48c6add5cca05d29047e858a6ebe8442b3fb" + }, + "version": "1.55.0" + }, + "io.opentelemetry:opentelemetry-exporter-common": { + "shasums": { + "jar": "3b4faaae49dd87bdefae13528d069a271f8476e2a64420e32f4e959a8d09c132", + "sources": "b795169dce773a549f6f3ce2202886ad93622306f2991bd5771547e3c649a2dc" + }, + "version": "1.55.0" + }, + "io.opentelemetry:opentelemetry-exporter-otlp": { + "shasums": { + "jar": "cf42ce6e7cc6755182149f269447f6677f69c0a31e101464594dbcf62fe874c3", + "sources": "a94ebfb492577503d49d43423328f5d0042206f309a18407386a4ab5375bcc82" + }, + "version": "1.55.0" + }, + "io.opentelemetry:opentelemetry-exporter-otlp-common": { + "shasums": { + "jar": "7ddfa417d88a5ff8626dad9ebe0c8c59776491478ab1f72aedfacd75b984931f", + "sources": "7b36e1080bbb2c4dbc7ce009393c568e3d968328f0e5891beb1e45ebd894337a" + }, + "version": "1.55.0" + }, + "io.opentelemetry:opentelemetry-exporter-sender-okhttp": { + "shasums": { + "jar": "e9cd97f59b18a89772ececbebccd773740eec2cd3ff67a4542eff73738acd60f", + "sources": "55f2f24814971e7b476db3713ec82f29285b679fbcaa434c481863f503e2a6e2" + }, + "version": "1.55.0" + }, + "io.opentelemetry:opentelemetry-extension-trace-propagators": { + "shasums": { + "jar": "27861a2b49b3acf3166f489426808032c3addd9c082999f74a110eb7ac6985ce", + "sources": "784afdd2a2a6fca26f8bf237b8aae7f6bfcb44c65d141901a110b4ff769bee0c" + }, + "version": "1.55.0" + }, + "io.opentelemetry:opentelemetry-sdk": { + "shasums": { + "jar": "d63231ea6fd33e0457c776a9aa8ae7ba778379b03119228ec56a5c8c16f9480e", + "sources": "3685819f7d9efb6761d35ecf5b6053dfc1d0161835da744b0fdb2c4d89c87a42" + }, + "version": "1.55.0" + }, + "io.opentelemetry:opentelemetry-sdk-common": { + "shasums": { + "jar": "e28bb83d0ae5a760ba95952daf820180ee7defb0c5783c9d21f9c00ada80020e", + "sources": "cb9423298f9c42ac2c568af5271d335e468d7730b21d7ca6c246c16c6eca25f7" + }, + "version": "1.55.0" + }, + "io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi": { + "shasums": { + "jar": "3ee1f647238bb77df7b7bde47bc87a35a7807b3c5bb389ca81b0ba16c77824ff", + "sources": "71760407f00ba82b762335ff2c3470daf3d5ff1c6a798eb9ae52a24c7772f418" + }, + "version": "1.55.0" + }, + "io.opentelemetry:opentelemetry-sdk-logs": { + "shasums": { + "jar": "d917bb833899057c7cbdbcc30290e816071b90e52c965693aaad4cc1b32ecc11", + "sources": "edb0008c29edf69671865945a1c47d1944c1f498ef7e895f7b21b916fea2f14c" + }, + "version": "1.55.0" + }, + "io.opentelemetry:opentelemetry-sdk-metrics": { + "shasums": { + "jar": "6219d69c3abdd6113bee35df94826f48e84b742041f5124b5857a2b801f74573", + "sources": "5f9c8dab78339e402caa7f7aa4616b6b5c8e2d50201335c73e23bd21aba147fd" + }, + "version": "1.55.0" + }, + "io.opentelemetry:opentelemetry-sdk-testing": { + "shasums": { + "jar": "9e257ac45834e5d184abdc238b5ee146a74a259d940c57722999ef400cdc2232", + "sources": "b40c580007e26d721d406e0b85385e87f6e2e8c36bea55adfd8837d77f57ccee" + }, + "version": "1.55.0" + }, + "io.opentelemetry:opentelemetry-sdk-trace": { + "shasums": { + "jar": "e593660b9fad8bfdb5e981ccd392aa030f788d577c55f8bac3b6c4c6dae509bb", + "sources": "2f374e9b5f2e7e33157bd6fc97eb5c629d0dac0f22a975075b52714916dfc6c5" + }, + "version": "1.55.0" + }, + "io.perfmark:perfmark-api": { + "shasums": { + "jar": "c7b478503ec524e55df19b424d46d27c8a68aeb801664fadd4f069b71f52d0f6", + "sources": "311551ab29cf51e5a8abee6a019e88dee47d1ea71deb9fcd3649db9c51b237bc" + }, + "version": "0.27.0" + }, + "io.projectreactor.netty:reactor-netty-core": { + "shasums": { + "jar": "b8aaddd6025af42c2d810a76dc5b9a7717f0fde84beb93d6d4a778dac25fc287", + "sources": "061136ccc1bc3bed6938cea77a7343dc47de275aad4851b3407fb7ac15854121" + }, + "version": "1.3.6" + }, + "io.projectreactor.netty:reactor-netty-http": { + "shasums": { + "jar": "0ffdcaafe718327ca4687dd41c21318a267e93cea7b43f42db6f3fb3175256a5", + "sources": "712c12723e57d68e909ce9221cb12e04be105435ca518d13f63075af81cbaa44" + }, + "version": "1.3.6" + }, + "io.projectreactor:reactor-core": { + "shasums": { + "jar": "ffc646b225465efce55d3ea350f1bcd1d27d4a56e912323e316dd8e6d04bff11", + "sources": "d6180835f642a1f6d8b330fac98876488994187a89c3df48b369f37344ea6845" + }, + "version": "3.8.6" + }, + "io.projectreactor:reactor-test": { + "shasums": { + "jar": "27acda356a59c19bc3db033f1ed4cff9a6469da6caf424a4004ffaabbfe24d2a", + "sources": "882b7654b056b77f721a03a804e4830030f072a2f4afb92638d6925568d6d930" + }, + "version": "3.8.6" + }, + "io.prometheus:prometheus-metrics-config": { + "shasums": { + "jar": "3da2d5f0123af9e313bcf26f04c1248afeacd1b0d5c3a35f220034604ac0ec47", + "sources": "b926a8a6802d8f1ea9800f9e88cb4b2ff8511b6fb63786ad51d778a5f22bd059" + }, + "version": "1.4.3" + }, + "io.prometheus:prometheus-metrics-core": { + "shasums": { + "jar": "7ecd546d5238e3d3f5f312f580eaaab10cb05d147597978ab90b78080cc58255", + "sources": "48721aa5dd183e912fe82f2c19ebd980a11ed56c9a8296d23fd4011051ec8d96" + }, + "version": "1.4.3" + }, + "io.prometheus:prometheus-metrics-exposition-formats": { + "shasums": { + "jar": "502ad6b37c44b1a6311f6070a18fc921ffa2e26abb43eaaaf7626aa1b97984b6", + "sources": "4bc087c844d7dd22799e5466bcd47c7e0feda0a6fbc084c26aaa843af5cee6e9" + }, + "version": "1.4.3" + }, + "io.prometheus:prometheus-metrics-exposition-textformats": { + "shasums": { + "jar": "4aeee30d937ae5baf34ca9daced0f84400ec0f034e7beaa8331d9c519d84e3d7", + "sources": "a4b5c7b615f221b4fd6dc46a877c9c5b5151a86f03789c21f2d708407d1a9bc3" + }, + "version": "1.4.3" + }, + "io.prometheus:prometheus-metrics-model": { + "shasums": { + "jar": "bc3f1825014a14006626086ea779b62893e647e71d1eab075c0bb65057c245f8", + "sources": "61abe1dd37b1f8caea95ba193e5d85dc4b37861017731524ca155bfb57936cfe" + }, + "version": "1.4.3" + }, + "io.prometheus:prometheus-metrics-tracer-common": { + "shasums": { + "jar": "b816aaf84e45d591e5f66c5b94c7a789dedf2d705e5bf3eec2ae8730f76c68cd", + "sources": "797e6e276ccf7d874248b4d779b705ce0a400fe02b54443a04758b393de3f66e" + }, + "version": "1.4.3" + }, + "io.swagger.core.v3:swagger-annotations-jakarta": { + "shasums": { + "jar": "9b30b319f1c31993e6128d22e12652be9a688589e30c67819ed84e95b96e7f88", + "sources": "b9324b72ab6c498fad2d766f5074b1b24be0cf2c1e55f6c937b4b8345ca90bf9" + }, + "version": "2.2.47" + }, + "io.swagger.core.v3:swagger-core-jakarta": { + "shasums": { + "jar": "e63b78c1e5b049e6670ca9bb43c3f35cf362ecc08ac59a783994a6a732a7d7eb", + "sources": "55b6e465caf14b019ebe4ab9d886915afd1a4796c6c790ffdd4789b36997f556" + }, + "version": "2.2.47" + }, + "io.swagger.core.v3:swagger-models-jakarta": { + "shasums": { + "jar": "15d10f4f7eac1e02a8ff940b430c634fc9dfe08368a54dffa3216cc2dc811aa2", + "sources": "4770b07fcb362a2c1b289fd255d5bf9ec11619bc0cbfcfc07e49599f24fef753" + }, + "version": "2.2.47" + }, + "io.swagger:swagger-annotations": { + "shasums": { + "jar": "c832295d639aa54139404b7406fb2f8fbf1da8c57219df3395de475503464297", + "sources": "7b2de9dc92520bd12e30987ee491191131e719d30e3bbe8a536f18e80ca14df3" + }, + "version": "1.6.16" + }, + "jakarta.activation:jakarta.activation-api": { + "shasums": { + "jar": "c9db52100ce6c8aac95cc39075f95720d2e561b11f8051b81c121ad4effd7004", + "sources": "2aa5a3ba55059b778a3b467269404d7ac3b9485ed4a23ad26d2e63aa769ec35f" + }, + "version": "2.1.4" + }, + "jakarta.annotation:jakarta.annotation-api": { + "shasums": { + "jar": "b01f55552284cfb149411e64eabca75e942d26d2e1786b32914250e4330afaa2", + "sources": "142dfd2343429df2aac3e1cfacfacc21c8393112c0e0280d3628648d9b612470" + }, + "version": "3.0.0" + }, + "jakarta.servlet:jakarta.servlet-api": { + "shasums": { + "jar": "8a31f465f3593bf2351531a5c952014eb839da96a605b5825b93dd54714c48c4", + "sources": "6eb958543e0548bb93d2519e40224d13c8003b10cc615b5652bfd9899350bfb4" + }, + "version": "6.1.0" + }, + "jakarta.validation:jakarta.validation-api": { + "shasums": { + "jar": "63ce00156388c365f3ac1be71fcfaf114682fc0c452020b5df6e7ec236e142ab", + "sources": "941cc2028fe8f5e6b912954bca360ed347ace453aca4f8e2fd58dc3845a0c792" + }, + "version": "3.1.1" + }, + "jakarta.xml.bind:jakarta.xml.bind-api": { + "shasums": { + "jar": "5e489b6c874c4119e003ff1403db523ee3a8959ec499f3de29e77245efccf216", + "sources": "5bcf811e6719582ab2be21c84bc48f963ba377dfe1dae5ecb2673c1efa00e422" + }, + "version": "4.0.5" + }, + "javax.annotation:javax.annotation-api": { + "shasums": { + "jar": "e04ba5195bcd555dc95650f7cc614d151e4bcd52d29a10b8aa2197f3ab89ab9b", + "sources": "128971e52e0d84a66e3b6e049dab8ad7b2c58b7e1ad37fa2debd3d40c2947b95" + }, + "version": "1.3.2" + }, + "net.bytebuddy:byte-buddy": { + "shasums": { + "jar": "2b5ddc8c1f4234bdb7cb45338a8e10a13e0e3ca473e91d5d821d681127ea8ba1", + "sources": "5211140f46c380a5e9630a86b2c07b396a9c374128fa603ca1d321b3c7da7449" + }, + "version": "1.17.8" + }, + "net.bytebuddy:byte-buddy-agent": { + "shasums": { + "jar": "5b17113e66e77ca6f8af07ff367c216df964a980f0e9f11e3b1aa793253aa64f", + "sources": "a205437d772e3edaf4a7a1a709e9d59c666e8a05218d0e000deb5651c52de2d2" + }, + "version": "1.17.8" + }, + "net.devh:grpc-common-spring-boot": { + "shasums": { + "jar": "951fd28aa9dce0cfc5be8ff9eba6d7dc616b2998e920a7b6acc05e11f4064f94", + "sources": "157991de7c495e40c1b18f8ef274e5ff1e2c0393b75642e7308457b866b3096a" + }, + "version": "3.1.0.RELEASE" + }, + "net.devh:grpc-server-spring-boot-starter": { + "shasums": { + "jar": "289b7b45fe511d14f54801745ac3de7602bf7d7eef0fb75890bef7fbedb94ec4", + "sources": "e0ddd0872ffbbc48c322ba617035bafd0f5bc656e91eec0bda876d3f07d9f3f1" + }, + "version": "3.1.0.RELEASE" + }, + "net.java.dev.jna:jna": { + "shasums": { + "jar": "260c4b1e22b1db9e110ee441c4f13ce115f841fa48c41d78750986214b395557", + "sources": "0b9224e215b3c6a464959e3f994ddd64c14d46fb4014facd6afa1cc18e469466" + }, + "version": "5.18.1" + }, + "net.javacrumbs.shedlock:shedlock-core": { + "shasums": { + "jar": "b2ca6f358b5dcbadc641a7c5ef6217b8c5f91bc2b49e89d715fdd5443cc48166", + "sources": "81a2914ff05c94d86b54d78fa59f79216df1db8e980d5d5a910559f6da3bb9e1" + }, + "version": "7.7.0" + }, + "net.javacrumbs.shedlock:shedlock-provider-cassandra": { + "shasums": { + "jar": "e8a5db022350461384618f4ebaf978dbc2894becb208d7c053ae0125dd31a7eb", + "sources": "2e6e6fdcbc77faffaa22b16850ae4b50f7693439b59fc146c0ec9f510c012eb5" + }, + "version": "7.7.0" + }, + "net.javacrumbs.shedlock:shedlock-spring": { + "shasums": { + "jar": "a71fa9d539b10140b5aaea5a4a0e58f219b396195b6bc7148c8adf65425cbce1", + "sources": "bb61469b2f50396b4ab6ccb2a30ecb3d394ca0d0c986f43086de2beaafeac67e" + }, + "version": "7.7.0" + }, + "net.minidev:accessors-smart": { + "shasums": { + "jar": "222c9f547bb20a99fc486403a398352d1306fb671b38abd7ecab6401df170e61", + "sources": "10880e44ed732de27ae424a9698a041c398102098b5b1bae3cc597ec62dac43e" + }, + "version": "2.6.0" + }, + "net.minidev:json-smart": { + "shasums": { + "jar": "1ae4b561458afb540be8ec5c6dbb4f2e715a319a7ae64854998aaf924770d61b", + "sources": "a4af3f3773286fe3f76f94d38d977611fd2493685f589466b76dd25cf70b400c" + }, + "version": "2.6.0" + }, + "org.apache.cassandra:java-driver-core": { + "shasums": { + "jar": "6276a8e25c8821eeaa5d2d67c50b81615d551dd7ec943302689996f6bdb2add1", + "sources": "80a95f2d4d61091a8f54bf76f2d26269ee7b8ac82e261314108d7ad83c083838" + }, + "version": "4.19.3" + }, + "org.apache.cassandra:java-driver-guava-shaded": { + "shasums": { + "jar": "fa5e6dfb61a987e69cd8559464145b6ceb6610d28760b0d8cff17eba052c8264", + "sources": "9415d1dd6132671cefc43eb5ac560f34d5e4a1b73ac25310fbfc4584a8033ec3" + }, + "version": "4.19.3" + }, + "org.apache.cassandra:java-driver-metrics-micrometer": { + "shasums": { + "jar": "4f61ed8dabc978f7c9bfdae578915480b6242468feea1c73571be7d832ee3d0a", + "sources": "6214d824dc8e72fd6221165b1497f4c46099027b7ad220ce17f44a8f3f58807f" + }, + "version": "4.19.3" + }, + "org.apache.cassandra:java-driver-query-builder": { + "shasums": { + "jar": "b6e4c84dff2448aaa67f5e3e867b1bf284ca6ad0c15701a4d4d7283384d8df12", + "sources": "dd63fa1af436d1b01155fdca72563338007e265fd8c05c3a8b2e80e76b2d4aa8" + }, + "version": "4.19.3" + }, + "org.apache.commons:commons-collections4": { + "shasums": { + "jar": "00f93263c267be201b8ae521b44a7137271b16688435340bf629db1bac0a5845", + "sources": "75f1bef9447cce189743f7d52f63a669bd796ae19ca863e1f22db1d5b6b504a6" + }, + "version": "4.5.0" + }, + "org.apache.commons:commons-compress": { + "shasums": { + "jar": "e1522945218456f3649a39bc4afd70ce4bd466221519dba7d378f2141a4642ca", + "sources": "6de9de4559f12bba6d41789c72f6a2a424514f2d2a3f7f49e2a3c52414db9632" + }, + "version": "1.28.0" + }, + "org.apache.commons:commons-lang3": { + "shasums": { + "jar": "69e5c9fa35da7a51a5fd2099dfe56a2d8d32cf233e2f6d770e796146440263f4", + "sources": "eec245e820ec2800a1780cf756aefb427c1c6170e06902e67ac15b6910ce6335" + }, + "version": "3.20.0" + }, + "org.apache.logging.log4j:log4j-api": { + "shasums": { + "jar": "c4b642a7f047275215de117e0e3847eb2c7711d84a0aa7433e7b3c096daf341d", + "sources": "b86680bcf8ffa25897b6114cae508bb8e6ecac8081a0fc8985e0c00e27d4f4ec" + }, + "version": "2.25.4" + }, + "org.apache.logging.log4j:log4j-to-slf4j": { + "shasums": { + "jar": "d7b78fc0aaaa5e8ada388b29d718b0ab187e512965bed0b259bb4ab299f13db2", + "sources": "ca9159da173bf88fb621adf745fe1d313ba4074f4c66576ae70f5dd99eab89c9" + }, + "version": "2.25.4" + }, + "org.apache.tomcat.embed:tomcat-embed-core": { + "shasums": { + "jar": "78cd7cd7c104b6b87142c1b0bd902e1ce005b0245c3cefa8a06759148947200b", + "sources": "0bfbdc27e60d4db5b83e0f51193bae5f4bd02ac270fd78b06945e219fc473359" + }, + "version": "11.0.22" + }, + "org.apache.tomcat.embed:tomcat-embed-el": { + "shasums": { + "jar": "1b34c33b858c141df36c501b4d809e68036c406bca3671a86facae297917c7de", + "sources": "da3724004575f5c8fa7e45649f2900ec53e7ecfb502b6ce227ca9cf86b36a156" + }, + "version": "11.0.22" + }, + "org.apache.tomcat.embed:tomcat-embed-websocket": { + "shasums": { + "jar": "210e0c7ab194a76cc7283df0be365276091b042369dae125fb477828ba67e922", + "sources": "711f09af528ac5af172c664244bcba4748eac00811ef7c6b52ddd6836b5a4a28" + }, + "version": "11.0.22" + }, + "org.apiguardian:apiguardian-api": { + "shasums": { + "jar": "b509448ac506d607319f182537f0b35d71007582ec741832a1f111e5b5b70b38", + "sources": "277a7a4315412817beb6655b324dc7276621e95ebff00b8bf65e17a27b685e2d" + }, + "version": "1.1.2" + }, + "org.aspectj:aspectjweaver": { + "shasums": { + "jar": "4fe86fdc18faea571f29129c70eaad5d121363504a06d7907be88f6c60ba3116", + "sources": "06fbde6ef3a83791e70965432b5f1891e493e21cdbc37307c54575ee86752595" + }, + "version": "1.9.25.1" + }, + "org.assertj:assertj-core": { + "shasums": { + "jar": "c4a445426c3c2861666863b842cc4ec7bbb1c4226fefd370b6d2fe83d6c4ff0f", + "sources": "5ba6de05730cf76021001f8437f35db4cb5b513465d4ace8c3a6fcd68d9a19ee" + }, + "version": "3.27.7" + }, + "org.awaitility:awaitility": { + "shasums": { + "jar": "ee58568ea5945dcf988551501655183dc184e23e45a8e013fdfd9036194e6f7b", + "sources": "92d209bd0135b04ca6bb7689c6b921819896ec2d517a5357760f598faafee46c" + }, + "version": "4.3.0" + }, + "org.bitbucket.b_c:jose4j": { + "shasums": { + "jar": "7314af50cde9c99e8eaf43eee617a23edcc6bb43036221064355094999d837ef", + "sources": "958be1837b507d3a1f1187257072b4c1e1d031c3a0c610d3c02ac69aabfac6a5" + }, + "version": "0.9.6" + }, + "org.bouncycastle:bcpkix-jdk18on": { + "shasums": { + "jar": "4f4ba6a92617ea19dc183f0fa5db492eee426fdde2a0a2d6c94777ffd1af6413", + "sources": "601ec2beb4749f0be65e296811b6e63de567f90d124f26887875bb722fd87e71" + }, + "version": "1.80" + }, + "org.bouncycastle:bcprov-jdk18on": { + "shasums": { + "jar": "64d6c5a6121fcd927152dd182cbed39afe0fda641a970d9bcc0c9cb1858b2731", + "sources": "e5f04550f7740e588edcbd1654c59277cd7ee8725d8b674e44f7f8f4b9c5674a" + }, + "version": "1.84" + }, + "org.bouncycastle:bcprov-lts8on": { + "shasums": { + "jar": "492049b928f8baab535af0185bbab8734d14e1c7648ae2a2037d58486cafb676", + "sources": "d4447a4f412b328f3e43595ab99603dd38b08ee1db9f1ea341e6158eeb86a70d" + }, + "version": "2.73.8" + }, + "org.bouncycastle:bcutil-jdk18on": { + "shasums": { + "jar": "bc78d32d7ffb141ee27e4fb77df04259d842c899e7e8eaf912f990d7253bd3b4", + "sources": "f1e43055e8287cde556a7741bf16b7fd7896b8f572ab91e0cadb337e710b015f" + }, + "version": "1.80.2" + }, + "org.checkerframework:checker-qual": { + "shasums": { + "jar": "e316255bbfcd9fe50d165314b85abb2b33cb2a66a93c491db648e498a82c2de1", + "sources": "443fa6151982bb4c6ce62e2938f53660085b13a7dceb517202777b87d0dea2c7" + }, + "version": "3.33.0" + }, + "org.codehaus.mojo:animal-sniffer-annotations": { + "shasums": { + "jar": "c720e6e5bcbe6b2f48ded75a47bccdb763eede79d14330102e0d352e3d89ed92", + "sources": "4270ce5531ed0f12e4234e08f240ef3b45ee3ceeb16e28d44abc61c12cf522ca" + }, + "version": "1.24" + }, + "org.hamcrest:hamcrest": { + "shasums": { + "jar": "5d66b6a4a680755cb6ed7cb104fa7835ef644667586ff0737adeb977c39ecdbc", + "sources": "7a4050b1898f7e1aa395cf2be78fb6683f9e2766fcb8e1507926b204fa24d1bf" + }, + "version": "3.0" + }, + "org.hdrhistogram:HdrHistogram": { + "shasums": { + "jar": "22d1d4316c4ec13a68b559e98c8256d69071593731da96136640f864fa14fad8", + "sources": "d3933c83a764994930f4477d4199539eaf413b42e32127ec2b68c61d711ac1a9" + }, + "version": "2.2.2" + }, + "org.hibernate.validator:hibernate-validator": { + "shasums": { + "jar": "25f40118fa4c50f8522d090d25d52d5a38953b0ccd1250835f052e7bd3164ce0", + "sources": "db6a3d49eceaae0a880de8749cd7f7e8928c18458b44fac84633c3ee8db7ac0d" + }, + "version": "9.0.1.Final" + }, + "org.jacoco:org.jacoco.agent": { + "shasums": { + "runtime": "3fb76eea65f81bd9415202bab34b6571728841dff1ab8e6bbe81adc2e299face", + "sources": "8a643b749deb255d7a42c445c3053c9ec263e27103becdaaf88cedda44357255" + }, + "version": "0.8.14" + }, + "org.jacoco:org.jacoco.cli": { + "shasums": { + "jar": "12d5d78351c638efeea71ac840f6a5cf7bcff89001ddb05eb89f956d1079a2c6", + "sources": "52f715f15b890960f70f4ae8fbdd4bca70eba59c0283b37af2d79ad9215d2e37" + }, + "version": "0.8.14" + }, + "org.jacoco:org.jacoco.core": { + "shasums": { + "jar": "28abbf0eea5a08e4f24097f2fbac663ca17c341c25c3a04d90d6cd325943c995", + "sources": "1550fd5081ecd2c2ad053994c23d91a4cef6dcbed4c4dac95130e7d75fa9cd3c" + }, + "version": "0.8.14" + }, + "org.jacoco:org.jacoco.report": { + "shasums": { + "jar": "a3e2026060ab8b8d5c650706406234bb4c033dfd5376afeb8b1666e8ed27c453", + "sources": "80ac2fac212d6a4583b7f025dc7b602f384a9dfcdbccd0e9cb78c415e9f5ffc6" + }, + "version": "0.8.14" + }, + "org.jboss.logging:jboss-logging": { + "shasums": { + "jar": "7c12ee575508f81e22b1db9334b969d0ec54ef0fd1dcba24eeab1a44235fc366", + "sources": "e8a2b9aaac82b0082aa040e6bdf6cd7f225cdbc75d2bd1a79fa7b17007ec1b15" + }, + "version": "3.6.3.Final" + }, + "org.jetbrains.kotlin:kotlin-stdlib": { + "shasums": { + "jar": "6558a3d233da56a20934b32159f9db5f86ed5816ef098f78a2c223dc6abb79dd", + "sources": "664f515359444a92267a13266101431a630f99d6b8d04407a92b1a0e558d33ee" + }, + "version": "2.2.21" + }, + "org.jetbrains.kotlin:kotlin-stdlib-jdk7": { + "shasums": { + "jar": "b785922f11e6d91a6dd1d75cb0aef1ce37b83f8de0e3a2139139dfb823bb8a2c", + "sources": "2534c8908432e06de73177509903d405b55f423dd4c2f747e16b92a2162611e6" + }, + "version": "2.2.21" + }, + "org.jetbrains.kotlin:kotlin-stdlib-jdk8": { + "shasums": { + "jar": "c62275c50ee591ca2f82c7ba42696b791600c25844f47e84bd9460302a0d5238", + "sources": "3cb6895054a0985bba591c165503fe4dd63a215af53263b67a071ccdc242bf6e" + }, + "version": "2.2.21" + }, + "org.jetbrains:annotations": { + "shasums": { + "jar": "195fb0da046d55bb042e91543484cf1da68b02bb7afbfe031f229e45ac84b3f2", + "sources": "b2c0d02e0a32c56d359e99634e7d769f9b1a8cd6e25061995abad1c1baf86f56" + }, + "version": "17.0.0" + }, + "org.jspecify:jspecify": { + "shasums": { + "jar": "1fad6e6be7557781e4d33729d49ae1cdc8fdda6fe477bb0cc68ce351eafdfbab", + "sources": "adf0898191d55937fb3192ba971826f4f294292c4a960740f3c27310e7b70296" + }, + "version": "1.0.0" + }, + "org.junit.jupiter:junit-jupiter": { + "shasums": { + "jar": "784b65815f479a0c99a9d3a573b142e2a525efb6025d97f751b19e72f90aeda3", + "sources": "402f86a4fdce930bb68b592f2ed5a9d57dc4d1b2747aa2d66c0b3cb7a2adceeb" + }, + "version": "6.0.3" + }, + "org.junit.jupiter:junit-jupiter-api": { + "shasums": { + "jar": "d655d7e6f0c7ae07f10a2f3bbaaebb6d30e9b26204a068ad9e9b3950aa28792c", + "sources": "8266d8da51d0c7d6a2ed4895a3cb76e0ec22194907f24364f2a4f3efd05f00a5" + }, + "version": "6.0.3" + }, + "org.junit.jupiter:junit-jupiter-engine": { + "shasums": { + "jar": "1e2fab61ad27ea08fc7c70dd9677cf8c6d1ae5434d42dcfdd633b12c7e7c04d0", + "sources": "35706a9edf1b580bf22d6eca9d6a9165f478f75b0108840ad6f31481cd662d6c" + }, + "version": "6.0.3" + }, + "org.junit.jupiter:junit-jupiter-params": { + "shasums": { + "jar": "cf2947e2302b9f8c8a059259a277881c1cadae8fbc2514c16a925cfeb7beb2e5", + "sources": "f0dcf217100b06b98cd36c2e74fb919c74e3024faad868bac9eba6ff00c7c263" + }, + "version": "6.0.3" + }, + "org.junit.platform:junit-platform-commons": { + "shasums": { + "jar": "39f262d09c3d52719fe0b77f080e90a3695e285d779a41b232e17963ae5da200", + "sources": "06cbe4a4bbd79339c3817983510cf3adc3d6a88a8a556c80c5b84eeb1ebd13dc" + }, + "version": "6.0.3" + }, + "org.junit.platform:junit-platform-console-standalone": { + "shasums": { + "jar": "3ba0d6150af79214a1411f9ea2fbef864eef68b68c89a17f672c0b89bff9d3a2", + "sources": "c4e79459727c6fe6afbddcc04daa67767fb73d7044d29846dd4ab90de1d0fa0c" + }, + "version": "6.0.3" + }, + "org.junit.platform:junit-platform-engine": { + "shasums": { + "jar": "491e9e4f745f161b8a8e4186a1a7c6a450ea12c70930c9aedae427215301d947", + "sources": "89a893566a97557dbbcb0706d9b5565c4e7a402050841753dc527f3e9139c9ac" + }, + "version": "6.0.3" + }, + "org.junit.platform:junit-platform-launcher": { + "shasums": { + "jar": "315608372e4dc44bca0ccb3ae8a07ecc206b3367033fa05748a03ccd563f1301", + "sources": "4fcbdb81cc882c0c3e73f742878db5884d3d2f86facc08369ca953e32796d144" + }, + "version": "6.0.3" + }, + "org.junit.platform:junit-platform-reporting": { + "shasums": { + "jar": "f19c5be871c37ebed493f3152b67a909f89a44dff67c2db8016dfe34167d5730", + "sources": "bbdda2b9c002dbd1b05cfec144bab91e8cca46ed8d58525f51b547f3a0a84a7d" + }, + "version": "6.0.3" + }, + "org.latencyutils:LatencyUtils": { + "shasums": { + "jar": "a32a9ffa06b2f4e01c5360f8f9df7bc5d9454a5d373cd8f361347fa5a57165ec", + "sources": "717e271b5d67c190afba092795d79bba496434256aca7151cf6a02f83564e724" + }, + "version": "2.0.3" + }, + "org.mockito:mockito-core": { + "shasums": { + "jar": "d1a96d252128d3a4247cfd8a2e76412efa3cc103977be17933c942117a24f374", + "sources": "dcde489c1db6449c162f05105ace4c172850d3dc7f6633bb4f54d47a16a0fd1b" + }, + "version": "5.20.0" + }, + "org.mockito:mockito-junit-jupiter": { + "shasums": { + "jar": "fd6c703c2b00b914f3adbc27b18077a708f3d6992f19242c444e737c6cce024e", + "sources": "3c199479a2319db4395fd9fd209946ecc4530f48fe5cdeed7677c285bf70fbb5" + }, + "version": "5.20.0" + }, + "org.objenesis:objenesis": { + "shasums": { + "jar": "02dfd0b0439a5591e35b708ed2f5474eb0948f53abf74637e959b8e4ef69bfeb", + "sources": "d06164f8ca002c8ef193cef2d682822014dd330505616af93a3fb64226fc131d" + }, + "version": "3.3" + }, + "org.opentest4j.reporting:open-test-reporting-tooling-spi": { + "shasums": { + "jar": "04ac4ecfcaf60abe0e6d5b18e8306320aec7cd9cbf15e59eeac54fa9faa16902", + "sources": "efe9672e74111726c0ff85a2508a0bc78be611a7cbe460560dc7cd429ee0a4ce" + }, + "version": "0.2.4" + }, + "org.opentest4j:opentest4j": { + "shasums": { + "jar": "48e2df636cab6563ced64dcdff8abb2355627cb236ef0bf37598682ddf742f1b", + "sources": "724a24e3a68267d5ebac9411389a15638a71e50c62448ffa58f59c34d5c1ebb2" + }, + "version": "1.3.0" + }, + "org.ow2.asm:asm": { + "shasums": { + "jar": "03d99a74ad1ee5c71334ef67437f4ef4fe3488caa7c96d8645abc73c8e2017d4", + "sources": "e37000a2a0bc9f0bef373714ad7dde4082212351847b74618d483057a4ae186c" + }, + "version": "9.9" + }, + "org.ow2.asm:asm-analysis": { + "shasums": { + "jar": "6a15d28e8bd29ba4fd5bca4baf9b50e8fba2d7b51fbf78cfa0c875a7214c678b", + "sources": "ff731d401ea2407759ea19b4b025800d32495a51a912f2553d987cddda424773" + }, + "version": "9.9" + }, + "org.ow2.asm:asm-commons": { + "shasums": { + "jar": "db2f6f26150bbe7c126606b4a1151836bcc22a1e05a423b3585698bece995ff8", + "sources": "218bbb648e24578a385cb6b6a21ceff222a2a8f8b2d5f6a256a8099dd336dc76" + }, + "version": "9.9" + }, + "org.ow2.asm:asm-tree": { + "shasums": { + "jar": "42178f3775c9c63f9e5e1446747d29b4eca4d91bd6e75e5c43cfa372a47d38c6", + "sources": "9d1fe261fa1d29904ca9dbc76878396e76bc225191676a8c16ad2669a205321a" + }, + "version": "9.9" + }, + "org.ow2.asm:asm-util": { + "shasums": { + "jar": "3842e13cfe324ee9ab7cdc4914be9943541ead397c17e26daf0b8a755bede717", + "sources": "e518a00b1d004832e72c6448351c4865971ac95a7cfe78fb0315d76acb393a46" + }, + "version": "9.9" + }, + "org.projectlombok:lombok": { + "shasums": { + "jar": "01f7b1a015e33e2b62d5f5f37053306357ab1415fd181fcba7794f5d198c1126", + "sources": "5b78c305a65fbe257d57878bff6530e2b79e1a2cd660f45dcb7d7f8f5e56a483" + }, + "version": "1.18.46" + }, + "org.reactivestreams:reactive-streams": { + "shasums": { + "jar": "f75ca597789b3dac58f61857b9ac2e1034a68fa672db35055a8fb4509e325f28", + "sources": "5a7a36ae9536698c434ebe119feb374d721210fee68eb821a37ef3859b64b708" + }, + "version": "1.0.4" + }, + "org.rnorth.duct-tape:duct-tape": { + "shasums": { + "jar": "31cef12ddec979d1f86d7cf708c41a17da523d05c685fd6642e9d0b2addb7240", + "sources": "b385fd2c2b435c313b3f02988d351503230c9631bfb432261cbd8ce9765d2a26" + }, + "version": "1.0.8" + }, + "org.skyscreamer:jsonassert": { + "shasums": { + "jar": "719095c07d4203961320da593441d8b3b643c18eb1d81aa98ea933bb7eb351ba", + "sources": "a825c29f8cc40f85ea4e7a431a55d4278a785c34acdeef4cd1be7367f70ea6bb" + }, + "version": "1.5.3" + }, + "org.slf4j:jul-to-slf4j": { + "shasums": { + "jar": "cbb7d1aaaa9e871eb1a06594abd911bf97027152976edf1edc315be75239204e", + "sources": "b6dd2138f3e83d876bf07206d09f2b48ca655bc36a8e80b0c2a32ad19ab8f1d5" + }, + "version": "2.0.18" + }, + "org.slf4j:slf4j-api": { + "shasums": { + "jar": "44508fd1576500688c790b190acdd16fec4f8c79a3e0b900afd70503cf055f55", + "sources": "192e007cf7f2be41d40574e44521fc0b7ce55e01f13dbe0fa8707c8ae3329075" + }, + "version": "2.0.18" + }, + "org.springdoc:springdoc-openapi-starter-common": { + "shasums": { + "jar": "a0b5a6a5384b4a36718fd7a69efbd48311fd5f404c96ce286a6c285c5d0038e6", + "sources": "19a2612f56ea7d867c70cdae5e8fdf9d2b7a3cbdcba257c1d9ddfe88e48a74b0" + }, + "version": "3.0.3" + }, + "org.springdoc:springdoc-openapi-starter-webflux-api": { + "shasums": { + "jar": "a58f130aa60c47001e0d7b6b5e611edbbf187f58aa7d697dd720ac220f57b384", + "sources": "90968a39c963a144ee30248146dff38eb568edf57109ccddb843d6a92c1ef756" + }, + "version": "3.0.3" + }, + "org.springdoc:springdoc-openapi-starter-webmvc-api": { + "shasums": { + "jar": "c7e0221797240037eaf20c834f2d03fabec3f26051bd7052be8bf169f2c02876", + "sources": "e0fad37b01fefa5b52aec1cc09101017a397ae93f7ba8dace72ed29d1f2a3106" + }, + "version": "3.0.3" + }, + "org.springframework.boot:spring-boot": { + "shasums": { + "jar": "edb984d0bc80d209bed271e6d334fbfbfcf11cc4c1ef5059adc31c5bde7b1d7c", + "sources": "850ec7c91b0ff92c46797e0adcf1f47369d64a0cf4a8427d01b4834df129d0d4" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-actuator": { + "shasums": { + "jar": "edfedbcc5d33c8b0a8d0156dcc8cbf6234a33dc861001c7ec8ef63af19197b7e", + "sources": "d74a19a07e1eaf70bfe00b33332c3d61d82621e887b1a8af3b4dbb05051ca197" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-actuator-autoconfigure": { + "shasums": { + "jar": "59b188a313fda88bbe6cba613dd13aa00d1cc49135b11120ae5d451f72d49c00", + "sources": "c4aa275f1a4c97020d56d96cdb5f1b9a0b8157da06b62313c55e2d861e683c59" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-autoconfigure": { + "shasums": { + "jar": "1e8a953294fe76727965970de31e3bb08fba2b65e3ca0ee9b8bca492d0818d10", + "sources": "477e9834d7982b080b485c7baeb27ea399fca324d0442dc2f694a473b6a394fd" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-cassandra": { + "shasums": { + "jar": "8a69a41383b36eed9b58b462c698cf7ec825ea0ac3b131ce7c2f92419dbc3bc7", + "sources": "e580260c129670d80a96c84c2241d5cbad3d9f9a183d3af201b2b5acab96e3cd" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-data-cassandra": { + "shasums": { + "jar": "f17d6ed4fe4825abb68ec4743a3248d9e456c94e099e2653c392ee75cef4b8a6", + "sources": "d2fcf562626d79bc13f71284c2a9b820975ce0bd35e9e9daeef8deb05fb14e53" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-data-cassandra-test": { + "shasums": { + "jar": "5ad17d2ffcd040eae3f425e7588e2b2604461b47ac7801c5ccfb5179e6725832", + "sources": "73ca527b7a6d67b0e8a20865d91f0bb15092ef3415c7ebefe475bc14894440da" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-data-commons": { + "shasums": { + "jar": "991f28c95c3b5687d41429ec1da258d6ebdf33c1778dab2057361df9983dc6c7", + "sources": "bbfa0f3571ee162c21597e7fc7a925a5919e1267ebb55eb5b3698c2832de9ec0" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-health": { + "shasums": { + "jar": "e1c81e0e8d89ba7d25a3522d52159a4bcfa9bf7ee4e0d53cef61244e75a244bb", + "sources": "0d664e89d03dffde004f79e9aa5a7482128d0358c284edb0b5c2895eb25a43b7" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-http-client": { + "shasums": { + "jar": "7881d09b33f278b39fd1018d0cb7d91b73b72406d2350351166511b1c3a76c6b", + "sources": "17ee08d609a1d4d1d64198b9cf0cf79920974400460022b4b97117d22b7ea73a" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-http-codec": { + "shasums": { + "jar": "dd3e79f5bf872e34eca182f3a6f050278263562da042a1a0bc338f5d70d4ab60", + "sources": "4f2231f549e7353f3095b58995520bcb073d4c155aadc839f3f66d1b6543059e" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-http-converter": { + "shasums": { + "jar": "9f620c36cb98103ef664a9fccad4173ae20120d1abc790b795130be4e02dbb90", + "sources": "9f4378bcb3caa6696d8fe340c519bd673287f2c046098607cbe079ba9aa98874" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-jackson": { + "shasums": { + "jar": "0cdbadd10bcc3b23d32dffd419caceda4a4ed6b3da0262617f543732e9105ece", + "sources": "efe6e9f38861e94fbf36045bb23d23076407d26fed5752efb852ad2accaea3bb" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-loader": { + "shasums": { + "jar": "bb1cd5fee23e03eec3fb5fdaff59c56d1db3829afe5f59381904764df76fb1a8", + "sources": "539b6b3e0fde31a126ee1bc885840874aae9275f28c8c7d4c30e1c15ed85b221" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-micrometer-metrics": { + "shasums": { + "jar": "1cd20b112104d244fdc96b44b3a8193e0916686a819a6be93127c1c7eefc1c9d", + "sources": "b61f894a893ef3f3e0b978e7430f08c6b3580c19ac963bbbf8901a28b2d18f6b" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-micrometer-metrics-test": { + "shasums": { + "jar": "124e88e2d8ef0331653bb9d2c849143e210e97d3ded4e8cbdb0bd68c05ea2e65", + "sources": "b17d0251cee5454db0d3e573a8c23d6b0055de534fa49b75c18bc0af6ea9f100" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-micrometer-observation": { + "shasums": { + "jar": "aced85ab6f7a2a8b15d8bd52c2b75dfe47c9890dc08d39e24b2e7b78f79b6ac2", + "sources": "8e159976cbcf123f3333793f47e88c71932ff6f2f785db8c69831bfbcf75bc3b" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-micrometer-tracing": { + "shasums": { + "jar": "dfb60c9422c80957a020e8751317bc3515f3ed56d5d92da685bfece6c0ba780a", + "sources": "c0d8f28ffbd343b00586195ee8fd34d2441562c67f01cc100578f62145e51846" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-micrometer-tracing-opentelemetry": { + "shasums": { + "jar": "3463de0849ee471c99726b8c9a334cde69a96c78c496aa452db9d9f34b53603e", + "sources": "01b024f9530bce7dabf3592a3f50fe8063c1f9f5ae6d982edf73ba85410b3cd6" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-netty": { + "shasums": { + "jar": "d5526be25b050ad5e4dd7a56095b78357bf73bbe447d900588fe7f895873ff3f", + "sources": "34b0173a82c5b35275a773b213b20591c4047b87e3f0b6dc9c1d0736b5084591" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-opentelemetry": { + "shasums": { + "jar": "42ce3e301fb94f6d15efbed5bae1c3ea9f8fe8da93afa1ac4aacf1819c1d2cd4", + "sources": "f07c50fd5e2dc2b27fbcf08f2d7ad1b8663b8611788b6bf1f4b66fe5c5dbee5b" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-persistence": { + "shasums": { + "jar": "201cd088c5fddbcff7ece343f42eee0cabbab64083d339f35e5eb4edbcdbd4bb", + "sources": "863fc339ae51cc5b5287cac067ff5527cdff2ec8da85358d8bf61fa9a460568c" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-reactor": { + "shasums": { + "jar": "abb8ac783f1a3e2de68f2ececfb22ef4ba47c74089ce377a1476f3ccf5c35539", + "sources": "0753ac2c9596f010acdac06e9bc69d3d5a35dd9abec4e44c1de600dbb7577c13" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-reactor-netty": { + "shasums": { + "jar": "5679a1518fece25f608b6abdb165bae59c4ba1aa76833700fb6cf35d528575a1", + "sources": "35281bbd1465a0a22c1f6a2188c64e2efc8535f2e30807687c77ec15197b58ca" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-restclient": { + "shasums": { + "jar": "4438e7cbe09fe2d1aa40da4112cbc2a7f0067046dbfd153e79122be6e143c82a", + "sources": "87f4a654821800a30f5d41ac5320877cd96cf436a60ac2dd541369b159a4eff2" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-resttestclient": { + "shasums": { + "jar": "976fada4921b1817e1ced3c0da93a709d85638b519a9e63c3075e76c1e3c0593", + "sources": "ad2de8d55af3be0eba0e59259eb6427fd83eca7fdd134454a0c9cde2cde4c9bc" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-security": { + "shasums": { + "jar": "fef4d4952d7c4f86112d4a27cb98cf1d71001373f9d8f88fbf0af9d908fdaa3c", + "sources": "edc45113d48d5b3f7e3ef6f722ffb905a2b0bd5791e79879b591cfe74972178e" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-security-oauth2-client": { + "shasums": { + "jar": "37a6474b11b65f39b444971572e66553512992f4434280365cedcb396b8afbec", + "sources": "dcf7f976f5e8216498d3415508598fa6e8da7248a9ae3056f94fc3abfb76c65f" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-security-oauth2-resource-server": { + "shasums": { + "jar": "d33c17f53bab6054589d94bbc36f8ed017fb0c1cd353c9b8a85359b72d4d25e8", + "sources": "2d598d95730fca23bc1ab8d08af3cad04c6cd69e5d4f728d7ce25f3f5e410953" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-security-test": { + "shasums": { + "jar": "7e34b14edd632dc3cd911931d3e3d74de40d863aa1a1849be4b217a293b14004", + "sources": "ad5a8312d621e12e659b198ded8b8c1b1a2066b34940443856e6302bd8e885b1" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-servlet": { + "shasums": { + "jar": "fb1af769617daa2808a82921d98ca94efde8cb20fcefc55e71b2e0bf93de1423", + "sources": "172a6736933d75bdeeee725078769e27d8142a826e811940c595aea815913512" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-starter": { + "shasums": { + "jar": "d70f5f300c9e7af18813799bffce38974398f6429c578c825822a32560c4b202", + "sources": "d70f5f300c9e7af18813799bffce38974398f6429c578c825822a32560c4b202" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-starter-actuator": { + "shasums": { + "jar": "576d445c6d0b7920f098822f45d74c2239f363d06508f8acf2a181f0b69c2cb9", + "sources": "576d445c6d0b7920f098822f45d74c2239f363d06508f8acf2a181f0b69c2cb9" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-starter-actuator-test": { + "shasums": { + "jar": "9f87aeefd9049094dd1fd64d96632bee353f871e0999c7c0531d69a2dcf7a945", + "sources": "9f87aeefd9049094dd1fd64d96632bee353f871e0999c7c0531d69a2dcf7a945" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-starter-aspectj": { + "shasums": { + "jar": "5521390213e6f2a0a3ef0d78eed35094868f840888823f9508e175dab10e7306", + "sources": "5521390213e6f2a0a3ef0d78eed35094868f840888823f9508e175dab10e7306" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-starter-data-cassandra": { + "shasums": { + "jar": "32abc561b414e781bc1998e1a6cd1167f3eff2247e6bb2b1b08a347bb3054acb", + "sources": "32abc561b414e781bc1998e1a6cd1167f3eff2247e6bb2b1b08a347bb3054acb" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-starter-data-cassandra-test": { + "shasums": { + "jar": "aacd60f7f5cab180a23dbd87fd5b53d524c2c89ce42635d5eaa4331075dec548", + "sources": "aacd60f7f5cab180a23dbd87fd5b53d524c2c89ce42635d5eaa4331075dec548" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-starter-jackson": { + "shasums": { + "jar": "bd042218bf291c4ee821d7ec3e86f7f747223d32cd87066aa5e3730a2dd5c3b6", + "sources": "bd042218bf291c4ee821d7ec3e86f7f747223d32cd87066aa5e3730a2dd5c3b6" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-starter-jackson-test": { + "shasums": { + "jar": "72ad611e32e370446bb2de890da4f084def1d354f4526522f0ae1182265b545a", + "sources": "72ad611e32e370446bb2de890da4f084def1d354f4526522f0ae1182265b545a" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-starter-logging": { + "shasums": { + "jar": "b5f1d01cd179ffc24b125a6ce971854b7b141c4e19e9c050a0b82d514983b1f6", + "sources": "b5f1d01cd179ffc24b125a6ce971854b7b141c4e19e9c050a0b82d514983b1f6" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-starter-micrometer-metrics": { + "shasums": { + "jar": "a5d302b2d6e9a8e1989455888aad2f69349f4c0b43b7ef41c8063c4bb92dec32", + "sources": "a5d302b2d6e9a8e1989455888aad2f69349f4c0b43b7ef41c8063c4bb92dec32" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-starter-micrometer-metrics-test": { + "shasums": { + "jar": "dd6d8969ce0e7736d29c5ce1dbdf9d9d89ac0c7ecbae41485abeb5b3efe87546", + "sources": "dd6d8969ce0e7736d29c5ce1dbdf9d9d89ac0c7ecbae41485abeb5b3efe87546" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-starter-reactor-netty": { + "shasums": { + "jar": "ceebf772bae1c9492fce1c766fdc18a7a17388f02f639a6ba20824b8a3dd848c", + "sources": "ceebf772bae1c9492fce1c766fdc18a7a17388f02f639a6ba20824b8a3dd848c" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-starter-security": { + "shasums": { + "jar": "04e806b5737be0d399c85d356b060599684df6fc4f56cc08b85a563ae1a066dd", + "sources": "04e806b5737be0d399c85d356b060599684df6fc4f56cc08b85a563ae1a066dd" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-starter-security-oauth2-client": { + "shasums": { + "jar": "1afd7f96736afc19451ad2a4f001e54af93d9d9d788802df9f4e536860560aca", + "sources": "1afd7f96736afc19451ad2a4f001e54af93d9d9d788802df9f4e536860560aca" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server": { + "shasums": { + "jar": "72dbb14dc0b21f43cee18ae6caa6bf7b0c4efe4bac11702e34529280865ecd83", + "sources": "72dbb14dc0b21f43cee18ae6caa6bf7b0c4efe4bac11702e34529280865ecd83" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server-test": { + "shasums": { + "jar": "8e13abf7c7754171c83c8236b796ef3d6e8d841a3ddafd84dfec0e5615b77e75", + "sources": "8e13abf7c7754171c83c8236b796ef3d6e8d841a3ddafd84dfec0e5615b77e75" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-starter-security-test": { + "shasums": { + "jar": "a7320624975022865468e255b8e0c414f76d380eef7793faeca87f98496998ad", + "sources": "a7320624975022865468e255b8e0c414f76d380eef7793faeca87f98496998ad" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-starter-test": { + "shasums": { + "jar": "e4844ae2375d569711af218763620993ea434b4836d3463cf26d9f6b6e589340", + "sources": "e4844ae2375d569711af218763620993ea434b4836d3463cf26d9f6b6e589340" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-starter-tomcat": { + "shasums": { + "jar": "f4a81ce616baa9c715be0dc0735210d770aa67301f92d3b11942f780056fc7ad", + "sources": "f4a81ce616baa9c715be0dc0735210d770aa67301f92d3b11942f780056fc7ad" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-starter-tomcat-runtime": { + "shasums": { + "jar": "8d0c7cbd6bd43d47e664a9127f70ceddab952828797f20e2b0b93848796d82f2", + "sources": "8d0c7cbd6bd43d47e664a9127f70ceddab952828797f20e2b0b93848796d82f2" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-starter-validation": { + "shasums": { + "jar": "bc449f60bb483374e7358afcda3fccb6e01906e158c7e1e00d9035277a6545b7", + "sources": "bc449f60bb483374e7358afcda3fccb6e01906e158c7e1e00d9035277a6545b7" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-starter-web": { + "shasums": { + "jar": "1ac009b240450c089df7ef1e5cc9b63df292bea22393ed5c7deca42c85944e3c", + "sources": "1ac009b240450c089df7ef1e5cc9b63df292bea22393ed5c7deca42c85944e3c" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-starter-webflux": { + "shasums": { + "jar": "dd99ab79bd18c6358183b146c3eb35730652dd36d2225d5795405efa7137b1a0", + "sources": "dd99ab79bd18c6358183b146c3eb35730652dd36d2225d5795405efa7137b1a0" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-starter-webflux-test": { + "shasums": { + "jar": "78c866953b611065c85b8f069b18d330c1f2051db932fc3a3e8213b852b7f8eb", + "sources": "78c866953b611065c85b8f069b18d330c1f2051db932fc3a3e8213b852b7f8eb" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-starter-webmvc": { + "shasums": { + "jar": "b70e0d9e1bc667a3a9ad509f98a6e9ac443af8eab5143f8c77a38aec0a014a2c", + "sources": "b70e0d9e1bc667a3a9ad509f98a6e9ac443af8eab5143f8c77a38aec0a014a2c" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-starter-webmvc-test": { + "shasums": { + "jar": "d11fd7bbd613040f88ddba503c486970dd282abb92f12158bc9655ee533e9f31", + "sources": "d11fd7bbd613040f88ddba503c486970dd282abb92f12158bc9655ee533e9f31" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-test": { + "shasums": { + "jar": "8879b4a336972eb498ca6606266e6ecdae911964c0a480d3f4bf37a6c2455b33", + "sources": "4dc67a1a332d75fa3dcf517f4b6dc66ed146793307aa9d23c0ebb5f4b399850a" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-test-autoconfigure": { + "shasums": { + "jar": "99ca7ab8be0dde10fa6c03e1026969619e826fcc914b6bc0d09090e75ba17cb4", + "sources": "f94cf34c24539cc3752fae1a0bf182282086452e9c83cfae5241574f20951eb3" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-tomcat": { + "shasums": { + "jar": "ad7c6527319f5cac0b5638a28820847f64d21282147fb98daaaa1f515ee17323", + "sources": "2388d2eaeb9d413d3d7525983fe14030d3b48bc0cca1530c8c7e9dc73e05e8b5" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-validation": { + "shasums": { + "jar": "15161d6eda4589a24ea30d1fd466bfe3843861c3b55963d49a26bfc0bf2ebbb2", + "sources": "52beb1b2b90adb6cec5bf8523e534e56fed771a7f0fe3d42191a4d3b8a5d3873" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-web-server": { + "shasums": { + "jar": "26a13c73ee85e7a851b73eb2d683ed4d3b7a4ca581b608dfd627bd4551997cf2", + "sources": "41e1dddf6e1be5fc35c4849f51639c097e7a8eb9c6627a780791a1d9e430c311" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-webclient": { + "shasums": { + "jar": "119d82faa651b35964eab73ea3d962b1c7434792647cbf82c9dde44785749671", + "sources": "bf3dd5bf566482bc32c0c75548eb9c6a598b4d26c66677cfb84fca4cd21ccf81" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-webflux": { + "shasums": { + "jar": "7eca957fe0ad8ee60642d58e6a8e652ebaf64198b72f9ccfa959bea056fb7091", + "sources": "fc7dcb5570215a40c78fdab85c60876b740be714cb479d03b3bd39b2c7b26e5f" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-webflux-test": { + "shasums": { + "jar": "3ed73416ab316d0247d9c2efbb922db1247f03d114fada897f70f9d59408c839", + "sources": "5164cd1c633380d2f2616855a2773f099f15aebc2ad70c04a942e673be12be6b" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-webmvc": { + "shasums": { + "jar": "95250948bda9a0a1e1f2ad3f413bd23e36dfedefb89fe59d309d447c6c4c5010", + "sources": "26a04367e170092463c619c886f4f8b688644eecc4a6c91c18d17c242a8f4211" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-webmvc-test": { + "shasums": { + "jar": "06180d3ee7f9019880b0528cc93164f8f038e35007bd99a40fbe52892d96a955", + "sources": "4c5b614a96d50a44fce7c3269b82f26fed6d3d04933140ecf52db5e4d32e2480" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-webtestclient": { + "shasums": { + "jar": "7015636f7e41b69d80fd903acdcb1554f2b062551c1ce353e625ea4a11f52903", + "sources": "b1175e4937c93d493bbae0a2c7e2cee13cd60a6b7dd859fb6e662091f986e28f" + }, + "version": "4.0.7" + }, + "org.springframework.cloud:spring-cloud-commons": { + "shasums": { + "jar": "6973e75b09d7ccb98566e4e980f600cd98ffcdc76d19fd822e93c7c2166ffa49", + "sources": "fd39f42ebda40c120a450256bbca653d250ff105ea640a530680c1251ced5ca3" + }, + "version": "5.0.2" + }, + "org.springframework.cloud:spring-cloud-context": { + "shasums": { + "jar": "8972e4677e511dc518280d13a16d1a3e6e3ed4ee91e643d3f0c66676f6078f75", + "sources": "3765a79f4a43fe01a1298b09cd8ee51f0e9692971555478fd157bdf456a70c7b" + }, + "version": "5.0.2" + }, + "org.springframework.cloud:spring-cloud-kubernetes-client-autoconfig": { + "shasums": { + "jar": "3ccfe0d3f130c7e2ddede783c416a331e935c5818df7ad6a0369c646641cd596", + "sources": "15ba3dfaf88146e82232510b8a02bdb1c0e6982efe5a0e00a5bbaacd40f7321f" + }, + "version": "5.0.2" + }, + "org.springframework.cloud:spring-cloud-kubernetes-client-config": { + "shasums": { + "jar": "3891c4930a4c214e316a6f1624a596c4007f759b3465cc1fa3cb1fc7edba2614", + "sources": "abf13b94b56188d1df40c9f080c3771c77c1252350a4d6b674887fa1466076e5" + }, + "version": "5.0.2" + }, + "org.springframework.cloud:spring-cloud-kubernetes-commons": { + "shasums": { + "jar": "34a0c7e9a1036e03faa0d75655f7e82eade86f6fc3b4ae2273e434b5798bd8f5", + "sources": "bec63622fa749d090a711f9a24b0c0561f70a8ee5853db7c1bf727990c373817" + }, + "version": "5.0.2" + }, + "org.springframework.cloud:spring-cloud-starter": { + "shasums": { + "jar": "7568b8ced4069bc055af52b5455b206092401a44dcbd4f89d6fa00f89df1cc18" + }, + "version": "5.0.2" + }, + "org.springframework.cloud:spring-cloud-starter-bootstrap": { + "shasums": { + "jar": "366aa9da9bd1e8222bed83fa698649b16ba4b2a976a028d565b95afe610735df", + "sources": "46bb02036834b9db0cfe086ca2b4e9581319029e9dff2b420ddf3eb8094f3d62" + }, + "version": "5.0.2" + }, + "org.springframework.cloud:spring-cloud-starter-kubernetes-client-config": { + "shasums": { + "jar": "f0b4f8adf2dbac198147d18e1890e5ebd5f41d8de4db68ae5eca930e946c1efe" + }, + "version": "5.0.2" + }, + "org.springframework.data:spring-data-cassandra": { + "shasums": { + "jar": "d9e4f2656df238d5561d02d0521036f52518b91d0ef840fd8f25d113b4325610", + "sources": "35340468867c3c37447606312f1d2e2ab18b5123885967a364743f77f196bdb7" + }, + "version": "5.0.6" + }, + "org.springframework.data:spring-data-commons": { + "shasums": { + "jar": "626151b9c33ab98ebec7f1a2e9746cfe1aa428b0de513f9bb90383533ab8ba6d", + "sources": "8d08a88e7b6761bfb84a79fadde38bafaeeed90ddf4595ba9cbf71c25ed7e2dd" + }, + "version": "4.0.6" + }, + "org.springframework.retry:spring-retry": { + "shasums": { + "jar": "213785750007f90b067ba43036cbffdad2890f6bb98917e199f6b049cf810040", + "sources": "672447ec8df39cf31fcd8b9fdd209ae65776fb06c17e1e6fd13e30943963947b" + }, + "version": "2.0.13" + }, + "org.springframework.security:spring-security-config": { + "shasums": { + "jar": "7aeafd876d48d8b5660356953ed7a607d2d09e8f2b9844acba3fcbc32beb63cc", + "sources": "aeb9131e5cd38ea7ebeb0d348c90da837c807f8b68ae3c0fc3152a46682f16ee" + }, + "version": "7.0.6" + }, + "org.springframework.security:spring-security-core": { + "shasums": { + "jar": "f9e1aebb39e051f6f92be029a6fca31e2977a06d417aa51504bfb298bc2a7c69", + "sources": "73d208a0dd021cad8cbbb85a71c8efc66df0161f49e91cd9d877a55def6bc9d0" + }, + "version": "7.0.6" + }, + "org.springframework.security:spring-security-crypto": { + "shasums": { + "jar": "baf9f76bc5b15d090a82841fd5713fa11b75f91fc86de27029d972ce85d3d2e2", + "sources": "bb183230f96711625bdc1d0fc45398917062c2b6b605f94f8dbf0de6a7a1f862" + }, + "version": "7.0.6" + }, + "org.springframework.security:spring-security-oauth2-client": { + "shasums": { + "jar": "2c50bff8f60f08a46bef837dca50d1270f0dba64a60f551c0b96b33a1f608487", + "sources": "47549b16e028266bf4836b4bf00e9111a46143ae486aaed1ff0370c56ddbe82a" + }, + "version": "7.0.6" + }, + "org.springframework.security:spring-security-oauth2-core": { + "shasums": { + "jar": "01cc03b6f30e5b526e85fc276b32af25f34b119f601bc17ba3cbe023f45b0271", + "sources": "68bc19e0b85c108766d92bc4a9e9948a641d65d23d1d93cca7f724998665f88f" + }, + "version": "7.0.6" + }, + "org.springframework.security:spring-security-oauth2-jose": { + "shasums": { + "jar": "c8cd9a8aefc42a02e34166ff02f3f7def2f6028f555932f04f163dea729bdff9", + "sources": "1a33db514d2ce33222aae9bb3ba41227112de08986aac4e58be857417e7332ea" + }, + "version": "7.0.6" + }, + "org.springframework.security:spring-security-oauth2-resource-server": { + "shasums": { + "jar": "4c53ad5b6a06b9f6272212b5a0a71d003b4ba01dd16de691fd63ddf37554f098", + "sources": "97d33151cd02afcded341ab7ad65f1bcca4798789f5626a5d948809ba529373a" + }, + "version": "7.0.6" + }, + "org.springframework.security:spring-security-test": { + "shasums": { + "jar": "4b65c38c7fcf372793cdf6e57651be1332ec241fff9481b15ed8f3ea2207382c", + "sources": "61886c39c6853ebafa91718c1bc44ebaad6f834dcb8d0524e509135033c9498c" + }, + "version": "7.0.6" + }, + "org.springframework.security:spring-security-web": { + "shasums": { + "jar": "6ef060f97271218c0bff56273dc2edb8e2e001a253a0291278d5fdafa5d70573", + "sources": "33298fd169429984bb6cebf9f4a6176ae9eee047e8b5a3ab6b3d752526db03d9" + }, + "version": "7.0.6" + }, + "org.springframework:spring-aop": { + "shasums": { + "jar": "1178f039e087884174e2affc46e484f4a8bd7f2a4e011d33dd9137709f740f80", + "sources": "580610d9e5e2418ea48f64850673ed1d1fdc2d9c8e5cf6e9cfaece1e61b70522" + }, + "version": "7.0.8" + }, + "org.springframework:spring-beans": { + "shasums": { + "jar": "6ec2e361a8872a71d8b1ff66f1bcb8cfa29fcc437931998919da7cecfb59b45b", + "sources": "d75bdcfe142b1576f72356748292cad5c21872a52be2c7f2920a9795bb3c52a5" + }, + "version": "7.0.8" + }, + "org.springframework:spring-context": { + "shasums": { + "jar": "1eb7d552414ebac00e30ab3e809138d810785f6d2c4271db77cdf0181f308f19", + "sources": "a28b30679b51bcf8aac7f06cb564a379cc2d6c4891b2e2dfc738ddd750c6278e" + }, + "version": "7.0.8" + }, + "org.springframework:spring-context-support": { + "shasums": { + "jar": "9ab80715682c47ad66a1a2c0e9ab2be9ec3d828276f281597f12c5208147b92e", + "sources": "22d3e1ee4d52ede6b31cd6fd27d65d4bdd0b2709fcc14af92ec287286ae8abf3" + }, + "version": "7.0.8" + }, + "org.springframework:spring-core": { + "shasums": { + "jar": "726ba2a5130833644bdf267a55ff26e1f52e8dcc9aa1ffa06904ca9c14619f25", + "sources": "3cbdaed9f2b1eea10d8ac27148ac5e6407d2861fa2d373253a09a1220a232919" + }, + "version": "7.0.8" + }, + "org.springframework:spring-expression": { + "shasums": { + "jar": "3c97c38ab59c77ee886e08ccf8096f6bb58a1245f68dfed7a40e93f41c435f9a", + "sources": "35517249c504d1d4550186808665587c8bb5be953cb6cbbb3856804194e790e9" + }, + "version": "7.0.8" + }, + "org.springframework:spring-test": { + "shasums": { + "jar": "6ffb7796075a204915edc4bb9e54dc420183cecb520d753004f660f153763c8e", + "sources": "7bc670e2e1c9cc902da5557a857dde0a4d8089c267ccfcc1bb554cbf2a8c5a05" + }, + "version": "7.0.8" + }, + "org.springframework:spring-tx": { + "shasums": { + "jar": "57e8fdb6de949e7ec2617683fec03af0253bdbdf4bf3d2651a926a94413df283", + "sources": "7887541d74a7221ca92e21d1a2ecc13e8f98767b1603b3b6bb81d7bbd5aede48" + }, + "version": "7.0.8" + }, + "org.springframework:spring-web": { + "shasums": { + "jar": "4d4ed7ecb0453d25d735ea27d025ea36b003c3d29cb7d006bedd6d5188a2f5c0", + "sources": "281cbbd965844cdf2e08396924eacd8a369cd38f56fdfb9519c7492217d8b411" + }, + "version": "7.0.8" + }, + "org.springframework:spring-webflux": { + "shasums": { + "jar": "3e48db9c30d3768ac14898cfad4bad21f4cfc6a8979a12071b75e725143e5eb9", + "sources": "9b00f6ad4a63f3c636e455f3e733d0f75cf5dcdd8225820a1498469b707652ba" + }, + "version": "7.0.8" + }, + "org.springframework:spring-webmvc": { + "shasums": { + "jar": "48f7e1e2d0d46e98ed3fa30d5a64cb1f7ed2aa339a82edcd87289ed8ff216f04", + "sources": "6dcbc3dc4d5222121f83d1eb0d30807e389771b8d233be38b8e413b92b88a106" + }, + "version": "7.0.8" + }, + "org.testcontainers:testcontainers": { + "shasums": { + "jar": "0466f481343d5f350a91274cd7bf984308cbaf90d706247fd1cf4b1a8010c2e1", + "sources": "b4dfdb7d0f8dadc6bfa6d817df703b5c6881b83b6d0452148fd9a00434387e24" + }, + "version": "2.0.5" + }, + "org.testcontainers:testcontainers-cassandra": { + "shasums": { + "jar": "c6ce343636e40330da6ffa317ca4a56bf09affd3e272445d0176498497218cbe", + "sources": "4b2324b4336a0e6d928467abef387ded2b9014ab1353f85cf715f87d1dbb5be3" + }, + "version": "2.0.5" + }, + "org.testcontainers:testcontainers-database-commons": { + "shasums": { + "jar": "0ebbc62bdcfb315cb840a63fbaa148b455927666d9034b5e5c00009d84c755b0", + "sources": "017efc160847bf209b3fdfa3561fa6eb1a5b5b5b82d2214f965caabe9c2cf9ab" + }, + "version": "2.0.5" + }, + "org.testcontainers:testcontainers-junit-jupiter": { + "shasums": { + "jar": "d66eb7f257a85833a8cc973e3814d740967d40a7db1a0de0040653c6ed236748", + "sources": "0dd4463ca900cbce90894cdaafb18fd146ea50b92ee0ee72a9c3e1e48b53a8e6" + }, + "version": "2.0.5" + }, + "org.testcontainers:testcontainers-localstack": { + "shasums": { + "jar": "2fa0f4271a69112ece3841bb26b251962280e39f2e6b2daa7a4aa9128a54485d", + "sources": "b37477b207c29a395c8d0428a6131954aa3495ba2cf5a8db40c9f57c1e8cfa8d" + }, + "version": "2.0.5" + }, + "org.wiremock:wiremock-standalone": { + "shasums": { + "jar": "d097b19bd483c5038479b13a5c71e9faf8f2f5106584f0c120a7770ab0bdb367", + "sources": "76cda98377991ed09088773fe7127f9787e14f8bd41bcd285f94cbd7cd95546f" + }, + "version": "3.13.2" + }, + "org.xmlunit:xmlunit-core": { + "shasums": { + "jar": "208e0cee82aedd9183937e4b9ae44b83884179f724a706bef5795477acfcca91", + "sources": "bb8dba65e8bc1ade346e4bfd98d7f620f51ae8b9034e9758cd6f3031838e79fd" + }, + "version": "2.10.4" + }, + "org.yaml:snakeyaml": { + "shasums": { + "jar": "e6682acf1ace77508ef13649cbf4f8d09d2cf5457bdb61d25ffb6ac0233d78dd", + "sources": "7a7d307ca9fe1663219a60045a8e5a113a69331566f9ebbe1d3b12c6781909ac" + }, + "version": "2.5" + }, + "software.amazon.awssdk:annotations": { + "shasums": { + "jar": "fa3ba3b1b635dfc4d0b20f3910b325f8b70419d1fdb56b487d2e1c423c85e041", + "sources": "2c15cad3cec83ce99c86b9f135d24f42429c5c9a4d032351adfc42330cde8b97" + }, + "version": "2.40.1" + }, + "software.amazon.awssdk:checksums": { + "shasums": { + "jar": "6770fdd0d970c1869cd869d784cc20963a4a6b2bee09f125da0504ba2c9e818d", + "sources": "3a5de1a7994ab25bef0eda898645ba6f02ab584bd3d904f21014bfd9d7cb98b5" + }, + "version": "2.40.1" + }, + "software.amazon.awssdk:checksums-spi": { + "shasums": { + "jar": "1f9d68cd2f5ec133757e37b794ab06de015d1b35f4c1452b43ab8b612318a8c3", + "sources": "d17d8d92268f9c6773aa6b72564774dc394ae2fb2149bed26152385a9b6751ff" + }, + "version": "2.40.1" + }, + "software.amazon.awssdk:endpoints-spi": { + "shasums": { + "jar": "05a48200f243664fa9ca8f05cf29725cbd059a9a6f3cdd55bac44a8fc12903de", + "sources": "24644eb6a36a38df7a31e81fb9fcd106298f188215b6e2ec178732711fc4b0ba" + }, + "version": "2.40.1" + }, + "software.amazon.awssdk:http-auth-aws": { + "shasums": { + "jar": "9b182f3697acc111b213524126f857f844fed5fdf95f734470d16b96097fcd3a", + "sources": "6de3c527d996a46a4e14e268fc13a32b314383a3b2976e7820720c9ddff483a5" + }, + "version": "2.40.1" + }, + "software.amazon.awssdk:http-auth-spi": { + "shasums": { + "jar": "d0cd6f8dd1ef77a990c4b0ae45132707490f886307d9ee446ae1eae93a80ae5a", + "sources": "6bd36a3bfbce87b5550d73ad7ff6d0950dc6aec1baf071b0c47bd02cd98daa3d" + }, + "version": "2.40.1" + }, + "software.amazon.awssdk:http-client-spi": { + "shasums": { + "jar": "87c6fc3ec6c79e088ebfcc818963715bc0a5e103f5612bd4b6d5c49720bb06e3", + "sources": "d6667c353cc231efee460dae061be2b654d3319ffb66d16804da30f5a8475d84" + }, + "version": "2.40.1" + }, + "software.amazon.awssdk:identity-spi": { + "shasums": { + "jar": "b4693f3832b3669850a11f29608a2a3d6e0150ab1528d01cad2a7a32848db591", + "sources": "56ab003dea16ded5f70c1a3af840433c6f5f8fd33435500535e7b888cdf8c923" + }, + "version": "2.40.1" + }, + "software.amazon.awssdk:json-utils": { + "shasums": { + "jar": "f565187ae223ab13a4b959f213933540475652269c414b0c82f33cab45977a74", + "sources": "3fbd4a882a672587b93b9cdd2ee7c2c1faa0f5a848509d3d3d7931ef714d6d95" + }, + "version": "2.40.1" + }, + "software.amazon.awssdk:metrics-spi": { + "shasums": { + "jar": "033b5d20384c9b4ac98a17eba0656711738da94a9d33a292b414aa0905177471", + "sources": "373fbebacc328596dda847d8183f22b9e6abef85f7c6287d7c71615cab3d4939" + }, + "version": "2.40.1" + }, + "software.amazon.awssdk:profiles": { + "shasums": { + "jar": "602cac04531cf13d4c06d8d70d7b5b0e109517c73a4c91473058886fbe574cc1", + "sources": "e498cf7ef147b8fc789a448554561b5706daae1062a5e23bc4870149b42d8002" + }, + "version": "2.40.1" + }, + "software.amazon.awssdk:regions": { + "shasums": { + "jar": "6b1c788306fd7a4fac6bc788a8f5d2300be13049197adacfca072d1b69eb9ddb", + "sources": "1bae6ad3cb124a6850fbede87c9dcd72f7c7eab1f570c9ae71a98f3597c4b59f" + }, + "version": "2.40.1" + }, + "software.amazon.awssdk:retries": { + "shasums": { + "jar": "198f5f0202fe8e861f3ad2fa8ecb70d0a8180dd568f4d136c898f824b3cd0dd3", + "sources": "2305b334eceb894749d281a3f48be9198e9305f09cb3b40b948a5c661c20c41a" + }, + "version": "2.40.1" + }, + "software.amazon.awssdk:retries-spi": { + "shasums": { + "jar": "af1c67e4212fffe7d215b41fb74e6994c36a0499234e325954c38db6b14e0e28", + "sources": "c8e5f28924cc8e0cb017a2a25c370a0d0ed9223cfb0051c6a1b0c769a5a46e0b" + }, + "version": "2.40.1" + }, + "software.amazon.awssdk:sdk-core": { + "shasums": { + "jar": "6c6b1a49b18538060d1f9a797998ca8d589910b274b345bbf0a61c4540e41f27", + "sources": "560156fe956a48cd171077edc2ccb1bcfe2f93c09e3ce62667018228b6144450" + }, + "version": "2.40.1" + }, + "software.amazon.awssdk:third-party-jackson-core": { + "shasums": { + "jar": "9939a77038dd0d53675a44fc06afb9b34805cef8fc7b3641d2e861740c1655fc", + "sources": "92ce15d5817f97d935c595b780135666d4674eaf3aeb94ae13b1e4e553f93e42" + }, + "version": "2.40.1" + }, + "software.amazon.awssdk:utils": { + "shasums": { + "jar": "40f19e6ce26acc6a78204aa493833f578e2245cc0bc9749cc9ba431bb8f855e1", + "sources": "2ddd7c56fbc36d7c4e0c84739d68388faff130f51855ce2b80466c8784cf1b25" + }, + "version": "2.40.1" + }, + "tools.jackson.core:jackson-core": { + "shasums": { + "jar": "3bda1cd6eff0a8d47bdfcaeae7c2bd5311d6c8ed494ef5f3e51029bb44aa9bdf", + "sources": "5aa481c1c120505fc1d204510ec201a40c2bb0bb6bdea24560e0b5fb66484e60" + }, + "version": "3.1.4" + }, + "tools.jackson.core:jackson-databind": { + "shasums": { + "jar": "14034bfdf392b6ebec1b4bb6c1de29d604f0aa97251259a19d5f19af8719bb20", + "sources": "109baa39968ff6fdcc4389dd4249f04d2edcab7387421ea17bfb51bf18e24189" + }, + "version": "3.1.4" + }, + "tools.jackson.module:jackson-module-blackbird": { + "shasums": { + "jar": "d93aef324acdbffeb4e943e75ed0772f43101930b70fe37219147e5d3b84b3cd", + "sources": "5c7f6900e8b888c6c3edad9b13cd4df0d11f5bd8307064bb79881cb4edd389ef" + }, + "version": "3.1.4" + } + }, + "conflict_resolution": { + "com.github.jnr:jnr-ffi:2.2.11": "com.github.jnr:jnr-ffi:2.1.7", + "com.github.jnr:jnr-posix:3.0.44": "com.github.jnr:jnr-posix:3.1.15", + "com.squareup.okio:okio-jvm:3.6.0": "com.squareup.okio:okio-jvm:3.16.1", + "commons-io:commons-io:2.19.0": "commons-io:commons-io:2.20.0", + "io.grpc:grpc-core:1.63.0": "io.grpc:grpc-core:1.74.0", + "io.grpc:grpc-util:1.63.0": "io.grpc:grpc-util:1.74.0", + "io.perfmark:perfmark-api:0.26.0": "io.perfmark:perfmark-api:0.27.0", + "org.apache.commons:commons-compress:1.27.1": "org.apache.commons:commons-compress:1.28.0", + "org.jetbrains:annotations:13.0": "org.jetbrains:annotations:17.0.0" + }, + "dependencies": { + "ch.qos.logback:logback-classic": [ + "ch.qos.logback:logback-core", + "org.slf4j:slf4j-api" + ], + "com.datastax.cassandra:cassandra-driver-core": [ + "com.fasterxml.jackson.core:jackson-databind", + "com.github.jnr:jnr-ffi", + "com.github.jnr:jnr-posix", + "com.google.guava:guava", + "io.dropwizard.metrics:metrics-core", + "io.netty:netty-handler", + "org.slf4j:slf4j-api" + ], + "com.fasterxml.jackson.core:jackson-databind": [ + "com.fasterxml.jackson.core:jackson-annotations", + "com.fasterxml.jackson.core:jackson-core" + ], + "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml": [ + "com.fasterxml.jackson.core:jackson-core", + "com.fasterxml.jackson.core:jackson-databind", + "org.yaml:snakeyaml" + ], + "com.fasterxml.jackson.datatype:jackson-datatype-jsr310": [ + "com.fasterxml.jackson.core:jackson-annotations", + "com.fasterxml.jackson.core:jackson-core", + "com.fasterxml.jackson.core:jackson-databind" + ], + "com.github.ben-manes.caffeine:caffeine": [ + "com.google.errorprone:error_prone_annotations", + "org.jspecify:jspecify" + ], + "com.github.ben-manes.caffeine:guava": [ + "com.github.ben-manes.caffeine:caffeine", + "com.google.guava:guava" + ], + "com.github.docker-java:docker-java-api": [ + "com.fasterxml.jackson.core:jackson-annotations", + "org.slf4j:slf4j-api" + ], + "com.github.docker-java:docker-java-transport-zerodep": [ + "com.github.docker-java:docker-java-transport", + "net.java.dev.jna:jna", + "org.slf4j:slf4j-api" + ], + "com.github.java-json-tools:btf": [ + "com.google.code.findbugs:jsr305" + ], + "com.github.java-json-tools:jackson-coreutils": [ + "com.fasterxml.jackson.core:jackson-databind", + "com.github.java-json-tools:msg-simple", + "com.google.code.findbugs:jsr305" + ], + "com.github.java-json-tools:json-patch": [ + "com.fasterxml.jackson.core:jackson-databind", + "com.github.java-json-tools:jackson-coreutils", + "com.github.java-json-tools:msg-simple" + ], + "com.github.java-json-tools:msg-simple": [ + "com.github.java-json-tools:btf", + "com.google.code.findbugs:jsr305" + ], + "com.github.jnr:jnr-ffi": [ + "com.github.jnr:jffi", + "com.github.jnr:jffi:jar:native", + "com.github.jnr:jnr-x86asm", + "org.ow2.asm:asm", + "org.ow2.asm:asm-analysis", + "org.ow2.asm:asm-commons", + "org.ow2.asm:asm-tree", + "org.ow2.asm:asm-util" + ], + "com.github.jnr:jnr-posix": [ + "com.github.jnr:jnr-constants", + "com.github.jnr:jnr-ffi" + ], + "com.google.api.grpc:proto-google-common-protos": [ + "com.google.protobuf:protobuf-java" + ], + "com.google.guava:guava": [ + "com.google.code.findbugs:jsr305", + "com.google.errorprone:error_prone_annotations", + "com.google.guava:failureaccess", + "com.google.guava:listenablefuture", + "com.google.j2objc:j2objc-annotations", + "org.checkerframework:checker-qual" + ], + "com.google.protobuf:protobuf-java-util": [ + "com.google.code.findbugs:jsr305", + "com.google.code.gson:gson", + "com.google.errorprone:error_prone_annotations", + "com.google.protobuf:protobuf-java" + ], + "com.jayway.jsonpath:json-path": [ + "net.minidev:json-smart", + "org.slf4j:slf4j-api" + ], + "com.nimbusds:oauth2-oidc-sdk": [ + "com.github.stephenc.jcip:jcip-annotations", + "com.nimbusds:content-type", + "com.nimbusds:lang-tag", + "com.nimbusds:nimbus-jose-jwt", + "net.minidev:json-smart" + ], + "com.squareup.okhttp3:logging-interceptor": [ + "com.squareup.okhttp3:okhttp", + "org.jetbrains.kotlin:kotlin-stdlib-jdk8" + ], + "com.squareup.okhttp3:okhttp": [ + "com.squareup.okio:okio", + "org.jetbrains.kotlin:kotlin-stdlib-jdk8" + ], + "com.squareup.okhttp3:okhttp-jvm": [ + "com.squareup.okio:okio-jvm", + "org.jetbrains.kotlin:kotlin-stdlib" + ], + "com.squareup.okio:okio": [ + "com.squareup.okio:okio-jvm" + ], + "com.squareup.okio:okio-jvm": [ + "org.jetbrains.kotlin:kotlin-stdlib" + ], + "io.cloudevents:cloudevents-core": [ + "io.cloudevents:cloudevents-api" + ], + "io.cloudevents:cloudevents-json-jackson": [ + "com.fasterxml.jackson.core:jackson-core", + "com.fasterxml.jackson.core:jackson-databind", + "io.cloudevents:cloudevents-core" + ], + "io.dropwizard.metrics:metrics-core": [ + "org.slf4j:slf4j-api" + ], + "io.grpc:grpc-api": [ + "com.google.code.findbugs:jsr305", + "com.google.errorprone:error_prone_annotations", + "com.google.guava:guava" + ], + "io.grpc:grpc-context": [ + "io.grpc:grpc-api" + ], + "io.grpc:grpc-core": [ + "com.google.android:annotations", + "com.google.code.gson:gson", + "com.google.errorprone:error_prone_annotations", + "com.google.guava:guava", + "io.grpc:grpc-api", + "io.grpc:grpc-context", + "io.perfmark:perfmark-api", + "org.codehaus.mojo:animal-sniffer-annotations" + ], + "io.grpc:grpc-inprocess": [ + "com.google.guava:guava", + "io.grpc:grpc-api", + "io.grpc:grpc-core" + ], + "io.grpc:grpc-netty": [ + "com.google.errorprone:error_prone_annotations", + "com.google.guava:guava", + "io.grpc:grpc-api", + "io.grpc:grpc-core", + "io.grpc:grpc-util", + "io.netty:netty-codec-http2", + "io.netty:netty-handler-proxy", + "io.netty:netty-transport-native-unix-common", + "io.perfmark:perfmark-api", + "org.codehaus.mojo:animal-sniffer-annotations" + ], + "io.grpc:grpc-netty-shaded": [ + "com.google.errorprone:error_prone_annotations", + "com.google.guava:guava", + "io.grpc:grpc-api", + "io.grpc:grpc-core", + "io.grpc:grpc-util", + "io.perfmark:perfmark-api" + ], + "io.grpc:grpc-protobuf": [ + "com.google.api.grpc:proto-google-common-protos", + "com.google.code.findbugs:jsr305", + "com.google.guava:guava", + "com.google.protobuf:protobuf-java", + "io.grpc:grpc-api", + "io.grpc:grpc-protobuf-lite" + ], + "io.grpc:grpc-protobuf-lite": [ + "com.google.code.findbugs:jsr305", + "com.google.guava:guava", + "io.grpc:grpc-api" + ], + "io.grpc:grpc-services": [ + "com.google.code.gson:gson", + "com.google.errorprone:error_prone_annotations", + "com.google.guava:guava", + "com.google.j2objc:j2objc-annotations", + "com.google.protobuf:protobuf-java-util", + "io.grpc:grpc-core", + "io.grpc:grpc-protobuf", + "io.grpc:grpc-stub", + "io.grpc:grpc-util" + ], + "io.grpc:grpc-stub": [ + "com.google.errorprone:error_prone_annotations", + "com.google.guava:guava", + "io.grpc:grpc-api" + ], + "io.grpc:grpc-util": [ + "com.google.guava:guava", + "io.grpc:grpc-api", + "io.grpc:grpc-core", + "org.codehaus.mojo:animal-sniffer-annotations" + ], + "io.gsonfire:gson-fire": [ + "com.google.code.gson:gson" + ], + "io.kubernetes:client-java": [ + "com.google.protobuf:protobuf-java", + "commons-codec:commons-codec", + "commons-io:commons-io", + "io.kubernetes:client-java-api", + "io.kubernetes:client-java-proto", + "org.apache.commons:commons-collections4", + "org.apache.commons:commons-compress", + "org.apache.commons:commons-lang3", + "org.bitbucket.b_c:jose4j", + "org.bouncycastle:bcpkix-jdk18on", + "org.slf4j:slf4j-api", + "org.yaml:snakeyaml" + ], + "io.kubernetes:client-java-api": [ + "com.fasterxml.jackson.core:jackson-databind", + "com.google.code.findbugs:jsr305", + "com.google.code.gson:gson", + "com.squareup.okhttp3:logging-interceptor", + "com.squareup.okhttp3:okhttp", + "io.gsonfire:gson-fire", + "io.swagger:swagger-annotations", + "jakarta.annotation:jakarta.annotation-api", + "javax.annotation:javax.annotation-api", + "org.apache.commons:commons-lang3" + ], + "io.kubernetes:client-java-api-fluent": [ + "io.kubernetes:client-java-api" + ], + "io.kubernetes:client-java-extended": [ + "com.bucket4j:bucket4j-core", + "com.github.ben-manes.caffeine:caffeine", + "io.kubernetes:client-java", + "io.kubernetes:client-java-api", + "io.kubernetes:client-java-api-fluent", + "io.kubernetes:client-java-proto", + "org.apache.commons:commons-lang3" + ], + "io.kubernetes:client-java-proto": [ + "com.google.protobuf:protobuf-java" + ], + "io.micrometer:context-propagation": [ + "org.jspecify:jspecify" + ], + "io.micrometer:micrometer-commons": [ + "org.jspecify:jspecify" + ], + "io.micrometer:micrometer-core": [ + "io.micrometer:micrometer-commons", + "io.micrometer:micrometer-observation", + "org.hdrhistogram:HdrHistogram", + "org.jspecify:jspecify", + "org.latencyutils:LatencyUtils" + ], + "io.micrometer:micrometer-jakarta9": [ + "io.micrometer:micrometer-commons", + "io.micrometer:micrometer-core", + "io.micrometer:micrometer-observation", + "org.jspecify:jspecify" + ], + "io.micrometer:micrometer-observation": [ + "io.micrometer:micrometer-commons", + "org.jspecify:jspecify" + ], + "io.micrometer:micrometer-observation-test": [ + "io.micrometer:micrometer-observation", + "org.assertj:assertj-core", + "org.jspecify:jspecify", + "org.junit.jupiter:junit-jupiter", + "org.mockito:mockito-core" + ], + "io.micrometer:micrometer-registry-prometheus": [ + "io.micrometer:micrometer-core", + "io.prometheus:prometheus-metrics-core", + "io.prometheus:prometheus-metrics-exposition-formats", + "io.prometheus:prometheus-metrics-tracer-common", + "org.jspecify:jspecify" + ], + "io.micrometer:micrometer-tracing": [ + "aopalliance:aopalliance", + "io.micrometer:context-propagation", + "io.micrometer:micrometer-observation", + "org.jspecify:jspecify" + ], + "io.micrometer:micrometer-tracing-bridge-otel": [ + "io.micrometer:micrometer-observation", + "io.micrometer:micrometer-tracing", + "io.opentelemetry.semconv:opentelemetry-semconv", + "io.opentelemetry:opentelemetry-api", + "io.opentelemetry:opentelemetry-extension-trace-propagators", + "io.opentelemetry:opentelemetry-sdk", + "io.opentelemetry:opentelemetry-sdk-common", + "io.opentelemetry:opentelemetry-sdk-trace", + "org.jspecify:jspecify", + "org.slf4j:slf4j-api" + ], + "io.nats:jnats": [ + "org.bouncycastle:bcprov-lts8on", + "org.jspecify:jspecify" + ], + "io.netty:netty-buffer": [ + "io.netty:netty-common" + ], + "io.netty:netty-codec-base": [ + "io.netty:netty-buffer", + "io.netty:netty-common", + "io.netty:netty-transport" + ], + "io.netty:netty-codec-compression": [ + "io.netty:netty-buffer", + "io.netty:netty-codec-base", + "io.netty:netty-common", + "io.netty:netty-transport" + ], + "io.netty:netty-codec-dns": [ + "io.netty:netty-buffer", + "io.netty:netty-codec-base", + "io.netty:netty-common", + "io.netty:netty-transport" + ], + "io.netty:netty-codec-http": [ + "io.netty:netty-buffer", + "io.netty:netty-codec-base", + "io.netty:netty-codec-compression", + "io.netty:netty-common", + "io.netty:netty-handler", + "io.netty:netty-transport" + ], + "io.netty:netty-codec-http2": [ + "io.netty:netty-buffer", + "io.netty:netty-codec-base", + "io.netty:netty-codec-http", + "io.netty:netty-common", + "io.netty:netty-handler", + "io.netty:netty-transport" + ], + "io.netty:netty-codec-http3": [ + "io.netty:netty-buffer", + "io.netty:netty-codec-base", + "io.netty:netty-codec-classes-quic", + "io.netty:netty-codec-compression", + "io.netty:netty-codec-http", + "io.netty:netty-codec-native-quic:jar:linux-aarch_64", + "io.netty:netty-codec-native-quic:jar:linux-x86_64", + "io.netty:netty-codec-native-quic:jar:osx-aarch_64", + "io.netty:netty-codec-native-quic:jar:osx-x86_64", + "io.netty:netty-codec-native-quic:jar:windows-x86_64", + "io.netty:netty-common", + "io.netty:netty-handler", + "io.netty:netty-resolver", + "io.netty:netty-transport", + "io.netty:netty-transport-native-unix-common" + ], + "io.netty:netty-codec-native-quic:jar:linux-aarch_64": [ + "io.netty:netty-codec-classes-quic" + ], + "io.netty:netty-codec-native-quic:jar:linux-x86_64": [ + "io.netty:netty-codec-classes-quic" + ], + "io.netty:netty-codec-native-quic:jar:osx-aarch_64": [ + "io.netty:netty-codec-classes-quic" + ], + "io.netty:netty-codec-native-quic:jar:osx-x86_64": [ + "io.netty:netty-codec-classes-quic" + ], + "io.netty:netty-codec-native-quic:jar:windows-x86_64": [ + "io.netty:netty-codec-classes-quic" + ], + "io.netty:netty-codec-socks": [ + "io.netty:netty-buffer", + "io.netty:netty-codec-base", + "io.netty:netty-common", + "io.netty:netty-transport" + ], + "io.netty:netty-handler": [ + "io.netty:netty-buffer", + "io.netty:netty-codec-base", + "io.netty:netty-common", + "io.netty:netty-resolver", + "io.netty:netty-transport", + "io.netty:netty-transport-native-unix-common" + ], + "io.netty:netty-handler-proxy": [ + "io.netty:netty-buffer", + "io.netty:netty-codec-base", + "io.netty:netty-codec-http", + "io.netty:netty-codec-socks", + "io.netty:netty-common", + "io.netty:netty-handler", + "io.netty:netty-transport" + ], + "io.netty:netty-resolver": [ + "io.netty:netty-common" + ], + "io.netty:netty-resolver-dns": [ + "io.netty:netty-buffer", + "io.netty:netty-codec-base", + "io.netty:netty-codec-dns", + "io.netty:netty-common", + "io.netty:netty-handler", + "io.netty:netty-resolver", + "io.netty:netty-transport" + ], + "io.netty:netty-resolver-dns-classes-macos": [ + "io.netty:netty-common", + "io.netty:netty-resolver-dns", + "io.netty:netty-transport-native-unix-common" + ], + "io.netty:netty-resolver-dns-native-macos:jar:osx-x86_64": [ + "io.netty:netty-resolver-dns-classes-macos" + ], + "io.netty:netty-transport": [ + "io.netty:netty-buffer", + "io.netty:netty-common", + "io.netty:netty-resolver" + ], + "io.netty:netty-transport-classes-epoll": [ + "io.netty:netty-buffer", + "io.netty:netty-common", + "io.netty:netty-transport", + "io.netty:netty-transport-native-unix-common" + ], + "io.netty:netty-transport-native-epoll:jar:linux-x86_64": [ + "io.netty:netty-buffer", + "io.netty:netty-common", + "io.netty:netty-transport", + "io.netty:netty-transport-classes-epoll", + "io.netty:netty-transport-native-unix-common" + ], + "io.netty:netty-transport-native-unix-common": [ + "io.netty:netty-buffer", + "io.netty:netty-common", + "io.netty:netty-transport" + ], + "io.opentelemetry:opentelemetry-api": [ + "io.opentelemetry:opentelemetry-context" + ], + "io.opentelemetry:opentelemetry-context": [ + "io.opentelemetry:opentelemetry-common" + ], + "io.opentelemetry:opentelemetry-exporter-common": [ + "io.opentelemetry:opentelemetry-api", + "io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi" + ], + "io.opentelemetry:opentelemetry-exporter-otlp": [ + "io.opentelemetry:opentelemetry-exporter-otlp-common", + "io.opentelemetry:opentelemetry-exporter-sender-okhttp", + "io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi", + "io.opentelemetry:opentelemetry-sdk-logs", + "io.opentelemetry:opentelemetry-sdk-metrics", + "io.opentelemetry:opentelemetry-sdk-trace" + ], + "io.opentelemetry:opentelemetry-exporter-otlp-common": [ + "io.opentelemetry:opentelemetry-exporter-common" + ], + "io.opentelemetry:opentelemetry-exporter-sender-okhttp": [ + "com.squareup.okhttp3:okhttp-jvm", + "io.opentelemetry:opentelemetry-exporter-common", + "io.opentelemetry:opentelemetry-sdk-common" + ], + "io.opentelemetry:opentelemetry-extension-trace-propagators": [ + "io.opentelemetry:opentelemetry-api" + ], + "io.opentelemetry:opentelemetry-sdk": [ + "io.opentelemetry:opentelemetry-api", + "io.opentelemetry:opentelemetry-sdk-common", + "io.opentelemetry:opentelemetry-sdk-logs", + "io.opentelemetry:opentelemetry-sdk-metrics", + "io.opentelemetry:opentelemetry-sdk-trace" + ], + "io.opentelemetry:opentelemetry-sdk-common": [ + "io.opentelemetry:opentelemetry-api" + ], + "io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi": [ + "io.opentelemetry:opentelemetry-sdk" + ], + "io.opentelemetry:opentelemetry-sdk-logs": [ + "io.opentelemetry:opentelemetry-api", + "io.opentelemetry:opentelemetry-sdk-common" + ], + "io.opentelemetry:opentelemetry-sdk-metrics": [ + "io.opentelemetry:opentelemetry-api", + "io.opentelemetry:opentelemetry-sdk-common" + ], + "io.opentelemetry:opentelemetry-sdk-testing": [ + "io.opentelemetry:opentelemetry-api", + "io.opentelemetry:opentelemetry-sdk" + ], + "io.opentelemetry:opentelemetry-sdk-trace": [ + "io.opentelemetry:opentelemetry-api", + "io.opentelemetry:opentelemetry-sdk-common" + ], + "io.projectreactor.netty:reactor-netty-core": [ + "io.netty:netty-handler", + "io.netty:netty-handler-proxy", + "io.netty:netty-resolver-dns", + "io.netty:netty-resolver-dns-native-macos:jar:osx-x86_64", + "io.netty:netty-transport-native-epoll:jar:linux-x86_64", + "io.projectreactor:reactor-core", + "org.jspecify:jspecify" + ], + "io.projectreactor.netty:reactor-netty-http": [ + "io.netty:netty-codec-http", + "io.netty:netty-codec-http2", + "io.netty:netty-codec-http3", + "io.netty:netty-resolver-dns", + "io.netty:netty-resolver-dns-native-macos:jar:osx-x86_64", + "io.netty:netty-transport-native-epoll:jar:linux-x86_64", + "io.projectreactor.netty:reactor-netty-core", + "io.projectreactor:reactor-core", + "org.jspecify:jspecify" + ], + "io.projectreactor:reactor-core": [ + "org.jspecify:jspecify", + "org.reactivestreams:reactive-streams" + ], + "io.projectreactor:reactor-test": [ + "io.projectreactor:reactor-core", + "org.jspecify:jspecify" + ], + "io.prometheus:prometheus-metrics-core": [ + "io.prometheus:prometheus-metrics-config", + "io.prometheus:prometheus-metrics-model" + ], + "io.prometheus:prometheus-metrics-exposition-formats": [ + "io.prometheus:prometheus-metrics-exposition-textformats" + ], + "io.prometheus:prometheus-metrics-exposition-textformats": [ + "io.prometheus:prometheus-metrics-config", + "io.prometheus:prometheus-metrics-model" + ], + "io.prometheus:prometheus-metrics-model": [ + "io.prometheus:prometheus-metrics-config" + ], + "io.swagger.core.v3:swagger-core-jakarta": [ + "com.fasterxml.jackson.core:jackson-annotations", + "com.fasterxml.jackson.core:jackson-databind", + "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml", + "com.fasterxml.jackson.datatype:jackson-datatype-jsr310", + "io.swagger.core.v3:swagger-annotations-jakarta", + "io.swagger.core.v3:swagger-models-jakarta", + "jakarta.validation:jakarta.validation-api", + "jakarta.xml.bind:jakarta.xml.bind-api", + "org.apache.commons:commons-lang3", + "org.slf4j:slf4j-api", + "org.yaml:snakeyaml" + ], + "io.swagger.core.v3:swagger-models-jakarta": [ + "com.fasterxml.jackson.core:jackson-annotations" + ], + "jakarta.xml.bind:jakarta.xml.bind-api": [ + "jakarta.activation:jakarta.activation-api" + ], + "net.devh:grpc-common-spring-boot": [ + "io.grpc:grpc-core", + "org.springframework.boot:spring-boot-starter" + ], + "net.devh:grpc-server-spring-boot-starter": [ + "io.grpc:grpc-api", + "io.grpc:grpc-inprocess", + "io.grpc:grpc-netty-shaded", + "io.grpc:grpc-protobuf", + "io.grpc:grpc-services", + "io.grpc:grpc-stub", + "net.devh:grpc-common-spring-boot", + "org.springframework.boot:spring-boot-starter" + ], + "net.javacrumbs.shedlock:shedlock-core": [ + "org.slf4j:slf4j-api" + ], + "net.javacrumbs.shedlock:shedlock-provider-cassandra": [ + "net.javacrumbs.shedlock:shedlock-core", + "org.apache.cassandra:java-driver-core", + "org.apache.cassandra:java-driver-query-builder" + ], + "net.javacrumbs.shedlock:shedlock-spring": [ + "net.javacrumbs.shedlock:shedlock-core", + "org.springframework:spring-context" + ], + "net.minidev:accessors-smart": [ + "org.ow2.asm:asm" + ], + "net.minidev:json-smart": [ + "net.minidev:accessors-smart" + ], + "org.apache.cassandra:java-driver-core": [ + "com.datastax.oss:native-protocol", + "com.fasterxml.jackson.core:jackson-core", + "com.fasterxml.jackson.core:jackson-databind", + "com.github.jnr:jnr-posix", + "com.typesafe:config", + "io.netty:netty-handler", + "org.apache.cassandra:java-driver-guava-shaded", + "org.reactivestreams:reactive-streams", + "org.slf4j:slf4j-api" + ], + "org.apache.cassandra:java-driver-metrics-micrometer": [ + "io.micrometer:micrometer-core", + "org.apache.cassandra:java-driver-core" + ], + "org.apache.cassandra:java-driver-query-builder": [ + "org.apache.cassandra:java-driver-core", + "org.apache.cassandra:java-driver-guava-shaded" + ], + "org.apache.commons:commons-compress": [ + "commons-codec:commons-codec", + "commons-io:commons-io", + "org.apache.commons:commons-lang3" + ], + "org.apache.logging.log4j:log4j-to-slf4j": [ + "org.apache.logging.log4j:log4j-api", + "org.slf4j:slf4j-api" + ], + "org.apache.tomcat.embed:tomcat-embed-websocket": [ + "org.apache.tomcat.embed:tomcat-embed-core" + ], + "org.assertj:assertj-core": [ + "net.bytebuddy:byte-buddy" + ], + "org.awaitility:awaitility": [ + "org.hamcrest:hamcrest" + ], + "org.bitbucket.b_c:jose4j": [ + "org.slf4j:slf4j-api" + ], + "org.bouncycastle:bcpkix-jdk18on": [ + "org.bouncycastle:bcutil-jdk18on" + ], + "org.bouncycastle:bcutil-jdk18on": [ + "org.bouncycastle:bcprov-jdk18on" + ], + "org.hibernate.validator:hibernate-validator": [ + "com.fasterxml:classmate", + "jakarta.validation:jakarta.validation-api", + "org.jboss.logging:jboss-logging" + ], + "org.jacoco:org.jacoco.cli": [ + "args4j:args4j", + "org.jacoco:org.jacoco.core", + "org.jacoco:org.jacoco.report" + ], + "org.jacoco:org.jacoco.core": [ + "org.ow2.asm:asm", + "org.ow2.asm:asm-commons", + "org.ow2.asm:asm-tree" + ], + "org.jacoco:org.jacoco.report": [ + "org.jacoco:org.jacoco.core" + ], + "org.jetbrains.kotlin:kotlin-stdlib": [ + "org.jetbrains:annotations" + ], + "org.jetbrains.kotlin:kotlin-stdlib-jdk7": [ + "org.jetbrains.kotlin:kotlin-stdlib" + ], + "org.jetbrains.kotlin:kotlin-stdlib-jdk8": [ + "org.jetbrains.kotlin:kotlin-stdlib", + "org.jetbrains.kotlin:kotlin-stdlib-jdk7" + ], + "org.junit.jupiter:junit-jupiter": [ + "org.junit.jupiter:junit-jupiter-api", + "org.junit.jupiter:junit-jupiter-engine", + "org.junit.jupiter:junit-jupiter-params" + ], + "org.junit.jupiter:junit-jupiter-api": [ + "org.apiguardian:apiguardian-api", + "org.jspecify:jspecify", + "org.junit.platform:junit-platform-commons", + "org.opentest4j:opentest4j" + ], + "org.junit.jupiter:junit-jupiter-engine": [ + "org.apiguardian:apiguardian-api", + "org.jspecify:jspecify", + "org.junit.jupiter:junit-jupiter-api", + "org.junit.platform:junit-platform-engine" + ], + "org.junit.jupiter:junit-jupiter-params": [ + "org.apiguardian:apiguardian-api", + "org.jspecify:jspecify", + "org.junit.jupiter:junit-jupiter-api" + ], + "org.junit.platform:junit-platform-commons": [ + "org.apiguardian:apiguardian-api", + "org.jspecify:jspecify" + ], + "org.junit.platform:junit-platform-engine": [ + "org.apiguardian:apiguardian-api", + "org.jspecify:jspecify", + "org.junit.platform:junit-platform-commons", + "org.opentest4j:opentest4j" + ], + "org.junit.platform:junit-platform-launcher": [ + "org.apiguardian:apiguardian-api", + "org.jspecify:jspecify", + "org.junit.platform:junit-platform-engine" + ], + "org.junit.platform:junit-platform-reporting": [ + "org.apiguardian:apiguardian-api", + "org.jspecify:jspecify", + "org.junit.platform:junit-platform-launcher", + "org.opentest4j.reporting:open-test-reporting-tooling-spi" + ], + "org.mockito:mockito-core": [ + "net.bytebuddy:byte-buddy", + "net.bytebuddy:byte-buddy-agent", + "org.objenesis:objenesis" + ], + "org.mockito:mockito-junit-jupiter": [ + "org.junit.jupiter:junit-jupiter-api", + "org.mockito:mockito-core" + ], + "org.opentest4j.reporting:open-test-reporting-tooling-spi": [ + "org.apiguardian:apiguardian-api" + ], + "org.ow2.asm:asm-analysis": [ + "org.ow2.asm:asm-tree" + ], + "org.ow2.asm:asm-commons": [ + "org.ow2.asm:asm", + "org.ow2.asm:asm-tree" + ], + "org.ow2.asm:asm-tree": [ + "org.ow2.asm:asm" + ], + "org.ow2.asm:asm-util": [ + "org.ow2.asm:asm", + "org.ow2.asm:asm-analysis", + "org.ow2.asm:asm-tree" + ], + "org.rnorth.duct-tape:duct-tape": [ + "org.jetbrains:annotations" + ], + "org.skyscreamer:jsonassert": [ + "com.vaadin.external.google:android-json" + ], + "org.slf4j:jul-to-slf4j": [ + "org.slf4j:slf4j-api" + ], + "org.springdoc:springdoc-openapi-starter-common": [ + "io.swagger.core.v3:swagger-core-jakarta", + "org.springframework.boot:spring-boot-autoconfigure", + "org.springframework.boot:spring-boot-jackson", + "org.springframework.boot:spring-boot-starter", + "org.springframework.boot:spring-boot-validation" + ], + "org.springdoc:springdoc-openapi-starter-webflux-api": [ + "org.springdoc:springdoc-openapi-starter-common", + "org.springframework.boot:spring-boot-web-server", + "org.springframework.boot:spring-boot-webflux" + ], + "org.springdoc:springdoc-openapi-starter-webmvc-api": [ + "org.springdoc:springdoc-openapi-starter-common", + "org.springframework.boot:spring-boot-web-server", + "org.springframework.boot:spring-boot-webmvc" + ], + "org.springframework.boot:spring-boot": [ + "org.springframework:spring-context", + "org.springframework:spring-core" + ], + "org.springframework.boot:spring-boot-actuator": [ + "org.springframework.boot:spring-boot" + ], + "org.springframework.boot:spring-boot-actuator-autoconfigure": [ + "org.springframework.boot:spring-boot-actuator", + "org.springframework.boot:spring-boot-autoconfigure" + ], + "org.springframework.boot:spring-boot-autoconfigure": [ + "org.springframework.boot:spring-boot" + ], + "org.springframework.boot:spring-boot-cassandra": [ + "org.apache.cassandra:java-driver-core", + "org.springframework.boot:spring-boot" + ], + "org.springframework.boot:spring-boot-data-cassandra": [ + "org.springframework.boot:spring-boot-cassandra", + "org.springframework.boot:spring-boot-data-commons", + "org.springframework.data:spring-data-cassandra" + ], + "org.springframework.boot:spring-boot-data-cassandra-test": [ + "org.springframework.boot:spring-boot-data-cassandra", + "org.springframework.boot:spring-boot-test-autoconfigure" + ], + "org.springframework.boot:spring-boot-data-commons": [ + "org.springframework.boot:spring-boot", + "org.springframework.boot:spring-boot-persistence", + "org.springframework.data:spring-data-commons" + ], + "org.springframework.boot:spring-boot-health": [ + "org.springframework.boot:spring-boot" + ], + "org.springframework.boot:spring-boot-http-client": [ + "org.springframework.boot:spring-boot", + "org.springframework.boot:spring-boot-http-converter", + "org.springframework:spring-web" + ], + "org.springframework.boot:spring-boot-http-codec": [ + "org.springframework.boot:spring-boot", + "org.springframework:spring-web" + ], + "org.springframework.boot:spring-boot-http-converter": [ + "org.springframework.boot:spring-boot", + "org.springframework:spring-web" + ], + "org.springframework.boot:spring-boot-jackson": [ + "org.springframework.boot:spring-boot", + "tools.jackson.core:jackson-databind" + ], + "org.springframework.boot:spring-boot-micrometer-metrics": [ + "io.micrometer:micrometer-core", + "org.springframework.boot:spring-boot", + "org.springframework.boot:spring-boot-micrometer-observation" + ], + "org.springframework.boot:spring-boot-micrometer-metrics-test": [ + "io.micrometer:micrometer-observation-test", + "org.springframework.boot:spring-boot-micrometer-metrics", + "org.springframework.boot:spring-boot-test-autoconfigure" + ], + "org.springframework.boot:spring-boot-micrometer-observation": [ + "io.micrometer:micrometer-observation", + "org.springframework.boot:spring-boot" + ], + "org.springframework.boot:spring-boot-micrometer-tracing": [ + "io.micrometer:micrometer-tracing", + "org.springframework.boot:spring-boot", + "org.springframework.boot:spring-boot-micrometer-observation" + ], + "org.springframework.boot:spring-boot-micrometer-tracing-opentelemetry": [ + "io.micrometer:micrometer-tracing", + "org.springframework.boot:spring-boot", + "org.springframework.boot:spring-boot-micrometer-observation", + "org.springframework.boot:spring-boot-micrometer-tracing", + "org.springframework.boot:spring-boot-opentelemetry" + ], + "org.springframework.boot:spring-boot-netty": [ + "io.netty:netty-common", + "org.springframework.boot:spring-boot" + ], + "org.springframework.boot:spring-boot-opentelemetry": [ + "io.opentelemetry:opentelemetry-api", + "io.opentelemetry:opentelemetry-sdk", + "org.springframework.boot:spring-boot" + ], + "org.springframework.boot:spring-boot-persistence": [ + "org.springframework.boot:spring-boot", + "org.springframework:spring-tx" + ], + "org.springframework.boot:spring-boot-reactor": [ + "io.projectreactor:reactor-core", + "org.springframework.boot:spring-boot" + ], + "org.springframework.boot:spring-boot-reactor-netty": [ + "io.projectreactor.netty:reactor-netty-http", + "org.springframework.boot:spring-boot-netty", + "org.springframework.boot:spring-boot-web-server", + "org.springframework:spring-web" + ], + "org.springframework.boot:spring-boot-restclient": [ + "org.springframework.boot:spring-boot", + "org.springframework.boot:spring-boot-http-client", + "org.springframework.boot:spring-boot-http-converter" + ], + "org.springframework.boot:spring-boot-resttestclient": [ + "org.springframework.boot:spring-boot-http-converter", + "org.springframework.boot:spring-boot-test", + "org.springframework:spring-web" + ], + "org.springframework.boot:spring-boot-security": [ + "org.springframework.boot:spring-boot", + "org.springframework.security:spring-security-config", + "org.springframework.security:spring-security-web" + ], + "org.springframework.boot:spring-boot-security-oauth2-client": [ + "org.springframework.boot:spring-boot", + "org.springframework.boot:spring-boot-security", + "org.springframework.security:spring-security-oauth2-client" + ], + "org.springframework.boot:spring-boot-security-oauth2-resource-server": [ + "org.springframework.boot:spring-boot", + "org.springframework.boot:spring-boot-security", + "org.springframework.security:spring-security-oauth2-jose", + "org.springframework.security:spring-security-oauth2-resource-server" + ], + "org.springframework.boot:spring-boot-security-test": [ + "org.springframework.boot:spring-boot-security", + "org.springframework.boot:spring-boot-test-autoconfigure", + "org.springframework.security:spring-security-test" + ], + "org.springframework.boot:spring-boot-servlet": [ + "org.springframework.boot:spring-boot", + "org.springframework:spring-web" + ], + "org.springframework.boot:spring-boot-starter": [ + "jakarta.annotation:jakarta.annotation-api", + "org.springframework.boot:spring-boot-autoconfigure", + "org.springframework.boot:spring-boot-starter-logging", + "org.yaml:snakeyaml" + ], + "org.springframework.boot:spring-boot-starter-actuator": [ + "io.micrometer:micrometer-jakarta9", + "io.micrometer:micrometer-observation", + "org.springframework.boot:spring-boot-actuator-autoconfigure", + "org.springframework.boot:spring-boot-health", + "org.springframework.boot:spring-boot-starter", + "org.springframework.boot:spring-boot-starter-micrometer-metrics" + ], + "org.springframework.boot:spring-boot-starter-actuator-test": [ + "org.springframework.boot:spring-boot-starter-actuator", + "org.springframework.boot:spring-boot-starter-micrometer-metrics-test", + "org.springframework.boot:spring-boot-starter-test" + ], + "org.springframework.boot:spring-boot-starter-aspectj": [ + "org.aspectj:aspectjweaver", + "org.springframework.boot:spring-boot-starter", + "org.springframework:spring-aop" + ], + "org.springframework.boot:spring-boot-starter-data-cassandra": [ + "org.springframework.boot:spring-boot-cassandra", + "org.springframework.boot:spring-boot-data-cassandra", + "org.springframework.boot:spring-boot-starter" + ], + "org.springframework.boot:spring-boot-starter-data-cassandra-test": [ + "org.springframework.boot:spring-boot-data-cassandra-test", + "org.springframework.boot:spring-boot-starter-data-cassandra", + "org.springframework.boot:spring-boot-starter-test" + ], + "org.springframework.boot:spring-boot-starter-jackson": [ + "org.springframework.boot:spring-boot-jackson", + "org.springframework.boot:spring-boot-starter" + ], + "org.springframework.boot:spring-boot-starter-jackson-test": [ + "org.springframework.boot:spring-boot-starter-jackson", + "org.springframework.boot:spring-boot-starter-test" + ], + "org.springframework.boot:spring-boot-starter-logging": [ + "ch.qos.logback:logback-classic", + "org.apache.logging.log4j:log4j-to-slf4j", + "org.slf4j:jul-to-slf4j" + ], + "org.springframework.boot:spring-boot-starter-micrometer-metrics": [ + "org.springframework.boot:spring-boot-micrometer-metrics", + "org.springframework.boot:spring-boot-starter" + ], + "org.springframework.boot:spring-boot-starter-micrometer-metrics-test": [ + "org.springframework.boot:spring-boot-micrometer-metrics-test", + "org.springframework.boot:spring-boot-starter-micrometer-metrics", + "org.springframework.boot:spring-boot-starter-test" + ], + "org.springframework.boot:spring-boot-starter-reactor-netty": [ + "org.springframework.boot:spring-boot-reactor", + "org.springframework.boot:spring-boot-reactor-netty", + "org.springframework.boot:spring-boot-starter" + ], + "org.springframework.boot:spring-boot-starter-security": [ + "org.springframework.boot:spring-boot-security", + "org.springframework.boot:spring-boot-starter", + "org.springframework:spring-aop" + ], + "org.springframework.boot:spring-boot-starter-security-oauth2-client": [ + "org.springframework.boot:spring-boot-security-oauth2-client", + "org.springframework.boot:spring-boot-starter", + "org.springframework.boot:spring-boot-starter-security", + "org.springframework.security:spring-security-oauth2-jose" + ], + "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server": [ + "org.springframework.boot:spring-boot-security-oauth2-resource-server", + "org.springframework.boot:spring-boot-starter", + "org.springframework.boot:spring-boot-starter-security" + ], + "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server-test": [ + "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server", + "org.springframework.boot:spring-boot-starter-security-test", + "org.springframework.boot:spring-boot-starter-test" + ], + "org.springframework.boot:spring-boot-starter-security-test": [ + "org.springframework.boot:spring-boot-security-test", + "org.springframework.boot:spring-boot-starter-security", + "org.springframework.boot:spring-boot-starter-test" + ], + "org.springframework.boot:spring-boot-starter-test": [ + "com.jayway.jsonpath:json-path", + "jakarta.xml.bind:jakarta.xml.bind-api", + "net.minidev:json-smart", + "org.assertj:assertj-core", + "org.awaitility:awaitility", + "org.hamcrest:hamcrest", + "org.junit.jupiter:junit-jupiter", + "org.mockito:mockito-core", + "org.mockito:mockito-junit-jupiter", + "org.skyscreamer:jsonassert", + "org.springframework.boot:spring-boot-starter", + "org.springframework.boot:spring-boot-test", + "org.springframework.boot:spring-boot-test-autoconfigure", + "org.springframework:spring-core", + "org.springframework:spring-test", + "org.xmlunit:xmlunit-core" + ], + "org.springframework.boot:spring-boot-starter-tomcat": [ + "org.springframework.boot:spring-boot-starter", + "org.springframework.boot:spring-boot-starter-tomcat-runtime", + "org.springframework.boot:spring-boot-tomcat" + ], + "org.springframework.boot:spring-boot-starter-tomcat-runtime": [ + "jakarta.annotation:jakarta.annotation-api", + "org.apache.tomcat.embed:tomcat-embed-core", + "org.apache.tomcat.embed:tomcat-embed-el", + "org.apache.tomcat.embed:tomcat-embed-websocket", + "org.springframework.boot:spring-boot-tomcat", + "org.springframework.boot:spring-boot-web-server" + ], + "org.springframework.boot:spring-boot-starter-validation": [ + "org.springframework.boot:spring-boot-starter", + "org.springframework.boot:spring-boot-validation" + ], + "org.springframework.boot:spring-boot-starter-web": [ + "org.springframework.boot:spring-boot-http-converter", + "org.springframework.boot:spring-boot-starter-jackson", + "org.springframework.boot:spring-boot-starter-tomcat", + "org.springframework.boot:spring-boot-webmvc" + ], + "org.springframework.boot:spring-boot-starter-webflux": [ + "org.springframework.boot:spring-boot-reactor", + "org.springframework.boot:spring-boot-starter", + "org.springframework.boot:spring-boot-starter-jackson", + "org.springframework.boot:spring-boot-starter-reactor-netty", + "org.springframework.boot:spring-boot-webflux" + ], + "org.springframework.boot:spring-boot-starter-webflux-test": [ + "io.projectreactor:reactor-test", + "org.springframework.boot:spring-boot-starter-jackson-test", + "org.springframework.boot:spring-boot-starter-test", + "org.springframework.boot:spring-boot-starter-webflux", + "org.springframework.boot:spring-boot-webflux-test", + "org.springframework.boot:spring-boot-webtestclient" + ], + "org.springframework.boot:spring-boot-starter-webmvc": [ + "org.springframework.boot:spring-boot-http-converter", + "org.springframework.boot:spring-boot-starter", + "org.springframework.boot:spring-boot-starter-jackson", + "org.springframework.boot:spring-boot-starter-tomcat", + "org.springframework.boot:spring-boot-webmvc" + ], + "org.springframework.boot:spring-boot-starter-webmvc-test": [ + "org.springframework.boot:spring-boot-resttestclient", + "org.springframework.boot:spring-boot-starter-jackson-test", + "org.springframework.boot:spring-boot-starter-test", + "org.springframework.boot:spring-boot-starter-webmvc", + "org.springframework.boot:spring-boot-webmvc-test" + ], + "org.springframework.boot:spring-boot-test": [ + "org.springframework.boot:spring-boot", + "org.springframework:spring-test" + ], + "org.springframework.boot:spring-boot-test-autoconfigure": [ + "org.springframework.boot:spring-boot-test" + ], + "org.springframework.boot:spring-boot-tomcat": [ + "jakarta.annotation:jakarta.annotation-api", + "org.apache.tomcat.embed:tomcat-embed-core", + "org.springframework.boot:spring-boot-web-server" + ], + "org.springframework.boot:spring-boot-validation": [ + "org.apache.tomcat.embed:tomcat-embed-el", + "org.hibernate.validator:hibernate-validator", + "org.springframework.boot:spring-boot" + ], + "org.springframework.boot:spring-boot-web-server": [ + "org.springframework.boot:spring-boot", + "org.springframework:spring-web" + ], + "org.springframework.boot:spring-boot-webclient": [ + "org.springframework.boot:spring-boot", + "org.springframework.boot:spring-boot-http-client", + "org.springframework.boot:spring-boot-http-codec", + "org.springframework:spring-webflux" + ], + "org.springframework.boot:spring-boot-webflux": [ + "org.springframework.boot:spring-boot", + "org.springframework.boot:spring-boot-http-codec", + "org.springframework.boot:spring-boot-web-server", + "org.springframework:spring-webflux" + ], + "org.springframework.boot:spring-boot-webflux-test": [ + "org.springframework.boot:spring-boot-test-autoconfigure", + "org.springframework.boot:spring-boot-webflux", + "org.springframework.boot:spring-boot-webtestclient" + ], + "org.springframework.boot:spring-boot-webmvc": [ + "org.springframework.boot:spring-boot-http-converter", + "org.springframework.boot:spring-boot-servlet", + "org.springframework:spring-web", + "org.springframework:spring-webmvc" + ], + "org.springframework.boot:spring-boot-webmvc-test": [ + "org.springframework.boot:spring-boot-http-converter", + "org.springframework.boot:spring-boot-test-autoconfigure", + "org.springframework.boot:spring-boot-web-server", + "org.springframework.boot:spring-boot-webmvc" + ], + "org.springframework.boot:spring-boot-webtestclient": [ + "org.springframework.boot:spring-boot-http-codec", + "org.springframework.boot:spring-boot-test", + "org.springframework:spring-webflux" + ], + "org.springframework.cloud:spring-cloud-commons": [ + "org.springframework.security:spring-security-crypto" + ], + "org.springframework.cloud:spring-cloud-context": [ + "org.springframework.security:spring-security-crypto" + ], + "org.springframework.cloud:spring-cloud-kubernetes-client-autoconfig": [ + "io.kubernetes:client-java", + "io.kubernetes:client-java-extended", + "org.springframework.boot:spring-boot-autoconfigure", + "org.springframework.cloud:spring-cloud-kubernetes-commons" + ], + "org.springframework.cloud:spring-cloud-kubernetes-client-config": [ + "io.kubernetes:client-java", + "io.kubernetes:client-java-extended", + "org.springframework.boot:spring-boot-autoconfigure", + "org.springframework.cloud:spring-cloud-kubernetes-client-autoconfig", + "org.springframework.cloud:spring-cloud-kubernetes-commons", + "org.springframework.cloud:spring-cloud-starter" + ], + "org.springframework.cloud:spring-cloud-kubernetes-commons": [ + "jakarta.annotation:jakarta.annotation-api", + "org.springframework.boot:spring-boot-autoconfigure", + "org.springframework.cloud:spring-cloud-commons", + "org.springframework.cloud:spring-cloud-context" + ], + "org.springframework.cloud:spring-cloud-starter": [ + "org.bouncycastle:bcprov-jdk18on", + "org.springframework.boot:spring-boot-starter", + "org.springframework.cloud:spring-cloud-commons", + "org.springframework.cloud:spring-cloud-context" + ], + "org.springframework.cloud:spring-cloud-starter-bootstrap": [ + "org.springframework.cloud:spring-cloud-starter" + ], + "org.springframework.cloud:spring-cloud-starter-kubernetes-client-config": [ + "org.springframework.cloud:spring-cloud-kubernetes-client-config" + ], + "org.springframework.data:spring-data-cassandra": [ + "org.apache.cassandra:java-driver-core", + "org.apache.cassandra:java-driver-query-builder", + "org.slf4j:slf4j-api", + "org.springframework.data:spring-data-commons", + "org.springframework:spring-beans", + "org.springframework:spring-context", + "org.springframework:spring-core", + "org.springframework:spring-expression", + "org.springframework:spring-tx" + ], + "org.springframework.data:spring-data-commons": [ + "org.slf4j:slf4j-api", + "org.springframework:spring-beans", + "org.springframework:spring-core" + ], + "org.springframework.security:spring-security-config": [ + "org.springframework.security:spring-security-core", + "org.springframework:spring-aop", + "org.springframework:spring-beans", + "org.springframework:spring-context", + "org.springframework:spring-core" + ], + "org.springframework.security:spring-security-core": [ + "io.micrometer:micrometer-observation", + "org.springframework.security:spring-security-crypto", + "org.springframework:spring-aop", + "org.springframework:spring-beans", + "org.springframework:spring-context", + "org.springframework:spring-core", + "org.springframework:spring-expression" + ], + "org.springframework.security:spring-security-oauth2-client": [ + "com.nimbusds:oauth2-oidc-sdk", + "org.springframework.security:spring-security-core", + "org.springframework.security:spring-security-oauth2-core", + "org.springframework.security:spring-security-web", + "org.springframework:spring-core" + ], + "org.springframework.security:spring-security-oauth2-core": [ + "org.springframework.security:spring-security-core", + "org.springframework:spring-core", + "org.springframework:spring-web" + ], + "org.springframework.security:spring-security-oauth2-jose": [ + "com.nimbusds:nimbus-jose-jwt", + "org.springframework.security:spring-security-core", + "org.springframework.security:spring-security-oauth2-core", + "org.springframework:spring-core" + ], + "org.springframework.security:spring-security-oauth2-resource-server": [ + "org.springframework.security:spring-security-core", + "org.springframework.security:spring-security-oauth2-core", + "org.springframework.security:spring-security-web", + "org.springframework:spring-core" + ], + "org.springframework.security:spring-security-test": [ + "org.springframework.security:spring-security-core", + "org.springframework.security:spring-security-web", + "org.springframework:spring-core", + "org.springframework:spring-test" + ], + "org.springframework.security:spring-security-web": [ + "org.springframework.security:spring-security-core", + "org.springframework:spring-aop", + "org.springframework:spring-beans", + "org.springframework:spring-context", + "org.springframework:spring-core", + "org.springframework:spring-expression", + "org.springframework:spring-web" + ], + "org.springframework:spring-aop": [ + "org.springframework:spring-beans", + "org.springframework:spring-core" + ], + "org.springframework:spring-beans": [ + "org.springframework:spring-core" + ], + "org.springframework:spring-context": [ + "io.micrometer:micrometer-observation", + "org.springframework:spring-aop", + "org.springframework:spring-beans", + "org.springframework:spring-core", + "org.springframework:spring-expression" + ], + "org.springframework:spring-context-support": [ + "org.springframework:spring-beans", + "org.springframework:spring-context", + "org.springframework:spring-core" + ], + "org.springframework:spring-core": [ + "commons-logging:commons-logging", + "org.jspecify:jspecify" + ], + "org.springframework:spring-expression": [ + "org.springframework:spring-core" + ], + "org.springframework:spring-test": [ + "org.springframework:spring-core" + ], + "org.springframework:spring-tx": [ + "org.springframework:spring-beans", + "org.springframework:spring-core" + ], + "org.springframework:spring-web": [ + "io.micrometer:micrometer-observation", + "org.springframework:spring-beans", + "org.springframework:spring-core" + ], + "org.springframework:spring-webflux": [ + "io.projectreactor:reactor-core", + "org.springframework:spring-beans", + "org.springframework:spring-core", + "org.springframework:spring-web" + ], + "org.springframework:spring-webmvc": [ + "org.springframework:spring-aop", + "org.springframework:spring-beans", + "org.springframework:spring-context", + "org.springframework:spring-core", + "org.springframework:spring-expression", + "org.springframework:spring-web" + ], + "org.testcontainers:testcontainers": [ + "com.github.docker-java:docker-java-api", + "com.github.docker-java:docker-java-transport-zerodep", + "org.apache.commons:commons-compress", + "org.rnorth.duct-tape:duct-tape", + "org.slf4j:slf4j-api" + ], + "org.testcontainers:testcontainers-cassandra": [ + "com.datastax.cassandra:cassandra-driver-core", + "org.testcontainers:testcontainers-database-commons" + ], + "org.testcontainers:testcontainers-database-commons": [ + "org.testcontainers:testcontainers" + ], + "org.testcontainers:testcontainers-junit-jupiter": [ + "org.testcontainers:testcontainers" + ], + "org.testcontainers:testcontainers-localstack": [ + "org.testcontainers:testcontainers" + ], + "org.xmlunit:xmlunit-core": [ + "jakarta.xml.bind:jakarta.xml.bind-api" + ], + "software.amazon.awssdk:checksums": [ + "software.amazon.awssdk:annotations", + "software.amazon.awssdk:checksums-spi", + "software.amazon.awssdk:utils" + ], + "software.amazon.awssdk:checksums-spi": [ + "software.amazon.awssdk:annotations" + ], + "software.amazon.awssdk:endpoints-spi": [ + "software.amazon.awssdk:annotations" + ], + "software.amazon.awssdk:http-auth-aws": [ + "software.amazon.awssdk:annotations", + "software.amazon.awssdk:checksums", + "software.amazon.awssdk:checksums-spi", + "software.amazon.awssdk:http-auth-spi", + "software.amazon.awssdk:http-client-spi", + "software.amazon.awssdk:identity-spi", + "software.amazon.awssdk:utils" + ], + "software.amazon.awssdk:http-auth-spi": [ + "org.reactivestreams:reactive-streams", + "software.amazon.awssdk:annotations", + "software.amazon.awssdk:checksums-spi", + "software.amazon.awssdk:http-client-spi", + "software.amazon.awssdk:identity-spi", + "software.amazon.awssdk:utils" + ], + "software.amazon.awssdk:http-client-spi": [ + "org.reactivestreams:reactive-streams", + "software.amazon.awssdk:annotations", + "software.amazon.awssdk:metrics-spi", + "software.amazon.awssdk:utils" + ], + "software.amazon.awssdk:identity-spi": [ + "software.amazon.awssdk:annotations", + "software.amazon.awssdk:utils" + ], + "software.amazon.awssdk:json-utils": [ + "software.amazon.awssdk:annotations", + "software.amazon.awssdk:third-party-jackson-core", + "software.amazon.awssdk:utils" + ], + "software.amazon.awssdk:metrics-spi": [ + "software.amazon.awssdk:annotations", + "software.amazon.awssdk:utils" + ], + "software.amazon.awssdk:profiles": [ + "software.amazon.awssdk:annotations", + "software.amazon.awssdk:utils" + ], + "software.amazon.awssdk:regions": [ + "org.slf4j:slf4j-api", + "software.amazon.awssdk:annotations", + "software.amazon.awssdk:json-utils", + "software.amazon.awssdk:profiles", + "software.amazon.awssdk:sdk-core", + "software.amazon.awssdk:utils" + ], + "software.amazon.awssdk:retries": [ + "software.amazon.awssdk:annotations", + "software.amazon.awssdk:retries-spi", + "software.amazon.awssdk:utils" + ], + "software.amazon.awssdk:retries-spi": [ + "software.amazon.awssdk:annotations", + "software.amazon.awssdk:utils" + ], + "software.amazon.awssdk:sdk-core": [ + "org.reactivestreams:reactive-streams", + "org.slf4j:slf4j-api", + "software.amazon.awssdk:annotations", + "software.amazon.awssdk:checksums", + "software.amazon.awssdk:checksums-spi", + "software.amazon.awssdk:endpoints-spi", + "software.amazon.awssdk:http-auth-aws", + "software.amazon.awssdk:http-auth-spi", + "software.amazon.awssdk:http-client-spi", + "software.amazon.awssdk:identity-spi", + "software.amazon.awssdk:metrics-spi", + "software.amazon.awssdk:profiles", + "software.amazon.awssdk:retries", + "software.amazon.awssdk:retries-spi", + "software.amazon.awssdk:utils" + ], + "software.amazon.awssdk:utils": [ + "org.reactivestreams:reactive-streams", + "org.slf4j:slf4j-api", + "software.amazon.awssdk:annotations" + ], + "tools.jackson.core:jackson-databind": [ + "com.fasterxml.jackson.core:jackson-annotations", + "tools.jackson.core:jackson-core" + ], + "tools.jackson.module:jackson-module-blackbird": [ + "tools.jackson.core:jackson-core", + "tools.jackson.core:jackson-databind" + ] + }, + "packages": { + "aopalliance:aopalliance": [ + "org.aopalliance.aop", + "org.aopalliance.intercept" + ], + "args4j:args4j": [ + "org.kohsuke.args4j", + "org.kohsuke.args4j.spi" + ], + "at.yawk.lz4:lz4-java": [ + "net.jpountz.lz4", + "net.jpountz.util", + "net.jpountz.xxhash" + ], + "ch.qos.logback:logback-classic": [ + "ch.qos.logback.classic", + "ch.qos.logback.classic.boolex", + "ch.qos.logback.classic.encoder", + "ch.qos.logback.classic.filter", + "ch.qos.logback.classic.helpers", + "ch.qos.logback.classic.html", + "ch.qos.logback.classic.joran", + "ch.qos.logback.classic.joran.action", + "ch.qos.logback.classic.joran.sanity", + "ch.qos.logback.classic.joran.serializedModel", + "ch.qos.logback.classic.jul", + "ch.qos.logback.classic.layout", + "ch.qos.logback.classic.log4j", + "ch.qos.logback.classic.model", + "ch.qos.logback.classic.model.processor", + "ch.qos.logback.classic.model.util", + "ch.qos.logback.classic.net", + "ch.qos.logback.classic.net.server", + "ch.qos.logback.classic.pattern", + "ch.qos.logback.classic.pattern.color", + "ch.qos.logback.classic.selector", + "ch.qos.logback.classic.selector.servlet", + "ch.qos.logback.classic.servlet", + "ch.qos.logback.classic.sift", + "ch.qos.logback.classic.spi", + "ch.qos.logback.classic.turbo", + "ch.qos.logback.classic.tyler", + "ch.qos.logback.classic.util" + ], + "ch.qos.logback:logback-core": [ + "ch.qos.logback.core", + "ch.qos.logback.core.boolex", + "ch.qos.logback.core.encoder", + "ch.qos.logback.core.filter", + "ch.qos.logback.core.helpers", + "ch.qos.logback.core.hook", + "ch.qos.logback.core.html", + "ch.qos.logback.core.joran", + "ch.qos.logback.core.joran.action", + "ch.qos.logback.core.joran.conditional", + "ch.qos.logback.core.joran.event", + "ch.qos.logback.core.joran.sanity", + "ch.qos.logback.core.joran.spi", + "ch.qos.logback.core.joran.util", + "ch.qos.logback.core.joran.util.beans", + "ch.qos.logback.core.layout", + "ch.qos.logback.core.model", + "ch.qos.logback.core.model.conditional", + "ch.qos.logback.core.model.processor", + "ch.qos.logback.core.model.processor.conditional", + "ch.qos.logback.core.model.util", + "ch.qos.logback.core.net", + "ch.qos.logback.core.net.ssl", + "ch.qos.logback.core.pattern", + "ch.qos.logback.core.pattern.color", + "ch.qos.logback.core.pattern.parser", + "ch.qos.logback.core.pattern.util", + "ch.qos.logback.core.property", + "ch.qos.logback.core.read", + "ch.qos.logback.core.recovery", + "ch.qos.logback.core.rolling", + "ch.qos.logback.core.rolling.helper", + "ch.qos.logback.core.sift", + "ch.qos.logback.core.spi", + "ch.qos.logback.core.status", + "ch.qos.logback.core.subst", + "ch.qos.logback.core.testUtil", + "ch.qos.logback.core.util" + ], + "com.bucket4j:bucket4j-core": [ + "io.github.bucket4j", + "io.github.bucket4j.distributed", + "io.github.bucket4j.distributed.expiration", + "io.github.bucket4j.distributed.jdbc", + "io.github.bucket4j.distributed.proxy", + "io.github.bucket4j.distributed.proxy.generic.compare_and_swap", + "io.github.bucket4j.distributed.proxy.generic.pessimistic_locking", + "io.github.bucket4j.distributed.proxy.generic.select_for_update", + "io.github.bucket4j.distributed.proxy.optimization", + "io.github.bucket4j.distributed.proxy.optimization.batch", + "io.github.bucket4j.distributed.proxy.optimization.delay", + "io.github.bucket4j.distributed.proxy.optimization.manual", + "io.github.bucket4j.distributed.proxy.optimization.predictive", + "io.github.bucket4j.distributed.proxy.optimization.skiponzero", + "io.github.bucket4j.distributed.remote", + "io.github.bucket4j.distributed.remote.commands", + "io.github.bucket4j.distributed.serialization", + "io.github.bucket4j.distributed.versioning", + "io.github.bucket4j.local", + "io.github.bucket4j.util", + "io.github.bucket4j.util.concurrent.batch" + ], + "com.bucket4j:bucket4j_jdk17-core": [ + "io.github.bucket4j", + "io.github.bucket4j.distributed", + "io.github.bucket4j.distributed.expiration", + "io.github.bucket4j.distributed.jdbc", + "io.github.bucket4j.distributed.proxy", + "io.github.bucket4j.distributed.proxy.generic.compare_and_swap", + "io.github.bucket4j.distributed.proxy.generic.pessimistic_locking", + "io.github.bucket4j.distributed.proxy.generic.select_for_update", + "io.github.bucket4j.distributed.proxy.optimization", + "io.github.bucket4j.distributed.proxy.optimization.batch", + "io.github.bucket4j.distributed.proxy.optimization.delay", + "io.github.bucket4j.distributed.proxy.optimization.manual", + "io.github.bucket4j.distributed.proxy.optimization.predictive", + "io.github.bucket4j.distributed.proxy.optimization.skiponzero", + "io.github.bucket4j.distributed.remote", + "io.github.bucket4j.distributed.remote.commands", + "io.github.bucket4j.distributed.serialization", + "io.github.bucket4j.distributed.versioning", + "io.github.bucket4j.local", + "io.github.bucket4j.util", + "io.github.bucket4j.util.concurrent.batch" + ], + "com.datastax.cassandra:cassandra-driver-core": [ + "com.datastax.driver.core", + "com.datastax.driver.core.exceptions", + "com.datastax.driver.core.policies", + "com.datastax.driver.core.querybuilder", + "com.datastax.driver.core.schemabuilder", + "com.datastax.driver.core.utils" + ], + "com.datastax.oss:native-protocol": [ + "com.datastax.dse.protocol.internal", + "com.datastax.dse.protocol.internal.request", + "com.datastax.dse.protocol.internal.request.query", + "com.datastax.dse.protocol.internal.response.result", + "com.datastax.oss.protocol.internal", + "com.datastax.oss.protocol.internal.request", + "com.datastax.oss.protocol.internal.request.query", + "com.datastax.oss.protocol.internal.response", + "com.datastax.oss.protocol.internal.response.error", + "com.datastax.oss.protocol.internal.response.event", + "com.datastax.oss.protocol.internal.response.result", + "com.datastax.oss.protocol.internal.util", + "com.datastax.oss.protocol.internal.util.collection" + ], + "com.fasterxml.jackson.core:jackson-annotations": [ + "com.fasterxml.jackson.annotation" + ], + "com.fasterxml.jackson.core:jackson-core": [ + "com.fasterxml.jackson.core", + "com.fasterxml.jackson.core.async", + "com.fasterxml.jackson.core.base", + "com.fasterxml.jackson.core.exc", + "com.fasterxml.jackson.core.filter", + "com.fasterxml.jackson.core.format", + "com.fasterxml.jackson.core.internal.shaded.fdp.v2_21_4", + "com.fasterxml.jackson.core.internal.shaded.fdp.v2_21_4.bte", + "com.fasterxml.jackson.core.internal.shaded.fdp.v2_21_4.chr", + "com.fasterxml.jackson.core.io", + "com.fasterxml.jackson.core.io.schubfach", + "com.fasterxml.jackson.core.json", + "com.fasterxml.jackson.core.json.async", + "com.fasterxml.jackson.core.sym", + "com.fasterxml.jackson.core.type", + "com.fasterxml.jackson.core.util" + ], + "com.fasterxml.jackson.core:jackson-databind": [ + "com.fasterxml.jackson.databind", + "com.fasterxml.jackson.databind.annotation", + "com.fasterxml.jackson.databind.cfg", + "com.fasterxml.jackson.databind.deser", + "com.fasterxml.jackson.databind.deser.impl", + "com.fasterxml.jackson.databind.deser.std", + "com.fasterxml.jackson.databind.exc", + "com.fasterxml.jackson.databind.ext", + "com.fasterxml.jackson.databind.introspect", + "com.fasterxml.jackson.databind.jdk14", + "com.fasterxml.jackson.databind.json", + "com.fasterxml.jackson.databind.jsonFormatVisitors", + "com.fasterxml.jackson.databind.jsonschema", + "com.fasterxml.jackson.databind.jsontype", + "com.fasterxml.jackson.databind.jsontype.impl", + "com.fasterxml.jackson.databind.module", + "com.fasterxml.jackson.databind.node", + "com.fasterxml.jackson.databind.ser", + "com.fasterxml.jackson.databind.ser.impl", + "com.fasterxml.jackson.databind.ser.std", + "com.fasterxml.jackson.databind.type", + "com.fasterxml.jackson.databind.util", + "com.fasterxml.jackson.databind.util.internal" + ], + "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml": [ + "com.fasterxml.jackson.dataformat.yaml", + "com.fasterxml.jackson.dataformat.yaml.snakeyaml.error", + "com.fasterxml.jackson.dataformat.yaml.util" + ], + "com.fasterxml.jackson.datatype:jackson-datatype-jsr310": [ + "com.fasterxml.jackson.datatype.jsr310", + "com.fasterxml.jackson.datatype.jsr310.deser", + "com.fasterxml.jackson.datatype.jsr310.deser.key", + "com.fasterxml.jackson.datatype.jsr310.ser", + "com.fasterxml.jackson.datatype.jsr310.ser.key", + "com.fasterxml.jackson.datatype.jsr310.util" + ], + "com.fasterxml:classmate": [ + "com.fasterxml.classmate", + "com.fasterxml.classmate.members", + "com.fasterxml.classmate.types", + "com.fasterxml.classmate.util" + ], + "com.github.ben-manes.caffeine:caffeine": [ + "com.github.benmanes.caffeine.cache", + "com.github.benmanes.caffeine.cache.stats" + ], + "com.github.ben-manes.caffeine:guava": [ + "com.github.benmanes.caffeine.guava" + ], + "com.github.docker-java:docker-java-api": [ + "com.github.dockerjava.api", + "com.github.dockerjava.api.async", + "com.github.dockerjava.api.command", + "com.github.dockerjava.api.exception", + "com.github.dockerjava.api.model" + ], + "com.github.docker-java:docker-java-transport": [ + "com.github.dockerjava.transport" + ], + "com.github.docker-java:docker-java-transport-zerodep": [ + "com.github.dockerjava.zerodep", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.async", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.async.methods", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.auth", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.classic", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.classic.methods", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.config", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.cookie", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.entity", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.entity.mime", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.impl", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.impl.async", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.impl.auth", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.impl.classic", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.impl.compat", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.impl.cookie", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.impl.io", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.impl.nio", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.impl.routing", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.io", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.nio", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.protocol", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.psl", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.routing", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.socket", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.ssl", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.utils", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.validator", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.annotation", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.concurrent", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.function", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.config", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.impl", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.impl.bootstrap", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.impl.io", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.impl.nio", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.impl.routing", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.io", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.io.entity", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.io.ssl", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.io.support", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.message", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.nio", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.nio.command", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.nio.entity", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.nio.ssl", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.nio.support", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.nio.support.classic", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.protocol", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.ssl", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.support", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http2", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http2.config", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http2.frame", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http2.hpack", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http2.impl", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http2.impl.io", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http2.impl.nio", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http2.impl.nio.bootstrap", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http2.nio", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http2.nio.command", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http2.nio.pool", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http2.nio.support", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http2.protocol", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http2.ssl", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.io", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.net", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.pool", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.reactor", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.reactor.ssl", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.ssl", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.util" + ], + "com.github.java-json-tools:btf": [ + "com.github.fge" + ], + "com.github.java-json-tools:jackson-coreutils": [ + "com.github.fge.jackson", + "com.github.fge.jackson.jsonpointer" + ], + "com.github.java-json-tools:json-patch": [ + "com.github.fge.jsonpatch", + "com.github.fge.jsonpatch.diff", + "com.github.fge.jsonpatch.mergepatch" + ], + "com.github.java-json-tools:msg-simple": [ + "com.github.fge.msgsimple", + "com.github.fge.msgsimple.bundle", + "com.github.fge.msgsimple.load", + "com.github.fge.msgsimple.locale", + "com.github.fge.msgsimple.provider", + "com.github.fge.msgsimple.source" + ], + "com.github.jnr:jffi": [ + "com.kenai.jffi", + "com.kenai.jffi.internal" + ], + "com.github.jnr:jnr-constants": [ + "jnr.constants", + "jnr.constants.platform", + "jnr.constants.platform.aix", + "jnr.constants.platform.darwin", + "jnr.constants.platform.dragonflybsd", + "jnr.constants.platform.fake", + "jnr.constants.platform.freebsd", + "jnr.constants.platform.freebsd.aarch64", + "jnr.constants.platform.linux", + "jnr.constants.platform.linux.aarch64", + "jnr.constants.platform.linux.loongarch64", + "jnr.constants.platform.linux.mips64el", + "jnr.constants.platform.linux.powerpc64", + "jnr.constants.platform.linux.s390x", + "jnr.constants.platform.openbsd", + "jnr.constants.platform.solaris", + "jnr.constants.platform.windows" + ], + "com.github.jnr:jnr-ffi": [ + "jnr.ffi", + "jnr.ffi.annotations", + "jnr.ffi.byref", + "jnr.ffi.mapper", + "jnr.ffi.provider", + "jnr.ffi.provider.converters", + "jnr.ffi.provider.jffi", + "jnr.ffi.provider.jffi.platform.aarch64.linux", + "jnr.ffi.provider.jffi.platform.arm.linux", + "jnr.ffi.provider.jffi.platform.i386.darwin", + "jnr.ffi.provider.jffi.platform.i386.freebsd", + "jnr.ffi.provider.jffi.platform.i386.linux", + "jnr.ffi.provider.jffi.platform.i386.openbsd", + "jnr.ffi.provider.jffi.platform.i386.solaris", + "jnr.ffi.provider.jffi.platform.i386.windows", + "jnr.ffi.provider.jffi.platform.mips.linux", + "jnr.ffi.provider.jffi.platform.mipsel.linux", + "jnr.ffi.provider.jffi.platform.ppc.aix", + "jnr.ffi.provider.jffi.platform.ppc.darwin", + "jnr.ffi.provider.jffi.platform.ppc.linux", + "jnr.ffi.provider.jffi.platform.ppc64.linux", + "jnr.ffi.provider.jffi.platform.ppc64le.linux", + "jnr.ffi.provider.jffi.platform.s390.linux", + "jnr.ffi.provider.jffi.platform.s390x.linux", + "jnr.ffi.provider.jffi.platform.sparc.solaris", + "jnr.ffi.provider.jffi.platform.sparcv9.linux", + "jnr.ffi.provider.jffi.platform.sparcv9.solaris", + "jnr.ffi.provider.jffi.platform.x86_64.darwin", + "jnr.ffi.provider.jffi.platform.x86_64.freebsd", + "jnr.ffi.provider.jffi.platform.x86_64.linux", + "jnr.ffi.provider.jffi.platform.x86_64.openbsd", + "jnr.ffi.provider.jffi.platform.x86_64.solaris", + "jnr.ffi.provider.jffi.platform.x86_64.windows", + "jnr.ffi.types", + "jnr.ffi.util", + "jnr.ffi.util.ref", + "jnr.ffi.util.ref.internal" + ], + "com.github.jnr:jnr-posix": [ + "jnr.posix", + "jnr.posix.util", + "jnr.posix.windows" + ], + "com.github.jnr:jnr-x86asm": [ + "com.kenai.jnr.x86asm", + "jnr.x86asm" + ], + "com.github.stephenc.jcip:jcip-annotations": [ + "net.jcip.annotations" + ], + "com.google.android:annotations": [ + "android.annotation" + ], + "com.google.api.grpc:proto-google-common-protos": [ + "com.google.api", + "com.google.cloud", + "com.google.cloud.audit", + "com.google.cloud.location", + "com.google.geo.type", + "com.google.logging.type", + "com.google.longrunning", + "com.google.rpc", + "com.google.rpc.context", + "com.google.type" + ], + "com.google.code.findbugs:jsr305": [ + "javax.annotation", + "javax.annotation.concurrent", + "javax.annotation.meta" + ], + "com.google.code.gson:gson": [ + "com.google.gson", + "com.google.gson.annotations", + "com.google.gson.internal", + "com.google.gson.internal.bind", + "com.google.gson.internal.bind.util", + "com.google.gson.internal.reflect", + "com.google.gson.internal.sql", + "com.google.gson.reflect", + "com.google.gson.stream" + ], + "com.google.errorprone:error_prone_annotations": [ + "com.google.errorprone.annotations", + "com.google.errorprone.annotations.concurrent" + ], + "com.google.guava:failureaccess": [ + "com.google.common.util.concurrent.internal" + ], + "com.google.guava:guava": [ + "com.google.common.annotations", + "com.google.common.base", + "com.google.common.base.internal", + "com.google.common.cache", + "com.google.common.collect", + "com.google.common.escape", + "com.google.common.eventbus", + "com.google.common.graph", + "com.google.common.hash", + "com.google.common.html", + "com.google.common.io", + "com.google.common.math", + "com.google.common.net", + "com.google.common.primitives", + "com.google.common.reflect", + "com.google.common.util.concurrent", + "com.google.common.xml", + "com.google.thirdparty.publicsuffix" + ], + "com.google.j2objc:j2objc-annotations": [ + "com.google.j2objc.annotations" + ], + "com.google.protobuf:protobuf-java": [ + "com.google.protobuf", + "com.google.protobuf.compiler" + ], + "com.google.protobuf:protobuf-java-util": [ + "com.google.protobuf.util" + ], + "com.jayway.jsonpath:json-path": [ + "com.jayway.jsonpath", + "com.jayway.jsonpath.internal", + "com.jayway.jsonpath.internal.filter", + "com.jayway.jsonpath.internal.function", + "com.jayway.jsonpath.internal.function.json", + "com.jayway.jsonpath.internal.function.latebinding", + "com.jayway.jsonpath.internal.function.numeric", + "com.jayway.jsonpath.internal.function.sequence", + "com.jayway.jsonpath.internal.function.text", + "com.jayway.jsonpath.internal.path", + "com.jayway.jsonpath.spi.cache", + "com.jayway.jsonpath.spi.json", + "com.jayway.jsonpath.spi.mapper" + ], + "com.nimbusds:content-type": [ + "com.nimbusds.common.contenttype" + ], + "com.nimbusds:lang-tag": [ + "com.nimbusds.langtag" + ], + "com.nimbusds:nimbus-jose-jwt": [ + "com.nimbusds.jose", + "com.nimbusds.jose.crypto", + "com.nimbusds.jose.crypto.bc", + "com.nimbusds.jose.crypto.factories", + "com.nimbusds.jose.crypto.impl", + "com.nimbusds.jose.crypto.opts", + "com.nimbusds.jose.crypto.utils", + "com.nimbusds.jose.jca", + "com.nimbusds.jose.jwk", + "com.nimbusds.jose.jwk.gen", + "com.nimbusds.jose.jwk.source", + "com.nimbusds.jose.mint", + "com.nimbusds.jose.proc", + "com.nimbusds.jose.produce", + "com.nimbusds.jose.shaded.gson", + "com.nimbusds.jose.shaded.gson.annotations", + "com.nimbusds.jose.shaded.gson.internal", + "com.nimbusds.jose.shaded.gson.internal.bind", + "com.nimbusds.jose.shaded.gson.internal.bind.util", + "com.nimbusds.jose.shaded.gson.internal.reflect", + "com.nimbusds.jose.shaded.gson.internal.sql", + "com.nimbusds.jose.shaded.gson.reflect", + "com.nimbusds.jose.shaded.gson.stream", + "com.nimbusds.jose.shaded.jcip", + "com.nimbusds.jose.util", + "com.nimbusds.jose.util.cache", + "com.nimbusds.jose.util.events", + "com.nimbusds.jose.util.health", + "com.nimbusds.jwt", + "com.nimbusds.jwt.proc", + "com.nimbusds.jwt.util" + ], + "com.nimbusds:oauth2-oidc-sdk": [ + "com.nimbusds.oauth2.sdk", + "com.nimbusds.oauth2.sdk.as", + "com.nimbusds.oauth2.sdk.assertions", + "com.nimbusds.oauth2.sdk.assertions.jwt", + "com.nimbusds.oauth2.sdk.assertions.saml2", + "com.nimbusds.oauth2.sdk.auth", + "com.nimbusds.oauth2.sdk.auth.verifier", + "com.nimbusds.oauth2.sdk.ciba", + "com.nimbusds.oauth2.sdk.client", + "com.nimbusds.oauth2.sdk.cnf", + "com.nimbusds.oauth2.sdk.device", + "com.nimbusds.oauth2.sdk.dpop", + "com.nimbusds.oauth2.sdk.dpop.verifiers", + "com.nimbusds.oauth2.sdk.http", + "com.nimbusds.oauth2.sdk.id", + "com.nimbusds.oauth2.sdk.jarm", + "com.nimbusds.oauth2.sdk.jose", + "com.nimbusds.oauth2.sdk.pkce", + "com.nimbusds.oauth2.sdk.rar", + "com.nimbusds.oauth2.sdk.token", + "com.nimbusds.oauth2.sdk.tokenexchange", + "com.nimbusds.oauth2.sdk.util", + "com.nimbusds.oauth2.sdk.util.date", + "com.nimbusds.oauth2.sdk.util.singleuse", + "com.nimbusds.oauth2.sdk.util.tls", + "com.nimbusds.openid.connect.sdk", + "com.nimbusds.openid.connect.sdk.assurance", + "com.nimbusds.openid.connect.sdk.assurance.claims", + "com.nimbusds.openid.connect.sdk.assurance.evidences", + "com.nimbusds.openid.connect.sdk.assurance.evidences.attachment", + "com.nimbusds.openid.connect.sdk.assurance.request", + "com.nimbusds.openid.connect.sdk.claims", + "com.nimbusds.openid.connect.sdk.federation", + "com.nimbusds.openid.connect.sdk.federation.api", + "com.nimbusds.openid.connect.sdk.federation.config", + "com.nimbusds.openid.connect.sdk.federation.entities", + "com.nimbusds.openid.connect.sdk.federation.policy", + "com.nimbusds.openid.connect.sdk.federation.policy.language", + "com.nimbusds.openid.connect.sdk.federation.policy.operations", + "com.nimbusds.openid.connect.sdk.federation.registration", + "com.nimbusds.openid.connect.sdk.federation.trust", + "com.nimbusds.openid.connect.sdk.federation.trust.constraints", + "com.nimbusds.openid.connect.sdk.federation.trust.marks", + "com.nimbusds.openid.connect.sdk.federation.utils", + "com.nimbusds.openid.connect.sdk.id", + "com.nimbusds.openid.connect.sdk.nativesso", + "com.nimbusds.openid.connect.sdk.op", + "com.nimbusds.openid.connect.sdk.rp", + "com.nimbusds.openid.connect.sdk.rp.statement", + "com.nimbusds.openid.connect.sdk.token", + "com.nimbusds.openid.connect.sdk.validators", + "com.nimbusds.secevent.sdk.claims" + ], + "com.squareup.okhttp3:logging-interceptor": [ + "okhttp3.logging" + ], + "com.squareup.okhttp3:okhttp": [ + "okhttp3", + "okhttp3.internal", + "okhttp3.internal.authenticator", + "okhttp3.internal.cache", + "okhttp3.internal.cache2", + "okhttp3.internal.concurrent", + "okhttp3.internal.connection", + "okhttp3.internal.http", + "okhttp3.internal.http1", + "okhttp3.internal.http2", + "okhttp3.internal.io", + "okhttp3.internal.platform", + "okhttp3.internal.platform.android", + "okhttp3.internal.proxy", + "okhttp3.internal.publicsuffix", + "okhttp3.internal.tls", + "okhttp3.internal.ws" + ], + "com.squareup.okhttp3:okhttp-jvm": [ + "okhttp3", + "okhttp3.internal", + "okhttp3.internal.authenticator", + "okhttp3.internal.cache", + "okhttp3.internal.cache2", + "okhttp3.internal.concurrent", + "okhttp3.internal.connection", + "okhttp3.internal.graal", + "okhttp3.internal.http", + "okhttp3.internal.http1", + "okhttp3.internal.http2", + "okhttp3.internal.http2.flowcontrol", + "okhttp3.internal.idn", + "okhttp3.internal.platform", + "okhttp3.internal.proxy", + "okhttp3.internal.publicsuffix", + "okhttp3.internal.tls", + "okhttp3.internal.url", + "okhttp3.internal.ws" + ], + "com.squareup.okio:okio-jvm": [ + "okio", + "okio.internal" + ], + "com.typesafe:config": [ + "com.typesafe.config", + "com.typesafe.config.impl", + "com.typesafe.config.parser" + ], + "com.vaadin.external.google:android-json": [ + "org.json" + ], + "commons-codec:commons-codec": [ + "org.apache.commons.codec", + "org.apache.commons.codec.binary", + "org.apache.commons.codec.cli", + "org.apache.commons.codec.digest", + "org.apache.commons.codec.language", + "org.apache.commons.codec.language.bm", + "org.apache.commons.codec.net" + ], + "commons-io:commons-io": [ + "org.apache.commons.io", + "org.apache.commons.io.build", + "org.apache.commons.io.channels", + "org.apache.commons.io.charset", + "org.apache.commons.io.comparator", + "org.apache.commons.io.file", + "org.apache.commons.io.file.attribute", + "org.apache.commons.io.file.spi", + "org.apache.commons.io.filefilter", + "org.apache.commons.io.function", + "org.apache.commons.io.input", + "org.apache.commons.io.input.buffer", + "org.apache.commons.io.monitor", + "org.apache.commons.io.output", + "org.apache.commons.io.serialization" + ], + "commons-logging:commons-logging": [ + "org.apache.commons.logging", + "org.apache.commons.logging.impl" + ], + "io.cloudevents:cloudevents-api": [ + "io.cloudevents", + "io.cloudevents.lang", + "io.cloudevents.rw", + "io.cloudevents.types" + ], + "io.cloudevents:cloudevents-core": [ + "io.cloudevents.core", + "io.cloudevents.core.builder", + "io.cloudevents.core.data", + "io.cloudevents.core.extensions", + "io.cloudevents.core.extensions.impl", + "io.cloudevents.core.format", + "io.cloudevents.core.impl", + "io.cloudevents.core.message", + "io.cloudevents.core.message.impl", + "io.cloudevents.core.provider", + "io.cloudevents.core.v03", + "io.cloudevents.core.v1", + "io.cloudevents.core.validator" + ], + "io.cloudevents:cloudevents-json-jackson": [ + "io.cloudevents.jackson" + ], + "io.dropwizard.metrics:metrics-core": [ + "com.codahale.metrics" + ], + "io.grpc:grpc-api": [ + "io.grpc" + ], + "io.grpc:grpc-core": [ + "io.grpc.internal" + ], + "io.grpc:grpc-inprocess": [ + "io.grpc.inprocess" + ], + "io.grpc:grpc-netty": [ + "io.grpc.netty" + ], + "io.grpc:grpc-netty-shaded": [ + "io.grpc.netty.shaded.io.grpc.netty", + "io.grpc.netty.shaded.io.netty.bootstrap", + "io.grpc.netty.shaded.io.netty.buffer", + "io.grpc.netty.shaded.io.netty.buffer.search", + "io.grpc.netty.shaded.io.netty.channel", + "io.grpc.netty.shaded.io.netty.channel.embedded", + "io.grpc.netty.shaded.io.netty.channel.epoll", + "io.grpc.netty.shaded.io.netty.channel.group", + "io.grpc.netty.shaded.io.netty.channel.internal", + "io.grpc.netty.shaded.io.netty.channel.local", + "io.grpc.netty.shaded.io.netty.channel.nio", + "io.grpc.netty.shaded.io.netty.channel.oio", + "io.grpc.netty.shaded.io.netty.channel.pool", + "io.grpc.netty.shaded.io.netty.channel.socket", + "io.grpc.netty.shaded.io.netty.channel.socket.nio", + "io.grpc.netty.shaded.io.netty.channel.socket.oio", + "io.grpc.netty.shaded.io.netty.channel.unix", + "io.grpc.netty.shaded.io.netty.handler.address", + "io.grpc.netty.shaded.io.netty.handler.codec", + "io.grpc.netty.shaded.io.netty.handler.codec.base64", + "io.grpc.netty.shaded.io.netty.handler.codec.bytes", + "io.grpc.netty.shaded.io.netty.handler.codec.compression", + "io.grpc.netty.shaded.io.netty.handler.codec.http", + "io.grpc.netty.shaded.io.netty.handler.codec.http.cookie", + "io.grpc.netty.shaded.io.netty.handler.codec.http.cors", + "io.grpc.netty.shaded.io.netty.handler.codec.http.multipart", + "io.grpc.netty.shaded.io.netty.handler.codec.http.websocketx", + "io.grpc.netty.shaded.io.netty.handler.codec.http.websocketx.extensions", + "io.grpc.netty.shaded.io.netty.handler.codec.http.websocketx.extensions.compression", + "io.grpc.netty.shaded.io.netty.handler.codec.http2", + "io.grpc.netty.shaded.io.netty.handler.codec.json", + "io.grpc.netty.shaded.io.netty.handler.codec.marshalling", + "io.grpc.netty.shaded.io.netty.handler.codec.protobuf", + "io.grpc.netty.shaded.io.netty.handler.codec.rtsp", + "io.grpc.netty.shaded.io.netty.handler.codec.serialization", + "io.grpc.netty.shaded.io.netty.handler.codec.socks", + "io.grpc.netty.shaded.io.netty.handler.codec.socksx", + "io.grpc.netty.shaded.io.netty.handler.codec.socksx.v4", + "io.grpc.netty.shaded.io.netty.handler.codec.socksx.v5", + "io.grpc.netty.shaded.io.netty.handler.codec.spdy", + "io.grpc.netty.shaded.io.netty.handler.codec.string", + "io.grpc.netty.shaded.io.netty.handler.codec.xml", + "io.grpc.netty.shaded.io.netty.handler.flow", + "io.grpc.netty.shaded.io.netty.handler.flush", + "io.grpc.netty.shaded.io.netty.handler.ipfilter", + "io.grpc.netty.shaded.io.netty.handler.logging", + "io.grpc.netty.shaded.io.netty.handler.pcap", + "io.grpc.netty.shaded.io.netty.handler.proxy", + "io.grpc.netty.shaded.io.netty.handler.ssl", + "io.grpc.netty.shaded.io.netty.handler.ssl.ocsp", + "io.grpc.netty.shaded.io.netty.handler.ssl.util", + "io.grpc.netty.shaded.io.netty.handler.stream", + "io.grpc.netty.shaded.io.netty.handler.timeout", + "io.grpc.netty.shaded.io.netty.handler.traffic", + "io.grpc.netty.shaded.io.netty.internal.tcnative", + "io.grpc.netty.shaded.io.netty.resolver", + "io.grpc.netty.shaded.io.netty.util", + "io.grpc.netty.shaded.io.netty.util.collection", + "io.grpc.netty.shaded.io.netty.util.concurrent", + "io.grpc.netty.shaded.io.netty.util.internal", + "io.grpc.netty.shaded.io.netty.util.internal.logging", + "io.grpc.netty.shaded.io.netty.util.internal.shaded.org.jctools.queues", + "io.grpc.netty.shaded.io.netty.util.internal.shaded.org.jctools.queues.atomic", + "io.grpc.netty.shaded.io.netty.util.internal.shaded.org.jctools.util", + "io.grpc.netty.shaded.io.netty.util.internal.svm" + ], + "io.grpc:grpc-protobuf": [ + "io.grpc.protobuf" + ], + "io.grpc:grpc-protobuf-lite": [ + "io.grpc.protobuf.lite" + ], + "io.grpc:grpc-services": [ + "io.grpc.binarylog.v1", + "io.grpc.channelz.v1", + "io.grpc.health.v1", + "io.grpc.protobuf.services", + "io.grpc.protobuf.services.internal", + "io.grpc.reflection.v1alpha", + "io.grpc.services" + ], + "io.grpc:grpc-stub": [ + "io.grpc.stub", + "io.grpc.stub.annotations" + ], + "io.grpc:grpc-util": [ + "io.grpc.util" + ], + "io.gsonfire:gson-fire": [ + "io.gsonfire", + "io.gsonfire.annotations", + "io.gsonfire.builders", + "io.gsonfire.gson", + "io.gsonfire.postprocessors", + "io.gsonfire.postprocessors.methodinvoker", + "io.gsonfire.util", + "io.gsonfire.util.reflection" + ], + "io.kubernetes:client-java": [ + "io.kubernetes.client", + "io.kubernetes.client.apimachinery", + "io.kubernetes.client.informer", + "io.kubernetes.client.informer.cache", + "io.kubernetes.client.informer.exception", + "io.kubernetes.client.informer.impl", + "io.kubernetes.client.monitoring", + "io.kubernetes.client.persister", + "io.kubernetes.client.simplified", + "io.kubernetes.client.util", + "io.kubernetes.client.util.annotations", + "io.kubernetes.client.util.authenticators", + "io.kubernetes.client.util.conversion", + "io.kubernetes.client.util.credentials", + "io.kubernetes.client.util.exception", + "io.kubernetes.client.util.generic", + "io.kubernetes.client.util.generic.dynamic", + "io.kubernetes.client.util.generic.options", + "io.kubernetes.client.util.labels", + "io.kubernetes.client.util.okhttp", + "io.kubernetes.client.util.taints", + "io.kubernetes.client.util.version", + "io.kubernetes.client.util.wait" + ], + "io.kubernetes:client-java-api": [ + "io.kubernetes.client.common", + "io.kubernetes.client.custom", + "io.kubernetes.client.gson", + "io.kubernetes.client.openapi", + "io.kubernetes.client.openapi.apis", + "io.kubernetes.client.openapi.auth", + "io.kubernetes.client.openapi.models" + ], + "io.kubernetes:client-java-api-fluent": [ + "io.kubernetes.client.fluent", + "io.kubernetes.client.openapi.models" + ], + "io.kubernetes:client-java-extended": [ + "io.kubernetes.client.extended.controller", + "io.kubernetes.client.extended.controller.builder", + "io.kubernetes.client.extended.controller.reconciler", + "io.kubernetes.client.extended.event", + "io.kubernetes.client.extended.event.legacy", + "io.kubernetes.client.extended.event.v1", + "io.kubernetes.client.extended.kubectl", + "io.kubernetes.client.extended.kubectl.exception", + "io.kubernetes.client.extended.kubectl.util.deployment", + "io.kubernetes.client.extended.leaderelection", + "io.kubernetes.client.extended.leaderelection.resourcelock", + "io.kubernetes.client.extended.network", + "io.kubernetes.client.extended.network.exception", + "io.kubernetes.client.extended.pager", + "io.kubernetes.client.extended.wait", + "io.kubernetes.client.extended.workqueue", + "io.kubernetes.client.extended.workqueue.ratelimiter" + ], + "io.kubernetes:client-java-proto": [ + "io.kubernetes.client.proto" + ], + "io.micrometer:context-propagation": [ + "io.micrometer.context", + "io.micrometer.context.integration" + ], + "io.micrometer:micrometer-commons": [ + "io.micrometer.common", + "io.micrometer.common.annotation", + "io.micrometer.common.docs", + "io.micrometer.common.lang", + "io.micrometer.common.lang.internal", + "io.micrometer.common.util", + "io.micrometer.common.util.internal.logging" + ], + "io.micrometer:micrometer-core": [ + "io.micrometer.core.annotation", + "io.micrometer.core.aop", + "io.micrometer.core.instrument", + "io.micrometer.core.instrument.binder", + "io.micrometer.core.instrument.binder.cache", + "io.micrometer.core.instrument.binder.commonspool2", + "io.micrometer.core.instrument.binder.db", + "io.micrometer.core.instrument.binder.grpc", + "io.micrometer.core.instrument.binder.http", + "io.micrometer.core.instrument.binder.httpcomponents", + "io.micrometer.core.instrument.binder.httpcomponents.hc5", + "io.micrometer.core.instrument.binder.hystrix", + "io.micrometer.core.instrument.binder.jersey.server", + "io.micrometer.core.instrument.binder.jetty", + "io.micrometer.core.instrument.binder.jpa", + "io.micrometer.core.instrument.binder.jvm", + "io.micrometer.core.instrument.binder.jvm.convention", + "io.micrometer.core.instrument.binder.jvm.convention.micrometer", + "io.micrometer.core.instrument.binder.jvm.convention.otel", + "io.micrometer.core.instrument.binder.kafka", + "io.micrometer.core.instrument.binder.logging", + "io.micrometer.core.instrument.binder.mongodb", + "io.micrometer.core.instrument.binder.netty4", + "io.micrometer.core.instrument.binder.okhttp3", + "io.micrometer.core.instrument.binder.system", + "io.micrometer.core.instrument.binder.tomcat", + "io.micrometer.core.instrument.composite", + "io.micrometer.core.instrument.config", + "io.micrometer.core.instrument.config.validate", + "io.micrometer.core.instrument.cumulative", + "io.micrometer.core.instrument.distribution", + "io.micrometer.core.instrument.distribution.pause", + "io.micrometer.core.instrument.docs", + "io.micrometer.core.instrument.dropwizard", + "io.micrometer.core.instrument.internal", + "io.micrometer.core.instrument.kotlin", + "io.micrometer.core.instrument.logging", + "io.micrometer.core.instrument.noop", + "io.micrometer.core.instrument.observation", + "io.micrometer.core.instrument.push", + "io.micrometer.core.instrument.search", + "io.micrometer.core.instrument.simple", + "io.micrometer.core.instrument.step", + "io.micrometer.core.instrument.util", + "io.micrometer.core.ipc.http", + "io.micrometer.core.util.internal.logging" + ], + "io.micrometer:micrometer-jakarta9": [ + "io.micrometer.jakarta9.instrument.jms", + "io.micrometer.jakarta9.instrument.mail" + ], + "io.micrometer:micrometer-observation": [ + "io.micrometer.observation", + "io.micrometer.observation.annotation", + "io.micrometer.observation.aop", + "io.micrometer.observation.contextpropagation", + "io.micrometer.observation.docs", + "io.micrometer.observation.transport" + ], + "io.micrometer:micrometer-observation-test": [ + "io.micrometer.observation.tck" + ], + "io.micrometer:micrometer-registry-prometheus": [ + "io.micrometer.prometheusmetrics" + ], + "io.micrometer:micrometer-tracing": [ + "io.micrometer.tracing", + "io.micrometer.tracing.annotation", + "io.micrometer.tracing.contextpropagation", + "io.micrometer.tracing.contextpropagation.reactor", + "io.micrometer.tracing.docs", + "io.micrometer.tracing.exporter", + "io.micrometer.tracing.handler", + "io.micrometer.tracing.internal", + "io.micrometer.tracing.propagation" + ], + "io.micrometer:micrometer-tracing-bridge-otel": [ + "io.micrometer.tracing.otel", + "io.micrometer.tracing.otel.bridge", + "io.micrometer.tracing.otel.propagation" + ], + "io.nats:jnats": [ + "io.nats.client", + "io.nats.client.api", + "io.nats.client.impl", + "io.nats.client.support", + "io.nats.service" + ], + "io.netty:netty-buffer": [ + "io.netty.buffer", + "io.netty.buffer.search" + ], + "io.netty:netty-codec-base": [ + "io.netty.handler.codec", + "io.netty.handler.codec.base64", + "io.netty.handler.codec.bytes", + "io.netty.handler.codec.json", + "io.netty.handler.codec.serialization", + "io.netty.handler.codec.string" + ], + "io.netty:netty-codec-classes-quic": [ + "io.netty.handler.codec.quic" + ], + "io.netty:netty-codec-compression": [ + "io.netty.handler.codec.compression" + ], + "io.netty:netty-codec-dns": [ + "io.netty.handler.codec.dns" + ], + "io.netty:netty-codec-http": [ + "io.netty.handler.codec.http", + "io.netty.handler.codec.http.cookie", + "io.netty.handler.codec.http.cors", + "io.netty.handler.codec.http.multipart", + "io.netty.handler.codec.http.websocketx", + "io.netty.handler.codec.http.websocketx.extensions", + "io.netty.handler.codec.http.websocketx.extensions.compression", + "io.netty.handler.codec.rtsp", + "io.netty.handler.codec.spdy" + ], + "io.netty:netty-codec-http2": [ + "io.netty.handler.codec.http2" + ], + "io.netty:netty-codec-http3": [ + "io.netty.handler.codec.http3" + ], + "io.netty:netty-codec-socks": [ + "io.netty.handler.codec.socks", + "io.netty.handler.codec.socksx", + "io.netty.handler.codec.socksx.v4", + "io.netty.handler.codec.socksx.v5" + ], + "io.netty:netty-common": [ + "io.netty.util", + "io.netty.util.collection", + "io.netty.util.concurrent", + "io.netty.util.internal", + "io.netty.util.internal.logging", + "io.netty.util.internal.shaded.org.jctools.counters", + "io.netty.util.internal.shaded.org.jctools.maps", + "io.netty.util.internal.shaded.org.jctools.queues", + "io.netty.util.internal.shaded.org.jctools.queues.atomic", + "io.netty.util.internal.shaded.org.jctools.queues.atomic.unpadded", + "io.netty.util.internal.shaded.org.jctools.queues.unpadded", + "io.netty.util.internal.shaded.org.jctools.util", + "io.netty.util.internal.svm" + ], + "io.netty:netty-handler": [ + "io.netty.handler.address", + "io.netty.handler.flow", + "io.netty.handler.flush", + "io.netty.handler.ipfilter", + "io.netty.handler.logging", + "io.netty.handler.pcap", + "io.netty.handler.ssl", + "io.netty.handler.ssl.util", + "io.netty.handler.stream", + "io.netty.handler.timeout", + "io.netty.handler.traffic" + ], + "io.netty:netty-handler-proxy": [ + "io.netty.handler.proxy" + ], + "io.netty:netty-resolver": [ + "io.netty.resolver" + ], + "io.netty:netty-resolver-dns": [ + "io.netty.resolver.dns" + ], + "io.netty:netty-resolver-dns-classes-macos": [ + "io.netty.resolver.dns.macos" + ], + "io.netty:netty-transport": [ + "io.netty.bootstrap", + "io.netty.channel", + "io.netty.channel.embedded", + "io.netty.channel.group", + "io.netty.channel.internal", + "io.netty.channel.local", + "io.netty.channel.nio", + "io.netty.channel.oio", + "io.netty.channel.pool", + "io.netty.channel.socket", + "io.netty.channel.socket.nio", + "io.netty.channel.socket.oio" + ], + "io.netty:netty-transport-classes-epoll": [ + "io.netty.channel.epoll" + ], + "io.netty:netty-transport-native-unix-common": [ + "io.netty.channel.unix" + ], + "io.opentelemetry.semconv:opentelemetry-semconv": [ + "io.opentelemetry.semconv" + ], + "io.opentelemetry:opentelemetry-api": [ + "io.opentelemetry.api", + "io.opentelemetry.api.baggage", + "io.opentelemetry.api.baggage.propagation", + "io.opentelemetry.api.common", + "io.opentelemetry.api.internal", + "io.opentelemetry.api.logs", + "io.opentelemetry.api.metrics", + "io.opentelemetry.api.trace", + "io.opentelemetry.api.trace.propagation", + "io.opentelemetry.api.trace.propagation.internal" + ], + "io.opentelemetry:opentelemetry-common": [ + "io.opentelemetry.common" + ], + "io.opentelemetry:opentelemetry-context": [ + "io.opentelemetry.context", + "io.opentelemetry.context.internal.shaded", + "io.opentelemetry.context.propagation", + "io.opentelemetry.context.propagation.internal" + ], + "io.opentelemetry:opentelemetry-exporter-common": [ + "io.opentelemetry.exporter.internal", + "io.opentelemetry.exporter.internal.compression", + "io.opentelemetry.exporter.internal.grpc", + "io.opentelemetry.exporter.internal.http", + "io.opentelemetry.exporter.internal.marshal", + "io.opentelemetry.exporter.internal.metrics" + ], + "io.opentelemetry:opentelemetry-exporter-otlp": [ + "io.opentelemetry.exporter.otlp.all.internal", + "io.opentelemetry.exporter.otlp.http.logs", + "io.opentelemetry.exporter.otlp.http.metrics", + "io.opentelemetry.exporter.otlp.http.trace", + "io.opentelemetry.exporter.otlp.internal", + "io.opentelemetry.exporter.otlp.logs", + "io.opentelemetry.exporter.otlp.metrics", + "io.opentelemetry.exporter.otlp.trace" + ], + "io.opentelemetry:opentelemetry-exporter-otlp-common": [ + "io.opentelemetry.exporter.internal.otlp", + "io.opentelemetry.exporter.internal.otlp.logs", + "io.opentelemetry.exporter.internal.otlp.metrics", + "io.opentelemetry.exporter.internal.otlp.traces", + "io.opentelemetry.proto.collector.logs.v1.internal", + "io.opentelemetry.proto.collector.metrics.v1.internal", + "io.opentelemetry.proto.collector.profiles.v1development.internal", + "io.opentelemetry.proto.collector.trace.v1.internal", + "io.opentelemetry.proto.common.v1.internal", + "io.opentelemetry.proto.logs.v1.internal", + "io.opentelemetry.proto.metrics.v1.internal", + "io.opentelemetry.proto.profiles.v1development.internal", + "io.opentelemetry.proto.resource.v1.internal", + "io.opentelemetry.proto.trace.v1.internal" + ], + "io.opentelemetry:opentelemetry-exporter-sender-okhttp": [ + "io.opentelemetry.exporter.sender.okhttp.internal" + ], + "io.opentelemetry:opentelemetry-extension-trace-propagators": [ + "io.opentelemetry.extension.trace.propagation", + "io.opentelemetry.extension.trace.propagation.internal" + ], + "io.opentelemetry:opentelemetry-sdk": [ + "io.opentelemetry.sdk" + ], + "io.opentelemetry:opentelemetry-sdk-common": [ + "io.opentelemetry.sdk.common", + "io.opentelemetry.sdk.common.export", + "io.opentelemetry.sdk.common.internal", + "io.opentelemetry.sdk.internal", + "io.opentelemetry.sdk.resources" + ], + "io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi": [ + "io.opentelemetry.sdk.autoconfigure.spi", + "io.opentelemetry.sdk.autoconfigure.spi.internal", + "io.opentelemetry.sdk.autoconfigure.spi.logs", + "io.opentelemetry.sdk.autoconfigure.spi.metrics", + "io.opentelemetry.sdk.autoconfigure.spi.traces" + ], + "io.opentelemetry:opentelemetry-sdk-logs": [ + "io.opentelemetry.sdk.logs", + "io.opentelemetry.sdk.logs.data", + "io.opentelemetry.sdk.logs.data.internal", + "io.opentelemetry.sdk.logs.export", + "io.opentelemetry.sdk.logs.internal" + ], + "io.opentelemetry:opentelemetry-sdk-metrics": [ + "io.opentelemetry.sdk.metrics", + "io.opentelemetry.sdk.metrics.data", + "io.opentelemetry.sdk.metrics.export", + "io.opentelemetry.sdk.metrics.internal", + "io.opentelemetry.sdk.metrics.internal.aggregator", + "io.opentelemetry.sdk.metrics.internal.concurrent", + "io.opentelemetry.sdk.metrics.internal.data", + "io.opentelemetry.sdk.metrics.internal.debug", + "io.opentelemetry.sdk.metrics.internal.descriptor", + "io.opentelemetry.sdk.metrics.internal.exemplar", + "io.opentelemetry.sdk.metrics.internal.export", + "io.opentelemetry.sdk.metrics.internal.state", + "io.opentelemetry.sdk.metrics.internal.view" + ], + "io.opentelemetry:opentelemetry-sdk-testing": [ + "io.opentelemetry.sdk.testing.assertj", + "io.opentelemetry.sdk.testing.context", + "io.opentelemetry.sdk.testing.exporter", + "io.opentelemetry.sdk.testing.junit4", + "io.opentelemetry.sdk.testing.junit5", + "io.opentelemetry.sdk.testing.logs", + "io.opentelemetry.sdk.testing.logs.internal", + "io.opentelemetry.sdk.testing.metrics", + "io.opentelemetry.sdk.testing.time", + "io.opentelemetry.sdk.testing.trace" + ], + "io.opentelemetry:opentelemetry-sdk-trace": [ + "io.opentelemetry.internal.shaded.jctools.counters", + "io.opentelemetry.internal.shaded.jctools.maps", + "io.opentelemetry.internal.shaded.jctools.queues", + "io.opentelemetry.internal.shaded.jctools.queues.atomic", + "io.opentelemetry.internal.shaded.jctools.queues.atomic.unpadded", + "io.opentelemetry.internal.shaded.jctools.queues.unpadded", + "io.opentelemetry.internal.shaded.jctools.util", + "io.opentelemetry.sdk.trace", + "io.opentelemetry.sdk.trace.data", + "io.opentelemetry.sdk.trace.export", + "io.opentelemetry.sdk.trace.internal", + "io.opentelemetry.sdk.trace.samplers" + ], + "io.perfmark:perfmark-api": [ + "io.perfmark" + ], + "io.projectreactor.netty:reactor-netty-core": [ + "reactor.netty", + "reactor.netty.channel", + "reactor.netty.contextpropagation", + "reactor.netty.internal.shaded.reactor.pool", + "reactor.netty.internal.shaded.reactor.pool.decorators", + "reactor.netty.internal.shaded.reactor.pool.introspection", + "reactor.netty.internal.util", + "reactor.netty.observability", + "reactor.netty.resources", + "reactor.netty.tcp", + "reactor.netty.transport", + "reactor.netty.transport.logging", + "reactor.netty.udp" + ], + "io.projectreactor.netty:reactor-netty-http": [ + "reactor.netty.http", + "reactor.netty.http.client", + "reactor.netty.http.internal", + "reactor.netty.http.logging", + "reactor.netty.http.observability", + "reactor.netty.http.server", + "reactor.netty.http.server.compression", + "reactor.netty.http.server.logging", + "reactor.netty.http.server.logging.error", + "reactor.netty.http.websocket" + ], + "io.projectreactor:reactor-core": [ + "reactor.adapter", + "reactor.core", + "reactor.core.observability", + "reactor.core.publisher", + "reactor.core.scheduler", + "reactor.util", + "reactor.util.annotation", + "reactor.util.concurrent", + "reactor.util.context", + "reactor.util.function", + "reactor.util.repeat", + "reactor.util.retry" + ], + "io.projectreactor:reactor-test": [ + "reactor.test", + "reactor.test.publisher", + "reactor.test.scheduler", + "reactor.test.subscriber", + "reactor.test.util" + ], + "io.prometheus:prometheus-metrics-config": [ + "io.prometheus.metrics.config" + ], + "io.prometheus:prometheus-metrics-core": [ + "io.prometheus.metrics.core.datapoints", + "io.prometheus.metrics.core.exemplars", + "io.prometheus.metrics.core.metrics", + "io.prometheus.metrics.core.util" + ], + "io.prometheus:prometheus-metrics-exposition-formats": [ + "io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_33_0", + "io.prometheus.metrics.expositionformats.internal", + "io.prometheus.metrics.shaded.com_google_protobuf_4_33_0", + "io.prometheus.metrics.shaded.com_google_protobuf_4_33_0.compiler" + ], + "io.prometheus:prometheus-metrics-exposition-textformats": [ + "io.prometheus.metrics.expositionformats" + ], + "io.prometheus:prometheus-metrics-model": [ + "io.prometheus.metrics.model.registry", + "io.prometheus.metrics.model.snapshots" + ], + "io.prometheus:prometheus-metrics-tracer-common": [ + "io.prometheus.metrics.tracer.common" + ], + "io.swagger.core.v3:swagger-annotations-jakarta": [ + "io.swagger.v3.oas.annotations", + "io.swagger.v3.oas.annotations.callbacks", + "io.swagger.v3.oas.annotations.enums", + "io.swagger.v3.oas.annotations.extensions", + "io.swagger.v3.oas.annotations.headers", + "io.swagger.v3.oas.annotations.info", + "io.swagger.v3.oas.annotations.links", + "io.swagger.v3.oas.annotations.media", + "io.swagger.v3.oas.annotations.parameters", + "io.swagger.v3.oas.annotations.responses", + "io.swagger.v3.oas.annotations.security", + "io.swagger.v3.oas.annotations.servers", + "io.swagger.v3.oas.annotations.tags" + ], + "io.swagger.core.v3:swagger-core-jakarta": [ + "io.swagger.v3.core.converter", + "io.swagger.v3.core.filter", + "io.swagger.v3.core.jackson", + "io.swagger.v3.core.jackson.mixin", + "io.swagger.v3.core.model", + "io.swagger.v3.core.util" + ], + "io.swagger.core.v3:swagger-models-jakarta": [ + "io.swagger.v3.oas.models", + "io.swagger.v3.oas.models.annotations", + "io.swagger.v3.oas.models.callbacks", + "io.swagger.v3.oas.models.examples", + "io.swagger.v3.oas.models.headers", + "io.swagger.v3.oas.models.info", + "io.swagger.v3.oas.models.links", + "io.swagger.v3.oas.models.media", + "io.swagger.v3.oas.models.parameters", + "io.swagger.v3.oas.models.responses", + "io.swagger.v3.oas.models.security", + "io.swagger.v3.oas.models.servers", + "io.swagger.v3.oas.models.tags" + ], + "io.swagger:swagger-annotations": [ + "io.swagger.annotations" + ], + "jakarta.activation:jakarta.activation-api": [ + "jakarta.activation", + "jakarta.activation.spi" + ], + "jakarta.annotation:jakarta.annotation-api": [ + "jakarta.annotation", + "jakarta.annotation.security", + "jakarta.annotation.sql" + ], + "jakarta.servlet:jakarta.servlet-api": [ + "jakarta.servlet", + "jakarta.servlet.annotation", + "jakarta.servlet.descriptor", + "jakarta.servlet.http" + ], + "jakarta.validation:jakarta.validation-api": [ + "jakarta.validation", + "jakarta.validation.bootstrap", + "jakarta.validation.constraints", + "jakarta.validation.constraintvalidation", + "jakarta.validation.executable", + "jakarta.validation.groups", + "jakarta.validation.metadata", + "jakarta.validation.spi", + "jakarta.validation.valueextraction" + ], + "jakarta.xml.bind:jakarta.xml.bind-api": [ + "jakarta.xml.bind", + "jakarta.xml.bind.annotation", + "jakarta.xml.bind.annotation.adapters", + "jakarta.xml.bind.attachment", + "jakarta.xml.bind.helpers", + "jakarta.xml.bind.util" + ], + "javax.annotation:javax.annotation-api": [ + "javax.annotation", + "javax.annotation.security", + "javax.annotation.sql" + ], + "net.bytebuddy:byte-buddy": [ + "net.bytebuddy", + "net.bytebuddy.agent.builder", + "net.bytebuddy.asm", + "net.bytebuddy.build", + "net.bytebuddy.description", + "net.bytebuddy.description.annotation", + "net.bytebuddy.description.enumeration", + "net.bytebuddy.description.field", + "net.bytebuddy.description.method", + "net.bytebuddy.description.modifier", + "net.bytebuddy.description.type", + "net.bytebuddy.dynamic", + "net.bytebuddy.dynamic.loading", + "net.bytebuddy.dynamic.scaffold", + "net.bytebuddy.dynamic.scaffold.inline", + "net.bytebuddy.dynamic.scaffold.subclass", + "net.bytebuddy.implementation", + "net.bytebuddy.implementation.attribute", + "net.bytebuddy.implementation.auxiliary", + "net.bytebuddy.implementation.bind", + "net.bytebuddy.implementation.bind.annotation", + "net.bytebuddy.implementation.bytecode", + "net.bytebuddy.implementation.bytecode.assign", + "net.bytebuddy.implementation.bytecode.assign.primitive", + "net.bytebuddy.implementation.bytecode.assign.reference", + "net.bytebuddy.implementation.bytecode.collection", + "net.bytebuddy.implementation.bytecode.constant", + "net.bytebuddy.implementation.bytecode.member", + "net.bytebuddy.jar.asm", + "net.bytebuddy.jar.asm.commons", + "net.bytebuddy.jar.asm.signature", + "net.bytebuddy.jar.asmjdkbridge", + "net.bytebuddy.matcher", + "net.bytebuddy.pool", + "net.bytebuddy.utility", + "net.bytebuddy.utility.dispatcher", + "net.bytebuddy.utility.nullability", + "net.bytebuddy.utility.privilege", + "net.bytebuddy.utility.visitor" + ], + "net.bytebuddy:byte-buddy-agent": [ + "net.bytebuddy.agent", + "net.bytebuddy.agent.utility.nullability" + ], + "net.devh:grpc-common-spring-boot": [ + "net.devh.boot.grpc.common.autoconfigure", + "net.devh.boot.grpc.common.codec", + "net.devh.boot.grpc.common.security", + "net.devh.boot.grpc.common.util" + ], + "net.devh:grpc-server-spring-boot-starter": [ + "net.devh.boot.grpc.server.advice", + "net.devh.boot.grpc.server.autoconfigure", + "net.devh.boot.grpc.server.condition", + "net.devh.boot.grpc.server.config", + "net.devh.boot.grpc.server.error", + "net.devh.boot.grpc.server.event", + "net.devh.boot.grpc.server.interceptor", + "net.devh.boot.grpc.server.metrics", + "net.devh.boot.grpc.server.nameresolver", + "net.devh.boot.grpc.server.scope", + "net.devh.boot.grpc.server.security.authentication", + "net.devh.boot.grpc.server.security.check", + "net.devh.boot.grpc.server.security.interceptors", + "net.devh.boot.grpc.server.serverfactory", + "net.devh.boot.grpc.server.service" + ], + "net.java.dev.jna:jna": [ + "com.sun.jna", + "com.sun.jna.internal", + "com.sun.jna.ptr", + "com.sun.jna.win32" + ], + "net.javacrumbs.shedlock:shedlock-core": [ + "net.javacrumbs.shedlock.core", + "net.javacrumbs.shedlock.support", + "net.javacrumbs.shedlock.util" + ], + "net.javacrumbs.shedlock:shedlock-provider-cassandra": [ + "net.javacrumbs.shedlock.provider.cassandra" + ], + "net.javacrumbs.shedlock:shedlock-spring": [ + "net.javacrumbs.shedlock.spring", + "net.javacrumbs.shedlock.spring.annotation", + "net.javacrumbs.shedlock.spring.aop" + ], + "net.minidev:accessors-smart": [ + "net.minidev.asm", + "net.minidev.asm.ex" + ], + "net.minidev:json-smart": [ + "net.minidev.json", + "net.minidev.json.annotate", + "net.minidev.json.parser", + "net.minidev.json.reader", + "net.minidev.json.writer" + ], + "org.apache.cassandra:java-driver-core": [ + "com.datastax.dse.driver.api.core", + "com.datastax.dse.driver.api.core.auth", + "com.datastax.dse.driver.api.core.config", + "com.datastax.dse.driver.api.core.cql.continuous", + "com.datastax.dse.driver.api.core.cql.continuous.reactive", + "com.datastax.dse.driver.api.core.cql.reactive", + "com.datastax.dse.driver.api.core.data.geometry", + "com.datastax.dse.driver.api.core.data.time", + "com.datastax.dse.driver.api.core.graph", + "com.datastax.dse.driver.api.core.graph.predicates", + "com.datastax.dse.driver.api.core.graph.reactive", + "com.datastax.dse.driver.api.core.metadata", + "com.datastax.dse.driver.api.core.metadata.schema", + "com.datastax.dse.driver.api.core.metrics", + "com.datastax.dse.driver.api.core.servererrors", + "com.datastax.dse.driver.api.core.type", + "com.datastax.dse.driver.api.core.type.codec", + "com.datastax.dse.driver.internal.core", + "com.datastax.dse.driver.internal.core.auth", + "com.datastax.dse.driver.internal.core.cql", + "com.datastax.dse.driver.internal.core.cql.continuous", + "com.datastax.dse.driver.internal.core.cql.continuous.reactive", + "com.datastax.dse.driver.internal.core.cql.reactive", + "com.datastax.dse.driver.internal.core.data.geometry", + "com.datastax.dse.driver.internal.core.graph", + "com.datastax.dse.driver.internal.core.graph.binary", + "com.datastax.dse.driver.internal.core.graph.binary.buffer", + "com.datastax.dse.driver.internal.core.graph.reactive", + "com.datastax.dse.driver.internal.core.insights", + "com.datastax.dse.driver.internal.core.insights.configuration", + "com.datastax.dse.driver.internal.core.insights.exceptions", + "com.datastax.dse.driver.internal.core.insights.schema", + "com.datastax.dse.driver.internal.core.loadbalancing", + "com.datastax.dse.driver.internal.core.metadata.schema", + "com.datastax.dse.driver.internal.core.metadata.schema.parsing", + "com.datastax.dse.driver.internal.core.protocol", + "com.datastax.dse.driver.internal.core.search", + "com.datastax.dse.driver.internal.core.session", + "com.datastax.dse.driver.internal.core.type.codec", + "com.datastax.dse.driver.internal.core.type.codec.geometry", + "com.datastax.dse.driver.internal.core.type.codec.time", + "com.datastax.dse.driver.internal.core.util.concurrent", + "com.datastax.oss.driver.api.core", + "com.datastax.oss.driver.api.core.addresstranslation", + "com.datastax.oss.driver.api.core.auth", + "com.datastax.oss.driver.api.core.config", + "com.datastax.oss.driver.api.core.connection", + "com.datastax.oss.driver.api.core.context", + "com.datastax.oss.driver.api.core.cql", + "com.datastax.oss.driver.api.core.data", + "com.datastax.oss.driver.api.core.detach", + "com.datastax.oss.driver.api.core.loadbalancing", + "com.datastax.oss.driver.api.core.metadata", + "com.datastax.oss.driver.api.core.metadata.schema", + "com.datastax.oss.driver.api.core.metadata.token", + "com.datastax.oss.driver.api.core.metrics", + "com.datastax.oss.driver.api.core.paging", + "com.datastax.oss.driver.api.core.retry", + "com.datastax.oss.driver.api.core.servererrors", + "com.datastax.oss.driver.api.core.session", + "com.datastax.oss.driver.api.core.session.throttling", + "com.datastax.oss.driver.api.core.specex", + "com.datastax.oss.driver.api.core.ssl", + "com.datastax.oss.driver.api.core.time", + "com.datastax.oss.driver.api.core.tracker", + "com.datastax.oss.driver.api.core.type", + "com.datastax.oss.driver.api.core.type.codec", + "com.datastax.oss.driver.api.core.type.codec.registry", + "com.datastax.oss.driver.api.core.type.reflect", + "com.datastax.oss.driver.api.core.uuid", + "com.datastax.oss.driver.internal.core", + "com.datastax.oss.driver.internal.core.addresstranslation", + "com.datastax.oss.driver.internal.core.adminrequest", + "com.datastax.oss.driver.internal.core.auth", + "com.datastax.oss.driver.internal.core.channel", + "com.datastax.oss.driver.internal.core.config", + "com.datastax.oss.driver.internal.core.config.cloud", + "com.datastax.oss.driver.internal.core.config.composite", + "com.datastax.oss.driver.internal.core.config.map", + "com.datastax.oss.driver.internal.core.config.typesafe", + "com.datastax.oss.driver.internal.core.connection", + "com.datastax.oss.driver.internal.core.context", + "com.datastax.oss.driver.internal.core.control", + "com.datastax.oss.driver.internal.core.cql", + "com.datastax.oss.driver.internal.core.data", + "com.datastax.oss.driver.internal.core.loadbalancing", + "com.datastax.oss.driver.internal.core.loadbalancing.helper", + "com.datastax.oss.driver.internal.core.loadbalancing.nodeset", + "com.datastax.oss.driver.internal.core.metadata", + "com.datastax.oss.driver.internal.core.metadata.schema", + "com.datastax.oss.driver.internal.core.metadata.schema.events", + "com.datastax.oss.driver.internal.core.metadata.schema.parsing", + "com.datastax.oss.driver.internal.core.metadata.schema.queries", + "com.datastax.oss.driver.internal.core.metadata.schema.refresh", + "com.datastax.oss.driver.internal.core.metadata.token", + "com.datastax.oss.driver.internal.core.metrics", + "com.datastax.oss.driver.internal.core.os", + "com.datastax.oss.driver.internal.core.pool", + "com.datastax.oss.driver.internal.core.protocol", + "com.datastax.oss.driver.internal.core.retry", + "com.datastax.oss.driver.internal.core.servererrors", + "com.datastax.oss.driver.internal.core.session", + "com.datastax.oss.driver.internal.core.session.throttling", + "com.datastax.oss.driver.internal.core.specex", + "com.datastax.oss.driver.internal.core.ssl", + "com.datastax.oss.driver.internal.core.time", + "com.datastax.oss.driver.internal.core.tracker", + "com.datastax.oss.driver.internal.core.type", + "com.datastax.oss.driver.internal.core.type.codec", + "com.datastax.oss.driver.internal.core.type.codec.extras", + "com.datastax.oss.driver.internal.core.type.codec.extras.array", + "com.datastax.oss.driver.internal.core.type.codec.extras.enums", + "com.datastax.oss.driver.internal.core.type.codec.extras.json", + "com.datastax.oss.driver.internal.core.type.codec.extras.time", + "com.datastax.oss.driver.internal.core.type.codec.extras.vector", + "com.datastax.oss.driver.internal.core.type.codec.registry", + "com.datastax.oss.driver.internal.core.type.util", + "com.datastax.oss.driver.internal.core.util", + "com.datastax.oss.driver.internal.core.util.collection", + "com.datastax.oss.driver.internal.core.util.concurrent" + ], + "org.apache.cassandra:java-driver-guava-shaded": [ + "com.datastax.oss.driver.shaded.guava.common.annotations", + "com.datastax.oss.driver.shaded.guava.common.base", + "com.datastax.oss.driver.shaded.guava.common.base.internal", + "com.datastax.oss.driver.shaded.guava.common.cache", + "com.datastax.oss.driver.shaded.guava.common.collect", + "com.datastax.oss.driver.shaded.guava.common.escape", + "com.datastax.oss.driver.shaded.guava.common.eventbus", + "com.datastax.oss.driver.shaded.guava.common.graph", + "com.datastax.oss.driver.shaded.guava.common.hash", + "com.datastax.oss.driver.shaded.guava.common.html", + "com.datastax.oss.driver.shaded.guava.common.io", + "com.datastax.oss.driver.shaded.guava.common.math", + "com.datastax.oss.driver.shaded.guava.common.net", + "com.datastax.oss.driver.shaded.guava.common.primitives", + "com.datastax.oss.driver.shaded.guava.common.reflect", + "com.datastax.oss.driver.shaded.guava.common.util.concurrent", + "com.datastax.oss.driver.shaded.guava.common.util.concurrent.internal", + "com.datastax.oss.driver.shaded.guava.common.xml", + "com.datastax.oss.driver.shaded.guava.j2objc.annotations", + "com.datastax.oss.driver.shaded.guava.thirdparty.publicsuffix" + ], + "org.apache.cassandra:java-driver-metrics-micrometer": [ + "com.datastax.oss.driver.internal.metrics.micrometer" + ], + "org.apache.cassandra:java-driver-query-builder": [ + "com.datastax.dse.driver.api.querybuilder", + "com.datastax.dse.driver.api.querybuilder.schema", + "com.datastax.dse.driver.internal.querybuilder.schema", + "com.datastax.oss.driver.api.querybuilder", + "com.datastax.oss.driver.api.querybuilder.condition", + "com.datastax.oss.driver.api.querybuilder.delete", + "com.datastax.oss.driver.api.querybuilder.insert", + "com.datastax.oss.driver.api.querybuilder.relation", + "com.datastax.oss.driver.api.querybuilder.schema", + "com.datastax.oss.driver.api.querybuilder.schema.compaction", + "com.datastax.oss.driver.api.querybuilder.select", + "com.datastax.oss.driver.api.querybuilder.term", + "com.datastax.oss.driver.api.querybuilder.truncate", + "com.datastax.oss.driver.api.querybuilder.update", + "com.datastax.oss.driver.internal.querybuilder", + "com.datastax.oss.driver.internal.querybuilder.condition", + "com.datastax.oss.driver.internal.querybuilder.delete", + "com.datastax.oss.driver.internal.querybuilder.insert", + "com.datastax.oss.driver.internal.querybuilder.lhs", + "com.datastax.oss.driver.internal.querybuilder.relation", + "com.datastax.oss.driver.internal.querybuilder.schema", + "com.datastax.oss.driver.internal.querybuilder.schema.compaction", + "com.datastax.oss.driver.internal.querybuilder.select", + "com.datastax.oss.driver.internal.querybuilder.term", + "com.datastax.oss.driver.internal.querybuilder.truncate", + "com.datastax.oss.driver.internal.querybuilder.update" + ], + "org.apache.commons:commons-collections4": [ + "org.apache.commons.collections4", + "org.apache.commons.collections4.bag", + "org.apache.commons.collections4.bidimap", + "org.apache.commons.collections4.bloomfilter", + "org.apache.commons.collections4.collection", + "org.apache.commons.collections4.comparators", + "org.apache.commons.collections4.functors", + "org.apache.commons.collections4.iterators", + "org.apache.commons.collections4.keyvalue", + "org.apache.commons.collections4.list", + "org.apache.commons.collections4.map", + "org.apache.commons.collections4.multimap", + "org.apache.commons.collections4.multiset", + "org.apache.commons.collections4.properties", + "org.apache.commons.collections4.queue", + "org.apache.commons.collections4.sequence", + "org.apache.commons.collections4.set", + "org.apache.commons.collections4.splitmap", + "org.apache.commons.collections4.trie", + "org.apache.commons.collections4.trie.analyzer" + ], + "org.apache.commons:commons-compress": [ + "org.apache.commons.compress", + "org.apache.commons.compress.archivers", + "org.apache.commons.compress.archivers.ar", + "org.apache.commons.compress.archivers.arj", + "org.apache.commons.compress.archivers.cpio", + "org.apache.commons.compress.archivers.dump", + "org.apache.commons.compress.archivers.examples", + "org.apache.commons.compress.archivers.jar", + "org.apache.commons.compress.archivers.sevenz", + "org.apache.commons.compress.archivers.tar", + "org.apache.commons.compress.archivers.zip", + "org.apache.commons.compress.changes", + "org.apache.commons.compress.compressors", + "org.apache.commons.compress.compressors.brotli", + "org.apache.commons.compress.compressors.bzip2", + "org.apache.commons.compress.compressors.deflate", + "org.apache.commons.compress.compressors.deflate64", + "org.apache.commons.compress.compressors.gzip", + "org.apache.commons.compress.compressors.lz4", + "org.apache.commons.compress.compressors.lz77support", + "org.apache.commons.compress.compressors.lzma", + "org.apache.commons.compress.compressors.lzw", + "org.apache.commons.compress.compressors.pack200", + "org.apache.commons.compress.compressors.snappy", + "org.apache.commons.compress.compressors.xz", + "org.apache.commons.compress.compressors.z", + "org.apache.commons.compress.compressors.zstandard", + "org.apache.commons.compress.harmony", + "org.apache.commons.compress.harmony.archive.internal.nls", + "org.apache.commons.compress.harmony.pack200", + "org.apache.commons.compress.harmony.unpack200", + "org.apache.commons.compress.harmony.unpack200.bytecode", + "org.apache.commons.compress.harmony.unpack200.bytecode.forms", + "org.apache.commons.compress.java.util.jar", + "org.apache.commons.compress.parallel", + "org.apache.commons.compress.utils" + ], + "org.apache.commons:commons-lang3": [ + "org.apache.commons.lang3", + "org.apache.commons.lang3.arch", + "org.apache.commons.lang3.builder", + "org.apache.commons.lang3.compare", + "org.apache.commons.lang3.concurrent", + "org.apache.commons.lang3.concurrent.locks", + "org.apache.commons.lang3.event", + "org.apache.commons.lang3.exception", + "org.apache.commons.lang3.function", + "org.apache.commons.lang3.math", + "org.apache.commons.lang3.mutable", + "org.apache.commons.lang3.reflect", + "org.apache.commons.lang3.stream", + "org.apache.commons.lang3.text", + "org.apache.commons.lang3.text.translate", + "org.apache.commons.lang3.time", + "org.apache.commons.lang3.tuple", + "org.apache.commons.lang3.util" + ], + "org.apache.logging.log4j:log4j-api": [ + "org.apache.logging.log4j", + "org.apache.logging.log4j.internal", + "org.apache.logging.log4j.internal.annotation", + "org.apache.logging.log4j.internal.map", + "org.apache.logging.log4j.message", + "org.apache.logging.log4j.simple", + "org.apache.logging.log4j.simple.internal", + "org.apache.logging.log4j.spi", + "org.apache.logging.log4j.status", + "org.apache.logging.log4j.util", + "org.apache.logging.log4j.util.internal" + ], + "org.apache.logging.log4j:log4j-to-slf4j": [ + "org.apache.logging.slf4j" + ], + "org.apache.tomcat.embed:tomcat-embed-core": [ + "jakarta.security.auth.message", + "jakarta.security.auth.message.callback", + "jakarta.security.auth.message.config", + "jakarta.security.auth.message.module", + "jakarta.servlet", + "jakarta.servlet.annotation", + "jakarta.servlet.descriptor", + "jakarta.servlet.http", + "org.apache.catalina", + "org.apache.catalina.authenticator", + "org.apache.catalina.authenticator.jaspic", + "org.apache.catalina.connector", + "org.apache.catalina.core", + "org.apache.catalina.deploy", + "org.apache.catalina.filters", + "org.apache.catalina.loader", + "org.apache.catalina.manager", + "org.apache.catalina.manager.host", + "org.apache.catalina.manager.util", + "org.apache.catalina.mapper", + "org.apache.catalina.mbeans", + "org.apache.catalina.realm", + "org.apache.catalina.security", + "org.apache.catalina.servlets", + "org.apache.catalina.session", + "org.apache.catalina.startup", + "org.apache.catalina.users", + "org.apache.catalina.util", + "org.apache.catalina.valves", + "org.apache.catalina.valves.rewrite", + "org.apache.catalina.webresources", + "org.apache.catalina.webresources.war", + "org.apache.coyote", + "org.apache.coyote.ajp", + "org.apache.coyote.http11", + "org.apache.coyote.http11.filters", + "org.apache.coyote.http11.upgrade", + "org.apache.coyote.http2", + "org.apache.juli", + "org.apache.juli.logging", + "org.apache.naming", + "org.apache.naming.factory", + "org.apache.naming.java", + "org.apache.tomcat", + "org.apache.tomcat.jni", + "org.apache.tomcat.util", + "org.apache.tomcat.util.bcel", + "org.apache.tomcat.util.bcel.classfile", + "org.apache.tomcat.util.buf", + "org.apache.tomcat.util.collections", + "org.apache.tomcat.util.compat", + "org.apache.tomcat.util.concurrent", + "org.apache.tomcat.util.descriptor", + "org.apache.tomcat.util.descriptor.tagplugin", + "org.apache.tomcat.util.descriptor.web", + "org.apache.tomcat.util.digester", + "org.apache.tomcat.util.file", + "org.apache.tomcat.util.http", + "org.apache.tomcat.util.http.fileupload", + "org.apache.tomcat.util.http.fileupload.disk", + "org.apache.tomcat.util.http.fileupload.impl", + "org.apache.tomcat.util.http.fileupload.servlet", + "org.apache.tomcat.util.http.fileupload.util", + "org.apache.tomcat.util.http.fileupload.util.mime", + "org.apache.tomcat.util.http.parser", + "org.apache.tomcat.util.json", + "org.apache.tomcat.util.log", + "org.apache.tomcat.util.modeler", + "org.apache.tomcat.util.modeler.modules", + "org.apache.tomcat.util.net", + "org.apache.tomcat.util.net.jsse", + "org.apache.tomcat.util.net.openssl", + "org.apache.tomcat.util.net.openssl.ciphers", + "org.apache.tomcat.util.res", + "org.apache.tomcat.util.scan", + "org.apache.tomcat.util.security", + "org.apache.tomcat.util.threads" + ], + "org.apache.tomcat.embed:tomcat-embed-el": [ + "jakarta.el", + "org.apache.el", + "org.apache.el.lang", + "org.apache.el.parser", + "org.apache.el.stream", + "org.apache.el.util" + ], + "org.apache.tomcat.embed:tomcat-embed-websocket": [ + "jakarta.websocket", + "jakarta.websocket.server", + "org.apache.tomcat.websocket", + "org.apache.tomcat.websocket.pojo", + "org.apache.tomcat.websocket.server" + ], + "org.apiguardian:apiguardian-api": [ + "org.apiguardian.api" + ], + "org.aspectj:aspectjweaver": [ + "aj.org.objectweb.asm", + "aj.org.objectweb.asm.commons", + "aj.org.objectweb.asm.signature", + "org.aspectj.apache.bcel", + "org.aspectj.apache.bcel.classfile", + "org.aspectj.apache.bcel.classfile.annotation", + "org.aspectj.apache.bcel.generic", + "org.aspectj.apache.bcel.util", + "org.aspectj.asm", + "org.aspectj.asm.internal", + "org.aspectj.bridge", + "org.aspectj.bridge.context", + "org.aspectj.internal.lang.annotation", + "org.aspectj.internal.lang.reflect", + "org.aspectj.lang", + "org.aspectj.lang.annotation", + "org.aspectj.lang.annotation.control", + "org.aspectj.lang.internal.lang", + "org.aspectj.lang.reflect", + "org.aspectj.runtime", + "org.aspectj.runtime.internal", + "org.aspectj.runtime.internal.cflowstack", + "org.aspectj.runtime.reflect", + "org.aspectj.util", + "org.aspectj.weaver", + "org.aspectj.weaver.ast", + "org.aspectj.weaver.bcel", + "org.aspectj.weaver.bcel.asm", + "org.aspectj.weaver.internal.tools", + "org.aspectj.weaver.loadtime", + "org.aspectj.weaver.loadtime.definition", + "org.aspectj.weaver.ltw", + "org.aspectj.weaver.model", + "org.aspectj.weaver.patterns", + "org.aspectj.weaver.reflect", + "org.aspectj.weaver.tools", + "org.aspectj.weaver.tools.cache" + ], + "org.assertj:assertj-core": [ + "org.assertj.core.annotation", + "org.assertj.core.annotations", + "org.assertj.core.api", + "org.assertj.core.api.exception", + "org.assertj.core.api.filter", + "org.assertj.core.api.iterable", + "org.assertj.core.api.junit.jupiter", + "org.assertj.core.api.recursive", + "org.assertj.core.api.recursive.assertion", + "org.assertj.core.api.recursive.comparison", + "org.assertj.core.condition", + "org.assertj.core.configuration", + "org.assertj.core.data", + "org.assertj.core.description", + "org.assertj.core.error", + "org.assertj.core.error.array2d", + "org.assertj.core.error.future", + "org.assertj.core.error.uri", + "org.assertj.core.extractor", + "org.assertj.core.groups", + "org.assertj.core.internal", + "org.assertj.core.internal.annotation", + "org.assertj.core.matcher", + "org.assertj.core.presentation", + "org.assertj.core.util", + "org.assertj.core.util.diff", + "org.assertj.core.util.diff.myers", + "org.assertj.core.util.introspection", + "org.assertj.core.util.xml" + ], + "org.awaitility:awaitility": [ + "org.awaitility", + "org.awaitility.classpath", + "org.awaitility.constraint", + "org.awaitility.core", + "org.awaitility.pollinterval", + "org.awaitility.reflect", + "org.awaitility.reflect.exception", + "org.awaitility.spi" + ], + "org.bitbucket.b_c:jose4j": [ + "org.jose4j.base64url", + "org.jose4j.base64url.internal.apache.commons.codec.binary", + "org.jose4j.http", + "org.jose4j.jca", + "org.jose4j.json", + "org.jose4j.json.internal.json_simple", + "org.jose4j.json.internal.json_simple.parser", + "org.jose4j.jwa", + "org.jose4j.jwe", + "org.jose4j.jwe.kdf", + "org.jose4j.jwk", + "org.jose4j.jws", + "org.jose4j.jwt", + "org.jose4j.jwt.consumer", + "org.jose4j.jwx", + "org.jose4j.keys", + "org.jose4j.keys.resolvers", + "org.jose4j.lang", + "org.jose4j.mac", + "org.jose4j.zip" + ], + "org.bouncycastle:bcpkix-jdk18on": [ + "org.bouncycastle.cert", + "org.bouncycastle.cert.bc", + "org.bouncycastle.cert.cmp", + "org.bouncycastle.cert.crmf", + "org.bouncycastle.cert.crmf.bc", + "org.bouncycastle.cert.crmf.jcajce", + "org.bouncycastle.cert.dane", + "org.bouncycastle.cert.dane.fetcher", + "org.bouncycastle.cert.jcajce", + "org.bouncycastle.cert.ocsp", + "org.bouncycastle.cert.ocsp.jcajce", + "org.bouncycastle.cert.path", + "org.bouncycastle.cert.path.validations", + "org.bouncycastle.cert.selector", + "org.bouncycastle.cert.selector.jcajce", + "org.bouncycastle.cmc", + "org.bouncycastle.cms", + "org.bouncycastle.cms.bc", + "org.bouncycastle.cms.jcajce", + "org.bouncycastle.dvcs", + "org.bouncycastle.eac", + "org.bouncycastle.eac.jcajce", + "org.bouncycastle.eac.operator", + "org.bouncycastle.eac.operator.jcajce", + "org.bouncycastle.est", + "org.bouncycastle.est.jcajce", + "org.bouncycastle.its", + "org.bouncycastle.its.bc", + "org.bouncycastle.its.jcajce", + "org.bouncycastle.its.operator", + "org.bouncycastle.mime", + "org.bouncycastle.mime.encoding", + "org.bouncycastle.mime.smime", + "org.bouncycastle.mozilla", + "org.bouncycastle.mozilla.jcajce", + "org.bouncycastle.openssl", + "org.bouncycastle.openssl.bc", + "org.bouncycastle.openssl.jcajce", + "org.bouncycastle.operator", + "org.bouncycastle.operator.bc", + "org.bouncycastle.operator.jcajce", + "org.bouncycastle.pkcs", + "org.bouncycastle.pkcs.bc", + "org.bouncycastle.pkcs.jcajce", + "org.bouncycastle.pkix", + "org.bouncycastle.pkix.jcajce", + "org.bouncycastle.pkix.util", + "org.bouncycastle.pkix.util.filter", + "org.bouncycastle.tsp", + "org.bouncycastle.tsp.cms", + "org.bouncycastle.tsp.ers", + "org.bouncycastle.voms" + ], + "org.bouncycastle:bcprov-jdk18on": [ + "org.bouncycastle", + "org.bouncycastle.asn1", + "org.bouncycastle.asn1.anssi", + "org.bouncycastle.asn1.bc", + "org.bouncycastle.asn1.cryptopro", + "org.bouncycastle.asn1.gm", + "org.bouncycastle.asn1.nist", + "org.bouncycastle.asn1.ocsp", + "org.bouncycastle.asn1.pkcs", + "org.bouncycastle.asn1.sec", + "org.bouncycastle.asn1.teletrust", + "org.bouncycastle.asn1.ua", + "org.bouncycastle.asn1.util", + "org.bouncycastle.asn1.x500", + "org.bouncycastle.asn1.x500.style", + "org.bouncycastle.asn1.x509", + "org.bouncycastle.asn1.x509.qualified", + "org.bouncycastle.asn1.x509.sigi", + "org.bouncycastle.asn1.x9", + "org.bouncycastle.crypto", + "org.bouncycastle.crypto.agreement", + "org.bouncycastle.crypto.agreement.ecjpake", + "org.bouncycastle.crypto.agreement.jpake", + "org.bouncycastle.crypto.agreement.kdf", + "org.bouncycastle.crypto.agreement.srp", + "org.bouncycastle.crypto.commitments", + "org.bouncycastle.crypto.constraints", + "org.bouncycastle.crypto.digests", + "org.bouncycastle.crypto.ec", + "org.bouncycastle.crypto.encodings", + "org.bouncycastle.crypto.engines", + "org.bouncycastle.crypto.examples", + "org.bouncycastle.crypto.fpe", + "org.bouncycastle.crypto.generators", + "org.bouncycastle.crypto.hash2curve", + "org.bouncycastle.crypto.hash2curve.data", + "org.bouncycastle.crypto.hash2curve.impl", + "org.bouncycastle.crypto.hpke", + "org.bouncycastle.crypto.io", + "org.bouncycastle.crypto.kems", + "org.bouncycastle.crypto.kems.mlkem", + "org.bouncycastle.crypto.macs", + "org.bouncycastle.crypto.modes", + "org.bouncycastle.crypto.modes.gcm", + "org.bouncycastle.crypto.modes.kgcm", + "org.bouncycastle.crypto.paddings", + "org.bouncycastle.crypto.params", + "org.bouncycastle.crypto.parsers", + "org.bouncycastle.crypto.prng", + "org.bouncycastle.crypto.prng.drbg", + "org.bouncycastle.crypto.signers", + "org.bouncycastle.crypto.signers.mldsa", + "org.bouncycastle.crypto.signers.slhdsa", + "org.bouncycastle.crypto.threshold", + "org.bouncycastle.crypto.tls", + "org.bouncycastle.crypto.util", + "org.bouncycastle.i18n", + "org.bouncycastle.i18n.filter", + "org.bouncycastle.iana", + "org.bouncycastle.internal.asn1.bsi", + "org.bouncycastle.internal.asn1.cms", + "org.bouncycastle.internal.asn1.cryptlib", + "org.bouncycastle.internal.asn1.eac", + "org.bouncycastle.internal.asn1.edec", + "org.bouncycastle.internal.asn1.gnu", + "org.bouncycastle.internal.asn1.iana", + "org.bouncycastle.internal.asn1.isara", + "org.bouncycastle.internal.asn1.isismtt", + "org.bouncycastle.internal.asn1.iso", + "org.bouncycastle.internal.asn1.kisa", + "org.bouncycastle.internal.asn1.microsoft", + "org.bouncycastle.internal.asn1.misc", + "org.bouncycastle.internal.asn1.nsri", + "org.bouncycastle.internal.asn1.ntt", + "org.bouncycastle.internal.asn1.oiw", + "org.bouncycastle.internal.asn1.rosstandart", + "org.bouncycastle.jcajce", + "org.bouncycastle.jcajce.interfaces", + "org.bouncycastle.jcajce.io", + "org.bouncycastle.jcajce.provider.asymmetric", + "org.bouncycastle.jcajce.provider.asymmetric.compositesignatures", + "org.bouncycastle.jcajce.provider.asymmetric.dh", + "org.bouncycastle.jcajce.provider.asymmetric.dsa", + "org.bouncycastle.jcajce.provider.asymmetric.dstu", + "org.bouncycastle.jcajce.provider.asymmetric.ec", + "org.bouncycastle.jcajce.provider.asymmetric.ecgost", + "org.bouncycastle.jcajce.provider.asymmetric.ecgost12", + "org.bouncycastle.jcajce.provider.asymmetric.edec", + "org.bouncycastle.jcajce.provider.asymmetric.elgamal", + "org.bouncycastle.jcajce.provider.asymmetric.gost", + "org.bouncycastle.jcajce.provider.asymmetric.ies", + "org.bouncycastle.jcajce.provider.asymmetric.mldsa", + "org.bouncycastle.jcajce.provider.asymmetric.mlkem", + "org.bouncycastle.jcajce.provider.asymmetric.rsa", + "org.bouncycastle.jcajce.provider.asymmetric.slhdsa", + "org.bouncycastle.jcajce.provider.asymmetric.util", + "org.bouncycastle.jcajce.provider.asymmetric.x509", + "org.bouncycastle.jcajce.provider.config", + "org.bouncycastle.jcajce.provider.digest", + "org.bouncycastle.jcajce.provider.drbg", + "org.bouncycastle.jcajce.provider.kdf", + "org.bouncycastle.jcajce.provider.kdf.hkdf", + "org.bouncycastle.jcajce.provider.kdf.pbkdf2", + "org.bouncycastle.jcajce.provider.kdf.scrypt", + "org.bouncycastle.jcajce.provider.keystore", + "org.bouncycastle.jcajce.provider.keystore.bc", + "org.bouncycastle.jcajce.provider.keystore.bcfks", + "org.bouncycastle.jcajce.provider.keystore.pkcs12", + "org.bouncycastle.jcajce.provider.keystore.util", + "org.bouncycastle.jcajce.provider.symmetric", + "org.bouncycastle.jcajce.provider.symmetric.util", + "org.bouncycastle.jcajce.provider.util", + "org.bouncycastle.jcajce.spec", + "org.bouncycastle.jcajce.util", + "org.bouncycastle.jce", + "org.bouncycastle.jce.exception", + "org.bouncycastle.jce.interfaces", + "org.bouncycastle.jce.netscape", + "org.bouncycastle.jce.provider", + "org.bouncycastle.jce.spec", + "org.bouncycastle.ldap", + "org.bouncycastle.math", + "org.bouncycastle.math.ec", + "org.bouncycastle.math.ec.custom.djb", + "org.bouncycastle.math.ec.custom.gm", + "org.bouncycastle.math.ec.custom.sec", + "org.bouncycastle.math.ec.endo", + "org.bouncycastle.math.ec.rfc7748", + "org.bouncycastle.math.ec.rfc8032", + "org.bouncycastle.math.ec.tools", + "org.bouncycastle.math.field", + "org.bouncycastle.math.raw", + "org.bouncycastle.pqc.asn1", + "org.bouncycastle.pqc.crypto", + "org.bouncycastle.pqc.crypto.cmce", + "org.bouncycastle.pqc.crypto.crystals.dilithium", + "org.bouncycastle.pqc.crypto.falcon", + "org.bouncycastle.pqc.crypto.frodo", + "org.bouncycastle.pqc.crypto.hqc", + "org.bouncycastle.pqc.crypto.lms", + "org.bouncycastle.pqc.crypto.mayo", + "org.bouncycastle.pqc.crypto.mldsa", + "org.bouncycastle.pqc.crypto.mlkem", + "org.bouncycastle.pqc.crypto.newhope", + "org.bouncycastle.pqc.crypto.ntru", + "org.bouncycastle.pqc.crypto.ntruplus", + "org.bouncycastle.pqc.crypto.ntruprime", + "org.bouncycastle.pqc.crypto.saber", + "org.bouncycastle.pqc.crypto.slhdsa", + "org.bouncycastle.pqc.crypto.snova", + "org.bouncycastle.pqc.crypto.sphincs", + "org.bouncycastle.pqc.crypto.util", + "org.bouncycastle.pqc.crypto.xmss", + "org.bouncycastle.pqc.crypto.xwing", + "org.bouncycastle.pqc.jcajce.interfaces", + "org.bouncycastle.pqc.jcajce.provider", + "org.bouncycastle.pqc.jcajce.provider.bike", + "org.bouncycastle.pqc.jcajce.provider.cmce", + "org.bouncycastle.pqc.jcajce.provider.dilithium", + "org.bouncycastle.pqc.jcajce.provider.falcon", + "org.bouncycastle.pqc.jcajce.provider.frodo", + "org.bouncycastle.pqc.jcajce.provider.hqc", + "org.bouncycastle.pqc.jcajce.provider.kyber", + "org.bouncycastle.pqc.jcajce.provider.lms", + "org.bouncycastle.pqc.jcajce.provider.mayo", + "org.bouncycastle.pqc.jcajce.provider.newhope", + "org.bouncycastle.pqc.jcajce.provider.ntru", + "org.bouncycastle.pqc.jcajce.provider.ntruplus", + "org.bouncycastle.pqc.jcajce.provider.ntruprime", + "org.bouncycastle.pqc.jcajce.provider.picnic", + "org.bouncycastle.pqc.jcajce.provider.saber", + "org.bouncycastle.pqc.jcajce.provider.snova", + "org.bouncycastle.pqc.jcajce.provider.sphincs", + "org.bouncycastle.pqc.jcajce.provider.sphincsplus", + "org.bouncycastle.pqc.jcajce.provider.util", + "org.bouncycastle.pqc.jcajce.provider.xmss", + "org.bouncycastle.pqc.jcajce.spec", + "org.bouncycastle.pqc.legacy.bike", + "org.bouncycastle.pqc.legacy.picnic", + "org.bouncycastle.pqc.legacy.rainbow", + "org.bouncycastle.pqc.legacy.sphincsplus", + "org.bouncycastle.pqc.math.ntru", + "org.bouncycastle.pqc.math.ntru.parameters", + "org.bouncycastle.util", + "org.bouncycastle.util.encoders", + "org.bouncycastle.util.io", + "org.bouncycastle.util.io.pem", + "org.bouncycastle.util.test", + "org.bouncycastle.x509", + "org.bouncycastle.x509.extension", + "org.bouncycastle.x509.util" + ], + "org.bouncycastle:bcprov-lts8on": [ + "org.bouncycastle", + "org.bouncycastle.asn1", + "org.bouncycastle.asn1.anssi", + "org.bouncycastle.asn1.bc", + "org.bouncycastle.asn1.cryptlib", + "org.bouncycastle.asn1.cryptopro", + "org.bouncycastle.asn1.edec", + "org.bouncycastle.asn1.gm", + "org.bouncycastle.asn1.gnu", + "org.bouncycastle.asn1.iana", + "org.bouncycastle.asn1.isara", + "org.bouncycastle.asn1.iso", + "org.bouncycastle.asn1.kisa", + "org.bouncycastle.asn1.microsoft", + "org.bouncycastle.asn1.misc", + "org.bouncycastle.asn1.mozilla", + "org.bouncycastle.asn1.nist", + "org.bouncycastle.asn1.nsri", + "org.bouncycastle.asn1.ntt", + "org.bouncycastle.asn1.ocsp", + "org.bouncycastle.asn1.oiw", + "org.bouncycastle.asn1.pkcs", + "org.bouncycastle.asn1.rosstandart", + "org.bouncycastle.asn1.sec", + "org.bouncycastle.asn1.teletrust", + "org.bouncycastle.asn1.ua", + "org.bouncycastle.asn1.util", + "org.bouncycastle.asn1.x500", + "org.bouncycastle.asn1.x500.style", + "org.bouncycastle.asn1.x509", + "org.bouncycastle.asn1.x509.qualified", + "org.bouncycastle.asn1.x509.sigi", + "org.bouncycastle.asn1.x9", + "org.bouncycastle.crypto", + "org.bouncycastle.crypto.agreement", + "org.bouncycastle.crypto.agreement.ecjpake", + "org.bouncycastle.crypto.agreement.jpake", + "org.bouncycastle.crypto.agreement.kdf", + "org.bouncycastle.crypto.agreement.srp", + "org.bouncycastle.crypto.commitments", + "org.bouncycastle.crypto.constraints", + "org.bouncycastle.crypto.digests", + "org.bouncycastle.crypto.ec", + "org.bouncycastle.crypto.encodings", + "org.bouncycastle.crypto.engines", + "org.bouncycastle.crypto.fpe", + "org.bouncycastle.crypto.generators", + "org.bouncycastle.crypto.hpke", + "org.bouncycastle.crypto.io", + "org.bouncycastle.crypto.kems", + "org.bouncycastle.crypto.macs", + "org.bouncycastle.crypto.modes", + "org.bouncycastle.crypto.modes.gcm", + "org.bouncycastle.crypto.modes.kgcm", + "org.bouncycastle.crypto.paddings", + "org.bouncycastle.crypto.params", + "org.bouncycastle.crypto.parsers", + "org.bouncycastle.crypto.prng", + "org.bouncycastle.crypto.prng.drbg", + "org.bouncycastle.crypto.signers", + "org.bouncycastle.crypto.tls", + "org.bouncycastle.crypto.util", + "org.bouncycastle.iana", + "org.bouncycastle.internal.asn1.bsi", + "org.bouncycastle.internal.asn1.cms", + "org.bouncycastle.internal.asn1.cryptlib", + "org.bouncycastle.internal.asn1.eac", + "org.bouncycastle.internal.asn1.edec", + "org.bouncycastle.internal.asn1.gnu", + "org.bouncycastle.internal.asn1.iana", + "org.bouncycastle.internal.asn1.isara", + "org.bouncycastle.internal.asn1.isismtt", + "org.bouncycastle.internal.asn1.iso", + "org.bouncycastle.internal.asn1.kisa", + "org.bouncycastle.internal.asn1.microsoft", + "org.bouncycastle.internal.asn1.misc", + "org.bouncycastle.internal.asn1.nsri", + "org.bouncycastle.internal.asn1.ntt", + "org.bouncycastle.internal.asn1.oiw", + "org.bouncycastle.internal.asn1.rosstandart", + "org.bouncycastle.jcajce", + "org.bouncycastle.jcajce.interfaces", + "org.bouncycastle.jcajce.io", + "org.bouncycastle.jcajce.provider.asymmetric", + "org.bouncycastle.jcajce.provider.asymmetric.compositesignatures", + "org.bouncycastle.jcajce.provider.asymmetric.dh", + "org.bouncycastle.jcajce.provider.asymmetric.dsa", + "org.bouncycastle.jcajce.provider.asymmetric.dstu", + "org.bouncycastle.jcajce.provider.asymmetric.ec", + "org.bouncycastle.jcajce.provider.asymmetric.ecgost", + "org.bouncycastle.jcajce.provider.asymmetric.ecgost12", + "org.bouncycastle.jcajce.provider.asymmetric.edec", + "org.bouncycastle.jcajce.provider.asymmetric.elgamal", + "org.bouncycastle.jcajce.provider.asymmetric.gost", + "org.bouncycastle.jcajce.provider.asymmetric.ies", + "org.bouncycastle.jcajce.provider.asymmetric.mldsa", + "org.bouncycastle.jcajce.provider.asymmetric.mlkem", + "org.bouncycastle.jcajce.provider.asymmetric.rsa", + "org.bouncycastle.jcajce.provider.asymmetric.slhdsa", + "org.bouncycastle.jcajce.provider.asymmetric.util", + "org.bouncycastle.jcajce.provider.asymmetric.x509", + "org.bouncycastle.jcajce.provider.config", + "org.bouncycastle.jcajce.provider.digest", + "org.bouncycastle.jcajce.provider.drbg", + "org.bouncycastle.jcajce.provider.keystore", + "org.bouncycastle.jcajce.provider.keystore.bc", + "org.bouncycastle.jcajce.provider.keystore.bcfks", + "org.bouncycastle.jcajce.provider.keystore.pkcs12", + "org.bouncycastle.jcajce.provider.keystore.util", + "org.bouncycastle.jcajce.provider.symmetric", + "org.bouncycastle.jcajce.provider.symmetric.util", + "org.bouncycastle.jcajce.provider.util", + "org.bouncycastle.jcajce.spec", + "org.bouncycastle.jcajce.util", + "org.bouncycastle.jce", + "org.bouncycastle.jce.exception", + "org.bouncycastle.jce.interfaces", + "org.bouncycastle.jce.netscape", + "org.bouncycastle.jce.provider", + "org.bouncycastle.jce.spec", + "org.bouncycastle.math", + "org.bouncycastle.math.ec", + "org.bouncycastle.math.ec.custom.djb", + "org.bouncycastle.math.ec.custom.gm", + "org.bouncycastle.math.ec.custom.sec", + "org.bouncycastle.math.ec.endo", + "org.bouncycastle.math.ec.rfc7748", + "org.bouncycastle.math.ec.rfc8032", + "org.bouncycastle.math.ec.tools", + "org.bouncycastle.math.field", + "org.bouncycastle.math.raw", + "org.bouncycastle.pqc.crypto", + "org.bouncycastle.pqc.crypto.lms", + "org.bouncycastle.pqc.crypto.mldsa", + "org.bouncycastle.pqc.crypto.mlkem", + "org.bouncycastle.pqc.crypto.slhdsa", + "org.bouncycastle.pqc.crypto.util", + "org.bouncycastle.pqc.jcajce.interfaces", + "org.bouncycastle.pqc.jcajce.provider.lms", + "org.bouncycastle.pqc.jcajce.provider.util", + "org.bouncycastle.pqc.jcajce.spec", + "org.bouncycastle.util", + "org.bouncycastle.util.dispose", + "org.bouncycastle.util.encoders", + "org.bouncycastle.util.io", + "org.bouncycastle.util.io.pem", + "org.bouncycastle.util.test" + ], + "org.bouncycastle:bcutil-jdk18on": [ + "org.bouncycastle.asn1.bsi", + "org.bouncycastle.asn1.cmc", + "org.bouncycastle.asn1.cmp", + "org.bouncycastle.asn1.cms", + "org.bouncycastle.asn1.cms.ecc", + "org.bouncycastle.asn1.crmf", + "org.bouncycastle.asn1.cryptlib", + "org.bouncycastle.asn1.dvcs", + "org.bouncycastle.asn1.eac", + "org.bouncycastle.asn1.edec", + "org.bouncycastle.asn1.esf", + "org.bouncycastle.asn1.ess", + "org.bouncycastle.asn1.est", + "org.bouncycastle.asn1.gnu", + "org.bouncycastle.asn1.iana", + "org.bouncycastle.asn1.icao", + "org.bouncycastle.asn1.isara", + "org.bouncycastle.asn1.isismtt", + "org.bouncycastle.asn1.isismtt.ocsp", + "org.bouncycastle.asn1.isismtt.x509", + "org.bouncycastle.asn1.iso", + "org.bouncycastle.asn1.kisa", + "org.bouncycastle.asn1.microsoft", + "org.bouncycastle.asn1.misc", + "org.bouncycastle.asn1.mozilla", + "org.bouncycastle.asn1.nsri", + "org.bouncycastle.asn1.ntt", + "org.bouncycastle.asn1.oiw", + "org.bouncycastle.asn1.rosstandart", + "org.bouncycastle.asn1.smime", + "org.bouncycastle.asn1.tsp", + "org.bouncycastle.oer", + "org.bouncycastle.oer.its", + "org.bouncycastle.oer.its.etsi102941", + "org.bouncycastle.oer.its.etsi102941.basetypes", + "org.bouncycastle.oer.its.etsi103097", + "org.bouncycastle.oer.its.etsi103097.extension", + "org.bouncycastle.oer.its.ieee1609dot2", + "org.bouncycastle.oer.its.ieee1609dot2.basetypes", + "org.bouncycastle.oer.its.ieee1609dot2dot1", + "org.bouncycastle.oer.its.template.etsi102941", + "org.bouncycastle.oer.its.template.etsi102941.basetypes", + "org.bouncycastle.oer.its.template.etsi103097", + "org.bouncycastle.oer.its.template.etsi103097.extension", + "org.bouncycastle.oer.its.template.ieee1609dot2", + "org.bouncycastle.oer.its.template.ieee1609dot2.basetypes", + "org.bouncycastle.oer.its.template.ieee1609dot2dot1" + ], + "org.checkerframework:checker-qual": [ + "org.checkerframework.checker.builder.qual", + "org.checkerframework.checker.calledmethods.qual", + "org.checkerframework.checker.compilermsgs.qual", + "org.checkerframework.checker.fenum.qual", + "org.checkerframework.checker.formatter.qual", + "org.checkerframework.checker.guieffect.qual", + "org.checkerframework.checker.i18n.qual", + "org.checkerframework.checker.i18nformatter.qual", + "org.checkerframework.checker.index.qual", + "org.checkerframework.checker.initialization.qual", + "org.checkerframework.checker.interning.qual", + "org.checkerframework.checker.lock.qual", + "org.checkerframework.checker.mustcall.qual", + "org.checkerframework.checker.nullness.qual", + "org.checkerframework.checker.optional.qual", + "org.checkerframework.checker.propkey.qual", + "org.checkerframework.checker.regex.qual", + "org.checkerframework.checker.signature.qual", + "org.checkerframework.checker.signedness.qual", + "org.checkerframework.checker.tainting.qual", + "org.checkerframework.checker.units.qual", + "org.checkerframework.common.aliasing.qual", + "org.checkerframework.common.initializedfields.qual", + "org.checkerframework.common.reflection.qual", + "org.checkerframework.common.returnsreceiver.qual", + "org.checkerframework.common.subtyping.qual", + "org.checkerframework.common.util.report.qual", + "org.checkerframework.common.value.qual", + "org.checkerframework.dataflow.qual", + "org.checkerframework.framework.qual" + ], + "org.codehaus.mojo:animal-sniffer-annotations": [ + "org.codehaus.mojo.animal_sniffer" + ], + "org.hamcrest:hamcrest": [ + "org.hamcrest", + "org.hamcrest.beans", + "org.hamcrest.collection", + "org.hamcrest.comparator", + "org.hamcrest.core", + "org.hamcrest.internal", + "org.hamcrest.io", + "org.hamcrest.number", + "org.hamcrest.object", + "org.hamcrest.text", + "org.hamcrest.xml" + ], + "org.hdrhistogram:HdrHistogram": [ + "org.HdrHistogram", + "org.HdrHistogram.packedarray" + ], + "org.hibernate.validator:hibernate-validator": [ + "org.hibernate.validator", + "org.hibernate.validator.cfg", + "org.hibernate.validator.cfg.context", + "org.hibernate.validator.cfg.defs", + "org.hibernate.validator.cfg.defs.br", + "org.hibernate.validator.cfg.defs.kor", + "org.hibernate.validator.cfg.defs.pl", + "org.hibernate.validator.cfg.defs.ru", + "org.hibernate.validator.constraints", + "org.hibernate.validator.constraints.br", + "org.hibernate.validator.constraints.kor", + "org.hibernate.validator.constraints.pl", + "org.hibernate.validator.constraints.ru", + "org.hibernate.validator.constraints.time", + "org.hibernate.validator.constraintvalidation", + "org.hibernate.validator.constraintvalidation.spi", + "org.hibernate.validator.constraintvalidators", + "org.hibernate.validator.engine", + "org.hibernate.validator.group", + "org.hibernate.validator.internal", + "org.hibernate.validator.internal.cfg", + "org.hibernate.validator.internal.cfg.context", + "org.hibernate.validator.internal.constraintvalidators", + "org.hibernate.validator.internal.constraintvalidators.bv", + "org.hibernate.validator.internal.constraintvalidators.bv.money", + "org.hibernate.validator.internal.constraintvalidators.bv.notempty", + "org.hibernate.validator.internal.constraintvalidators.bv.number", + "org.hibernate.validator.internal.constraintvalidators.bv.number.bound", + "org.hibernate.validator.internal.constraintvalidators.bv.number.bound.decimal", + "org.hibernate.validator.internal.constraintvalidators.bv.number.sign", + "org.hibernate.validator.internal.constraintvalidators.bv.size", + "org.hibernate.validator.internal.constraintvalidators.bv.time", + "org.hibernate.validator.internal.constraintvalidators.bv.time.future", + "org.hibernate.validator.internal.constraintvalidators.bv.time.futureorpresent", + "org.hibernate.validator.internal.constraintvalidators.bv.time.past", + "org.hibernate.validator.internal.constraintvalidators.bv.time.pastorpresent", + "org.hibernate.validator.internal.constraintvalidators.hv", + "org.hibernate.validator.internal.constraintvalidators.hv.br", + "org.hibernate.validator.internal.constraintvalidators.hv.kor", + "org.hibernate.validator.internal.constraintvalidators.hv.pl", + "org.hibernate.validator.internal.constraintvalidators.hv.ru", + "org.hibernate.validator.internal.constraintvalidators.hv.time", + "org.hibernate.validator.internal.engine", + "org.hibernate.validator.internal.engine.constraintdefinition", + "org.hibernate.validator.internal.engine.constraintvalidation", + "org.hibernate.validator.internal.engine.groups", + "org.hibernate.validator.internal.engine.messageinterpolation", + "org.hibernate.validator.internal.engine.messageinterpolation.el", + "org.hibernate.validator.internal.engine.messageinterpolation.parser", + "org.hibernate.validator.internal.engine.messageinterpolation.util", + "org.hibernate.validator.internal.engine.path", + "org.hibernate.validator.internal.engine.resolver", + "org.hibernate.validator.internal.engine.scripting", + "org.hibernate.validator.internal.engine.validationcontext", + "org.hibernate.validator.internal.engine.valuecontext", + "org.hibernate.validator.internal.engine.valueextraction", + "org.hibernate.validator.internal.metadata", + "org.hibernate.validator.internal.metadata.aggregated", + "org.hibernate.validator.internal.metadata.aggregated.rule", + "org.hibernate.validator.internal.metadata.core", + "org.hibernate.validator.internal.metadata.descriptor", + "org.hibernate.validator.internal.metadata.facets", + "org.hibernate.validator.internal.metadata.location", + "org.hibernate.validator.internal.metadata.provider", + "org.hibernate.validator.internal.metadata.raw", + "org.hibernate.validator.internal.properties", + "org.hibernate.validator.internal.properties.javabean", + "org.hibernate.validator.internal.util", + "org.hibernate.validator.internal.util.actions", + "org.hibernate.validator.internal.util.annotation", + "org.hibernate.validator.internal.util.classhierarchy", + "org.hibernate.validator.internal.util.logging", + "org.hibernate.validator.internal.util.logging.formatter", + "org.hibernate.validator.internal.util.stereotypes", + "org.hibernate.validator.internal.xml", + "org.hibernate.validator.internal.xml.config", + "org.hibernate.validator.internal.xml.mapping", + "org.hibernate.validator.messageinterpolation", + "org.hibernate.validator.metadata", + "org.hibernate.validator.parameternameprovider", + "org.hibernate.validator.path", + "org.hibernate.validator.resourceloading", + "org.hibernate.validator.spi.cfg", + "org.hibernate.validator.spi.group", + "org.hibernate.validator.spi.messageinterpolation", + "org.hibernate.validator.spi.nodenameprovider", + "org.hibernate.validator.spi.properties", + "org.hibernate.validator.spi.resourceloading", + "org.hibernate.validator.spi.scripting" + ], + "org.jacoco:org.jacoco.agent:jar:runtime": [ + "com.vladium.emma.rt", + "org.jacoco.agent.rt", + "org.jacoco.agent.rt.internal_29a6edd", + "org.jacoco.agent.rt.internal_29a6edd.asm", + "org.jacoco.agent.rt.internal_29a6edd.asm.commons", + "org.jacoco.agent.rt.internal_29a6edd.asm.tree", + "org.jacoco.agent.rt.internal_29a6edd.core", + "org.jacoco.agent.rt.internal_29a6edd.core.analysis", + "org.jacoco.agent.rt.internal_29a6edd.core.data", + "org.jacoco.agent.rt.internal_29a6edd.core.instr", + "org.jacoco.agent.rt.internal_29a6edd.core.internal", + "org.jacoco.agent.rt.internal_29a6edd.core.internal.analysis", + "org.jacoco.agent.rt.internal_29a6edd.core.internal.analysis.filter", + "org.jacoco.agent.rt.internal_29a6edd.core.internal.data", + "org.jacoco.agent.rt.internal_29a6edd.core.internal.flow", + "org.jacoco.agent.rt.internal_29a6edd.core.internal.instr", + "org.jacoco.agent.rt.internal_29a6edd.core.runtime", + "org.jacoco.agent.rt.internal_29a6edd.core.tools", + "org.jacoco.agent.rt.internal_29a6edd.output" + ], + "org.jacoco:org.jacoco.cli": [ + "org.jacoco.cli.internal", + "org.jacoco.cli.internal.commands" + ], + "org.jacoco:org.jacoco.core": [ + "org.jacoco.core", + "org.jacoco.core.analysis", + "org.jacoco.core.data", + "org.jacoco.core.instr", + "org.jacoco.core.internal", + "org.jacoco.core.internal.analysis", + "org.jacoco.core.internal.analysis.filter", + "org.jacoco.core.internal.data", + "org.jacoco.core.internal.flow", + "org.jacoco.core.internal.instr", + "org.jacoco.core.runtime", + "org.jacoco.core.tools" + ], + "org.jacoco:org.jacoco.report": [ + "org.jacoco.report", + "org.jacoco.report.check", + "org.jacoco.report.csv", + "org.jacoco.report.html", + "org.jacoco.report.internal", + "org.jacoco.report.internal.html", + "org.jacoco.report.internal.html.index", + "org.jacoco.report.internal.html.page", + "org.jacoco.report.internal.html.resources", + "org.jacoco.report.internal.html.table", + "org.jacoco.report.internal.xml", + "org.jacoco.report.xml" + ], + "org.jboss.logging:jboss-logging": [ + "org.jboss.logging" + ], + "org.jetbrains.kotlin:kotlin-stdlib": [ + "kotlin", + "kotlin.annotation", + "kotlin.collections", + "kotlin.collections.builders", + "kotlin.collections.jdk8", + "kotlin.collections.unsigned", + "kotlin.comparisons", + "kotlin.concurrent", + "kotlin.concurrent.atomics", + "kotlin.concurrent.internal", + "kotlin.contracts", + "kotlin.coroutines", + "kotlin.coroutines.cancellation", + "kotlin.coroutines.intrinsics", + "kotlin.coroutines.jvm.internal", + "kotlin.enums", + "kotlin.experimental", + "kotlin.internal", + "kotlin.internal.jdk7", + "kotlin.internal.jdk8", + "kotlin.io", + "kotlin.io.encoding", + "kotlin.io.path", + "kotlin.jdk7", + "kotlin.js", + "kotlin.jvm", + "kotlin.jvm.functions", + "kotlin.jvm.internal", + "kotlin.jvm.internal.markers", + "kotlin.jvm.internal.unsafe", + "kotlin.jvm.jdk8", + "kotlin.jvm.optionals", + "kotlin.math", + "kotlin.properties", + "kotlin.random", + "kotlin.random.jdk8", + "kotlin.ranges", + "kotlin.reflect", + "kotlin.sequences", + "kotlin.streams.jdk8", + "kotlin.system", + "kotlin.text", + "kotlin.text.jdk8", + "kotlin.time", + "kotlin.time.jdk8", + "kotlin.uuid" + ], + "org.jetbrains:annotations": [ + "org.intellij.lang.annotations", + "org.jetbrains.annotations" + ], + "org.jspecify:jspecify": [ + "org.jspecify.annotations" + ], + "org.junit.jupiter:junit-jupiter-api": [ + "org.junit.jupiter.api", + "org.junit.jupiter.api.condition", + "org.junit.jupiter.api.extension", + "org.junit.jupiter.api.extension.support", + "org.junit.jupiter.api.function", + "org.junit.jupiter.api.io", + "org.junit.jupiter.api.parallel", + "org.junit.jupiter.api.util" + ], + "org.junit.jupiter:junit-jupiter-engine": [ + "org.junit.jupiter.engine", + "org.junit.jupiter.engine.config", + "org.junit.jupiter.engine.descriptor", + "org.junit.jupiter.engine.discovery", + "org.junit.jupiter.engine.discovery.predicates", + "org.junit.jupiter.engine.execution", + "org.junit.jupiter.engine.extension", + "org.junit.jupiter.engine.support" + ], + "org.junit.jupiter:junit-jupiter-params": [ + "org.junit.jupiter.params", + "org.junit.jupiter.params.aggregator", + "org.junit.jupiter.params.converter", + "org.junit.jupiter.params.provider", + "org.junit.jupiter.params.shadow.de.siegmar.fastcsv.reader", + "org.junit.jupiter.params.shadow.de.siegmar.fastcsv.util", + "org.junit.jupiter.params.shadow.de.siegmar.fastcsv.writer", + "org.junit.jupiter.params.support" + ], + "org.junit.platform:junit-platform-commons": [ + "org.junit.platform.commons", + "org.junit.platform.commons.annotation", + "org.junit.platform.commons.function", + "org.junit.platform.commons.io", + "org.junit.platform.commons.logging", + "org.junit.platform.commons.support", + "org.junit.platform.commons.support.conversion", + "org.junit.platform.commons.support.scanning", + "org.junit.platform.commons.util" + ], + "org.junit.platform:junit-platform-console-standalone": [ + "junit.extensions", + "junit.framework", + "junit.runner", + "junit.textui", + "org.apiguardian.api", + "org.hamcrest", + "org.hamcrest.core", + "org.hamcrest.internal", + "org.junit", + "org.junit.experimental", + "org.junit.experimental.categories", + "org.junit.experimental.max", + "org.junit.experimental.results", + "org.junit.experimental.runners", + "org.junit.experimental.theories", + "org.junit.experimental.theories.internal", + "org.junit.experimental.theories.suppliers", + "org.junit.function", + "org.junit.internal", + "org.junit.internal.builders", + "org.junit.internal.management", + "org.junit.internal.matchers", + "org.junit.internal.requests", + "org.junit.internal.runners", + "org.junit.internal.runners.model", + "org.junit.internal.runners.rules", + "org.junit.internal.runners.statements", + "org.junit.jupiter.api", + "org.junit.jupiter.api.condition", + "org.junit.jupiter.api.extension", + "org.junit.jupiter.api.extension.support", + "org.junit.jupiter.api.function", + "org.junit.jupiter.api.io", + "org.junit.jupiter.api.parallel", + "org.junit.jupiter.api.util", + "org.junit.jupiter.engine", + "org.junit.jupiter.engine.config", + "org.junit.jupiter.engine.descriptor", + "org.junit.jupiter.engine.discovery", + "org.junit.jupiter.engine.discovery.predicates", + "org.junit.jupiter.engine.execution", + "org.junit.jupiter.engine.extension", + "org.junit.jupiter.engine.support", + "org.junit.jupiter.params", + "org.junit.jupiter.params.aggregator", + "org.junit.jupiter.params.converter", + "org.junit.jupiter.params.provider", + "org.junit.jupiter.params.shadow.de.siegmar.fastcsv.reader", + "org.junit.jupiter.params.shadow.de.siegmar.fastcsv.util", + "org.junit.jupiter.params.shadow.de.siegmar.fastcsv.writer", + "org.junit.jupiter.params.support", + "org.junit.matchers", + "org.junit.platform.commons", + "org.junit.platform.commons.annotation", + "org.junit.platform.commons.function", + "org.junit.platform.commons.io", + "org.junit.platform.commons.logging", + "org.junit.platform.commons.support", + "org.junit.platform.commons.support.conversion", + "org.junit.platform.commons.support.scanning", + "org.junit.platform.commons.util", + "org.junit.platform.console", + "org.junit.platform.console.command", + "org.junit.platform.console.options", + "org.junit.platform.console.output", + "org.junit.platform.console.shadow.picocli", + "org.junit.platform.engine", + "org.junit.platform.engine.discovery", + "org.junit.platform.engine.reporting", + "org.junit.platform.engine.support.config", + "org.junit.platform.engine.support.descriptor", + "org.junit.platform.engine.support.discovery", + "org.junit.platform.engine.support.hierarchical", + "org.junit.platform.engine.support.store", + "org.junit.platform.launcher", + "org.junit.platform.launcher.core", + "org.junit.platform.launcher.jfr", + "org.junit.platform.launcher.listeners", + "org.junit.platform.launcher.listeners.discovery", + "org.junit.platform.launcher.listeners.session", + "org.junit.platform.launcher.tagexpression", + "org.junit.platform.reporting", + "org.junit.platform.reporting.legacy", + "org.junit.platform.reporting.legacy.xml", + "org.junit.platform.reporting.open.xml", + "org.junit.platform.reporting.shadow.org.opentest4j.reporting.events.api", + "org.junit.platform.reporting.shadow.org.opentest4j.reporting.events.core", + "org.junit.platform.reporting.shadow.org.opentest4j.reporting.events.git", + "org.junit.platform.reporting.shadow.org.opentest4j.reporting.events.java", + "org.junit.platform.reporting.shadow.org.opentest4j.reporting.events.root", + "org.junit.platform.reporting.shadow.org.opentest4j.reporting.schema", + "org.junit.platform.suite.api", + "org.junit.platform.suite.engine", + "org.junit.rules", + "org.junit.runner", + "org.junit.runner.manipulation", + "org.junit.runner.notification", + "org.junit.runners", + "org.junit.runners.model", + "org.junit.runners.parameterized", + "org.junit.validator", + "org.junit.vintage.engine", + "org.junit.vintage.engine.descriptor", + "org.junit.vintage.engine.discovery", + "org.junit.vintage.engine.execution", + "org.junit.vintage.engine.support", + "org.opentest4j", + "org.opentest4j.reporting.tooling.spi.htmlreport" + ], + "org.junit.platform:junit-platform-engine": [ + "org.junit.platform.engine", + "org.junit.platform.engine.discovery", + "org.junit.platform.engine.reporting", + "org.junit.platform.engine.support.config", + "org.junit.platform.engine.support.descriptor", + "org.junit.platform.engine.support.discovery", + "org.junit.platform.engine.support.hierarchical", + "org.junit.platform.engine.support.store" + ], + "org.junit.platform:junit-platform-launcher": [ + "org.junit.platform.launcher", + "org.junit.platform.launcher.core", + "org.junit.platform.launcher.jfr", + "org.junit.platform.launcher.listeners", + "org.junit.platform.launcher.listeners.discovery", + "org.junit.platform.launcher.listeners.session", + "org.junit.platform.launcher.tagexpression" + ], + "org.junit.platform:junit-platform-reporting": [ + "org.junit.platform.reporting", + "org.junit.platform.reporting.legacy", + "org.junit.platform.reporting.legacy.xml", + "org.junit.platform.reporting.open.xml", + "org.junit.platform.reporting.shadow.org.opentest4j.reporting.events.api", + "org.junit.platform.reporting.shadow.org.opentest4j.reporting.events.core", + "org.junit.platform.reporting.shadow.org.opentest4j.reporting.events.git", + "org.junit.platform.reporting.shadow.org.opentest4j.reporting.events.java", + "org.junit.platform.reporting.shadow.org.opentest4j.reporting.events.root", + "org.junit.platform.reporting.shadow.org.opentest4j.reporting.schema" + ], + "org.latencyutils:LatencyUtils": [ + "org.LatencyUtils" + ], + "org.mockito:mockito-core": [ + "org.mockito", + "org.mockito.configuration", + "org.mockito.creation.instance", + "org.mockito.exceptions.base", + "org.mockito.exceptions.misusing", + "org.mockito.exceptions.stacktrace", + "org.mockito.exceptions.verification", + "org.mockito.exceptions.verification.junit", + "org.mockito.exceptions.verification.opentest4j", + "org.mockito.hamcrest", + "org.mockito.internal", + "org.mockito.internal.configuration", + "org.mockito.internal.configuration.injection", + "org.mockito.internal.configuration.injection.filter", + "org.mockito.internal.configuration.injection.scanner", + "org.mockito.internal.configuration.plugins", + "org.mockito.internal.creation", + "org.mockito.internal.creation.bytebuddy", + "org.mockito.internal.creation.bytebuddy.access", + "org.mockito.internal.creation.bytebuddy.codegen", + "org.mockito.internal.creation.instance", + "org.mockito.internal.creation.proxy", + "org.mockito.internal.creation.settings", + "org.mockito.internal.creation.util", + "org.mockito.internal.debugging", + "org.mockito.internal.exceptions", + "org.mockito.internal.exceptions.stacktrace", + "org.mockito.internal.exceptions.util", + "org.mockito.internal.framework", + "org.mockito.internal.hamcrest", + "org.mockito.internal.handler", + "org.mockito.internal.invocation", + "org.mockito.internal.invocation.finder", + "org.mockito.internal.invocation.mockref", + "org.mockito.internal.junit", + "org.mockito.internal.listeners", + "org.mockito.internal.matchers", + "org.mockito.internal.matchers.apachecommons", + "org.mockito.internal.matchers.text", + "org.mockito.internal.progress", + "org.mockito.internal.reporting", + "org.mockito.internal.runners", + "org.mockito.internal.runners.util", + "org.mockito.internal.session", + "org.mockito.internal.stubbing", + "org.mockito.internal.stubbing.answers", + "org.mockito.internal.stubbing.defaultanswers", + "org.mockito.internal.util", + "org.mockito.internal.util.collections", + "org.mockito.internal.util.concurrent", + "org.mockito.internal.util.io", + "org.mockito.internal.util.reflection", + "org.mockito.internal.verification", + "org.mockito.internal.verification.api", + "org.mockito.internal.verification.argumentmatching", + "org.mockito.internal.verification.checkers", + "org.mockito.invocation", + "org.mockito.junit", + "org.mockito.listeners", + "org.mockito.mock", + "org.mockito.plugins", + "org.mockito.quality", + "org.mockito.session", + "org.mockito.stubbing", + "org.mockito.verification" + ], + "org.mockito:mockito-junit-jupiter": [ + "org.mockito.junit.jupiter", + "org.mockito.junit.jupiter.resolver" + ], + "org.objenesis:objenesis": [ + "org.objenesis", + "org.objenesis.instantiator", + "org.objenesis.instantiator.android", + "org.objenesis.instantiator.annotations", + "org.objenesis.instantiator.basic", + "org.objenesis.instantiator.gcj", + "org.objenesis.instantiator.perc", + "org.objenesis.instantiator.sun", + "org.objenesis.instantiator.util", + "org.objenesis.strategy" + ], + "org.opentest4j.reporting:open-test-reporting-tooling-spi": [ + "org.opentest4j.reporting.tooling.spi.htmlreport" + ], + "org.opentest4j:opentest4j": [ + "org.opentest4j" + ], + "org.ow2.asm:asm": [ + "org.objectweb.asm", + "org.objectweb.asm.signature" + ], + "org.ow2.asm:asm-analysis": [ + "org.objectweb.asm.tree.analysis" + ], + "org.ow2.asm:asm-commons": [ + "org.objectweb.asm.commons" + ], + "org.ow2.asm:asm-tree": [ + "org.objectweb.asm.tree" + ], + "org.ow2.asm:asm-util": [ + "org.objectweb.asm.util" + ], + "org.projectlombok:lombok": [ + "lombok", + "lombok.delombok.ant", + "lombok.experimental", + "lombok.extern.apachecommons", + "lombok.extern.flogger", + "lombok.extern.jackson", + "lombok.extern.java", + "lombok.extern.jbosslog", + "lombok.extern.log4j", + "lombok.extern.slf4j", + "lombok.javac.apt", + "lombok.launch" + ], + "org.reactivestreams:reactive-streams": [ + "org.reactivestreams" + ], + "org.rnorth.duct-tape:duct-tape": [ + "org.rnorth.ducttape", + "org.rnorth.ducttape.circuitbreakers", + "org.rnorth.ducttape.inconsistents", + "org.rnorth.ducttape.ratelimits", + "org.rnorth.ducttape.timeouts", + "org.rnorth.ducttape.unreliables" + ], + "org.skyscreamer:jsonassert": [ + "org.json", + "org.skyscreamer.jsonassert", + "org.skyscreamer.jsonassert.comparator" + ], + "org.slf4j:jul-to-slf4j": [ + "org.slf4j.bridge" + ], + "org.slf4j:slf4j-api": [ + "org.slf4j", + "org.slf4j.event", + "org.slf4j.helpers", + "org.slf4j.spi" + ], + "org.springdoc:springdoc-openapi-starter-common": [ + "org.springdoc.api", + "org.springdoc.core.annotations", + "org.springdoc.core.conditions", + "org.springdoc.core.configuration", + "org.springdoc.core.configuration.hints", + "org.springdoc.core.configuration.oauth2", + "org.springdoc.core.configurer", + "org.springdoc.core.converters", + "org.springdoc.core.converters.models", + "org.springdoc.core.customizers", + "org.springdoc.core.data", + "org.springdoc.core.discoverer", + "org.springdoc.core.events", + "org.springdoc.core.extractor", + "org.springdoc.core.filters", + "org.springdoc.core.fn", + "org.springdoc.core.fn.builders.apiresponse", + "org.springdoc.core.fn.builders.arrayschema", + "org.springdoc.core.fn.builders.content", + "org.springdoc.core.fn.builders.discriminatormapping", + "org.springdoc.core.fn.builders.encoding", + "org.springdoc.core.fn.builders.exampleobject", + "org.springdoc.core.fn.builders.extension", + "org.springdoc.core.fn.builders.extensionproperty", + "org.springdoc.core.fn.builders.externaldocumentation", + "org.springdoc.core.fn.builders.header", + "org.springdoc.core.fn.builders.link", + "org.springdoc.core.fn.builders.linkparameter", + "org.springdoc.core.fn.builders.operation", + "org.springdoc.core.fn.builders.parameter", + "org.springdoc.core.fn.builders.requestbody", + "org.springdoc.core.fn.builders.schema", + "org.springdoc.core.fn.builders.securityrequirement", + "org.springdoc.core.fn.builders.server", + "org.springdoc.core.fn.builders.servervariable", + "org.springdoc.core.mixins", + "org.springdoc.core.models", + "org.springdoc.core.properties", + "org.springdoc.core.providers", + "org.springdoc.core.service", + "org.springdoc.core.utils", + "org.springdoc.core.versions", + "org.springdoc.scalar", + "org.springdoc.ui" + ], + "org.springdoc:springdoc-openapi-starter-webflux-api": [ + "org.springdoc.webflux.api", + "org.springdoc.webflux.core.configuration", + "org.springdoc.webflux.core.configuration.hints", + "org.springdoc.webflux.core.fn", + "org.springdoc.webflux.core.providers", + "org.springdoc.webflux.core.service", + "org.springdoc.webflux.core.visitor" + ], + "org.springdoc:springdoc-openapi-starter-webmvc-api": [ + "org.springdoc.webmvc.api", + "org.springdoc.webmvc.core.configuration", + "org.springdoc.webmvc.core.configuration.hints", + "org.springdoc.webmvc.core.fn", + "org.springdoc.webmvc.core.providers", + "org.springdoc.webmvc.core.service" + ], + "org.springframework.boot:spring-boot": [ + "org.springframework.boot", + "org.springframework.boot.admin", + "org.springframework.boot.ansi", + "org.springframework.boot.availability", + "org.springframework.boot.bootstrap", + "org.springframework.boot.builder", + "org.springframework.boot.cloud", + "org.springframework.boot.context", + "org.springframework.boot.context.annotation", + "org.springframework.boot.context.config", + "org.springframework.boot.context.event", + "org.springframework.boot.context.logging", + "org.springframework.boot.context.metrics.buffering", + "org.springframework.boot.context.properties", + "org.springframework.boot.context.properties.bind", + "org.springframework.boot.context.properties.bind.handler", + "org.springframework.boot.context.properties.bind.validation", + "org.springframework.boot.context.properties.source", + "org.springframework.boot.convert", + "org.springframework.boot.diagnostics", + "org.springframework.boot.diagnostics.analyzer", + "org.springframework.boot.env", + "org.springframework.boot.info", + "org.springframework.boot.io", + "org.springframework.boot.json", + "org.springframework.boot.logging", + "org.springframework.boot.logging.java", + "org.springframework.boot.logging.log4j2", + "org.springframework.boot.logging.logback", + "org.springframework.boot.logging.structured", + "org.springframework.boot.origin", + "org.springframework.boot.retry", + "org.springframework.boot.ssl", + "org.springframework.boot.ssl.jks", + "org.springframework.boot.ssl.pem", + "org.springframework.boot.support", + "org.springframework.boot.system", + "org.springframework.boot.task", + "org.springframework.boot.thread", + "org.springframework.boot.util", + "org.springframework.boot.validation", + "org.springframework.boot.validation.beanvalidation", + "org.springframework.boot.web.context.reactive", + "org.springframework.boot.web.context.servlet", + "org.springframework.boot.web.error", + "org.springframework.boot.web.servlet", + "org.springframework.boot.web.servlet.support" + ], + "org.springframework.boot:spring-boot-actuator": [ + "org.springframework.boot.actuate.audit", + "org.springframework.boot.actuate.audit.listener", + "org.springframework.boot.actuate.beans", + "org.springframework.boot.actuate.context", + "org.springframework.boot.actuate.context.properties", + "org.springframework.boot.actuate.endpoint", + "org.springframework.boot.actuate.endpoint.annotation", + "org.springframework.boot.actuate.endpoint.invoke", + "org.springframework.boot.actuate.endpoint.invoke.convert", + "org.springframework.boot.actuate.endpoint.invoke.reflect", + "org.springframework.boot.actuate.endpoint.invoker.cache", + "org.springframework.boot.actuate.endpoint.jackson", + "org.springframework.boot.actuate.endpoint.jmx", + "org.springframework.boot.actuate.endpoint.jmx.annotation", + "org.springframework.boot.actuate.endpoint.web", + "org.springframework.boot.actuate.endpoint.web.annotation", + "org.springframework.boot.actuate.env", + "org.springframework.boot.actuate.info", + "org.springframework.boot.actuate.logging", + "org.springframework.boot.actuate.management", + "org.springframework.boot.actuate.sbom", + "org.springframework.boot.actuate.scheduling", + "org.springframework.boot.actuate.security", + "org.springframework.boot.actuate.startup", + "org.springframework.boot.actuate.web.exchanges", + "org.springframework.boot.actuate.web.mappings" + ], + "org.springframework.boot:spring-boot-actuator-autoconfigure": [ + "org.springframework.boot.actuate.autoconfigure", + "org.springframework.boot.actuate.autoconfigure.audit", + "org.springframework.boot.actuate.autoconfigure.beans", + "org.springframework.boot.actuate.autoconfigure.condition", + "org.springframework.boot.actuate.autoconfigure.context", + "org.springframework.boot.actuate.autoconfigure.context.properties", + "org.springframework.boot.actuate.autoconfigure.endpoint", + "org.springframework.boot.actuate.autoconfigure.endpoint.condition", + "org.springframework.boot.actuate.autoconfigure.endpoint.expose", + "org.springframework.boot.actuate.autoconfigure.endpoint.jackson", + "org.springframework.boot.actuate.autoconfigure.endpoint.jmx", + "org.springframework.boot.actuate.autoconfigure.endpoint.web", + "org.springframework.boot.actuate.autoconfigure.env", + "org.springframework.boot.actuate.autoconfigure.info", + "org.springframework.boot.actuate.autoconfigure.logging", + "org.springframework.boot.actuate.autoconfigure.management", + "org.springframework.boot.actuate.autoconfigure.sbom", + "org.springframework.boot.actuate.autoconfigure.scheduling", + "org.springframework.boot.actuate.autoconfigure.startup", + "org.springframework.boot.actuate.autoconfigure.web", + "org.springframework.boot.actuate.autoconfigure.web.exchanges", + "org.springframework.boot.actuate.autoconfigure.web.mappings", + "org.springframework.boot.actuate.autoconfigure.web.server" + ], + "org.springframework.boot:spring-boot-autoconfigure": [ + "org.springframework.boot.autoconfigure", + "org.springframework.boot.autoconfigure.admin", + "org.springframework.boot.autoconfigure.aop", + "org.springframework.boot.autoconfigure.availability", + "org.springframework.boot.autoconfigure.cache", + "org.springframework.boot.autoconfigure.condition", + "org.springframework.boot.autoconfigure.container", + "org.springframework.boot.autoconfigure.context", + "org.springframework.boot.autoconfigure.data", + "org.springframework.boot.autoconfigure.diagnostics.analyzer", + "org.springframework.boot.autoconfigure.info", + "org.springframework.boot.autoconfigure.jmx", + "org.springframework.boot.autoconfigure.logging", + "org.springframework.boot.autoconfigure.preinitialize", + "org.springframework.boot.autoconfigure.service.connection", + "org.springframework.boot.autoconfigure.ssl", + "org.springframework.boot.autoconfigure.task", + "org.springframework.boot.autoconfigure.template", + "org.springframework.boot.autoconfigure.web", + "org.springframework.boot.autoconfigure.web.format" + ], + "org.springframework.boot:spring-boot-cassandra": [ + "org.springframework.boot.cassandra.autoconfigure", + "org.springframework.boot.cassandra.autoconfigure.health", + "org.springframework.boot.cassandra.docker.compose", + "org.springframework.boot.cassandra.health", + "org.springframework.boot.cassandra.testcontainers" + ], + "org.springframework.boot:spring-boot-data-cassandra": [ + "org.springframework.boot.data.cassandra.autoconfigure" + ], + "org.springframework.boot:spring-boot-data-cassandra-test": [ + "org.springframework.boot.data.cassandra.test.autoconfigure" + ], + "org.springframework.boot:spring-boot-data-commons": [ + "org.springframework.boot.data.autoconfigure.metrics", + "org.springframework.boot.data.autoconfigure.web", + "org.springframework.boot.data.metrics" + ], + "org.springframework.boot:spring-boot-health": [ + "org.springframework.boot.health.actuate.endpoint", + "org.springframework.boot.health.application", + "org.springframework.boot.health.autoconfigure.actuate.endpoint", + "org.springframework.boot.health.autoconfigure.application", + "org.springframework.boot.health.autoconfigure.contributor", + "org.springframework.boot.health.autoconfigure.registry", + "org.springframework.boot.health.contributor", + "org.springframework.boot.health.registry" + ], + "org.springframework.boot:spring-boot-http-client": [ + "org.springframework.boot.http.client", + "org.springframework.boot.http.client.autoconfigure", + "org.springframework.boot.http.client.autoconfigure.imperative", + "org.springframework.boot.http.client.autoconfigure.metrics", + "org.springframework.boot.http.client.autoconfigure.reactive", + "org.springframework.boot.http.client.autoconfigure.service", + "org.springframework.boot.http.client.reactive" + ], + "org.springframework.boot:spring-boot-http-codec": [ + "org.springframework.boot.http.codec", + "org.springframework.boot.http.codec.autoconfigure" + ], + "org.springframework.boot:spring-boot-http-converter": [ + "org.springframework.boot.http.converter.autoconfigure" + ], + "org.springframework.boot:spring-boot-jackson": [ + "org.springframework.boot.jackson", + "org.springframework.boot.jackson.autoconfigure" + ], + "org.springframework.boot:spring-boot-loader": [ + "org.springframework.boot.loader.jar", + "org.springframework.boot.loader.jarmode", + "org.springframework.boot.loader.launch", + "org.springframework.boot.loader.log", + "org.springframework.boot.loader.net.protocol", + "org.springframework.boot.loader.net.protocol.jar", + "org.springframework.boot.loader.net.protocol.nested", + "org.springframework.boot.loader.net.util", + "org.springframework.boot.loader.nio.file", + "org.springframework.boot.loader.ref", + "org.springframework.boot.loader.zip" + ], + "org.springframework.boot:spring-boot-micrometer-metrics": [ + "org.springframework.boot.micrometer.metrics", + "org.springframework.boot.micrometer.metrics.actuate.endpoint", + "org.springframework.boot.micrometer.metrics.autoconfigure", + "org.springframework.boot.micrometer.metrics.autoconfigure.export", + "org.springframework.boot.micrometer.metrics.autoconfigure.export.appoptics", + "org.springframework.boot.micrometer.metrics.autoconfigure.export.atlas", + "org.springframework.boot.micrometer.metrics.autoconfigure.export.datadog", + "org.springframework.boot.micrometer.metrics.autoconfigure.export.dynatrace", + "org.springframework.boot.micrometer.metrics.autoconfigure.export.elastic", + "org.springframework.boot.micrometer.metrics.autoconfigure.export.ganglia", + "org.springframework.boot.micrometer.metrics.autoconfigure.export.graphite", + "org.springframework.boot.micrometer.metrics.autoconfigure.export.humio", + "org.springframework.boot.micrometer.metrics.autoconfigure.export.influx", + "org.springframework.boot.micrometer.metrics.autoconfigure.export.jmx", + "org.springframework.boot.micrometer.metrics.autoconfigure.export.kairos", + "org.springframework.boot.micrometer.metrics.autoconfigure.export.newrelic", + "org.springframework.boot.micrometer.metrics.autoconfigure.export.otlp", + "org.springframework.boot.micrometer.metrics.autoconfigure.export.prometheus", + "org.springframework.boot.micrometer.metrics.autoconfigure.export.properties", + "org.springframework.boot.micrometer.metrics.autoconfigure.export.simple", + "org.springframework.boot.micrometer.metrics.autoconfigure.export.stackdriver", + "org.springframework.boot.micrometer.metrics.autoconfigure.export.statsd", + "org.springframework.boot.micrometer.metrics.autoconfigure.jvm", + "org.springframework.boot.micrometer.metrics.autoconfigure.logging.log4j2", + "org.springframework.boot.micrometer.metrics.autoconfigure.logging.logback", + "org.springframework.boot.micrometer.metrics.autoconfigure.ssl", + "org.springframework.boot.micrometer.metrics.autoconfigure.startup", + "org.springframework.boot.micrometer.metrics.autoconfigure.system", + "org.springframework.boot.micrometer.metrics.autoconfigure.task", + "org.springframework.boot.micrometer.metrics.docker.compose.otlp", + "org.springframework.boot.micrometer.metrics.export.prometheus", + "org.springframework.boot.micrometer.metrics.export.prometheus.endpoint", + "org.springframework.boot.micrometer.metrics.startup", + "org.springframework.boot.micrometer.metrics.system", + "org.springframework.boot.micrometer.metrics.testcontainers.otlp" + ], + "org.springframework.boot:spring-boot-micrometer-metrics-test": [ + "org.springframework.boot.micrometer.metrics.test.autoconfigure" + ], + "org.springframework.boot:spring-boot-micrometer-observation": [ + "org.springframework.boot.micrometer.observation.autoconfigure" + ], + "org.springframework.boot:spring-boot-micrometer-tracing": [ + "org.springframework.boot.micrometer.tracing.autoconfigure", + "org.springframework.boot.micrometer.tracing.autoconfigure.prometheus" + ], + "org.springframework.boot:spring-boot-micrometer-tracing-opentelemetry": [ + "org.springframework.boot.micrometer.tracing.opentelemetry.autoconfigure", + "org.springframework.boot.micrometer.tracing.opentelemetry.autoconfigure.otlp", + "org.springframework.boot.micrometer.tracing.opentelemetry.autoconfigure.zipkin", + "org.springframework.boot.micrometer.tracing.opentelemetry.docker.compose.otlp", + "org.springframework.boot.micrometer.tracing.opentelemetry.testcontainers.otlp" + ], + "org.springframework.boot:spring-boot-netty": [ + "org.springframework.boot.netty.autoconfigure" + ], + "org.springframework.boot:spring-boot-opentelemetry": [ + "org.springframework.boot.opentelemetry.autoconfigure", + "org.springframework.boot.opentelemetry.autoconfigure.logging", + "org.springframework.boot.opentelemetry.autoconfigure.logging.otlp", + "org.springframework.boot.opentelemetry.docker.compose", + "org.springframework.boot.opentelemetry.testcontainers" + ], + "org.springframework.boot:spring-boot-persistence": [ + "org.springframework.boot.persistence.autoconfigure" + ], + "org.springframework.boot:spring-boot-reactor": [ + "org.springframework.boot.reactor", + "org.springframework.boot.reactor.autoconfigure" + ], + "org.springframework.boot:spring-boot-reactor-netty": [ + "org.springframework.boot.reactor.netty", + "org.springframework.boot.reactor.netty.autoconfigure", + "org.springframework.boot.reactor.netty.autoconfigure.actuate.web.server" + ], + "org.springframework.boot:spring-boot-restclient": [ + "org.springframework.boot.restclient", + "org.springframework.boot.restclient.autoconfigure", + "org.springframework.boot.restclient.autoconfigure.service", + "org.springframework.boot.restclient.observation" + ], + "org.springframework.boot:spring-boot-resttestclient": [ + "org.springframework.boot.resttestclient", + "org.springframework.boot.resttestclient.autoconfigure" + ], + "org.springframework.boot:spring-boot-security": [ + "org.springframework.boot.security.autoconfigure", + "org.springframework.boot.security.autoconfigure.actuate.web.reactive", + "org.springframework.boot.security.autoconfigure.actuate.web.servlet", + "org.springframework.boot.security.autoconfigure.rsocket", + "org.springframework.boot.security.autoconfigure.web", + "org.springframework.boot.security.autoconfigure.web.reactive", + "org.springframework.boot.security.autoconfigure.web.servlet", + "org.springframework.boot.security.web.reactive", + "org.springframework.boot.security.web.servlet" + ], + "org.springframework.boot:spring-boot-security-oauth2-client": [ + "org.springframework.boot.security.oauth2.client.autoconfigure", + "org.springframework.boot.security.oauth2.client.autoconfigure.reactive", + "org.springframework.boot.security.oauth2.client.autoconfigure.servlet" + ], + "org.springframework.boot:spring-boot-security-oauth2-resource-server": [ + "org.springframework.boot.security.oauth2.server.resource.autoconfigure", + "org.springframework.boot.security.oauth2.server.resource.autoconfigure.reactive", + "org.springframework.boot.security.oauth2.server.resource.autoconfigure.servlet" + ], + "org.springframework.boot:spring-boot-security-test": [ + "org.springframework.boot.security.test.autoconfigure.webflux", + "org.springframework.boot.security.test.autoconfigure.webmvc" + ], + "org.springframework.boot:spring-boot-servlet": [ + "org.springframework.boot.servlet", + "org.springframework.boot.servlet.actuate.web.exchanges", + "org.springframework.boot.servlet.actuate.web.mappings", + "org.springframework.boot.servlet.autoconfigure", + "org.springframework.boot.servlet.autoconfigure.actuate.web", + "org.springframework.boot.servlet.autoconfigure.actuate.web.exchanges", + "org.springframework.boot.servlet.autoconfigure.actuate.web.mappings", + "org.springframework.boot.servlet.filter" + ], + "org.springframework.boot:spring-boot-test": [ + "org.springframework.boot.test.context", + "org.springframework.boot.test.context.assertj", + "org.springframework.boot.test.context.filter", + "org.springframework.boot.test.context.filter.annotation", + "org.springframework.boot.test.context.runner", + "org.springframework.boot.test.http.client", + "org.springframework.boot.test.http.server", + "org.springframework.boot.test.json", + "org.springframework.boot.test.mock.web", + "org.springframework.boot.test.system", + "org.springframework.boot.test.util", + "org.springframework.boot.test.web.htmlunit", + "org.springframework.boot.test.web.server" + ], + "org.springframework.boot:spring-boot-test-autoconfigure": [ + "org.springframework.boot.test.autoconfigure", + "org.springframework.boot.test.autoconfigure.jdbc", + "org.springframework.boot.test.autoconfigure.json" + ], + "org.springframework.boot:spring-boot-tomcat": [ + "org.springframework.boot.tomcat", + "org.springframework.boot.tomcat.autoconfigure", + "org.springframework.boot.tomcat.autoconfigure.actuate.web.server", + "org.springframework.boot.tomcat.autoconfigure.metrics", + "org.springframework.boot.tomcat.autoconfigure.reactive", + "org.springframework.boot.tomcat.autoconfigure.servlet", + "org.springframework.boot.tomcat.metrics", + "org.springframework.boot.tomcat.reactive", + "org.springframework.boot.tomcat.servlet" + ], + "org.springframework.boot:spring-boot-validation": [ + "org.springframework.boot.validation.autoconfigure" + ], + "org.springframework.boot:spring-boot-web-server": [ + "org.springframework.boot.web.server", + "org.springframework.boot.web.server.autoconfigure", + "org.springframework.boot.web.server.autoconfigure.reactive", + "org.springframework.boot.web.server.autoconfigure.servlet", + "org.springframework.boot.web.server.context", + "org.springframework.boot.web.server.reactive", + "org.springframework.boot.web.server.reactive.context", + "org.springframework.boot.web.server.servlet", + "org.springframework.boot.web.server.servlet.context" + ], + "org.springframework.boot:spring-boot-webclient": [ + "org.springframework.boot.webclient", + "org.springframework.boot.webclient.autoconfigure", + "org.springframework.boot.webclient.autoconfigure.service", + "org.springframework.boot.webclient.observation" + ], + "org.springframework.boot:spring-boot-webflux": [ + "org.springframework.boot.webflux", + "org.springframework.boot.webflux.actuate.endpoint.web", + "org.springframework.boot.webflux.actuate.web.exchanges", + "org.springframework.boot.webflux.actuate.web.mappings", + "org.springframework.boot.webflux.autoconfigure", + "org.springframework.boot.webflux.autoconfigure.actuate.endpoint.web", + "org.springframework.boot.webflux.autoconfigure.actuate.web", + "org.springframework.boot.webflux.autoconfigure.actuate.web.exchanges", + "org.springframework.boot.webflux.autoconfigure.actuate.web.mappings", + "org.springframework.boot.webflux.autoconfigure.error", + "org.springframework.boot.webflux.error", + "org.springframework.boot.webflux.filter" + ], + "org.springframework.boot:spring-boot-webflux-test": [ + "org.springframework.boot.webflux.test.autoconfigure" + ], + "org.springframework.boot:spring-boot-webmvc": [ + "org.springframework.boot.webmvc", + "org.springframework.boot.webmvc.actuate.endpoint.web", + "org.springframework.boot.webmvc.actuate.web.mappings", + "org.springframework.boot.webmvc.autoconfigure", + "org.springframework.boot.webmvc.autoconfigure.actuate.endpoint.web", + "org.springframework.boot.webmvc.autoconfigure.actuate.web", + "org.springframework.boot.webmvc.autoconfigure.actuate.web.mappings", + "org.springframework.boot.webmvc.autoconfigure.error", + "org.springframework.boot.webmvc.error" + ], + "org.springframework.boot:spring-boot-webmvc-test": [ + "org.springframework.boot.webmvc.test.autoconfigure" + ], + "org.springframework.boot:spring-boot-webtestclient": [ + "org.springframework.boot.webtestclient.autoconfigure" + ], + "org.springframework.cloud:spring-cloud-commons": [ + "org.springframework.cloud.client", + "org.springframework.cloud.client.actuator", + "org.springframework.cloud.client.circuitbreaker", + "org.springframework.cloud.client.circuitbreaker.httpservice", + "org.springframework.cloud.client.circuitbreaker.observation", + "org.springframework.cloud.client.discovery", + "org.springframework.cloud.client.discovery.composite", + "org.springframework.cloud.client.discovery.composite.reactive", + "org.springframework.cloud.client.discovery.event", + "org.springframework.cloud.client.discovery.health", + "org.springframework.cloud.client.discovery.health.reactive", + "org.springframework.cloud.client.discovery.simple", + "org.springframework.cloud.client.discovery.simple.reactive", + "org.springframework.cloud.client.hypermedia", + "org.springframework.cloud.client.loadbalancer", + "org.springframework.cloud.client.loadbalancer.reactive", + "org.springframework.cloud.client.serviceregistry", + "org.springframework.cloud.client.serviceregistry.endpoint", + "org.springframework.cloud.commons", + "org.springframework.cloud.commons.config", + "org.springframework.cloud.commons.publisher", + "org.springframework.cloud.commons.security", + "org.springframework.cloud.commons.util", + "org.springframework.cloud.configuration" + ], + "org.springframework.cloud:spring-cloud-context": [ + "org.springframework.cloud.autoconfigure", + "org.springframework.cloud.bootstrap", + "org.springframework.cloud.bootstrap.config", + "org.springframework.cloud.bootstrap.encrypt", + "org.springframework.cloud.bootstrap.support", + "org.springframework.cloud.context", + "org.springframework.cloud.context.config", + "org.springframework.cloud.context.config.annotation", + "org.springframework.cloud.context.encrypt", + "org.springframework.cloud.context.environment", + "org.springframework.cloud.context.named", + "org.springframework.cloud.context.properties", + "org.springframework.cloud.context.refresh", + "org.springframework.cloud.context.restart", + "org.springframework.cloud.context.scope", + "org.springframework.cloud.context.scope.refresh", + "org.springframework.cloud.context.scope.thread", + "org.springframework.cloud.endpoint", + "org.springframework.cloud.endpoint.event", + "org.springframework.cloud.env", + "org.springframework.cloud.health", + "org.springframework.cloud.logging", + "org.springframework.cloud.util", + "org.springframework.cloud.util.random" + ], + "org.springframework.cloud:spring-cloud-kubernetes-client-autoconfig": [ + "org.springframework.cloud.kubernetes.client" + ], + "org.springframework.cloud:spring-cloud-kubernetes-client-config": [ + "org.springframework.cloud.kubernetes.client.config", + "org.springframework.cloud.kubernetes.client.config.reload" + ], + "org.springframework.cloud:spring-cloud-kubernetes-commons": [ + "org.springframework.cloud.kubernetes.commons", + "org.springframework.cloud.kubernetes.commons.autoconfig", + "org.springframework.cloud.kubernetes.commons.config", + "org.springframework.cloud.kubernetes.commons.config.reload", + "org.springframework.cloud.kubernetes.commons.config.reload.condition", + "org.springframework.cloud.kubernetes.commons.configdata", + "org.springframework.cloud.kubernetes.commons.discovery", + "org.springframework.cloud.kubernetes.commons.discovery.conditionals", + "org.springframework.cloud.kubernetes.commons.leader", + "org.springframework.cloud.kubernetes.commons.leader.election", + "org.springframework.cloud.kubernetes.commons.leader.election.events", + "org.springframework.cloud.kubernetes.commons.loadbalancer", + "org.springframework.cloud.kubernetes.commons.profile" + ], + "org.springframework.cloud:spring-cloud-starter-bootstrap": [ + "org.springframework.cloud.bootstrap.marker" + ], + "org.springframework.data:spring-data-cassandra": [ + "org.springframework.data.cassandra", + "org.springframework.data.cassandra.aot", + "org.springframework.data.cassandra.config", + "org.springframework.data.cassandra.core", + "org.springframework.data.cassandra.core.convert", + "org.springframework.data.cassandra.core.cql", + "org.springframework.data.cassandra.core.cql.converter", + "org.springframework.data.cassandra.core.cql.generator", + "org.springframework.data.cassandra.core.cql.keyspace", + "org.springframework.data.cassandra.core.cql.session", + "org.springframework.data.cassandra.core.cql.session.init", + "org.springframework.data.cassandra.core.cql.session.lookup", + "org.springframework.data.cassandra.core.cql.util", + "org.springframework.data.cassandra.core.mapping", + "org.springframework.data.cassandra.core.mapping.event", + "org.springframework.data.cassandra.core.query", + "org.springframework.data.cassandra.observability", + "org.springframework.data.cassandra.repository", + "org.springframework.data.cassandra.repository.aot", + "org.springframework.data.cassandra.repository.cdi", + "org.springframework.data.cassandra.repository.config", + "org.springframework.data.cassandra.repository.query", + "org.springframework.data.cassandra.repository.support", + "org.springframework.data.cassandra.util" + ], + "org.springframework.data:spring-data-commons": [ + "org.springframework.data.annotation", + "org.springframework.data.aot", + "org.springframework.data.auditing", + "org.springframework.data.auditing.config", + "org.springframework.data.config", + "org.springframework.data.convert", + "org.springframework.data.core", + "org.springframework.data.crossstore", + "org.springframework.data.domain", + "org.springframework.data.domain.jaxb", + "org.springframework.data.expression", + "org.springframework.data.geo", + "org.springframework.data.geo.format", + "org.springframework.data.history", + "org.springframework.data.javapoet", + "org.springframework.data.mapping", + "org.springframework.data.mapping.callback", + "org.springframework.data.mapping.context", + "org.springframework.data.mapping.model", + "org.springframework.data.projection", + "org.springframework.data.querydsl", + "org.springframework.data.querydsl.aot", + "org.springframework.data.querydsl.binding", + "org.springframework.data.repository", + "org.springframework.data.repository.aot.generate", + "org.springframework.data.repository.aot.hint", + "org.springframework.data.repository.cdi", + "org.springframework.data.repository.config", + "org.springframework.data.repository.core", + "org.springframework.data.repository.core.support", + "org.springframework.data.repository.history", + "org.springframework.data.repository.history.support", + "org.springframework.data.repository.init", + "org.springframework.data.repository.kotlin", + "org.springframework.data.repository.query", + "org.springframework.data.repository.query.parser", + "org.springframework.data.repository.reactive", + "org.springframework.data.repository.support", + "org.springframework.data.repository.util", + "org.springframework.data.spel", + "org.springframework.data.spel.spi", + "org.springframework.data.support", + "org.springframework.data.transaction", + "org.springframework.data.util", + "org.springframework.data.web", + "org.springframework.data.web.aot", + "org.springframework.data.web.config", + "org.springframework.data.web.querydsl" + ], + "org.springframework.retry:spring-retry": [ + "org.springframework.classify", + "org.springframework.classify.annotation", + "org.springframework.classify.util", + "org.springframework.retry", + "org.springframework.retry.annotation", + "org.springframework.retry.backoff", + "org.springframework.retry.context", + "org.springframework.retry.interceptor", + "org.springframework.retry.listener", + "org.springframework.retry.policy", + "org.springframework.retry.stats", + "org.springframework.retry.support" + ], + "org.springframework.security:spring-security-config": [ + "org.springframework.security.config", + "org.springframework.security.config.annotation", + "org.springframework.security.config.annotation.authentication", + "org.springframework.security.config.annotation.authentication.builders", + "org.springframework.security.config.annotation.authentication.configuration", + "org.springframework.security.config.annotation.authentication.configurers.ldap", + "org.springframework.security.config.annotation.authentication.configurers.provisioning", + "org.springframework.security.config.annotation.authentication.configurers.userdetails", + "org.springframework.security.config.annotation.authorization", + "org.springframework.security.config.annotation.configuration", + "org.springframework.security.config.annotation.method.configuration", + "org.springframework.security.config.annotation.rsocket", + "org.springframework.security.config.annotation.web", + "org.springframework.security.config.annotation.web.builders", + "org.springframework.security.config.annotation.web.configuration", + "org.springframework.security.config.annotation.web.configurers", + "org.springframework.security.config.annotation.web.configurers.oauth2.client", + "org.springframework.security.config.annotation.web.configurers.oauth2.server.authorization", + "org.springframework.security.config.annotation.web.configurers.oauth2.server.resource", + "org.springframework.security.config.annotation.web.configurers.ott", + "org.springframework.security.config.annotation.web.configurers.saml2", + "org.springframework.security.config.annotation.web.headers", + "org.springframework.security.config.annotation.web.oauth2.client", + "org.springframework.security.config.annotation.web.oauth2.login", + "org.springframework.security.config.annotation.web.oauth2.resourceserver", + "org.springframework.security.config.annotation.web.reactive", + "org.springframework.security.config.annotation.web.saml2", + "org.springframework.security.config.annotation.web.servlet.configuration", + "org.springframework.security.config.annotation.web.session", + "org.springframework.security.config.annotation.web.socket", + "org.springframework.security.config.aot.hint", + "org.springframework.security.config.authentication", + "org.springframework.security.config.core", + "org.springframework.security.config.core.userdetails", + "org.springframework.security.config.crypto", + "org.springframework.security.config.debug", + "org.springframework.security.config.http", + "org.springframework.security.config.ldap", + "org.springframework.security.config.method", + "org.springframework.security.config.oauth2.client", + "org.springframework.security.config.observation", + "org.springframework.security.config.provisioning", + "org.springframework.security.config.saml2", + "org.springframework.security.config.web", + "org.springframework.security.config.web.messaging", + "org.springframework.security.config.web.server", + "org.springframework.security.config.websocket" + ], + "org.springframework.security:spring-security-core": [ + "org.springframework.security.access", + "org.springframework.security.access.annotation", + "org.springframework.security.access.expression", + "org.springframework.security.access.expression.method", + "org.springframework.security.access.hierarchicalroles", + "org.springframework.security.access.prepost", + "org.springframework.security.aot.hint", + "org.springframework.security.authentication", + "org.springframework.security.authentication.dao", + "org.springframework.security.authentication.event", + "org.springframework.security.authentication.jaas", + "org.springframework.security.authentication.jaas.event", + "org.springframework.security.authentication.jaas.memory", + "org.springframework.security.authentication.ott", + "org.springframework.security.authentication.ott.reactive", + "org.springframework.security.authentication.password", + "org.springframework.security.authorization", + "org.springframework.security.authorization.event", + "org.springframework.security.authorization.method", + "org.springframework.security.concurrent", + "org.springframework.security.context", + "org.springframework.security.converter", + "org.springframework.security.core", + "org.springframework.security.core.annotation", + "org.springframework.security.core.authority", + "org.springframework.security.core.authority.mapping", + "org.springframework.security.core.context", + "org.springframework.security.core.parameters", + "org.springframework.security.core.session", + "org.springframework.security.core.token", + "org.springframework.security.core.userdetails", + "org.springframework.security.core.userdetails.cache", + "org.springframework.security.core.userdetails.jdbc", + "org.springframework.security.core.userdetails.memory", + "org.springframework.security.jackson", + "org.springframework.security.jackson2", + "org.springframework.security.provisioning", + "org.springframework.security.scheduling", + "org.springframework.security.task", + "org.springframework.security.util" + ], + "org.springframework.security:spring-security-crypto": [ + "org.springframework.security.crypto.argon2", + "org.springframework.security.crypto.bcrypt", + "org.springframework.security.crypto.codec", + "org.springframework.security.crypto.encrypt", + "org.springframework.security.crypto.factory", + "org.springframework.security.crypto.keygen", + "org.springframework.security.crypto.password", + "org.springframework.security.crypto.password4j", + "org.springframework.security.crypto.scrypt", + "org.springframework.security.crypto.util" + ], + "org.springframework.security:spring-security-oauth2-client": [ + "org.springframework.security.oauth2.client", + "org.springframework.security.oauth2.client.annotation", + "org.springframework.security.oauth2.client.aot.hint", + "org.springframework.security.oauth2.client.authentication", + "org.springframework.security.oauth2.client.endpoint", + "org.springframework.security.oauth2.client.event", + "org.springframework.security.oauth2.client.http", + "org.springframework.security.oauth2.client.jackson", + "org.springframework.security.oauth2.client.jackson2", + "org.springframework.security.oauth2.client.oidc.authentication", + "org.springframework.security.oauth2.client.oidc.authentication.event", + "org.springframework.security.oauth2.client.oidc.authentication.logout", + "org.springframework.security.oauth2.client.oidc.server.session", + "org.springframework.security.oauth2.client.oidc.session", + "org.springframework.security.oauth2.client.oidc.userinfo", + "org.springframework.security.oauth2.client.oidc.web.logout", + "org.springframework.security.oauth2.client.oidc.web.server.logout", + "org.springframework.security.oauth2.client.registration", + "org.springframework.security.oauth2.client.userinfo", + "org.springframework.security.oauth2.client.web", + "org.springframework.security.oauth2.client.web.client", + "org.springframework.security.oauth2.client.web.client.support", + "org.springframework.security.oauth2.client.web.method.annotation", + "org.springframework.security.oauth2.client.web.reactive.function.client", + "org.springframework.security.oauth2.client.web.reactive.function.client.support", + "org.springframework.security.oauth2.client.web.reactive.result.method.annotation", + "org.springframework.security.oauth2.client.web.server", + "org.springframework.security.oauth2.client.web.server.authentication" + ], + "org.springframework.security:spring-security-oauth2-core": [ + "org.springframework.security.oauth2.core", + "org.springframework.security.oauth2.core.authorization", + "org.springframework.security.oauth2.core.converter", + "org.springframework.security.oauth2.core.endpoint", + "org.springframework.security.oauth2.core.http.converter", + "org.springframework.security.oauth2.core.oidc", + "org.springframework.security.oauth2.core.oidc.endpoint", + "org.springframework.security.oauth2.core.oidc.user", + "org.springframework.security.oauth2.core.user", + "org.springframework.security.oauth2.core.web.reactive.function" + ], + "org.springframework.security:spring-security-oauth2-jose": [ + "org.springframework.security.oauth2.jose", + "org.springframework.security.oauth2.jose.jws", + "org.springframework.security.oauth2.jwt" + ], + "org.springframework.security:spring-security-oauth2-resource-server": [ + "org.springframework.security.oauth2.server.resource", + "org.springframework.security.oauth2.server.resource.authentication", + "org.springframework.security.oauth2.server.resource.introspection", + "org.springframework.security.oauth2.server.resource.web", + "org.springframework.security.oauth2.server.resource.web.access", + "org.springframework.security.oauth2.server.resource.web.access.server", + "org.springframework.security.oauth2.server.resource.web.authentication", + "org.springframework.security.oauth2.server.resource.web.reactive.function.client", + "org.springframework.security.oauth2.server.resource.web.server", + "org.springframework.security.oauth2.server.resource.web.server.authentication" + ], + "org.springframework.security:spring-security-test": [ + "org.springframework.security.test.aot.hint", + "org.springframework.security.test.context", + "org.springframework.security.test.context.annotation", + "org.springframework.security.test.context.support", + "org.springframework.security.test.web.reactive.server", + "org.springframework.security.test.web.servlet.request", + "org.springframework.security.test.web.servlet.response", + "org.springframework.security.test.web.servlet.setup", + "org.springframework.security.test.web.support" + ], + "org.springframework.security:spring-security-web": [ + "org.springframework.security.web", + "org.springframework.security.web.access", + "org.springframework.security.web.access.expression", + "org.springframework.security.web.access.intercept", + "org.springframework.security.web.aot.hint", + "org.springframework.security.web.authentication", + "org.springframework.security.web.authentication.logout", + "org.springframework.security.web.authentication.ott", + "org.springframework.security.web.authentication.password", + "org.springframework.security.web.authentication.preauth", + "org.springframework.security.web.authentication.preauth.j2ee", + "org.springframework.security.web.authentication.preauth.websphere", + "org.springframework.security.web.authentication.preauth.x509", + "org.springframework.security.web.authentication.rememberme", + "org.springframework.security.web.authentication.session", + "org.springframework.security.web.authentication.switchuser", + "org.springframework.security.web.authentication.ui", + "org.springframework.security.web.authentication.www", + "org.springframework.security.web.bind", + "org.springframework.security.web.bind.annotation", + "org.springframework.security.web.bind.support", + "org.springframework.security.web.context", + "org.springframework.security.web.context.request.async", + "org.springframework.security.web.context.support", + "org.springframework.security.web.csrf", + "org.springframework.security.web.debug", + "org.springframework.security.web.firewall", + "org.springframework.security.web.header", + "org.springframework.security.web.header.writers", + "org.springframework.security.web.header.writers.frameoptions", + "org.springframework.security.web.http", + "org.springframework.security.web.jaasapi", + "org.springframework.security.web.jackson", + "org.springframework.security.web.jackson2", + "org.springframework.security.web.method.annotation", + "org.springframework.security.web.reactive.result.method.annotation", + "org.springframework.security.web.reactive.result.view", + "org.springframework.security.web.savedrequest", + "org.springframework.security.web.server", + "org.springframework.security.web.server.authentication", + "org.springframework.security.web.server.authentication.logout", + "org.springframework.security.web.server.authentication.ott", + "org.springframework.security.web.server.authorization", + "org.springframework.security.web.server.context", + "org.springframework.security.web.server.csrf", + "org.springframework.security.web.server.firewall", + "org.springframework.security.web.server.header", + "org.springframework.security.web.server.jackson", + "org.springframework.security.web.server.jackson2", + "org.springframework.security.web.server.savedrequest", + "org.springframework.security.web.server.transport", + "org.springframework.security.web.server.ui", + "org.springframework.security.web.server.util.matcher", + "org.springframework.security.web.servlet.support.csrf", + "org.springframework.security.web.servlet.util.matcher", + "org.springframework.security.web.servletapi", + "org.springframework.security.web.session", + "org.springframework.security.web.transport", + "org.springframework.security.web.util", + "org.springframework.security.web.util.matcher" + ], + "org.springframework:spring-aop": [ + "org.aopalliance", + "org.aopalliance.aop", + "org.aopalliance.intercept", + "org.springframework.aop", + "org.springframework.aop.aspectj", + "org.springframework.aop.aspectj.annotation", + "org.springframework.aop.aspectj.autoproxy", + "org.springframework.aop.config", + "org.springframework.aop.framework", + "org.springframework.aop.framework.adapter", + "org.springframework.aop.framework.autoproxy", + "org.springframework.aop.framework.autoproxy.target", + "org.springframework.aop.interceptor", + "org.springframework.aop.scope", + "org.springframework.aop.support", + "org.springframework.aop.support.annotation", + "org.springframework.aop.target", + "org.springframework.aop.target.dynamic" + ], + "org.springframework:spring-beans": [ + "org.springframework.beans", + "org.springframework.beans.factory", + "org.springframework.beans.factory.annotation", + "org.springframework.beans.factory.aot", + "org.springframework.beans.factory.config", + "org.springframework.beans.factory.groovy", + "org.springframework.beans.factory.parsing", + "org.springframework.beans.factory.serviceloader", + "org.springframework.beans.factory.support", + "org.springframework.beans.factory.wiring", + "org.springframework.beans.factory.xml", + "org.springframework.beans.propertyeditors", + "org.springframework.beans.support" + ], + "org.springframework:spring-context": [ + "org.springframework.cache", + "org.springframework.cache.annotation", + "org.springframework.cache.concurrent", + "org.springframework.cache.config", + "org.springframework.cache.interceptor", + "org.springframework.cache.support", + "org.springframework.context", + "org.springframework.context.annotation", + "org.springframework.context.aot", + "org.springframework.context.config", + "org.springframework.context.event", + "org.springframework.context.expression", + "org.springframework.context.i18n", + "org.springframework.context.index", + "org.springframework.context.support", + "org.springframework.context.weaving", + "org.springframework.ejb.config", + "org.springframework.format", + "org.springframework.format.annotation", + "org.springframework.format.datetime", + "org.springframework.format.datetime.standard", + "org.springframework.format.number", + "org.springframework.format.number.money", + "org.springframework.format.support", + "org.springframework.instrument.classloading", + "org.springframework.instrument.classloading.glassfish", + "org.springframework.instrument.classloading.jboss", + "org.springframework.instrument.classloading.tomcat", + "org.springframework.jmx", + "org.springframework.jmx.access", + "org.springframework.jmx.export", + "org.springframework.jmx.export.annotation", + "org.springframework.jmx.export.assembler", + "org.springframework.jmx.export.metadata", + "org.springframework.jmx.export.naming", + "org.springframework.jmx.export.notification", + "org.springframework.jmx.support", + "org.springframework.jndi", + "org.springframework.jndi.support", + "org.springframework.resilience", + "org.springframework.resilience.annotation", + "org.springframework.resilience.retry", + "org.springframework.scheduling", + "org.springframework.scheduling.annotation", + "org.springframework.scheduling.concurrent", + "org.springframework.scheduling.config", + "org.springframework.scheduling.support", + "org.springframework.scripting", + "org.springframework.scripting.bsh", + "org.springframework.scripting.config", + "org.springframework.scripting.groovy", + "org.springframework.scripting.support", + "org.springframework.stereotype", + "org.springframework.ui", + "org.springframework.validation", + "org.springframework.validation.annotation", + "org.springframework.validation.beanvalidation", + "org.springframework.validation.method", + "org.springframework.validation.support" + ], + "org.springframework:spring-context-support": [ + "org.springframework.cache.caffeine", + "org.springframework.cache.jcache", + "org.springframework.cache.jcache.config", + "org.springframework.cache.jcache.interceptor", + "org.springframework.cache.transaction", + "org.springframework.mail", + "org.springframework.mail.javamail", + "org.springframework.scheduling.quartz", + "org.springframework.ui.freemarker" + ], + "org.springframework:spring-core": [ + "org.springframework.aot", + "org.springframework.aot.generate", + "org.springframework.aot.hint", + "org.springframework.aot.hint.annotation", + "org.springframework.aot.hint.predicate", + "org.springframework.aot.hint.support", + "org.springframework.aot.nativex", + "org.springframework.aot.nativex.feature", + "org.springframework.asm", + "org.springframework.cglib", + "org.springframework.cglib.beans", + "org.springframework.cglib.core", + "org.springframework.cglib.core.internal", + "org.springframework.cglib.proxy", + "org.springframework.cglib.reflect", + "org.springframework.cglib.transform", + "org.springframework.cglib.transform.impl", + "org.springframework.cglib.util", + "org.springframework.core", + "org.springframework.core.annotation", + "org.springframework.core.codec", + "org.springframework.core.convert", + "org.springframework.core.convert.converter", + "org.springframework.core.convert.support", + "org.springframework.core.env", + "org.springframework.core.io", + "org.springframework.core.io.buffer", + "org.springframework.core.io.support", + "org.springframework.core.log", + "org.springframework.core.metrics", + "org.springframework.core.metrics.jfr", + "org.springframework.core.retry", + "org.springframework.core.retry.support", + "org.springframework.core.serializer", + "org.springframework.core.serializer.support", + "org.springframework.core.style", + "org.springframework.core.task", + "org.springframework.core.task.support", + "org.springframework.core.type", + "org.springframework.core.type.classreading", + "org.springframework.core.type.filter", + "org.springframework.javapoet", + "org.springframework.lang", + "org.springframework.objenesis", + "org.springframework.objenesis.instantiator", + "org.springframework.objenesis.instantiator.android", + "org.springframework.objenesis.instantiator.annotations", + "org.springframework.objenesis.instantiator.basic", + "org.springframework.objenesis.instantiator.gcj", + "org.springframework.objenesis.instantiator.perc", + "org.springframework.objenesis.instantiator.sun", + "org.springframework.objenesis.instantiator.util", + "org.springframework.objenesis.strategy", + "org.springframework.util", + "org.springframework.util.backoff", + "org.springframework.util.comparator", + "org.springframework.util.concurrent", + "org.springframework.util.function", + "org.springframework.util.unit", + "org.springframework.util.xml" + ], + "org.springframework:spring-expression": [ + "org.springframework.expression", + "org.springframework.expression.common", + "org.springframework.expression.spel", + "org.springframework.expression.spel.ast", + "org.springframework.expression.spel.standard", + "org.springframework.expression.spel.support" + ], + "org.springframework:spring-test": [ + "org.springframework.mock.env", + "org.springframework.mock.http", + "org.springframework.mock.http.client", + "org.springframework.mock.http.client.reactive", + "org.springframework.mock.http.server.reactive", + "org.springframework.mock.web", + "org.springframework.mock.web.reactive.function.server", + "org.springframework.mock.web.server", + "org.springframework.test.annotation", + "org.springframework.test.context", + "org.springframework.test.context.aot", + "org.springframework.test.context.bean.override", + "org.springframework.test.context.bean.override.convention", + "org.springframework.test.context.bean.override.mockito", + "org.springframework.test.context.cache", + "org.springframework.test.context.event", + "org.springframework.test.context.event.annotation", + "org.springframework.test.context.hint", + "org.springframework.test.context.jdbc", + "org.springframework.test.context.junit.jupiter", + "org.springframework.test.context.junit.jupiter.web", + "org.springframework.test.context.junit4", + "org.springframework.test.context.junit4.rules", + "org.springframework.test.context.junit4.statements", + "org.springframework.test.context.observation", + "org.springframework.test.context.support", + "org.springframework.test.context.testng", + "org.springframework.test.context.transaction", + "org.springframework.test.context.util", + "org.springframework.test.context.web", + "org.springframework.test.context.web.socket", + "org.springframework.test.http", + "org.springframework.test.jdbc", + "org.springframework.test.json", + "org.springframework.test.util", + "org.springframework.test.validation", + "org.springframework.test.web", + "org.springframework.test.web.client", + "org.springframework.test.web.client.match", + "org.springframework.test.web.client.response", + "org.springframework.test.web.reactive.server", + "org.springframework.test.web.reactive.server.assertj", + "org.springframework.test.web.servlet", + "org.springframework.test.web.servlet.assertj", + "org.springframework.test.web.servlet.client", + "org.springframework.test.web.servlet.client.assertj", + "org.springframework.test.web.servlet.htmlunit", + "org.springframework.test.web.servlet.htmlunit.webdriver", + "org.springframework.test.web.servlet.request", + "org.springframework.test.web.servlet.result", + "org.springframework.test.web.servlet.setup", + "org.springframework.test.web.support" + ], + "org.springframework:spring-tx": [ + "org.springframework.dao", + "org.springframework.dao.annotation", + "org.springframework.dao.support", + "org.springframework.jca.endpoint", + "org.springframework.jca.support", + "org.springframework.transaction", + "org.springframework.transaction.annotation", + "org.springframework.transaction.config", + "org.springframework.transaction.event", + "org.springframework.transaction.interceptor", + "org.springframework.transaction.jta", + "org.springframework.transaction.reactive", + "org.springframework.transaction.support" + ], + "org.springframework:spring-web": [ + "org.springframework.http", + "org.springframework.http.client", + "org.springframework.http.client.observation", + "org.springframework.http.client.reactive", + "org.springframework.http.client.support", + "org.springframework.http.codec", + "org.springframework.http.codec.cbor", + "org.springframework.http.codec.json", + "org.springframework.http.codec.multipart", + "org.springframework.http.codec.protobuf", + "org.springframework.http.codec.smile", + "org.springframework.http.codec.support", + "org.springframework.http.codec.xml", + "org.springframework.http.converter", + "org.springframework.http.converter.cbor", + "org.springframework.http.converter.feed", + "org.springframework.http.converter.json", + "org.springframework.http.converter.protobuf", + "org.springframework.http.converter.smile", + "org.springframework.http.converter.support", + "org.springframework.http.converter.xml", + "org.springframework.http.converter.yaml", + "org.springframework.http.server", + "org.springframework.http.server.observation", + "org.springframework.http.server.reactive", + "org.springframework.http.server.reactive.observation", + "org.springframework.http.support", + "org.springframework.web", + "org.springframework.web.accept", + "org.springframework.web.bind", + "org.springframework.web.bind.annotation", + "org.springframework.web.bind.support", + "org.springframework.web.client", + "org.springframework.web.client.support", + "org.springframework.web.context", + "org.springframework.web.context.annotation", + "org.springframework.web.context.request", + "org.springframework.web.context.request.async", + "org.springframework.web.context.support", + "org.springframework.web.cors", + "org.springframework.web.cors.reactive", + "org.springframework.web.filter", + "org.springframework.web.filter.reactive", + "org.springframework.web.jsf", + "org.springframework.web.jsf.el", + "org.springframework.web.method", + "org.springframework.web.method.annotation", + "org.springframework.web.method.support", + "org.springframework.web.multipart", + "org.springframework.web.multipart.support", + "org.springframework.web.server", + "org.springframework.web.server.adapter", + "org.springframework.web.server.handler", + "org.springframework.web.server.i18n", + "org.springframework.web.server.session", + "org.springframework.web.service", + "org.springframework.web.service.annotation", + "org.springframework.web.service.invoker", + "org.springframework.web.service.registry", + "org.springframework.web.util", + "org.springframework.web.util.pattern" + ], + "org.springframework:spring-webflux": [ + "org.springframework.web.reactive", + "org.springframework.web.reactive.accept", + "org.springframework.web.reactive.config", + "org.springframework.web.reactive.function", + "org.springframework.web.reactive.function.client", + "org.springframework.web.reactive.function.client.support", + "org.springframework.web.reactive.function.server", + "org.springframework.web.reactive.function.server.support", + "org.springframework.web.reactive.handler", + "org.springframework.web.reactive.resource", + "org.springframework.web.reactive.result", + "org.springframework.web.reactive.result.condition", + "org.springframework.web.reactive.result.method", + "org.springframework.web.reactive.result.method.annotation", + "org.springframework.web.reactive.result.view", + "org.springframework.web.reactive.result.view.freemarker", + "org.springframework.web.reactive.result.view.script", + "org.springframework.web.reactive.socket", + "org.springframework.web.reactive.socket.adapter", + "org.springframework.web.reactive.socket.client", + "org.springframework.web.reactive.socket.server", + "org.springframework.web.reactive.socket.server.support", + "org.springframework.web.reactive.socket.server.upgrade" + ], + "org.springframework:spring-webmvc": [ + "org.springframework.web.servlet", + "org.springframework.web.servlet.config", + "org.springframework.web.servlet.config.annotation", + "org.springframework.web.servlet.function", + "org.springframework.web.servlet.function.support", + "org.springframework.web.servlet.handler", + "org.springframework.web.servlet.i18n", + "org.springframework.web.servlet.mvc", + "org.springframework.web.servlet.mvc.annotation", + "org.springframework.web.servlet.mvc.condition", + "org.springframework.web.servlet.mvc.method", + "org.springframework.web.servlet.mvc.method.annotation", + "org.springframework.web.servlet.mvc.support", + "org.springframework.web.servlet.resource", + "org.springframework.web.servlet.support", + "org.springframework.web.servlet.tags", + "org.springframework.web.servlet.tags.form", + "org.springframework.web.servlet.view", + "org.springframework.web.servlet.view.document", + "org.springframework.web.servlet.view.feed", + "org.springframework.web.servlet.view.freemarker", + "org.springframework.web.servlet.view.groovy", + "org.springframework.web.servlet.view.json", + "org.springframework.web.servlet.view.script", + "org.springframework.web.servlet.view.xml", + "org.springframework.web.servlet.view.xslt" + ], + "org.testcontainers:testcontainers": [ + "org.testcontainers", + "org.testcontainers.containers", + "org.testcontainers.containers.output", + "org.testcontainers.containers.startupcheck", + "org.testcontainers.containers.traits", + "org.testcontainers.containers.wait.internal", + "org.testcontainers.containers.wait.strategy", + "org.testcontainers.core", + "org.testcontainers.dockerclient", + "org.testcontainers.images", + "org.testcontainers.images.builder", + "org.testcontainers.images.builder.dockerfile", + "org.testcontainers.images.builder.dockerfile.statement", + "org.testcontainers.images.builder.dockerfile.traits", + "org.testcontainers.images.builder.traits", + "org.testcontainers.jib", + "org.testcontainers.lifecycle", + "org.testcontainers.shaded.com.fasterxml.jackson.core", + "org.testcontainers.shaded.com.fasterxml.jackson.core.async", + "org.testcontainers.shaded.com.fasterxml.jackson.core.base", + "org.testcontainers.shaded.com.fasterxml.jackson.core.exc", + "org.testcontainers.shaded.com.fasterxml.jackson.core.filter", + "org.testcontainers.shaded.com.fasterxml.jackson.core.format", + "org.testcontainers.shaded.com.fasterxml.jackson.core.internal.shaded.fdp.v2_18_4", + "org.testcontainers.shaded.com.fasterxml.jackson.core.io", + "org.testcontainers.shaded.com.fasterxml.jackson.core.io.schubfach", + "org.testcontainers.shaded.com.fasterxml.jackson.core.json", + "org.testcontainers.shaded.com.fasterxml.jackson.core.json.async", + "org.testcontainers.shaded.com.fasterxml.jackson.core.sym", + "org.testcontainers.shaded.com.fasterxml.jackson.core.type", + "org.testcontainers.shaded.com.fasterxml.jackson.core.util", + "org.testcontainers.shaded.com.fasterxml.jackson.databind", + "org.testcontainers.shaded.com.fasterxml.jackson.databind.annotation", + "org.testcontainers.shaded.com.fasterxml.jackson.databind.cfg", + "org.testcontainers.shaded.com.fasterxml.jackson.databind.deser", + "org.testcontainers.shaded.com.fasterxml.jackson.databind.deser.impl", + "org.testcontainers.shaded.com.fasterxml.jackson.databind.deser.std", + "org.testcontainers.shaded.com.fasterxml.jackson.databind.exc", + "org.testcontainers.shaded.com.fasterxml.jackson.databind.ext", + "org.testcontainers.shaded.com.fasterxml.jackson.databind.introspect", + "org.testcontainers.shaded.com.fasterxml.jackson.databind.jdk14", + "org.testcontainers.shaded.com.fasterxml.jackson.databind.json", + "org.testcontainers.shaded.com.fasterxml.jackson.databind.jsonFormatVisitors", + "org.testcontainers.shaded.com.fasterxml.jackson.databind.jsonschema", + "org.testcontainers.shaded.com.fasterxml.jackson.databind.jsontype", + "org.testcontainers.shaded.com.fasterxml.jackson.databind.jsontype.impl", + "org.testcontainers.shaded.com.fasterxml.jackson.databind.module", + "org.testcontainers.shaded.com.fasterxml.jackson.databind.node", + "org.testcontainers.shaded.com.fasterxml.jackson.databind.ser", + "org.testcontainers.shaded.com.fasterxml.jackson.databind.ser.impl", + "org.testcontainers.shaded.com.fasterxml.jackson.databind.ser.std", + "org.testcontainers.shaded.com.fasterxml.jackson.databind.type", + "org.testcontainers.shaded.com.fasterxml.jackson.databind.util", + "org.testcontainers.shaded.com.fasterxml.jackson.databind.util.internal", + "org.testcontainers.shaded.com.github.dockerjava.core", + "org.testcontainers.shaded.com.github.dockerjava.core.async", + "org.testcontainers.shaded.com.github.dockerjava.core.command", + "org.testcontainers.shaded.com.github.dockerjava.core.dockerfile", + "org.testcontainers.shaded.com.github.dockerjava.core.exception", + "org.testcontainers.shaded.com.github.dockerjava.core.exec", + "org.testcontainers.shaded.com.github.dockerjava.core.util", + "org.testcontainers.shaded.com.google.common.annotations", + "org.testcontainers.shaded.com.google.common.base", + "org.testcontainers.shaded.com.google.common.base.internal", + "org.testcontainers.shaded.com.google.common.cache", + "org.testcontainers.shaded.com.google.common.collect", + "org.testcontainers.shaded.com.google.common.escape", + "org.testcontainers.shaded.com.google.common.eventbus", + "org.testcontainers.shaded.com.google.common.graph", + "org.testcontainers.shaded.com.google.common.hash", + "org.testcontainers.shaded.com.google.common.html", + "org.testcontainers.shaded.com.google.common.io", + "org.testcontainers.shaded.com.google.common.math", + "org.testcontainers.shaded.com.google.common.net", + "org.testcontainers.shaded.com.google.common.primitives", + "org.testcontainers.shaded.com.google.common.reflect", + "org.testcontainers.shaded.com.google.common.util.concurrent", + "org.testcontainers.shaded.com.google.common.util.concurrent.internal", + "org.testcontainers.shaded.com.google.common.xml", + "org.testcontainers.shaded.com.google.errorprone.annotations", + "org.testcontainers.shaded.com.google.errorprone.annotations.concurrent", + "org.testcontainers.shaded.com.google.thirdparty.publicsuffix", + "org.testcontainers.shaded.com.trilead.ssh2", + "org.testcontainers.shaded.com.trilead.ssh2.auth", + "org.testcontainers.shaded.com.trilead.ssh2.channel", + "org.testcontainers.shaded.com.trilead.ssh2.crypto", + "org.testcontainers.shaded.com.trilead.ssh2.crypto.cipher", + "org.testcontainers.shaded.com.trilead.ssh2.crypto.dh", + "org.testcontainers.shaded.com.trilead.ssh2.crypto.digest", + "org.testcontainers.shaded.com.trilead.ssh2.log", + "org.testcontainers.shaded.com.trilead.ssh2.packets", + "org.testcontainers.shaded.com.trilead.ssh2.sftp", + "org.testcontainers.shaded.com.trilead.ssh2.signature", + "org.testcontainers.shaded.com.trilead.ssh2.transport", + "org.testcontainers.shaded.com.trilead.ssh2.util", + "org.testcontainers.shaded.org.awaitility", + "org.testcontainers.shaded.org.awaitility.classpath", + "org.testcontainers.shaded.org.awaitility.constraint", + "org.testcontainers.shaded.org.awaitility.core", + "org.testcontainers.shaded.org.awaitility.pollinterval", + "org.testcontainers.shaded.org.awaitility.reflect", + "org.testcontainers.shaded.org.awaitility.reflect.exception", + "org.testcontainers.shaded.org.awaitility.spi", + "org.testcontainers.shaded.org.bouncycastle", + "org.testcontainers.shaded.org.bouncycastle.asn1", + "org.testcontainers.shaded.org.bouncycastle.asn1.anssi", + "org.testcontainers.shaded.org.bouncycastle.asn1.bc", + "org.testcontainers.shaded.org.bouncycastle.asn1.bsi", + "org.testcontainers.shaded.org.bouncycastle.asn1.cmc", + "org.testcontainers.shaded.org.bouncycastle.asn1.cmp", + "org.testcontainers.shaded.org.bouncycastle.asn1.cms", + "org.testcontainers.shaded.org.bouncycastle.asn1.cms.ecc", + "org.testcontainers.shaded.org.bouncycastle.asn1.crmf", + "org.testcontainers.shaded.org.bouncycastle.asn1.cryptlib", + "org.testcontainers.shaded.org.bouncycastle.asn1.cryptopro", + "org.testcontainers.shaded.org.bouncycastle.asn1.dvcs", + "org.testcontainers.shaded.org.bouncycastle.asn1.eac", + "org.testcontainers.shaded.org.bouncycastle.asn1.edec", + "org.testcontainers.shaded.org.bouncycastle.asn1.esf", + "org.testcontainers.shaded.org.bouncycastle.asn1.ess", + "org.testcontainers.shaded.org.bouncycastle.asn1.est", + "org.testcontainers.shaded.org.bouncycastle.asn1.gm", + "org.testcontainers.shaded.org.bouncycastle.asn1.gnu", + "org.testcontainers.shaded.org.bouncycastle.asn1.iana", + "org.testcontainers.shaded.org.bouncycastle.asn1.icao", + "org.testcontainers.shaded.org.bouncycastle.asn1.isara", + "org.testcontainers.shaded.org.bouncycastle.asn1.isismtt", + "org.testcontainers.shaded.org.bouncycastle.asn1.isismtt.ocsp", + "org.testcontainers.shaded.org.bouncycastle.asn1.isismtt.x509", + "org.testcontainers.shaded.org.bouncycastle.asn1.iso", + "org.testcontainers.shaded.org.bouncycastle.asn1.kisa", + "org.testcontainers.shaded.org.bouncycastle.asn1.microsoft", + "org.testcontainers.shaded.org.bouncycastle.asn1.misc", + "org.testcontainers.shaded.org.bouncycastle.asn1.mod", + "org.testcontainers.shaded.org.bouncycastle.asn1.mozilla", + "org.testcontainers.shaded.org.bouncycastle.asn1.nist", + "org.testcontainers.shaded.org.bouncycastle.asn1.nsri", + "org.testcontainers.shaded.org.bouncycastle.asn1.ntt", + "org.testcontainers.shaded.org.bouncycastle.asn1.ocsp", + "org.testcontainers.shaded.org.bouncycastle.asn1.oiw", + "org.testcontainers.shaded.org.bouncycastle.asn1.pkcs", + "org.testcontainers.shaded.org.bouncycastle.asn1.rosstandart", + "org.testcontainers.shaded.org.bouncycastle.asn1.sec", + "org.testcontainers.shaded.org.bouncycastle.asn1.smime", + "org.testcontainers.shaded.org.bouncycastle.asn1.teletrust", + "org.testcontainers.shaded.org.bouncycastle.asn1.tsp", + "org.testcontainers.shaded.org.bouncycastle.asn1.ua", + "org.testcontainers.shaded.org.bouncycastle.asn1.util", + "org.testcontainers.shaded.org.bouncycastle.asn1.x500", + "org.testcontainers.shaded.org.bouncycastle.asn1.x500.style", + "org.testcontainers.shaded.org.bouncycastle.asn1.x509", + "org.testcontainers.shaded.org.bouncycastle.asn1.x509.qualified", + "org.testcontainers.shaded.org.bouncycastle.asn1.x509.sigi", + "org.testcontainers.shaded.org.bouncycastle.asn1.x9", + "org.testcontainers.shaded.org.bouncycastle.cert", + "org.testcontainers.shaded.org.bouncycastle.cert.bc", + "org.testcontainers.shaded.org.bouncycastle.cert.cmp", + "org.testcontainers.shaded.org.bouncycastle.cert.crmf", + "org.testcontainers.shaded.org.bouncycastle.cert.crmf.bc", + "org.testcontainers.shaded.org.bouncycastle.cert.crmf.jcajce", + "org.testcontainers.shaded.org.bouncycastle.cert.dane", + "org.testcontainers.shaded.org.bouncycastle.cert.dane.fetcher", + "org.testcontainers.shaded.org.bouncycastle.cert.jcajce", + "org.testcontainers.shaded.org.bouncycastle.cert.ocsp", + "org.testcontainers.shaded.org.bouncycastle.cert.ocsp.jcajce", + "org.testcontainers.shaded.org.bouncycastle.cert.path", + "org.testcontainers.shaded.org.bouncycastle.cert.path.validations", + "org.testcontainers.shaded.org.bouncycastle.cert.selector", + "org.testcontainers.shaded.org.bouncycastle.cert.selector.jcajce", + "org.testcontainers.shaded.org.bouncycastle.cmc", + "org.testcontainers.shaded.org.bouncycastle.cms", + "org.testcontainers.shaded.org.bouncycastle.cms.bc", + "org.testcontainers.shaded.org.bouncycastle.cms.jcajce", + "org.testcontainers.shaded.org.bouncycastle.crypto", + "org.testcontainers.shaded.org.bouncycastle.crypto.agreement", + "org.testcontainers.shaded.org.bouncycastle.crypto.agreement.ecjpake", + "org.testcontainers.shaded.org.bouncycastle.crypto.agreement.jpake", + "org.testcontainers.shaded.org.bouncycastle.crypto.agreement.kdf", + "org.testcontainers.shaded.org.bouncycastle.crypto.agreement.srp", + "org.testcontainers.shaded.org.bouncycastle.crypto.commitments", + "org.testcontainers.shaded.org.bouncycastle.crypto.constraints", + "org.testcontainers.shaded.org.bouncycastle.crypto.digests", + "org.testcontainers.shaded.org.bouncycastle.crypto.ec", + "org.testcontainers.shaded.org.bouncycastle.crypto.encodings", + "org.testcontainers.shaded.org.bouncycastle.crypto.engines", + "org.testcontainers.shaded.org.bouncycastle.crypto.examples", + "org.testcontainers.shaded.org.bouncycastle.crypto.fpe", + "org.testcontainers.shaded.org.bouncycastle.crypto.generators", + "org.testcontainers.shaded.org.bouncycastle.crypto.hpke", + "org.testcontainers.shaded.org.bouncycastle.crypto.io", + "org.testcontainers.shaded.org.bouncycastle.crypto.kems", + "org.testcontainers.shaded.org.bouncycastle.crypto.macs", + "org.testcontainers.shaded.org.bouncycastle.crypto.modes", + "org.testcontainers.shaded.org.bouncycastle.crypto.modes.gcm", + "org.testcontainers.shaded.org.bouncycastle.crypto.modes.kgcm", + "org.testcontainers.shaded.org.bouncycastle.crypto.paddings", + "org.testcontainers.shaded.org.bouncycastle.crypto.params", + "org.testcontainers.shaded.org.bouncycastle.crypto.parsers", + "org.testcontainers.shaded.org.bouncycastle.crypto.prng", + "org.testcontainers.shaded.org.bouncycastle.crypto.prng.drbg", + "org.testcontainers.shaded.org.bouncycastle.crypto.signers", + "org.testcontainers.shaded.org.bouncycastle.crypto.threshold", + "org.testcontainers.shaded.org.bouncycastle.crypto.tls", + "org.testcontainers.shaded.org.bouncycastle.crypto.util", + "org.testcontainers.shaded.org.bouncycastle.dvcs", + "org.testcontainers.shaded.org.bouncycastle.eac", + "org.testcontainers.shaded.org.bouncycastle.eac.jcajce", + "org.testcontainers.shaded.org.bouncycastle.eac.operator", + "org.testcontainers.shaded.org.bouncycastle.eac.operator.jcajce", + "org.testcontainers.shaded.org.bouncycastle.est", + "org.testcontainers.shaded.org.bouncycastle.est.jcajce", + "org.testcontainers.shaded.org.bouncycastle.i18n", + "org.testcontainers.shaded.org.bouncycastle.i18n.filter", + "org.testcontainers.shaded.org.bouncycastle.iana", + "org.testcontainers.shaded.org.bouncycastle.internal.asn1.bsi", + "org.testcontainers.shaded.org.bouncycastle.internal.asn1.cms", + "org.testcontainers.shaded.org.bouncycastle.internal.asn1.cryptlib", + "org.testcontainers.shaded.org.bouncycastle.internal.asn1.eac", + "org.testcontainers.shaded.org.bouncycastle.internal.asn1.edec", + "org.testcontainers.shaded.org.bouncycastle.internal.asn1.gnu", + "org.testcontainers.shaded.org.bouncycastle.internal.asn1.iana", + "org.testcontainers.shaded.org.bouncycastle.internal.asn1.isara", + "org.testcontainers.shaded.org.bouncycastle.internal.asn1.isismtt", + "org.testcontainers.shaded.org.bouncycastle.internal.asn1.iso", + "org.testcontainers.shaded.org.bouncycastle.internal.asn1.kisa", + "org.testcontainers.shaded.org.bouncycastle.internal.asn1.microsoft", + "org.testcontainers.shaded.org.bouncycastle.internal.asn1.misc", + "org.testcontainers.shaded.org.bouncycastle.internal.asn1.nsri", + "org.testcontainers.shaded.org.bouncycastle.internal.asn1.ntt", + "org.testcontainers.shaded.org.bouncycastle.internal.asn1.oiw", + "org.testcontainers.shaded.org.bouncycastle.internal.asn1.rosstandart", + "org.testcontainers.shaded.org.bouncycastle.its", + "org.testcontainers.shaded.org.bouncycastle.its.bc", + "org.testcontainers.shaded.org.bouncycastle.its.jcajce", + "org.testcontainers.shaded.org.bouncycastle.its.operator", + "org.testcontainers.shaded.org.bouncycastle.jcajce", + "org.testcontainers.shaded.org.bouncycastle.jcajce.interfaces", + "org.testcontainers.shaded.org.bouncycastle.jcajce.io", + "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.asymmetric", + "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.asymmetric.compositesignatures", + "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.asymmetric.dh", + "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.asymmetric.dsa", + "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.asymmetric.dstu", + "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.asymmetric.ec", + "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.asymmetric.ecgost", + "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.asymmetric.ecgost12", + "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.asymmetric.edec", + "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.asymmetric.elgamal", + "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.asymmetric.gost", + "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.asymmetric.ies", + "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.asymmetric.mldsa", + "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.asymmetric.mlkem", + "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.asymmetric.rsa", + "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.asymmetric.slhdsa", + "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.asymmetric.util", + "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.asymmetric.x509", + "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.config", + "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.digest", + "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.drbg", + "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.keystore", + "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.keystore.bc", + "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.keystore.bcfks", + "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.keystore.pkcs12", + "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.keystore.util", + "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.symmetric", + "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.symmetric.util", + "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.util", + "org.testcontainers.shaded.org.bouncycastle.jcajce.spec", + "org.testcontainers.shaded.org.bouncycastle.jcajce.util", + "org.testcontainers.shaded.org.bouncycastle.jce", + "org.testcontainers.shaded.org.bouncycastle.jce.exception", + "org.testcontainers.shaded.org.bouncycastle.jce.interfaces", + "org.testcontainers.shaded.org.bouncycastle.jce.netscape", + "org.testcontainers.shaded.org.bouncycastle.jce.provider", + "org.testcontainers.shaded.org.bouncycastle.jce.spec", + "org.testcontainers.shaded.org.bouncycastle.math", + "org.testcontainers.shaded.org.bouncycastle.math.ec", + "org.testcontainers.shaded.org.bouncycastle.math.ec.custom.djb", + "org.testcontainers.shaded.org.bouncycastle.math.ec.custom.gm", + "org.testcontainers.shaded.org.bouncycastle.math.ec.custom.sec", + "org.testcontainers.shaded.org.bouncycastle.math.ec.endo", + "org.testcontainers.shaded.org.bouncycastle.math.ec.rfc7748", + "org.testcontainers.shaded.org.bouncycastle.math.ec.rfc8032", + "org.testcontainers.shaded.org.bouncycastle.math.ec.tools", + "org.testcontainers.shaded.org.bouncycastle.math.field", + "org.testcontainers.shaded.org.bouncycastle.math.raw", + "org.testcontainers.shaded.org.bouncycastle.mime", + "org.testcontainers.shaded.org.bouncycastle.mime.encoding", + "org.testcontainers.shaded.org.bouncycastle.mime.smime", + "org.testcontainers.shaded.org.bouncycastle.mozilla", + "org.testcontainers.shaded.org.bouncycastle.mozilla.jcajce", + "org.testcontainers.shaded.org.bouncycastle.oer", + "org.testcontainers.shaded.org.bouncycastle.oer.its", + "org.testcontainers.shaded.org.bouncycastle.oer.its.etsi102941", + "org.testcontainers.shaded.org.bouncycastle.oer.its.etsi102941.basetypes", + "org.testcontainers.shaded.org.bouncycastle.oer.its.etsi103097", + "org.testcontainers.shaded.org.bouncycastle.oer.its.etsi103097.extension", + "org.testcontainers.shaded.org.bouncycastle.oer.its.ieee1609dot2", + "org.testcontainers.shaded.org.bouncycastle.oer.its.ieee1609dot2.basetypes", + "org.testcontainers.shaded.org.bouncycastle.oer.its.ieee1609dot2dot1", + "org.testcontainers.shaded.org.bouncycastle.oer.its.template.etsi102941", + "org.testcontainers.shaded.org.bouncycastle.oer.its.template.etsi102941.basetypes", + "org.testcontainers.shaded.org.bouncycastle.oer.its.template.etsi103097", + "org.testcontainers.shaded.org.bouncycastle.oer.its.template.etsi103097.extension", + "org.testcontainers.shaded.org.bouncycastle.oer.its.template.ieee1609dot2", + "org.testcontainers.shaded.org.bouncycastle.oer.its.template.ieee1609dot2.basetypes", + "org.testcontainers.shaded.org.bouncycastle.oer.its.template.ieee1609dot2dot1", + "org.testcontainers.shaded.org.bouncycastle.openssl", + "org.testcontainers.shaded.org.bouncycastle.openssl.bc", + "org.testcontainers.shaded.org.bouncycastle.openssl.jcajce", + "org.testcontainers.shaded.org.bouncycastle.operator", + "org.testcontainers.shaded.org.bouncycastle.operator.bc", + "org.testcontainers.shaded.org.bouncycastle.operator.jcajce", + "org.testcontainers.shaded.org.bouncycastle.pkcs", + "org.testcontainers.shaded.org.bouncycastle.pkcs.bc", + "org.testcontainers.shaded.org.bouncycastle.pkcs.jcajce", + "org.testcontainers.shaded.org.bouncycastle.pkix", + "org.testcontainers.shaded.org.bouncycastle.pkix.jcajce", + "org.testcontainers.shaded.org.bouncycastle.pkix.util", + "org.testcontainers.shaded.org.bouncycastle.pkix.util.filter", + "org.testcontainers.shaded.org.bouncycastle.pqc.asn1", + "org.testcontainers.shaded.org.bouncycastle.pqc.crypto", + "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.bike", + "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.cmce", + "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.crystals.dilithium", + "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.falcon", + "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.frodo", + "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.hqc", + "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.lms", + "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.mayo", + "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.mldsa", + "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.mlkem", + "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.newhope", + "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.ntru", + "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.ntruprime", + "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.picnic", + "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.rainbow", + "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.saber", + "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.slhdsa", + "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.snova", + "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.sphincs", + "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.sphincsplus", + "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.util", + "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.xmss", + "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.xwing", + "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.interfaces", + "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider", + "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider.bike", + "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider.cmce", + "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider.dilithium", + "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider.falcon", + "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider.frodo", + "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider.hqc", + "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider.kyber", + "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider.lms", + "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider.mayo", + "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider.newhope", + "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider.ntru", + "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider.ntruprime", + "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider.picnic", + "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider.saber", + "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider.snova", + "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider.sphincs", + "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider.sphincsplus", + "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider.util", + "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider.xmss", + "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.spec", + "org.testcontainers.shaded.org.bouncycastle.pqc.math.ntru", + "org.testcontainers.shaded.org.bouncycastle.pqc.math.ntru.parameters", + "org.testcontainers.shaded.org.bouncycastle.tsp", + "org.testcontainers.shaded.org.bouncycastle.tsp.cms", + "org.testcontainers.shaded.org.bouncycastle.tsp.ers", + "org.testcontainers.shaded.org.bouncycastle.util", + "org.testcontainers.shaded.org.bouncycastle.util.encoders", + "org.testcontainers.shaded.org.bouncycastle.util.io", + "org.testcontainers.shaded.org.bouncycastle.util.io.pem", + "org.testcontainers.shaded.org.bouncycastle.util.test", + "org.testcontainers.shaded.org.bouncycastle.voms", + "org.testcontainers.shaded.org.bouncycastle.x509", + "org.testcontainers.shaded.org.bouncycastle.x509.extension", + "org.testcontainers.shaded.org.bouncycastle.x509.util", + "org.testcontainers.shaded.org.checkerframework.checker.builder.qual", + "org.testcontainers.shaded.org.checkerframework.checker.calledmethods.qual", + "org.testcontainers.shaded.org.checkerframework.checker.compilermsgs.qual", + "org.testcontainers.shaded.org.checkerframework.checker.fenum.qual", + "org.testcontainers.shaded.org.checkerframework.checker.formatter.qual", + "org.testcontainers.shaded.org.checkerframework.checker.guieffect.qual", + "org.testcontainers.shaded.org.checkerframework.checker.i18n.qual", + "org.testcontainers.shaded.org.checkerframework.checker.i18nformatter.qual", + "org.testcontainers.shaded.org.checkerframework.checker.index.qual", + "org.testcontainers.shaded.org.checkerframework.checker.initialization.qual", + "org.testcontainers.shaded.org.checkerframework.checker.interning.qual", + "org.testcontainers.shaded.org.checkerframework.checker.lock.qual", + "org.testcontainers.shaded.org.checkerframework.checker.mustcall.qual", + "org.testcontainers.shaded.org.checkerframework.checker.nullness.qual", + "org.testcontainers.shaded.org.checkerframework.checker.optional.qual", + "org.testcontainers.shaded.org.checkerframework.checker.propkey.qual", + "org.testcontainers.shaded.org.checkerframework.checker.regex.qual", + "org.testcontainers.shaded.org.checkerframework.checker.signature.qual", + "org.testcontainers.shaded.org.checkerframework.checker.signedness.qual", + "org.testcontainers.shaded.org.checkerframework.checker.tainting.qual", + "org.testcontainers.shaded.org.checkerframework.checker.units.qual", + "org.testcontainers.shaded.org.checkerframework.common.aliasing.qual", + "org.testcontainers.shaded.org.checkerframework.common.initializedfields.qual", + "org.testcontainers.shaded.org.checkerframework.common.reflection.qual", + "org.testcontainers.shaded.org.checkerframework.common.returnsreceiver.qual", + "org.testcontainers.shaded.org.checkerframework.common.subtyping.qual", + "org.testcontainers.shaded.org.checkerframework.common.util.count.report.qual", + "org.testcontainers.shaded.org.checkerframework.common.value.qual", + "org.testcontainers.shaded.org.checkerframework.dataflow.qual", + "org.testcontainers.shaded.org.checkerframework.framework.qual", + "org.testcontainers.shaded.org.hamcrest", + "org.testcontainers.shaded.org.hamcrest.beans", + "org.testcontainers.shaded.org.hamcrest.collection", + "org.testcontainers.shaded.org.hamcrest.comparator", + "org.testcontainers.shaded.org.hamcrest.core", + "org.testcontainers.shaded.org.hamcrest.internal", + "org.testcontainers.shaded.org.hamcrest.io", + "org.testcontainers.shaded.org.hamcrest.number", + "org.testcontainers.shaded.org.hamcrest.object", + "org.testcontainers.shaded.org.hamcrest.text", + "org.testcontainers.shaded.org.hamcrest.xml", + "org.testcontainers.shaded.org.yaml.snakeyaml", + "org.testcontainers.shaded.org.yaml.snakeyaml.comments", + "org.testcontainers.shaded.org.yaml.snakeyaml.composer", + "org.testcontainers.shaded.org.yaml.snakeyaml.constructor", + "org.testcontainers.shaded.org.yaml.snakeyaml.emitter", + "org.testcontainers.shaded.org.yaml.snakeyaml.env", + "org.testcontainers.shaded.org.yaml.snakeyaml.error", + "org.testcontainers.shaded.org.yaml.snakeyaml.events", + "org.testcontainers.shaded.org.yaml.snakeyaml.extensions.compactnotation", + "org.testcontainers.shaded.org.yaml.snakeyaml.external.com.google.gdata.util.common.base", + "org.testcontainers.shaded.org.yaml.snakeyaml.inspector", + "org.testcontainers.shaded.org.yaml.snakeyaml.internal", + "org.testcontainers.shaded.org.yaml.snakeyaml.introspector", + "org.testcontainers.shaded.org.yaml.snakeyaml.nodes", + "org.testcontainers.shaded.org.yaml.snakeyaml.parser", + "org.testcontainers.shaded.org.yaml.snakeyaml.reader", + "org.testcontainers.shaded.org.yaml.snakeyaml.representer", + "org.testcontainers.shaded.org.yaml.snakeyaml.resolver", + "org.testcontainers.shaded.org.yaml.snakeyaml.scanner", + "org.testcontainers.shaded.org.yaml.snakeyaml.serializer", + "org.testcontainers.shaded.org.yaml.snakeyaml.tokens", + "org.testcontainers.shaded.org.yaml.snakeyaml.util", + "org.testcontainers.shaded.org.zeroturnaround.exec", + "org.testcontainers.shaded.org.zeroturnaround.exec.close", + "org.testcontainers.shaded.org.zeroturnaround.exec.listener", + "org.testcontainers.shaded.org.zeroturnaround.exec.stop", + "org.testcontainers.shaded.org.zeroturnaround.exec.stream", + "org.testcontainers.shaded.org.zeroturnaround.exec.stream.slf4j", + "org.testcontainers.utility" + ], + "org.testcontainers:testcontainers-cassandra": [ + "org.testcontainers.cassandra", + "org.testcontainers.containers", + "org.testcontainers.containers.delegate", + "org.testcontainers.containers.wait" + ], + "org.testcontainers:testcontainers-database-commons": [ + "org.testcontainers.delegate", + "org.testcontainers.exception", + "org.testcontainers.ext" + ], + "org.testcontainers:testcontainers-junit-jupiter": [ + "org.testcontainers.junit.jupiter" + ], + "org.testcontainers:testcontainers-localstack": [ + "org.testcontainers.containers.localstack", + "org.testcontainers.localstack" + ], + "org.wiremock:wiremock-standalone": [ + "com.github.tomakehurst.wiremock", + "com.github.tomakehurst.wiremock.admin", + "com.github.tomakehurst.wiremock.admin.model", + "com.github.tomakehurst.wiremock.admin.tasks", + "com.github.tomakehurst.wiremock.client", + "com.github.tomakehurst.wiremock.common", + "com.github.tomakehurst.wiremock.common.filemaker", + "com.github.tomakehurst.wiremock.common.ssl", + "com.github.tomakehurst.wiremock.common.url", + "com.github.tomakehurst.wiremock.common.xml", + "com.github.tomakehurst.wiremock.core", + "com.github.tomakehurst.wiremock.direct", + "com.github.tomakehurst.wiremock.extension", + "com.github.tomakehurst.wiremock.extension.requestfilter", + "com.github.tomakehurst.wiremock.extension.responsetemplating", + "com.github.tomakehurst.wiremock.extension.responsetemplating.helpers", + "com.github.tomakehurst.wiremock.global", + "com.github.tomakehurst.wiremock.http", + "com.github.tomakehurst.wiremock.http.client", + "com.github.tomakehurst.wiremock.http.multipart", + "com.github.tomakehurst.wiremock.http.ssl", + "com.github.tomakehurst.wiremock.http.trafficlistener", + "com.github.tomakehurst.wiremock.jetty", + "com.github.tomakehurst.wiremock.jetty11", + "com.github.tomakehurst.wiremock.junit", + "com.github.tomakehurst.wiremock.junit5", + "com.github.tomakehurst.wiremock.matching", + "com.github.tomakehurst.wiremock.recording", + "com.github.tomakehurst.wiremock.security", + "com.github.tomakehurst.wiremock.servlet", + "com.github.tomakehurst.wiremock.standalone", + "com.github.tomakehurst.wiremock.store", + "com.github.tomakehurst.wiremock.store.files", + "com.github.tomakehurst.wiremock.stubbing", + "com.github.tomakehurst.wiremock.verification", + "com.github.tomakehurst.wiremock.verification.diff", + "com.github.tomakehurst.wiremock.verification.notmatched", + "org.jspecify.annotations", + "org.wiremock.annotations", + "org.wiremock.webhooks", + "wiremock", + "wiremock.com.ethlo.time", + "wiremock.com.ethlo.time.internal", + "wiremock.com.ethlo.time.internal.fixed", + "wiremock.com.ethlo.time.internal.token", + "wiremock.com.ethlo.time.internal.util", + "wiremock.com.ethlo.time.token", + "wiremock.com.fasterxml.jackson.annotation", + "wiremock.com.fasterxml.jackson.core", + "wiremock.com.fasterxml.jackson.core.async", + "wiremock.com.fasterxml.jackson.core.base", + "wiremock.com.fasterxml.jackson.core.exc", + "wiremock.com.fasterxml.jackson.core.filter", + "wiremock.com.fasterxml.jackson.core.format", + "wiremock.com.fasterxml.jackson.core.internal.shaded.fdp.v2_20_1", + "wiremock.com.fasterxml.jackson.core.internal.shaded.fdp.v2_20_1.bte", + "wiremock.com.fasterxml.jackson.core.internal.shaded.fdp.v2_20_1.chr", + "wiremock.com.fasterxml.jackson.core.io", + "wiremock.com.fasterxml.jackson.core.io.schubfach", + "wiremock.com.fasterxml.jackson.core.json", + "wiremock.com.fasterxml.jackson.core.json.async", + "wiremock.com.fasterxml.jackson.core.sym", + "wiremock.com.fasterxml.jackson.core.type", + "wiremock.com.fasterxml.jackson.core.util", + "wiremock.com.fasterxml.jackson.databind", + "wiremock.com.fasterxml.jackson.databind.annotation", + "wiremock.com.fasterxml.jackson.databind.cfg", + "wiremock.com.fasterxml.jackson.databind.deser", + "wiremock.com.fasterxml.jackson.databind.deser.impl", + "wiremock.com.fasterxml.jackson.databind.deser.std", + "wiremock.com.fasterxml.jackson.databind.exc", + "wiremock.com.fasterxml.jackson.databind.ext", + "wiremock.com.fasterxml.jackson.databind.introspect", + "wiremock.com.fasterxml.jackson.databind.jdk14", + "wiremock.com.fasterxml.jackson.databind.json", + "wiremock.com.fasterxml.jackson.databind.jsonFormatVisitors", + "wiremock.com.fasterxml.jackson.databind.jsonschema", + "wiremock.com.fasterxml.jackson.databind.jsontype", + "wiremock.com.fasterxml.jackson.databind.jsontype.impl", + "wiremock.com.fasterxml.jackson.databind.module", + "wiremock.com.fasterxml.jackson.databind.node", + "wiremock.com.fasterxml.jackson.databind.ser", + "wiremock.com.fasterxml.jackson.databind.ser.impl", + "wiremock.com.fasterxml.jackson.databind.ser.std", + "wiremock.com.fasterxml.jackson.databind.type", + "wiremock.com.fasterxml.jackson.databind.util", + "wiremock.com.fasterxml.jackson.databind.util.internal", + "wiremock.com.fasterxml.jackson.dataformat.yaml", + "wiremock.com.fasterxml.jackson.dataformat.yaml.snakeyaml.error", + "wiremock.com.fasterxml.jackson.dataformat.yaml.util", + "wiremock.com.fasterxml.jackson.datatype.jsr310", + "wiremock.com.fasterxml.jackson.datatype.jsr310.deser", + "wiremock.com.fasterxml.jackson.datatype.jsr310.deser.key", + "wiremock.com.fasterxml.jackson.datatype.jsr310.ser", + "wiremock.com.fasterxml.jackson.datatype.jsr310.ser.key", + "wiremock.com.fasterxml.jackson.datatype.jsr310.util", + "wiremock.com.github.jknack.handlebars", + "wiremock.com.github.jknack.handlebars.cache", + "wiremock.com.github.jknack.handlebars.context", + "wiremock.com.github.jknack.handlebars.helper", + "wiremock.com.github.jknack.handlebars.internal", + "wiremock.com.github.jknack.handlebars.internal.antlr", + "wiremock.com.github.jknack.handlebars.internal.antlr.atn", + "wiremock.com.github.jknack.handlebars.internal.antlr.dfa", + "wiremock.com.github.jknack.handlebars.internal.antlr.misc", + "wiremock.com.github.jknack.handlebars.internal.antlr.tree", + "wiremock.com.github.jknack.handlebars.internal.antlr.tree.pattern", + "wiremock.com.github.jknack.handlebars.internal.antlr.tree.xpath", + "wiremock.com.github.jknack.handlebars.internal.lang3", + "wiremock.com.github.jknack.handlebars.internal.lang3.builder", + "wiremock.com.github.jknack.handlebars.internal.lang3.exception", + "wiremock.com.github.jknack.handlebars.internal.lang3.function", + "wiremock.com.github.jknack.handlebars.internal.lang3.math", + "wiremock.com.github.jknack.handlebars.internal.lang3.mutable", + "wiremock.com.github.jknack.handlebars.internal.lang3.text", + "wiremock.com.github.jknack.handlebars.internal.lang3.text.translate", + "wiremock.com.github.jknack.handlebars.internal.lang3.time", + "wiremock.com.github.jknack.handlebars.internal.lang3.tuple", + "wiremock.com.github.jknack.handlebars.internal.path", + "wiremock.com.github.jknack.handlebars.internal.text", + "wiremock.com.github.jknack.handlebars.internal.text.diff", + "wiremock.com.github.jknack.handlebars.internal.text.io", + "wiremock.com.github.jknack.handlebars.internal.text.lookup", + "wiremock.com.github.jknack.handlebars.internal.text.matcher", + "wiremock.com.github.jknack.handlebars.internal.text.numbers", + "wiremock.com.github.jknack.handlebars.internal.text.similarity", + "wiremock.com.github.jknack.handlebars.internal.text.translate", + "wiremock.com.github.jknack.handlebars.io", + "wiremock.com.google.common.annotations", + "wiremock.com.google.common.base", + "wiremock.com.google.common.base.internal", + "wiremock.com.google.common.cache", + "wiremock.com.google.common.collect", + "wiremock.com.google.common.escape", + "wiremock.com.google.common.eventbus", + "wiremock.com.google.common.graph", + "wiremock.com.google.common.hash", + "wiremock.com.google.common.html", + "wiremock.com.google.common.io", + "wiremock.com.google.common.math", + "wiremock.com.google.common.net", + "wiremock.com.google.common.primitives", + "wiremock.com.google.common.reflect", + "wiremock.com.google.common.util.concurrent", + "wiremock.com.google.common.util.concurrent.internal", + "wiremock.com.google.common.xml", + "wiremock.com.google.errorprone.annotations", + "wiremock.com.google.errorprone.annotations.concurrent", + "wiremock.com.google.j2objc.annotations", + "wiremock.com.google.thirdparty.publicsuffix", + "wiremock.com.jayway.jsonpath", + "wiremock.com.jayway.jsonpath.internal", + "wiremock.com.jayway.jsonpath.internal.filter", + "wiremock.com.jayway.jsonpath.internal.function", + "wiremock.com.jayway.jsonpath.internal.function.json", + "wiremock.com.jayway.jsonpath.internal.function.latebinding", + "wiremock.com.jayway.jsonpath.internal.function.numeric", + "wiremock.com.jayway.jsonpath.internal.function.sequence", + "wiremock.com.jayway.jsonpath.internal.function.text", + "wiremock.com.jayway.jsonpath.internal.path", + "wiremock.com.jayway.jsonpath.spi.cache", + "wiremock.com.jayway.jsonpath.spi.json", + "wiremock.com.jayway.jsonpath.spi.mapper", + "wiremock.com.networknt.org.apache.commons.validator.routines", + "wiremock.com.networknt.schema", + "wiremock.com.networknt.schema.annotation", + "wiremock.com.networknt.schema.format", + "wiremock.com.networknt.schema.i18n", + "wiremock.com.networknt.schema.oas", + "wiremock.com.networknt.schema.output", + "wiremock.com.networknt.schema.regex", + "wiremock.com.networknt.schema.resource", + "wiremock.com.networknt.schema.result", + "wiremock.com.networknt.schema.serialization", + "wiremock.com.networknt.schema.serialization.node", + "wiremock.com.networknt.schema.utils", + "wiremock.com.networknt.schema.walk", + "wiremock.jakarta.servlet", + "wiremock.jakarta.servlet.annotation", + "wiremock.jakarta.servlet.descriptor", + "wiremock.jakarta.servlet.http", + "wiremock.joptsimple", + "wiremock.joptsimple.internal", + "wiremock.joptsimple.util", + "wiremock.net.javacrumbs.jsonunit.core", + "wiremock.net.javacrumbs.jsonunit.core.internal", + "wiremock.net.javacrumbs.jsonunit.core.internal.matchers", + "wiremock.net.javacrumbs.jsonunit.core.listener", + "wiremock.net.javacrumbs.jsonunit.core.util", + "wiremock.net.javacrumbs.jsonunit.providers", + "wiremock.net.minidev.asm", + "wiremock.net.minidev.asm.ex", + "wiremock.net.minidev.json", + "wiremock.net.minidev.json.annotate", + "wiremock.net.minidev.json.parser", + "wiremock.net.minidev.json.reader", + "wiremock.net.minidev.json.writer", + "wiremock.org.apache.commons.fileupload", + "wiremock.org.apache.commons.fileupload.disk", + "wiremock.org.apache.commons.fileupload.portlet", + "wiremock.org.apache.commons.fileupload.servlet", + "wiremock.org.apache.commons.fileupload.util", + "wiremock.org.apache.commons.fileupload.util.mime", + "wiremock.org.apache.commons.io", + "wiremock.org.apache.commons.io.build", + "wiremock.org.apache.commons.io.channels", + "wiremock.org.apache.commons.io.charset", + "wiremock.org.apache.commons.io.comparator", + "wiremock.org.apache.commons.io.file", + "wiremock.org.apache.commons.io.file.attribute", + "wiremock.org.apache.commons.io.file.spi", + "wiremock.org.apache.commons.io.filefilter", + "wiremock.org.apache.commons.io.function", + "wiremock.org.apache.commons.io.input", + "wiremock.org.apache.commons.io.input.buffer", + "wiremock.org.apache.commons.io.monitor", + "wiremock.org.apache.commons.io.output", + "wiremock.org.apache.commons.io.serialization", + "wiremock.org.apache.hc.client5.http", + "wiremock.org.apache.hc.client5.http.async", + "wiremock.org.apache.hc.client5.http.async.methods", + "wiremock.org.apache.hc.client5.http.auth", + "wiremock.org.apache.hc.client5.http.classic", + "wiremock.org.apache.hc.client5.http.classic.methods", + "wiremock.org.apache.hc.client5.http.config", + "wiremock.org.apache.hc.client5.http.cookie", + "wiremock.org.apache.hc.client5.http.entity", + "wiremock.org.apache.hc.client5.http.entity.mime", + "wiremock.org.apache.hc.client5.http.impl", + "wiremock.org.apache.hc.client5.http.impl.async", + "wiremock.org.apache.hc.client5.http.impl.auth", + "wiremock.org.apache.hc.client5.http.impl.classic", + "wiremock.org.apache.hc.client5.http.impl.compat", + "wiremock.org.apache.hc.client5.http.impl.cookie", + "wiremock.org.apache.hc.client5.http.impl.io", + "wiremock.org.apache.hc.client5.http.impl.nio", + "wiremock.org.apache.hc.client5.http.impl.routing", + "wiremock.org.apache.hc.client5.http.io", + "wiremock.org.apache.hc.client5.http.nio", + "wiremock.org.apache.hc.client5.http.protocol", + "wiremock.org.apache.hc.client5.http.psl", + "wiremock.org.apache.hc.client5.http.routing", + "wiremock.org.apache.hc.client5.http.socket", + "wiremock.org.apache.hc.client5.http.ssl", + "wiremock.org.apache.hc.client5.http.utils", + "wiremock.org.apache.hc.client5.http.validator", + "wiremock.org.apache.hc.core5.annotation", + "wiremock.org.apache.hc.core5.concurrent", + "wiremock.org.apache.hc.core5.function", + "wiremock.org.apache.hc.core5.http", + "wiremock.org.apache.hc.core5.http.config", + "wiremock.org.apache.hc.core5.http.impl", + "wiremock.org.apache.hc.core5.http.impl.bootstrap", + "wiremock.org.apache.hc.core5.http.impl.io", + "wiremock.org.apache.hc.core5.http.impl.nio", + "wiremock.org.apache.hc.core5.http.impl.routing", + "wiremock.org.apache.hc.core5.http.io", + "wiremock.org.apache.hc.core5.http.io.entity", + "wiremock.org.apache.hc.core5.http.io.ssl", + "wiremock.org.apache.hc.core5.http.io.support", + "wiremock.org.apache.hc.core5.http.message", + "wiremock.org.apache.hc.core5.http.nio", + "wiremock.org.apache.hc.core5.http.nio.command", + "wiremock.org.apache.hc.core5.http.nio.entity", + "wiremock.org.apache.hc.core5.http.nio.ssl", + "wiremock.org.apache.hc.core5.http.nio.support", + "wiremock.org.apache.hc.core5.http.nio.support.classic", + "wiremock.org.apache.hc.core5.http.protocol", + "wiremock.org.apache.hc.core5.http.ssl", + "wiremock.org.apache.hc.core5.http.support", + "wiremock.org.apache.hc.core5.http2", + "wiremock.org.apache.hc.core5.http2.config", + "wiremock.org.apache.hc.core5.http2.frame", + "wiremock.org.apache.hc.core5.http2.hpack", + "wiremock.org.apache.hc.core5.http2.impl", + "wiremock.org.apache.hc.core5.http2.impl.io", + "wiremock.org.apache.hc.core5.http2.impl.nio", + "wiremock.org.apache.hc.core5.http2.impl.nio.bootstrap", + "wiremock.org.apache.hc.core5.http2.nio", + "wiremock.org.apache.hc.core5.http2.nio.command", + "wiremock.org.apache.hc.core5.http2.nio.pool", + "wiremock.org.apache.hc.core5.http2.nio.support", + "wiremock.org.apache.hc.core5.http2.protocol", + "wiremock.org.apache.hc.core5.http2.ssl", + "wiremock.org.apache.hc.core5.io", + "wiremock.org.apache.hc.core5.net", + "wiremock.org.apache.hc.core5.pool", + "wiremock.org.apache.hc.core5.reactor", + "wiremock.org.apache.hc.core5.reactor.ssl", + "wiremock.org.apache.hc.core5.ssl", + "wiremock.org.apache.hc.core5.util", + "wiremock.org.custommonkey.xmlunit", + "wiremock.org.custommonkey.xmlunit.examples", + "wiremock.org.custommonkey.xmlunit.exceptions", + "wiremock.org.custommonkey.xmlunit.jaxp13", + "wiremock.org.custommonkey.xmlunit.util", + "wiremock.org.eclipse.jetty.alpn.client", + "wiremock.org.eclipse.jetty.alpn.java.client", + "wiremock.org.eclipse.jetty.alpn.java.server", + "wiremock.org.eclipse.jetty.alpn.server", + "wiremock.org.eclipse.jetty.client", + "wiremock.org.eclipse.jetty.client.api", + "wiremock.org.eclipse.jetty.client.dynamic", + "wiremock.org.eclipse.jetty.client.http", + "wiremock.org.eclipse.jetty.client.internal", + "wiremock.org.eclipse.jetty.client.jmx", + "wiremock.org.eclipse.jetty.client.util", + "wiremock.org.eclipse.jetty.http", + "wiremock.org.eclipse.jetty.http.compression", + "wiremock.org.eclipse.jetty.http.pathmap", + "wiremock.org.eclipse.jetty.http2", + "wiremock.org.eclipse.jetty.http2.api", + "wiremock.org.eclipse.jetty.http2.api.server", + "wiremock.org.eclipse.jetty.http2.frames", + "wiremock.org.eclipse.jetty.http2.generator", + "wiremock.org.eclipse.jetty.http2.hpack", + "wiremock.org.eclipse.jetty.http2.parser", + "wiremock.org.eclipse.jetty.http2.server", + "wiremock.org.eclipse.jetty.io", + "wiremock.org.eclipse.jetty.io.jmx", + "wiremock.org.eclipse.jetty.io.ssl", + "wiremock.org.eclipse.jetty.proxy", + "wiremock.org.eclipse.jetty.security", + "wiremock.org.eclipse.jetty.security.authentication", + "wiremock.org.eclipse.jetty.server", + "wiremock.org.eclipse.jetty.server.handler", + "wiremock.org.eclipse.jetty.server.handler.gzip", + "wiremock.org.eclipse.jetty.server.handler.jmx", + "wiremock.org.eclipse.jetty.server.jmx", + "wiremock.org.eclipse.jetty.server.resource", + "wiremock.org.eclipse.jetty.server.session", + "wiremock.org.eclipse.jetty.servlet", + "wiremock.org.eclipse.jetty.servlet.jmx", + "wiremock.org.eclipse.jetty.servlet.listener", + "wiremock.org.eclipse.jetty.servlets", + "wiremock.org.eclipse.jetty.util", + "wiremock.org.eclipse.jetty.util.annotation", + "wiremock.org.eclipse.jetty.util.component", + "wiremock.org.eclipse.jetty.util.compression", + "wiremock.org.eclipse.jetty.util.log", + "wiremock.org.eclipse.jetty.util.preventers", + "wiremock.org.eclipse.jetty.util.resource", + "wiremock.org.eclipse.jetty.util.security", + "wiremock.org.eclipse.jetty.util.ssl", + "wiremock.org.eclipse.jetty.util.statistic", + "wiremock.org.eclipse.jetty.util.thread", + "wiremock.org.eclipse.jetty.util.thread.strategy", + "wiremock.org.eclipse.jetty.webapp", + "wiremock.org.eclipse.jetty.xml", + "wiremock.org.hamcrest", + "wiremock.org.hamcrest.beans", + "wiremock.org.hamcrest.collection", + "wiremock.org.hamcrest.comparator", + "wiremock.org.hamcrest.core", + "wiremock.org.hamcrest.core.deprecated", + "wiremock.org.hamcrest.internal", + "wiremock.org.hamcrest.io", + "wiremock.org.hamcrest.number", + "wiremock.org.hamcrest.object", + "wiremock.org.hamcrest.text", + "wiremock.org.hamcrest.xml", + "wiremock.org.slf4j", + "wiremock.org.slf4j.event", + "wiremock.org.slf4j.helpers", + "wiremock.org.slf4j.spi", + "wiremock.org.xmlunit", + "wiremock.org.xmlunit.builder", + "wiremock.org.xmlunit.builder.javax_jaxb", + "wiremock.org.xmlunit.diff", + "wiremock.org.xmlunit.input", + "wiremock.org.xmlunit.placeholder", + "wiremock.org.xmlunit.transform", + "wiremock.org.xmlunit.util", + "wiremock.org.xmlunit.validation", + "wiremock.org.xmlunit.xpath", + "wiremock.org.yaml.snakeyaml", + "wiremock.org.yaml.snakeyaml.comments", + "wiremock.org.yaml.snakeyaml.composer", + "wiremock.org.yaml.snakeyaml.constructor", + "wiremock.org.yaml.snakeyaml.emitter", + "wiremock.org.yaml.snakeyaml.env", + "wiremock.org.yaml.snakeyaml.error", + "wiremock.org.yaml.snakeyaml.events", + "wiremock.org.yaml.snakeyaml.extensions.compactnotation", + "wiremock.org.yaml.snakeyaml.external.com.google.gdata.util.common.base", + "wiremock.org.yaml.snakeyaml.inspector", + "wiremock.org.yaml.snakeyaml.internal", + "wiremock.org.yaml.snakeyaml.introspector", + "wiremock.org.yaml.snakeyaml.nodes", + "wiremock.org.yaml.snakeyaml.parser", + "wiremock.org.yaml.snakeyaml.reader", + "wiremock.org.yaml.snakeyaml.representer", + "wiremock.org.yaml.snakeyaml.resolver", + "wiremock.org.yaml.snakeyaml.scanner", + "wiremock.org.yaml.snakeyaml.serializer", + "wiremock.org.yaml.snakeyaml.tokens", + "wiremock.org.yaml.snakeyaml.util" + ], + "org.xmlunit:xmlunit-core": [ + "org.xmlunit", + "org.xmlunit.builder", + "org.xmlunit.builder.javax_jaxb", + "org.xmlunit.diff", + "org.xmlunit.input", + "org.xmlunit.transform", + "org.xmlunit.util", + "org.xmlunit.validation", + "org.xmlunit.xpath" + ], + "org.yaml:snakeyaml": [ + "org.yaml.snakeyaml", + "org.yaml.snakeyaml.comments", + "org.yaml.snakeyaml.composer", + "org.yaml.snakeyaml.constructor", + "org.yaml.snakeyaml.emitter", + "org.yaml.snakeyaml.env", + "org.yaml.snakeyaml.error", + "org.yaml.snakeyaml.events", + "org.yaml.snakeyaml.extensions.compactnotation", + "org.yaml.snakeyaml.external.com.google.gdata.util.common.base", + "org.yaml.snakeyaml.inspector", + "org.yaml.snakeyaml.internal", + "org.yaml.snakeyaml.introspector", + "org.yaml.snakeyaml.nodes", + "org.yaml.snakeyaml.parser", + "org.yaml.snakeyaml.reader", + "org.yaml.snakeyaml.representer", + "org.yaml.snakeyaml.resolver", + "org.yaml.snakeyaml.scanner", + "org.yaml.snakeyaml.serializer", + "org.yaml.snakeyaml.tokens", + "org.yaml.snakeyaml.util" + ], + "software.amazon.awssdk:annotations": [ + "software.amazon.awssdk.annotations" + ], + "software.amazon.awssdk:checksums": [ + "software.amazon.awssdk.checksums", + "software.amazon.awssdk.checksums.internal" + ], + "software.amazon.awssdk:checksums-spi": [ + "software.amazon.awssdk.checksums.spi" + ], + "software.amazon.awssdk:endpoints-spi": [ + "software.amazon.awssdk.endpoints" + ], + "software.amazon.awssdk:http-auth-aws": [ + "software.amazon.awssdk.http.auth.aws.crt.internal.io", + "software.amazon.awssdk.http.auth.aws.crt.internal.signer", + "software.amazon.awssdk.http.auth.aws.crt.internal.util", + "software.amazon.awssdk.http.auth.aws.eventstream.internal.io", + "software.amazon.awssdk.http.auth.aws.eventstream.internal.signer", + "software.amazon.awssdk.http.auth.aws.internal.scheme", + "software.amazon.awssdk.http.auth.aws.internal.signer", + "software.amazon.awssdk.http.auth.aws.internal.signer.checksums", + "software.amazon.awssdk.http.auth.aws.internal.signer.chunkedencoding", + "software.amazon.awssdk.http.auth.aws.internal.signer.io", + "software.amazon.awssdk.http.auth.aws.internal.signer.util", + "software.amazon.awssdk.http.auth.aws.scheme", + "software.amazon.awssdk.http.auth.aws.signer" + ], + "software.amazon.awssdk:http-auth-spi": [ + "software.amazon.awssdk.http.auth.spi.internal.scheme", + "software.amazon.awssdk.http.auth.spi.internal.signer", + "software.amazon.awssdk.http.auth.spi.scheme", + "software.amazon.awssdk.http.auth.spi.signer" + ], + "software.amazon.awssdk:http-client-spi": [ + "software.amazon.awssdk.http", + "software.amazon.awssdk.http.async", + "software.amazon.awssdk.internal.http" + ], + "software.amazon.awssdk:identity-spi": [ + "software.amazon.awssdk.identity.spi", + "software.amazon.awssdk.identity.spi.internal" + ], + "software.amazon.awssdk:json-utils": [ + "software.amazon.awssdk.protocols.jsoncore", + "software.amazon.awssdk.protocols.jsoncore.internal" + ], + "software.amazon.awssdk:metrics-spi": [ + "software.amazon.awssdk.metrics", + "software.amazon.awssdk.metrics.internal" + ], + "software.amazon.awssdk:profiles": [ + "software.amazon.awssdk.profiles", + "software.amazon.awssdk.profiles.internal" + ], + "software.amazon.awssdk:regions": [ + "software.amazon.awssdk.regions", + "software.amazon.awssdk.regions.internal", + "software.amazon.awssdk.regions.internal.util", + "software.amazon.awssdk.regions.partitionmetadata", + "software.amazon.awssdk.regions.providers", + "software.amazon.awssdk.regions.regionmetadata", + "software.amazon.awssdk.regions.servicemetadata", + "software.amazon.awssdk.regions.util" + ], + "software.amazon.awssdk:retries": [ + "software.amazon.awssdk.retries", + "software.amazon.awssdk.retries.internal", + "software.amazon.awssdk.retries.internal.circuitbreaker", + "software.amazon.awssdk.retries.internal.ratelimiter" + ], + "software.amazon.awssdk:retries-spi": [ + "software.amazon.awssdk.retries.api", + "software.amazon.awssdk.retries.api.internal", + "software.amazon.awssdk.retries.api.internal.backoff" + ], + "software.amazon.awssdk:sdk-core": [ + "software.amazon.awssdk.core", + "software.amazon.awssdk.core.adapter", + "software.amazon.awssdk.core.async", + "software.amazon.awssdk.core.async.listener", + "software.amazon.awssdk.core.checksums", + "software.amazon.awssdk.core.client.builder", + "software.amazon.awssdk.core.client.config", + "software.amazon.awssdk.core.client.handler", + "software.amazon.awssdk.core.document", + "software.amazon.awssdk.core.document.internal", + "software.amazon.awssdk.core.endpointdiscovery", + "software.amazon.awssdk.core.endpointdiscovery.providers", + "software.amazon.awssdk.core.exception", + "software.amazon.awssdk.core.http", + "software.amazon.awssdk.core.identity", + "software.amazon.awssdk.core.interceptor", + "software.amazon.awssdk.core.interceptor.trait", + "software.amazon.awssdk.core.internal", + "software.amazon.awssdk.core.internal.async", + "software.amazon.awssdk.core.internal.capacity", + "software.amazon.awssdk.core.internal.checksums", + "software.amazon.awssdk.core.internal.chunked", + "software.amazon.awssdk.core.internal.compression", + "software.amazon.awssdk.core.internal.handler", + "software.amazon.awssdk.core.internal.http", + "software.amazon.awssdk.core.internal.http.async", + "software.amazon.awssdk.core.internal.http.loader", + "software.amazon.awssdk.core.internal.http.pipeline", + "software.amazon.awssdk.core.internal.http.pipeline.stages", + "software.amazon.awssdk.core.internal.http.pipeline.stages.utils", + "software.amazon.awssdk.core.internal.http.timers", + "software.amazon.awssdk.core.internal.interceptor", + "software.amazon.awssdk.core.internal.interceptor.trait", + "software.amazon.awssdk.core.internal.io", + "software.amazon.awssdk.core.internal.metrics", + "software.amazon.awssdk.core.internal.pagination.async", + "software.amazon.awssdk.core.internal.retry", + "software.amazon.awssdk.core.internal.signer", + "software.amazon.awssdk.core.internal.sync", + "software.amazon.awssdk.core.internal.transform", + "software.amazon.awssdk.core.internal.useragent", + "software.amazon.awssdk.core.internal.util", + "software.amazon.awssdk.core.internal.waiters", + "software.amazon.awssdk.core.io", + "software.amazon.awssdk.core.metrics", + "software.amazon.awssdk.core.pagination.async", + "software.amazon.awssdk.core.pagination.sync", + "software.amazon.awssdk.core.protocol", + "software.amazon.awssdk.core.retry", + "software.amazon.awssdk.core.retry.backoff", + "software.amazon.awssdk.core.retry.conditions", + "software.amazon.awssdk.core.runtime", + "software.amazon.awssdk.core.runtime.transform", + "software.amazon.awssdk.core.signer", + "software.amazon.awssdk.core.sync", + "software.amazon.awssdk.core.traits", + "software.amazon.awssdk.core.useragent", + "software.amazon.awssdk.core.util", + "software.amazon.awssdk.core.waiters" + ], + "software.amazon.awssdk:third-party-jackson-core": [ + "software.amazon.awssdk.thirdparty.jackson.core", + "software.amazon.awssdk.thirdparty.jackson.core.async", + "software.amazon.awssdk.thirdparty.jackson.core.base", + "software.amazon.awssdk.thirdparty.jackson.core.exc", + "software.amazon.awssdk.thirdparty.jackson.core.filter", + "software.amazon.awssdk.thirdparty.jackson.core.format", + "software.amazon.awssdk.thirdparty.jackson.core.internal.shaded.fdp.v2_19_4", + "software.amazon.awssdk.thirdparty.jackson.core.io", + "software.amazon.awssdk.thirdparty.jackson.core.io.schubfach", + "software.amazon.awssdk.thirdparty.jackson.core.json", + "software.amazon.awssdk.thirdparty.jackson.core.json.async", + "software.amazon.awssdk.thirdparty.jackson.core.sym", + "software.amazon.awssdk.thirdparty.jackson.core.type", + "software.amazon.awssdk.thirdparty.jackson.core.util" + ], + "software.amazon.awssdk:utils": [ + "software.amazon.awssdk.utils", + "software.amazon.awssdk.utils.async", + "software.amazon.awssdk.utils.builder", + "software.amazon.awssdk.utils.cache", + "software.amazon.awssdk.utils.cache.bounded", + "software.amazon.awssdk.utils.cache.lru", + "software.amazon.awssdk.utils.http", + "software.amazon.awssdk.utils.internal", + "software.amazon.awssdk.utils.internal.async", + "software.amazon.awssdk.utils.internal.proxy", + "software.amazon.awssdk.utils.io", + "software.amazon.awssdk.utils.uri", + "software.amazon.awssdk.utils.uri.internal" + ], + "tools.jackson.core:jackson-core": [ + "tools.jackson.core", + "tools.jackson.core.async", + "tools.jackson.core.base", + "tools.jackson.core.exc", + "tools.jackson.core.filter", + "tools.jackson.core.internal.shaded.fdp", + "tools.jackson.core.internal.shaded.fdp.bte", + "tools.jackson.core.internal.shaded.fdp.chr", + "tools.jackson.core.io", + "tools.jackson.core.io.schubfach", + "tools.jackson.core.json", + "tools.jackson.core.json.async", + "tools.jackson.core.sym", + "tools.jackson.core.tree", + "tools.jackson.core.type", + "tools.jackson.core.util" + ], + "tools.jackson.core:jackson-databind": [ + "tools.jackson.databind", + "tools.jackson.databind.annotation", + "tools.jackson.databind.cfg", + "tools.jackson.databind.deser", + "tools.jackson.databind.deser.bean", + "tools.jackson.databind.deser.impl", + "tools.jackson.databind.deser.jackson", + "tools.jackson.databind.deser.jdk", + "tools.jackson.databind.deser.std", + "tools.jackson.databind.exc", + "tools.jackson.databind.ext", + "tools.jackson.databind.ext.beans", + "tools.jackson.databind.ext.javatime", + "tools.jackson.databind.ext.javatime.deser", + "tools.jackson.databind.ext.javatime.deser.key", + "tools.jackson.databind.ext.javatime.ser", + "tools.jackson.databind.ext.javatime.ser.key", + "tools.jackson.databind.ext.javatime.util", + "tools.jackson.databind.ext.jdk8", + "tools.jackson.databind.ext.sql", + "tools.jackson.databind.introspect", + "tools.jackson.databind.json", + "tools.jackson.databind.jsonFormatVisitors", + "tools.jackson.databind.jsontype", + "tools.jackson.databind.jsontype.impl", + "tools.jackson.databind.module", + "tools.jackson.databind.node", + "tools.jackson.databind.ser", + "tools.jackson.databind.ser.bean", + "tools.jackson.databind.ser.impl", + "tools.jackson.databind.ser.jackson", + "tools.jackson.databind.ser.jdk", + "tools.jackson.databind.ser.std", + "tools.jackson.databind.type", + "tools.jackson.databind.util", + "tools.jackson.databind.util.internal" + ], + "tools.jackson.module:jackson-module-blackbird": [ + "tools.jackson.module.blackbird", + "tools.jackson.module.blackbird.deser", + "tools.jackson.module.blackbird.ser", + "tools.jackson.module.blackbird.util" + ] + }, + "repositories": { + "https://maven-central.storage-download.googleapis.com/maven2/": [ + "aopalliance:aopalliance", + "aopalliance:aopalliance:jar:sources", + "args4j:args4j", + "args4j:args4j:jar:sources", + "at.yawk.lz4:lz4-java", + "at.yawk.lz4:lz4-java:jar:sources", + "ch.qos.logback:logback-classic", + "ch.qos.logback:logback-classic:jar:sources", + "ch.qos.logback:logback-core", + "ch.qos.logback:logback-core:jar:sources", + "com.bucket4j:bucket4j-core", + "com.bucket4j:bucket4j-core:jar:sources", + "com.bucket4j:bucket4j_jdk17-core", + "com.bucket4j:bucket4j_jdk17-core:jar:sources", + "com.datastax.cassandra:cassandra-driver-core", + "com.datastax.cassandra:cassandra-driver-core:jar:sources", + "com.datastax.oss:native-protocol", + "com.datastax.oss:native-protocol:jar:sources", + "com.fasterxml.jackson.core:jackson-annotations", + "com.fasterxml.jackson.core:jackson-annotations:jar:sources", + "com.fasterxml.jackson.core:jackson-core", + "com.fasterxml.jackson.core:jackson-core:jar:sources", + "com.fasterxml.jackson.core:jackson-databind", + "com.fasterxml.jackson.core:jackson-databind:jar:sources", + "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml", + "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:jar:sources", + "com.fasterxml.jackson.datatype:jackson-datatype-jsr310", + "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:jar:sources", + "com.fasterxml:classmate", + "com.fasterxml:classmate:jar:sources", + "com.github.ben-manes.caffeine:caffeine", + "com.github.ben-manes.caffeine:caffeine:jar:sources", + "com.github.ben-manes.caffeine:guava", + "com.github.ben-manes.caffeine:guava:jar:sources", + "com.github.docker-java:docker-java-api", + "com.github.docker-java:docker-java-api:jar:sources", + "com.github.docker-java:docker-java-transport", + "com.github.docker-java:docker-java-transport-zerodep", + "com.github.docker-java:docker-java-transport-zerodep:jar:sources", + "com.github.docker-java:docker-java-transport:jar:sources", + "com.github.java-json-tools:btf", + "com.github.java-json-tools:btf:jar:sources", + "com.github.java-json-tools:jackson-coreutils", + "com.github.java-json-tools:jackson-coreutils:jar:sources", + "com.github.java-json-tools:json-patch", + "com.github.java-json-tools:json-patch:jar:sources", + "com.github.java-json-tools:msg-simple", + "com.github.java-json-tools:msg-simple:jar:sources", + "com.github.jnr:jffi", + "com.github.jnr:jffi:jar:native", + "com.github.jnr:jffi:jar:sources", + "com.github.jnr:jnr-constants", + "com.github.jnr:jnr-constants:jar:sources", + "com.github.jnr:jnr-ffi", + "com.github.jnr:jnr-ffi:jar:sources", + "com.github.jnr:jnr-posix", + "com.github.jnr:jnr-posix:jar:sources", + "com.github.jnr:jnr-x86asm", + "com.github.jnr:jnr-x86asm:jar:sources", + "com.github.stephenc.jcip:jcip-annotations", + "com.github.stephenc.jcip:jcip-annotations:jar:sources", + "com.google.android:annotations", + "com.google.android:annotations:jar:sources", + "com.google.api.grpc:proto-google-common-protos", + "com.google.api.grpc:proto-google-common-protos:jar:sources", + "com.google.code.findbugs:jsr305", + "com.google.code.findbugs:jsr305:jar:sources", + "com.google.code.gson:gson", + "com.google.code.gson:gson:jar:sources", + "com.google.errorprone:error_prone_annotations", + "com.google.errorprone:error_prone_annotations:jar:sources", + "com.google.guava:failureaccess", + "com.google.guava:failureaccess:jar:sources", + "com.google.guava:guava", + "com.google.guava:guava:jar:sources", + "com.google.guava:listenablefuture", + "com.google.j2objc:j2objc-annotations", + "com.google.j2objc:j2objc-annotations:jar:sources", + "com.google.protobuf:protobuf-java", + "com.google.protobuf:protobuf-java-util", + "com.google.protobuf:protobuf-java-util:jar:sources", + "com.google.protobuf:protobuf-java:jar:sources", + "com.jayway.jsonpath:json-path", + "com.jayway.jsonpath:json-path:jar:sources", + "com.nimbusds:content-type", + "com.nimbusds:content-type:jar:sources", + "com.nimbusds:lang-tag", + "com.nimbusds:lang-tag:jar:sources", + "com.nimbusds:nimbus-jose-jwt", + "com.nimbusds:nimbus-jose-jwt:jar:sources", + "com.nimbusds:oauth2-oidc-sdk", + "com.nimbusds:oauth2-oidc-sdk:jar:sources", + "com.squareup.okhttp3:logging-interceptor", + "com.squareup.okhttp3:logging-interceptor:jar:sources", + "com.squareup.okhttp3:okhttp", + "com.squareup.okhttp3:okhttp-jvm", + "com.squareup.okhttp3:okhttp-jvm:jar:sources", + "com.squareup.okhttp3:okhttp:jar:sources", + "com.squareup.okio:okio", + "com.squareup.okio:okio-jvm", + "com.squareup.okio:okio-jvm:jar:sources", + "com.squareup.okio:okio:jar:sources", + "com.typesafe:config", + "com.typesafe:config:jar:sources", + "com.vaadin.external.google:android-json", + "com.vaadin.external.google:android-json:jar:sources", + "commons-codec:commons-codec", + "commons-codec:commons-codec:jar:sources", + "commons-io:commons-io", + "commons-io:commons-io:jar:sources", + "commons-logging:commons-logging", + "commons-logging:commons-logging:jar:sources", + "io.cloudevents:cloudevents-api", + "io.cloudevents:cloudevents-api:jar:sources", + "io.cloudevents:cloudevents-core", + "io.cloudevents:cloudevents-core:jar:sources", + "io.cloudevents:cloudevents-json-jackson", + "io.cloudevents:cloudevents-json-jackson:jar:sources", + "io.dropwizard.metrics:metrics-core", + "io.dropwizard.metrics:metrics-core:jar:sources", + "io.grpc:grpc-api", + "io.grpc:grpc-api:jar:sources", + "io.grpc:grpc-context", + "io.grpc:grpc-context:jar:sources", + "io.grpc:grpc-core", + "io.grpc:grpc-core:jar:sources", + "io.grpc:grpc-inprocess", + "io.grpc:grpc-inprocess:jar:sources", + "io.grpc:grpc-netty", + "io.grpc:grpc-netty-shaded", + "io.grpc:grpc-netty-shaded:jar:sources", + "io.grpc:grpc-netty:jar:sources", + "io.grpc:grpc-protobuf", + "io.grpc:grpc-protobuf-lite", + "io.grpc:grpc-protobuf-lite:jar:sources", + "io.grpc:grpc-protobuf:jar:sources", + "io.grpc:grpc-services", + "io.grpc:grpc-services:jar:sources", + "io.grpc:grpc-stub", + "io.grpc:grpc-stub:jar:sources", + "io.grpc:grpc-util", + "io.grpc:grpc-util:jar:sources", + "io.gsonfire:gson-fire", + "io.gsonfire:gson-fire:jar:sources", + "io.kubernetes:client-java", + "io.kubernetes:client-java-api", + "io.kubernetes:client-java-api-fluent", + "io.kubernetes:client-java-api-fluent:jar:sources", + "io.kubernetes:client-java-api:jar:sources", + "io.kubernetes:client-java-extended", + "io.kubernetes:client-java-extended:jar:sources", + "io.kubernetes:client-java-proto", + "io.kubernetes:client-java-proto:jar:sources", + "io.kubernetes:client-java:jar:sources", + "io.micrometer:context-propagation", + "io.micrometer:context-propagation:jar:sources", + "io.micrometer:micrometer-commons", + "io.micrometer:micrometer-commons:jar:sources", + "io.micrometer:micrometer-core", + "io.micrometer:micrometer-core:jar:sources", + "io.micrometer:micrometer-jakarta9", + "io.micrometer:micrometer-jakarta9:jar:sources", + "io.micrometer:micrometer-observation", + "io.micrometer:micrometer-observation-test", + "io.micrometer:micrometer-observation-test:jar:sources", + "io.micrometer:micrometer-observation:jar:sources", + "io.micrometer:micrometer-registry-prometheus", + "io.micrometer:micrometer-registry-prometheus:jar:sources", + "io.micrometer:micrometer-tracing", + "io.micrometer:micrometer-tracing-bridge-otel", + "io.micrometer:micrometer-tracing-bridge-otel:jar:sources", + "io.micrometer:micrometer-tracing:jar:sources", + "io.nats:jnats", + "io.nats:jnats:jar:sources", + "io.netty:netty-buffer", + "io.netty:netty-buffer:jar:sources", + "io.netty:netty-codec-base", + "io.netty:netty-codec-base:jar:sources", + "io.netty:netty-codec-classes-quic", + "io.netty:netty-codec-classes-quic:jar:sources", + "io.netty:netty-codec-compression", + "io.netty:netty-codec-compression:jar:sources", + "io.netty:netty-codec-dns", + "io.netty:netty-codec-dns:jar:sources", + "io.netty:netty-codec-http", + "io.netty:netty-codec-http2", + "io.netty:netty-codec-http2:jar:sources", + "io.netty:netty-codec-http3", + "io.netty:netty-codec-http3:jar:sources", + "io.netty:netty-codec-http:jar:sources", + "io.netty:netty-codec-native-quic:jar:linux-aarch_64", + "io.netty:netty-codec-native-quic:jar:linux-x86_64", + "io.netty:netty-codec-native-quic:jar:osx-aarch_64", + "io.netty:netty-codec-native-quic:jar:osx-x86_64", + "io.netty:netty-codec-native-quic:jar:sources", + "io.netty:netty-codec-native-quic:jar:windows-x86_64", + "io.netty:netty-codec-socks", + "io.netty:netty-codec-socks:jar:sources", + "io.netty:netty-common", + "io.netty:netty-common:jar:sources", + "io.netty:netty-handler", + "io.netty:netty-handler-proxy", + "io.netty:netty-handler-proxy:jar:sources", + "io.netty:netty-handler:jar:sources", + "io.netty:netty-resolver", + "io.netty:netty-resolver-dns", + "io.netty:netty-resolver-dns-classes-macos", + "io.netty:netty-resolver-dns-classes-macos:jar:sources", + "io.netty:netty-resolver-dns-native-macos:jar:osx-x86_64", + "io.netty:netty-resolver-dns-native-macos:jar:sources", + "io.netty:netty-resolver-dns:jar:sources", + "io.netty:netty-resolver:jar:sources", + "io.netty:netty-transport", + "io.netty:netty-transport-classes-epoll", + "io.netty:netty-transport-classes-epoll:jar:sources", + "io.netty:netty-transport-native-epoll:jar:linux-x86_64", + "io.netty:netty-transport-native-epoll:jar:sources", + "io.netty:netty-transport-native-unix-common", + "io.netty:netty-transport-native-unix-common:jar:sources", + "io.netty:netty-transport:jar:sources", + "io.opentelemetry.semconv:opentelemetry-semconv", + "io.opentelemetry.semconv:opentelemetry-semconv:jar:sources", + "io.opentelemetry:opentelemetry-api", + "io.opentelemetry:opentelemetry-api:jar:sources", + "io.opentelemetry:opentelemetry-common", + "io.opentelemetry:opentelemetry-common:jar:sources", + "io.opentelemetry:opentelemetry-context", + "io.opentelemetry:opentelemetry-context:jar:sources", + "io.opentelemetry:opentelemetry-exporter-common", + "io.opentelemetry:opentelemetry-exporter-common:jar:sources", + "io.opentelemetry:opentelemetry-exporter-otlp", + "io.opentelemetry:opentelemetry-exporter-otlp-common", + "io.opentelemetry:opentelemetry-exporter-otlp-common:jar:sources", + "io.opentelemetry:opentelemetry-exporter-otlp:jar:sources", + "io.opentelemetry:opentelemetry-exporter-sender-okhttp", + "io.opentelemetry:opentelemetry-exporter-sender-okhttp:jar:sources", + "io.opentelemetry:opentelemetry-extension-trace-propagators", + "io.opentelemetry:opentelemetry-extension-trace-propagators:jar:sources", + "io.opentelemetry:opentelemetry-sdk", + "io.opentelemetry:opentelemetry-sdk-common", + "io.opentelemetry:opentelemetry-sdk-common:jar:sources", + "io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi", + "io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi:jar:sources", + "io.opentelemetry:opentelemetry-sdk-logs", + "io.opentelemetry:opentelemetry-sdk-logs:jar:sources", + "io.opentelemetry:opentelemetry-sdk-metrics", + "io.opentelemetry:opentelemetry-sdk-metrics:jar:sources", + "io.opentelemetry:opentelemetry-sdk-testing", + "io.opentelemetry:opentelemetry-sdk-testing:jar:sources", + "io.opentelemetry:opentelemetry-sdk-trace", + "io.opentelemetry:opentelemetry-sdk-trace:jar:sources", + "io.opentelemetry:opentelemetry-sdk:jar:sources", + "io.perfmark:perfmark-api", + "io.perfmark:perfmark-api:jar:sources", + "io.projectreactor.netty:reactor-netty-core", + "io.projectreactor.netty:reactor-netty-core:jar:sources", + "io.projectreactor.netty:reactor-netty-http", + "io.projectreactor.netty:reactor-netty-http:jar:sources", + "io.projectreactor:reactor-core", + "io.projectreactor:reactor-core:jar:sources", + "io.projectreactor:reactor-test", + "io.projectreactor:reactor-test:jar:sources", + "io.prometheus:prometheus-metrics-config", + "io.prometheus:prometheus-metrics-config:jar:sources", + "io.prometheus:prometheus-metrics-core", + "io.prometheus:prometheus-metrics-core:jar:sources", + "io.prometheus:prometheus-metrics-exposition-formats", + "io.prometheus:prometheus-metrics-exposition-formats:jar:sources", + "io.prometheus:prometheus-metrics-exposition-textformats", + "io.prometheus:prometheus-metrics-exposition-textformats:jar:sources", + "io.prometheus:prometheus-metrics-model", + "io.prometheus:prometheus-metrics-model:jar:sources", + "io.prometheus:prometheus-metrics-tracer-common", + "io.prometheus:prometheus-metrics-tracer-common:jar:sources", + "io.swagger.core.v3:swagger-annotations-jakarta", + "io.swagger.core.v3:swagger-annotations-jakarta:jar:sources", + "io.swagger.core.v3:swagger-core-jakarta", + "io.swagger.core.v3:swagger-core-jakarta:jar:sources", + "io.swagger.core.v3:swagger-models-jakarta", + "io.swagger.core.v3:swagger-models-jakarta:jar:sources", + "io.swagger:swagger-annotations", + "io.swagger:swagger-annotations:jar:sources", + "jakarta.activation:jakarta.activation-api", + "jakarta.activation:jakarta.activation-api:jar:sources", + "jakarta.annotation:jakarta.annotation-api", + "jakarta.annotation:jakarta.annotation-api:jar:sources", + "jakarta.servlet:jakarta.servlet-api", + "jakarta.servlet:jakarta.servlet-api:jar:sources", + "jakarta.validation:jakarta.validation-api", + "jakarta.validation:jakarta.validation-api:jar:sources", + "jakarta.xml.bind:jakarta.xml.bind-api", + "jakarta.xml.bind:jakarta.xml.bind-api:jar:sources", + "javax.annotation:javax.annotation-api", + "javax.annotation:javax.annotation-api:jar:sources", + "net.bytebuddy:byte-buddy", + "net.bytebuddy:byte-buddy-agent", + "net.bytebuddy:byte-buddy-agent:jar:sources", + "net.bytebuddy:byte-buddy:jar:sources", + "net.devh:grpc-common-spring-boot", + "net.devh:grpc-common-spring-boot:jar:sources", + "net.devh:grpc-server-spring-boot-starter", + "net.devh:grpc-server-spring-boot-starter:jar:sources", + "net.java.dev.jna:jna", + "net.java.dev.jna:jna:jar:sources", + "net.javacrumbs.shedlock:shedlock-core", + "net.javacrumbs.shedlock:shedlock-core:jar:sources", + "net.javacrumbs.shedlock:shedlock-provider-cassandra", + "net.javacrumbs.shedlock:shedlock-provider-cassandra:jar:sources", + "net.javacrumbs.shedlock:shedlock-spring", + "net.javacrumbs.shedlock:shedlock-spring:jar:sources", + "net.minidev:accessors-smart", + "net.minidev:accessors-smart:jar:sources", + "net.minidev:json-smart", + "net.minidev:json-smart:jar:sources", + "org.apache.cassandra:java-driver-core", + "org.apache.cassandra:java-driver-core:jar:sources", + "org.apache.cassandra:java-driver-guava-shaded", + "org.apache.cassandra:java-driver-guava-shaded:jar:sources", + "org.apache.cassandra:java-driver-metrics-micrometer", + "org.apache.cassandra:java-driver-metrics-micrometer:jar:sources", + "org.apache.cassandra:java-driver-query-builder", + "org.apache.cassandra:java-driver-query-builder:jar:sources", + "org.apache.commons:commons-collections4", + "org.apache.commons:commons-collections4:jar:sources", + "org.apache.commons:commons-compress", + "org.apache.commons:commons-compress:jar:sources", + "org.apache.commons:commons-lang3", + "org.apache.commons:commons-lang3:jar:sources", + "org.apache.logging.log4j:log4j-api", + "org.apache.logging.log4j:log4j-api:jar:sources", + "org.apache.logging.log4j:log4j-to-slf4j", + "org.apache.logging.log4j:log4j-to-slf4j:jar:sources", + "org.apache.tomcat.embed:tomcat-embed-core", + "org.apache.tomcat.embed:tomcat-embed-core:jar:sources", + "org.apache.tomcat.embed:tomcat-embed-el", + "org.apache.tomcat.embed:tomcat-embed-el:jar:sources", + "org.apache.tomcat.embed:tomcat-embed-websocket", + "org.apache.tomcat.embed:tomcat-embed-websocket:jar:sources", + "org.apiguardian:apiguardian-api", + "org.apiguardian:apiguardian-api:jar:sources", + "org.aspectj:aspectjweaver", + "org.aspectj:aspectjweaver:jar:sources", + "org.assertj:assertj-core", + "org.assertj:assertj-core:jar:sources", + "org.awaitility:awaitility", + "org.awaitility:awaitility:jar:sources", + "org.bitbucket.b_c:jose4j", + "org.bitbucket.b_c:jose4j:jar:sources", + "org.bouncycastle:bcpkix-jdk18on", + "org.bouncycastle:bcpkix-jdk18on:jar:sources", + "org.bouncycastle:bcprov-jdk18on", + "org.bouncycastle:bcprov-jdk18on:jar:sources", + "org.bouncycastle:bcprov-lts8on", + "org.bouncycastle:bcprov-lts8on:jar:sources", + "org.bouncycastle:bcutil-jdk18on", + "org.bouncycastle:bcutil-jdk18on:jar:sources", + "org.checkerframework:checker-qual", + "org.checkerframework:checker-qual:jar:sources", + "org.codehaus.mojo:animal-sniffer-annotations", + "org.codehaus.mojo:animal-sniffer-annotations:jar:sources", + "org.hamcrest:hamcrest", + "org.hamcrest:hamcrest:jar:sources", + "org.hdrhistogram:HdrHistogram", + "org.hdrhistogram:HdrHistogram:jar:sources", + "org.hibernate.validator:hibernate-validator", + "org.hibernate.validator:hibernate-validator:jar:sources", + "org.jacoco:org.jacoco.agent:jar:runtime", + "org.jacoco:org.jacoco.agent:jar:sources", + "org.jacoco:org.jacoco.cli", + "org.jacoco:org.jacoco.cli:jar:sources", + "org.jacoco:org.jacoco.core", + "org.jacoco:org.jacoco.core:jar:sources", + "org.jacoco:org.jacoco.report", + "org.jacoco:org.jacoco.report:jar:sources", + "org.jboss.logging:jboss-logging", + "org.jboss.logging:jboss-logging:jar:sources", + "org.jetbrains.kotlin:kotlin-stdlib", + "org.jetbrains.kotlin:kotlin-stdlib-jdk7", + "org.jetbrains.kotlin:kotlin-stdlib-jdk7:jar:sources", + "org.jetbrains.kotlin:kotlin-stdlib-jdk8", + "org.jetbrains.kotlin:kotlin-stdlib-jdk8:jar:sources", + "org.jetbrains.kotlin:kotlin-stdlib:jar:sources", + "org.jetbrains:annotations", + "org.jetbrains:annotations:jar:sources", + "org.jspecify:jspecify", + "org.jspecify:jspecify:jar:sources", + "org.junit.jupiter:junit-jupiter", + "org.junit.jupiter:junit-jupiter-api", + "org.junit.jupiter:junit-jupiter-api:jar:sources", + "org.junit.jupiter:junit-jupiter-engine", + "org.junit.jupiter:junit-jupiter-engine:jar:sources", + "org.junit.jupiter:junit-jupiter-params", + "org.junit.jupiter:junit-jupiter-params:jar:sources", + "org.junit.jupiter:junit-jupiter:jar:sources", + "org.junit.platform:junit-platform-commons", + "org.junit.platform:junit-platform-commons:jar:sources", + "org.junit.platform:junit-platform-console-standalone", + "org.junit.platform:junit-platform-console-standalone:jar:sources", + "org.junit.platform:junit-platform-engine", + "org.junit.platform:junit-platform-engine:jar:sources", + "org.junit.platform:junit-platform-launcher", + "org.junit.platform:junit-platform-launcher:jar:sources", + "org.junit.platform:junit-platform-reporting", + "org.junit.platform:junit-platform-reporting:jar:sources", + "org.latencyutils:LatencyUtils", + "org.latencyutils:LatencyUtils:jar:sources", + "org.mockito:mockito-core", + "org.mockito:mockito-core:jar:sources", + "org.mockito:mockito-junit-jupiter", + "org.mockito:mockito-junit-jupiter:jar:sources", + "org.objenesis:objenesis", + "org.objenesis:objenesis:jar:sources", + "org.opentest4j.reporting:open-test-reporting-tooling-spi", + "org.opentest4j.reporting:open-test-reporting-tooling-spi:jar:sources", + "org.opentest4j:opentest4j", + "org.opentest4j:opentest4j:jar:sources", + "org.ow2.asm:asm", + "org.ow2.asm:asm-analysis", + "org.ow2.asm:asm-analysis:jar:sources", + "org.ow2.asm:asm-commons", + "org.ow2.asm:asm-commons:jar:sources", + "org.ow2.asm:asm-tree", + "org.ow2.asm:asm-tree:jar:sources", + "org.ow2.asm:asm-util", + "org.ow2.asm:asm-util:jar:sources", + "org.ow2.asm:asm:jar:sources", + "org.projectlombok:lombok", + "org.projectlombok:lombok:jar:sources", + "org.reactivestreams:reactive-streams", + "org.reactivestreams:reactive-streams:jar:sources", + "org.rnorth.duct-tape:duct-tape", + "org.rnorth.duct-tape:duct-tape:jar:sources", + "org.skyscreamer:jsonassert", + "org.skyscreamer:jsonassert:jar:sources", + "org.slf4j:jul-to-slf4j", + "org.slf4j:jul-to-slf4j:jar:sources", + "org.slf4j:slf4j-api", + "org.slf4j:slf4j-api:jar:sources", + "org.springdoc:springdoc-openapi-starter-common", + "org.springdoc:springdoc-openapi-starter-common:jar:sources", + "org.springdoc:springdoc-openapi-starter-webflux-api", + "org.springdoc:springdoc-openapi-starter-webflux-api:jar:sources", + "org.springdoc:springdoc-openapi-starter-webmvc-api", + "org.springdoc:springdoc-openapi-starter-webmvc-api:jar:sources", + "org.springframework.boot:spring-boot", + "org.springframework.boot:spring-boot-actuator", + "org.springframework.boot:spring-boot-actuator-autoconfigure", + "org.springframework.boot:spring-boot-actuator-autoconfigure:jar:sources", + "org.springframework.boot:spring-boot-actuator:jar:sources", + "org.springframework.boot:spring-boot-autoconfigure", + "org.springframework.boot:spring-boot-autoconfigure:jar:sources", + "org.springframework.boot:spring-boot-cassandra", + "org.springframework.boot:spring-boot-cassandra:jar:sources", + "org.springframework.boot:spring-boot-data-cassandra", + "org.springframework.boot:spring-boot-data-cassandra-test", + "org.springframework.boot:spring-boot-data-cassandra-test:jar:sources", + "org.springframework.boot:spring-boot-data-cassandra:jar:sources", + "org.springframework.boot:spring-boot-data-commons", + "org.springframework.boot:spring-boot-data-commons:jar:sources", + "org.springframework.boot:spring-boot-health", + "org.springframework.boot:spring-boot-health:jar:sources", + "org.springframework.boot:spring-boot-http-client", + "org.springframework.boot:spring-boot-http-client:jar:sources", + "org.springframework.boot:spring-boot-http-codec", + "org.springframework.boot:spring-boot-http-codec:jar:sources", + "org.springframework.boot:spring-boot-http-converter", + "org.springframework.boot:spring-boot-http-converter:jar:sources", + "org.springframework.boot:spring-boot-jackson", + "org.springframework.boot:spring-boot-jackson:jar:sources", + "org.springframework.boot:spring-boot-loader", + "org.springframework.boot:spring-boot-loader:jar:sources", + "org.springframework.boot:spring-boot-micrometer-metrics", + "org.springframework.boot:spring-boot-micrometer-metrics-test", + "org.springframework.boot:spring-boot-micrometer-metrics-test:jar:sources", + "org.springframework.boot:spring-boot-micrometer-metrics:jar:sources", + "org.springframework.boot:spring-boot-micrometer-observation", + "org.springframework.boot:spring-boot-micrometer-observation:jar:sources", + "org.springframework.boot:spring-boot-micrometer-tracing", + "org.springframework.boot:spring-boot-micrometer-tracing-opentelemetry", + "org.springframework.boot:spring-boot-micrometer-tracing-opentelemetry:jar:sources", + "org.springframework.boot:spring-boot-micrometer-tracing:jar:sources", + "org.springframework.boot:spring-boot-netty", + "org.springframework.boot:spring-boot-netty:jar:sources", + "org.springframework.boot:spring-boot-opentelemetry", + "org.springframework.boot:spring-boot-opentelemetry:jar:sources", + "org.springframework.boot:spring-boot-persistence", + "org.springframework.boot:spring-boot-persistence:jar:sources", + "org.springframework.boot:spring-boot-reactor", + "org.springframework.boot:spring-boot-reactor-netty", + "org.springframework.boot:spring-boot-reactor-netty:jar:sources", + "org.springframework.boot:spring-boot-reactor:jar:sources", + "org.springframework.boot:spring-boot-restclient", + "org.springframework.boot:spring-boot-restclient:jar:sources", + "org.springframework.boot:spring-boot-resttestclient", + "org.springframework.boot:spring-boot-resttestclient:jar:sources", + "org.springframework.boot:spring-boot-security", + "org.springframework.boot:spring-boot-security-oauth2-client", + "org.springframework.boot:spring-boot-security-oauth2-client:jar:sources", + "org.springframework.boot:spring-boot-security-oauth2-resource-server", + "org.springframework.boot:spring-boot-security-oauth2-resource-server:jar:sources", + "org.springframework.boot:spring-boot-security-test", + "org.springframework.boot:spring-boot-security-test:jar:sources", + "org.springframework.boot:spring-boot-security:jar:sources", + "org.springframework.boot:spring-boot-servlet", + "org.springframework.boot:spring-boot-servlet:jar:sources", + "org.springframework.boot:spring-boot-starter", + "org.springframework.boot:spring-boot-starter-actuator", + "org.springframework.boot:spring-boot-starter-actuator-test", + "org.springframework.boot:spring-boot-starter-actuator-test:jar:sources", + "org.springframework.boot:spring-boot-starter-actuator:jar:sources", + "org.springframework.boot:spring-boot-starter-aspectj", + "org.springframework.boot:spring-boot-starter-aspectj:jar:sources", + "org.springframework.boot:spring-boot-starter-data-cassandra", + "org.springframework.boot:spring-boot-starter-data-cassandra-test", + "org.springframework.boot:spring-boot-starter-data-cassandra-test:jar:sources", + "org.springframework.boot:spring-boot-starter-data-cassandra:jar:sources", + "org.springframework.boot:spring-boot-starter-jackson", + "org.springframework.boot:spring-boot-starter-jackson-test", + "org.springframework.boot:spring-boot-starter-jackson-test:jar:sources", + "org.springframework.boot:spring-boot-starter-jackson:jar:sources", + "org.springframework.boot:spring-boot-starter-logging", + "org.springframework.boot:spring-boot-starter-logging:jar:sources", + "org.springframework.boot:spring-boot-starter-micrometer-metrics", + "org.springframework.boot:spring-boot-starter-micrometer-metrics-test", + "org.springframework.boot:spring-boot-starter-micrometer-metrics-test:jar:sources", + "org.springframework.boot:spring-boot-starter-micrometer-metrics:jar:sources", + "org.springframework.boot:spring-boot-starter-reactor-netty", + "org.springframework.boot:spring-boot-starter-reactor-netty:jar:sources", + "org.springframework.boot:spring-boot-starter-security", + "org.springframework.boot:spring-boot-starter-security-oauth2-client", + "org.springframework.boot:spring-boot-starter-security-oauth2-client:jar:sources", + "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server", + "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server-test", + "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server-test:jar:sources", + "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server:jar:sources", + "org.springframework.boot:spring-boot-starter-security-test", + "org.springframework.boot:spring-boot-starter-security-test:jar:sources", + "org.springframework.boot:spring-boot-starter-security:jar:sources", + "org.springframework.boot:spring-boot-starter-test", + "org.springframework.boot:spring-boot-starter-test:jar:sources", + "org.springframework.boot:spring-boot-starter-tomcat", + "org.springframework.boot:spring-boot-starter-tomcat-runtime", + "org.springframework.boot:spring-boot-starter-tomcat-runtime:jar:sources", + "org.springframework.boot:spring-boot-starter-tomcat:jar:sources", + "org.springframework.boot:spring-boot-starter-validation", + "org.springframework.boot:spring-boot-starter-validation:jar:sources", + "org.springframework.boot:spring-boot-starter-web", + "org.springframework.boot:spring-boot-starter-web:jar:sources", + "org.springframework.boot:spring-boot-starter-webflux", + "org.springframework.boot:spring-boot-starter-webflux-test", + "org.springframework.boot:spring-boot-starter-webflux-test:jar:sources", + "org.springframework.boot:spring-boot-starter-webflux:jar:sources", + "org.springframework.boot:spring-boot-starter-webmvc", + "org.springframework.boot:spring-boot-starter-webmvc-test", + "org.springframework.boot:spring-boot-starter-webmvc-test:jar:sources", + "org.springframework.boot:spring-boot-starter-webmvc:jar:sources", + "org.springframework.boot:spring-boot-starter:jar:sources", + "org.springframework.boot:spring-boot-test", + "org.springframework.boot:spring-boot-test-autoconfigure", + "org.springframework.boot:spring-boot-test-autoconfigure:jar:sources", + "org.springframework.boot:spring-boot-test:jar:sources", + "org.springframework.boot:spring-boot-tomcat", + "org.springframework.boot:spring-boot-tomcat:jar:sources", + "org.springframework.boot:spring-boot-validation", + "org.springframework.boot:spring-boot-validation:jar:sources", + "org.springframework.boot:spring-boot-web-server", + "org.springframework.boot:spring-boot-web-server:jar:sources", + "org.springframework.boot:spring-boot-webclient", + "org.springframework.boot:spring-boot-webclient:jar:sources", + "org.springframework.boot:spring-boot-webflux", + "org.springframework.boot:spring-boot-webflux-test", + "org.springframework.boot:spring-boot-webflux-test:jar:sources", + "org.springframework.boot:spring-boot-webflux:jar:sources", + "org.springframework.boot:spring-boot-webmvc", + "org.springframework.boot:spring-boot-webmvc-test", + "org.springframework.boot:spring-boot-webmvc-test:jar:sources", + "org.springframework.boot:spring-boot-webmvc:jar:sources", + "org.springframework.boot:spring-boot-webtestclient", + "org.springframework.boot:spring-boot-webtestclient:jar:sources", + "org.springframework.boot:spring-boot:jar:sources", + "org.springframework.cloud:spring-cloud-commons", + "org.springframework.cloud:spring-cloud-commons:jar:sources", + "org.springframework.cloud:spring-cloud-context", + "org.springframework.cloud:spring-cloud-context:jar:sources", + "org.springframework.cloud:spring-cloud-kubernetes-client-autoconfig", + "org.springframework.cloud:spring-cloud-kubernetes-client-autoconfig:jar:sources", + "org.springframework.cloud:spring-cloud-kubernetes-client-config", + "org.springframework.cloud:spring-cloud-kubernetes-client-config:jar:sources", + "org.springframework.cloud:spring-cloud-kubernetes-commons", + "org.springframework.cloud:spring-cloud-kubernetes-commons:jar:sources", + "org.springframework.cloud:spring-cloud-starter", + "org.springframework.cloud:spring-cloud-starter-bootstrap", + "org.springframework.cloud:spring-cloud-starter-bootstrap:jar:sources", + "org.springframework.cloud:spring-cloud-starter-kubernetes-client-config", + "org.springframework.data:spring-data-cassandra", + "org.springframework.data:spring-data-cassandra:jar:sources", + "org.springframework.data:spring-data-commons", + "org.springframework.data:spring-data-commons:jar:sources", + "org.springframework.retry:spring-retry", + "org.springframework.retry:spring-retry:jar:sources", + "org.springframework.security:spring-security-config", + "org.springframework.security:spring-security-config:jar:sources", + "org.springframework.security:spring-security-core", + "org.springframework.security:spring-security-core:jar:sources", + "org.springframework.security:spring-security-crypto", + "org.springframework.security:spring-security-crypto:jar:sources", + "org.springframework.security:spring-security-oauth2-client", + "org.springframework.security:spring-security-oauth2-client:jar:sources", + "org.springframework.security:spring-security-oauth2-core", + "org.springframework.security:spring-security-oauth2-core:jar:sources", + "org.springframework.security:spring-security-oauth2-jose", + "org.springframework.security:spring-security-oauth2-jose:jar:sources", + "org.springframework.security:spring-security-oauth2-resource-server", + "org.springframework.security:spring-security-oauth2-resource-server:jar:sources", + "org.springframework.security:spring-security-test", + "org.springframework.security:spring-security-test:jar:sources", + "org.springframework.security:spring-security-web", + "org.springframework.security:spring-security-web:jar:sources", + "org.springframework:spring-aop", + "org.springframework:spring-aop:jar:sources", + "org.springframework:spring-beans", + "org.springframework:spring-beans:jar:sources", + "org.springframework:spring-context", + "org.springframework:spring-context-support", + "org.springframework:spring-context-support:jar:sources", + "org.springframework:spring-context:jar:sources", + "org.springframework:spring-core", + "org.springframework:spring-core:jar:sources", + "org.springframework:spring-expression", + "org.springframework:spring-expression:jar:sources", + "org.springframework:spring-test", + "org.springframework:spring-test:jar:sources", + "org.springframework:spring-tx", + "org.springframework:spring-tx:jar:sources", + "org.springframework:spring-web", + "org.springframework:spring-web:jar:sources", + "org.springframework:spring-webflux", + "org.springframework:spring-webflux:jar:sources", + "org.springframework:spring-webmvc", + "org.springframework:spring-webmvc:jar:sources", + "org.testcontainers:testcontainers", + "org.testcontainers:testcontainers-cassandra", + "org.testcontainers:testcontainers-cassandra:jar:sources", + "org.testcontainers:testcontainers-database-commons", + "org.testcontainers:testcontainers-database-commons:jar:sources", + "org.testcontainers:testcontainers-junit-jupiter", + "org.testcontainers:testcontainers-junit-jupiter:jar:sources", + "org.testcontainers:testcontainers-localstack", + "org.testcontainers:testcontainers-localstack:jar:sources", + "org.testcontainers:testcontainers:jar:sources", + "org.wiremock:wiremock-standalone", + "org.wiremock:wiremock-standalone:jar:sources", + "org.xmlunit:xmlunit-core", + "org.xmlunit:xmlunit-core:jar:sources", + "org.yaml:snakeyaml", + "org.yaml:snakeyaml:jar:sources", + "software.amazon.awssdk:annotations", + "software.amazon.awssdk:annotations:jar:sources", + "software.amazon.awssdk:checksums", + "software.amazon.awssdk:checksums-spi", + "software.amazon.awssdk:checksums-spi:jar:sources", + "software.amazon.awssdk:checksums:jar:sources", + "software.amazon.awssdk:endpoints-spi", + "software.amazon.awssdk:endpoints-spi:jar:sources", + "software.amazon.awssdk:http-auth-aws", + "software.amazon.awssdk:http-auth-aws:jar:sources", + "software.amazon.awssdk:http-auth-spi", + "software.amazon.awssdk:http-auth-spi:jar:sources", + "software.amazon.awssdk:http-client-spi", + "software.amazon.awssdk:http-client-spi:jar:sources", + "software.amazon.awssdk:identity-spi", + "software.amazon.awssdk:identity-spi:jar:sources", + "software.amazon.awssdk:json-utils", + "software.amazon.awssdk:json-utils:jar:sources", + "software.amazon.awssdk:metrics-spi", + "software.amazon.awssdk:metrics-spi:jar:sources", + "software.amazon.awssdk:profiles", + "software.amazon.awssdk:profiles:jar:sources", + "software.amazon.awssdk:regions", + "software.amazon.awssdk:regions:jar:sources", + "software.amazon.awssdk:retries", + "software.amazon.awssdk:retries-spi", + "software.amazon.awssdk:retries-spi:jar:sources", + "software.amazon.awssdk:retries:jar:sources", + "software.amazon.awssdk:sdk-core", + "software.amazon.awssdk:sdk-core:jar:sources", + "software.amazon.awssdk:third-party-jackson-core", + "software.amazon.awssdk:third-party-jackson-core:jar:sources", + "software.amazon.awssdk:utils", + "software.amazon.awssdk:utils:jar:sources", + "tools.jackson.core:jackson-core", + "tools.jackson.core:jackson-core:jar:sources", + "tools.jackson.core:jackson-databind", + "tools.jackson.core:jackson-databind:jar:sources", + "tools.jackson.module:jackson-module-blackbird", + "tools.jackson.module:jackson-module-blackbird:jar:sources" + ], + "https://repo.maven.apache.org/maven2/": [ + "aopalliance:aopalliance", + "aopalliance:aopalliance:jar:sources", + "args4j:args4j", + "args4j:args4j:jar:sources", + "at.yawk.lz4:lz4-java", + "at.yawk.lz4:lz4-java:jar:sources", + "ch.qos.logback:logback-classic", + "ch.qos.logback:logback-classic:jar:sources", + "ch.qos.logback:logback-core", + "ch.qos.logback:logback-core:jar:sources", + "com.bucket4j:bucket4j-core", + "com.bucket4j:bucket4j-core:jar:sources", + "com.bucket4j:bucket4j_jdk17-core", + "com.bucket4j:bucket4j_jdk17-core:jar:sources", + "com.datastax.cassandra:cassandra-driver-core", + "com.datastax.cassandra:cassandra-driver-core:jar:sources", + "com.datastax.oss:native-protocol", + "com.datastax.oss:native-protocol:jar:sources", + "com.fasterxml.jackson.core:jackson-annotations", + "com.fasterxml.jackson.core:jackson-annotations:jar:sources", + "com.fasterxml.jackson.core:jackson-core", + "com.fasterxml.jackson.core:jackson-core:jar:sources", + "com.fasterxml.jackson.core:jackson-databind", + "com.fasterxml.jackson.core:jackson-databind:jar:sources", + "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml", + "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:jar:sources", + "com.fasterxml.jackson.datatype:jackson-datatype-jsr310", + "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:jar:sources", + "com.fasterxml:classmate", + "com.fasterxml:classmate:jar:sources", + "com.github.ben-manes.caffeine:caffeine", + "com.github.ben-manes.caffeine:caffeine:jar:sources", + "com.github.ben-manes.caffeine:guava", + "com.github.ben-manes.caffeine:guava:jar:sources", + "com.github.docker-java:docker-java-api", + "com.github.docker-java:docker-java-api:jar:sources", + "com.github.docker-java:docker-java-transport", + "com.github.docker-java:docker-java-transport-zerodep", + "com.github.docker-java:docker-java-transport-zerodep:jar:sources", + "com.github.docker-java:docker-java-transport:jar:sources", + "com.github.java-json-tools:btf", + "com.github.java-json-tools:btf:jar:sources", + "com.github.java-json-tools:jackson-coreutils", + "com.github.java-json-tools:jackson-coreutils:jar:sources", + "com.github.java-json-tools:json-patch", + "com.github.java-json-tools:json-patch:jar:sources", + "com.github.java-json-tools:msg-simple", + "com.github.java-json-tools:msg-simple:jar:sources", + "com.github.jnr:jffi", + "com.github.jnr:jffi:jar:native", + "com.github.jnr:jffi:jar:sources", + "com.github.jnr:jnr-constants", + "com.github.jnr:jnr-constants:jar:sources", + "com.github.jnr:jnr-ffi", + "com.github.jnr:jnr-ffi:jar:sources", + "com.github.jnr:jnr-posix", + "com.github.jnr:jnr-posix:jar:sources", + "com.github.jnr:jnr-x86asm", + "com.github.jnr:jnr-x86asm:jar:sources", + "com.github.stephenc.jcip:jcip-annotations", + "com.github.stephenc.jcip:jcip-annotations:jar:sources", + "com.google.android:annotations", + "com.google.android:annotations:jar:sources", + "com.google.api.grpc:proto-google-common-protos", + "com.google.api.grpc:proto-google-common-protos:jar:sources", + "com.google.code.findbugs:jsr305", + "com.google.code.findbugs:jsr305:jar:sources", + "com.google.code.gson:gson", + "com.google.code.gson:gson:jar:sources", + "com.google.errorprone:error_prone_annotations", + "com.google.errorprone:error_prone_annotations:jar:sources", + "com.google.guava:failureaccess", + "com.google.guava:failureaccess:jar:sources", + "com.google.guava:guava", + "com.google.guava:guava:jar:sources", + "com.google.guava:listenablefuture", + "com.google.j2objc:j2objc-annotations", + "com.google.j2objc:j2objc-annotations:jar:sources", + "com.google.protobuf:protobuf-java", + "com.google.protobuf:protobuf-java-util", + "com.google.protobuf:protobuf-java-util:jar:sources", + "com.google.protobuf:protobuf-java:jar:sources", + "com.jayway.jsonpath:json-path", + "com.jayway.jsonpath:json-path:jar:sources", + "com.nimbusds:content-type", + "com.nimbusds:content-type:jar:sources", + "com.nimbusds:lang-tag", + "com.nimbusds:lang-tag:jar:sources", + "com.nimbusds:nimbus-jose-jwt", + "com.nimbusds:nimbus-jose-jwt:jar:sources", + "com.nimbusds:oauth2-oidc-sdk", + "com.nimbusds:oauth2-oidc-sdk:jar:sources", + "com.squareup.okhttp3:logging-interceptor", + "com.squareup.okhttp3:logging-interceptor:jar:sources", + "com.squareup.okhttp3:okhttp", + "com.squareup.okhttp3:okhttp-jvm", + "com.squareup.okhttp3:okhttp-jvm:jar:sources", + "com.squareup.okhttp3:okhttp:jar:sources", + "com.squareup.okio:okio", + "com.squareup.okio:okio-jvm", + "com.squareup.okio:okio-jvm:jar:sources", + "com.squareup.okio:okio:jar:sources", + "com.typesafe:config", + "com.typesafe:config:jar:sources", + "com.vaadin.external.google:android-json", + "com.vaadin.external.google:android-json:jar:sources", + "commons-codec:commons-codec", + "commons-codec:commons-codec:jar:sources", + "commons-io:commons-io", + "commons-io:commons-io:jar:sources", + "commons-logging:commons-logging", + "commons-logging:commons-logging:jar:sources", + "io.cloudevents:cloudevents-api", + "io.cloudevents:cloudevents-api:jar:sources", + "io.cloudevents:cloudevents-core", + "io.cloudevents:cloudevents-core:jar:sources", + "io.cloudevents:cloudevents-json-jackson", + "io.cloudevents:cloudevents-json-jackson:jar:sources", + "io.dropwizard.metrics:metrics-core", + "io.dropwizard.metrics:metrics-core:jar:sources", + "io.grpc:grpc-api", + "io.grpc:grpc-api:jar:sources", + "io.grpc:grpc-context", + "io.grpc:grpc-context:jar:sources", + "io.grpc:grpc-core", + "io.grpc:grpc-core:jar:sources", + "io.grpc:grpc-inprocess", + "io.grpc:grpc-inprocess:jar:sources", + "io.grpc:grpc-netty", + "io.grpc:grpc-netty-shaded", + "io.grpc:grpc-netty-shaded:jar:sources", + "io.grpc:grpc-netty:jar:sources", + "io.grpc:grpc-protobuf", + "io.grpc:grpc-protobuf-lite", + "io.grpc:grpc-protobuf-lite:jar:sources", + "io.grpc:grpc-protobuf:jar:sources", + "io.grpc:grpc-services", + "io.grpc:grpc-services:jar:sources", + "io.grpc:grpc-stub", + "io.grpc:grpc-stub:jar:sources", + "io.grpc:grpc-util", + "io.grpc:grpc-util:jar:sources", + "io.gsonfire:gson-fire", + "io.gsonfire:gson-fire:jar:sources", + "io.kubernetes:client-java", + "io.kubernetes:client-java-api", + "io.kubernetes:client-java-api-fluent", + "io.kubernetes:client-java-api-fluent:jar:sources", + "io.kubernetes:client-java-api:jar:sources", + "io.kubernetes:client-java-extended", + "io.kubernetes:client-java-extended:jar:sources", + "io.kubernetes:client-java-proto", + "io.kubernetes:client-java-proto:jar:sources", + "io.kubernetes:client-java:jar:sources", + "io.micrometer:context-propagation", + "io.micrometer:context-propagation:jar:sources", + "io.micrometer:micrometer-commons", + "io.micrometer:micrometer-commons:jar:sources", + "io.micrometer:micrometer-core", + "io.micrometer:micrometer-core:jar:sources", + "io.micrometer:micrometer-jakarta9", + "io.micrometer:micrometer-jakarta9:jar:sources", + "io.micrometer:micrometer-observation", + "io.micrometer:micrometer-observation-test", + "io.micrometer:micrometer-observation-test:jar:sources", + "io.micrometer:micrometer-observation:jar:sources", + "io.micrometer:micrometer-registry-prometheus", + "io.micrometer:micrometer-registry-prometheus:jar:sources", + "io.micrometer:micrometer-tracing", + "io.micrometer:micrometer-tracing-bridge-otel", + "io.micrometer:micrometer-tracing-bridge-otel:jar:sources", + "io.micrometer:micrometer-tracing:jar:sources", + "io.nats:jnats", + "io.nats:jnats:jar:sources", + "io.netty:netty-buffer", + "io.netty:netty-buffer:jar:sources", + "io.netty:netty-codec-base", + "io.netty:netty-codec-base:jar:sources", + "io.netty:netty-codec-classes-quic", + "io.netty:netty-codec-classes-quic:jar:sources", + "io.netty:netty-codec-compression", + "io.netty:netty-codec-compression:jar:sources", + "io.netty:netty-codec-dns", + "io.netty:netty-codec-dns:jar:sources", + "io.netty:netty-codec-http", + "io.netty:netty-codec-http2", + "io.netty:netty-codec-http2:jar:sources", + "io.netty:netty-codec-http3", + "io.netty:netty-codec-http3:jar:sources", + "io.netty:netty-codec-http:jar:sources", + "io.netty:netty-codec-native-quic:jar:linux-aarch_64", + "io.netty:netty-codec-native-quic:jar:linux-x86_64", + "io.netty:netty-codec-native-quic:jar:osx-aarch_64", + "io.netty:netty-codec-native-quic:jar:osx-x86_64", + "io.netty:netty-codec-native-quic:jar:sources", + "io.netty:netty-codec-native-quic:jar:windows-x86_64", + "io.netty:netty-codec-socks", + "io.netty:netty-codec-socks:jar:sources", + "io.netty:netty-common", + "io.netty:netty-common:jar:sources", + "io.netty:netty-handler", + "io.netty:netty-handler-proxy", + "io.netty:netty-handler-proxy:jar:sources", + "io.netty:netty-handler:jar:sources", + "io.netty:netty-resolver", + "io.netty:netty-resolver-dns", + "io.netty:netty-resolver-dns-classes-macos", + "io.netty:netty-resolver-dns-classes-macos:jar:sources", + "io.netty:netty-resolver-dns-native-macos:jar:osx-x86_64", + "io.netty:netty-resolver-dns-native-macos:jar:sources", + "io.netty:netty-resolver-dns:jar:sources", + "io.netty:netty-resolver:jar:sources", + "io.netty:netty-transport", + "io.netty:netty-transport-classes-epoll", + "io.netty:netty-transport-classes-epoll:jar:sources", + "io.netty:netty-transport-native-epoll:jar:linux-x86_64", + "io.netty:netty-transport-native-epoll:jar:sources", + "io.netty:netty-transport-native-unix-common", + "io.netty:netty-transport-native-unix-common:jar:sources", + "io.netty:netty-transport:jar:sources", + "io.opentelemetry.semconv:opentelemetry-semconv", + "io.opentelemetry.semconv:opentelemetry-semconv:jar:sources", + "io.opentelemetry:opentelemetry-api", + "io.opentelemetry:opentelemetry-api:jar:sources", + "io.opentelemetry:opentelemetry-common", + "io.opentelemetry:opentelemetry-common:jar:sources", + "io.opentelemetry:opentelemetry-context", + "io.opentelemetry:opentelemetry-context:jar:sources", + "io.opentelemetry:opentelemetry-exporter-common", + "io.opentelemetry:opentelemetry-exporter-common:jar:sources", + "io.opentelemetry:opentelemetry-exporter-otlp", + "io.opentelemetry:opentelemetry-exporter-otlp-common", + "io.opentelemetry:opentelemetry-exporter-otlp-common:jar:sources", + "io.opentelemetry:opentelemetry-exporter-otlp:jar:sources", + "io.opentelemetry:opentelemetry-exporter-sender-okhttp", + "io.opentelemetry:opentelemetry-exporter-sender-okhttp:jar:sources", + "io.opentelemetry:opentelemetry-extension-trace-propagators", + "io.opentelemetry:opentelemetry-extension-trace-propagators:jar:sources", + "io.opentelemetry:opentelemetry-sdk", + "io.opentelemetry:opentelemetry-sdk-common", + "io.opentelemetry:opentelemetry-sdk-common:jar:sources", + "io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi", + "io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi:jar:sources", + "io.opentelemetry:opentelemetry-sdk-logs", + "io.opentelemetry:opentelemetry-sdk-logs:jar:sources", + "io.opentelemetry:opentelemetry-sdk-metrics", + "io.opentelemetry:opentelemetry-sdk-metrics:jar:sources", + "io.opentelemetry:opentelemetry-sdk-testing", + "io.opentelemetry:opentelemetry-sdk-testing:jar:sources", + "io.opentelemetry:opentelemetry-sdk-trace", + "io.opentelemetry:opentelemetry-sdk-trace:jar:sources", + "io.opentelemetry:opentelemetry-sdk:jar:sources", + "io.perfmark:perfmark-api", + "io.perfmark:perfmark-api:jar:sources", + "io.projectreactor.netty:reactor-netty-core", + "io.projectreactor.netty:reactor-netty-core:jar:sources", + "io.projectreactor.netty:reactor-netty-http", + "io.projectreactor.netty:reactor-netty-http:jar:sources", + "io.projectreactor:reactor-core", + "io.projectreactor:reactor-core:jar:sources", + "io.projectreactor:reactor-test", + "io.projectreactor:reactor-test:jar:sources", + "io.prometheus:prometheus-metrics-config", + "io.prometheus:prometheus-metrics-config:jar:sources", + "io.prometheus:prometheus-metrics-core", + "io.prometheus:prometheus-metrics-core:jar:sources", + "io.prometheus:prometheus-metrics-exposition-formats", + "io.prometheus:prometheus-metrics-exposition-formats:jar:sources", + "io.prometheus:prometheus-metrics-exposition-textformats", + "io.prometheus:prometheus-metrics-exposition-textformats:jar:sources", + "io.prometheus:prometheus-metrics-model", + "io.prometheus:prometheus-metrics-model:jar:sources", + "io.prometheus:prometheus-metrics-tracer-common", + "io.prometheus:prometheus-metrics-tracer-common:jar:sources", + "io.swagger.core.v3:swagger-annotations-jakarta", + "io.swagger.core.v3:swagger-annotations-jakarta:jar:sources", + "io.swagger.core.v3:swagger-core-jakarta", + "io.swagger.core.v3:swagger-core-jakarta:jar:sources", + "io.swagger.core.v3:swagger-models-jakarta", + "io.swagger.core.v3:swagger-models-jakarta:jar:sources", + "io.swagger:swagger-annotations", + "io.swagger:swagger-annotations:jar:sources", + "jakarta.activation:jakarta.activation-api", + "jakarta.activation:jakarta.activation-api:jar:sources", + "jakarta.annotation:jakarta.annotation-api", + "jakarta.annotation:jakarta.annotation-api:jar:sources", + "jakarta.servlet:jakarta.servlet-api", + "jakarta.servlet:jakarta.servlet-api:jar:sources", + "jakarta.validation:jakarta.validation-api", + "jakarta.validation:jakarta.validation-api:jar:sources", + "jakarta.xml.bind:jakarta.xml.bind-api", + "jakarta.xml.bind:jakarta.xml.bind-api:jar:sources", + "javax.annotation:javax.annotation-api", + "javax.annotation:javax.annotation-api:jar:sources", + "net.bytebuddy:byte-buddy", + "net.bytebuddy:byte-buddy-agent", + "net.bytebuddy:byte-buddy-agent:jar:sources", + "net.bytebuddy:byte-buddy:jar:sources", + "net.devh:grpc-common-spring-boot", + "net.devh:grpc-common-spring-boot:jar:sources", + "net.devh:grpc-server-spring-boot-starter", + "net.devh:grpc-server-spring-boot-starter:jar:sources", + "net.java.dev.jna:jna", + "net.java.dev.jna:jna:jar:sources", + "net.javacrumbs.shedlock:shedlock-core", + "net.javacrumbs.shedlock:shedlock-core:jar:sources", + "net.javacrumbs.shedlock:shedlock-provider-cassandra", + "net.javacrumbs.shedlock:shedlock-provider-cassandra:jar:sources", + "net.javacrumbs.shedlock:shedlock-spring", + "net.javacrumbs.shedlock:shedlock-spring:jar:sources", + "net.minidev:accessors-smart", + "net.minidev:accessors-smart:jar:sources", + "net.minidev:json-smart", + "net.minidev:json-smart:jar:sources", + "org.apache.cassandra:java-driver-core", + "org.apache.cassandra:java-driver-core:jar:sources", + "org.apache.cassandra:java-driver-guava-shaded", + "org.apache.cassandra:java-driver-guava-shaded:jar:sources", + "org.apache.cassandra:java-driver-metrics-micrometer", + "org.apache.cassandra:java-driver-metrics-micrometer:jar:sources", + "org.apache.cassandra:java-driver-query-builder", + "org.apache.cassandra:java-driver-query-builder:jar:sources", + "org.apache.commons:commons-collections4", + "org.apache.commons:commons-collections4:jar:sources", + "org.apache.commons:commons-compress", + "org.apache.commons:commons-compress:jar:sources", + "org.apache.commons:commons-lang3", + "org.apache.commons:commons-lang3:jar:sources", + "org.apache.logging.log4j:log4j-api", + "org.apache.logging.log4j:log4j-api:jar:sources", + "org.apache.logging.log4j:log4j-to-slf4j", + "org.apache.logging.log4j:log4j-to-slf4j:jar:sources", + "org.apache.tomcat.embed:tomcat-embed-core", + "org.apache.tomcat.embed:tomcat-embed-core:jar:sources", + "org.apache.tomcat.embed:tomcat-embed-el", + "org.apache.tomcat.embed:tomcat-embed-el:jar:sources", + "org.apache.tomcat.embed:tomcat-embed-websocket", + "org.apache.tomcat.embed:tomcat-embed-websocket:jar:sources", + "org.apiguardian:apiguardian-api", + "org.apiguardian:apiguardian-api:jar:sources", + "org.aspectj:aspectjweaver", + "org.aspectj:aspectjweaver:jar:sources", + "org.assertj:assertj-core", + "org.assertj:assertj-core:jar:sources", + "org.awaitility:awaitility", + "org.awaitility:awaitility:jar:sources", + "org.bitbucket.b_c:jose4j", + "org.bitbucket.b_c:jose4j:jar:sources", + "org.bouncycastle:bcpkix-jdk18on", + "org.bouncycastle:bcpkix-jdk18on:jar:sources", + "org.bouncycastle:bcprov-jdk18on", + "org.bouncycastle:bcprov-jdk18on:jar:sources", + "org.bouncycastle:bcprov-lts8on", + "org.bouncycastle:bcprov-lts8on:jar:sources", + "org.bouncycastle:bcutil-jdk18on", + "org.bouncycastle:bcutil-jdk18on:jar:sources", + "org.checkerframework:checker-qual", + "org.checkerframework:checker-qual:jar:sources", + "org.codehaus.mojo:animal-sniffer-annotations", + "org.codehaus.mojo:animal-sniffer-annotations:jar:sources", + "org.hamcrest:hamcrest", + "org.hamcrest:hamcrest:jar:sources", + "org.hdrhistogram:HdrHistogram", + "org.hdrhistogram:HdrHistogram:jar:sources", + "org.hibernate.validator:hibernate-validator", + "org.hibernate.validator:hibernate-validator:jar:sources", + "org.jacoco:org.jacoco.agent:jar:runtime", + "org.jacoco:org.jacoco.agent:jar:sources", + "org.jacoco:org.jacoco.cli", + "org.jacoco:org.jacoco.cli:jar:sources", + "org.jacoco:org.jacoco.core", + "org.jacoco:org.jacoco.core:jar:sources", + "org.jacoco:org.jacoco.report", + "org.jacoco:org.jacoco.report:jar:sources", + "org.jboss.logging:jboss-logging", + "org.jboss.logging:jboss-logging:jar:sources", + "org.jetbrains.kotlin:kotlin-stdlib", + "org.jetbrains.kotlin:kotlin-stdlib-jdk7", + "org.jetbrains.kotlin:kotlin-stdlib-jdk7:jar:sources", + "org.jetbrains.kotlin:kotlin-stdlib-jdk8", + "org.jetbrains.kotlin:kotlin-stdlib-jdk8:jar:sources", + "org.jetbrains.kotlin:kotlin-stdlib:jar:sources", + "org.jetbrains:annotations", + "org.jetbrains:annotations:jar:sources", + "org.jspecify:jspecify", + "org.jspecify:jspecify:jar:sources", + "org.junit.jupiter:junit-jupiter", + "org.junit.jupiter:junit-jupiter-api", + "org.junit.jupiter:junit-jupiter-api:jar:sources", + "org.junit.jupiter:junit-jupiter-engine", + "org.junit.jupiter:junit-jupiter-engine:jar:sources", + "org.junit.jupiter:junit-jupiter-params", + "org.junit.jupiter:junit-jupiter-params:jar:sources", + "org.junit.jupiter:junit-jupiter:jar:sources", + "org.junit.platform:junit-platform-commons", + "org.junit.platform:junit-platform-commons:jar:sources", + "org.junit.platform:junit-platform-console-standalone", + "org.junit.platform:junit-platform-console-standalone:jar:sources", + "org.junit.platform:junit-platform-engine", + "org.junit.platform:junit-platform-engine:jar:sources", + "org.junit.platform:junit-platform-launcher", + "org.junit.platform:junit-platform-launcher:jar:sources", + "org.junit.platform:junit-platform-reporting", + "org.junit.platform:junit-platform-reporting:jar:sources", + "org.latencyutils:LatencyUtils", + "org.latencyutils:LatencyUtils:jar:sources", + "org.mockito:mockito-core", + "org.mockito:mockito-core:jar:sources", + "org.mockito:mockito-junit-jupiter", + "org.mockito:mockito-junit-jupiter:jar:sources", + "org.objenesis:objenesis", + "org.objenesis:objenesis:jar:sources", + "org.opentest4j.reporting:open-test-reporting-tooling-spi", + "org.opentest4j.reporting:open-test-reporting-tooling-spi:jar:sources", + "org.opentest4j:opentest4j", + "org.opentest4j:opentest4j:jar:sources", + "org.ow2.asm:asm", + "org.ow2.asm:asm-analysis", + "org.ow2.asm:asm-analysis:jar:sources", + "org.ow2.asm:asm-commons", + "org.ow2.asm:asm-commons:jar:sources", + "org.ow2.asm:asm-tree", + "org.ow2.asm:asm-tree:jar:sources", + "org.ow2.asm:asm-util", + "org.ow2.asm:asm-util:jar:sources", + "org.ow2.asm:asm:jar:sources", + "org.projectlombok:lombok", + "org.projectlombok:lombok:jar:sources", + "org.reactivestreams:reactive-streams", + "org.reactivestreams:reactive-streams:jar:sources", + "org.rnorth.duct-tape:duct-tape", + "org.rnorth.duct-tape:duct-tape:jar:sources", + "org.skyscreamer:jsonassert", + "org.skyscreamer:jsonassert:jar:sources", + "org.slf4j:jul-to-slf4j", + "org.slf4j:jul-to-slf4j:jar:sources", + "org.slf4j:slf4j-api", + "org.slf4j:slf4j-api:jar:sources", + "org.springdoc:springdoc-openapi-starter-common", + "org.springdoc:springdoc-openapi-starter-common:jar:sources", + "org.springdoc:springdoc-openapi-starter-webflux-api", + "org.springdoc:springdoc-openapi-starter-webflux-api:jar:sources", + "org.springdoc:springdoc-openapi-starter-webmvc-api", + "org.springdoc:springdoc-openapi-starter-webmvc-api:jar:sources", + "org.springframework.boot:spring-boot", + "org.springframework.boot:spring-boot-actuator", + "org.springframework.boot:spring-boot-actuator-autoconfigure", + "org.springframework.boot:spring-boot-actuator-autoconfigure:jar:sources", + "org.springframework.boot:spring-boot-actuator:jar:sources", + "org.springframework.boot:spring-boot-autoconfigure", + "org.springframework.boot:spring-boot-autoconfigure:jar:sources", + "org.springframework.boot:spring-boot-cassandra", + "org.springframework.boot:spring-boot-cassandra:jar:sources", + "org.springframework.boot:spring-boot-data-cassandra", + "org.springframework.boot:spring-boot-data-cassandra-test", + "org.springframework.boot:spring-boot-data-cassandra-test:jar:sources", + "org.springframework.boot:spring-boot-data-cassandra:jar:sources", + "org.springframework.boot:spring-boot-data-commons", + "org.springframework.boot:spring-boot-data-commons:jar:sources", + "org.springframework.boot:spring-boot-health", + "org.springframework.boot:spring-boot-health:jar:sources", + "org.springframework.boot:spring-boot-http-client", + "org.springframework.boot:spring-boot-http-client:jar:sources", + "org.springframework.boot:spring-boot-http-codec", + "org.springframework.boot:spring-boot-http-codec:jar:sources", + "org.springframework.boot:spring-boot-http-converter", + "org.springframework.boot:spring-boot-http-converter:jar:sources", + "org.springframework.boot:spring-boot-jackson", + "org.springframework.boot:spring-boot-jackson:jar:sources", + "org.springframework.boot:spring-boot-loader", + "org.springframework.boot:spring-boot-loader:jar:sources", + "org.springframework.boot:spring-boot-micrometer-metrics", + "org.springframework.boot:spring-boot-micrometer-metrics-test", + "org.springframework.boot:spring-boot-micrometer-metrics-test:jar:sources", + "org.springframework.boot:spring-boot-micrometer-metrics:jar:sources", + "org.springframework.boot:spring-boot-micrometer-observation", + "org.springframework.boot:spring-boot-micrometer-observation:jar:sources", + "org.springframework.boot:spring-boot-micrometer-tracing", + "org.springframework.boot:spring-boot-micrometer-tracing-opentelemetry", + "org.springframework.boot:spring-boot-micrometer-tracing-opentelemetry:jar:sources", + "org.springframework.boot:spring-boot-micrometer-tracing:jar:sources", + "org.springframework.boot:spring-boot-netty", + "org.springframework.boot:spring-boot-netty:jar:sources", + "org.springframework.boot:spring-boot-opentelemetry", + "org.springframework.boot:spring-boot-opentelemetry:jar:sources", + "org.springframework.boot:spring-boot-persistence", + "org.springframework.boot:spring-boot-persistence:jar:sources", + "org.springframework.boot:spring-boot-reactor", + "org.springframework.boot:spring-boot-reactor-netty", + "org.springframework.boot:spring-boot-reactor-netty:jar:sources", + "org.springframework.boot:spring-boot-reactor:jar:sources", + "org.springframework.boot:spring-boot-restclient", + "org.springframework.boot:spring-boot-restclient:jar:sources", + "org.springframework.boot:spring-boot-resttestclient", + "org.springframework.boot:spring-boot-resttestclient:jar:sources", + "org.springframework.boot:spring-boot-security", + "org.springframework.boot:spring-boot-security-oauth2-client", + "org.springframework.boot:spring-boot-security-oauth2-client:jar:sources", + "org.springframework.boot:spring-boot-security-oauth2-resource-server", + "org.springframework.boot:spring-boot-security-oauth2-resource-server:jar:sources", + "org.springframework.boot:spring-boot-security-test", + "org.springframework.boot:spring-boot-security-test:jar:sources", + "org.springframework.boot:spring-boot-security:jar:sources", + "org.springframework.boot:spring-boot-servlet", + "org.springframework.boot:spring-boot-servlet:jar:sources", + "org.springframework.boot:spring-boot-starter", + "org.springframework.boot:spring-boot-starter-actuator", + "org.springframework.boot:spring-boot-starter-actuator-test", + "org.springframework.boot:spring-boot-starter-actuator-test:jar:sources", + "org.springframework.boot:spring-boot-starter-actuator:jar:sources", + "org.springframework.boot:spring-boot-starter-aspectj", + "org.springframework.boot:spring-boot-starter-aspectj:jar:sources", + "org.springframework.boot:spring-boot-starter-data-cassandra", + "org.springframework.boot:spring-boot-starter-data-cassandra-test", + "org.springframework.boot:spring-boot-starter-data-cassandra-test:jar:sources", + "org.springframework.boot:spring-boot-starter-data-cassandra:jar:sources", + "org.springframework.boot:spring-boot-starter-jackson", + "org.springframework.boot:spring-boot-starter-jackson-test", + "org.springframework.boot:spring-boot-starter-jackson-test:jar:sources", + "org.springframework.boot:spring-boot-starter-jackson:jar:sources", + "org.springframework.boot:spring-boot-starter-logging", + "org.springframework.boot:spring-boot-starter-logging:jar:sources", + "org.springframework.boot:spring-boot-starter-micrometer-metrics", + "org.springframework.boot:spring-boot-starter-micrometer-metrics-test", + "org.springframework.boot:spring-boot-starter-micrometer-metrics-test:jar:sources", + "org.springframework.boot:spring-boot-starter-micrometer-metrics:jar:sources", + "org.springframework.boot:spring-boot-starter-reactor-netty", + "org.springframework.boot:spring-boot-starter-reactor-netty:jar:sources", + "org.springframework.boot:spring-boot-starter-security", + "org.springframework.boot:spring-boot-starter-security-oauth2-client", + "org.springframework.boot:spring-boot-starter-security-oauth2-client:jar:sources", + "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server", + "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server-test", + "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server-test:jar:sources", + "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server:jar:sources", + "org.springframework.boot:spring-boot-starter-security-test", + "org.springframework.boot:spring-boot-starter-security-test:jar:sources", + "org.springframework.boot:spring-boot-starter-security:jar:sources", + "org.springframework.boot:spring-boot-starter-test", + "org.springframework.boot:spring-boot-starter-test:jar:sources", + "org.springframework.boot:spring-boot-starter-tomcat", + "org.springframework.boot:spring-boot-starter-tomcat-runtime", + "org.springframework.boot:spring-boot-starter-tomcat-runtime:jar:sources", + "org.springframework.boot:spring-boot-starter-tomcat:jar:sources", + "org.springframework.boot:spring-boot-starter-validation", + "org.springframework.boot:spring-boot-starter-validation:jar:sources", + "org.springframework.boot:spring-boot-starter-web", + "org.springframework.boot:spring-boot-starter-web:jar:sources", + "org.springframework.boot:spring-boot-starter-webflux", + "org.springframework.boot:spring-boot-starter-webflux-test", + "org.springframework.boot:spring-boot-starter-webflux-test:jar:sources", + "org.springframework.boot:spring-boot-starter-webflux:jar:sources", + "org.springframework.boot:spring-boot-starter-webmvc", + "org.springframework.boot:spring-boot-starter-webmvc-test", + "org.springframework.boot:spring-boot-starter-webmvc-test:jar:sources", + "org.springframework.boot:spring-boot-starter-webmvc:jar:sources", + "org.springframework.boot:spring-boot-starter:jar:sources", + "org.springframework.boot:spring-boot-test", + "org.springframework.boot:spring-boot-test-autoconfigure", + "org.springframework.boot:spring-boot-test-autoconfigure:jar:sources", + "org.springframework.boot:spring-boot-test:jar:sources", + "org.springframework.boot:spring-boot-tomcat", + "org.springframework.boot:spring-boot-tomcat:jar:sources", + "org.springframework.boot:spring-boot-validation", + "org.springframework.boot:spring-boot-validation:jar:sources", + "org.springframework.boot:spring-boot-web-server", + "org.springframework.boot:spring-boot-web-server:jar:sources", + "org.springframework.boot:spring-boot-webclient", + "org.springframework.boot:spring-boot-webclient:jar:sources", + "org.springframework.boot:spring-boot-webflux", + "org.springframework.boot:spring-boot-webflux-test", + "org.springframework.boot:spring-boot-webflux-test:jar:sources", + "org.springframework.boot:spring-boot-webflux:jar:sources", + "org.springframework.boot:spring-boot-webmvc", + "org.springframework.boot:spring-boot-webmvc-test", + "org.springframework.boot:spring-boot-webmvc-test:jar:sources", + "org.springframework.boot:spring-boot-webmvc:jar:sources", + "org.springframework.boot:spring-boot-webtestclient", + "org.springframework.boot:spring-boot-webtestclient:jar:sources", + "org.springframework.boot:spring-boot:jar:sources", + "org.springframework.cloud:spring-cloud-commons", + "org.springframework.cloud:spring-cloud-commons:jar:sources", + "org.springframework.cloud:spring-cloud-context", + "org.springframework.cloud:spring-cloud-context:jar:sources", + "org.springframework.cloud:spring-cloud-kubernetes-client-autoconfig", + "org.springframework.cloud:spring-cloud-kubernetes-client-autoconfig:jar:sources", + "org.springframework.cloud:spring-cloud-kubernetes-client-config", + "org.springframework.cloud:spring-cloud-kubernetes-client-config:jar:sources", + "org.springframework.cloud:spring-cloud-kubernetes-commons", + "org.springframework.cloud:spring-cloud-kubernetes-commons:jar:sources", + "org.springframework.cloud:spring-cloud-starter", + "org.springframework.cloud:spring-cloud-starter-bootstrap", + "org.springframework.cloud:spring-cloud-starter-bootstrap:jar:sources", + "org.springframework.cloud:spring-cloud-starter-kubernetes-client-config", + "org.springframework.data:spring-data-cassandra", + "org.springframework.data:spring-data-cassandra:jar:sources", + "org.springframework.data:spring-data-commons", + "org.springframework.data:spring-data-commons:jar:sources", + "org.springframework.retry:spring-retry", + "org.springframework.retry:spring-retry:jar:sources", + "org.springframework.security:spring-security-config", + "org.springframework.security:spring-security-config:jar:sources", + "org.springframework.security:spring-security-core", + "org.springframework.security:spring-security-core:jar:sources", + "org.springframework.security:spring-security-crypto", + "org.springframework.security:spring-security-crypto:jar:sources", + "org.springframework.security:spring-security-oauth2-client", + "org.springframework.security:spring-security-oauth2-client:jar:sources", + "org.springframework.security:spring-security-oauth2-core", + "org.springframework.security:spring-security-oauth2-core:jar:sources", + "org.springframework.security:spring-security-oauth2-jose", + "org.springframework.security:spring-security-oauth2-jose:jar:sources", + "org.springframework.security:spring-security-oauth2-resource-server", + "org.springframework.security:spring-security-oauth2-resource-server:jar:sources", + "org.springframework.security:spring-security-test", + "org.springframework.security:spring-security-test:jar:sources", + "org.springframework.security:spring-security-web", + "org.springframework.security:spring-security-web:jar:sources", + "org.springframework:spring-aop", + "org.springframework:spring-aop:jar:sources", + "org.springframework:spring-beans", + "org.springframework:spring-beans:jar:sources", + "org.springframework:spring-context", + "org.springframework:spring-context-support", + "org.springframework:spring-context-support:jar:sources", + "org.springframework:spring-context:jar:sources", + "org.springframework:spring-core", + "org.springframework:spring-core:jar:sources", + "org.springframework:spring-expression", + "org.springframework:spring-expression:jar:sources", + "org.springframework:spring-test", + "org.springframework:spring-test:jar:sources", + "org.springframework:spring-tx", + "org.springframework:spring-tx:jar:sources", + "org.springframework:spring-web", + "org.springframework:spring-web:jar:sources", + "org.springframework:spring-webflux", + "org.springframework:spring-webflux:jar:sources", + "org.springframework:spring-webmvc", + "org.springframework:spring-webmvc:jar:sources", + "org.testcontainers:testcontainers", + "org.testcontainers:testcontainers-cassandra", + "org.testcontainers:testcontainers-cassandra:jar:sources", + "org.testcontainers:testcontainers-database-commons", + "org.testcontainers:testcontainers-database-commons:jar:sources", + "org.testcontainers:testcontainers-junit-jupiter", + "org.testcontainers:testcontainers-junit-jupiter:jar:sources", + "org.testcontainers:testcontainers-localstack", + "org.testcontainers:testcontainers-localstack:jar:sources", + "org.testcontainers:testcontainers:jar:sources", + "org.wiremock:wiremock-standalone", + "org.wiremock:wiremock-standalone:jar:sources", + "org.xmlunit:xmlunit-core", + "org.xmlunit:xmlunit-core:jar:sources", + "org.yaml:snakeyaml", + "org.yaml:snakeyaml:jar:sources", + "software.amazon.awssdk:annotations", + "software.amazon.awssdk:annotations:jar:sources", + "software.amazon.awssdk:checksums", + "software.amazon.awssdk:checksums-spi", + "software.amazon.awssdk:checksums-spi:jar:sources", + "software.amazon.awssdk:checksums:jar:sources", + "software.amazon.awssdk:endpoints-spi", + "software.amazon.awssdk:endpoints-spi:jar:sources", + "software.amazon.awssdk:http-auth-aws", + "software.amazon.awssdk:http-auth-aws:jar:sources", + "software.amazon.awssdk:http-auth-spi", + "software.amazon.awssdk:http-auth-spi:jar:sources", + "software.amazon.awssdk:http-client-spi", + "software.amazon.awssdk:http-client-spi:jar:sources", + "software.amazon.awssdk:identity-spi", + "software.amazon.awssdk:identity-spi:jar:sources", + "software.amazon.awssdk:json-utils", + "software.amazon.awssdk:json-utils:jar:sources", + "software.amazon.awssdk:metrics-spi", + "software.amazon.awssdk:metrics-spi:jar:sources", + "software.amazon.awssdk:profiles", + "software.amazon.awssdk:profiles:jar:sources", + "software.amazon.awssdk:regions", + "software.amazon.awssdk:regions:jar:sources", + "software.amazon.awssdk:retries", + "software.amazon.awssdk:retries-spi", + "software.amazon.awssdk:retries-spi:jar:sources", + "software.amazon.awssdk:retries:jar:sources", + "software.amazon.awssdk:sdk-core", + "software.amazon.awssdk:sdk-core:jar:sources", + "software.amazon.awssdk:third-party-jackson-core", + "software.amazon.awssdk:third-party-jackson-core:jar:sources", + "software.amazon.awssdk:utils", + "software.amazon.awssdk:utils:jar:sources", + "tools.jackson.core:jackson-core", + "tools.jackson.core:jackson-core:jar:sources", + "tools.jackson.core:jackson-databind", + "tools.jackson.core:jackson-databind:jar:sources", + "tools.jackson.module:jackson-module-blackbird", + "tools.jackson.module:jackson-module-blackbird:jar:sources" + ] + }, + "services": { + "ch.qos.logback:logback-classic": { + "jakarta.servlet.ServletContainerInitializer": [ + "ch.qos.logback.classic.servlet.LogbackServletContainerInitializer" + ], + "org.slf4j.spi.SLF4JServiceProvider": [ + "ch.qos.logback.classic.spi.LogbackServiceProvider" + ] + }, + "com.fasterxml.jackson.core:jackson-core": { + "com.fasterxml.jackson.core.JsonFactory": [ + "com.fasterxml.jackson.core.JsonFactory" + ] + }, + "com.fasterxml.jackson.core:jackson-databind": { + "com.fasterxml.jackson.core.ObjectCodec": [ + "com.fasterxml.jackson.databind.ObjectMapper" + ] + }, + "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml": { + "com.fasterxml.jackson.core.JsonFactory": [ + "com.fasterxml.jackson.dataformat.yaml.YAMLFactory" + ], + "com.fasterxml.jackson.core.ObjectCodec": [ + "com.fasterxml.jackson.dataformat.yaml.YAMLMapper" + ] + }, + "com.fasterxml.jackson.datatype:jackson-datatype-jsr310": { + "com.fasterxml.jackson.databind.Module": [ + "com.fasterxml.jackson.datatype.jsr310.JavaTimeModule" + ] + }, + "io.cloudevents:cloudevents-json-jackson": { + "io.cloudevents.core.format.EventFormat": [ + "io.cloudevents.jackson.JsonFormat" + ] + }, + "io.grpc:grpc-core": { + "io.grpc.LoadBalancerProvider": [ + "io.grpc.internal.PickFirstLoadBalancerProvider" + ], + "io.grpc.NameResolverProvider": [ + "io.grpc.internal.DnsNameResolverProvider" + ] + }, + "io.grpc:grpc-netty": { + "io.grpc.ManagedChannelProvider": [ + "io.grpc.netty.NettyChannelProvider", + "io.grpc.netty.UdsNettyChannelProvider" + ], + "io.grpc.NameResolverProvider": [ + "io.grpc.netty.UdsNameResolverProvider" + ], + "io.grpc.ServerProvider": [ + "io.grpc.netty.NettyServerProvider" + ] + }, + "io.grpc:grpc-netty-shaded": { + "io.grpc.ManagedChannelProvider": [ + "io.grpc.netty.shaded.io.grpc.netty.NettyChannelProvider", + "io.grpc.netty.shaded.io.grpc.netty.UdsNettyChannelProvider" + ], + "io.grpc.NameResolverProvider": [ + "io.grpc.netty.shaded.io.grpc.netty.UdsNameResolverProvider" + ], + "io.grpc.ServerProvider": [ + "io.grpc.netty.shaded.io.grpc.netty.NettyServerProvider" + ], + "reactor.blockhound.integration.BlockHoundIntegration": [ + "io.grpc.netty.shaded.io.netty.util.internal.Hidden$NettyBlockHoundIntegration" + ] + }, + "io.grpc:grpc-services": { + "io.grpc.LoadBalancerProvider": [ + "io.grpc.protobuf.services.internal.HealthCheckingRoundRobinLoadBalancerProvider" + ] + }, + "io.grpc:grpc-util": { + "io.grpc.LoadBalancerProvider": [ + "io.grpc.util.OutlierDetectionLoadBalancerProvider", + "io.grpc.util.SecretRoundRobinLoadBalancerProvider$Provider" + ] + }, + "io.micrometer:micrometer-observation": { + "io.micrometer.context.ThreadLocalAccessor": [ + "io.micrometer.observation.contextpropagation.ObservationThreadLocalAccessor" + ] + }, + "io.netty:netty-common": { + "reactor.blockhound.integration.BlockHoundIntegration": [ + "io.netty.util.internal.Hidden$NettyBlockHoundIntegration" + ] + }, + "io.opentelemetry:opentelemetry-exporter-otlp": { + "io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider": [ + "io.opentelemetry.exporter.otlp.internal.OtlpGrpcLogRecordExporterComponentProvider", + "io.opentelemetry.exporter.otlp.internal.OtlpGrpcMetricExporterComponentProvider", + "io.opentelemetry.exporter.otlp.internal.OtlpGrpcSpanExporterComponentProvider", + "io.opentelemetry.exporter.otlp.internal.OtlpHttpLogRecordExporterComponentProvider", + "io.opentelemetry.exporter.otlp.internal.OtlpHttpMetricExporterComponentProvider", + "io.opentelemetry.exporter.otlp.internal.OtlpHttpSpanExporterComponentProvider" + ], + "io.opentelemetry.sdk.autoconfigure.spi.logs.ConfigurableLogRecordExporterProvider": [ + "io.opentelemetry.exporter.otlp.internal.OtlpLogRecordExporterProvider" + ], + "io.opentelemetry.sdk.autoconfigure.spi.metrics.ConfigurableMetricExporterProvider": [ + "io.opentelemetry.exporter.otlp.internal.OtlpMetricExporterProvider" + ], + "io.opentelemetry.sdk.autoconfigure.spi.traces.ConfigurableSpanExporterProvider": [ + "io.opentelemetry.exporter.otlp.internal.OtlpSpanExporterProvider" + ] + }, + "io.opentelemetry:opentelemetry-exporter-sender-okhttp": { + "io.opentelemetry.exporter.internal.grpc.GrpcSenderProvider": [ + "io.opentelemetry.exporter.sender.okhttp.internal.OkHttpGrpcSenderProvider" + ], + "io.opentelemetry.exporter.internal.http.HttpSenderProvider": [ + "io.opentelemetry.exporter.sender.okhttp.internal.OkHttpHttpSenderProvider" + ] + }, + "io.opentelemetry:opentelemetry-extension-trace-propagators": { + "io.opentelemetry.sdk.autoconfigure.spi.ConfigurablePropagatorProvider": [ + "io.opentelemetry.extension.trace.propagation.B3ConfigurablePropagator", + "io.opentelemetry.extension.trace.propagation.B3MultiConfigurablePropagator", + "io.opentelemetry.extension.trace.propagation.JaegerConfigurablePropagator", + "io.opentelemetry.extension.trace.propagation.OtTraceConfigurablePropagator" + ], + "io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider": [ + "io.opentelemetry.extension.trace.propagation.internal.B3ComponentProvider", + "io.opentelemetry.extension.trace.propagation.internal.B3MultiComponentProvider", + "io.opentelemetry.extension.trace.propagation.internal.JaegerComponentProvider", + "io.opentelemetry.extension.trace.propagation.internal.OtTraceComponentProvider" + ] + }, + "io.opentelemetry:opentelemetry-sdk-testing": { + "io.opentelemetry.context.ContextStorageProvider": [ + "io.opentelemetry.sdk.testing.context.SettableContextStorageProvider" + ] + }, + "io.projectreactor.netty:reactor-netty-core": { + "io.micrometer.context.ContextAccessor": [ + "reactor.netty.contextpropagation.ChannelContextAccessor" + ] + }, + "io.projectreactor:reactor-core": { + "io.micrometer.context.ContextAccessor": [ + "reactor.util.context.ReactorContextAccessor" + ], + "reactor.blockhound.integration.BlockHoundIntegration": [ + "reactor.core.scheduler.ReactorBlockHoundIntegration" + ] + }, + "org.apache.cassandra:java-driver-core": { + "reactor.blockhound.integration.BlockHoundIntegration": [ + "com.datastax.oss.driver.internal.core.util.concurrent.DriverBlockHoundIntegration" + ] + }, + "org.apache.logging.log4j:log4j-api": { + "org.apache.logging.log4j.util.PropertySource": [ + "org.apache.logging.log4j.util.EnvironmentPropertySource", + "org.apache.logging.log4j.util.SystemPropertiesPropertySource" + ] + }, + "org.apache.logging.log4j:log4j-to-slf4j": { + "org.apache.logging.log4j.spi.Provider": [ + "org.apache.logging.slf4j.SLF4JProvider" + ] + }, + "org.apache.tomcat.embed:tomcat-embed-el": { + "jakarta.el.ExpressionFactory": [ + "org.apache.el.ExpressionFactoryImpl" + ] + }, + "org.apache.tomcat.embed:tomcat-embed-websocket": { + "jakarta.servlet.ServletContainerInitializer": [ + "org.apache.tomcat.websocket.server.WsSci" + ], + "jakarta.websocket.ContainerProvider": [ + "org.apache.tomcat.websocket.WsContainerProvider" + ], + "jakarta.websocket.server.ServerEndpointConfig$Configurator": [ + "org.apache.tomcat.websocket.server.DefaultServerEndpointConfigurator" + ] + }, + "org.bouncycastle:bcprov-jdk18on": { + "java.security.Provider": [ + "org.bouncycastle.jce.provider.BouncyCastleProvider", + "org.bouncycastle.pqc.jcajce.provider.BouncyCastlePQCProvider" + ] + }, + "org.bouncycastle:bcprov-lts8on": { + "java.security.Provider": [ + "org.bouncycastle.jce.provider.BouncyCastleProvider", + "org.bouncycastle.pqc.jcajce.provider.BouncyCastlePQCProvider" + ] + }, + "org.hibernate.validator:hibernate-validator": { + "jakarta.validation.spi.ValidationProvider": [ + "org.hibernate.validator.HibernateValidator" + ] + }, + "org.junit.jupiter:junit-jupiter-engine": { + "org.junit.platform.engine.TestEngine": [ + "org.junit.jupiter.engine.JupiterTestEngine" + ] + }, + "org.junit.platform:junit-platform-console-standalone": { + "java.util.spi.ToolProvider": [ + "org.junit.platform.console.ConsoleLauncherToolProvider" + ], + "org.junit.platform.engine.TestEngine": [ + "org.junit.jupiter.engine.JupiterTestEngine", + "org.junit.platform.suite.engine.SuiteTestEngine", + "org.junit.vintage.engine.VintageTestEngine" + ], + "org.junit.platform.engine.discovery.DiscoverySelectorIdentifierParser": [ + "org.junit.platform.engine.discovery.ClassSelector$IdentifierParser", + "org.junit.platform.engine.discovery.ClasspathResourceSelector$IdentifierParser", + "org.junit.platform.engine.discovery.ClasspathRootSelector$IdentifierParser", + "org.junit.platform.engine.discovery.DirectorySelector$IdentifierParser", + "org.junit.platform.engine.discovery.FileSelector$IdentifierParser", + "org.junit.platform.engine.discovery.IterationSelector$IdentifierParser", + "org.junit.platform.engine.discovery.MethodSelector$IdentifierParser", + "org.junit.platform.engine.discovery.ModuleSelector$IdentifierParser", + "org.junit.platform.engine.discovery.NestedClassSelector$IdentifierParser", + "org.junit.platform.engine.discovery.NestedMethodSelector$IdentifierParser", + "org.junit.platform.engine.discovery.PackageSelector$IdentifierParser", + "org.junit.platform.engine.discovery.UniqueIdSelector$IdentifierParser", + "org.junit.platform.engine.discovery.UriSelector$IdentifierParser" + ], + "org.junit.platform.launcher.TestExecutionListener": [ + "org.junit.platform.launcher.listeners.UniqueIdTrackingListener", + "org.junit.platform.reporting.open.xml.OpenTestReportGeneratingListener" + ], + "org.opentest4j.reporting.tooling.spi.htmlreport.Contributor": [ + "org.junit.platform.reporting.open.xml.JUnitContributor" + ] + }, + "org.junit.platform:junit-platform-engine": { + "org.junit.platform.engine.discovery.DiscoverySelectorIdentifierParser": [ + "org.junit.platform.engine.discovery.ClassSelector$IdentifierParser", + "org.junit.platform.engine.discovery.ClasspathResourceSelector$IdentifierParser", + "org.junit.platform.engine.discovery.ClasspathRootSelector$IdentifierParser", + "org.junit.platform.engine.discovery.DirectorySelector$IdentifierParser", + "org.junit.platform.engine.discovery.FileSelector$IdentifierParser", + "org.junit.platform.engine.discovery.IterationSelector$IdentifierParser", + "org.junit.platform.engine.discovery.MethodSelector$IdentifierParser", + "org.junit.platform.engine.discovery.ModuleSelector$IdentifierParser", + "org.junit.platform.engine.discovery.NestedClassSelector$IdentifierParser", + "org.junit.platform.engine.discovery.NestedMethodSelector$IdentifierParser", + "org.junit.platform.engine.discovery.PackageSelector$IdentifierParser", + "org.junit.platform.engine.discovery.UniqueIdSelector$IdentifierParser", + "org.junit.platform.engine.discovery.UriSelector$IdentifierParser" + ] + }, + "org.junit.platform:junit-platform-launcher": { + "org.junit.platform.launcher.TestExecutionListener": [ + "org.junit.platform.launcher.listeners.UniqueIdTrackingListener" + ] + }, + "org.junit.platform:junit-platform-reporting": { + "org.junit.platform.launcher.TestExecutionListener": [ + "org.junit.platform.reporting.open.xml.OpenTestReportGeneratingListener" + ], + "org.opentest4j.reporting.tooling.spi.htmlreport.Contributor": [ + "org.junit.platform.reporting.open.xml.JUnitContributor" + ] + }, + "org.projectlombok:lombok": { + "javax.annotation.processing.Processor": [ + "lombok.launch.AnnotationProcessorHider$AnnotationProcessor", + "lombok.launch.AnnotationProcessorHider$ClaimingProcessor" + ], + "lombok.core.LombokApp": [ + "lombok.bytecode.PoolConstantsApp", + "lombok.bytecode.PostCompilerApp", + "lombok.core.Main$LicenseApp", + "lombok.core.Main$VersionApp", + "lombok.core.PublicApiCreatorApp", + "lombok.core.configuration.ConfigurationApp", + "lombok.core.runtimeDependencies.CreateLombokRuntimeApp", + "lombok.delombok.DelombokApp", + "lombok.eclipse.agent.MavenEcjBootstrapApp", + "lombok.installer.Installer$CommandLineInstallerApp", + "lombok.installer.Installer$CommandLineUninstallerApp", + "lombok.installer.Installer$GraphicalInstallerApp" + ], + "lombok.core.PostCompilerTransformation": [ + "lombok.bytecode.PreventNullAnalysisRemover", + "lombok.bytecode.SneakyThrowsRemover" + ], + "lombok.core.runtimeDependencies.RuntimeDependencyInfo": [ + "lombok.core.handlers.SneakyThrowsAndCleanupDependencyInfo" + ], + "lombok.eclipse.EclipseASTVisitor": [ + "lombok.eclipse.handlers.HandleFieldDefaults", + "lombok.eclipse.handlers.HandleVal" + ], + "lombok.eclipse.EclipseAnnotationHandler": [ + "lombok.eclipse.handlers.HandleAccessors", + "lombok.eclipse.handlers.HandleBuilder", + "lombok.eclipse.handlers.HandleBuilderDefault", + "lombok.eclipse.handlers.HandleCleanup", + "lombok.eclipse.handlers.HandleConstructor$HandleAllArgsConstructor", + "lombok.eclipse.handlers.HandleConstructor$HandleNoArgsConstructor", + "lombok.eclipse.handlers.HandleConstructor$HandleRequiredArgsConstructor", + "lombok.eclipse.handlers.HandleData", + "lombok.eclipse.handlers.HandleDelegate", + "lombok.eclipse.handlers.HandleEqualsAndHashCode", + "lombok.eclipse.handlers.HandleExtensionMethod", + "lombok.eclipse.handlers.HandleFieldNameConstants", + "lombok.eclipse.handlers.HandleGetter", + "lombok.eclipse.handlers.HandleHelper", + "lombok.eclipse.handlers.HandleJacksonized", + "lombok.eclipse.handlers.HandleLocked", + "lombok.eclipse.handlers.HandleLockedRead", + "lombok.eclipse.handlers.HandleLockedWrite", + "lombok.eclipse.handlers.HandleLog$HandleCommonsLog", + "lombok.eclipse.handlers.HandleLog$HandleCustomLog", + "lombok.eclipse.handlers.HandleLog$HandleFloggerLog", + "lombok.eclipse.handlers.HandleLog$HandleJBossLog", + "lombok.eclipse.handlers.HandleLog$HandleJulLog", + "lombok.eclipse.handlers.HandleLog$HandleLog4j2Log", + "lombok.eclipse.handlers.HandleLog$HandleLog4jLog", + "lombok.eclipse.handlers.HandleLog$HandleSlf4jLog", + "lombok.eclipse.handlers.HandleLog$HandleXSlf4jLog", + "lombok.eclipse.handlers.HandleNonNull", + "lombok.eclipse.handlers.HandlePrintAST", + "lombok.eclipse.handlers.HandleSetter", + "lombok.eclipse.handlers.HandleSneakyThrows", + "lombok.eclipse.handlers.HandleStandardException", + "lombok.eclipse.handlers.HandleSuperBuilder", + "lombok.eclipse.handlers.HandleSynchronized", + "lombok.eclipse.handlers.HandleToString", + "lombok.eclipse.handlers.HandleUtilityClass", + "lombok.eclipse.handlers.HandleValue", + "lombok.eclipse.handlers.HandleWith", + "lombok.eclipse.handlers.HandleWithBy" + ], + "lombok.eclipse.handlers.EclipseSingularsRecipes$EclipseSingularizer": [ + "lombok.eclipse.handlers.singulars.EclipseGuavaMapSingularizer", + "lombok.eclipse.handlers.singulars.EclipseGuavaSetListSingularizer", + "lombok.eclipse.handlers.singulars.EclipseGuavaTableSingularizer", + "lombok.eclipse.handlers.singulars.EclipseJavaUtilListSingularizer", + "lombok.eclipse.handlers.singulars.EclipseJavaUtilMapSingularizer", + "lombok.eclipse.handlers.singulars.EclipseJavaUtilSetSingularizer" + ], + "lombok.installer.IdeLocationProvider": [ + "lombok.installer.eclipse.AngularIDELocationProvider", + "lombok.installer.eclipse.EclipseLocationProvider", + "lombok.installer.eclipse.JbdsLocationProvider", + "lombok.installer.eclipse.MyEclipseLocationProvider", + "lombok.installer.eclipse.RhcrLocationProvider", + "lombok.installer.eclipse.RhdsLocationProvider", + "lombok.installer.eclipse.STS4LocationProvider", + "lombok.installer.eclipse.STS5LocationProvider", + "lombok.installer.eclipse.STSLocationProvider" + ], + "lombok.javac.JavacASTVisitor": [ + "lombok.javac.handlers.HandleFieldDefaults", + "lombok.javac.handlers.HandleVal" + ], + "lombok.javac.JavacAnnotationHandler": [ + "lombok.javac.handlers.HandleAccessors", + "lombok.javac.handlers.HandleBuilder", + "lombok.javac.handlers.HandleBuilderDefault", + "lombok.javac.handlers.HandleBuilderDefaultRemove", + "lombok.javac.handlers.HandleBuilderRemove", + "lombok.javac.handlers.HandleCleanup", + "lombok.javac.handlers.HandleConstructor$HandleAllArgsConstructor", + "lombok.javac.handlers.HandleConstructor$HandleNoArgsConstructor", + "lombok.javac.handlers.HandleConstructor$HandleRequiredArgsConstructor", + "lombok.javac.handlers.HandleData", + "lombok.javac.handlers.HandleDelegate", + "lombok.javac.handlers.HandleEqualsAndHashCode", + "lombok.javac.handlers.HandleExtensionMethod", + "lombok.javac.handlers.HandleFieldNameConstants", + "lombok.javac.handlers.HandleGetter", + "lombok.javac.handlers.HandleHelper", + "lombok.javac.handlers.HandleJacksonized", + "lombok.javac.handlers.HandleLocked", + "lombok.javac.handlers.HandleLockedRead", + "lombok.javac.handlers.HandleLockedWrite", + "lombok.javac.handlers.HandleLog$HandleCommonsLog", + "lombok.javac.handlers.HandleLog$HandleCustomLog", + "lombok.javac.handlers.HandleLog$HandleFloggerLog", + "lombok.javac.handlers.HandleLog$HandleJBossLog", + "lombok.javac.handlers.HandleLog$HandleJulLog", + "lombok.javac.handlers.HandleLog$HandleLog4j2Log", + "lombok.javac.handlers.HandleLog$HandleLog4jLog", + "lombok.javac.handlers.HandleLog$HandleSlf4jLog", + "lombok.javac.handlers.HandleLog$HandleXSlf4jLog", + "lombok.javac.handlers.HandleNonNull", + "lombok.javac.handlers.HandlePrintAST", + "lombok.javac.handlers.HandleSetter", + "lombok.javac.handlers.HandleSingularRemove", + "lombok.javac.handlers.HandleSneakyThrows", + "lombok.javac.handlers.HandleStandardException", + "lombok.javac.handlers.HandleSuperBuilder", + "lombok.javac.handlers.HandleSuperBuilderRemove", + "lombok.javac.handlers.HandleSynchronized", + "lombok.javac.handlers.HandleToString", + "lombok.javac.handlers.HandleUtilityClass", + "lombok.javac.handlers.HandleValue", + "lombok.javac.handlers.HandleWith", + "lombok.javac.handlers.HandleWithBy" + ], + "lombok.javac.handlers.JavacSingularsRecipes$JavacSingularizer": [ + "lombok.javac.handlers.singulars.JavacGuavaMapSingularizer", + "lombok.javac.handlers.singulars.JavacGuavaSetListSingularizer", + "lombok.javac.handlers.singulars.JavacGuavaTableSingularizer", + "lombok.javac.handlers.singulars.JavacJavaUtilListSingularizer", + "lombok.javac.handlers.singulars.JavacJavaUtilMapSingularizer", + "lombok.javac.handlers.singulars.JavacJavaUtilSetSingularizer" + ] + }, + "org.springframework.boot:spring-boot": { + "ch.qos.logback.classic.spi.Configurator": [ + "org.springframework.boot.logging.logback.RootLogLevelConfigurator" + ], + "org.apache.logging.log4j.util.PropertySource": [ + "org.springframework.boot.logging.log4j2.SpringBootPropertySource" + ] + }, + "org.springframework.boot:spring-boot-loader": { + "java.nio.file.spi.FileSystemProvider": [ + "org.springframework.boot.loader.nio.file.NestedFileSystemProvider" + ] + }, + "org.springframework.boot:spring-boot-micrometer-tracing-opentelemetry": { + "org.junit.platform.launcher.TestExecutionListener": [ + "org.springframework.boot.micrometer.tracing.opentelemetry.autoconfigure.OpenTelemetryEventPublisherBeansTestExecutionListener" + ] + }, + "org.springframework.data:spring-data-cassandra": { + "jakarta.enterprise.inject.spi.Extension": [ + "org.springframework.data.cassandra.repository.cdi.CassandraRepositoryExtension" + ] + }, + "org.springframework.security:spring-security-core": { + "io.micrometer.context.ThreadLocalAccessor": [ + "org.springframework.security.core.context.ReactiveSecurityContextHolderThreadLocalAccessor", + "org.springframework.security.core.context.SecurityContextHolderThreadLocalAccessor" + ] + }, + "org.springframework.security:spring-security-web": { + "io.micrometer.context.ThreadLocalAccessor": [ + "org.springframework.security.web.server.ServerWebExchangeThreadLocalAccessor" + ] + }, + "org.springframework:spring-core": { + "reactor.blockhound.integration.BlockHoundIntegration": [ + "org.springframework.core.ReactiveAdapterRegistry$SpringCoreBlockHoundIntegration" + ] + }, + "org.springframework:spring-web": { + "jakarta.servlet.ServletContainerInitializer": [ + "org.springframework.web.SpringServletContainerInitializer" + ], + "reactor.blockhound.integration.BlockHoundIntegration": [ + "org.springframework.web.server.adapter.WebHttpHandlerBuilder$SpringWebBlockHoundIntegration" + ] + }, + "org.testcontainers:testcontainers": { + "org.testcontainers.dockerclient.DockerClientProviderStrategy": [ + "org.testcontainers.dockerclient.DockerDesktopClientProviderStrategy", + "org.testcontainers.dockerclient.DockerMachineClientProviderStrategy", + "org.testcontainers.dockerclient.EnvironmentAndSystemPropertyClientProviderStrategy", + "org.testcontainers.dockerclient.NpipeSocketClientProviderStrategy", + "org.testcontainers.dockerclient.RootlessDockerClientProviderStrategy", + "org.testcontainers.dockerclient.TestcontainersHostPropertyClientProviderStrategy", + "org.testcontainers.dockerclient.UnixSocketClientProviderStrategy" + ], + "org.testcontainers.shaded.com.fasterxml.jackson.core.JsonFactory": [ + "org.testcontainers.shaded.com.fasterxml.jackson.core.JsonFactory" + ], + "org.testcontainers.shaded.com.fasterxml.jackson.core.ObjectCodec": [ + "org.testcontainers.shaded.com.fasterxml.jackson.databind.ObjectMapper" + ] + }, + "org.wiremock:wiremock-standalone": { + "wiremock.com.fasterxml.jackson.core.JsonFactory": [ + "wiremock.com.fasterxml.jackson.core.JsonFactory", + "wiremock.com.fasterxml.jackson.dataformat.yaml.YAMLFactory" + ], + "wiremock.com.fasterxml.jackson.core.ObjectCodec": [ + "wiremock.com.fasterxml.jackson.databind.ObjectMapper", + "wiremock.com.fasterxml.jackson.dataformat.yaml.YAMLMapper" + ], + "wiremock.com.fasterxml.jackson.databind.Module": [ + "wiremock.com.fasterxml.jackson.datatype.jsr310.JavaTimeModule" + ], + "wiremock.org.eclipse.jetty.http.HttpFieldPreEncoder": [ + "wiremock.org.eclipse.jetty.http.Http1FieldPreEncoder", + "wiremock.org.eclipse.jetty.http2.hpack.HpackFieldPreEncoder" + ], + "wiremock.org.eclipse.jetty.io.ssl.ALPNProcessor$Client": [ + "wiremock.org.eclipse.jetty.alpn.java.client.JDK9ClientALPNProcessor" + ], + "wiremock.org.eclipse.jetty.io.ssl.ALPNProcessor$Server": [ + "wiremock.org.eclipse.jetty.alpn.java.server.JDK9ServerALPNProcessor" + ], + "wiremock.org.eclipse.jetty.webapp.Configuration": [ + "wiremock.org.eclipse.jetty.webapp.FragmentConfiguration", + "wiremock.org.eclipse.jetty.webapp.JaasConfiguration", + "wiremock.org.eclipse.jetty.webapp.JaspiConfiguration", + "wiremock.org.eclipse.jetty.webapp.JettyWebXmlConfiguration", + "wiremock.org.eclipse.jetty.webapp.JmxConfiguration", + "wiremock.org.eclipse.jetty.webapp.JndiConfiguration", + "wiremock.org.eclipse.jetty.webapp.JspConfiguration", + "wiremock.org.eclipse.jetty.webapp.MetaInfConfiguration", + "wiremock.org.eclipse.jetty.webapp.ServletsConfiguration", + "wiremock.org.eclipse.jetty.webapp.WebAppConfiguration", + "wiremock.org.eclipse.jetty.webapp.WebInfConfiguration", + "wiremock.org.eclipse.jetty.webapp.WebXmlConfiguration" + ], + "wiremock.org.slf4j.spi.SLF4JServiceProvider": [ + "wiremock.org.slf4j.helpers.NOP_FallbackServiceProvider" + ], + "wiremock.org.xmlunit.placeholder.PlaceholderHandler": [ + "wiremock.org.xmlunit.placeholder.IgnorePlaceholderHandler", + "wiremock.org.xmlunit.placeholder.IsDateTimePlaceholderHandler", + "wiremock.org.xmlunit.placeholder.IsNumberPlaceholderHandler", + "wiremock.org.xmlunit.placeholder.MatchesRegexPlaceholderHandler" + ] + }, + "software.amazon.awssdk:third-party-jackson-core": { + "software.amazon.awssdk.thirdparty.jackson.core.JsonFactory": [ + "software.amazon.awssdk.thirdparty.jackson.core.JsonFactory" + ] + }, + "tools.jackson.core:jackson-core": { + "tools.jackson.core.TokenStreamFactory": [ + "tools.jackson.core.json.JsonFactory" + ] + }, + "tools.jackson.core:jackson-databind": { + "tools.jackson.databind.ObjectMapper": [ + "tools.jackson.databind.json.JsonMapper" + ] + }, + "tools.jackson.module:jackson-module-blackbird": { + "tools.jackson.databind.JacksonModule": [ + "tools.jackson.module.blackbird.BlackbirdModule" + ] + } + }, + "skipped": [], + "version": "3" +} diff --git a/src/control-plane-services/cloud-tasks/nvct-core/BUILD.bazel b/src/control-plane-services/cloud-tasks/nvct-core/BUILD.bazel index 075240aeb..cca9b3952 100644 --- a/src/control-plane-services/cloud-tasks/nvct-core/BUILD.bazel +++ b/src/control-plane-services/cloud-tasks/nvct-core/BUILD.bazel @@ -1,8 +1,8 @@ load("@com_google_protobuf//bazel:proto_library.bzl", "proto_library") load("@contrib_rules_jvm//java:defs.bzl", "java_junit5_test") load("@rules_java//java:defs.bzl", "java_library") -load("//rules/java:defs.bzl", "nvcf_java_library") -load("//src/control-plane-services/cloud-tasks/tools/bazel:proto.bzl", "nvct_java_grpc_compile") +load("@nvcf_java_rules//:defs.bzl", "nvcf_java_library") +load("//tools/bazel:proto.bzl", "nvct_java_grpc_compile") package(default_visibility = ["//visibility:public"]) @@ -21,20 +21,20 @@ NVCT_JAVACOPTS = [ # nvcf_java_library does not wire Lombok; add the annotation processor plugin # plus the neverlink annotations jar to every library that compiles Lombok # sources. Both targets already exist in tools/bazel. -LOMBOK_PLUGINS = ["//src/control-plane-services/cloud-tasks/tools/bazel:lombok_plugin"] +LOMBOK_PLUGINS = ["//tools/bazel:lombok_plugin"] -LOMBOK_DEPS = ["//src/control-plane-services/cloud-tasks/tools/bazel:lombok_annotations"] +LOMBOK_DEPS = ["//tools/bazel:lombok_annotations"] JUNIT5_RUNTIME_DEPS = [ - "@nv_third_party_deps//:org_junit_jupiter_junit_jupiter_engine", - "@nv_third_party_deps//:org_junit_platform_junit_platform_launcher", - "@nv_third_party_deps//:org_junit_platform_junit_platform_reporting", + "@maven//:org_junit_jupiter_junit_jupiter_engine", + "@maven//:org_junit_platform_junit_platform_launcher", + "@maven//:org_junit_platform_junit_platform_reporting", ] NVCT_CORE_TEST_SRCS = glob(["src/test/java/**/*.java"]) NVCT_CORE_TEST_RESOURCES = glob(["src/test/resources/**"]) + [ - "//src/control-plane-services/cloud-tasks:integration_local_env_files", + "//:integration_local_env_files", ] proto_library( @@ -50,27 +50,27 @@ nvct_java_grpc_compile( # rules_proto_grpc_java's convenience java_grpc_library macro hardcodes its # private @maven runtime hub. Owning this small wrapper keeps all application -# runtime jars in the merged @nv_third_party_deps hub shared with nv-boot-parent. +# runtime jars in this module's own @maven hub. java_library( name = "nvct_proto_java_grpc", srcs = [":nvct_proto_java_grpc_srcs"], deps = [ - "@nv_third_party_deps//:com_google_guava_guava", - "@nv_third_party_deps//:com_google_protobuf_protobuf_java", - "@nv_third_party_deps//:com_google_protobuf_protobuf_java_util", - "@nv_third_party_deps//:io_grpc_grpc_api", - "@nv_third_party_deps//:io_grpc_grpc_protobuf", - "@nv_third_party_deps//:io_grpc_grpc_stub", - "@nv_third_party_deps//:javax_annotation_javax_annotation_api", + "@maven//:com_google_guava_guava", + "@maven//:com_google_protobuf_protobuf_java", + "@maven//:com_google_protobuf_protobuf_java_util", + "@maven//:io_grpc_grpc_api", + "@maven//:io_grpc_grpc_protobuf", + "@maven//:io_grpc_grpc_stub", + "@maven//:javax_annotation_javax_annotation_api", ], exports = [ - "@nv_third_party_deps//:com_google_guava_guava", - "@nv_third_party_deps//:com_google_protobuf_protobuf_java", - "@nv_third_party_deps//:com_google_protobuf_protobuf_java_util", - "@nv_third_party_deps//:io_grpc_grpc_api", - "@nv_third_party_deps//:io_grpc_grpc_protobuf", - "@nv_third_party_deps//:io_grpc_grpc_stub", - "@nv_third_party_deps//:javax_annotation_javax_annotation_api", + "@maven//:com_google_guava_guava", + "@maven//:com_google_protobuf_protobuf_java", + "@maven//:com_google_protobuf_protobuf_java_util", + "@maven//:io_grpc_grpc_api", + "@maven//:io_grpc_grpc_protobuf", + "@maven//:io_grpc_grpc_stub", + "@maven//:javax_annotation_javax_annotation_api", ], ) @@ -81,149 +81,149 @@ nvcf_java_library( plugins = LOMBOK_PLUGINS, deps = [ ":nvct_proto_java_grpc", - "@nv_third_party_deps//:com_bucket4j_bucket4j_jdk17_core", - "@nv_third_party_deps//:commons_codec_commons_codec", - "@nv_third_party_deps//:com_fasterxml_jackson_core_jackson_annotations", - "@nv_third_party_deps//:com_github_ben_manes_caffeine_caffeine", - "@nv_third_party_deps//:com_github_ben_manes_caffeine_guava", - "@nv_third_party_deps//:com_google_guava_guava", - "@nv_third_party_deps//:com_google_protobuf_protobuf_java", - "@nv_third_party_deps//:com_nimbusds_oauth2_oidc_sdk", - "//src/libraries/java/nv-boot-parent/nv-boot-starter-audit:nv_boot_starter_audit", - "//src/libraries/java/nv-boot-parent/nv-boot-starter-cassandra:nv_boot_starter_cassandra", - "//src/libraries/java/nv-boot-parent/nv-boot-starter-core:nv_boot_starter_core", - "//src/libraries/java/nv-boot-parent/nv-boot-starter-exceptions:nv_boot_starter_exceptions", - "//src/libraries/java/nv-boot-parent/nv-boot-starter-observability:nv_boot_starter_observability", - "//src/libraries/java/nv-boot-parent/nv-boot-starter-registries:nv_boot_starter_registries", - "//src/libraries/java/nv-boot-parent/nv-boot-starter-reloadable-properties:nv_boot_starter_reloadable_properties", - "@nv_third_party_deps//:io_grpc_grpc_api", - "@nv_third_party_deps//:io_grpc_grpc_netty_shaded", - "@nv_third_party_deps//:io_grpc_grpc_stub", - "@nv_third_party_deps//:io_micrometer_micrometer_core", - "@nv_third_party_deps//:io_micrometer_micrometer_observation", - "@nv_third_party_deps//:io_micrometer_micrometer_registry_prometheus", - "@nv_third_party_deps//:io_micrometer_micrometer_tracing", - "@nv_third_party_deps//:io_swagger_core_v3_swagger_annotations_jakarta", - "@nv_third_party_deps//:io_swagger_core_v3_swagger_models_jakarta", - "@nv_third_party_deps//:io_netty_netty_transport", - "@nv_third_party_deps//:io_netty_netty_handler", - "@nv_third_party_deps//:jakarta_annotation_jakarta_annotation_api", - "@nv_third_party_deps//:jakarta_servlet_jakarta_servlet_api", - "@nv_third_party_deps//:jakarta_validation_jakarta_validation_api", - "@nv_third_party_deps//:net_devh_grpc_server_spring_boot_starter", - "@nv_third_party_deps//:net_javacrumbs_shedlock_shedlock_core", - "@nv_third_party_deps//:net_javacrumbs_shedlock_shedlock_provider_cassandra", - "@nv_third_party_deps//:net_javacrumbs_shedlock_shedlock_spring", - "@nv_third_party_deps//:org_apache_cassandra_java_driver_metrics_micrometer", - "@nv_third_party_deps//:org_apache_cassandra_java_driver_core", - "@nv_third_party_deps//:org_apache_cassandra_java_driver_query_builder", - "@nv_third_party_deps//:org_apache_commons_commons_lang3", - "@nv_third_party_deps//:org_apache_logging_log4j_log4j_api", - "@nv_third_party_deps//:org_hibernate_validator_hibernate_validator", - "@nv_third_party_deps//:org_jspecify_jspecify", - "@nv_third_party_deps//:org_slf4j_slf4j_api", - "@nv_third_party_deps//:org_springdoc_springdoc_openapi_starter_common", - "@nv_third_party_deps//:org_springdoc_springdoc_openapi_starter_webmvc_api", - "@nv_third_party_deps//:org_springframework_boot_spring_boot", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_actuator", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_autoconfigure", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_micrometer_metrics", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_aspectj", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_jackson", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_security", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_security_oauth2_client", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_security_oauth2_resource_server", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_validation", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_webmvc", - "@nv_third_party_deps//:org_springframework_cloud_spring_cloud_context", - "@nv_third_party_deps//:org_springframework_cloud_spring_cloud_starter_kubernetes_client_config", - "@nv_third_party_deps//:org_springframework_data_spring_data_cassandra", - "@nv_third_party_deps//:org_springframework_data_spring_data_commons", - "@nv_third_party_deps//:org_springframework_spring_aop", - "@nv_third_party_deps//:org_springframework_spring_beans", - "@nv_third_party_deps//:org_springframework_spring_context", - "@nv_third_party_deps//:org_springframework_spring_context_support", - "@nv_third_party_deps//:org_springframework_spring_core", - "@nv_third_party_deps//:org_springframework_spring_expression", - "@nv_third_party_deps//:org_springframework_spring_tx", - "@nv_third_party_deps//:org_springframework_spring_web", - "@nv_third_party_deps//:org_springframework_spring_webflux", - "@nv_third_party_deps//:org_springframework_spring_webmvc", - "@nv_third_party_deps//:org_springframework_retry_spring_retry", - "@nv_third_party_deps//:org_springframework_security_spring_security_config", - "@nv_third_party_deps//:org_springframework_security_spring_security_core", - "@nv_third_party_deps//:org_springframework_security_spring_security_oauth2_client", - "@nv_third_party_deps//:org_springframework_security_spring_security_oauth2_core", - "@nv_third_party_deps//:org_springframework_security_spring_security_oauth2_jose", - "@nv_third_party_deps//:org_springframework_security_spring_security_oauth2_resource_server", - "@nv_third_party_deps//:org_springframework_security_spring_security_web", - "@nv_third_party_deps//:io_projectreactor_reactor_core", - "@nv_third_party_deps//:io_projectreactor_netty_reactor_netty_core", - "@nv_third_party_deps//:io_projectreactor_netty_reactor_netty_http", - "@nv_third_party_deps//:tools_jackson_core_jackson_core", - "@nv_third_party_deps//:tools_jackson_core_jackson_databind", - "@nv_third_party_deps//:tools_jackson_module_jackson_module_blackbird", + "@maven//:com_bucket4j_bucket4j_jdk17_core", + "@maven//:commons_codec_commons_codec", + "@maven//:com_fasterxml_jackson_core_jackson_annotations", + "@maven//:com_github_ben_manes_caffeine_caffeine", + "@maven//:com_github_ben_manes_caffeine_guava", + "@maven//:com_google_guava_guava", + "@maven//:com_google_protobuf_protobuf_java", + "@maven//:com_nimbusds_oauth2_oidc_sdk", + "@nv_boot_parent//nv-boot-starter-audit:nv_boot_starter_audit", + "@nv_boot_parent//nv-boot-starter-cassandra:nv_boot_starter_cassandra", + "@nv_boot_parent//nv-boot-starter-core:nv_boot_starter_core", + "@nv_boot_parent//nv-boot-starter-exceptions:nv_boot_starter_exceptions", + "@nv_boot_parent//nv-boot-starter-observability:nv_boot_starter_observability", + "@nv_boot_parent//nv-boot-starter-registries:nv_boot_starter_registries", + "@nv_boot_parent//nv-boot-starter-reloadable-properties:nv_boot_starter_reloadable_properties", + "@maven//:io_grpc_grpc_api", + "@maven//:io_grpc_grpc_netty_shaded", + "@maven//:io_grpc_grpc_stub", + "@maven//:io_micrometer_micrometer_core", + "@maven//:io_micrometer_micrometer_observation", + "@maven//:io_micrometer_micrometer_registry_prometheus", + "@maven//:io_micrometer_micrometer_tracing", + "@maven//:io_swagger_core_v3_swagger_annotations_jakarta", + "@maven//:io_swagger_core_v3_swagger_models_jakarta", + "@maven//:io_netty_netty_transport", + "@maven//:io_netty_netty_handler", + "@maven//:jakarta_annotation_jakarta_annotation_api", + "@maven//:jakarta_servlet_jakarta_servlet_api", + "@maven//:jakarta_validation_jakarta_validation_api", + "@maven//:net_devh_grpc_server_spring_boot_starter", + "@maven//:net_javacrumbs_shedlock_shedlock_core", + "@maven//:net_javacrumbs_shedlock_shedlock_provider_cassandra", + "@maven//:net_javacrumbs_shedlock_shedlock_spring", + "@maven//:org_apache_cassandra_java_driver_metrics_micrometer", + "@maven//:org_apache_cassandra_java_driver_core", + "@maven//:org_apache_cassandra_java_driver_query_builder", + "@maven//:org_apache_commons_commons_lang3", + "@maven//:org_apache_logging_log4j_log4j_api", + "@maven//:org_hibernate_validator_hibernate_validator", + "@maven//:org_jspecify_jspecify", + "@maven//:org_slf4j_slf4j_api", + "@maven//:org_springdoc_springdoc_openapi_starter_common", + "@maven//:org_springdoc_springdoc_openapi_starter_webmvc_api", + "@maven//:org_springframework_boot_spring_boot", + "@maven//:org_springframework_boot_spring_boot_actuator", + "@maven//:org_springframework_boot_spring_boot_autoconfigure", + "@maven//:org_springframework_boot_spring_boot_micrometer_metrics", + "@maven//:org_springframework_boot_spring_boot_starter_aspectj", + "@maven//:org_springframework_boot_spring_boot_starter_jackson", + "@maven//:org_springframework_boot_spring_boot_starter_security", + "@maven//:org_springframework_boot_spring_boot_starter_security_oauth2_client", + "@maven//:org_springframework_boot_spring_boot_starter_security_oauth2_resource_server", + "@maven//:org_springframework_boot_spring_boot_starter_validation", + "@maven//:org_springframework_boot_spring_boot_starter_webmvc", + "@maven//:org_springframework_cloud_spring_cloud_context", + "@maven//:org_springframework_cloud_spring_cloud_starter_kubernetes_client_config", + "@maven//:org_springframework_data_spring_data_cassandra", + "@maven//:org_springframework_data_spring_data_commons", + "@maven//:org_springframework_spring_aop", + "@maven//:org_springframework_spring_beans", + "@maven//:org_springframework_spring_context", + "@maven//:org_springframework_spring_context_support", + "@maven//:org_springframework_spring_core", + "@maven//:org_springframework_spring_expression", + "@maven//:org_springframework_spring_tx", + "@maven//:org_springframework_spring_web", + "@maven//:org_springframework_spring_webflux", + "@maven//:org_springframework_spring_webmvc", + "@maven//:org_springframework_retry_spring_retry", + "@maven//:org_springframework_security_spring_security_config", + "@maven//:org_springframework_security_spring_security_core", + "@maven//:org_springframework_security_spring_security_oauth2_client", + "@maven//:org_springframework_security_spring_security_oauth2_core", + "@maven//:org_springframework_security_spring_security_oauth2_jose", + "@maven//:org_springframework_security_spring_security_oauth2_resource_server", + "@maven//:org_springframework_security_spring_security_web", + "@maven//:io_projectreactor_reactor_core", + "@maven//:io_projectreactor_netty_reactor_netty_core", + "@maven//:io_projectreactor_netty_reactor_netty_http", + "@maven//:tools_jackson_core_jackson_core", + "@maven//:tools_jackson_core_jackson_databind", + "@maven//:tools_jackson_module_jackson_module_blackbird", ] + LOMBOK_DEPS, ) NVCT_CORE_TEST_DEPS = [ ":nvct_core", ":nvct_proto_java_grpc", - "@nv_third_party_deps//:org_apache_cassandra_java_driver_core", - "@nv_third_party_deps//:org_apache_cassandra_java_driver_guava_shaded", - "@nv_third_party_deps//:com_google_guava_guava", - "@nv_third_party_deps//:com_google_protobuf_protobuf_java", - "@nv_third_party_deps//:com_nimbusds_nimbus_jose_jwt", - "//src/libraries/java/nv-boot-parent/nv-boot-mock-servers-test:nv_boot_mock_servers_test", - "//src/libraries/java/nv-boot-parent/nv-boot-starter-audit:nv_boot_starter_audit", - "//src/libraries/java/nv-boot-parent/nv-boot-starter-core:nv_boot_starter_core", - "//src/libraries/java/nv-boot-parent/nv-boot-starter-exceptions:nv_boot_starter_exceptions", - "//src/libraries/java/nv-boot-parent/nv-boot-starter-observability:nv_boot_starter_observability", - "//src/libraries/java/nv-boot-parent/nv-boot-starter-registries:nv_boot_starter_registries", - "//src/libraries/java/nv-boot-parent/nv-boot-starter-reloadable-properties:nv_boot_starter_reloadable_properties", - "@nv_third_party_deps//:io_grpc_grpc_api", - "@nv_third_party_deps//:io_grpc_grpc_stub", - "@nv_third_party_deps//:io_micrometer_micrometer_core", - "@nv_third_party_deps//:io_opentelemetry_opentelemetry_api", - "@nv_third_party_deps//:io_opentelemetry_opentelemetry_sdk_testing", - "@nv_third_party_deps//:io_opentelemetry_opentelemetry_sdk_trace", - "@nv_third_party_deps//:io_projectreactor_reactor_core", - "@nv_third_party_deps//:io_projectreactor_netty_reactor_netty_core", - "@nv_third_party_deps//:jakarta_annotation_jakarta_annotation_api", - "@nv_third_party_deps//:jakarta_validation_jakarta_validation_api", - "@nv_third_party_deps//:net_minidev_json_smart", - "@nv_third_party_deps//:org_apache_commons_commons_lang3", - "@nv_third_party_deps//:org_apache_logging_log4j_log4j_api", - "@nv_third_party_deps//:org_assertj_assertj_core", - "@nv_third_party_deps//:org_awaitility_awaitility", - "@nv_third_party_deps//:org_junit_jupiter_junit_jupiter_api", - "@nv_third_party_deps//:org_junit_jupiter_junit_jupiter_params", - "@nv_third_party_deps//:org_mockito_mockito_core", - "@nv_third_party_deps//:org_mockito_mockito_junit_jupiter", - "@nv_third_party_deps//:org_springframework_boot_spring_boot", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_autoconfigure", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_micrometer_tracing", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_restclient", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_resttestclient", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_security", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_data_cassandra_test", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_webmvc_test", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_test", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_test_autoconfigure", - "@nv_third_party_deps//:org_slf4j_slf4j_api", - "@nv_third_party_deps//:org_springframework_data_spring_data_cassandra", - "@nv_third_party_deps//:org_springframework_spring_beans", - "@nv_third_party_deps//:org_springframework_spring_context", - "@nv_third_party_deps//:org_springframework_spring_core", - "@nv_third_party_deps//:org_springframework_spring_test", - "@nv_third_party_deps//:org_springframework_spring_web", - "@nv_third_party_deps//:org_springframework_spring_webflux", - "@nv_third_party_deps//:org_springframework_spring_webmvc", - "@nv_third_party_deps//:org_testcontainers_testcontainers", - "@nv_third_party_deps//:org_testcontainers_testcontainers_cassandra", - "@nv_third_party_deps//:tools_jackson_core_jackson_core", - "@nv_third_party_deps//:tools_jackson_core_jackson_databind", - "@nv_third_party_deps//:org_wiremock_wiremock_standalone", + "@maven//:org_apache_cassandra_java_driver_core", + "@maven//:org_apache_cassandra_java_driver_guava_shaded", + "@maven//:com_google_guava_guava", + "@maven//:com_google_protobuf_protobuf_java", + "@maven//:com_nimbusds_nimbus_jose_jwt", + "@nv_boot_parent//nv-boot-mock-servers-test:nv_boot_mock_servers_test", + "@nv_boot_parent//nv-boot-starter-audit:nv_boot_starter_audit", + "@nv_boot_parent//nv-boot-starter-core:nv_boot_starter_core", + "@nv_boot_parent//nv-boot-starter-exceptions:nv_boot_starter_exceptions", + "@nv_boot_parent//nv-boot-starter-observability:nv_boot_starter_observability", + "@nv_boot_parent//nv-boot-starter-registries:nv_boot_starter_registries", + "@nv_boot_parent//nv-boot-starter-reloadable-properties:nv_boot_starter_reloadable_properties", + "@maven//:io_grpc_grpc_api", + "@maven//:io_grpc_grpc_stub", + "@maven//:io_micrometer_micrometer_core", + "@maven//:io_opentelemetry_opentelemetry_api", + "@maven//:io_opentelemetry_opentelemetry_sdk_testing", + "@maven//:io_opentelemetry_opentelemetry_sdk_trace", + "@maven//:io_projectreactor_reactor_core", + "@maven//:io_projectreactor_netty_reactor_netty_core", + "@maven//:jakarta_annotation_jakarta_annotation_api", + "@maven//:jakarta_validation_jakarta_validation_api", + "@maven//:net_minidev_json_smart", + "@maven//:org_apache_commons_commons_lang3", + "@maven//:org_apache_logging_log4j_log4j_api", + "@maven//:org_assertj_assertj_core", + "@maven//:org_awaitility_awaitility", + "@maven//:org_junit_jupiter_junit_jupiter_api", + "@maven//:org_junit_jupiter_junit_jupiter_params", + "@maven//:org_mockito_mockito_core", + "@maven//:org_mockito_mockito_junit_jupiter", + "@maven//:org_springframework_boot_spring_boot", + "@maven//:org_springframework_boot_spring_boot_autoconfigure", + "@maven//:org_springframework_boot_spring_boot_micrometer_tracing", + "@maven//:org_springframework_boot_spring_boot_restclient", + "@maven//:org_springframework_boot_spring_boot_resttestclient", + "@maven//:org_springframework_boot_spring_boot_security", + "@maven//:org_springframework_boot_spring_boot_starter_data_cassandra_test", + "@maven//:org_springframework_boot_spring_boot_starter_webmvc_test", + "@maven//:org_springframework_boot_spring_boot_test", + "@maven//:org_springframework_boot_spring_boot_test_autoconfigure", + "@maven//:org_slf4j_slf4j_api", + "@maven//:org_springframework_data_spring_data_cassandra", + "@maven//:org_springframework_spring_beans", + "@maven//:org_springframework_spring_context", + "@maven//:org_springframework_spring_core", + "@maven//:org_springframework_spring_test", + "@maven//:org_springframework_spring_web", + "@maven//:org_springframework_spring_webflux", + "@maven//:org_springframework_spring_webmvc", + "@maven//:org_testcontainers_testcontainers", + "@maven//:org_testcontainers_testcontainers_cassandra", + "@maven//:tools_jackson_core_jackson_core", + "@maven//:tools_jackson_core_jackson_databind", + "@maven//:org_wiremock_wiremock_standalone", ] + LOMBOK_DEPS # Compiled test classes, reused by the nvct-service integration test module. @@ -246,7 +246,7 @@ java_junit5_test( # that pause/restart cycle on Linux, so retain the pre-Spring-7 lifecycle. jvm_flags = ["-Dspring.test.context.cache.pause=never"], data = [ - "//src/control-plane-services/cloud-tasks:integration_local_env", + "//:integration_local_env", ], tags = [ # Testcontainers/Cassandra integration test. Runs in the dedicated diff --git a/src/control-plane-services/cloud-tasks/nvct-service/BUILD.bazel b/src/control-plane-services/cloud-tasks/nvct-service/BUILD.bazel index 68f8cf568..70b7a0e8d 100644 --- a/src/control-plane-services/cloud-tasks/nvct-service/BUILD.bazel +++ b/src/control-plane-services/cloud-tasks/nvct-service/BUILD.bazel @@ -1,5 +1,5 @@ load("@contrib_rules_jvm//java:defs.bzl", "java_junit5_test") -load("//rules/java:defs.bzl", "nvcf_java_library", "nvcf_spring_boot_image") +load("@nvcf_java_rules//:defs.bzl", "nvcf_java_library", "nvcf_spring_boot_image") package(default_visibility = ["//visibility:public"]) @@ -18,14 +18,14 @@ NVCT_JAVACOPTS = [ # nvcf_java_library does not wire Lombok; add the annotation processor plugin # plus the neverlink annotations jar to every library that compiles Lombok # sources. Both targets already exist in tools/bazel. -LOMBOK_PLUGINS = ["//src/control-plane-services/cloud-tasks/tools/bazel:lombok_plugin"] +LOMBOK_PLUGINS = ["//tools/bazel:lombok_plugin"] -LOMBOK_DEPS = ["//src/control-plane-services/cloud-tasks/tools/bazel:lombok_annotations"] +LOMBOK_DEPS = ["//tools/bazel:lombok_annotations"] JUNIT5_RUNTIME_DEPS = [ - "@nv_third_party_deps//:org_junit_jupiter_junit_jupiter_engine", - "@nv_third_party_deps//:org_junit_platform_junit_platform_launcher", - "@nv_third_party_deps//:org_junit_platform_junit_platform_reporting", + "@maven//:org_junit_jupiter_junit_jupiter_engine", + "@maven//:org_junit_platform_junit_platform_launcher", + "@maven//:org_junit_platform_junit_platform_reporting", ] nvcf_java_library( @@ -33,16 +33,16 @@ nvcf_java_library( srcs = glob(["src/main/java/**/*.java"]), javacopts = NVCT_JAVACOPTS, plugins = LOMBOK_PLUGINS, - resource_strip_prefix = "src/control-plane-services/cloud-tasks/nvct-service/src/main/resources", + resource_strip_prefix = "nvct-service/src/main/resources", resources = glob(["src/main/resources/**"]), deps = [ - "//src/control-plane-services/cloud-tasks/nvct-core:nvct_core", - "@nv_third_party_deps//:org_slf4j_slf4j_api", - "@nv_third_party_deps//:org_springframework_boot_spring_boot", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_autoconfigure", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_loader", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_micrometer_tracing", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_security", + "//nvct-core:nvct_core", + "@maven//:org_slf4j_slf4j_api", + "@maven//:org_springframework_boot_spring_boot", + "@maven//:org_springframework_boot_spring_boot_autoconfigure", + "@maven//:org_springframework_boot_spring_boot_loader", + "@maven//:org_springframework_boot_spring_boot_micrometer_tracing", + "@maven//:org_springframework_boot_spring_boot_security", ] + LOMBOK_DEPS, ) @@ -63,10 +63,10 @@ java_junit5_test( javacopts = NVCT_JAVACOPTS, plugins = LOMBOK_PLUGINS, resources = glob(["src/test/resources/**"]) + [ - "//src/control-plane-services/cloud-tasks:integration_local_env_files", + "//:integration_local_env_files", ], data = [ - "//src/control-plane-services/cloud-tasks:integration_local_env", + "//:integration_local_env", ], tags = [ # Full Spring context + Testcontainers integration test. Runs in the @@ -78,28 +78,28 @@ java_junit5_test( timeout = "long", deps = [ ":app_classes", - "//src/control-plane-services/cloud-tasks/nvct-core:nvct_core", - "//src/control-plane-services/cloud-tasks/nvct-core:nvct_core_test_fixtures", - "//src/libraries/java/nv-boot-parent/nv-boot-mock-servers-test:nv_boot_mock_servers_test", - "@nv_third_party_deps//:io_opentelemetry_opentelemetry_sdk_testing", - "@nv_third_party_deps//:org_assertj_assertj_core", - "@nv_third_party_deps//:org_junit_jupiter_junit_jupiter_api", - "@nv_third_party_deps//:org_junit_jupiter_junit_jupiter_params", - "@nv_third_party_deps//:org_mockito_mockito_core", - "@nv_third_party_deps//:org_mockito_mockito_junit_jupiter", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_test", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_test_autoconfigure", - "@nv_third_party_deps//:org_springframework_spring_test", - "@nv_third_party_deps//:org_springframework_boot_spring_boot", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_restclient", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_resttestclient", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_webmvc_test", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_web_server", - "@nv_third_party_deps//:org_springframework_spring_beans", - "@nv_third_party_deps//:org_springframework_spring_web", - "@nv_third_party_deps//:org_springframework_spring_webmvc", - "@nv_third_party_deps//:org_testcontainers_testcontainers", - "@nv_third_party_deps//:org_testcontainers_testcontainers_cassandra", + "//nvct-core:nvct_core", + "//nvct-core:nvct_core_test_fixtures", + "@nv_boot_parent//nv-boot-mock-servers-test:nv_boot_mock_servers_test", + "@maven//:io_opentelemetry_opentelemetry_sdk_testing", + "@maven//:org_assertj_assertj_core", + "@maven//:org_junit_jupiter_junit_jupiter_api", + "@maven//:org_junit_jupiter_junit_jupiter_params", + "@maven//:org_mockito_mockito_core", + "@maven//:org_mockito_mockito_junit_jupiter", + "@maven//:org_springframework_boot_spring_boot_test", + "@maven//:org_springframework_boot_spring_boot_test_autoconfigure", + "@maven//:org_springframework_spring_test", + "@maven//:org_springframework_boot_spring_boot", + "@maven//:org_springframework_boot_spring_boot_restclient", + "@maven//:org_springframework_boot_spring_boot_resttestclient", + "@maven//:org_springframework_boot_spring_boot_starter_webmvc_test", + "@maven//:org_springframework_boot_spring_boot_web_server", + "@maven//:org_springframework_spring_beans", + "@maven//:org_springframework_spring_web", + "@maven//:org_springframework_spring_webmvc", + "@maven//:org_testcontainers_testcontainers", + "@maven//:org_testcontainers_testcontainers_cassandra", ] + LOMBOK_DEPS, runtime_deps = JUNIT5_RUNTIME_DEPS, ) diff --git a/src/control-plane-services/cloud-tasks/tools/bazel/BUILD.bazel b/src/control-plane-services/cloud-tasks/tools/bazel/BUILD.bazel index 144f56d8a..cd72e556c 100644 --- a/src/control-plane-services/cloud-tasks/tools/bazel/BUILD.bazel +++ b/src/control-plane-services/cloud-tasks/tools/bazel/BUILD.bazel @@ -24,17 +24,17 @@ java_plugin( name = "lombok_plugin", generates_api = True, processor_class = "lombok.launch.AnnotationProcessorHider$AnnotationProcessor", - deps = ["@nv_third_party_deps//:org_projectlombok_lombok"], + deps = ["@maven//:org_projectlombok_lombok"], ) java_binary( name = "jacoco_cli", main_class = "org.jacoco.cli.internal.Main", - runtime_deps = ["@nv_third_party_deps//:org_jacoco_org_jacoco_cli"], + runtime_deps = ["@maven//:org_jacoco_org_jacoco_cli"], ) java_library( name = "lombok_annotations", - exports = ["@nv_third_party_deps//:org_projectlombok_lombok"], + exports = ["@maven//:org_projectlombok_lombok"], neverlink = True, ) diff --git a/src/control-plane-services/cloud-tasks/tools/bazel/proto.bzl b/src/control-plane-services/cloud-tasks/tools/bazel/proto.bzl index 1e3c83dc1..ef77df006 100644 --- a/src/control-plane-services/cloud-tasks/tools/bazel/proto.bzl +++ b/src/control-plane-services/cloud-tasks/tools/bazel/proto.bzl @@ -18,7 +18,7 @@ nvct_java_grpc_compile = rule( providers = [ProtoPluginInfo], default = [ Label("@rules_proto_grpc_java//:proto_plugin"), - Label("//src/control-plane-services/cloud-tasks/tools/bazel:grpc_java_1_63_plugin"), + Label("//tools/bazel:grpc_java_1_63_plugin"), ], cfg = "exec", ), diff --git a/src/libraries/java/nv-boot-parent/.bazelrc b/src/libraries/java/nv-boot-parent/.bazelrc new file mode 100644 index 000000000..3dcfdd132 --- /dev/null +++ b/src/libraries/java/nv-boot-parent/.bazelrc @@ -0,0 +1,47 @@ +# SPDX-FileCopyrightText: Copyright (c) NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +# +# 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. + +# Standalone module .bazelrc. `cd rules/java && bazel build //...` must work with +# no reference to the repo root. The caller supplies any remote cache endpoint; +# no cache config is baked in (parity with the other nested modules). + +common --enable_bzlmod +common --enable_platform_specific_config +build --incompatible_strict_action_env + +# Route public Maven Central through an internal Artifactory mirror on internal +# builds only. The target host lives in an un-mirrored internal bazelrc, so +# public builds go straight to Maven Central (try-import is a no-op when absent). +try-import %workspace%/tools/bazel/internal.bazelrc + +# Java: hermetic remotejdk 25 regardless of the host JDK, matching the root +# module so builds are reproducible everywhere. +build --java_language_version=25 +build --java_runtime_version=remotejdk_25 +build --tool_java_language_version=25 +build --tool_java_runtime_version=remotejdk_25 +build --java_header_compilation=false + +test --test_output=errors +test --test_env=HOME=/tmp +test --test_env=XDG_CACHE_HOME=/tmp/.cache + +startup --host_jvm_args=-Xmx4g + +build:release --compilation_mode=opt +build:release --strip=always + +try-import %workspace%/user.bazelrc +try-import %user.home%/.bazelrc.user diff --git a/src/libraries/java/nv-boot-parent/AGENTS.md b/src/libraries/java/nv-boot-parent/AGENTS.md new file mode 100644 index 000000000..9188494c9 --- /dev/null +++ b/src/libraries/java/nv-boot-parent/AGENTS.md @@ -0,0 +1,47 @@ +# AGENTS.md - nv_boot_parent + +The NVCF Spring Boot platform library, as a standalone Bazel module +(`module(name = "nv_boot_parent")`). Owns the shared Spring BOM set and the +`nv-boot-*` starter `java_library` targets that every NVCF Java service depends +on. + +## Build and test (from this directory) + +``` +cd src/libraries/java/nv-boot-parent +bazel build //... +bazel test //... +``` + +The module builds on its own with no reference to the repo root. Docker +integration tests are tagged `requires-docker` and run in the dedicated +integration lane, not the default `bazel test //...`. + +## Maven dependencies + +This module has its own `@maven` hub and its own committed `maven_install.json`. +After editing `maven.install` in `MODULE.bazel`, re-pin and commit the lockfile: + +``` +REPIN=1 bazel run @maven//:pin +``` + +The `boms` list in `MODULE.bazel` must stay identical to `SPRING_BOOT_BOM` in +`@nvcf_java_rules//:platform.bzl`. `//:bom_alignment_test` fails the build if it +drifts. Bumping a shared version (Spring, Spring Cloud, Testcontainers, +ShedLock) is a one-line edit in that `platform.bzl`, the matching edit here, then +a re-pin. + +## Layout + +- `nv-boot-starter-*/` - the platform starters, each a public `nv_boot_library`. +- `tools/bazel/` - `nv_boot_library` / `nv_boot_library_test` macros + (`java.bzl`), Lombok wiring, JUnit 5 + JaCoCo runners, and the NOTICE + generator (`generate_notice.py`). +- `NOTICE` - generated from this module's own `maven_install.json`. + +## Consuming this module + +In-tree, a service module uses `bazel_dep` + `local_path_override`. Out-of-tree, +`git_override` with `strip_prefix = "src/libraries/java/nv-boot-parent"`, which +works because `MODULE.bazel` is rooted here. diff --git a/src/libraries/java/nv-boot-parent/BUILD.bazel b/src/libraries/java/nv-boot-parent/BUILD.bazel index 3c9cae942..7b8da684b 100644 --- a/src/libraries/java/nv-boot-parent/BUILD.bazel +++ b/src/libraries/java/nv-boot-parent/BUILD.bazel @@ -1,22 +1,31 @@ +load("@nvcf_java_rules//:bom_alignment.bzl", "bom_alignment_test") + package(default_visibility = ["//visibility:public"]) -exports_files(["NOTICE"]) +exports_files(["NOTICE", "MODULE.bazel"]) + +# Fails the build if this module's inlined maven.install boms drift from the +# canonical SPRING_BOOT_BOM in @nvcf_java_rules//:platform.bzl. load() cannot be +# used in MODULE.bazel, so the boms list is inlined and guarded here instead. +bom_alignment_test( + name = "bom_alignment_test", +) genrule( name = "third_party_notice", srcs = [ "//:maven_install.json", - "//src/libraries/java/nv-boot-parent/tools/bazel:notice_metadata.json", - "//src/libraries/java/nv-boot-parent/tools/bazel:notice_roots.json", + "//tools/bazel:notice_metadata.json", + "//tools/bazel:notice_roots.json", ], - tools = ["//src/libraries/java/nv-boot-parent/tools/bazel:generate_notice_tool"], + tools = ["//tools/bazel:generate_notice_tool"], outs = ["THIRD_PARTY_NOTICE"], cmd = """ set -eu -"$(execpath //src/libraries/java/nv-boot-parent/tools/bazel:generate_notice_tool)" \ +"$(execpath //tools/bazel:generate_notice_tool)" \ --maven-install "$(location //:maven_install.json)" \ - --metadata "$(location //src/libraries/java/nv-boot-parent/tools/bazel:notice_metadata.json)" \ - --root-manifest "$(location //src/libraries/java/nv-boot-parent/tools/bazel:notice_roots.json)" \ + --metadata "$(location //tools/bazel:notice_metadata.json)" \ + --root-manifest "$(location //tools/bazel:notice_roots.json)" \ --output "$@" \ --write """, @@ -26,10 +35,10 @@ genrule( name = "generate_notice", srcs = [ "//:maven_install.json", - "//src/libraries/java/nv-boot-parent/tools/bazel:notice_metadata.json", - "//src/libraries/java/nv-boot-parent/tools/bazel:notice_roots.json", + "//tools/bazel:notice_metadata.json", + "//tools/bazel:notice_roots.json", ], - tools = ["//src/libraries/java/nv-boot-parent/tools/bazel:generate_notice_tool"], + tools = ["//tools/bazel:generate_notice_tool"], outs = ["generate_notice.sh"], cmd = """ cat > "$@" <<'EOF' @@ -37,11 +46,11 @@ cat > "$@" <<'EOF' set -euo pipefail workspace="$${BUILD_WORKSPACE_DIRECTORY:-$$(pwd)}" -exec "$(execpath //src/libraries/java/nv-boot-parent/tools/bazel:generate_notice_tool)" \ +exec "$(execpath //tools/bazel:generate_notice_tool)" \ --maven-install "$(location //:maven_install.json)" \ --metadata "$${workspace}/tools/bazel/notice_metadata.json" \ --notice "$${workspace}/NOTICE" \ - --root-manifest "$(location //src/libraries/java/nv-boot-parent/tools/bazel:notice_roots.json)" \ + --root-manifest "$(location //tools/bazel:notice_roots.json)" \ "$$@" EOF chmod +x "$@" diff --git a/src/libraries/java/nv-boot-parent/CLAUDE.md b/src/libraries/java/nv-boot-parent/CLAUDE.md new file mode 100644 index 000000000..43c994c2d --- /dev/null +++ b/src/libraries/java/nv-boot-parent/CLAUDE.md @@ -0,0 +1 @@ +@AGENTS.md diff --git a/src/libraries/java/nv-boot-parent/MODULE.bazel b/src/libraries/java/nv-boot-parent/MODULE.bazel new file mode 100644 index 000000000..34493bc45 --- /dev/null +++ b/src/libraries/java/nv-boot-parent/MODULE.bazel @@ -0,0 +1,143 @@ +# SPDX-FileCopyrightText: Copyright (c) NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +# +# 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. + +"""nv_boot_parent: the NVCF Spring Boot platform library, as a standalone module. + +Owns the shared Spring BOM set and the nv-boot-* starter java_library targets. +Every Java service module depends on this module (bazel_dep + local_path_override +in-tree, git_override with strip_prefix out-of-tree) plus nvcf_java_rules, and +builds on its own: `cd src/libraries/java/nv-boot-parent && bazel build //...`. + +Maven: this module resolves its own graph into its own @maven hub and commits +its own maven_install.json. The boms list below is inlined (load() is forbidden +in MODULE.bazel) and must stay identical to SPRING_BOOT_BOM in +@nvcf_java_rules//:platform.bzl; //:bom_alignment_test enforces that. +""" + +module( + name = "nv_boot_parent", + version = "4.0.7", +) + +bazel_dep(name = "nvcf_java_rules", version = "0.1.0") +local_path_override( + module_name = "nvcf_java_rules", + path = "../../../../rules/java", +) + +bazel_dep(name = "rules_java", version = "9.3.0") +bazel_dep(name = "rules_jvm_external", version = "7.0") +bazel_dep(name = "rules_python", version = "1.4.1") +bazel_dep(name = "rules_shell", version = "0.8.0") + +python = use_extension("@rules_python//python/extensions:python.bzl", "python") +python.toolchain( + ignore_root_user_error = True, + python_version = "3.11", +) + +maven = use_extension("@rules_jvm_external//:extensions.bzl", "maven") +maven.install( + name = "maven", + artifacts = [ + # nv-boot-parent third-party closure (Spring Boot 4 / Spring Cloud / + # OTel / Cassandra / Testcontainers). Root coordinates only: BOM-managed + # starters/modules, parent-owned explicit pins, and build/test tools. + # Version-less coordinates are managed by the boms below. + "at.yawk.lz4:lz4-java:1.10.3", + "com.github.ben-manes.caffeine:guava", + "com.github.java-json-tools:json-patch:1.13", + "commons-codec:commons-codec", + "io.cloudevents:cloudevents-core:4.1.1", + "io.cloudevents:cloudevents-json-jackson:4.1.1", + "io.micrometer:micrometer-tracing-bridge-otel", + "io.nats:jnats:2.23.0", + "io.opentelemetry:opentelemetry-exporter-otlp", + "io.opentelemetry:opentelemetry-sdk-testing", + "jakarta.servlet:jakarta.servlet-api", + "org.apache.cassandra:java-driver-metrics-micrometer", + "org.apache.commons:commons-lang3:3.20.0", + "org.bouncycastle:bcprov-jdk18on:1.84", + "org.jacoco:org.jacoco.agent:jar:runtime:0.8.14", + "org.jacoco:org.jacoco.cli:0.8.14", + "org.junit.platform:junit-platform-console-standalone:6.0.3", + "org.ow2.asm:asm-analysis:9.9", + "org.ow2.asm:asm-util:9.9", + "org.projectlombok:lombok", + "org.springdoc:springdoc-openapi-starter-webflux-api:3.0.3", + "org.springdoc:springdoc-openapi-starter-webmvc-api:3.0.3", + "org.springframework.boot:spring-boot-micrometer-tracing-opentelemetry", + "org.springframework.boot:spring-boot-restclient", + "org.springframework.boot:spring-boot-starter", + "org.springframework.boot:spring-boot-starter-actuator", + "org.springframework.boot:spring-boot-starter-actuator-test", + "org.springframework.boot:spring-boot-starter-data-cassandra", + "org.springframework.boot:spring-boot-starter-data-cassandra-test", + "org.springframework.boot:spring-boot-starter-jackson", + "org.springframework.boot:spring-boot-starter-security-oauth2-client", + "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server", + "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server-test", + "org.springframework.boot:spring-boot-starter-test", + "org.springframework.boot:spring-boot-starter-validation", + "org.springframework.boot:spring-boot-starter-webflux", + "org.springframework.boot:spring-boot-starter-webflux-test", + "org.springframework.boot:spring-boot-starter-webmvc-test", + "org.springframework.boot:spring-boot-webclient", + "org.springframework.cloud:spring-cloud-commons", + "org.springframework.cloud:spring-cloud-context", + "org.springframework.cloud:spring-cloud-starter-bootstrap", + "org.springframework.security:spring-security-test", + "org.testcontainers:testcontainers-cassandra", + "org.testcontainers:testcontainers-junit-jupiter", + "org.wiremock:wiremock-standalone:3.13.2", + "software.amazon.awssdk:regions:2.40.1", + "tools.jackson.module:jackson-module-blackbird", + # Test tooling the nv-boot starters compile and run against directly + # (JUnit 5 console launcher, AssertJ, Awaitility, Mockito). Versions are + # managed by the Spring Boot BOM. + "org.assertj:assertj-core", + "org.awaitility:awaitility", + "org.junit.jupiter:junit-jupiter-api", + "org.junit.jupiter:junit-jupiter-engine", + "org.junit.jupiter:junit-jupiter-params", + "org.junit.platform:junit-platform-launcher", + "org.junit.platform:junit-platform-reporting", + "org.mockito:mockito-core", + "org.mockito:mockito-junit-jupiter", + ], + boms = [ + # Keep identical to SPRING_BOOT_BOM in @nvcf_java_rules//:platform.bzl. + # //:bom_alignment_test fails the build if these drift. + "org.springframework.boot:spring-boot-dependencies:4.0.7", + "org.springframework.cloud:spring-cloud-dependencies:2025.1.2", + "org.testcontainers:testcontainers-bom:2.0.5", + "net.javacrumbs.shedlock:shedlock-bom:7.7.0", + ], + fail_on_missing_checksum = True, + fetch_sources = True, + # contrib_rules_jvm (via nvcf_java_rules) contributes protobuf-java into this + # hub; acknowledged so resolution is shared cleanly rather than warned. + known_contributing_modules = ["protobuf"], + lock_file = "//:maven_install.json", + repositories = [ + # Public Central mirrors only; keep aligned with MAVEN_REPOSITORIES in + # @nvcf_java_rules//:platform.bzl. Internal builds add the Artifactory + # virtual repo in their own overlay. + "https://maven-central.storage-download.googleapis.com/maven2", + "https://repo.maven.apache.org/maven2", + ], + resolver = "maven", +) +use_repo(maven, "maven") diff --git a/src/libraries/java/nv-boot-parent/MODULE.bazel.lock b/src/libraries/java/nv-boot-parent/MODULE.bazel.lock new file mode 100644 index 000000000..1d8059294 --- /dev/null +++ b/src/libraries/java/nv-boot-parent/MODULE.bazel.lock @@ -0,0 +1,1221 @@ +{ + "lockFileVersion": 28, + "registryFileHashes": { + "https://bcr.bazel.build/bazel_registry.json": "8a28e4aff06ee60aed2a8c281907fb8bcbf3b753c91fb5a5c57da3215d5b3497", + "https://bcr.bazel.build/modules/abseil-cpp/20210324.2/MODULE.bazel": "7cd0312e064fde87c8d1cd79ba06c876bd23630c83466e9500321be55c96ace2", + "https://bcr.bazel.build/modules/abseil-cpp/20211102.0/MODULE.bazel": "70390338f7a5106231d20620712f7cccb659cd0e9d073d1991c038eb9fc57589", + "https://bcr.bazel.build/modules/abseil-cpp/20230125.1/MODULE.bazel": "89047429cb0207707b2dface14ba7f8df85273d484c2572755be4bab7ce9c3a0", + "https://bcr.bazel.build/modules/abseil-cpp/20230802.0.bcr.1/MODULE.bazel": "1c8cec495288dccd14fdae6e3f95f772c1c91857047a098fad772034264cc8cb", + "https://bcr.bazel.build/modules/abseil-cpp/20230802.0/MODULE.bazel": "d253ae36a8bd9ee3c5955384096ccb6baf16a1b1e93e858370da0a3b94f77c16", + "https://bcr.bazel.build/modules/abseil-cpp/20230802.1/MODULE.bazel": "fa92e2eb41a04df73cdabeec37107316f7e5272650f81d6cc096418fe647b915", + "https://bcr.bazel.build/modules/abseil-cpp/20240116.1/MODULE.bazel": "37bcdb4440fbb61df6a1c296ae01b327f19e9bb521f9b8e26ec854b6f97309ed", + "https://bcr.bazel.build/modules/abseil-cpp/20240116.2/MODULE.bazel": "73939767a4686cd9a520d16af5ab440071ed75cec1a876bf2fcfaf1f71987a16", + "https://bcr.bazel.build/modules/abseil-cpp/20250127.0/MODULE.bazel": "d1086e248cda6576862b4b3fe9ad76a214e08c189af5b42557a6e1888812c5d5", + "https://bcr.bazel.build/modules/abseil-cpp/20250127.1/MODULE.bazel": "c4a89e7ceb9bf1e25cf84a9f830ff6b817b72874088bf5141b314726e46a57c1", + "https://bcr.bazel.build/modules/abseil-cpp/20250512.1/MODULE.bazel": "d209fdb6f36ffaf61c509fcc81b19e81b411a999a934a032e10cd009a0226215", + "https://bcr.bazel.build/modules/abseil-cpp/20250814.1/MODULE.bazel": "51f2312901470cdab0dbdf3b88c40cd21c62a7ed58a3de45b365ddc5b11bcab2", + "https://bcr.bazel.build/modules/abseil-cpp/20250814.1/source.json": "cea3901d7e299da7320700abbaafe57a65d039f10d0d7ea601c4a66938ea4b0c", + "https://bcr.bazel.build/modules/abseil-py/2.1.0/MODULE.bazel": "5ebe5bf853769c65707e5c28f216798f7a4b1042015e6a36e6d03094d94bec8a", + "https://bcr.bazel.build/modules/abseil-py/2.1.0/source.json": "0e8fc4f088ce07099c1cd6594c20c7ddbb48b4b3c0849b7d94ba94be88ff042b", + "https://bcr.bazel.build/modules/apple_rules_lint/0.4.0/MODULE.bazel": "c59831c3a5389430516203777816527f257329a5da363994e1d62b9ae6729f71", + "https://bcr.bazel.build/modules/apple_rules_lint/0.4.0/source.json": "105883202602181f43f109372e1b9ea19e89bbe3bce4bc1fe9bb0baa51eb61ae", + "https://bcr.bazel.build/modules/apple_support/1.11.1/MODULE.bazel": "1843d7cd8a58369a444fc6000e7304425fba600ff641592161d9f15b179fb896", + "https://bcr.bazel.build/modules/apple_support/1.15.1/MODULE.bazel": "a0556fefca0b1bb2de8567b8827518f94db6a6e7e7d632b4c48dc5f865bc7c85", + "https://bcr.bazel.build/modules/apple_support/1.21.0/MODULE.bazel": "ac1824ed5edf17dee2fdd4927ada30c9f8c3b520be1b5fd02a5da15bc10bff3e", + "https://bcr.bazel.build/modules/apple_support/1.21.1/MODULE.bazel": "5809fa3efab15d1f3c3c635af6974044bac8a4919c62238cce06acee8a8c11f1", + "https://bcr.bazel.build/modules/apple_support/1.24.2/MODULE.bazel": "0e62471818affb9f0b26f128831d5c40b074d32e6dda5a0d3852847215a41ca4", + "https://bcr.bazel.build/modules/apple_support/1.24.2/source.json": "2c22c9827093250406c5568da6c54e6fdf0ef06238def3d99c71b12feb057a8d", + "https://bcr.bazel.build/modules/aspect_bazel_lib/2.14.0/MODULE.bazel": "2b31ffcc9bdc8295b2167e07a757dbbc9ac8906e7028e5170a3708cecaac119f", + "https://bcr.bazel.build/modules/aspect_bazel_lib/2.19.3/MODULE.bazel": "253d739ba126f62a5767d832765b12b59e9f8d2bc88cc1572f4a73e46eb298ca", + "https://bcr.bazel.build/modules/aspect_bazel_lib/2.19.3/source.json": "ffab9254c65ba945f8369297ad97ca0dec213d3adc6e07877e23a48624a8b456", + "https://bcr.bazel.build/modules/aspect_bazel_lib/2.7.2/MODULE.bazel": "780d1a6522b28f5edb7ea09630748720721dfe27690d65a2d33aa7509de77e07", + "https://bcr.bazel.build/modules/aspect_bazel_lib/2.8.1/MODULE.bazel": "812d2dd42f65dca362152101fbec418029cc8fd34cbad1a2fde905383d705838", + "https://bcr.bazel.build/modules/bazel_features/1.1.0/MODULE.bazel": "cfd42ff3b815a5f39554d97182657f8c4b9719568eb7fded2b9135f084bf760b", + "https://bcr.bazel.build/modules/bazel_features/1.1.1/MODULE.bazel": "27b8c79ef57efe08efccbd9dd6ef70d61b4798320b8d3c134fd571f78963dbcd", + "https://bcr.bazel.build/modules/bazel_features/1.10.0/MODULE.bazel": "f75e8807570484a99be90abcd52b5e1f390362c258bcb73106f4544957a48101", + "https://bcr.bazel.build/modules/bazel_features/1.11.0/MODULE.bazel": "f9382337dd5a474c3b7d334c2f83e50b6eaedc284253334cf823044a26de03e8", + "https://bcr.bazel.build/modules/bazel_features/1.13.0/MODULE.bazel": "c14c33c7c3c730612bdbe14ebbb5e61936b6f11322ea95a6e91cd1ba962f94df", + "https://bcr.bazel.build/modules/bazel_features/1.15.0/MODULE.bazel": "d38ff6e517149dc509406aca0db3ad1efdd890a85e049585b7234d04238e2a4d", + "https://bcr.bazel.build/modules/bazel_features/1.17.0/MODULE.bazel": "039de32d21b816b47bd42c778e0454217e9c9caac4a3cf8e15c7231ee3ddee4d", + "https://bcr.bazel.build/modules/bazel_features/1.18.0/MODULE.bazel": "1be0ae2557ab3a72a57aeb31b29be347bcdc5d2b1eb1e70f39e3851a7e97041a", + "https://bcr.bazel.build/modules/bazel_features/1.19.0/MODULE.bazel": "59adcdf28230d220f0067b1f435b8537dd033bfff8db21335ef9217919c7fb58", + "https://bcr.bazel.build/modules/bazel_features/1.21.0/MODULE.bazel": "675642261665d8eea09989aa3b8afb5c37627f1be178382c320d1b46afba5e3b", + "https://bcr.bazel.build/modules/bazel_features/1.23.0/MODULE.bazel": "fd1ac84bc4e97a5a0816b7fd7d4d4f6d837b0047cf4cbd81652d616af3a6591a", + "https://bcr.bazel.build/modules/bazel_features/1.25.0/MODULE.bazel": "e2e60a10a6da64bbf533f15ca652bf61a033e41c2ed734d79a9a08ba87f68c1a", + "https://bcr.bazel.build/modules/bazel_features/1.27.0/MODULE.bazel": "621eeee06c4458a9121d1f104efb80f39d34deff4984e778359c60eaf1a8cb65", + "https://bcr.bazel.build/modules/bazel_features/1.28.0/MODULE.bazel": "4b4200e6cbf8fa335b2c3f43e1d6ef3e240319c33d43d60cc0fbd4b87ece299d", + "https://bcr.bazel.build/modules/bazel_features/1.3.0/MODULE.bazel": "cdcafe83ec318cda34e02948e81d790aab8df7a929cec6f6969f13a489ccecd9", + "https://bcr.bazel.build/modules/bazel_features/1.30.0/MODULE.bazel": "a14b62d05969a293b80257e72e597c2da7f717e1e69fa8b339703ed6731bec87", + "https://bcr.bazel.build/modules/bazel_features/1.33.0/MODULE.bazel": "8b8dc9d2a4c88609409c3191165bccec0e4cb044cd7a72ccbe826583303459f6", + "https://bcr.bazel.build/modules/bazel_features/1.4.1/MODULE.bazel": "e45b6bb2350aff3e442ae1111c555e27eac1d915e77775f6fdc4b351b758b5d7", + "https://bcr.bazel.build/modules/bazel_features/1.42.1/MODULE.bazel": "275a59b5406ff18c01739860aa70ad7ccb3cfb474579411decca11c93b951080", + "https://bcr.bazel.build/modules/bazel_features/1.42.1/source.json": "fcd4396b2df85f64f2b3bb436ad870793ecf39180f1d796f913cc9276d355309", + "https://bcr.bazel.build/modules/bazel_features/1.9.0/MODULE.bazel": "885151d58d90d8d9c811eb75e3288c11f850e1d6b481a8c9f766adee4712358b", + "https://bcr.bazel.build/modules/bazel_features/1.9.1/MODULE.bazel": "8f679097876a9b609ad1f60249c49d68bfab783dd9be012faf9d82547b14815a", + "https://bcr.bazel.build/modules/bazel_lib/3.0.0/MODULE.bazel": "22b70b80ac89ad3f3772526cd9feee2fa412c2b01933fea7ed13238a448d370d", + "https://bcr.bazel.build/modules/bazel_lib/3.0.0/source.json": "895f21909c6fba01d7c17914bb6c8e135982275a1b18cdaa4e62272217ef1751", + "https://bcr.bazel.build/modules/bazel_skylib/1.0.3/MODULE.bazel": "bcb0fd896384802d1ad283b4e4eb4d718eebd8cb820b0a2c3a347fb971afd9d8", + "https://bcr.bazel.build/modules/bazel_skylib/1.1.1/MODULE.bazel": "1add3e7d93ff2e6998f9e118022c84d163917d912f5afafb3058e3d2f1545b5e", + "https://bcr.bazel.build/modules/bazel_skylib/1.2.0/MODULE.bazel": "44fe84260e454ed94ad326352a698422dbe372b21a1ac9f3eab76eb531223686", + "https://bcr.bazel.build/modules/bazel_skylib/1.2.1/MODULE.bazel": "f35baf9da0efe45fa3da1696ae906eea3d615ad41e2e3def4aeb4e8bc0ef9a7a", + "https://bcr.bazel.build/modules/bazel_skylib/1.3.0/MODULE.bazel": "20228b92868bf5cfc41bda7afc8a8ba2a543201851de39d990ec957b513579c5", + "https://bcr.bazel.build/modules/bazel_skylib/1.4.1/MODULE.bazel": "a0dcb779424be33100dcae821e9e27e4f2901d9dfd5333efe5ac6a8d7ab75e1d", + "https://bcr.bazel.build/modules/bazel_skylib/1.4.2/MODULE.bazel": "3bd40978e7a1fac911d5989e6b09d8f64921865a45822d8b09e815eaa726a651", + "https://bcr.bazel.build/modules/bazel_skylib/1.5.0/MODULE.bazel": "32880f5e2945ce6a03d1fbd588e9198c0a959bb42297b2cfaf1685b7bc32e138", + "https://bcr.bazel.build/modules/bazel_skylib/1.6.1/MODULE.bazel": "8fdee2dbaace6c252131c00e1de4b165dc65af02ea278476187765e1a617b917", + "https://bcr.bazel.build/modules/bazel_skylib/1.7.0/MODULE.bazel": "0db596f4563de7938de764cc8deeabec291f55e8ec15299718b93c4423e9796d", + "https://bcr.bazel.build/modules/bazel_skylib/1.7.1/MODULE.bazel": "3120d80c5861aa616222ec015332e5f8d3171e062e3e804a2a0253e1be26e59b", + "https://bcr.bazel.build/modules/bazel_skylib/1.8.1/MODULE.bazel": "88ade7293becda963e0e3ea33e7d54d3425127e0a326e0d17da085a5f1f03ff6", + "https://bcr.bazel.build/modules/bazel_skylib/1.8.2/MODULE.bazel": "69ad6927098316848b34a9142bcc975e018ba27f08c4ff403f50c1b6e646ca67", + "https://bcr.bazel.build/modules/bazel_skylib/1.8.2/source.json": "34a3c8bcf233b835eb74be9d628899bb32999d3e0eadef1947a0a562a2b16ffb", + "https://bcr.bazel.build/modules/bazel_worker_api/0.0.1/MODULE.bazel": "02a13b77321773b2042e70ee5e4c5e099c8ddee4cf2da9cd420442c36938d4bd", + "https://bcr.bazel.build/modules/bazel_worker_api/0.0.4/MODULE.bazel": "460aa12d01231a80cce03c548287b433b321d205b0028ae596728c35e5ee442e", + "https://bcr.bazel.build/modules/bazel_worker_api/0.0.8/MODULE.bazel": "396c1ef53835aafe3d42ce6619080531ee770648303731f16cfaa33fa056bf0c", + "https://bcr.bazel.build/modules/bazel_worker_api/0.0.8/source.json": "abaf8ac9d2ab2f47bda9af4c0c080ff7907378888e1f4bc62a0539dd13ba61e8", + "https://bcr.bazel.build/modules/bazel_worker_java/0.0.4/MODULE.bazel": "82494a01018bb7ef06d4a17ec4cd7a758721f10eb8b6c820a818e70d669500db", + "https://bcr.bazel.build/modules/bazel_worker_java/0.0.8/MODULE.bazel": "e76479eae70bd4e8f5f4c2dfc5d03ab971cfb18750246c7b3f3454c5c2ee6629", + "https://bcr.bazel.build/modules/bazel_worker_java/0.0.8/source.json": "9395c4679444bc47bf7e51a710366a4480aa371c6f6bed01868e2fabcf11acec", + "https://bcr.bazel.build/modules/buildozer/8.5.1/MODULE.bazel": "a35d9561b3fc5b18797c330793e99e3b834a473d5fbd3d7d7634aafc9bdb6f8f", + "https://bcr.bazel.build/modules/buildozer/8.5.1/source.json": "e3386e6ff4529f2442800dee47ad28d3e6487f36a1f75ae39ae56c70f0cd2fbd", + "https://bcr.bazel.build/modules/contrib_rules_jvm/0.33.0/MODULE.bazel": "1aba514585748372ee392484b2645f0bbcb13ad4271d5b7cace018280f15bae1", + "https://bcr.bazel.build/modules/contrib_rules_jvm/0.33.0/source.json": "e52d62ce2a2b8a513d6afe9178acc06a4349c9b0b4c0934d59085ed9df4b4de0", + "https://bcr.bazel.build/modules/gazelle/0.32.0/MODULE.bazel": "b499f58a5d0d3537f3cf5b76d8ada18242f64ec474d8391247438bf04f58c7b8", + "https://bcr.bazel.build/modules/gazelle/0.33.0/MODULE.bazel": "a13a0f279b462b784fb8dd52a4074526c4a2afe70e114c7d09066097a46b3350", + "https://bcr.bazel.build/modules/gazelle/0.34.0/MODULE.bazel": "abdd8ce4d70978933209db92e436deb3a8b737859e9354fb5fd11fb5c2004c8a", + "https://bcr.bazel.build/modules/gazelle/0.36.0/MODULE.bazel": "e375d5d6e9a6ca59b0cb38b0540bc9a05b6aa926d322f2de268ad267a2ee74c0", + "https://bcr.bazel.build/modules/gazelle/0.40.0/MODULE.bazel": "42ba5378ebe845fca43989a53186ab436d956db498acde790685fe0e8f9c6146", + "https://bcr.bazel.build/modules/gazelle/0.42.0/MODULE.bazel": "fa140a7c019f3a22779ba7c6132ffff9d2d10a51dba2f3304dee61523d11fef4", + "https://bcr.bazel.build/modules/gazelle/0.47.0/MODULE.bazel": "b61bb007c4efad134aa30ee7f4a8e2a39b22aa5685f005edaa022fbd1de43ebc", + "https://bcr.bazel.build/modules/gazelle/0.47.0/source.json": "aeb2e5df14b7fb298625d75d08b9c65bdb0b56014c5eb89da9e5dd0572280ae6", + "https://bcr.bazel.build/modules/google_benchmark/1.8.2/MODULE.bazel": "a70cf1bba851000ba93b58ae2f6d76490a9feb74192e57ab8e8ff13c34ec50cb", + "https://bcr.bazel.build/modules/googletest/1.11.0/MODULE.bazel": "3a83f095183f66345ca86aa13c58b59f9f94a2f81999c093d4eeaa2d262d12f4", + "https://bcr.bazel.build/modules/googletest/1.14.0.bcr.1/MODULE.bazel": "22c31a561553727960057361aa33bf20fb2e98584bc4fec007906e27053f80c6", + "https://bcr.bazel.build/modules/googletest/1.14.0/MODULE.bazel": "cfbcbf3e6eac06ef9d85900f64424708cc08687d1b527f0ef65aa7517af8118f", + "https://bcr.bazel.build/modules/googletest/1.15.2/MODULE.bazel": "6de1edc1d26cafb0ea1a6ab3f4d4192d91a312fd2d360b63adaa213cd00b2108", + "https://bcr.bazel.build/modules/googletest/1.17.0/MODULE.bazel": "dbec758171594a705933a29fcf69293d2468c49ec1f2ebca65c36f504d72df46", + "https://bcr.bazel.build/modules/googletest/1.17.0/source.json": "38e4454b25fc30f15439c0378e57909ab1fd0a443158aa35aec685da727cd713", + "https://bcr.bazel.build/modules/jq.bzl/0.1.0/MODULE.bazel": "2ce69b1af49952cd4121a9c3055faa679e748ce774c7f1fda9657f936cae902f", + "https://bcr.bazel.build/modules/jq.bzl/0.1.0/source.json": "746bf13cac0860f091df5e4911d0c593971cd8796b5ad4e809b2f8e133eee3d5", + "https://bcr.bazel.build/modules/jsoncpp/1.9.5/MODULE.bazel": "31271aedc59e815656f5736f282bb7509a97c7ecb43e927ac1a37966e0578075", + "https://bcr.bazel.build/modules/jsoncpp/1.9.6/MODULE.bazel": "2f8d20d3b7d54143213c4dfc3d98225c42de7d666011528dc8fe91591e2e17b0", + "https://bcr.bazel.build/modules/jsoncpp/1.9.6/source.json": "a04756d367a2126c3541682864ecec52f92cdee80a35735a3cb249ce015ca000", + "https://bcr.bazel.build/modules/libpfm/4.11.0/MODULE.bazel": "45061ff025b301940f1e30d2c16bea596c25b176c8b6b3087e92615adbd52902", + "https://bcr.bazel.build/modules/nlohmann_json/3.6.1/MODULE.bazel": "6f7b417dcc794d9add9e556673ad25cb3ba835224290f4f848f8e2db1e1fca74", + "https://bcr.bazel.build/modules/nlohmann_json/3.6.1/source.json": "f448c6e8963fdfa7eb831457df83ad63d3d6355018f6574fb017e8169deb43a9", + "https://bcr.bazel.build/modules/package_metadata/0.0.2/MODULE.bazel": "fb8d25550742674d63d7b250063d4580ca530499f045d70748b1b142081ebb92", + "https://bcr.bazel.build/modules/package_metadata/0.0.3/MODULE.bazel": "77890552ecea9e284b5424c9de827a58099348763a4359e975c359a83d4faa83", + "https://bcr.bazel.build/modules/package_metadata/0.0.5/MODULE.bazel": "ef4f9439e3270fdd6b9fd4dbc3d2f29d13888e44c529a1b243f7a31dfbc2e8e4", + "https://bcr.bazel.build/modules/package_metadata/0.0.7/MODULE.bazel": "7adb03933fc8401f495800cf4eafcff0edc6da0ff55c7db223ef69d19f689486", + "https://bcr.bazel.build/modules/package_metadata/0.0.7/source.json": "50639625e937b56115012674c797cca7a05a96b4878c87d803c13dc2b31de8a0", + "https://bcr.bazel.build/modules/platforms/0.0.10/MODULE.bazel": "8cb8efaf200bdeb2150d93e162c40f388529a25852b332cec879373771e48ed5", + "https://bcr.bazel.build/modules/platforms/0.0.11/MODULE.bazel": "0daefc49732e227caa8bfa834d65dc52e8cc18a2faf80df25e8caea151a9413f", + "https://bcr.bazel.build/modules/platforms/0.0.4/MODULE.bazel": "9b328e31ee156f53f3c416a64f8491f7eb731742655a47c9eec4703a71644aee", + "https://bcr.bazel.build/modules/platforms/0.0.5/MODULE.bazel": "5733b54ea419d5eaf7997054bb55f6a1d0b5ff8aedf0176fef9eea44f3acda37", + "https://bcr.bazel.build/modules/platforms/0.0.6/MODULE.bazel": "ad6eeef431dc52aefd2d77ed20a4b353f8ebf0f4ecdd26a807d2da5aa8cd0615", + "https://bcr.bazel.build/modules/platforms/0.0.7/MODULE.bazel": "72fd4a0ede9ee5c021f6a8dd92b503e089f46c227ba2813ff183b71616034814", + "https://bcr.bazel.build/modules/platforms/0.0.8/MODULE.bazel": "9f142c03e348f6d263719f5074b21ef3adf0b139ee4c5133e2aa35664da9eb2d", + "https://bcr.bazel.build/modules/platforms/0.0.9/MODULE.bazel": "4a87a60c927b56ddd67db50c89acaa62f4ce2a1d2149ccb63ffd871d5ce29ebc", + "https://bcr.bazel.build/modules/platforms/1.0.0/MODULE.bazel": "f05feb42b48f1b3c225e4ccf351f367be0371411a803198ec34a389fb22aa580", + "https://bcr.bazel.build/modules/platforms/1.0.0/source.json": "f4ff1fd412e0246fd38c82328eb209130ead81d62dcd5a9e40910f867f733d96", + "https://bcr.bazel.build/modules/protobuf/21.7/MODULE.bazel": "a5a29bb89544f9b97edce05642fac225a808b5b7be74038ea3640fae2f8e66a7", + "https://bcr.bazel.build/modules/protobuf/23.1/MODULE.bazel": "88b393b3eb4101d18129e5db51847cd40a5517a53e81216144a8c32dfeeca52a", + "https://bcr.bazel.build/modules/protobuf/24.4/MODULE.bazel": "7bc7ce5f2abf36b3b7b7c8218d3acdebb9426aeb35c2257c96445756f970eb12", + "https://bcr.bazel.build/modules/protobuf/27.0/MODULE.bazel": "7873b60be88844a0a1d8f80b9d5d20cfbd8495a689b8763e76c6372998d3f64c", + "https://bcr.bazel.build/modules/protobuf/27.1/MODULE.bazel": "703a7b614728bb06647f965264967a8ef1c39e09e8f167b3ca0bb1fd80449c0d", + "https://bcr.bazel.build/modules/protobuf/27.2/MODULE.bazel": "32450b50673882e4c8c3d10a83f3bc82161b213ed2f80d17e38bece8f165c295", + "https://bcr.bazel.build/modules/protobuf/29.0-rc2.bcr.1/MODULE.bazel": "52f4126f63a2f0bbf36b99c2a87648f08467a4eaf92ba726bc7d6a500bbf770c", + "https://bcr.bazel.build/modules/protobuf/29.0-rc2/MODULE.bazel": "6241d35983510143049943fc0d57937937122baf1b287862f9dc8590fc4c37df", + "https://bcr.bazel.build/modules/protobuf/29.0-rc3/MODULE.bazel": "33c2dfa286578573afc55a7acaea3cada4122b9631007c594bf0729f41c8de92", + "https://bcr.bazel.build/modules/protobuf/29.0/MODULE.bazel": "319dc8bf4c679ff87e71b1ccfb5a6e90a6dbc4693501d471f48662ac46d04e4e", + "https://bcr.bazel.build/modules/protobuf/29.1/MODULE.bazel": "557c3457560ff49e122ed76c0bc3397a64af9574691cb8201b4e46d4ab2ecb95", + "https://bcr.bazel.build/modules/protobuf/29.3/MODULE.bazel": "77480eea5fb5541903e49683f24dc3e09f4a79e0eea247414887bb9fc0066e94", + "https://bcr.bazel.build/modules/protobuf/3.19.0/MODULE.bazel": "6b5fbb433f760a99a22b18b6850ed5784ef0e9928a72668b66e4d7ccd47db9b0", + "https://bcr.bazel.build/modules/protobuf/3.19.2/MODULE.bazel": "532ffe5f2186b69fdde039efe6df13ba726ff338c6bc82275ad433013fa10573", + "https://bcr.bazel.build/modules/protobuf/3.19.6/MODULE.bazel": "9233edc5e1f2ee276a60de3eaa47ac4132302ef9643238f23128fea53ea12858", + "https://bcr.bazel.build/modules/protobuf/31.1/MODULE.bazel": "379a389bb330b7b8c1cdf331cc90bf3e13de5614799b3b52cdb7c6f389f6b38e", + "https://bcr.bazel.build/modules/protobuf/32.1/MODULE.bazel": "89cd2866a9cb07fee9ff74c41ceace11554f32e0d849de4e23ac55515cfada4d", + "https://bcr.bazel.build/modules/protobuf/33.4/MODULE.bazel": "114775b816b38b6d0ca620450d6b02550c60ceedfdc8d9a229833b34a223dc42", + "https://bcr.bazel.build/modules/protobuf/33.4/source.json": "555f8686b4c7d6b5ba731fbea13bf656b4bfd9a7ff629c1d9d3f6e1d6155de79", + "https://bcr.bazel.build/modules/pybind11_bazel/2.11.1/MODULE.bazel": "88af1c246226d87e65be78ed49ecd1e6f5e98648558c14ce99176da041dc378e", + "https://bcr.bazel.build/modules/pybind11_bazel/2.12.0/MODULE.bazel": "e6f4c20442eaa7c90d7190d8dc539d0ab422f95c65a57cc59562170c58ae3d34", + "https://bcr.bazel.build/modules/pybind11_bazel/2.12.0/source.json": "6900fdc8a9e95866b8c0d4ad4aba4d4236317b5c1cd04c502df3f0d33afed680", + "https://bcr.bazel.build/modules/re2/2023-09-01/MODULE.bazel": "cb3d511531b16cfc78a225a9e2136007a48cf8a677e4264baeab57fe78a80206", + "https://bcr.bazel.build/modules/re2/2024-07-02.bcr.1/MODULE.bazel": "b4963dda9b31080be1905ef085ecd7dd6cd47c05c79b9cdf83ade83ab2ab271a", + "https://bcr.bazel.build/modules/re2/2024-07-02.bcr.1/source.json": "2ff292be6ef3340325ce8a045ecc326e92cbfab47c7cbab4bd85d28971b97ac4", + "https://bcr.bazel.build/modules/re2/2024-07-02/MODULE.bazel": "0eadc4395959969297cbcf31a249ff457f2f1d456228c67719480205aa306daa", + "https://bcr.bazel.build/modules/rules_android/0.1.1/MODULE.bazel": "48809ab0091b07ad0182defb787c4c5328bd3a278938415c00a7b69b50c4d3a8", + "https://bcr.bazel.build/modules/rules_android/0.6.4/MODULE.bazel": "b4cde12d506dd65d82b2be39761f49f5797303343a3d5b4ee191c0cdf9ef387c", + "https://bcr.bazel.build/modules/rules_android/0.6.6/MODULE.bazel": "b0fb569752aab65ab1a9db0a8f6cfaf5aa1754965e17e95dcf0e4d88e192a68d", + "https://bcr.bazel.build/modules/rules_android/0.7.1/MODULE.bazel": "a806fc382a774252f228a40e3b11b9fcc6276f8778c7fb33e9f72937c6258363", + "https://bcr.bazel.build/modules/rules_android/0.7.1/source.json": "151440aed3f0f73a00d4ed5cec5d31f63a6fef9b95d8fab1eb1810150fa525f2", + "https://bcr.bazel.build/modules/rules_apple/3.16.0/MODULE.bazel": "0d1caf0b8375942ce98ea944be754a18874041e4e0459401d925577624d3a54a", + "https://bcr.bazel.build/modules/rules_apple/4.1.0/MODULE.bazel": "76e10fd4a48038d3fc7c5dc6e63b7063bbf5304a2e3bd42edda6ec660eebea68", + "https://bcr.bazel.build/modules/rules_apple/4.1.0/source.json": "8ee81e1708756f81b343a5eb2b2f0b953f1d25c4ab3d4a68dc02754872e80715", + "https://bcr.bazel.build/modules/rules_cc/0.0.1/MODULE.bazel": "cb2aa0747f84c6c3a78dad4e2049c154f08ab9d166b1273835a8174940365647", + "https://bcr.bazel.build/modules/rules_cc/0.0.10/MODULE.bazel": "ec1705118f7eaedd6e118508d3d26deba2a4e76476ada7e0e3965211be012002", + "https://bcr.bazel.build/modules/rules_cc/0.0.13/MODULE.bazel": "0e8529ed7b323dad0775ff924d2ae5af7640b23553dfcd4d34344c7e7a867191", + "https://bcr.bazel.build/modules/rules_cc/0.0.15/MODULE.bazel": "6704c35f7b4a72502ee81f61bf88706b54f06b3cbe5558ac17e2e14666cd5dcc", + "https://bcr.bazel.build/modules/rules_cc/0.0.16/MODULE.bazel": "7661303b8fc1b4d7f532e54e9d6565771fea666fbdf839e0a86affcd02defe87", + "https://bcr.bazel.build/modules/rules_cc/0.0.17/MODULE.bazel": "2ae1d8f4238ec67d7185d8861cb0a2cdf4bc608697c331b95bf990e69b62e64a", + "https://bcr.bazel.build/modules/rules_cc/0.0.2/MODULE.bazel": "6915987c90970493ab97393024c156ea8fb9f3bea953b2f3ec05c34f19b5695c", + "https://bcr.bazel.build/modules/rules_cc/0.0.6/MODULE.bazel": "abf360251023dfe3efcef65ab9d56beefa8394d4176dd29529750e1c57eaa33f", + "https://bcr.bazel.build/modules/rules_cc/0.0.8/MODULE.bazel": "964c85c82cfeb6f3855e6a07054fdb159aced38e99a5eecf7bce9d53990afa3e", + "https://bcr.bazel.build/modules/rules_cc/0.0.9/MODULE.bazel": "836e76439f354b89afe6a911a7adf59a6b2518fafb174483ad78a2a2fde7b1c5", + "https://bcr.bazel.build/modules/rules_cc/0.1.1/MODULE.bazel": "2f0222a6f229f0bf44cd711dc13c858dad98c62d52bd51d8fc3a764a83125513", + "https://bcr.bazel.build/modules/rules_cc/0.1.2/MODULE.bazel": "557ddc3a96858ec0d465a87c0a931054d7dcfd6583af2c7ed3baf494407fd8d0", + "https://bcr.bazel.build/modules/rules_cc/0.1.5/MODULE.bazel": "88dfc9361e8b5ae1008ac38f7cdfd45ad738e4fa676a3ad67d19204f045a1fd8", + "https://bcr.bazel.build/modules/rules_cc/0.2.0/MODULE.bazel": "b5c17f90458caae90d2ccd114c81970062946f49f355610ed89bebf954f5783c", + "https://bcr.bazel.build/modules/rules_cc/0.2.13/MODULE.bazel": "eecdd666eda6be16a8d9dc15e44b5c75133405e820f620a234acc4b1fdc5aa37", + "https://bcr.bazel.build/modules/rules_cc/0.2.14/MODULE.bazel": "353c99ed148887ee89c54a17d4100ae7e7e436593d104b668476019023b58df8", + "https://bcr.bazel.build/modules/rules_cc/0.2.17/MODULE.bazel": "1849602c86cb60da8613d2de887f9566a6d354a6df6d7009f9d04a14402f9a84", + "https://bcr.bazel.build/modules/rules_cc/0.2.17/source.json": "3832f45d145354049137c0090df04629d9c2b5493dc5c2bf46f1834040133a07", + "https://bcr.bazel.build/modules/rules_cc/0.2.8/MODULE.bazel": "f1df20f0bf22c28192a794f29b501ee2018fa37a3862a1a2132ae2940a23a642", + "https://bcr.bazel.build/modules/rules_foreign_cc/0.9.0/MODULE.bazel": "c9e8c682bf75b0e7c704166d79b599f93b72cfca5ad7477df596947891feeef6", + "https://bcr.bazel.build/modules/rules_fuzzing/0.5.2/MODULE.bazel": "40c97d1144356f52905566c55811f13b299453a14ac7769dfba2ac38192337a8", + "https://bcr.bazel.build/modules/rules_go/0.41.0/MODULE.bazel": "55861d8e8bb0e62cbd2896f60ff303f62ffcb0eddb74ecb0e5c0cbe36fc292c8", + "https://bcr.bazel.build/modules/rules_go/0.42.0/MODULE.bazel": "8cfa875b9aa8c6fce2b2e5925e73c1388173ea3c32a0db4d2b4804b453c14270", + "https://bcr.bazel.build/modules/rules_go/0.46.0/MODULE.bazel": "3477df8bdcc49e698b9d25f734c4f3a9f5931ff34ee48a2c662be168f5f2d3fd", + "https://bcr.bazel.build/modules/rules_go/0.50.1/MODULE.bazel": "b91a308dc5782bb0a8021ad4330c81fea5bda77f96b9e4c117b9b9c8f6665ee0", + "https://bcr.bazel.build/modules/rules_go/0.51.0-rc2/MODULE.bazel": "edfc3a9cea7bedb0eaaff37b0d7817c1a4bf72b3c615580b0ffcee6c52690fd4", + "https://bcr.bazel.build/modules/rules_go/0.52.0/MODULE.bazel": "0cf080a2706aa8fc9abf64286cee60fdf0238db37b7f1793b0f7d550d59ea3ae", + "https://bcr.bazel.build/modules/rules_go/0.53.0/MODULE.bazel": "a4ed760d3ac0dbc0d7b967631a9a3fd9100d28f7d9fcf214b4df87d4bfff5f9a", + "https://bcr.bazel.build/modules/rules_go/0.59.0/MODULE.bazel": "b7e43e7414a3139a7547d1b4909b29085fbe5182b6c58cbe1ed4c6272815aeae", + "https://bcr.bazel.build/modules/rules_go/0.59.0/source.json": "1df17bb7865cfc029492c30163cee891d0dd8658ea0d5bfdf252c4b6db5c1ef6", + "https://bcr.bazel.build/modules/rules_java/4.0.0/MODULE.bazel": "5a78a7ae82cd1a33cef56dc578c7d2a46ed0dca12643ee45edbb8417899e6f74", + "https://bcr.bazel.build/modules/rules_java/5.3.5/MODULE.bazel": "a4ec4f2db570171e3e5eb753276ee4b389bae16b96207e9d3230895c99644b86", + "https://bcr.bazel.build/modules/rules_java/6.3.0/MODULE.bazel": "a97c7678c19f236a956ad260d59c86e10a463badb7eb2eda787490f4c969b963", + "https://bcr.bazel.build/modules/rules_java/6.5.2/MODULE.bazel": "1d440d262d0e08453fa0c4d8f699ba81609ed0e9a9a0f02cd10b3e7942e61e31", + "https://bcr.bazel.build/modules/rules_java/7.1.0/MODULE.bazel": "30d9135a2b6561c761bd67bd4990da591e6bdc128790ce3e7afd6a3558b2fb64", + "https://bcr.bazel.build/modules/rules_java/7.10.0/MODULE.bazel": "530c3beb3067e870561739f1144329a21c851ff771cd752a49e06e3dc9c2e71a", + "https://bcr.bazel.build/modules/rules_java/7.12.2/MODULE.bazel": "579c505165ee757a4280ef83cda0150eea193eed3bef50b1004ba88b99da6de6", + "https://bcr.bazel.build/modules/rules_java/7.2.0/MODULE.bazel": "06c0334c9be61e6cef2c8c84a7800cef502063269a5af25ceb100b192453d4ab", + "https://bcr.bazel.build/modules/rules_java/7.4.0/MODULE.bazel": "a592852f8a3dd539e82ee6542013bf2cadfc4c6946be8941e189d224500a8934", + "https://bcr.bazel.build/modules/rules_java/7.6.1/MODULE.bazel": "2f14b7e8a1aa2f67ae92bc69d1ec0fa8d9f827c4e17ff5e5f02e91caa3b2d0fe", + "https://bcr.bazel.build/modules/rules_java/8.13.0/MODULE.bazel": "0444ebf737d144cf2bb2ccb368e7f1cce735264285f2a3711785827c1686625e", + "https://bcr.bazel.build/modules/rules_java/8.15.2/MODULE.bazel": "5cc6698c822b2f9ef90ca5558599851bed8c3b13f1f8eb140d9bfec638d2acb4", + "https://bcr.bazel.build/modules/rules_java/8.3.2/MODULE.bazel": "7336d5511ad5af0b8615fdc7477535a2e4e723a357b6713af439fe8cf0195017", + "https://bcr.bazel.build/modules/rules_java/8.5.1/MODULE.bazel": "d8a9e38cc5228881f7055a6079f6f7821a073df3744d441978e7a43e20226939", + "https://bcr.bazel.build/modules/rules_java/8.6.0/MODULE.bazel": "9c064c434606d75a086f15ade5edb514308cccd1544c2b2a89bbac4310e41c71", + "https://bcr.bazel.build/modules/rules_java/8.6.1/MODULE.bazel": "f4808e2ab5b0197f094cabce9f4b006a27766beb6a9975931da07099560ca9c2", + "https://bcr.bazel.build/modules/rules_java/8.6.3/MODULE.bazel": "e90505b7a931d194245ffcfb6ff4ca8ef9d46b4e830d12e64817752e0198e2ed", + "https://bcr.bazel.build/modules/rules_java/8.9.0/MODULE.bazel": "e17c876cb53dcd817b7b7f0d2985b710610169729e8c371b2221cacdcd3dce4a", + "https://bcr.bazel.build/modules/rules_java/9.1.0/MODULE.bazel": "ee63f27e36a3fada80342869361182f120a9819c74320e8e65b1e04ba0cd7a9d", + "https://bcr.bazel.build/modules/rules_java/9.3.0/MODULE.bazel": "f657c72d65ac449caae9abf2e68e66c0d36f9416848c4c4903d0b3234229e7f2", + "https://bcr.bazel.build/modules/rules_java/9.3.0/source.json": "59ae7e662c3c7042b88bbb42ad12483523e234c65ebe4c51611baa43e85cb248", + "https://bcr.bazel.build/modules/rules_jvm_external/4.4.2/MODULE.bazel": "a56b85e418c83eb1839819f0b515c431010160383306d13ec21959ac412d2fe7", + "https://bcr.bazel.build/modules/rules_jvm_external/5.1/MODULE.bazel": "33f6f999e03183f7d088c9be518a63467dfd0be94a11d0055fe2d210f89aa909", + "https://bcr.bazel.build/modules/rules_jvm_external/5.2/MODULE.bazel": "d9351ba35217ad0de03816ef3ed63f89d411349353077348a45348b096615036", + "https://bcr.bazel.build/modules/rules_jvm_external/6.10/MODULE.bazel": "33e636ca6bc9ee0fa090a38aa33c631ded2d8cf6fead4124181d1b35dc474f7c", + "https://bcr.bazel.build/modules/rules_jvm_external/6.2/MODULE.bazel": "36a6e52487a855f33cb960724eb56547fa87e2c98a0474c3acad94339d7f8e99", + "https://bcr.bazel.build/modules/rules_jvm_external/6.3/MODULE.bazel": "c998e060b85f71e00de5ec552019347c8bca255062c990ac02d051bb80a38df0", + "https://bcr.bazel.build/modules/rules_jvm_external/6.6/MODULE.bazel": "153042249c7060536dc95b6bb9f9bb8063b8a0b0cb7acdb381bddbc2374aed55", + "https://bcr.bazel.build/modules/rules_jvm_external/6.7/MODULE.bazel": "e717beabc4d091ecb2c803c2d341b88590e9116b8bf7947915eeb33aab4f96dd", + "https://bcr.bazel.build/modules/rules_jvm_external/6.9/MODULE.bazel": "07c5db05527db7744a54fcffd653e1550d40e0540207a7f7e6d0a4de5bef8274", + "https://bcr.bazel.build/modules/rules_jvm_external/7.0/MODULE.bazel": "421482bdbcf05709f933c96b867a599deb517f2804ceb3e74511880610cfbf71", + "https://bcr.bazel.build/modules/rules_jvm_external/7.0/source.json": "714cd003eadf5be5c83268311fe8e951db39f802babeaddc536b3560dc8f6faf", + "https://bcr.bazel.build/modules/rules_kotlin/1.9.5/MODULE.bazel": "043a16a572f610558ec2030db3ff0c9938574e7dd9f58bded1bb07c0192ef025", + "https://bcr.bazel.build/modules/rules_kotlin/1.9.6/MODULE.bazel": "d269a01a18ee74d0335450b10f62c9ed81f2321d7958a2934e44272fe82dcef3", + "https://bcr.bazel.build/modules/rules_kotlin/2.1.3/MODULE.bazel": "ce7def6d576aa8d3a9c6d10e13b4d157296229674371f67dbf788dae0afae3d5", + "https://bcr.bazel.build/modules/rules_kotlin/2.2.2/MODULE.bazel": "00d39c5e0fa78cd86193946265bb849e7878c24e44260f9525108428852b315c", + "https://bcr.bazel.build/modules/rules_kotlin/2.2.2/source.json": "7a32c2259c79ae0c9a036121f120de825e3ba5f0f3a209ffbbdccf4dc62489b9", + "https://bcr.bazel.build/modules/rules_license/0.0.3/MODULE.bazel": "627e9ab0247f7d1e05736b59dbb1b6871373de5ad31c3011880b4133cafd4bd0", + "https://bcr.bazel.build/modules/rules_license/0.0.7/MODULE.bazel": "088fbeb0b6a419005b89cf93fe62d9517c0a2b8bb56af3244af65ecfe37e7d5d", + "https://bcr.bazel.build/modules/rules_license/1.0.0/MODULE.bazel": "a7fda60eefdf3d8c827262ba499957e4df06f659330bbe6cdbdb975b768bb65c", + "https://bcr.bazel.build/modules/rules_license/1.0.0/source.json": "a52c89e54cc311196e478f8382df91c15f7a2bfdf4c6cd0e2675cc2ff0b56efb", + "https://bcr.bazel.build/modules/rules_oci/2.2.7/MODULE.bazel": "f6150e4b224d459f7f6523ef65967464ca4efdd266c7fbf2f5a2a51011957e0c", + "https://bcr.bazel.build/modules/rules_oci/2.2.7/source.json": "b099f02af330f47f19dc67fc9300ef6e1937a8c86882690db0e7a2fcea8c7f6b", + "https://bcr.bazel.build/modules/rules_pkg/0.7.0/MODULE.bazel": "df99f03fc7934a4737122518bb87e667e62d780b610910f0447665a7e2be62dc", + "https://bcr.bazel.build/modules/rules_pkg/1.0.1/MODULE.bazel": "5b1df97dbc29623bccdf2b0dcd0f5cb08e2f2c9050aab1092fd39a41e82686ff", + "https://bcr.bazel.build/modules/rules_pkg/1.2.0/MODULE.bazel": "c7db3c2b407e673c7a39e3625dc05dc9f12d6682cbd82a3a5924a13b491eda7e", + "https://bcr.bazel.build/modules/rules_pkg/1.2.0/source.json": "9062e00845bf91a4247465d371baa837adf9b6ff44c542f73ba084f07667e1dc", + "https://bcr.bazel.build/modules/rules_proto/4.0.0/MODULE.bazel": "a7a7b6ce9bee418c1a760b3d84f83a299ad6952f9903c67f19e4edd964894e06", + "https://bcr.bazel.build/modules/rules_proto/5.3.0-21.7/MODULE.bazel": "e8dff86b0971688790ae75528fe1813f71809b5afd57facb44dad9e8eca631b7", + "https://bcr.bazel.build/modules/rules_proto/6.0.0-rc1/MODULE.bazel": "1e5b502e2e1a9e825eef74476a5a1ee524a92297085015a052510b09a1a09483", + "https://bcr.bazel.build/modules/rules_proto/6.0.0/MODULE.bazel": "b531d7f09f58dce456cd61b4579ce8c86b38544da75184eadaf0a7cb7966453f", + "https://bcr.bazel.build/modules/rules_proto/6.0.2/MODULE.bazel": "ce916b775a62b90b61888052a416ccdda405212b6aaeb39522f7dc53431a5e73", + "https://bcr.bazel.build/modules/rules_proto/7.0.2/MODULE.bazel": "bf81793bd6d2ad89a37a40693e56c61b0ee30f7a7fdbaf3eabbf5f39de47dea2", + "https://bcr.bazel.build/modules/rules_proto/7.1.0/MODULE.bazel": "002d62d9108f75bb807cd56245d45648f38275cb3a99dcd45dfb864c5d74cb96", + "https://bcr.bazel.build/modules/rules_proto/7.1.0/source.json": "39f89066c12c24097854e8f57ab8558929f9c8d474d34b2c00ac04630ad8940e", + "https://bcr.bazel.build/modules/rules_python/0.10.2/MODULE.bazel": "cc82bc96f2997baa545ab3ce73f196d040ffb8756fd2d66125a530031cd90e5f", + "https://bcr.bazel.build/modules/rules_python/0.23.1/MODULE.bazel": "49ffccf0511cb8414de28321f5fcf2a31312b47c40cc21577144b7447f2bf300", + "https://bcr.bazel.build/modules/rules_python/0.25.0/MODULE.bazel": "72f1506841c920a1afec76975b35312410eea3aa7b63267436bfb1dd91d2d382", + "https://bcr.bazel.build/modules/rules_python/0.28.0/MODULE.bazel": "cba2573d870babc976664a912539b320cbaa7114cd3e8f053c720171cde331ed", + "https://bcr.bazel.build/modules/rules_python/0.31.0/MODULE.bazel": "93a43dc47ee570e6ec9f5779b2e64c1476a6ce921c48cc9a1678a91dd5f8fd58", + "https://bcr.bazel.build/modules/rules_python/0.33.2/MODULE.bazel": "3e036c4ad8d804a4dad897d333d8dce200d943df4827cb849840055be8d2e937", + "https://bcr.bazel.build/modules/rules_python/0.37.1/MODULE.bazel": "3faeb2d9fa0a81f8980643ee33f212308f4d93eea4b9ce6f36d0b742e71e9500", + "https://bcr.bazel.build/modules/rules_python/0.37.2/MODULE.bazel": "b5ffde91410745750b6c13be1c5dc4555ef5bc50562af4a89fd77807fdde626a", + "https://bcr.bazel.build/modules/rules_python/0.4.0/MODULE.bazel": "9208ee05fd48bf09ac60ed269791cf17fb343db56c8226a720fbb1cdf467166c", + "https://bcr.bazel.build/modules/rules_python/1.0.0/MODULE.bazel": "898a3d999c22caa585eb062b600f88654bf92efb204fa346fb55f6f8edffca43", + "https://bcr.bazel.build/modules/rules_python/1.3.0/MODULE.bazel": "8361d57eafb67c09b75bf4bbe6be360e1b8f4f18118ab48037f2bd50aa2ccb13", + "https://bcr.bazel.build/modules/rules_python/1.4.1/MODULE.bazel": "8991ad45bdc25018301d6b7e1d3626afc3c8af8aaf4bc04f23d0b99c938b73a6", + "https://bcr.bazel.build/modules/rules_python/1.6.0/MODULE.bazel": "7e04ad8f8d5bea40451cf80b1bd8262552aa73f841415d20db96b7241bd027d8", + "https://bcr.bazel.build/modules/rules_python/1.7.0/MODULE.bazel": "d01f995ecd137abf30238ad9ce97f8fc3ac57289c8b24bd0bf53324d937a14f8", + "https://bcr.bazel.build/modules/rules_python/1.7.0/source.json": "028a084b65dcf8f4dc4f82f8778dbe65df133f234b316828a82e060d81bdce32", + "https://bcr.bazel.build/modules/rules_robolectric/4.14.1.2/MODULE.bazel": "d44fec647d0aeb67b9f3b980cf68ba634976f3ae7ccd6c07d790b59b87a4f251", + "https://bcr.bazel.build/modules/rules_robolectric/4.14.1.2/source.json": "37c10335f2361c337c5c1f34ed36d2da70534c23088062b33a8bdaab68aa9dea", + "https://bcr.bazel.build/modules/rules_shell/0.1.2/MODULE.bazel": "66e4ca3ce084b04af0b9ff05ff14cab4e5df7503973818bb91cbc6cda08d32fc", + "https://bcr.bazel.build/modules/rules_shell/0.2.0/MODULE.bazel": "fda8a652ab3c7d8fee214de05e7a9916d8b28082234e8d2c0094505c5268ed3c", + "https://bcr.bazel.build/modules/rules_shell/0.3.0/MODULE.bazel": "de4402cd12f4cc8fda2354fce179fdb068c0b9ca1ec2d2b17b3e21b24c1a937b", + "https://bcr.bazel.build/modules/rules_shell/0.4.1/MODULE.bazel": "00e501db01bbf4e3e1dd1595959092c2fadf2087b2852d3f553b5370f5633592", + "https://bcr.bazel.build/modules/rules_shell/0.6.1/MODULE.bazel": "72e76b0eea4e81611ef5452aa82b3da34caca0c8b7b5c0c9584338aa93bae26b", + "https://bcr.bazel.build/modules/rules_shell/0.8.0/MODULE.bazel": "f6a89f1d6a669a26f28fe814503857055d76306b79cfc11d12399af08d0b80ae", + "https://bcr.bazel.build/modules/rules_shell/0.8.0/source.json": "eb53cc815bc503c6683c5fe12d943f98883f81fc22f51403ec8a95610cba4195", + "https://bcr.bazel.build/modules/rules_swift/1.16.0/MODULE.bazel": "4a09f199545a60d09895e8281362b1ff3bb08bbde69c6fc87aff5b92fcc916ca", + "https://bcr.bazel.build/modules/rules_swift/2.1.1/MODULE.bazel": "494900a80f944fc7aa61500c2073d9729dff0b764f0e89b824eb746959bc1046", + "https://bcr.bazel.build/modules/rules_swift/2.4.0/MODULE.bazel": "1639617eb1ede28d774d967a738b4a68b0accb40650beadb57c21846beab5efd", + "https://bcr.bazel.build/modules/rules_swift/3.1.2/MODULE.bazel": "72c8f5cf9d26427cee6c76c8e3853eb46ce6b0412a081b2b6db6e8ad56267400", + "https://bcr.bazel.build/modules/rules_swift/3.1.2/source.json": "e85761f3098a6faf40b8187695e3de6d97944e98abd0d8ce579cb2daf6319a66", + "https://bcr.bazel.build/modules/stardoc/0.5.1/MODULE.bazel": "1a05d92974d0c122f5ccf09291442580317cdd859f07a8655f1db9a60374f9f8", + "https://bcr.bazel.build/modules/stardoc/0.5.3/MODULE.bazel": "c7f6948dae6999bf0db32c1858ae345f112cacf98f174c7a8bb707e41b974f1c", + "https://bcr.bazel.build/modules/stardoc/0.5.4/MODULE.bazel": "6569966df04610b8520957cb8e97cf2e9faac2c0309657c537ab51c16c18a2a4", + "https://bcr.bazel.build/modules/stardoc/0.6.2/MODULE.bazel": "7060193196395f5dd668eda046ccbeacebfd98efc77fed418dbe2b82ffaa39fd", + "https://bcr.bazel.build/modules/stardoc/0.7.0/MODULE.bazel": "05e3d6d30c099b6770e97da986c53bd31844d7f13d41412480ea265ac9e8079c", + "https://bcr.bazel.build/modules/stardoc/0.7.2/MODULE.bazel": "fc152419aa2ea0f51c29583fab1e8c99ddefd5b3778421845606ee628629e0e5", + "https://bcr.bazel.build/modules/stardoc/0.7.2/source.json": "58b029e5e901d6802967754adf0a9056747e8176f017cfe3607c0851f4d42216", + "https://bcr.bazel.build/modules/swift_argument_parser/1.3.1.1/MODULE.bazel": "5e463fbfba7b1701d957555ed45097d7f984211330106ccd1352c6e0af0dcf91", + "https://bcr.bazel.build/modules/swift_argument_parser/1.3.1.2/MODULE.bazel": "75aab2373a4bbe2a1260b9bf2a1ebbdbf872d3bd36f80bff058dccd82e89422f", + "https://bcr.bazel.build/modules/swift_argument_parser/1.3.1.2/source.json": "5fba48bbe0ba48761f9e9f75f92876cafb5d07c0ce059cc7a8027416de94a05b", + "https://bcr.bazel.build/modules/tar.bzl/0.2.1/MODULE.bazel": "52d1c00a80a8cc67acbd01649e83d8dd6a9dc426a6c0b754a04fe8c219c76468", + "https://bcr.bazel.build/modules/tar.bzl/0.2.1/source.json": "600ac6ff61744667a439e7b814ae59c1f29632c3984fccf8000c64c9db8d7bb6", + "https://bcr.bazel.build/modules/toml.bzl/0.3.0/MODULE.bazel": "5016e5dd1ad2200e119a4b28b2b3935e276c4b480f2fe3e952bea7eeba88f578", + "https://bcr.bazel.build/modules/toml.bzl/0.3.0/source.json": "0cf7c878c419b37ddb55f3dd93dd7c0c409bd7c4efacb3da504e0748780b2fa9", + "https://bcr.bazel.build/modules/upb/0.0.0-20220923-a547704/MODULE.bazel": "7298990c00040a0e2f121f6c32544bab27d4452f80d9ce51349b1a28f3005c43", + "https://bcr.bazel.build/modules/upb/0.0.0-20230516-61a97ef/MODULE.bazel": "c0df5e35ad55e264160417fd0875932ee3c9dda63d9fccace35ac62f45e1b6f9", + "https://bcr.bazel.build/modules/yq.bzl/0.1.1/MODULE.bazel": "9039681f9bcb8958ee2c87ffc74bdafba9f4369096a2b5634b88abc0eaefa072", + "https://bcr.bazel.build/modules/yq.bzl/0.1.1/source.json": "2d2bad780a9f2b9195a4a370314d2c17ae95eaa745cefc2e12fbc49759b15aa3", + "https://bcr.bazel.build/modules/zlib/1.2.11/MODULE.bazel": "07b389abc85fdbca459b69e2ec656ae5622873af3f845e1c9d80fe179f3effa0", + "https://bcr.bazel.build/modules/zlib/1.2.12/MODULE.bazel": "3b1a8834ada2a883674be8cbd36ede1b6ec481477ada359cd2d3ddc562340b27", + "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.5/MODULE.bazel": "eec517b5bbe5492629466e11dae908d043364302283de25581e3eb944326c4ca", + "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.5/source.json": "22bc55c47af97246cfc093d0acf683a7869377de362b5d1c552c2c2e16b7a806", + "https://bcr.bazel.build/modules/zlib/1.3.1/MODULE.bazel": "751c9940dcfe869f5f7274e1295422a34623555916eb98c174c1e945594bf198" + }, + "selectedYankedVersions": {}, + "moduleExtensions": { + "@@rules_android+//rules/android_sdk_repository:rule.bzl%android_sdk_repository_extension": { + "general": { + "bzlTransitiveDigest": "+rMrzIrv7sImYmkbXJYv+gFpTJQ79X3MpwwMLI2A+oA=", + "usagesDigest": "iEGI2aNDMkHt9LXCdViLNUUOslpiVj2DrevWWXZEFnU=", + "recordedInputs": [], + "generatedRepoSpecs": { + "androidsdk": { + "repoRuleId": "@@rules_android+//rules/android_sdk_repository:rule.bzl%_android_sdk_repository", + "attributes": {} + } + } + } + }, + "@@rules_oci+//oci:extensions.bzl%oci": { + "general": { + "bzlTransitiveDigest": "pt4oC5w4SZXivjOVNAFM5W2NyEaU5cCGwrSOmM0x9wQ=", + "usagesDigest": "YV/my4HWfeIYZH762GR/gbfyrtmoU6x5X9/fNcX4Ioo=", + "recordedInputs": [ + "REPO_MAPPING:aspect_bazel_lib+,bazel_tools bazel_tools", + "REPO_MAPPING:bazel_features+,bazel_tools bazel_tools", + "REPO_MAPPING:rules_oci+,aspect_bazel_lib aspect_bazel_lib+", + "REPO_MAPPING:rules_oci+,bazel_features bazel_features+", + "REPO_MAPPING:rules_oci+,bazel_skylib bazel_skylib+" + ], + "generatedRepoSpecs": { + "temurin_jre_linux_arm64_v8": { + "repoRuleId": "@@rules_oci+//oci/private:pull.bzl%oci_pull", + "attributes": { + "www_authenticate_challenges": {}, + "scheme": "https", + "registry": "public.ecr.aws", + "repository": "docker/library/eclipse-temurin", + "identifier": "21-jre", + "platform": "linux/arm64/v8", + "target_name": "temurin_jre_linux_arm64_v8", + "bazel_tags": [] + } + }, + "temurin_jre_linux_amd64": { + "repoRuleId": "@@rules_oci+//oci/private:pull.bzl%oci_pull", + "attributes": { + "www_authenticate_challenges": {}, + "scheme": "https", + "registry": "public.ecr.aws", + "repository": "docker/library/eclipse-temurin", + "identifier": "21-jre", + "platform": "linux/amd64", + "target_name": "temurin_jre_linux_amd64", + "bazel_tags": [] + } + }, + "temurin_jre": { + "repoRuleId": "@@rules_oci+//oci/private:pull.bzl%oci_alias", + "attributes": { + "target_name": "temurin_jre", + "www_authenticate_challenges": {}, + "scheme": "https", + "registry": "public.ecr.aws", + "repository": "docker/library/eclipse-temurin", + "identifier": "21-jre", + "platforms": { + "@@platforms//cpu:arm64": "@temurin_jre_linux_arm64_v8", + "@@platforms//cpu:x86_64": "@temurin_jre_linux_amd64" + }, + "bzlmod_repository": "temurin_jre", + "reproducible": true + } + }, + "ubuntu_noble_linux_arm64_v8": { + "repoRuleId": "@@rules_oci+//oci/private:pull.bzl%oci_pull", + "attributes": { + "www_authenticate_challenges": {}, + "scheme": "https", + "registry": "public.ecr.aws", + "repository": "ubuntu/ubuntu", + "identifier": "sha256:ef59d9e82939bbce08973bdffb8761b025f75369fb7d2882cdc4938b5a9e992e", + "platform": "linux/arm64/v8", + "target_name": "ubuntu_noble_linux_arm64_v8", + "bazel_tags": [] + } + }, + "ubuntu_noble_linux_amd64": { + "repoRuleId": "@@rules_oci+//oci/private:pull.bzl%oci_pull", + "attributes": { + "www_authenticate_challenges": {}, + "scheme": "https", + "registry": "public.ecr.aws", + "repository": "ubuntu/ubuntu", + "identifier": "sha256:ef59d9e82939bbce08973bdffb8761b025f75369fb7d2882cdc4938b5a9e992e", + "platform": "linux/amd64", + "target_name": "ubuntu_noble_linux_amd64", + "bazel_tags": [] + } + }, + "ubuntu_noble": { + "repoRuleId": "@@rules_oci+//oci/private:pull.bzl%oci_alias", + "attributes": { + "target_name": "ubuntu_noble", + "www_authenticate_challenges": {}, + "scheme": "https", + "registry": "public.ecr.aws", + "repository": "ubuntu/ubuntu", + "identifier": "sha256:ef59d9e82939bbce08973bdffb8761b025f75369fb7d2882cdc4938b5a9e992e", + "platforms": { + "@@platforms//cpu:arm64": "@ubuntu_noble_linux_arm64_v8", + "@@platforms//cpu:x86_64": "@ubuntu_noble_linux_amd64" + }, + "bzlmod_repository": "ubuntu_noble", + "reproducible": true + } + }, + "oci_crane_darwin_amd64": { + "repoRuleId": "@@rules_oci+//oci:repositories.bzl%crane_repositories", + "attributes": { + "platform": "darwin_amd64", + "crane_version": "v0.18.0" + } + }, + "oci_crane_darwin_arm64": { + "repoRuleId": "@@rules_oci+//oci:repositories.bzl%crane_repositories", + "attributes": { + "platform": "darwin_arm64", + "crane_version": "v0.18.0" + } + }, + "oci_crane_linux_arm64": { + "repoRuleId": "@@rules_oci+//oci:repositories.bzl%crane_repositories", + "attributes": { + "platform": "linux_arm64", + "crane_version": "v0.18.0" + } + }, + "oci_crane_linux_armv6": { + "repoRuleId": "@@rules_oci+//oci:repositories.bzl%crane_repositories", + "attributes": { + "platform": "linux_armv6", + "crane_version": "v0.18.0" + } + }, + "oci_crane_linux_i386": { + "repoRuleId": "@@rules_oci+//oci:repositories.bzl%crane_repositories", + "attributes": { + "platform": "linux_i386", + "crane_version": "v0.18.0" + } + }, + "oci_crane_linux_s390x": { + "repoRuleId": "@@rules_oci+//oci:repositories.bzl%crane_repositories", + "attributes": { + "platform": "linux_s390x", + "crane_version": "v0.18.0" + } + }, + "oci_crane_linux_amd64": { + "repoRuleId": "@@rules_oci+//oci:repositories.bzl%crane_repositories", + "attributes": { + "platform": "linux_amd64", + "crane_version": "v0.18.0" + } + }, + "oci_crane_windows_armv6": { + "repoRuleId": "@@rules_oci+//oci:repositories.bzl%crane_repositories", + "attributes": { + "platform": "windows_armv6", + "crane_version": "v0.18.0" + } + }, + "oci_crane_windows_amd64": { + "repoRuleId": "@@rules_oci+//oci:repositories.bzl%crane_repositories", + "attributes": { + "platform": "windows_amd64", + "crane_version": "v0.18.0" + } + }, + "oci_crane_toolchains": { + "repoRuleId": "@@rules_oci+//oci/private:toolchains_repo.bzl%toolchains_repo", + "attributes": { + "toolchain_type": "@rules_oci//oci:crane_toolchain_type", + "toolchain": "@oci_crane_{platform}//:crane_toolchain" + } + }, + "oci_regctl_darwin_amd64": { + "repoRuleId": "@@rules_oci+//oci:repositories.bzl%regctl_repositories", + "attributes": { + "platform": "darwin_amd64" + } + }, + "oci_regctl_darwin_arm64": { + "repoRuleId": "@@rules_oci+//oci:repositories.bzl%regctl_repositories", + "attributes": { + "platform": "darwin_arm64" + } + }, + "oci_regctl_linux_arm64": { + "repoRuleId": "@@rules_oci+//oci:repositories.bzl%regctl_repositories", + "attributes": { + "platform": "linux_arm64" + } + }, + "oci_regctl_linux_s390x": { + "repoRuleId": "@@rules_oci+//oci:repositories.bzl%regctl_repositories", + "attributes": { + "platform": "linux_s390x" + } + }, + "oci_regctl_linux_amd64": { + "repoRuleId": "@@rules_oci+//oci:repositories.bzl%regctl_repositories", + "attributes": { + "platform": "linux_amd64" + } + }, + "oci_regctl_windows_amd64": { + "repoRuleId": "@@rules_oci+//oci:repositories.bzl%regctl_repositories", + "attributes": { + "platform": "windows_amd64" + } + }, + "oci_regctl_toolchains": { + "repoRuleId": "@@rules_oci+//oci/private:toolchains_repo.bzl%toolchains_repo", + "attributes": { + "toolchain_type": "@rules_oci//oci:regctl_toolchain_type", + "toolchain": "@oci_regctl_{platform}//:regctl_toolchain" + } + } + }, + "moduleExtensionMetadata": { + "explicitRootModuleDirectDeps": [], + "explicitRootModuleDirectDevDeps": [], + "useAllRepos": "NO", + "reproducible": false + } + } + }, + "@@rules_python+//python/extensions:config.bzl%config": { + "general": { + "bzlTransitiveDigest": "dzD8Q2YmrP3fz8saWLHPmlwPLO91ImtTmP/c9JKTStM=", + "usagesDigest": "ZVSXMAGpD+xzVNPuvF1IoLBkty7TROO0+akMapt1pAg=", + "recordedInputs": [ + "REPO_MAPPING:rules_python+,bazel_tools bazel_tools", + "REPO_MAPPING:rules_python+,pypi__build rules_python++config+pypi__build", + "REPO_MAPPING:rules_python+,pypi__click rules_python++config+pypi__click", + "REPO_MAPPING:rules_python+,pypi__colorama rules_python++config+pypi__colorama", + "REPO_MAPPING:rules_python+,pypi__importlib_metadata rules_python++config+pypi__importlib_metadata", + "REPO_MAPPING:rules_python+,pypi__installer rules_python++config+pypi__installer", + "REPO_MAPPING:rules_python+,pypi__more_itertools rules_python++config+pypi__more_itertools", + "REPO_MAPPING:rules_python+,pypi__packaging rules_python++config+pypi__packaging", + "REPO_MAPPING:rules_python+,pypi__pep517 rules_python++config+pypi__pep517", + "REPO_MAPPING:rules_python+,pypi__pip rules_python++config+pypi__pip", + "REPO_MAPPING:rules_python+,pypi__pip_tools rules_python++config+pypi__pip_tools", + "REPO_MAPPING:rules_python+,pypi__pyproject_hooks rules_python++config+pypi__pyproject_hooks", + "REPO_MAPPING:rules_python+,pypi__setuptools rules_python++config+pypi__setuptools", + "REPO_MAPPING:rules_python+,pypi__tomli rules_python++config+pypi__tomli", + "REPO_MAPPING:rules_python+,pypi__wheel rules_python++config+pypi__wheel", + "REPO_MAPPING:rules_python+,pypi__zipp rules_python++config+pypi__zipp" + ], + "generatedRepoSpecs": { + "rules_python_internal": { + "repoRuleId": "@@rules_python+//python/private:internal_config_repo.bzl%internal_config_repo", + "attributes": { + "transition_setting_generators": {}, + "transition_settings": [] + } + }, + "pypi__build": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/e2/03/f3c8ba0a6b6e30d7d18c40faab90807c9bb5e9a1e3b2fe2008af624a9c97/build-1.2.1-py3-none-any.whl", + "sha256": "75e10f767a433d9a86e50d83f418e83efc18ede923ee5ff7df93b6cb0306c5d4", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__click": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/00/2e/d53fa4befbf2cfa713304affc7ca780ce4fc1fd8710527771b58311a3229/click-8.1.7-py3-none-any.whl", + "sha256": "ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__colorama": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", + "sha256": "4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__importlib_metadata": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/2d/0a/679461c511447ffaf176567d5c496d1de27cbe34a87df6677d7171b2fbd4/importlib_metadata-7.1.0-py3-none-any.whl", + "sha256": "30962b96c0c223483ed6cc7280e7f0199feb01a0e40cfae4d4450fc6fab1f570", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__installer": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/e5/ca/1172b6638d52f2d6caa2dd262ec4c811ba59eee96d54a7701930726bce18/installer-0.7.0-py3-none-any.whl", + "sha256": "05d1933f0a5ba7d8d6296bb6d5018e7c94fa473ceb10cf198a92ccea19c27b53", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__more_itertools": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/50/e2/8e10e465ee3987bb7c9ab69efb91d867d93959095f4807db102d07995d94/more_itertools-10.2.0-py3-none-any.whl", + "sha256": "686b06abe565edfab151cb8fd385a05651e1fdf8f0a14191e4439283421f8684", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__packaging": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/49/df/1fceb2f8900f8639e278b056416d49134fb8d84c5942ffaa01ad34782422/packaging-24.0-py3-none-any.whl", + "sha256": "2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__pep517": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/25/6e/ca4a5434eb0e502210f591b97537d322546e4833dcb4d470a48c375c5540/pep517-0.13.1-py3-none-any.whl", + "sha256": "31b206f67165b3536dd577c5c3f1518e8fbaf38cbc57efff8369a392feff1721", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__pip": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/8a/6a/19e9fe04fca059ccf770861c7d5721ab4c2aebc539889e97c7977528a53b/pip-24.0-py3-none-any.whl", + "sha256": "ba0d021a166865d2265246961bec0152ff124de910c5cc39f1156ce3fa7c69dc", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__pip_tools": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/0d/dc/38f4ce065e92c66f058ea7a368a9c5de4e702272b479c0992059f7693941/pip_tools-7.4.1-py3-none-any.whl", + "sha256": "4c690e5fbae2f21e87843e89c26191f0d9454f362d8acdbd695716493ec8b3a9", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__pyproject_hooks": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/ae/f3/431b9d5fe7d14af7a32340792ef43b8a714e7726f1d7b69cc4e8e7a3f1d7/pyproject_hooks-1.1.0-py3-none-any.whl", + "sha256": "7ceeefe9aec63a1064c18d939bdc3adf2d8aa1988a510afec15151578b232aa2", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__setuptools": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/90/99/158ad0609729111163fc1f674a5a42f2605371a4cf036d0441070e2f7455/setuptools-78.1.1-py3-none-any.whl", + "sha256": "c3a9c4211ff4c309edb8b8c4f1cbfa7ae324c4ba9f91ff254e3d305b9fd54561", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__tomli": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/97/75/10a9ebee3fd790d20926a90a2547f0bf78f371b2f13aa822c759680ca7b9/tomli-2.0.1-py3-none-any.whl", + "sha256": "939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__wheel": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/7d/cd/d7460c9a869b16c3dd4e1e403cce337df165368c71d6af229a74699622ce/wheel-0.43.0-py3-none-any.whl", + "sha256": "55c570405f142630c6b9f72fe09d9b67cf1477fcf543ae5b8dcb1f5b7377da81", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + }, + "pypi__zipp": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "url": "https://files.pythonhosted.org/packages/da/55/a03fd7240714916507e1fcf7ae355bd9d9ed2e6db492595f1a67f61681be/zipp-3.18.2-py3-none-any.whl", + "sha256": "dce197b859eb796242b0622af1b8beb0a722d52aa2f57133ead08edd5bf5374e", + "type": "zip", + "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" + } + } + } + } + }, + "@@rules_python+//python/uv:uv.bzl%uv": { + "general": { + "bzlTransitiveDigest": "ijW9KS7qsIY+yBVvJ+Nr1mzwQox09j13DnE3iIwaeTM=", + "usagesDigest": "H8dQoNZcoqP+Mu0tHZTi4KHATzvNkM5ePuEqoQdklIU=", + "recordedInputs": [ + "REPO_MAPPING:rules_python+,bazel_tools bazel_tools", + "REPO_MAPPING:rules_python+,platforms platforms" + ], + "generatedRepoSpecs": { + "uv": { + "repoRuleId": "@@rules_python+//python/uv/private:uv_toolchains_repo.bzl%uv_toolchains_repo", + "attributes": { + "toolchain_type": "'@@rules_python+//python/uv:uv_toolchain_type'", + "toolchain_names": [ + "none" + ], + "toolchain_implementations": { + "none": "'@@rules_python+//python:none'" + }, + "toolchain_compatible_with": { + "none": [ + "@platforms//:incompatible" + ] + }, + "toolchain_target_settings": {} + } + } + } + } + } + }, + "facts": { + "@@rules_go+//go:extensions.bzl%go_sdk": { + "1.22.4": { + "aix_ppc64": [ + "go1.22.4.aix-ppc64.tar.gz", + "b9647fa9fc83a0cc5d4f092a19eaeaecf45f063a5aa7d4962fde65aeb7ae6ce1" + ], + "darwin_amd64": [ + "go1.22.4.darwin-amd64.tar.gz", + "c95967f50aa4ace34af0c236cbdb49a9a3e80ee2ad09d85775cb4462a5c19ed3" + ], + "darwin_arm64": [ + "go1.22.4.darwin-arm64.tar.gz", + "242b78dc4c8f3d5435d28a0d2cec9b4c1aa999b601fb8aa59fb4e5a1364bf827" + ], + "dragonfly_amd64": [ + "go1.22.4.dragonfly-amd64.tar.gz", + "f2fbb51af4719d3616efb482d6ed2b96579b474156f85a7ddc6f126764feec4b" + ], + "freebsd_386": [ + "go1.22.4.freebsd-386.tar.gz", + "7c54884bb9f274884651d41e61d1bc12738863ad1497e97ea19ad0e9aa6bf7b5" + ], + "freebsd_amd64": [ + "go1.22.4.freebsd-amd64.tar.gz", + "88d44500e1701dd35797619774d6dd51bf60f45a8338b0a82ddc018e4e63fb78" + ], + "freebsd_arm64": [ + "go1.22.4.freebsd-arm64.tar.gz", + "726dc093cf020277be45debf03c3b02b43c2efb3e2a5d4fba8f52579d65327dc" + ], + "freebsd_armv6l": [ + "go1.22.4.freebsd-arm.tar.gz", + "3d9efe47db142a22679aba46b1772e3900b0d87ae13bd2b3bc80dbf2ac0b2cd6" + ], + "freebsd_riscv64": [ + "go1.22.4.freebsd-riscv64.tar.gz", + "5f6b67e5e32f1d6ccb2d4dcb44934a5e2e870a877ba7443d86ec43cfc28afa71" + ], + "illumos_amd64": [ + "go1.22.4.illumos-amd64.tar.gz", + "d56ecc2f85b6418a21ef83879594d0c42ab4f65391a676bb12254870e6690d63" + ], + "linux_386": [ + "go1.22.4.linux-386.tar.gz", + "47a2a8d249a91eb8605c33bceec63aedda0441a43eac47b4721e3975ff916cec" + ], + "linux_amd64": [ + "go1.22.4.linux-amd64.tar.gz", + "ba79d4526102575196273416239cca418a651e049c2b099f3159db85e7bade7d" + ], + "linux_arm64": [ + "go1.22.4.linux-arm64.tar.gz", + "a8e177c354d2e4a1b61020aca3562e27ea3e8f8247eca3170e3fa1e0c2f9e771" + ], + "linux_armv6l": [ + "go1.22.4.linux-armv6l.tar.gz", + "e2b143fbacbc9cbd448e9ef41ac3981f0488ce849af1cf37e2341d09670661de" + ], + "linux_loong64": [ + "go1.22.4.linux-loong64.tar.gz", + "e2ff9436e4b34bf6926b06d97916e26d67a909a2effec17967245900f0816f1d" + ], + "linux_mips": [ + "go1.22.4.linux-mips.tar.gz", + "73f0dcc60458c4770593b05a7bc01cc0d31fc98f948c0c2334812c7a1f2fc3f1" + ], + "linux_mips64": [ + "go1.22.4.linux-mips64.tar.gz", + "417af97fc2630a647052375768be4c38adcc5af946352ea5b28613ea81ca5d45" + ], + "linux_mips64le": [ + "go1.22.4.linux-mips64le.tar.gz", + "7486e2d7dd8c98eb44df815ace35a7fe7f30b7c02326e3741bd934077508139b" + ], + "linux_mipsle": [ + "go1.22.4.linux-mipsle.tar.gz", + "69479c8aad301e459a8365b40cad1074a0dbba5defb9291669f94809c4c4be6e" + ], + "linux_ppc64": [ + "go1.22.4.linux-ppc64.tar.gz", + "dd238847e65bc3e2745caca475a5db6522a2fcf85cf6c38fc36a06642b19efd7" + ], + "linux_ppc64le": [ + "go1.22.4.linux-ppc64le.tar.gz", + "a3e5834657ef92523f570f798fed42f1f87bc18222a16815ec76b84169649ec4" + ], + "linux_riscv64": [ + "go1.22.4.linux-riscv64.tar.gz", + "56a827ff7dc6245bcd7a1e9288dffaa1d8b0fd7468562264c1523daf3b4f1b4a" + ], + "linux_s390x": [ + "go1.22.4.linux-s390x.tar.gz", + "7590c3e278e2dc6040aae0a39da3ca1eb2e3921673a7304cc34d588c45889eec" + ], + "netbsd_386": [ + "go1.22.4.netbsd-386.tar.gz", + "ddd2eebe34471a2502de6c5dad04ab27c9fc80cbde7a9ad5b3c66ecec4504e1d" + ], + "netbsd_amd64": [ + "go1.22.4.netbsd-amd64.tar.gz", + "33af79f6f935f6fbacc5d23876450b3567b79348fc065beef8e64081127dd234" + ], + "netbsd_arm64": [ + "go1.22.4.netbsd-arm64.tar.gz", + "c9a2971dec9f6d320c6f2b049b2353c6d0a2d35e87b8a4b2d78a2f0d62545f8e" + ], + "netbsd_armv6l": [ + "go1.22.4.netbsd-arm.tar.gz", + "fa3550ebd5375a70b3bcd342b5a71f4bd271dcbbfaf4eabefa2144ab5d8924b6" + ], + "openbsd_386": [ + "go1.22.4.openbsd-386.tar.gz", + "d21af022331bfdc2b5b161d616c3a1a4573d33cf7a30416ee509a8f3641deb47" + ], + "openbsd_amd64": [ + "go1.22.4.openbsd-amd64.tar.gz", + "72c0094c43f7e5722ec49c2a3e9dfa7a1123ac43a5f3a63eecf3e3795d3ff0ae" + ], + "openbsd_arm64": [ + "go1.22.4.openbsd-arm64.tar.gz", + "a7ab8d4e0b02bf06ed144ba42c61c0e93ee00f2b433415dfd4ad4b6e79f31650" + ], + "openbsd_armv6l": [ + "go1.22.4.openbsd-arm.tar.gz", + "1096831ea3c5ea3ca57d14251d9eda3786889531eb40d7d6775dcaa324d4b065" + ], + "openbsd_ppc64": [ + "go1.22.4.openbsd-ppc64.tar.gz", + "9716327c8a628358798898dc5148c49dbbeb5196bf2cbf088e550721a6e4f60b" + ], + "plan9_386": [ + "go1.22.4.plan9-386.tar.gz", + "a8dd4503c95c32a502a616ab78870a19889c9325fe9bd31eb16dd69346e4bfa8" + ], + "plan9_amd64": [ + "go1.22.4.plan9-amd64.tar.gz", + "5423a25808d76fe5aca8607a2e5ac5673abf45446b168cb5e9d8519ee9fe39a1" + ], + "plan9_armv6l": [ + "go1.22.4.plan9-arm.tar.gz", + "6af939ad583f5c85c09c53728ab7d38c3cc2b39167562d6c18a07c5c6608b370" + ], + "solaris_amd64": [ + "go1.22.4.solaris-amd64.tar.gz", + "e8cabe69c03085725afdb32a6f9998191a3e55a747b270d835fd05000d56abba" + ], + "windows_386": [ + "go1.22.4.windows-386.zip", + "aca4e2c37278a10f1c70dd0df142f7d66b50334fcee48978d409202d308d6d25" + ], + "windows_amd64": [ + "go1.22.4.windows-amd64.zip", + "26321c4d945a0035d8a5bc4a1965b0df401ff8ceac66ce2daadabf9030419a98" + ], + "windows_arm64": [ + "go1.22.4.windows-arm64.zip", + "8a2daa9ea28cbdafddc6171aefed384f4e5b6e714fb52116fe9ed25a132f37ed" + ], + "windows_armv6l": [ + "go1.22.4.windows-arm.zip", + "5fcd0671a49cecf39b41021621ee1b6e7aa1370f37122b72e80d4fd4185833b6" + ] + }, + "1.23.6": { + "aix_ppc64": [ + "go1.23.6.aix-ppc64.tar.gz", + "adec10f4ba56591f523aa04851f7f6900b1c61508dfa6b80e62717a8e6684a5c" + ], + "darwin_amd64": [ + "go1.23.6.darwin-amd64.tar.gz", + "782da50ce8ec5e98fac2cd3cdc6a1d7130d093294fc310038f651444232a3fb0" + ], + "darwin_arm64": [ + "go1.23.6.darwin-arm64.tar.gz", + "5cae2450a1708aeb0333237a155640d5562abaf195defebc4306054565536221" + ], + "dragonfly_amd64": [ + "go1.23.6.dragonfly-amd64.tar.gz", + "d52efb3020d9332477ade98163c03d2f2fe3e051b0e7e01f0e167412c66de0cb" + ], + "freebsd_386": [ + "go1.23.6.freebsd-386.tar.gz", + "d3287706b5823712ac6cf7dff684a556cff98163ef60e7b275abe3388c17aac7" + ], + "freebsd_amd64": [ + "go1.23.6.freebsd-amd64.tar.gz", + "ebb4c6a9b0673dbdabc439877779ed6add16575e21bd0a7955c33f692789aef6" + ], + "freebsd_arm": [ + "go1.23.6.freebsd-arm.tar.gz", + "b7241584afb0b161c09148f8fde16171bb743e47b99d451fbc5f5217ec7a88b6" + ], + "freebsd_arm64": [ + "go1.23.6.freebsd-arm64.tar.gz", + "004718b53cedd7955d1b1dc4053539fcd1053c031f5f3374334a22befd1f8310" + ], + "freebsd_riscv64": [ + "go1.23.6.freebsd-riscv64.tar.gz", + "ca026ec8a30dd0c18164f40e1ce21bd725e2445f11699177d05815189a38de7a" + ], + "illumos_amd64": [ + "go1.23.6.illumos-amd64.tar.gz", + "7db973efa3fb2e48e45059b855721550fce8e90803e7373d3efd37b88dd821e8" + ], + "linux_386": [ + "go1.23.6.linux-386.tar.gz", + "e61f87693169c0bbcc43363128f1e929b9dff0b7f448573f1bdd4e4a0b9687ba" + ], + "linux_amd64": [ + "go1.23.6.linux-amd64.tar.gz", + "9379441ea310de000f33a4dc767bd966e72ab2826270e038e78b2c53c2e7802d" + ], + "linux_arm64": [ + "go1.23.6.linux-arm64.tar.gz", + "561c780e8f4a8955d32bf72e46af0b5ee5e0debe1e4633df9a03781878219202" + ], + "linux_armv6l": [ + "go1.23.6.linux-armv6l.tar.gz", + "27a4611010c16b8c4f37ade3aada55bd5781998f02f348b164302fd5eea4eb74" + ], + "linux_loong64": [ + "go1.23.6.linux-loong64.tar.gz", + "c459226424372abc2b35957cc8955dad348330714f7605093325dbb73e33c750" + ], + "linux_mips": [ + "go1.23.6.linux-mips.tar.gz", + "e2a0aff70b958a3463a7d47132a2d0238369f64578d4f7f95e679e3a5af05622" + ], + "linux_mips64": [ + "go1.23.6.linux-mips64.tar.gz", + "7d30ec7db056311d420bf930c16abcae13c0f41c26a202868f279721ec3c2f2f" + ], + "linux_mips64le": [ + "go1.23.6.linux-mips64le.tar.gz", + "74ca7bc475bcc084c6718b74df024d7de9612932cea8a6dc75e29d3a5315a23a" + ], + "linux_mipsle": [ + "go1.23.6.linux-mipsle.tar.gz", + "09bf935a14e9f59a20499989438b1655453480016bdbcb10406acf4df2678ccb" + ], + "linux_ppc64": [ + "go1.23.6.linux-ppc64.tar.gz", + "5cb2f6a5090276c72c5eda8a55896f5a3d6ea0f28d10fa1a50e8318640f02d6c" + ], + "linux_ppc64le": [ + "go1.23.6.linux-ppc64le.tar.gz", + "0f817201e83d78ddbfa27f5f78d9b72450b92cc21d5e045145efacd0d3244a99" + ], + "linux_riscv64": [ + "go1.23.6.linux-riscv64.tar.gz", + "f95f7f817ab22ecab4503d0704d6449ea1aa26a595f57bf9b9f94ddf2aa7c1f3" + ], + "linux_s390x": [ + "go1.23.6.linux-s390x.tar.gz", + "321e7ed0d5416f731479c52fa7610b52b8079a8061967bd48cec6d66f671a60e" + ], + "netbsd_386": [ + "go1.23.6.netbsd-386.tar.gz", + "92d678fb8e1eeeb8c6af6f22e4e5494652dcbb4a320113fc08325cb9956a2d4c" + ], + "netbsd_amd64": [ + "go1.23.6.netbsd-amd64.tar.gz", + "86ba51e7bb26b30ea6a8d88ddb79d8e8c83b4116200040ecb7a5a44cf90a8c5c" + ], + "netbsd_arm": [ + "go1.23.6.netbsd-arm.tar.gz", + "4b974c35345100f0be6ea66afab2781de91ee9882117314126eaf0ae90fd3816" + ], + "netbsd_arm64": [ + "go1.23.6.netbsd-arm64.tar.gz", + "53e3589fc38e787a493ea038961f8e40803714dbb42754c1713b00099c12e9b9" + ], + "openbsd_386": [ + "go1.23.6.openbsd-386.tar.gz", + "6d2317b3a8505ccebff8f72d943f2ac9b82c115632e54a53a786eff24ced56d9" + ], + "openbsd_amd64": [ + "go1.23.6.openbsd-amd64.tar.gz", + "f699e707d95a984fcc00361d91aecdb413d3c75e18235156ffba7a89edf68aae" + ], + "openbsd_arm": [ + "go1.23.6.openbsd-arm.tar.gz", + "3c1cf6ab893657d0bf1942e40ce115acfd27cbce1ccb9bc88fd9cd21ca3d489f" + ], + "openbsd_arm64": [ + "go1.23.6.openbsd-arm64.tar.gz", + "cc0875535d14001f2da23ae9af89025b28c466e8f4f4c63f991ebb6f4b02f66c" + ], + "openbsd_ppc64": [ + "go1.23.6.openbsd-ppc64.tar.gz", + "64de80e29ca66cb566cbf8be030bf8599953af4e48402eab724cbe0a08b40602" + ], + "openbsd_riscv64": [ + "go1.23.6.openbsd-riscv64.tar.gz", + "c398a6b43c569f34bb4a2d16b52f8010eaac9a2a82ecac0602b4338e35cef377" + ], + "plan9_386": [ + "go1.23.6.plan9-386.tar.gz", + "10998b6b130bb7b542b407f0db42b86a913b111f8fa86d44394beaace4d45f01" + ], + "plan9_amd64": [ + "go1.23.6.plan9-amd64.tar.gz", + "9fbe8065436d8d12c02f19f64f51c9107da3a7a4ac46ab5777e182e9fe88c32f" + ], + "plan9_arm": [ + "go1.23.6.plan9-arm.tar.gz", + "8e3c826b884daee2de37e3b070d7eac4cea5d68edab8db09910e22201c75db83" + ], + "solaris_amd64": [ + "go1.23.6.solaris-amd64.tar.gz", + "b619eff63fec86daaea92ca170559e448a58b8ba0b92eef1971bc14e92ea86a7" + ], + "windows_386": [ + "go1.23.6.windows-386.zip", + "96820c0f5d464dd694543329e9b4d413b17c821c03a055717a29e6735b44c2d8" + ], + "windows_amd64": [ + "go1.23.6.windows-amd64.zip", + "53fec1586850b2cf5ad6438341ff7adc5f6700dd3ec1cfa3f5e8b141df190243" + ], + "windows_arm": [ + "go1.23.6.windows-arm.zip", + "22c2518c45c20018afa20d5376dc9fd7a7e74367240ed7b5209e79a30b5c4218" + ], + "windows_arm64": [ + "go1.23.6.windows-arm64.zip", + "a2d2ec1b3759552bdd9cdf58858f91dfbfd6ab3a472f00b5255acbed30b1aa41" + ] + }, + "1.25.0": { + "aix_ppc64": [ + "go1.25.0.aix-ppc64.tar.gz", + "e5234a7dac67bc86c528fe9752fc9d63557918627707a733ab4cac1a6faed2d4" + ], + "darwin_amd64": [ + "go1.25.0.darwin-amd64.tar.gz", + "5bd60e823037062c2307c71e8111809865116714d6f6b410597cf5075dfd80ef" + ], + "darwin_arm64": [ + "go1.25.0.darwin-arm64.tar.gz", + "544932844156d8172f7a28f77f2ac9c15a23046698b6243f633b0a0b00c0749c" + ], + "dragonfly_amd64": [ + "go1.25.0.dragonfly-amd64.tar.gz", + "5ed3cf9a810a1483822538674f1336c06b51aa1b94d6d545a1a0319a48177120" + ], + "freebsd_386": [ + "go1.25.0.freebsd-386.tar.gz", + "abea5d5c6697e6b5c224731f2158fe87c602996a2a233ac0c4730cd57bf8374e" + ], + "freebsd_amd64": [ + "go1.25.0.freebsd-amd64.tar.gz", + "86e6fe0a29698d7601c4442052dac48bd58d532c51cccb8f1917df648138730b" + ], + "freebsd_arm": [ + "go1.25.0.freebsd-arm.tar.gz", + "d90b78e41921f72f30e8bbc81d9dec2cff7ff384a33d8d8debb24053e4336bfe" + ], + "freebsd_arm64": [ + "go1.25.0.freebsd-arm64.tar.gz", + "451d0da1affd886bfb291b7c63a6018527b269505db21ce6e14724f22ab0662e" + ], + "freebsd_riscv64": [ + "go1.25.0.freebsd-riscv64.tar.gz", + "7b565f76bd8bda46549eeaaefe0e53b251e644c230577290c0f66b1ecdb3cdbe" + ], + "illumos_amd64": [ + "go1.25.0.illumos-amd64.tar.gz", + "b1e1fdaab1ad25aa1c08d7a36c97d45d74b98b89c3f78c6d2145f77face54a2c" + ], + "linux_386": [ + "go1.25.0.linux-386.tar.gz", + "8c602dd9d99bc9453b3995d20ce4baf382cc50855900a0ece5de9929df4a993a" + ], + "linux_amd64": [ + "go1.25.0.linux-amd64.tar.gz", + "2852af0cb20a13139b3448992e69b868e50ed0f8a1e5940ee1de9e19a123b613" + ], + "linux_arm64": [ + "go1.25.0.linux-arm64.tar.gz", + "05de75d6994a2783699815ee553bd5a9327d8b79991de36e38b66862782f54ae" + ], + "linux_armv6l": [ + "go1.25.0.linux-armv6l.tar.gz", + "a5a8f8198fcf00e1e485b8ecef9ee020778bf32a408a4e8873371bfce458cd09" + ], + "linux_loong64": [ + "go1.25.0.linux-loong64.tar.gz", + "cab86b1cf761b1cb3bac86a8877cfc92e7b036fc0d3084123d77013d61432afc" + ], + "linux_mips": [ + "go1.25.0.linux-mips.tar.gz", + "d66b6fb74c3d91b9829dc95ec10ca1f047ef5e89332152f92e136cf0e2da5be1" + ], + "linux_mips64": [ + "go1.25.0.linux-mips64.tar.gz", + "4082e4381a8661bc2a839ff94ba3daf4f6cde20f8fb771b5b3d4762dc84198a2" + ], + "linux_mips64le": [ + "go1.25.0.linux-mips64le.tar.gz", + "70002c299ec7f7175ac2ef673b1b347eecfa54ae11f34416a6053c17f855afcc" + ], + "linux_mipsle": [ + "go1.25.0.linux-mipsle.tar.gz", + "b00a3a39eff099f6df9f1c7355bf28e4589d0586f42d7d4a394efb763d145a73" + ], + "linux_ppc64": [ + "go1.25.0.linux-ppc64.tar.gz", + "df166f33bd98160662560a72ff0b4ba731f969a80f088922bddcf566a88c1ec1" + ], + "linux_ppc64le": [ + "go1.25.0.linux-ppc64le.tar.gz", + "0f18a89e7576cf2c5fa0b487a1635d9bcbf843df5f110e9982c64df52a983ad0" + ], + "linux_riscv64": [ + "go1.25.0.linux-riscv64.tar.gz", + "c018ff74a2c48d55c8ca9b07c8e24163558ffec8bea08b326d6336905d956b67" + ], + "linux_s390x": [ + "go1.25.0.linux-s390x.tar.gz", + "34e5a2e19f2292fbaf8783e3a241e6e49689276aef6510a8060ea5ef54eee408" + ], + "netbsd_386": [ + "go1.25.0.netbsd-386.tar.gz", + "f8586cdb7aa855657609a5c5f6dbf523efa00c2bbd7c76d3936bec80aa6c0aba" + ], + "netbsd_amd64": [ + "go1.25.0.netbsd-amd64.tar.gz", + "ae8dc1469385b86a157a423bb56304ba45730de8a897615874f57dd096db2c2a" + ], + "netbsd_arm": [ + "go1.25.0.netbsd-arm.tar.gz", + "1ff7e4cc764425fc9dd6825eaee79d02b3c7cafffbb3691687c8d672ade76cb7" + ], + "netbsd_arm64": [ + "go1.25.0.netbsd-arm64.tar.gz", + "e1b310739f26724216aa6d7d7208c4031f9ff54c9b5b9a796ddc8bebcb4a5f16" + ], + "openbsd_386": [ + "go1.25.0.openbsd-386.tar.gz", + "4802a9b20e533da91adb84aab42e94aa56cfe3e5475d0550bed3385b182e69d8" + ], + "openbsd_amd64": [ + "go1.25.0.openbsd-amd64.tar.gz", + "c016cd984bebe317b19a4f297c4f50def120dc9788490540c89f28e42f1dabe1" + ], + "openbsd_arm": [ + "go1.25.0.openbsd-arm.tar.gz", + "a1e31d0bf22172ddde42edf5ec811ef81be43433df0948ece52fecb247ccfd8d" + ], + "openbsd_arm64": [ + "go1.25.0.openbsd-arm64.tar.gz", + "343ea8edd8c218196e15a859c6072d0dd3246fbbb168481ab665eb4c4140458d" + ], + "openbsd_ppc64": [ + "go1.25.0.openbsd-ppc64.tar.gz", + "694c14da1bcaeb5e3332d49bdc2b6d155067648f8fe1540c5de8f3cf8e157154" + ], + "openbsd_riscv64": [ + "go1.25.0.openbsd-riscv64.tar.gz", + "aa510ad25cf54c06cd9c70b6d80ded69cb20188ac6e1735655eef29ff7e7885f" + ], + "plan9_386": [ + "go1.25.0.plan9-386.tar.gz", + "46f8cef02086cf04bf186c5912776b56535178d4cb319cd19c9fdbdd29231986" + ], + "plan9_amd64": [ + "go1.25.0.plan9-amd64.tar.gz", + "29b34391d84095e44608a228f63f2f88113a37b74a79781353ec043dfbcb427b" + ], + "plan9_arm": [ + "go1.25.0.plan9-arm.tar.gz", + "0a047107d13ebe7943aaa6d54b1d7bbd2e45e68ce449b52915a818da715799c2" + ], + "solaris_amd64": [ + "go1.25.0.solaris-amd64.tar.gz", + "9977f9e4351984364a3b2b78f8b88bfd1d339812356d5237678514594b7d3611" + ], + "windows_386": [ + "go1.25.0.windows-386.zip", + "df9f39db82a803af0db639e3613a36681ab7a42866b1384b3f3a1045663961a7" + ], + "windows_amd64": [ + "go1.25.0.windows-amd64.zip", + "89efb4f9b30812eee083cc1770fdd2913c14d301064f6454851428f9707d190b" + ], + "windows_arm64": [ + "go1.25.0.windows-arm64.zip", + "27bab004c72b3d7bd05a69b6ec0fc54a309b4b78cc569dd963d8b3ec28bfdb8c" + ] + } + } + }, + "factsVersions": {} +} diff --git a/src/libraries/java/nv-boot-parent/NOTICE b/src/libraries/java/nv-boot-parent/NOTICE index 400531af2..e56935131 100644 --- a/src/libraries/java/nv-boot-parent/NOTICE +++ b/src/libraries/java/nv-boot-parent/NOTICE @@ -1,5 +1,5 @@ -Lists of 208 third-party dependencies. +Lists of 209 third-party dependencies. (Public Domain) AOP alliance (aopalliance:aopalliance:1.0 - http://aopalliance.sourceforge.net) (Apache License, Version 2.0) LZ4 Java Compression (at.yawk.lz4:lz4-java:1.10.3 - https://github.com/yawkat/lz4-java) (EPL-2.0) (LGPL-2.1-only) Logback Classic Module (ch.qos.logback:logback-classic:1.5.34 - http://logback.qos.ch) @@ -24,11 +24,11 @@ Lists of 208 third-party dependencies. (MIT License) jnr-x86asm (com.github.jnr:jnr-x86asm:1.0.2 - http://github.com/jnr/jnr-x86asm) (Apache License, Version 2.0) JCIP Annotations under Apache License (com.github.stephenc.jcip:jcip-annotations:1.0-1 - http://stephenc.github.com/jcip-annotations) (The Apache Software License, Version 2.0) FindBugs-jsr305 (com.google.code.findbugs:jsr305:3.0.2 - http://findbugs.sourceforge.net/) - (Apache 2.0) error-prone annotations (com.google.errorprone:error_prone_annotations:2.49.0 - https://errorprone.info) - (Apache License, Version 2.0) Guava InternalFutureFailureAccess and InternalFutures (com.google.guava:failureaccess:1.0.3 - https://github.com/google/guava) - (Apache License, Version 2.0) Guava: Google Core Libraries for Java (com.google.guava:guava:33.6.0-jre - https://github.com/google/guava) + (Apache 2.0) error-prone annotations (com.google.errorprone:error_prone_annotations:2.5.1 - http://nexus.sonatype.org/oss-repository-hosting.html) + (The Apache Software License, Version 2.0) Guava InternalFutureFailureAccess and InternalFutures (com.google.guava:failureaccess:1.0.1 - https://github.com/google/guava) + (Apache License, Version 2.0) Guava: Google Core Libraries for Java (com.google.guava:guava:32.0.1-jre - https://github.com/google/guava) (The Apache Software License, Version 2.0) Guava ListenableFuture only (com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava - https://github.com/google/guava) - (Apache License, Version 2.0) J2ObjC Annotations (com.google.j2objc:j2objc-annotations:3.1 - https://github.com/google/j2objc/) + (Apache License, Version 2.0) J2ObjC Annotations (com.google.j2objc:j2objc-annotations:2.8 - https://github.com/google/j2objc/) (The Apache Software License, Version 2.0) Nimbus Content Type (com.nimbusds:content-type:2.3 - https://bitbucket.org/connect2id/nimbus-content-type) (The Apache Software License, Version 2.0) Nimbus LangTag (com.nimbusds:lang-tag:1.7 - https://bitbucket.org/connect2id/nimbus-language-tags) (The Apache Software License, Version 2.0) Nimbus JOSE+JWT (com.nimbusds:nimbus-jose-jwt:10.4 - https://bitbucket.org/connect2id/nimbus-jose-jwt) @@ -102,6 +102,7 @@ Lists of 208 third-party dependencies. (Apache License, Version 2.0) tomcat-embed-el (org.apache.tomcat.embed:tomcat-embed-el:11.0.22 - https://tomcat.apache.org/) (Bouncy Castle Licence) Bouncy Castle Provider (org.bouncycastle:bcprov-jdk18on:1.84 - https://www.bouncycastle.org/download/bouncy-castle-java/) (Bouncy Castle Licence) Bouncy Castle Provider (LTS Distribution) (org.bouncycastle:bcprov-lts8on:2.73.8 - https://www.bouncycastle.org/lts-java) + (The MIT License) Checker Qual (org.checkerframework:checker-qual:3.33.0 - https://checkerframework.org/) (Public Domain, per Creative Commons CC0) (BSD-2-Clause) HdrHistogram (org.hdrhistogram:HdrHistogram:2.2.2 - http://hdrhistogram.github.io/HdrHistogram/) (Apache License 2.0) Hibernate Validator Engine (org.hibernate.validator:hibernate-validator:9.0.1.Final - https://hibernate.org/validator) (Apache License 2.0) JBoss Logging 3 (org.jboss.logging:jboss-logging:3.6.3.Final - https://www.jboss.org) diff --git a/src/libraries/java/nv-boot-parent/maven_install.json b/src/libraries/java/nv-boot-parent/maven_install.json new file mode 100644 index 000000000..182e542e3 --- /dev/null +++ b/src/libraries/java/nv-boot-parent/maven_install.json @@ -0,0 +1,10215 @@ +{ + "__AUTOGENERATED_FILE_DO_NOT_MODIFY_THIS_FILE_MANUALLY": "THERE_IS_NO_DATA_ONLY_ZUUL", + "__INPUT_ARTIFACTS_HASH": { + "at.yawk.lz4:lz4-java": 1725015399, + "com.github.ben-manes.caffeine:guava": 1054685015, + "com.github.java-json-tools:json-patch": -1031005245, + "com.google.code.findbugs:jsr305": 495355163, + "com.google.code.gson:gson": 597770368, + "com.google.errorprone:error_prone_annotations": -1035138750, + "com.google.guava:guava": 1943808618, + "com.google.j2objc:j2objc-annotations": 2003271689, + "commons-codec:commons-codec": -1269462382, + "io.cloudevents:cloudevents-core": -2103567774, + "io.cloudevents:cloudevents-json-jackson": -1197487309, + "io.micrometer:micrometer-tracing-bridge-otel": -754588172, + "io.nats:jnats": 572014237, + "io.opentelemetry:opentelemetry-exporter-otlp": -12806658, + "io.opentelemetry:opentelemetry-sdk-testing": -32635354, + "jakarta.servlet:jakarta.servlet-api": 2120044853, + "net.javacrumbs.shedlock:shedlock-bom": -1406345450, + "org.apache.cassandra:java-driver-metrics-micrometer": -465267397, + "org.apache.commons:commons-lang3": -278168457, + "org.assertj:assertj-core": 1863574844, + "org.awaitility:awaitility": -1630939750, + "org.bouncycastle:bcprov-jdk18on": -1405390253, + "org.jacoco:org.jacoco.agent": -2069397525, + "org.jacoco:org.jacoco.cli": -1856875155, + "org.junit.jupiter:junit-jupiter-api": 194920406, + "org.junit.jupiter:junit-jupiter-engine": -1886863302, + "org.junit.jupiter:junit-jupiter-params": 1082310006, + "org.junit.platform:junit-platform-console-standalone": -1481831078, + "org.junit.platform:junit-platform-launcher": -354104948, + "org.junit.platform:junit-platform-reporting": 1896713402, + "org.mockito:mockito-core": -554630660, + "org.mockito:mockito-junit-jupiter": -1104541639, + "org.ow2.asm:asm-analysis": -1027574299, + "org.ow2.asm:asm-util": -307204853, + "org.projectlombok:lombok": -2073039513, + "org.springdoc:springdoc-openapi-starter-webflux-api": 1102747448, + "org.springdoc:springdoc-openapi-starter-webmvc-api": 655186513, + "org.springframework.boot:spring-boot-dependencies": 70164638, + "org.springframework.boot:spring-boot-micrometer-tracing-opentelemetry": 238152322, + "org.springframework.boot:spring-boot-restclient": 525086533, + "org.springframework.boot:spring-boot-starter": 1358725161, + "org.springframework.boot:spring-boot-starter-actuator": -1082017891, + "org.springframework.boot:spring-boot-starter-actuator-test": 536870722, + "org.springframework.boot:spring-boot-starter-data-cassandra": 699136521, + "org.springframework.boot:spring-boot-starter-data-cassandra-test": -667262890, + "org.springframework.boot:spring-boot-starter-jackson": -1899095121, + "org.springframework.boot:spring-boot-starter-security-oauth2-client": -1248590284, + "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server": 185843737, + "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server-test": -1173625786, + "org.springframework.boot:spring-boot-starter-test": -1561809354, + "org.springframework.boot:spring-boot-starter-validation": 113118493, + "org.springframework.boot:spring-boot-starter-webflux": 1788530073, + "org.springframework.boot:spring-boot-starter-webflux-test": 5326534, + "org.springframework.boot:spring-boot-starter-webmvc-test": -2111356331, + "org.springframework.boot:spring-boot-webclient": -1835278023, + "org.springframework.cloud:spring-cloud-commons": -673836000, + "org.springframework.cloud:spring-cloud-context": -1724959431, + "org.springframework.cloud:spring-cloud-dependencies": 46341733, + "org.springframework.cloud:spring-cloud-starter-bootstrap": -213001704, + "org.springframework.security:spring-security-test": 1317137564, + "org.testcontainers:testcontainers-bom": 483223872, + "org.testcontainers:testcontainers-cassandra": -1027104267, + "org.testcontainers:testcontainers-junit-jupiter": -918230293, + "org.wiremock:wiremock-standalone": -1242936487, + "repositories": -1624298853, + "software.amazon.awssdk:regions": -1274787064, + "tools.jackson.module:jackson-module-blackbird": -423541381 + }, + "__RESOLVED_ARTIFACTS_HASH": { + "aopalliance:aopalliance": -1763688673, + "aopalliance:aopalliance:jar:sources": 758113234, + "args4j:args4j": -572028113, + "args4j:args4j:jar:sources": 74047526, + "at.yawk.lz4:lz4-java": -1985362494, + "at.yawk.lz4:lz4-java:jar:sources": -2141970549, + "ch.qos.logback:logback-classic": -619930806, + "ch.qos.logback:logback-classic:jar:sources": -390128445, + "ch.qos.logback:logback-core": -1554021729, + "ch.qos.logback:logback-core:jar:sources": 77538609, + "com.datastax.cassandra:cassandra-driver-core": 197829386, + "com.datastax.cassandra:cassandra-driver-core:jar:sources": -2045236197, + "com.datastax.oss:native-protocol": 447263174, + "com.datastax.oss:native-protocol:jar:sources": 396473389, + "com.fasterxml.jackson.core:jackson-annotations": 1407322119, + "com.fasterxml.jackson.core:jackson-annotations:jar:sources": -1408285999, + "com.fasterxml.jackson.core:jackson-core": -1715692416, + "com.fasterxml.jackson.core:jackson-core:jar:sources": 1404881423, + "com.fasterxml.jackson.core:jackson-databind": -1922910990, + "com.fasterxml.jackson.core:jackson-databind:jar:sources": -802304801, + "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml": 2129087476, + "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:jar:sources": -175522790, + "com.fasterxml.jackson.datatype:jackson-datatype-jsr310": 1940996847, + "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:jar:sources": 1241536710, + "com.fasterxml:classmate": -1468141616, + "com.fasterxml:classmate:jar:sources": -179492269, + "com.github.ben-manes.caffeine:caffeine": 1925806502, + "com.github.ben-manes.caffeine:caffeine:jar:sources": -967473790, + "com.github.ben-manes.caffeine:guava": 2074933175, + "com.github.ben-manes.caffeine:guava:jar:sources": 1956210603, + "com.github.docker-java:docker-java-api": 1857041788, + "com.github.docker-java:docker-java-api:jar:sources": 300128277, + "com.github.docker-java:docker-java-transport": 689281477, + "com.github.docker-java:docker-java-transport-zerodep": -1848983763, + "com.github.docker-java:docker-java-transport-zerodep:jar:sources": 1882881505, + "com.github.docker-java:docker-java-transport:jar:sources": 864522470, + "com.github.java-json-tools:btf": 204024567, + "com.github.java-json-tools:btf:jar:sources": 1539011915, + "com.github.java-json-tools:jackson-coreutils": 1585779168, + "com.github.java-json-tools:jackson-coreutils:jar:sources": 323093438, + "com.github.java-json-tools:json-patch": 388171991, + "com.github.java-json-tools:json-patch:jar:sources": -1320375757, + "com.github.java-json-tools:msg-simple": -285204120, + "com.github.java-json-tools:msg-simple:jar:sources": 1013495835, + "com.github.jnr:jffi": 1952487985, + "com.github.jnr:jffi:jar:native": 1426144838, + "com.github.jnr:jffi:jar:sources": -252446498, + "com.github.jnr:jnr-constants": 1522135714, + "com.github.jnr:jnr-constants:jar:sources": -1920781516, + "com.github.jnr:jnr-ffi": 1663045836, + "com.github.jnr:jnr-ffi:jar:sources": -150631029, + "com.github.jnr:jnr-posix": 1594911544, + "com.github.jnr:jnr-posix:jar:sources": -992203730, + "com.github.jnr:jnr-x86asm": 1097235222, + "com.github.jnr:jnr-x86asm:jar:sources": -1784079536, + "com.github.stephenc.jcip:jcip-annotations": -121928928, + "com.github.stephenc.jcip:jcip-annotations:jar:sources": -2051941468, + "com.google.code.findbugs:jsr305": -1038659426, + "com.google.code.findbugs:jsr305:jar:sources": -1300148931, + "com.google.code.gson:gson": 1618556651, + "com.google.code.gson:gson:jar:sources": 389178860, + "com.google.errorprone:error_prone_annotations": 492382488, + "com.google.errorprone:error_prone_annotations:jar:sources": 456515251, + "com.google.guava:failureaccess": -268223546, + "com.google.guava:failureaccess:jar:sources": 2053502918, + "com.google.guava:guava": 1240305771, + "com.google.guava:guava:jar:sources": 1591586943, + "com.google.guava:listenablefuture": 1588902908, + "com.google.j2objc:j2objc-annotations": -596695707, + "com.google.j2objc:j2objc-annotations:jar:sources": 900785715, + "com.jayway.jsonpath:json-path": 626712679, + "com.jayway.jsonpath:json-path:jar:sources": -343427302, + "com.nimbusds:content-type": -444977683, + "com.nimbusds:content-type:jar:sources": -634646164, + "com.nimbusds:lang-tag": -694347345, + "com.nimbusds:lang-tag:jar:sources": 266930896, + "com.nimbusds:nimbus-jose-jwt": -286981492, + "com.nimbusds:nimbus-jose-jwt:jar:sources": 24935039, + "com.nimbusds:oauth2-oidc-sdk": -498816278, + "com.nimbusds:oauth2-oidc-sdk:jar:sources": 1276926642, + "com.squareup.okhttp3:okhttp-jvm": -314031254, + "com.squareup.okhttp3:okhttp-jvm:jar:sources": 447067750, + "com.squareup.okio:okio-jvm": -391120506, + "com.squareup.okio:okio-jvm:jar:sources": 1375453359, + "com.typesafe:config": 96906638, + "com.typesafe:config:jar:sources": -892423283, + "com.vaadin.external.google:android-json": -1531950165, + "com.vaadin.external.google:android-json:jar:sources": -116078240, + "commons-codec:commons-codec": -835030550, + "commons-codec:commons-codec:jar:sources": 990790236, + "commons-io:commons-io": -1021273518, + "commons-io:commons-io:jar:sources": 2066085027, + "commons-logging:commons-logging": 1061992981, + "commons-logging:commons-logging:jar:sources": 1867783947, + "io.cloudevents:cloudevents-api": -617548735, + "io.cloudevents:cloudevents-api:jar:sources": 924762007, + "io.cloudevents:cloudevents-core": -688560325, + "io.cloudevents:cloudevents-core:jar:sources": 223693387, + "io.cloudevents:cloudevents-json-jackson": -807987873, + "io.cloudevents:cloudevents-json-jackson:jar:sources": -166751855, + "io.dropwizard.metrics:metrics-core": 1029463962, + "io.dropwizard.metrics:metrics-core:jar:sources": 1607397396, + "io.micrometer:context-propagation": -1130727419, + "io.micrometer:context-propagation:jar:sources": -1135393170, + "io.micrometer:micrometer-commons": 326693391, + "io.micrometer:micrometer-commons:jar:sources": -57818626, + "io.micrometer:micrometer-core": 829567043, + "io.micrometer:micrometer-core:jar:sources": 265175165, + "io.micrometer:micrometer-jakarta9": -15933884, + "io.micrometer:micrometer-jakarta9:jar:sources": 1275065742, + "io.micrometer:micrometer-observation": -319705914, + "io.micrometer:micrometer-observation-test": -1818068529, + "io.micrometer:micrometer-observation-test:jar:sources": 117373145, + "io.micrometer:micrometer-observation:jar:sources": 1279306785, + "io.micrometer:micrometer-tracing": -109714346, + "io.micrometer:micrometer-tracing-bridge-otel": 975863312, + "io.micrometer:micrometer-tracing-bridge-otel:jar:sources": 1300289348, + "io.micrometer:micrometer-tracing:jar:sources": 266031561, + "io.nats:jnats": 1273546329, + "io.nats:jnats:jar:sources": 194791155, + "io.netty:netty-buffer": -1740802869, + "io.netty:netty-buffer:jar:sources": 622468392, + "io.netty:netty-codec-base": -1042304993, + "io.netty:netty-codec-base:jar:sources": -612797714, + "io.netty:netty-codec-classes-quic": -702276906, + "io.netty:netty-codec-classes-quic:jar:sources": 1548159851, + "io.netty:netty-codec-compression": -789209831, + "io.netty:netty-codec-compression:jar:sources": -1402960067, + "io.netty:netty-codec-dns": 81169397, + "io.netty:netty-codec-dns:jar:sources": -1086447458, + "io.netty:netty-codec-http": -95764323, + "io.netty:netty-codec-http2": 544878123, + "io.netty:netty-codec-http2:jar:sources": -83820759, + "io.netty:netty-codec-http3": -194972071, + "io.netty:netty-codec-http3:jar:sources": 1699772273, + "io.netty:netty-codec-http:jar:sources": -116842177, + "io.netty:netty-codec-native-quic:jar:linux-aarch_64": -2075260519, + "io.netty:netty-codec-native-quic:jar:linux-x86_64": -1982796133, + "io.netty:netty-codec-native-quic:jar:osx-aarch_64": -632727283, + "io.netty:netty-codec-native-quic:jar:osx-x86_64": 1253945631, + "io.netty:netty-codec-native-quic:jar:sources": -986328940, + "io.netty:netty-codec-native-quic:jar:windows-x86_64": -115110822, + "io.netty:netty-codec-socks": 336734625, + "io.netty:netty-codec-socks:jar:sources": -1241946572, + "io.netty:netty-common": -1557278455, + "io.netty:netty-common:jar:sources": -467395659, + "io.netty:netty-handler": -1757690436, + "io.netty:netty-handler-proxy": -892232184, + "io.netty:netty-handler-proxy:jar:sources": -216040607, + "io.netty:netty-handler:jar:sources": -1379156289, + "io.netty:netty-resolver": -1571627366, + "io.netty:netty-resolver-dns": 954988644, + "io.netty:netty-resolver-dns-classes-macos": -441663783, + "io.netty:netty-resolver-dns-classes-macos:jar:sources": 776580055, + "io.netty:netty-resolver-dns-native-macos:jar:osx-x86_64": -354533951, + "io.netty:netty-resolver-dns-native-macos:jar:sources": -120739665, + "io.netty:netty-resolver-dns:jar:sources": 1652413066, + "io.netty:netty-resolver:jar:sources": 2084403340, + "io.netty:netty-transport": 44555455, + "io.netty:netty-transport-classes-epoll": -588470325, + "io.netty:netty-transport-classes-epoll:jar:sources": -1697662320, + "io.netty:netty-transport-native-epoll:jar:linux-x86_64": -563523863, + "io.netty:netty-transport-native-epoll:jar:sources": -1040259378, + "io.netty:netty-transport-native-unix-common": -166041147, + "io.netty:netty-transport-native-unix-common:jar:sources": -1674017507, + "io.netty:netty-transport:jar:sources": -820889350, + "io.opentelemetry.semconv:opentelemetry-semconv": 1195624836, + "io.opentelemetry.semconv:opentelemetry-semconv:jar:sources": -893534237, + "io.opentelemetry:opentelemetry-api": 885391408, + "io.opentelemetry:opentelemetry-api:jar:sources": -1404426315, + "io.opentelemetry:opentelemetry-common": 676580228, + "io.opentelemetry:opentelemetry-common:jar:sources": 1797051654, + "io.opentelemetry:opentelemetry-context": 747746024, + "io.opentelemetry:opentelemetry-context:jar:sources": 560193252, + "io.opentelemetry:opentelemetry-exporter-common": 42591217, + "io.opentelemetry:opentelemetry-exporter-common:jar:sources": 2032641450, + "io.opentelemetry:opentelemetry-exporter-otlp": 1346623356, + "io.opentelemetry:opentelemetry-exporter-otlp-common": -2043450521, + "io.opentelemetry:opentelemetry-exporter-otlp-common:jar:sources": -1909225648, + "io.opentelemetry:opentelemetry-exporter-otlp:jar:sources": -1536215787, + "io.opentelemetry:opentelemetry-exporter-sender-okhttp": -2026614746, + "io.opentelemetry:opentelemetry-exporter-sender-okhttp:jar:sources": -1387239258, + "io.opentelemetry:opentelemetry-extension-trace-propagators": -480191373, + "io.opentelemetry:opentelemetry-extension-trace-propagators:jar:sources": 517135536, + "io.opentelemetry:opentelemetry-sdk": -369820209, + "io.opentelemetry:opentelemetry-sdk-common": -1049102876, + "io.opentelemetry:opentelemetry-sdk-common:jar:sources": -1004050981, + "io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi": -928104061, + "io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi:jar:sources": -1626691242, + "io.opentelemetry:opentelemetry-sdk-logs": -1310291573, + "io.opentelemetry:opentelemetry-sdk-logs:jar:sources": 1572252989, + "io.opentelemetry:opentelemetry-sdk-metrics": -2038069517, + "io.opentelemetry:opentelemetry-sdk-metrics:jar:sources": -323022280, + "io.opentelemetry:opentelemetry-sdk-testing": 19519171, + "io.opentelemetry:opentelemetry-sdk-testing:jar:sources": -578292790, + "io.opentelemetry:opentelemetry-sdk-trace": 2083919234, + "io.opentelemetry:opentelemetry-sdk-trace:jar:sources": 818630467, + "io.opentelemetry:opentelemetry-sdk:jar:sources": -1478160490, + "io.projectreactor.netty:reactor-netty-core": -1310988391, + "io.projectreactor.netty:reactor-netty-core:jar:sources": 160926198, + "io.projectreactor.netty:reactor-netty-http": -1289714469, + "io.projectreactor.netty:reactor-netty-http:jar:sources": 1066415166, + "io.projectreactor:reactor-core": -745004757, + "io.projectreactor:reactor-core:jar:sources": -717353230, + "io.projectreactor:reactor-test": 947112823, + "io.projectreactor:reactor-test:jar:sources": 383025302, + "io.swagger.core.v3:swagger-annotations-jakarta": -842428034, + "io.swagger.core.v3:swagger-annotations-jakarta:jar:sources": 133934665, + "io.swagger.core.v3:swagger-core-jakarta": -439612282, + "io.swagger.core.v3:swagger-core-jakarta:jar:sources": 449241668, + "io.swagger.core.v3:swagger-models-jakarta": -1439553498, + "io.swagger.core.v3:swagger-models-jakarta:jar:sources": 2092063988, + "jakarta.activation:jakarta.activation-api": -1560267684, + "jakarta.activation:jakarta.activation-api:jar:sources": 759160467, + "jakarta.annotation:jakarta.annotation-api": -1904975463, + "jakarta.annotation:jakarta.annotation-api:jar:sources": -247204066, + "jakarta.servlet:jakarta.servlet-api": 972614879, + "jakarta.servlet:jakarta.servlet-api:jar:sources": 2070183472, + "jakarta.validation:jakarta.validation-api": 666686261, + "jakarta.validation:jakarta.validation-api:jar:sources": -131796339, + "jakarta.xml.bind:jakarta.xml.bind-api": 1157993223, + "jakarta.xml.bind:jakarta.xml.bind-api:jar:sources": -945798747, + "net.bytebuddy:byte-buddy": 383637760, + "net.bytebuddy:byte-buddy-agent": -1380713096, + "net.bytebuddy:byte-buddy-agent:jar:sources": 564051985, + "net.bytebuddy:byte-buddy:jar:sources": -1360611642, + "net.java.dev.jna:jna": -1951542637, + "net.java.dev.jna:jna:jar:sources": -545183654, + "net.minidev:accessors-smart": -325667575, + "net.minidev:accessors-smart:jar:sources": -124254155, + "net.minidev:json-smart": 1673421716, + "net.minidev:json-smart:jar:sources": -1084786431, + "org.apache.cassandra:java-driver-core": 42196324, + "org.apache.cassandra:java-driver-core:jar:sources": -1508814165, + "org.apache.cassandra:java-driver-guava-shaded": 568990261, + "org.apache.cassandra:java-driver-guava-shaded:jar:sources": 1291502230, + "org.apache.cassandra:java-driver-metrics-micrometer": -93817708, + "org.apache.cassandra:java-driver-metrics-micrometer:jar:sources": -2019023443, + "org.apache.cassandra:java-driver-query-builder": 303143232, + "org.apache.cassandra:java-driver-query-builder:jar:sources": -1665027563, + "org.apache.commons:commons-compress": -134181577, + "org.apache.commons:commons-compress:jar:sources": -1845261624, + "org.apache.commons:commons-lang3": 759645435, + "org.apache.commons:commons-lang3:jar:sources": 1890991939, + "org.apache.logging.log4j:log4j-api": 191755139, + "org.apache.logging.log4j:log4j-api:jar:sources": 1226633672, + "org.apache.logging.log4j:log4j-to-slf4j": 357996538, + "org.apache.logging.log4j:log4j-to-slf4j:jar:sources": -1847454236, + "org.apache.tomcat.embed:tomcat-embed-core": -2079786590, + "org.apache.tomcat.embed:tomcat-embed-core:jar:sources": -745705587, + "org.apache.tomcat.embed:tomcat-embed-el": -727131551, + "org.apache.tomcat.embed:tomcat-embed-el:jar:sources": 1938415424, + "org.apache.tomcat.embed:tomcat-embed-websocket": 1876889190, + "org.apache.tomcat.embed:tomcat-embed-websocket:jar:sources": -1809736441, + "org.apiguardian:apiguardian-api": -1579303244, + "org.apiguardian:apiguardian-api:jar:sources": 768152577, + "org.assertj:assertj-core": -536770136, + "org.assertj:assertj-core:jar:sources": -1826278818, + "org.awaitility:awaitility": 755971515, + "org.awaitility:awaitility:jar:sources": -1322650242, + "org.bouncycastle:bcprov-jdk18on": -709136978, + "org.bouncycastle:bcprov-jdk18on:jar:sources": 106463766, + "org.bouncycastle:bcprov-lts8on": 973431866, + "org.bouncycastle:bcprov-lts8on:jar:sources": -196135755, + "org.checkerframework:checker-qual": -2018582244, + "org.checkerframework:checker-qual:jar:sources": 2110417205, + "org.hamcrest:hamcrest": 1116842741, + "org.hamcrest:hamcrest:jar:sources": -996443755, + "org.hdrhistogram:HdrHistogram": 1379183334, + "org.hdrhistogram:HdrHistogram:jar:sources": -1235434218, + "org.hibernate.validator:hibernate-validator": 1976561513, + "org.hibernate.validator:hibernate-validator:jar:sources": 367698734, + "org.jacoco:org.jacoco.agent:jar:runtime": -111724801, + "org.jacoco:org.jacoco.agent:jar:sources": 1432778515, + "org.jacoco:org.jacoco.cli": 2021870981, + "org.jacoco:org.jacoco.cli:jar:sources": 47843733, + "org.jacoco:org.jacoco.core": 579589309, + "org.jacoco:org.jacoco.core:jar:sources": -458393909, + "org.jacoco:org.jacoco.report": -1287135579, + "org.jacoco:org.jacoco.report:jar:sources": -2068401168, + "org.jboss.logging:jboss-logging": -2136063667, + "org.jboss.logging:jboss-logging:jar:sources": 2066441551, + "org.jetbrains.kotlin:kotlin-stdlib": -570435334, + "org.jetbrains.kotlin:kotlin-stdlib:jar:sources": 1404576391, + "org.jetbrains:annotations": 643765179, + "org.jetbrains:annotations:jar:sources": 1009912224, + "org.jspecify:jspecify": -1402924792, + "org.jspecify:jspecify:jar:sources": -841008091, + "org.junit.jupiter:junit-jupiter": -313198921, + "org.junit.jupiter:junit-jupiter-api": 80944698, + "org.junit.jupiter:junit-jupiter-api:jar:sources": -1650654944, + "org.junit.jupiter:junit-jupiter-engine": 730848020, + "org.junit.jupiter:junit-jupiter-engine:jar:sources": 1805473715, + "org.junit.jupiter:junit-jupiter-params": -1923494954, + "org.junit.jupiter:junit-jupiter-params:jar:sources": 1561682205, + "org.junit.jupiter:junit-jupiter:jar:sources": 1809716175, + "org.junit.platform:junit-platform-commons": -1304725543, + "org.junit.platform:junit-platform-commons:jar:sources": -139331649, + "org.junit.platform:junit-platform-console-standalone": -406221538, + "org.junit.platform:junit-platform-console-standalone:jar:sources": -103511349, + "org.junit.platform:junit-platform-engine": -748595950, + "org.junit.platform:junit-platform-engine:jar:sources": -191078126, + "org.junit.platform:junit-platform-launcher": 1722101087, + "org.junit.platform:junit-platform-launcher:jar:sources": -717285440, + "org.junit.platform:junit-platform-reporting": 1847654060, + "org.junit.platform:junit-platform-reporting:jar:sources": -1771745730, + "org.latencyutils:LatencyUtils": 1082471286, + "org.latencyutils:LatencyUtils:jar:sources": 1894864087, + "org.mockito:mockito-core": 734095861, + "org.mockito:mockito-core:jar:sources": 1757924088, + "org.mockito:mockito-junit-jupiter": -501680015, + "org.mockito:mockito-junit-jupiter:jar:sources": -1281757309, + "org.objenesis:objenesis": 1083875484, + "org.objenesis:objenesis:jar:sources": 703772823, + "org.opentest4j.reporting:open-test-reporting-tooling-spi": -1639379357, + "org.opentest4j.reporting:open-test-reporting-tooling-spi:jar:sources": 1632689314, + "org.opentest4j:opentest4j": 793813175, + "org.opentest4j:opentest4j:jar:sources": 1210936723, + "org.ow2.asm:asm": 716467505, + "org.ow2.asm:asm-analysis": 129370658, + "org.ow2.asm:asm-analysis:jar:sources": -2126326860, + "org.ow2.asm:asm-commons": 530868933, + "org.ow2.asm:asm-commons:jar:sources": 1248498766, + "org.ow2.asm:asm-tree": 369430530, + "org.ow2.asm:asm-tree:jar:sources": -1850601298, + "org.ow2.asm:asm-util": -803635337, + "org.ow2.asm:asm-util:jar:sources": 51483494, + "org.ow2.asm:asm:jar:sources": -947428423, + "org.projectlombok:lombok": -1095750717, + "org.projectlombok:lombok:jar:sources": 1834083797, + "org.reactivestreams:reactive-streams": -1996658890, + "org.reactivestreams:reactive-streams:jar:sources": -258070571, + "org.rnorth.duct-tape:duct-tape": 615461963, + "org.rnorth.duct-tape:duct-tape:jar:sources": 427419407, + "org.skyscreamer:jsonassert": -1571197746, + "org.skyscreamer:jsonassert:jar:sources": -392658057, + "org.slf4j:jul-to-slf4j": -911724984, + "org.slf4j:jul-to-slf4j:jar:sources": -662175280, + "org.slf4j:slf4j-api": -1249720338, + "org.slf4j:slf4j-api:jar:sources": -297247278, + "org.springdoc:springdoc-openapi-starter-common": -50810541, + "org.springdoc:springdoc-openapi-starter-common:jar:sources": 776689800, + "org.springdoc:springdoc-openapi-starter-webflux-api": -2128144311, + "org.springdoc:springdoc-openapi-starter-webflux-api:jar:sources": -1775632648, + "org.springdoc:springdoc-openapi-starter-webmvc-api": 479427887, + "org.springdoc:springdoc-openapi-starter-webmvc-api:jar:sources": -1201450538, + "org.springframework.boot:spring-boot": -1519545366, + "org.springframework.boot:spring-boot-actuator": 1868004981, + "org.springframework.boot:spring-boot-actuator-autoconfigure": 437017470, + "org.springframework.boot:spring-boot-actuator-autoconfigure:jar:sources": 1090885133, + "org.springframework.boot:spring-boot-actuator:jar:sources": 1545596535, + "org.springframework.boot:spring-boot-autoconfigure": -491644458, + "org.springframework.boot:spring-boot-autoconfigure:jar:sources": 562322138, + "org.springframework.boot:spring-boot-cassandra": 1880514148, + "org.springframework.boot:spring-boot-cassandra:jar:sources": -285158244, + "org.springframework.boot:spring-boot-data-cassandra": -1136414714, + "org.springframework.boot:spring-boot-data-cassandra-test": 1687171774, + "org.springframework.boot:spring-boot-data-cassandra-test:jar:sources": -601584645, + "org.springframework.boot:spring-boot-data-cassandra:jar:sources": 73983427, + "org.springframework.boot:spring-boot-data-commons": 1096447250, + "org.springframework.boot:spring-boot-data-commons:jar:sources": 867332098, + "org.springframework.boot:spring-boot-health": 988376788, + "org.springframework.boot:spring-boot-health:jar:sources": 1156692002, + "org.springframework.boot:spring-boot-http-client": -294534102, + "org.springframework.boot:spring-boot-http-client:jar:sources": 881974750, + "org.springframework.boot:spring-boot-http-codec": 434302862, + "org.springframework.boot:spring-boot-http-codec:jar:sources": 585983495, + "org.springframework.boot:spring-boot-http-converter": -1456188332, + "org.springframework.boot:spring-boot-http-converter:jar:sources": 678862764, + "org.springframework.boot:spring-boot-jackson": -886310726, + "org.springframework.boot:spring-boot-jackson:jar:sources": -928970153, + "org.springframework.boot:spring-boot-micrometer-metrics": -971815116, + "org.springframework.boot:spring-boot-micrometer-metrics-test": 1059861465, + "org.springframework.boot:spring-boot-micrometer-metrics-test:jar:sources": 539702709, + "org.springframework.boot:spring-boot-micrometer-metrics:jar:sources": -1326033951, + "org.springframework.boot:spring-boot-micrometer-observation": -515345138, + "org.springframework.boot:spring-boot-micrometer-observation:jar:sources": -1374159176, + "org.springframework.boot:spring-boot-micrometer-tracing": -1769177987, + "org.springframework.boot:spring-boot-micrometer-tracing-opentelemetry": 686601187, + "org.springframework.boot:spring-boot-micrometer-tracing-opentelemetry:jar:sources": 2058843242, + "org.springframework.boot:spring-boot-micrometer-tracing:jar:sources": -531678236, + "org.springframework.boot:spring-boot-netty": -1868279944, + "org.springframework.boot:spring-boot-netty:jar:sources": 2079852054, + "org.springframework.boot:spring-boot-opentelemetry": -1423093456, + "org.springframework.boot:spring-boot-opentelemetry:jar:sources": 1840051882, + "org.springframework.boot:spring-boot-persistence": -1485790991, + "org.springframework.boot:spring-boot-persistence:jar:sources": -1027448649, + "org.springframework.boot:spring-boot-reactor": 1298372962, + "org.springframework.boot:spring-boot-reactor-netty": 1434335970, + "org.springframework.boot:spring-boot-reactor-netty:jar:sources": -732886702, + "org.springframework.boot:spring-boot-reactor:jar:sources": -1373689055, + "org.springframework.boot:spring-boot-restclient": -67067992, + "org.springframework.boot:spring-boot-restclient:jar:sources": -1554622109, + "org.springframework.boot:spring-boot-resttestclient": 1078416021, + "org.springframework.boot:spring-boot-resttestclient:jar:sources": 1128597445, + "org.springframework.boot:spring-boot-security": -528218864, + "org.springframework.boot:spring-boot-security-oauth2-client": 1972725629, + "org.springframework.boot:spring-boot-security-oauth2-client:jar:sources": -1211778370, + "org.springframework.boot:spring-boot-security-oauth2-resource-server": -1021125134, + "org.springframework.boot:spring-boot-security-oauth2-resource-server:jar:sources": 1301519418, + "org.springframework.boot:spring-boot-security-test": -1810341741, + "org.springframework.boot:spring-boot-security-test:jar:sources": -311791400, + "org.springframework.boot:spring-boot-security:jar:sources": -1644906067, + "org.springframework.boot:spring-boot-servlet": -1040246830, + "org.springframework.boot:spring-boot-servlet:jar:sources": 1162002660, + "org.springframework.boot:spring-boot-starter": 191814674, + "org.springframework.boot:spring-boot-starter-actuator": 1761935967, + "org.springframework.boot:spring-boot-starter-actuator-test": 910069034, + "org.springframework.boot:spring-boot-starter-actuator-test:jar:sources": 314973026, + "org.springframework.boot:spring-boot-starter-actuator:jar:sources": -2079433447, + "org.springframework.boot:spring-boot-starter-data-cassandra": -1305411192, + "org.springframework.boot:spring-boot-starter-data-cassandra-test": 1049224325, + "org.springframework.boot:spring-boot-starter-data-cassandra-test:jar:sources": 464889083, + "org.springframework.boot:spring-boot-starter-data-cassandra:jar:sources": 62860247, + "org.springframework.boot:spring-boot-starter-jackson": 211326145, + "org.springframework.boot:spring-boot-starter-jackson-test": 538761659, + "org.springframework.boot:spring-boot-starter-jackson-test:jar:sources": 1211585483, + "org.springframework.boot:spring-boot-starter-jackson:jar:sources": 1689728463, + "org.springframework.boot:spring-boot-starter-logging": 51215582, + "org.springframework.boot:spring-boot-starter-logging:jar:sources": 1271111015, + "org.springframework.boot:spring-boot-starter-micrometer-metrics": 546085162, + "org.springframework.boot:spring-boot-starter-micrometer-metrics-test": -835747019, + "org.springframework.boot:spring-boot-starter-micrometer-metrics-test:jar:sources": 1830581000, + "org.springframework.boot:spring-boot-starter-micrometer-metrics:jar:sources": -1130818080, + "org.springframework.boot:spring-boot-starter-reactor-netty": 812139334, + "org.springframework.boot:spring-boot-starter-reactor-netty:jar:sources": 1164956430, + "org.springframework.boot:spring-boot-starter-security": 1058973423, + "org.springframework.boot:spring-boot-starter-security-oauth2-client": -1355057519, + "org.springframework.boot:spring-boot-starter-security-oauth2-client:jar:sources": 1707609356, + "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server": -265511875, + "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server-test": -17384836, + "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server-test:jar:sources": -746940353, + "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server:jar:sources": 2136275088, + "org.springframework.boot:spring-boot-starter-security-test": 1690721902, + "org.springframework.boot:spring-boot-starter-security-test:jar:sources": 468207576, + "org.springframework.boot:spring-boot-starter-security:jar:sources": -1720617031, + "org.springframework.boot:spring-boot-starter-test": -1087542039, + "org.springframework.boot:spring-boot-starter-test:jar:sources": -480189945, + "org.springframework.boot:spring-boot-starter-tomcat": -521361670, + "org.springframework.boot:spring-boot-starter-tomcat-runtime": -1912812722, + "org.springframework.boot:spring-boot-starter-tomcat-runtime:jar:sources": 1011838045, + "org.springframework.boot:spring-boot-starter-tomcat:jar:sources": 1319064174, + "org.springframework.boot:spring-boot-starter-validation": -321633530, + "org.springframework.boot:spring-boot-starter-validation:jar:sources": -1002865328, + "org.springframework.boot:spring-boot-starter-webflux": -818164168, + "org.springframework.boot:spring-boot-starter-webflux-test": -415179163, + "org.springframework.boot:spring-boot-starter-webflux-test:jar:sources": -1654084055, + "org.springframework.boot:spring-boot-starter-webflux:jar:sources": 1008425882, + "org.springframework.boot:spring-boot-starter-webmvc": 170962824, + "org.springframework.boot:spring-boot-starter-webmvc-test": -1343848488, + "org.springframework.boot:spring-boot-starter-webmvc-test:jar:sources": -1751111514, + "org.springframework.boot:spring-boot-starter-webmvc:jar:sources": -2120956724, + "org.springframework.boot:spring-boot-starter:jar:sources": 1138639700, + "org.springframework.boot:spring-boot-test": -927444958, + "org.springframework.boot:spring-boot-test-autoconfigure": -669950838, + "org.springframework.boot:spring-boot-test-autoconfigure:jar:sources": 392165449, + "org.springframework.boot:spring-boot-test:jar:sources": -1764708648, + "org.springframework.boot:spring-boot-tomcat": -1113349252, + "org.springframework.boot:spring-boot-tomcat:jar:sources": -1529683395, + "org.springframework.boot:spring-boot-validation": 1270368638, + "org.springframework.boot:spring-boot-validation:jar:sources": -1684576067, + "org.springframework.boot:spring-boot-web-server": 285708094, + "org.springframework.boot:spring-boot-web-server:jar:sources": 990724443, + "org.springframework.boot:spring-boot-webclient": -507647, + "org.springframework.boot:spring-boot-webclient:jar:sources": 71538120, + "org.springframework.boot:spring-boot-webflux": -231291542, + "org.springframework.boot:spring-boot-webflux-test": 1600114323, + "org.springframework.boot:spring-boot-webflux-test:jar:sources": 1452173744, + "org.springframework.boot:spring-boot-webflux:jar:sources": -1118813321, + "org.springframework.boot:spring-boot-webmvc": -2104103221, + "org.springframework.boot:spring-boot-webmvc-test": 749235095, + "org.springframework.boot:spring-boot-webmvc-test:jar:sources": 444837917, + "org.springframework.boot:spring-boot-webmvc:jar:sources": -1895028417, + "org.springframework.boot:spring-boot-webtestclient": -705991472, + "org.springframework.boot:spring-boot-webtestclient:jar:sources": -542316343, + "org.springframework.boot:spring-boot:jar:sources": 580880564, + "org.springframework.cloud:spring-cloud-commons": -788453967, + "org.springframework.cloud:spring-cloud-commons:jar:sources": 1320616004, + "org.springframework.cloud:spring-cloud-context": 1118197933, + "org.springframework.cloud:spring-cloud-context:jar:sources": -1413797918, + "org.springframework.cloud:spring-cloud-starter": -1812063683, + "org.springframework.cloud:spring-cloud-starter-bootstrap": -1263482746, + "org.springframework.cloud:spring-cloud-starter-bootstrap:jar:sources": 1965832056, + "org.springframework.data:spring-data-cassandra": -1548120966, + "org.springframework.data:spring-data-cassandra:jar:sources": -1628107854, + "org.springframework.data:spring-data-commons": 1312199320, + "org.springframework.data:spring-data-commons:jar:sources": 544548950, + "org.springframework.security:spring-security-config": 2001744589, + "org.springframework.security:spring-security-config:jar:sources": -756968726, + "org.springframework.security:spring-security-core": -1251894794, + "org.springframework.security:spring-security-core:jar:sources": 1285888871, + "org.springframework.security:spring-security-crypto": 424824057, + "org.springframework.security:spring-security-crypto:jar:sources": 1862561396, + "org.springframework.security:spring-security-oauth2-client": -1975050683, + "org.springframework.security:spring-security-oauth2-client:jar:sources": 1833974239, + "org.springframework.security:spring-security-oauth2-core": -1658804453, + "org.springframework.security:spring-security-oauth2-core:jar:sources": -948845785, + "org.springframework.security:spring-security-oauth2-jose": 502613895, + "org.springframework.security:spring-security-oauth2-jose:jar:sources": 17294361, + "org.springframework.security:spring-security-oauth2-resource-server": -1894007153, + "org.springframework.security:spring-security-oauth2-resource-server:jar:sources": -1508178760, + "org.springframework.security:spring-security-test": 1672796517, + "org.springframework.security:spring-security-test:jar:sources": -1326480212, + "org.springframework.security:spring-security-web": -1696304083, + "org.springframework.security:spring-security-web:jar:sources": 1443816202, + "org.springframework:spring-aop": -819786825, + "org.springframework:spring-aop:jar:sources": 1924976574, + "org.springframework:spring-beans": -698130853, + "org.springframework:spring-beans:jar:sources": -2147408778, + "org.springframework:spring-context": -846077202, + "org.springframework:spring-context:jar:sources": -1263444176, + "org.springframework:spring-core": -253727183, + "org.springframework:spring-core:jar:sources": -173347576, + "org.springframework:spring-expression": 1724609785, + "org.springframework:spring-expression:jar:sources": 1135225455, + "org.springframework:spring-test": -279979944, + "org.springframework:spring-test:jar:sources": -6017836, + "org.springframework:spring-tx": 1899606770, + "org.springframework:spring-tx:jar:sources": -1007028336, + "org.springframework:spring-web": 2084009704, + "org.springframework:spring-web:jar:sources": 1608360284, + "org.springframework:spring-webflux": 1763806581, + "org.springframework:spring-webflux:jar:sources": -1419709374, + "org.springframework:spring-webmvc": 56813816, + "org.springframework:spring-webmvc:jar:sources": -837106767, + "org.testcontainers:testcontainers": 450183679, + "org.testcontainers:testcontainers-cassandra": 584880112, + "org.testcontainers:testcontainers-cassandra:jar:sources": 2024290088, + "org.testcontainers:testcontainers-database-commons": -1213526598, + "org.testcontainers:testcontainers-database-commons:jar:sources": 315333060, + "org.testcontainers:testcontainers-junit-jupiter": -1827576744, + "org.testcontainers:testcontainers-junit-jupiter:jar:sources": 975697823, + "org.testcontainers:testcontainers:jar:sources": 76092129, + "org.wiremock:wiremock-standalone": -1817681233, + "org.wiremock:wiremock-standalone:jar:sources": 695361099, + "org.xmlunit:xmlunit-core": 1938864481, + "org.xmlunit:xmlunit-core:jar:sources": -54376142, + "org.yaml:snakeyaml": -1432706414, + "org.yaml:snakeyaml:jar:sources": 393768628, + "software.amazon.awssdk:annotations": -647669452, + "software.amazon.awssdk:annotations:jar:sources": -277384386, + "software.amazon.awssdk:checksums": 573213413, + "software.amazon.awssdk:checksums-spi": -720493267, + "software.amazon.awssdk:checksums-spi:jar:sources": -650776626, + "software.amazon.awssdk:checksums:jar:sources": -241565759, + "software.amazon.awssdk:endpoints-spi": 1412926322, + "software.amazon.awssdk:endpoints-spi:jar:sources": -1092637607, + "software.amazon.awssdk:http-auth-aws": -589182304, + "software.amazon.awssdk:http-auth-aws:jar:sources": -993506252, + "software.amazon.awssdk:http-auth-spi": -45686548, + "software.amazon.awssdk:http-auth-spi:jar:sources": -1486999869, + "software.amazon.awssdk:http-client-spi": 1386281563, + "software.amazon.awssdk:http-client-spi:jar:sources": 541891925, + "software.amazon.awssdk:identity-spi": -969758372, + "software.amazon.awssdk:identity-spi:jar:sources": -1418587191, + "software.amazon.awssdk:json-utils": -1666742251, + "software.amazon.awssdk:json-utils:jar:sources": 1618084806, + "software.amazon.awssdk:metrics-spi": -500500368, + "software.amazon.awssdk:metrics-spi:jar:sources": -1496041869, + "software.amazon.awssdk:profiles": 1556987661, + "software.amazon.awssdk:profiles:jar:sources": 517790158, + "software.amazon.awssdk:regions": 1394259783, + "software.amazon.awssdk:regions:jar:sources": 927040140, + "software.amazon.awssdk:retries": 1273159411, + "software.amazon.awssdk:retries-spi": 1857446587, + "software.amazon.awssdk:retries-spi:jar:sources": -974151310, + "software.amazon.awssdk:retries:jar:sources": 1826499536, + "software.amazon.awssdk:sdk-core": 1641186658, + "software.amazon.awssdk:sdk-core:jar:sources": -769872481, + "software.amazon.awssdk:third-party-jackson-core": -1062653941, + "software.amazon.awssdk:third-party-jackson-core:jar:sources": -230379012, + "software.amazon.awssdk:utils": 1497168994, + "software.amazon.awssdk:utils:jar:sources": 249477790, + "tools.jackson.core:jackson-core": -1258054011, + "tools.jackson.core:jackson-core:jar:sources": -1689479769, + "tools.jackson.core:jackson-databind": 1443518747, + "tools.jackson.core:jackson-databind:jar:sources": -871567409, + "tools.jackson.module:jackson-module-blackbird": 1038981586, + "tools.jackson.module:jackson-module-blackbird:jar:sources": -9825245 + }, + "artifacts": { + "aopalliance:aopalliance": { + "shasums": { + "jar": "0addec670fedcd3f113c5c8091d783280d23f75e3acb841b61a9cdb079376a08", + "sources": "e6ef91d439ada9045f419c77543ebe0416c3cdfc5b063448343417a3e4a72123" + }, + "version": "1.0" + }, + "args4j:args4j": { + "shasums": { + "jar": "11b029a602e787e2bc08eb3b77eda1a4f5e8b263d22e3c5d6220cd5c51f30b18", + "sources": "ec1eb6aa4859b9b4fd9da4d58efb28b2eb629a4c14919e9078054879540243b7" + }, + "version": "2.0.28" + }, + "at.yawk.lz4:lz4-java": { + "shasums": { + "jar": "49753ae8a9b7dc3ce48cb2989cc6605e43eb8269748ad3466251836ec4cd02a8", + "sources": "3b9a0590c53a4f4e45b204695af0e480dbd4f3a589913c6a36f7c2c3d31b0eaa" + }, + "version": "1.10.3" + }, + "ch.qos.logback:logback-classic": { + "shasums": { + "jar": "b65e05076a5c1aadb659b4fe4bc5fee31cb26cd70390292eb03e4a7a24cff10f", + "sources": "c2e39cb4d6d9b8c2343c6da2469e21e1d6aef2dde16c2227762c084d549ad0a0" + }, + "version": "1.5.34" + }, + "ch.qos.logback:logback-core": { + "shasums": { + "jar": "42eda264c0c650c2bec59e66151a88b708a8663dc1b49d788202d53e78b8caae", + "sources": "6a9f217ef206caf2880810c505e057fd2bb90a6024013906815e9513c6e488c5" + }, + "version": "1.5.34" + }, + "com.datastax.cassandra:cassandra-driver-core": { + "shasums": { + "jar": "09c4d54009e942e3afb8755c5fd51abac8ba721e407b61dcb22f435d1a33c1a1", + "sources": "b0e1d20dd052986f1cc1511fee039801ebb1ae3474a14f0708bedf9b6278083d" + }, + "version": "3.10.0" + }, + "com.datastax.oss:native-protocol": { + "shasums": { + "jar": "190dc40f3c63d6d803c48f90d457e06c65e6c5d955e47d4735dc9954a6743655", + "sources": "6029f3fd12ebe066826642d42f0efb63108b051577828458b66a8637847e88c9" + }, + "version": "1.5.2" + }, + "com.fasterxml.jackson.core:jackson-annotations": { + "shasums": { + "jar": "53ca085f4a150f703f49e1aabd935bd03b43e1ea3d55d135438292af22cef56b", + "sources": "71fe6323d91b16d5d1007fd1e1533fa06bb369abde74f68a42a68c0f8f061a8b" + }, + "version": "2.21" + }, + "com.fasterxml.jackson.core:jackson-core": { + "shasums": { + "jar": "4b40a06396f239f8de2da57419adde6e94e5edc18a2171d471ea05eeed4e5c2d", + "sources": "90ccada55626ce4f00a81bde235af0a942ec2bc4c701fcc86a93af1be9b3e08d" + }, + "version": "2.21.4" + }, + "com.fasterxml.jackson.core:jackson-databind": { + "shasums": { + "jar": "3888e9e69ab66fbacaacc9aea0e9ffbf15368288e4aca468b024dba11c09fbf9", + "sources": "23188e78e912c9866367bf038fb7f729e79f1c2724174ca66e0a00915de70e61" + }, + "version": "2.21.4" + }, + "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml": { + "shasums": { + "jar": "055eb4c008ab12f0cb63e93a6454463d032fde0fca85943d69f8dc7469489e4b", + "sources": "164cef68956eb2797e421dd6cf74bfd648581965a8df2389c260bb363d1f3baa" + }, + "version": "2.21.4" + }, + "com.fasterxml.jackson.datatype:jackson-datatype-jsr310": { + "shasums": { + "jar": "d1ac4b98b70304e56448423589fde5e775b100889643ad1ead62cc7811633684", + "sources": "884a8812af289bb56f38f09a4b3b7b73b4a16dbc184ae735fbe6c4aa1089161f" + }, + "version": "2.21.4" + }, + "com.fasterxml:classmate": { + "shasums": { + "jar": "75fbda45456f123fb6e2028a6189442d8d0730b357adce4c0a6d7e789f70669b", + "sources": "b0690a771dc54865c3d0ad9ab6abb319633b6b88849900a28f719e792c15fc68" + }, + "version": "1.7.3" + }, + "com.github.ben-manes.caffeine:caffeine": { + "shasums": { + "jar": "9d9d2cfd681fd9272ded3d27c9930db12f89f732345975aa113ebc223bbf1224", + "sources": "5079e1b327d79e2fc8ae3f5927587e59c968603e63785fb33479acd8b732211d" + }, + "version": "3.2.4" + }, + "com.github.ben-manes.caffeine:guava": { + "shasums": { + "jar": "7819335459a43b3d2d501bd19b6cf880041a1ad47a9a118d018d89c432357358", + "sources": "2de42779d0ee1807262065382a9302715b2d8daa186f9b39aca1043c10681ab5" + }, + "version": "3.2.4" + }, + "com.github.docker-java:docker-java-api": { + "shasums": { + "jar": "dad153d484b1f4ef009e2fdbad27e07aeb3191122da52b8985507ac504300081", + "sources": "57c9b5bc37d48c256a2a0de556095158f363b10eec58052e58f299c542cf9391" + }, + "version": "3.7.1" + }, + "com.github.docker-java:docker-java-transport": { + "shasums": { + "jar": "d15eec8034bf0f92c2a48ca9172691804048115c96dc853272f9486fa2695c3c", + "sources": "131ed62714d94125f89a3c3ad966e517c8ad48fbbc1905b08bcdafc0d6e9de45" + }, + "version": "3.7.1" + }, + "com.github.docker-java:docker-java-transport-zerodep": { + "shasums": { + "jar": "b89bdb1754160323597f9ea32a7fe7a4a3aa8f5b3b43b88e8d71fff3b267ab21", + "sources": "f4d1457f9e2e151d19713e46cf2b49796887d5a9744664a15a4ce07c76660883" + }, + "version": "3.7.1" + }, + "com.github.java-json-tools:btf": { + "shasums": { + "jar": "67c3e462eb50807f4e0a5f4dee304bbf17cd986a42ee5eb0b2f4c9bf64d130d9", + "sources": "97f8bfb9a8876534bf2832a5be4b913b695d72c6ff6f9c8c6719bd38fd4aeb73" + }, + "version": "1.3" + }, + "com.github.java-json-tools:jackson-coreutils": { + "shasums": { + "jar": "16b3aabd3a9eb25655dda433e35f9bd9c7c1aa7991427702f5f11f000813dbb0", + "sources": "6f39b6beed5b000702ade7014be2ca21f895a0b70ab6c199f6ca5bebc1807080" + }, + "version": "2.0" + }, + "com.github.java-json-tools:json-patch": { + "shasums": { + "jar": "1f794d256965b53ef37e70b55505e2ed00ddc0184d44e2e8e1fdce5a3cacc7de", + "sources": "f4ba54ca57611123fe972f05537d44d4b61fd8ed6f71541b3ca37e09a6e3e318" + }, + "version": "1.13" + }, + "com.github.java-json-tools:msg-simple": { + "shasums": { + "jar": "bef4111b993a5b3e6148d8f585621cceac2a1889cdbc34448b11632e0d8a9a8f", + "sources": "eeb0ecd504611cec75f261a6d282bb8b80214e473ef235481c8067b6b121f1cd" + }, + "version": "1.2" + }, + "com.github.jnr:jffi": { + "shasums": { + "jar": "7a616bb7dc6e10531a28a098078f8184df9b008d5231bdc5f1c131839385335f", + "native": "ef78953e3dbf47fab94469190bc2a6d601566a21d4651f73c822bad1c02b64fe", + "sources": "45ad89d2774e9d03de89905cf990d49d5821ce8012a841faddf23dca02538d72" + }, + "version": "1.2.16" + }, + "com.github.jnr:jnr-constants": { + "shasums": { + "jar": "a617b0d8463d3ea36435bd1611113dedb3749157afd2269908ab306c992aefed", + "sources": "9406718df04cd893a94933213b370d99c613d94d80e23119e2cf8dc51394ea12" + }, + "version": "0.10.3" + }, + "com.github.jnr:jnr-ffi": { + "shasums": { + "jar": "2ed1bedf59935cd3cc0964bac5cd91638b2e966a82041fe0a6c85f52279c9b34", + "sources": "61842708c7e617ae2ca3a389931142f506f854104392fa6f7aaac6f51c93cf58" + }, + "version": "2.1.7" + }, + "com.github.jnr:jnr-posix": { + "shasums": { + "jar": "c38ecfccd24e5f21f17a62e45d5bd454842c5db17ed42b01b868f9206d0e99e7", + "sources": "abfff56a7628d223ba86c3ccb3bcb5101aeefdeedbe58c3c52b1917a92d7e332" + }, + "version": "3.1.15" + }, + "com.github.jnr:jnr-x86asm": { + "shasums": { + "jar": "39f3675b910e6e9b93825f8284bec9f4ad3044cd20a6f7c8ff9e2f8695ebf21e", + "sources": "3c983efd496f95ea5382ca014f96613786826136e0ce13d5c1cbc3097ea92ca0" + }, + "version": "1.0.2" + }, + "com.github.stephenc.jcip:jcip-annotations": { + "shasums": { + "jar": "4fccff8382aafc589962c4edb262f6aa595e34f1e11e61057d1c6a96e8fc7323", + "sources": "d60bb3bf4e03a5e405f9b16f4c2625de86089d6ce4f999bcc2548dcac090ae19" + }, + "version": "1.0-1" + }, + "com.google.code.findbugs:jsr305": { + "shasums": { + "jar": "766ad2a0783f2687962c8ad74ceecc38a28b9f72a2d085ee438b7813e928d0c7", + "sources": "1c9e85e272d0708c6a591dc74828c71603053b48cc75ae83cce56912a2aa063b" + }, + "version": "3.0.2" + }, + "com.google.code.gson:gson": { + "shasums": { + "jar": "d3999291855de495c94c743761b8ab5176cfeabe281a5ab0d8e8d45326fd703e", + "sources": "ba5bddb1a89eb721fcca39f3b34294532060f851e2407a82d82134a41eec4719" + }, + "version": "2.8.9" + }, + "com.google.errorprone:error_prone_annotations": { + "shasums": { + "jar": "ff80626baaf12a09342befd4e84cba9d50662f5fcd7f7a9b3490a6b7cf87e66c", + "sources": "bf08616e340f5e2ef50aaa84aea8baa086fd7bb2ad310501ff4e88ec77f8f31a" + }, + "version": "2.5.1" + }, + "com.google.guava:failureaccess": { + "shasums": { + "jar": "a171ee4c734dd2da837e4b16be9df4661afab72a41adaf31eb84dfdaf936ca26", + "sources": "092346eebbb1657b51aa7485a246bf602bb464cc0b0e2e1c7e7201fadce1e98f" + }, + "version": "1.0.1" + }, + "com.google.guava:guava": { + "shasums": { + "jar": "bd7fa227591fb8509677d0d1122cf95158f3b8a9f45653f58281d879f6dc48c5", + "sources": "9105dfc522fb440b39ff8da07cc56aacf65a9f765044c7803a9f32e36e05a22b" + }, + "version": "32.0.1-jre" + }, + "com.google.guava:listenablefuture": { + "shasums": { + "jar": "b372a037d4230aa57fbeffdef30fd6123f9c0c2db85d0aced00c91b974f33f99" + }, + "version": "9999.0-empty-to-avoid-conflict-with-guava" + }, + "com.google.j2objc:j2objc-annotations": { + "shasums": { + "jar": "f02a95fa1a5e95edb3ed859fd0fb7df709d121a35290eff8b74dce2ab7f4d6ed", + "sources": "7413eed41f111453a08837f5ac680edded7faed466cbd35745e402e13f4cc3f5" + }, + "version": "2.8" + }, + "com.jayway.jsonpath:json-path": { + "shasums": { + "jar": "890daa95dd3892d34d9fabc27cd5153656e6f369358625c88f4dc7b79cbd6c5a", + "sources": "357f1c52217497c4251fae715ba8ef76ae310b1aae77ea319260bf4c6ad61440" + }, + "version": "2.10.0" + }, + "com.nimbusds:content-type": { + "shasums": { + "jar": "60349793e006fba96b532cb0c21e10e969fe0db8d87f91c3b9eaf82ba2998895", + "sources": "9a154c802659594d8745a0e364bd2e6b418e010268467cd222354445dd77d626" + }, + "version": "2.3" + }, + "com.nimbusds:lang-tag": { + "shasums": { + "jar": "e8c1c594e2425bdbea2d860de55c69b69fc5d59454452449a0f0913c2a5b8a31", + "sources": "8d37da312db366d702bd7254df6bceca0a7814e18da9c32db9cc1d8ca038c468" + }, + "version": "1.7" + }, + "com.nimbusds:nimbus-jose-jwt": { + "shasums": { + "jar": "6f13f3480ddc53d820d276f582f54843cff1daf5c6e35e534947e9de7723b46b", + "sources": "b3fd3b569013246fb9a1ac6b43ff3e3033065bce16de92ecf4c971d14875eb30" + }, + "version": "10.4" + }, + "com.nimbusds:oauth2-oidc-sdk": { + "shasums": { + "jar": "648494b00da090a4df23aa6a05e4dc03f6e8603b29dd807a4491f33d586f7f78", + "sources": "e4de2ef818fbb57aa3731b65e2f5edc1a40dc1e3f6e6541306ca9f45490aed2a" + }, + "version": "11.26.1" + }, + "com.squareup.okhttp3:okhttp-jvm": { + "shasums": { + "jar": "9632c08567dbb21c569b13d793107834c8580d44e4eea74b2eae0722f0506179", + "sources": "9fa32be62c7a46ffe70cdb1bf7e195f5ee3fc885999379292cb636b5aa311704" + }, + "version": "5.2.1" + }, + "com.squareup.okio:okio-jvm": { + "shasums": { + "jar": "31f48e6463ec587d6d262d042c91da00659c983b6ad20d5982bf31e85222693c", + "sources": "b29b5f4ad1adfd7cbfb3d388f7bf29d1702f0b85be1b6c61b0185ce7e2b2e6dc" + }, + "version": "3.16.1" + }, + "com.typesafe:config": { + "shasums": { + "jar": "4c0aa7e223c75c8840c41fc183d4cd3118140a1ee503e3e08ce66ed2794c948f", + "sources": "89af318a607f7e2b2691ed1ef4b4890bd37ea17d6986b0aec50dd4d5f889520c" + }, + "version": "1.4.1" + }, + "com.vaadin.external.google:android-json": { + "shasums": { + "jar": "dfb7bae2f404cfe0b72b4d23944698cb716b7665171812a0a4d0f5926c0fac79", + "sources": "54c781eea645c450cbbc4a5a1b5a474745465452cec1354cb567b781ea6622c3" + }, + "version": "0.0.20131108.vaadin1" + }, + "commons-codec:commons-codec": { + "shasums": { + "jar": "5c3881e4f556855e9c532927ee0c9dfde94cc66760d5805c031a59887070af5f", + "sources": "b0462142585d45fc15bc8091b7b02f1e3a85c83595068659548c82cac9cdc7a2" + }, + "version": "1.19.0" + }, + "commons-io:commons-io": { + "shasums": { + "jar": "df90bba0fe3cb586b7f164e78fe8f8f4da3f2dd5c27fa645f888100ccc25dd72", + "sources": "7a87277538cce40da6389a7163a4d9458bc7a9c39937a329881b91d144be8e0d" + }, + "version": "2.20.0" + }, + "commons-logging:commons-logging": { + "shasums": { + "jar": "f8ead8943401081dea0aa824b5b1ba40a0e4ed297a572a0f02258150a0b62357", + "sources": "6e821e03cfc64e509cc162d428af84697b6c4188eb14c0b137c75b69649976ef" + }, + "version": "1.3.6" + }, + "io.cloudevents:cloudevents-api": { + "shasums": { + "jar": "95751500be617f0c795ea3cd7c370fa712459da500fbd22bb8b7f69fcba46e97", + "sources": "962306ae4d9c9aaea5958a3e5e837c895bc683098c2da7f2fa8e972dfea82ebd" + }, + "version": "4.1.1" + }, + "io.cloudevents:cloudevents-core": { + "shasums": { + "jar": "25c3756d184eebf20aceadbd2357cd48516938ca458a1b77a3ebdc09f8dfc592", + "sources": "869ae88ca9b7f7e62af3f34ae6269e7c816b58d08ef371040530164e2aaea02a" + }, + "version": "4.1.1" + }, + "io.cloudevents:cloudevents-json-jackson": { + "shasums": { + "jar": "28aa328c61ae1783cecb430f7b51880e365ea8678628eca416e12654eafbb66d", + "sources": "b4ee1b7db2dfa50101a9fa7a3beef610b6931546be1bc5a61ae28cc929473406" + }, + "version": "4.1.1" + }, + "io.dropwizard.metrics:metrics-core": { + "shasums": { + "jar": "5c6f685e41664d10c70c65837cba9e58d39ff3896811e3b5707a934b11c85ad0", + "sources": "773164a026ea78df51d14608def3a746a2270f630e9a2f5f6f99d6e155ad5bcf" + }, + "version": "3.2.2" + }, + "io.micrometer:context-propagation": { + "shasums": { + "jar": "5b69e2100640879ccf4b20673ced86de560b8e217b55542f85a53d3563b72aaa", + "sources": "719639b819c3ecc76f2b3d4da4b17ca7a8ed6c73b93a770c69aa9d86276f8bf2" + }, + "version": "1.2.1" + }, + "io.micrometer:micrometer-commons": { + "shasums": { + "jar": "45aff76226830db257f4bc39a5bcff83d633e572fee9dc4e45cfa12af9a0a49a", + "sources": "0e4a336c7bca50bfa6cbea274ea681e42d86bfdac1038af3041301c8454f76ff" + }, + "version": "1.16.6" + }, + "io.micrometer:micrometer-core": { + "shasums": { + "jar": "1957ef2deaffbc1fb98cebfd0f5b3109ecf19c994d7e5378598c20747ba8d68b", + "sources": "f85d566a76d98891cdecd54c106b7ad7f8948cddad3b393debe341ecfba18bce" + }, + "version": "1.16.6" + }, + "io.micrometer:micrometer-jakarta9": { + "shasums": { + "jar": "987722add6461c5a4c796be11e7452e8813fba341f2cc067b1d283eef2bd4f40", + "sources": "83fa1c6356611b3381d6309a6159b2739c9c29446c8b52183b2111fb13ce5301" + }, + "version": "1.16.6" + }, + "io.micrometer:micrometer-observation": { + "shasums": { + "jar": "4c0826d5e7c8522a8e111470b4e77f77b0a10f520eb5502ddd143fdbcedb2340", + "sources": "ff5525482df358e7502d4c8680fb654ec700e3b01341149d870bd6cfd8ce04c0" + }, + "version": "1.16.6" + }, + "io.micrometer:micrometer-observation-test": { + "shasums": { + "jar": "e69bf8df81458f4ad6f6027a7310d75c8ca8d11df2e95d44dd4616f8637069ad", + "sources": "1ebcdbf4e14e6a4dcec4ad188bc4227ebd5ce0a3f361f5f0ed6df2bebb10cfb2" + }, + "version": "1.16.6" + }, + "io.micrometer:micrometer-tracing": { + "shasums": { + "jar": "b335096393e4d070dfda4fb30808f8488d31d43811b93b2d7496703c5f1315ef", + "sources": "a089a2bcc462d6ced28d7f67b01a9f54baf6c52984cd13f3ed713f2fda0810c6" + }, + "version": "1.6.6" + }, + "io.micrometer:micrometer-tracing-bridge-otel": { + "shasums": { + "jar": "581b6908d46ed2df6b9bb8167df4c44deddc5c2567c430c73bca66326138f661", + "sources": "2aa7115e2f0562e3c50149e77d6fc41340b20d5111b737ea443e0b8bf53a75b3" + }, + "version": "1.6.6" + }, + "io.nats:jnats": { + "shasums": { + "jar": "a5705531ff8fc96657d99d2fc4436178c04463df6a216ba6b5528a5d5228f240", + "sources": "40d6500a369ad57822074fa2a838367e4818ac61eba5c038c95b54772c4ef96f" + }, + "version": "2.23.0" + }, + "io.netty:netty-buffer": { + "shasums": { + "jar": "1361fd9c9ba85b9831cf54a1b2e45ddc3ce34a768931726c099d3f5ef0efe4a3", + "sources": "13259b636c4a91c0f34a8536d621178fba302f9ba61f3e4aaec3a17ca291dc2a" + }, + "version": "4.2.15.Final" + }, + "io.netty:netty-codec-base": { + "shasums": { + "jar": "2c6d39d7270628b8cfc3166fbd7a93d595958e59c461bc32ddb383c8c91bf811", + "sources": "029bea433dfc710c640338954c7403cc7ac31cc5bf4c192904c837b0ebda5fb2" + }, + "version": "4.2.15.Final" + }, + "io.netty:netty-codec-classes-quic": { + "shasums": { + "jar": "ec1d5da906ea0139741cd8c570907c399df5995e48a2b07fe3155272e0be21a6", + "sources": "edfbbece45f21e8f214c0f08f33666ef09ae4580322ffa27020633b5fdee6250" + }, + "version": "4.2.15.Final" + }, + "io.netty:netty-codec-compression": { + "shasums": { + "jar": "4adaa5cdd4d2e9b50b23e4c3eff42e73de6eb40848718b3aa84cd5b454da6ce8", + "sources": "58d61aa4f781657f955a196f17e28fcd9b02e21658b996571e4604a2dadbd8af" + }, + "version": "4.2.15.Final" + }, + "io.netty:netty-codec-dns": { + "shasums": { + "jar": "c5e2c05b4faeba3cf374cc6af29d6f4a7e969d7ca222be958e0800c79a02ee4e", + "sources": "f10017539ab2816efee10b70b47b262c04b881fca685327769d576dd8b222b47" + }, + "version": "4.2.15.Final" + }, + "io.netty:netty-codec-http": { + "shasums": { + "jar": "76ae57e87af37b3c4107140f50b9244b1456163a6a225510838f7c5a4458ec22", + "sources": "76b25b4884e7bec78cd310415b068204e67da5a87162774abfad9a0e6c7a0e78" + }, + "version": "4.2.15.Final" + }, + "io.netty:netty-codec-http2": { + "shasums": { + "jar": "4a9b052bd815c765d9c05e27b32abbd32a2c7c3e3364ccb992ce71da1a26bc0d", + "sources": "01f8ad714e5abb989b0e782da9ec467068821299cd17d80c2db833a6472507f6" + }, + "version": "4.2.15.Final" + }, + "io.netty:netty-codec-http3": { + "shasums": { + "jar": "f2f96b7557317c1378dd8d84b4d9b1865db285c5e665b1220ea519e9f868929d", + "sources": "3a35802b80f536b5693d53d6dfbf4102e94edd0e7b26b3b8d8ab400a12d0f9e0" + }, + "version": "4.2.15.Final" + }, + "io.netty:netty-codec-native-quic": { + "shasums": { + "linux-aarch_64": "59a8e59aa9d3a886cd7fae30fb3d3a18ebee40fa9dc08b83eb88bee58cf46774", + "linux-x86_64": "850ed59fac6679b5e205bf53187b45dbaf2d105ee5f669440645d2acd89524ec", + "osx-aarch_64": "ce18ffeccef21adb3caca5534061c921ef750662f29028fdde62d65196d63a9d", + "osx-x86_64": "10999923bf08ff5e3a75106bd8dbc5b5e4d06b5e614f8c135981ecb4377c944a", + "sources": "d9772d6d7d0eb6fdf82ccaeb9558f88b5600c6f0696a724f5e067b67bdc049f3", + "windows-x86_64": "40adba6df605302bf98a4a462bb002c4697f60958cea7cfec38f0fab6331eb7a" + }, + "version": "4.2.15.Final" + }, + "io.netty:netty-codec-socks": { + "shasums": { + "jar": "4230d43481241e49382a83da2fa9d5980c5702668fc5aa5a980346ce03d30828", + "sources": "f126a6f94589b56b1c056a5dbbda4e76e4e749cec1591a3e878e4d6854144a43" + }, + "version": "4.2.15.Final" + }, + "io.netty:netty-common": { + "shasums": { + "jar": "78206aa7f6d197caa926291408c01889b6b910ca0f74017d3fcbdaccf9562959", + "sources": "de720a128534ba1072b354c863d671ab1999900a8fddaadc4a68ee74c2e33fd6" + }, + "version": "4.2.15.Final" + }, + "io.netty:netty-handler": { + "shasums": { + "jar": "99b59e4bea72220d2aed52df8baf37d97431b06ade0b135226cdf73168975eab", + "sources": "68306697d15d870e7bb29ab9ce725d121ac3170428e8a5d7a33767c5fb0ffa0e" + }, + "version": "4.2.15.Final" + }, + "io.netty:netty-handler-proxy": { + "shasums": { + "jar": "a06aaaaa1a2e6eb26824e53566bfd020ba930a9390d57a1f0bbf57316e357373", + "sources": "91fa7fc64aaa39982b30cc19974f80021090c91023d1d5f6a8e4179aa3a5056b" + }, + "version": "4.2.15.Final" + }, + "io.netty:netty-resolver": { + "shasums": { + "jar": "24318497f2a3a645964fed418f48879ba11365cab8e1f8d66c47fa7da15ef19a", + "sources": "c87b295c43265b34c749331e12ee667f7d43329338618bee2a08027b839220d2" + }, + "version": "4.2.15.Final" + }, + "io.netty:netty-resolver-dns": { + "shasums": { + "jar": "2e8dd2d861775483d689329ab2546045647c8f8bf5ae3ed2dd48eefbb748952d", + "sources": "4db838a89ec84479476e71956d59c67a957779dc5f9781f1a9964f9a6b607c29" + }, + "version": "4.2.15.Final" + }, + "io.netty:netty-resolver-dns-classes-macos": { + "shasums": { + "jar": "dc91d81e0f6c8987ed34f6ca005b4b97cc6032f933a49f7500940e846ade7c43", + "sources": "00067617cc0927d804091590f9ea5041e39c4f907357e3c969c45078fe10be3d" + }, + "version": "4.2.15.Final" + }, + "io.netty:netty-resolver-dns-native-macos": { + "shasums": { + "osx-x86_64": "a1115fb0fd88fe50209fbd645cbfe09e41fe2d264bb1854dc545f44a1bd020cf", + "sources": "87a85f239a73c9a4e7dde8ca31e0a8dea711b3b5e3cff9df18b8c07f31f5dc50" + }, + "version": "4.2.15.Final" + }, + "io.netty:netty-transport": { + "shasums": { + "jar": "9fb671e96651066cf1a28dad3f1382c7c99df5b8326d4a214d9a375b311f8dc1", + "sources": "e17c0a4c7324a93fa01f00bc6ddd2bf2f6eb94702ad8de7af777dec87f89eaf8" + }, + "version": "4.2.15.Final" + }, + "io.netty:netty-transport-classes-epoll": { + "shasums": { + "jar": "be509407fd71a4b83378567c613420db544d659bb522df7b253a1dbe8ca297fe", + "sources": "bb095191a070714f769bff1dd0e5d2496305d10bd566bdc16dbca5773df48b4e" + }, + "version": "4.2.15.Final" + }, + "io.netty:netty-transport-native-epoll": { + "shasums": { + "linux-x86_64": "5440e38f5ca2858fee8d7898e65291e05b665736c9e8a14c832e707511f5dba6", + "sources": "d48e8de50b0994842bec4e65725a7f8e9734144dd4f08b78ffe5396a70ab06b6" + }, + "version": "4.2.15.Final" + }, + "io.netty:netty-transport-native-unix-common": { + "shasums": { + "jar": "b9ea9fc5ad5eba04e99afdff75b2eb97b5ddfb2ad772e2f2ef5d8f277f3cbd76", + "sources": "2b82c54d1b2b9908ec0104664edf58ded4848ae5b34266ee1cf90707efc420ab" + }, + "version": "4.2.15.Final" + }, + "io.opentelemetry.semconv:opentelemetry-semconv": { + "shasums": { + "jar": "693ad6f04f29b4b593a04adef5f575d28b3a91ea3449ab5b1e1e2e5c6efc6cdc", + "sources": "186f9e009d914ebe31f5994d42ff67c5dba8e0893569a4f0f0eeb7958b956d4f" + }, + "version": "1.37.0" + }, + "io.opentelemetry:opentelemetry-api": { + "shasums": { + "jar": "387b4bf98631fc2ede9470879a8ff28dd8c5cb2d3dcf5b6ef77f5ee2bdb7b4f1", + "sources": "3abc57abcaaff4521a5fb2b89593031da5feca24aa54816ec58a8d08ab71fd4a" + }, + "version": "1.55.0" + }, + "io.opentelemetry:opentelemetry-common": { + "shasums": { + "jar": "fca14bb87309d1193347d179b91c63045fa05a856f1fbeec6ef61c4a7f81b227", + "sources": "4219708637e60172c347e48b677b71f5ad97ab8e4850cfda2f85ed59da74e250" + }, + "version": "1.55.0" + }, + "io.opentelemetry:opentelemetry-context": { + "shasums": { + "jar": "f34a4718b70446ec462703ced5cc2c9ad4c9b7c69dcb41d0f032ba51c625a3dd", + "sources": "e0b63b17ccb407f6208a89a180ad48c6add5cca05d29047e858a6ebe8442b3fb" + }, + "version": "1.55.0" + }, + "io.opentelemetry:opentelemetry-exporter-common": { + "shasums": { + "jar": "3b4faaae49dd87bdefae13528d069a271f8476e2a64420e32f4e959a8d09c132", + "sources": "b795169dce773a549f6f3ce2202886ad93622306f2991bd5771547e3c649a2dc" + }, + "version": "1.55.0" + }, + "io.opentelemetry:opentelemetry-exporter-otlp": { + "shasums": { + "jar": "cf42ce6e7cc6755182149f269447f6677f69c0a31e101464594dbcf62fe874c3", + "sources": "a94ebfb492577503d49d43423328f5d0042206f309a18407386a4ab5375bcc82" + }, + "version": "1.55.0" + }, + "io.opentelemetry:opentelemetry-exporter-otlp-common": { + "shasums": { + "jar": "7ddfa417d88a5ff8626dad9ebe0c8c59776491478ab1f72aedfacd75b984931f", + "sources": "7b36e1080bbb2c4dbc7ce009393c568e3d968328f0e5891beb1e45ebd894337a" + }, + "version": "1.55.0" + }, + "io.opentelemetry:opentelemetry-exporter-sender-okhttp": { + "shasums": { + "jar": "e9cd97f59b18a89772ececbebccd773740eec2cd3ff67a4542eff73738acd60f", + "sources": "55f2f24814971e7b476db3713ec82f29285b679fbcaa434c481863f503e2a6e2" + }, + "version": "1.55.0" + }, + "io.opentelemetry:opentelemetry-extension-trace-propagators": { + "shasums": { + "jar": "27861a2b49b3acf3166f489426808032c3addd9c082999f74a110eb7ac6985ce", + "sources": "784afdd2a2a6fca26f8bf237b8aae7f6bfcb44c65d141901a110b4ff769bee0c" + }, + "version": "1.55.0" + }, + "io.opentelemetry:opentelemetry-sdk": { + "shasums": { + "jar": "d63231ea6fd33e0457c776a9aa8ae7ba778379b03119228ec56a5c8c16f9480e", + "sources": "3685819f7d9efb6761d35ecf5b6053dfc1d0161835da744b0fdb2c4d89c87a42" + }, + "version": "1.55.0" + }, + "io.opentelemetry:opentelemetry-sdk-common": { + "shasums": { + "jar": "e28bb83d0ae5a760ba95952daf820180ee7defb0c5783c9d21f9c00ada80020e", + "sources": "cb9423298f9c42ac2c568af5271d335e468d7730b21d7ca6c246c16c6eca25f7" + }, + "version": "1.55.0" + }, + "io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi": { + "shasums": { + "jar": "3ee1f647238bb77df7b7bde47bc87a35a7807b3c5bb389ca81b0ba16c77824ff", + "sources": "71760407f00ba82b762335ff2c3470daf3d5ff1c6a798eb9ae52a24c7772f418" + }, + "version": "1.55.0" + }, + "io.opentelemetry:opentelemetry-sdk-logs": { + "shasums": { + "jar": "d917bb833899057c7cbdbcc30290e816071b90e52c965693aaad4cc1b32ecc11", + "sources": "edb0008c29edf69671865945a1c47d1944c1f498ef7e895f7b21b916fea2f14c" + }, + "version": "1.55.0" + }, + "io.opentelemetry:opentelemetry-sdk-metrics": { + "shasums": { + "jar": "6219d69c3abdd6113bee35df94826f48e84b742041f5124b5857a2b801f74573", + "sources": "5f9c8dab78339e402caa7f7aa4616b6b5c8e2d50201335c73e23bd21aba147fd" + }, + "version": "1.55.0" + }, + "io.opentelemetry:opentelemetry-sdk-testing": { + "shasums": { + "jar": "9e257ac45834e5d184abdc238b5ee146a74a259d940c57722999ef400cdc2232", + "sources": "b40c580007e26d721d406e0b85385e87f6e2e8c36bea55adfd8837d77f57ccee" + }, + "version": "1.55.0" + }, + "io.opentelemetry:opentelemetry-sdk-trace": { + "shasums": { + "jar": "e593660b9fad8bfdb5e981ccd392aa030f788d577c55f8bac3b6c4c6dae509bb", + "sources": "2f374e9b5f2e7e33157bd6fc97eb5c629d0dac0f22a975075b52714916dfc6c5" + }, + "version": "1.55.0" + }, + "io.projectreactor.netty:reactor-netty-core": { + "shasums": { + "jar": "b8aaddd6025af42c2d810a76dc5b9a7717f0fde84beb93d6d4a778dac25fc287", + "sources": "061136ccc1bc3bed6938cea77a7343dc47de275aad4851b3407fb7ac15854121" + }, + "version": "1.3.6" + }, + "io.projectreactor.netty:reactor-netty-http": { + "shasums": { + "jar": "0ffdcaafe718327ca4687dd41c21318a267e93cea7b43f42db6f3fb3175256a5", + "sources": "712c12723e57d68e909ce9221cb12e04be105435ca518d13f63075af81cbaa44" + }, + "version": "1.3.6" + }, + "io.projectreactor:reactor-core": { + "shasums": { + "jar": "ffc646b225465efce55d3ea350f1bcd1d27d4a56e912323e316dd8e6d04bff11", + "sources": "d6180835f642a1f6d8b330fac98876488994187a89c3df48b369f37344ea6845" + }, + "version": "3.8.6" + }, + "io.projectreactor:reactor-test": { + "shasums": { + "jar": "27acda356a59c19bc3db033f1ed4cff9a6469da6caf424a4004ffaabbfe24d2a", + "sources": "882b7654b056b77f721a03a804e4830030f072a2f4afb92638d6925568d6d930" + }, + "version": "3.8.6" + }, + "io.swagger.core.v3:swagger-annotations-jakarta": { + "shasums": { + "jar": "9b30b319f1c31993e6128d22e12652be9a688589e30c67819ed84e95b96e7f88", + "sources": "b9324b72ab6c498fad2d766f5074b1b24be0cf2c1e55f6c937b4b8345ca90bf9" + }, + "version": "2.2.47" + }, + "io.swagger.core.v3:swagger-core-jakarta": { + "shasums": { + "jar": "e63b78c1e5b049e6670ca9bb43c3f35cf362ecc08ac59a783994a6a732a7d7eb", + "sources": "55b6e465caf14b019ebe4ab9d886915afd1a4796c6c790ffdd4789b36997f556" + }, + "version": "2.2.47" + }, + "io.swagger.core.v3:swagger-models-jakarta": { + "shasums": { + "jar": "15d10f4f7eac1e02a8ff940b430c634fc9dfe08368a54dffa3216cc2dc811aa2", + "sources": "4770b07fcb362a2c1b289fd255d5bf9ec11619bc0cbfcfc07e49599f24fef753" + }, + "version": "2.2.47" + }, + "jakarta.activation:jakarta.activation-api": { + "shasums": { + "jar": "c9db52100ce6c8aac95cc39075f95720d2e561b11f8051b81c121ad4effd7004", + "sources": "2aa5a3ba55059b778a3b467269404d7ac3b9485ed4a23ad26d2e63aa769ec35f" + }, + "version": "2.1.4" + }, + "jakarta.annotation:jakarta.annotation-api": { + "shasums": { + "jar": "b01f55552284cfb149411e64eabca75e942d26d2e1786b32914250e4330afaa2", + "sources": "142dfd2343429df2aac3e1cfacfacc21c8393112c0e0280d3628648d9b612470" + }, + "version": "3.0.0" + }, + "jakarta.servlet:jakarta.servlet-api": { + "shasums": { + "jar": "8a31f465f3593bf2351531a5c952014eb839da96a605b5825b93dd54714c48c4", + "sources": "6eb958543e0548bb93d2519e40224d13c8003b10cc615b5652bfd9899350bfb4" + }, + "version": "6.1.0" + }, + "jakarta.validation:jakarta.validation-api": { + "shasums": { + "jar": "63ce00156388c365f3ac1be71fcfaf114682fc0c452020b5df6e7ec236e142ab", + "sources": "941cc2028fe8f5e6b912954bca360ed347ace453aca4f8e2fd58dc3845a0c792" + }, + "version": "3.1.1" + }, + "jakarta.xml.bind:jakarta.xml.bind-api": { + "shasums": { + "jar": "5e489b6c874c4119e003ff1403db523ee3a8959ec499f3de29e77245efccf216", + "sources": "5bcf811e6719582ab2be21c84bc48f963ba377dfe1dae5ecb2673c1efa00e422" + }, + "version": "4.0.5" + }, + "net.bytebuddy:byte-buddy": { + "shasums": { + "jar": "2b5ddc8c1f4234bdb7cb45338a8e10a13e0e3ca473e91d5d821d681127ea8ba1", + "sources": "5211140f46c380a5e9630a86b2c07b396a9c374128fa603ca1d321b3c7da7449" + }, + "version": "1.17.8" + }, + "net.bytebuddy:byte-buddy-agent": { + "shasums": { + "jar": "5b17113e66e77ca6f8af07ff367c216df964a980f0e9f11e3b1aa793253aa64f", + "sources": "a205437d772e3edaf4a7a1a709e9d59c666e8a05218d0e000deb5651c52de2d2" + }, + "version": "1.17.8" + }, + "net.java.dev.jna:jna": { + "shasums": { + "jar": "260c4b1e22b1db9e110ee441c4f13ce115f841fa48c41d78750986214b395557", + "sources": "0b9224e215b3c6a464959e3f994ddd64c14d46fb4014facd6afa1cc18e469466" + }, + "version": "5.18.1" + }, + "net.minidev:accessors-smart": { + "shasums": { + "jar": "222c9f547bb20a99fc486403a398352d1306fb671b38abd7ecab6401df170e61", + "sources": "10880e44ed732de27ae424a9698a041c398102098b5b1bae3cc597ec62dac43e" + }, + "version": "2.6.0" + }, + "net.minidev:json-smart": { + "shasums": { + "jar": "1ae4b561458afb540be8ec5c6dbb4f2e715a319a7ae64854998aaf924770d61b", + "sources": "a4af3f3773286fe3f76f94d38d977611fd2493685f589466b76dd25cf70b400c" + }, + "version": "2.6.0" + }, + "org.apache.cassandra:java-driver-core": { + "shasums": { + "jar": "6276a8e25c8821eeaa5d2d67c50b81615d551dd7ec943302689996f6bdb2add1", + "sources": "80a95f2d4d61091a8f54bf76f2d26269ee7b8ac82e261314108d7ad83c083838" + }, + "version": "4.19.3" + }, + "org.apache.cassandra:java-driver-guava-shaded": { + "shasums": { + "jar": "fa5e6dfb61a987e69cd8559464145b6ceb6610d28760b0d8cff17eba052c8264", + "sources": "9415d1dd6132671cefc43eb5ac560f34d5e4a1b73ac25310fbfc4584a8033ec3" + }, + "version": "4.19.3" + }, + "org.apache.cassandra:java-driver-metrics-micrometer": { + "shasums": { + "jar": "4f61ed8dabc978f7c9bfdae578915480b6242468feea1c73571be7d832ee3d0a", + "sources": "6214d824dc8e72fd6221165b1497f4c46099027b7ad220ce17f44a8f3f58807f" + }, + "version": "4.19.3" + }, + "org.apache.cassandra:java-driver-query-builder": { + "shasums": { + "jar": "b6e4c84dff2448aaa67f5e3e867b1bf284ca6ad0c15701a4d4d7283384d8df12", + "sources": "dd63fa1af436d1b01155fdca72563338007e265fd8c05c3a8b2e80e76b2d4aa8" + }, + "version": "4.19.3" + }, + "org.apache.commons:commons-compress": { + "shasums": { + "jar": "e1522945218456f3649a39bc4afd70ce4bd466221519dba7d378f2141a4642ca", + "sources": "6de9de4559f12bba6d41789c72f6a2a424514f2d2a3f7f49e2a3c52414db9632" + }, + "version": "1.28.0" + }, + "org.apache.commons:commons-lang3": { + "shasums": { + "jar": "69e5c9fa35da7a51a5fd2099dfe56a2d8d32cf233e2f6d770e796146440263f4", + "sources": "eec245e820ec2800a1780cf756aefb427c1c6170e06902e67ac15b6910ce6335" + }, + "version": "3.20.0" + }, + "org.apache.logging.log4j:log4j-api": { + "shasums": { + "jar": "c4b642a7f047275215de117e0e3847eb2c7711d84a0aa7433e7b3c096daf341d", + "sources": "b86680bcf8ffa25897b6114cae508bb8e6ecac8081a0fc8985e0c00e27d4f4ec" + }, + "version": "2.25.4" + }, + "org.apache.logging.log4j:log4j-to-slf4j": { + "shasums": { + "jar": "d7b78fc0aaaa5e8ada388b29d718b0ab187e512965bed0b259bb4ab299f13db2", + "sources": "ca9159da173bf88fb621adf745fe1d313ba4074f4c66576ae70f5dd99eab89c9" + }, + "version": "2.25.4" + }, + "org.apache.tomcat.embed:tomcat-embed-core": { + "shasums": { + "jar": "78cd7cd7c104b6b87142c1b0bd902e1ce005b0245c3cefa8a06759148947200b", + "sources": "0bfbdc27e60d4db5b83e0f51193bae5f4bd02ac270fd78b06945e219fc473359" + }, + "version": "11.0.22" + }, + "org.apache.tomcat.embed:tomcat-embed-el": { + "shasums": { + "jar": "1b34c33b858c141df36c501b4d809e68036c406bca3671a86facae297917c7de", + "sources": "da3724004575f5c8fa7e45649f2900ec53e7ecfb502b6ce227ca9cf86b36a156" + }, + "version": "11.0.22" + }, + "org.apache.tomcat.embed:tomcat-embed-websocket": { + "shasums": { + "jar": "210e0c7ab194a76cc7283df0be365276091b042369dae125fb477828ba67e922", + "sources": "711f09af528ac5af172c664244bcba4748eac00811ef7c6b52ddd6836b5a4a28" + }, + "version": "11.0.22" + }, + "org.apiguardian:apiguardian-api": { + "shasums": { + "jar": "b509448ac506d607319f182537f0b35d71007582ec741832a1f111e5b5b70b38", + "sources": "277a7a4315412817beb6655b324dc7276621e95ebff00b8bf65e17a27b685e2d" + }, + "version": "1.1.2" + }, + "org.assertj:assertj-core": { + "shasums": { + "jar": "c4a445426c3c2861666863b842cc4ec7bbb1c4226fefd370b6d2fe83d6c4ff0f", + "sources": "5ba6de05730cf76021001f8437f35db4cb5b513465d4ace8c3a6fcd68d9a19ee" + }, + "version": "3.27.7" + }, + "org.awaitility:awaitility": { + "shasums": { + "jar": "ee58568ea5945dcf988551501655183dc184e23e45a8e013fdfd9036194e6f7b", + "sources": "92d209bd0135b04ca6bb7689c6b921819896ec2d517a5357760f598faafee46c" + }, + "version": "4.3.0" + }, + "org.bouncycastle:bcprov-jdk18on": { + "shasums": { + "jar": "64d6c5a6121fcd927152dd182cbed39afe0fda641a970d9bcc0c9cb1858b2731", + "sources": "e5f04550f7740e588edcbd1654c59277cd7ee8725d8b674e44f7f8f4b9c5674a" + }, + "version": "1.84" + }, + "org.bouncycastle:bcprov-lts8on": { + "shasums": { + "jar": "492049b928f8baab535af0185bbab8734d14e1c7648ae2a2037d58486cafb676", + "sources": "d4447a4f412b328f3e43595ab99603dd38b08ee1db9f1ea341e6158eeb86a70d" + }, + "version": "2.73.8" + }, + "org.checkerframework:checker-qual": { + "shasums": { + "jar": "e316255bbfcd9fe50d165314b85abb2b33cb2a66a93c491db648e498a82c2de1", + "sources": "443fa6151982bb4c6ce62e2938f53660085b13a7dceb517202777b87d0dea2c7" + }, + "version": "3.33.0" + }, + "org.hamcrest:hamcrest": { + "shasums": { + "jar": "5d66b6a4a680755cb6ed7cb104fa7835ef644667586ff0737adeb977c39ecdbc", + "sources": "7a4050b1898f7e1aa395cf2be78fb6683f9e2766fcb8e1507926b204fa24d1bf" + }, + "version": "3.0" + }, + "org.hdrhistogram:HdrHistogram": { + "shasums": { + "jar": "22d1d4316c4ec13a68b559e98c8256d69071593731da96136640f864fa14fad8", + "sources": "d3933c83a764994930f4477d4199539eaf413b42e32127ec2b68c61d711ac1a9" + }, + "version": "2.2.2" + }, + "org.hibernate.validator:hibernate-validator": { + "shasums": { + "jar": "25f40118fa4c50f8522d090d25d52d5a38953b0ccd1250835f052e7bd3164ce0", + "sources": "db6a3d49eceaae0a880de8749cd7f7e8928c18458b44fac84633c3ee8db7ac0d" + }, + "version": "9.0.1.Final" + }, + "org.jacoco:org.jacoco.agent": { + "shasums": { + "runtime": "3fb76eea65f81bd9415202bab34b6571728841dff1ab8e6bbe81adc2e299face", + "sources": "8a643b749deb255d7a42c445c3053c9ec263e27103becdaaf88cedda44357255" + }, + "version": "0.8.14" + }, + "org.jacoco:org.jacoco.cli": { + "shasums": { + "jar": "12d5d78351c638efeea71ac840f6a5cf7bcff89001ddb05eb89f956d1079a2c6", + "sources": "52f715f15b890960f70f4ae8fbdd4bca70eba59c0283b37af2d79ad9215d2e37" + }, + "version": "0.8.14" + }, + "org.jacoco:org.jacoco.core": { + "shasums": { + "jar": "28abbf0eea5a08e4f24097f2fbac663ca17c341c25c3a04d90d6cd325943c995", + "sources": "1550fd5081ecd2c2ad053994c23d91a4cef6dcbed4c4dac95130e7d75fa9cd3c" + }, + "version": "0.8.14" + }, + "org.jacoco:org.jacoco.report": { + "shasums": { + "jar": "a3e2026060ab8b8d5c650706406234bb4c033dfd5376afeb8b1666e8ed27c453", + "sources": "80ac2fac212d6a4583b7f025dc7b602f384a9dfcdbccd0e9cb78c415e9f5ffc6" + }, + "version": "0.8.14" + }, + "org.jboss.logging:jboss-logging": { + "shasums": { + "jar": "7c12ee575508f81e22b1db9334b969d0ec54ef0fd1dcba24eeab1a44235fc366", + "sources": "e8a2b9aaac82b0082aa040e6bdf6cd7f225cdbc75d2bd1a79fa7b17007ec1b15" + }, + "version": "3.6.3.Final" + }, + "org.jetbrains.kotlin:kotlin-stdlib": { + "shasums": { + "jar": "6558a3d233da56a20934b32159f9db5f86ed5816ef098f78a2c223dc6abb79dd", + "sources": "664f515359444a92267a13266101431a630f99d6b8d04407a92b1a0e558d33ee" + }, + "version": "2.2.21" + }, + "org.jetbrains:annotations": { + "shasums": { + "jar": "195fb0da046d55bb042e91543484cf1da68b02bb7afbfe031f229e45ac84b3f2", + "sources": "b2c0d02e0a32c56d359e99634e7d769f9b1a8cd6e25061995abad1c1baf86f56" + }, + "version": "17.0.0" + }, + "org.jspecify:jspecify": { + "shasums": { + "jar": "1fad6e6be7557781e4d33729d49ae1cdc8fdda6fe477bb0cc68ce351eafdfbab", + "sources": "adf0898191d55937fb3192ba971826f4f294292c4a960740f3c27310e7b70296" + }, + "version": "1.0.0" + }, + "org.junit.jupiter:junit-jupiter": { + "shasums": { + "jar": "784b65815f479a0c99a9d3a573b142e2a525efb6025d97f751b19e72f90aeda3", + "sources": "402f86a4fdce930bb68b592f2ed5a9d57dc4d1b2747aa2d66c0b3cb7a2adceeb" + }, + "version": "6.0.3" + }, + "org.junit.jupiter:junit-jupiter-api": { + "shasums": { + "jar": "d655d7e6f0c7ae07f10a2f3bbaaebb6d30e9b26204a068ad9e9b3950aa28792c", + "sources": "8266d8da51d0c7d6a2ed4895a3cb76e0ec22194907f24364f2a4f3efd05f00a5" + }, + "version": "6.0.3" + }, + "org.junit.jupiter:junit-jupiter-engine": { + "shasums": { + "jar": "1e2fab61ad27ea08fc7c70dd9677cf8c6d1ae5434d42dcfdd633b12c7e7c04d0", + "sources": "35706a9edf1b580bf22d6eca9d6a9165f478f75b0108840ad6f31481cd662d6c" + }, + "version": "6.0.3" + }, + "org.junit.jupiter:junit-jupiter-params": { + "shasums": { + "jar": "cf2947e2302b9f8c8a059259a277881c1cadae8fbc2514c16a925cfeb7beb2e5", + "sources": "f0dcf217100b06b98cd36c2e74fb919c74e3024faad868bac9eba6ff00c7c263" + }, + "version": "6.0.3" + }, + "org.junit.platform:junit-platform-commons": { + "shasums": { + "jar": "39f262d09c3d52719fe0b77f080e90a3695e285d779a41b232e17963ae5da200", + "sources": "06cbe4a4bbd79339c3817983510cf3adc3d6a88a8a556c80c5b84eeb1ebd13dc" + }, + "version": "6.0.3" + }, + "org.junit.platform:junit-platform-console-standalone": { + "shasums": { + "jar": "3ba0d6150af79214a1411f9ea2fbef864eef68b68c89a17f672c0b89bff9d3a2", + "sources": "c4e79459727c6fe6afbddcc04daa67767fb73d7044d29846dd4ab90de1d0fa0c" + }, + "version": "6.0.3" + }, + "org.junit.platform:junit-platform-engine": { + "shasums": { + "jar": "491e9e4f745f161b8a8e4186a1a7c6a450ea12c70930c9aedae427215301d947", + "sources": "89a893566a97557dbbcb0706d9b5565c4e7a402050841753dc527f3e9139c9ac" + }, + "version": "6.0.3" + }, + "org.junit.platform:junit-platform-launcher": { + "shasums": { + "jar": "315608372e4dc44bca0ccb3ae8a07ecc206b3367033fa05748a03ccd563f1301", + "sources": "4fcbdb81cc882c0c3e73f742878db5884d3d2f86facc08369ca953e32796d144" + }, + "version": "6.0.3" + }, + "org.junit.platform:junit-platform-reporting": { + "shasums": { + "jar": "f19c5be871c37ebed493f3152b67a909f89a44dff67c2db8016dfe34167d5730", + "sources": "bbdda2b9c002dbd1b05cfec144bab91e8cca46ed8d58525f51b547f3a0a84a7d" + }, + "version": "6.0.3" + }, + "org.latencyutils:LatencyUtils": { + "shasums": { + "jar": "a32a9ffa06b2f4e01c5360f8f9df7bc5d9454a5d373cd8f361347fa5a57165ec", + "sources": "717e271b5d67c190afba092795d79bba496434256aca7151cf6a02f83564e724" + }, + "version": "2.0.3" + }, + "org.mockito:mockito-core": { + "shasums": { + "jar": "d1a96d252128d3a4247cfd8a2e76412efa3cc103977be17933c942117a24f374", + "sources": "dcde489c1db6449c162f05105ace4c172850d3dc7f6633bb4f54d47a16a0fd1b" + }, + "version": "5.20.0" + }, + "org.mockito:mockito-junit-jupiter": { + "shasums": { + "jar": "fd6c703c2b00b914f3adbc27b18077a708f3d6992f19242c444e737c6cce024e", + "sources": "3c199479a2319db4395fd9fd209946ecc4530f48fe5cdeed7677c285bf70fbb5" + }, + "version": "5.20.0" + }, + "org.objenesis:objenesis": { + "shasums": { + "jar": "02dfd0b0439a5591e35b708ed2f5474eb0948f53abf74637e959b8e4ef69bfeb", + "sources": "d06164f8ca002c8ef193cef2d682822014dd330505616af93a3fb64226fc131d" + }, + "version": "3.3" + }, + "org.opentest4j.reporting:open-test-reporting-tooling-spi": { + "shasums": { + "jar": "04ac4ecfcaf60abe0e6d5b18e8306320aec7cd9cbf15e59eeac54fa9faa16902", + "sources": "efe9672e74111726c0ff85a2508a0bc78be611a7cbe460560dc7cd429ee0a4ce" + }, + "version": "0.2.4" + }, + "org.opentest4j:opentest4j": { + "shasums": { + "jar": "48e2df636cab6563ced64dcdff8abb2355627cb236ef0bf37598682ddf742f1b", + "sources": "724a24e3a68267d5ebac9411389a15638a71e50c62448ffa58f59c34d5c1ebb2" + }, + "version": "1.3.0" + }, + "org.ow2.asm:asm": { + "shasums": { + "jar": "03d99a74ad1ee5c71334ef67437f4ef4fe3488caa7c96d8645abc73c8e2017d4", + "sources": "e37000a2a0bc9f0bef373714ad7dde4082212351847b74618d483057a4ae186c" + }, + "version": "9.9" + }, + "org.ow2.asm:asm-analysis": { + "shasums": { + "jar": "6a15d28e8bd29ba4fd5bca4baf9b50e8fba2d7b51fbf78cfa0c875a7214c678b", + "sources": "ff731d401ea2407759ea19b4b025800d32495a51a912f2553d987cddda424773" + }, + "version": "9.9" + }, + "org.ow2.asm:asm-commons": { + "shasums": { + "jar": "db2f6f26150bbe7c126606b4a1151836bcc22a1e05a423b3585698bece995ff8", + "sources": "218bbb648e24578a385cb6b6a21ceff222a2a8f8b2d5f6a256a8099dd336dc76" + }, + "version": "9.9" + }, + "org.ow2.asm:asm-tree": { + "shasums": { + "jar": "42178f3775c9c63f9e5e1446747d29b4eca4d91bd6e75e5c43cfa372a47d38c6", + "sources": "9d1fe261fa1d29904ca9dbc76878396e76bc225191676a8c16ad2669a205321a" + }, + "version": "9.9" + }, + "org.ow2.asm:asm-util": { + "shasums": { + "jar": "3842e13cfe324ee9ab7cdc4914be9943541ead397c17e26daf0b8a755bede717", + "sources": "e518a00b1d004832e72c6448351c4865971ac95a7cfe78fb0315d76acb393a46" + }, + "version": "9.9" + }, + "org.projectlombok:lombok": { + "shasums": { + "jar": "01f7b1a015e33e2b62d5f5f37053306357ab1415fd181fcba7794f5d198c1126", + "sources": "5b78c305a65fbe257d57878bff6530e2b79e1a2cd660f45dcb7d7f8f5e56a483" + }, + "version": "1.18.46" + }, + "org.reactivestreams:reactive-streams": { + "shasums": { + "jar": "f75ca597789b3dac58f61857b9ac2e1034a68fa672db35055a8fb4509e325f28", + "sources": "5a7a36ae9536698c434ebe119feb374d721210fee68eb821a37ef3859b64b708" + }, + "version": "1.0.4" + }, + "org.rnorth.duct-tape:duct-tape": { + "shasums": { + "jar": "31cef12ddec979d1f86d7cf708c41a17da523d05c685fd6642e9d0b2addb7240", + "sources": "b385fd2c2b435c313b3f02988d351503230c9631bfb432261cbd8ce9765d2a26" + }, + "version": "1.0.8" + }, + "org.skyscreamer:jsonassert": { + "shasums": { + "jar": "719095c07d4203961320da593441d8b3b643c18eb1d81aa98ea933bb7eb351ba", + "sources": "a825c29f8cc40f85ea4e7a431a55d4278a785c34acdeef4cd1be7367f70ea6bb" + }, + "version": "1.5.3" + }, + "org.slf4j:jul-to-slf4j": { + "shasums": { + "jar": "cbb7d1aaaa9e871eb1a06594abd911bf97027152976edf1edc315be75239204e", + "sources": "b6dd2138f3e83d876bf07206d09f2b48ca655bc36a8e80b0c2a32ad19ab8f1d5" + }, + "version": "2.0.18" + }, + "org.slf4j:slf4j-api": { + "shasums": { + "jar": "44508fd1576500688c790b190acdd16fec4f8c79a3e0b900afd70503cf055f55", + "sources": "192e007cf7f2be41d40574e44521fc0b7ce55e01f13dbe0fa8707c8ae3329075" + }, + "version": "2.0.18" + }, + "org.springdoc:springdoc-openapi-starter-common": { + "shasums": { + "jar": "a0b5a6a5384b4a36718fd7a69efbd48311fd5f404c96ce286a6c285c5d0038e6", + "sources": "19a2612f56ea7d867c70cdae5e8fdf9d2b7a3cbdcba257c1d9ddfe88e48a74b0" + }, + "version": "3.0.3" + }, + "org.springdoc:springdoc-openapi-starter-webflux-api": { + "shasums": { + "jar": "a58f130aa60c47001e0d7b6b5e611edbbf187f58aa7d697dd720ac220f57b384", + "sources": "90968a39c963a144ee30248146dff38eb568edf57109ccddb843d6a92c1ef756" + }, + "version": "3.0.3" + }, + "org.springdoc:springdoc-openapi-starter-webmvc-api": { + "shasums": { + "jar": "c7e0221797240037eaf20c834f2d03fabec3f26051bd7052be8bf169f2c02876", + "sources": "e0fad37b01fefa5b52aec1cc09101017a397ae93f7ba8dace72ed29d1f2a3106" + }, + "version": "3.0.3" + }, + "org.springframework.boot:spring-boot": { + "shasums": { + "jar": "edb984d0bc80d209bed271e6d334fbfbfcf11cc4c1ef5059adc31c5bde7b1d7c", + "sources": "850ec7c91b0ff92c46797e0adcf1f47369d64a0cf4a8427d01b4834df129d0d4" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-actuator": { + "shasums": { + "jar": "edfedbcc5d33c8b0a8d0156dcc8cbf6234a33dc861001c7ec8ef63af19197b7e", + "sources": "d74a19a07e1eaf70bfe00b33332c3d61d82621e887b1a8af3b4dbb05051ca197" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-actuator-autoconfigure": { + "shasums": { + "jar": "59b188a313fda88bbe6cba613dd13aa00d1cc49135b11120ae5d451f72d49c00", + "sources": "c4aa275f1a4c97020d56d96cdb5f1b9a0b8157da06b62313c55e2d861e683c59" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-autoconfigure": { + "shasums": { + "jar": "1e8a953294fe76727965970de31e3bb08fba2b65e3ca0ee9b8bca492d0818d10", + "sources": "477e9834d7982b080b485c7baeb27ea399fca324d0442dc2f694a473b6a394fd" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-cassandra": { + "shasums": { + "jar": "8a69a41383b36eed9b58b462c698cf7ec825ea0ac3b131ce7c2f92419dbc3bc7", + "sources": "e580260c129670d80a96c84c2241d5cbad3d9f9a183d3af201b2b5acab96e3cd" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-data-cassandra": { + "shasums": { + "jar": "f17d6ed4fe4825abb68ec4743a3248d9e456c94e099e2653c392ee75cef4b8a6", + "sources": "d2fcf562626d79bc13f71284c2a9b820975ce0bd35e9e9daeef8deb05fb14e53" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-data-cassandra-test": { + "shasums": { + "jar": "5ad17d2ffcd040eae3f425e7588e2b2604461b47ac7801c5ccfb5179e6725832", + "sources": "73ca527b7a6d67b0e8a20865d91f0bb15092ef3415c7ebefe475bc14894440da" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-data-commons": { + "shasums": { + "jar": "991f28c95c3b5687d41429ec1da258d6ebdf33c1778dab2057361df9983dc6c7", + "sources": "bbfa0f3571ee162c21597e7fc7a925a5919e1267ebb55eb5b3698c2832de9ec0" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-health": { + "shasums": { + "jar": "e1c81e0e8d89ba7d25a3522d52159a4bcfa9bf7ee4e0d53cef61244e75a244bb", + "sources": "0d664e89d03dffde004f79e9aa5a7482128d0358c284edb0b5c2895eb25a43b7" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-http-client": { + "shasums": { + "jar": "7881d09b33f278b39fd1018d0cb7d91b73b72406d2350351166511b1c3a76c6b", + "sources": "17ee08d609a1d4d1d64198b9cf0cf79920974400460022b4b97117d22b7ea73a" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-http-codec": { + "shasums": { + "jar": "dd3e79f5bf872e34eca182f3a6f050278263562da042a1a0bc338f5d70d4ab60", + "sources": "4f2231f549e7353f3095b58995520bcb073d4c155aadc839f3f66d1b6543059e" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-http-converter": { + "shasums": { + "jar": "9f620c36cb98103ef664a9fccad4173ae20120d1abc790b795130be4e02dbb90", + "sources": "9f4378bcb3caa6696d8fe340c519bd673287f2c046098607cbe079ba9aa98874" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-jackson": { + "shasums": { + "jar": "0cdbadd10bcc3b23d32dffd419caceda4a4ed6b3da0262617f543732e9105ece", + "sources": "efe6e9f38861e94fbf36045bb23d23076407d26fed5752efb852ad2accaea3bb" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-micrometer-metrics": { + "shasums": { + "jar": "1cd20b112104d244fdc96b44b3a8193e0916686a819a6be93127c1c7eefc1c9d", + "sources": "b61f894a893ef3f3e0b978e7430f08c6b3580c19ac963bbbf8901a28b2d18f6b" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-micrometer-metrics-test": { + "shasums": { + "jar": "124e88e2d8ef0331653bb9d2c849143e210e97d3ded4e8cbdb0bd68c05ea2e65", + "sources": "b17d0251cee5454db0d3e573a8c23d6b0055de534fa49b75c18bc0af6ea9f100" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-micrometer-observation": { + "shasums": { + "jar": "aced85ab6f7a2a8b15d8bd52c2b75dfe47c9890dc08d39e24b2e7b78f79b6ac2", + "sources": "8e159976cbcf123f3333793f47e88c71932ff6f2f785db8c69831bfbcf75bc3b" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-micrometer-tracing": { + "shasums": { + "jar": "dfb60c9422c80957a020e8751317bc3515f3ed56d5d92da685bfece6c0ba780a", + "sources": "c0d8f28ffbd343b00586195ee8fd34d2441562c67f01cc100578f62145e51846" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-micrometer-tracing-opentelemetry": { + "shasums": { + "jar": "3463de0849ee471c99726b8c9a334cde69a96c78c496aa452db9d9f34b53603e", + "sources": "01b024f9530bce7dabf3592a3f50fe8063c1f9f5ae6d982edf73ba85410b3cd6" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-netty": { + "shasums": { + "jar": "d5526be25b050ad5e4dd7a56095b78357bf73bbe447d900588fe7f895873ff3f", + "sources": "34b0173a82c5b35275a773b213b20591c4047b87e3f0b6dc9c1d0736b5084591" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-opentelemetry": { + "shasums": { + "jar": "42ce3e301fb94f6d15efbed5bae1c3ea9f8fe8da93afa1ac4aacf1819c1d2cd4", + "sources": "f07c50fd5e2dc2b27fbcf08f2d7ad1b8663b8611788b6bf1f4b66fe5c5dbee5b" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-persistence": { + "shasums": { + "jar": "201cd088c5fddbcff7ece343f42eee0cabbab64083d339f35e5eb4edbcdbd4bb", + "sources": "863fc339ae51cc5b5287cac067ff5527cdff2ec8da85358d8bf61fa9a460568c" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-reactor": { + "shasums": { + "jar": "abb8ac783f1a3e2de68f2ececfb22ef4ba47c74089ce377a1476f3ccf5c35539", + "sources": "0753ac2c9596f010acdac06e9bc69d3d5a35dd9abec4e44c1de600dbb7577c13" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-reactor-netty": { + "shasums": { + "jar": "5679a1518fece25f608b6abdb165bae59c4ba1aa76833700fb6cf35d528575a1", + "sources": "35281bbd1465a0a22c1f6a2188c64e2efc8535f2e30807687c77ec15197b58ca" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-restclient": { + "shasums": { + "jar": "4438e7cbe09fe2d1aa40da4112cbc2a7f0067046dbfd153e79122be6e143c82a", + "sources": "87f4a654821800a30f5d41ac5320877cd96cf436a60ac2dd541369b159a4eff2" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-resttestclient": { + "shasums": { + "jar": "976fada4921b1817e1ced3c0da93a709d85638b519a9e63c3075e76c1e3c0593", + "sources": "ad2de8d55af3be0eba0e59259eb6427fd83eca7fdd134454a0c9cde2cde4c9bc" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-security": { + "shasums": { + "jar": "fef4d4952d7c4f86112d4a27cb98cf1d71001373f9d8f88fbf0af9d908fdaa3c", + "sources": "edc45113d48d5b3f7e3ef6f722ffb905a2b0bd5791e79879b591cfe74972178e" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-security-oauth2-client": { + "shasums": { + "jar": "37a6474b11b65f39b444971572e66553512992f4434280365cedcb396b8afbec", + "sources": "dcf7f976f5e8216498d3415508598fa6e8da7248a9ae3056f94fc3abfb76c65f" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-security-oauth2-resource-server": { + "shasums": { + "jar": "d33c17f53bab6054589d94bbc36f8ed017fb0c1cd353c9b8a85359b72d4d25e8", + "sources": "2d598d95730fca23bc1ab8d08af3cad04c6cd69e5d4f728d7ce25f3f5e410953" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-security-test": { + "shasums": { + "jar": "7e34b14edd632dc3cd911931d3e3d74de40d863aa1a1849be4b217a293b14004", + "sources": "ad5a8312d621e12e659b198ded8b8c1b1a2066b34940443856e6302bd8e885b1" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-servlet": { + "shasums": { + "jar": "fb1af769617daa2808a82921d98ca94efde8cb20fcefc55e71b2e0bf93de1423", + "sources": "172a6736933d75bdeeee725078769e27d8142a826e811940c595aea815913512" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-starter": { + "shasums": { + "jar": "d70f5f300c9e7af18813799bffce38974398f6429c578c825822a32560c4b202", + "sources": "d70f5f300c9e7af18813799bffce38974398f6429c578c825822a32560c4b202" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-starter-actuator": { + "shasums": { + "jar": "576d445c6d0b7920f098822f45d74c2239f363d06508f8acf2a181f0b69c2cb9", + "sources": "576d445c6d0b7920f098822f45d74c2239f363d06508f8acf2a181f0b69c2cb9" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-starter-actuator-test": { + "shasums": { + "jar": "9f87aeefd9049094dd1fd64d96632bee353f871e0999c7c0531d69a2dcf7a945", + "sources": "9f87aeefd9049094dd1fd64d96632bee353f871e0999c7c0531d69a2dcf7a945" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-starter-data-cassandra": { + "shasums": { + "jar": "32abc561b414e781bc1998e1a6cd1167f3eff2247e6bb2b1b08a347bb3054acb", + "sources": "32abc561b414e781bc1998e1a6cd1167f3eff2247e6bb2b1b08a347bb3054acb" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-starter-data-cassandra-test": { + "shasums": { + "jar": "aacd60f7f5cab180a23dbd87fd5b53d524c2c89ce42635d5eaa4331075dec548", + "sources": "aacd60f7f5cab180a23dbd87fd5b53d524c2c89ce42635d5eaa4331075dec548" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-starter-jackson": { + "shasums": { + "jar": "bd042218bf291c4ee821d7ec3e86f7f747223d32cd87066aa5e3730a2dd5c3b6", + "sources": "bd042218bf291c4ee821d7ec3e86f7f747223d32cd87066aa5e3730a2dd5c3b6" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-starter-jackson-test": { + "shasums": { + "jar": "72ad611e32e370446bb2de890da4f084def1d354f4526522f0ae1182265b545a", + "sources": "72ad611e32e370446bb2de890da4f084def1d354f4526522f0ae1182265b545a" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-starter-logging": { + "shasums": { + "jar": "b5f1d01cd179ffc24b125a6ce971854b7b141c4e19e9c050a0b82d514983b1f6", + "sources": "b5f1d01cd179ffc24b125a6ce971854b7b141c4e19e9c050a0b82d514983b1f6" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-starter-micrometer-metrics": { + "shasums": { + "jar": "a5d302b2d6e9a8e1989455888aad2f69349f4c0b43b7ef41c8063c4bb92dec32", + "sources": "a5d302b2d6e9a8e1989455888aad2f69349f4c0b43b7ef41c8063c4bb92dec32" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-starter-micrometer-metrics-test": { + "shasums": { + "jar": "dd6d8969ce0e7736d29c5ce1dbdf9d9d89ac0c7ecbae41485abeb5b3efe87546", + "sources": "dd6d8969ce0e7736d29c5ce1dbdf9d9d89ac0c7ecbae41485abeb5b3efe87546" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-starter-reactor-netty": { + "shasums": { + "jar": "ceebf772bae1c9492fce1c766fdc18a7a17388f02f639a6ba20824b8a3dd848c", + "sources": "ceebf772bae1c9492fce1c766fdc18a7a17388f02f639a6ba20824b8a3dd848c" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-starter-security": { + "shasums": { + "jar": "04e806b5737be0d399c85d356b060599684df6fc4f56cc08b85a563ae1a066dd", + "sources": "04e806b5737be0d399c85d356b060599684df6fc4f56cc08b85a563ae1a066dd" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-starter-security-oauth2-client": { + "shasums": { + "jar": "1afd7f96736afc19451ad2a4f001e54af93d9d9d788802df9f4e536860560aca", + "sources": "1afd7f96736afc19451ad2a4f001e54af93d9d9d788802df9f4e536860560aca" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server": { + "shasums": { + "jar": "72dbb14dc0b21f43cee18ae6caa6bf7b0c4efe4bac11702e34529280865ecd83", + "sources": "72dbb14dc0b21f43cee18ae6caa6bf7b0c4efe4bac11702e34529280865ecd83" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server-test": { + "shasums": { + "jar": "8e13abf7c7754171c83c8236b796ef3d6e8d841a3ddafd84dfec0e5615b77e75", + "sources": "8e13abf7c7754171c83c8236b796ef3d6e8d841a3ddafd84dfec0e5615b77e75" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-starter-security-test": { + "shasums": { + "jar": "a7320624975022865468e255b8e0c414f76d380eef7793faeca87f98496998ad", + "sources": "a7320624975022865468e255b8e0c414f76d380eef7793faeca87f98496998ad" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-starter-test": { + "shasums": { + "jar": "e4844ae2375d569711af218763620993ea434b4836d3463cf26d9f6b6e589340", + "sources": "e4844ae2375d569711af218763620993ea434b4836d3463cf26d9f6b6e589340" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-starter-tomcat": { + "shasums": { + "jar": "f4a81ce616baa9c715be0dc0735210d770aa67301f92d3b11942f780056fc7ad", + "sources": "f4a81ce616baa9c715be0dc0735210d770aa67301f92d3b11942f780056fc7ad" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-starter-tomcat-runtime": { + "shasums": { + "jar": "8d0c7cbd6bd43d47e664a9127f70ceddab952828797f20e2b0b93848796d82f2", + "sources": "8d0c7cbd6bd43d47e664a9127f70ceddab952828797f20e2b0b93848796d82f2" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-starter-validation": { + "shasums": { + "jar": "bc449f60bb483374e7358afcda3fccb6e01906e158c7e1e00d9035277a6545b7", + "sources": "bc449f60bb483374e7358afcda3fccb6e01906e158c7e1e00d9035277a6545b7" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-starter-webflux": { + "shasums": { + "jar": "dd99ab79bd18c6358183b146c3eb35730652dd36d2225d5795405efa7137b1a0", + "sources": "dd99ab79bd18c6358183b146c3eb35730652dd36d2225d5795405efa7137b1a0" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-starter-webflux-test": { + "shasums": { + "jar": "78c866953b611065c85b8f069b18d330c1f2051db932fc3a3e8213b852b7f8eb", + "sources": "78c866953b611065c85b8f069b18d330c1f2051db932fc3a3e8213b852b7f8eb" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-starter-webmvc": { + "shasums": { + "jar": "b70e0d9e1bc667a3a9ad509f98a6e9ac443af8eab5143f8c77a38aec0a014a2c", + "sources": "b70e0d9e1bc667a3a9ad509f98a6e9ac443af8eab5143f8c77a38aec0a014a2c" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-starter-webmvc-test": { + "shasums": { + "jar": "d11fd7bbd613040f88ddba503c486970dd282abb92f12158bc9655ee533e9f31", + "sources": "d11fd7bbd613040f88ddba503c486970dd282abb92f12158bc9655ee533e9f31" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-test": { + "shasums": { + "jar": "8879b4a336972eb498ca6606266e6ecdae911964c0a480d3f4bf37a6c2455b33", + "sources": "4dc67a1a332d75fa3dcf517f4b6dc66ed146793307aa9d23c0ebb5f4b399850a" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-test-autoconfigure": { + "shasums": { + "jar": "99ca7ab8be0dde10fa6c03e1026969619e826fcc914b6bc0d09090e75ba17cb4", + "sources": "f94cf34c24539cc3752fae1a0bf182282086452e9c83cfae5241574f20951eb3" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-tomcat": { + "shasums": { + "jar": "ad7c6527319f5cac0b5638a28820847f64d21282147fb98daaaa1f515ee17323", + "sources": "2388d2eaeb9d413d3d7525983fe14030d3b48bc0cca1530c8c7e9dc73e05e8b5" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-validation": { + "shasums": { + "jar": "15161d6eda4589a24ea30d1fd466bfe3843861c3b55963d49a26bfc0bf2ebbb2", + "sources": "52beb1b2b90adb6cec5bf8523e534e56fed771a7f0fe3d42191a4d3b8a5d3873" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-web-server": { + "shasums": { + "jar": "26a13c73ee85e7a851b73eb2d683ed4d3b7a4ca581b608dfd627bd4551997cf2", + "sources": "41e1dddf6e1be5fc35c4849f51639c097e7a8eb9c6627a780791a1d9e430c311" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-webclient": { + "shasums": { + "jar": "119d82faa651b35964eab73ea3d962b1c7434792647cbf82c9dde44785749671", + "sources": "bf3dd5bf566482bc32c0c75548eb9c6a598b4d26c66677cfb84fca4cd21ccf81" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-webflux": { + "shasums": { + "jar": "7eca957fe0ad8ee60642d58e6a8e652ebaf64198b72f9ccfa959bea056fb7091", + "sources": "fc7dcb5570215a40c78fdab85c60876b740be714cb479d03b3bd39b2c7b26e5f" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-webflux-test": { + "shasums": { + "jar": "3ed73416ab316d0247d9c2efbb922db1247f03d114fada897f70f9d59408c839", + "sources": "5164cd1c633380d2f2616855a2773f099f15aebc2ad70c04a942e673be12be6b" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-webmvc": { + "shasums": { + "jar": "95250948bda9a0a1e1f2ad3f413bd23e36dfedefb89fe59d309d447c6c4c5010", + "sources": "26a04367e170092463c619c886f4f8b688644eecc4a6c91c18d17c242a8f4211" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-webmvc-test": { + "shasums": { + "jar": "06180d3ee7f9019880b0528cc93164f8f038e35007bd99a40fbe52892d96a955", + "sources": "4c5b614a96d50a44fce7c3269b82f26fed6d3d04933140ecf52db5e4d32e2480" + }, + "version": "4.0.7" + }, + "org.springframework.boot:spring-boot-webtestclient": { + "shasums": { + "jar": "7015636f7e41b69d80fd903acdcb1554f2b062551c1ce353e625ea4a11f52903", + "sources": "b1175e4937c93d493bbae0a2c7e2cee13cd60a6b7dd859fb6e662091f986e28f" + }, + "version": "4.0.7" + }, + "org.springframework.cloud:spring-cloud-commons": { + "shasums": { + "jar": "6973e75b09d7ccb98566e4e980f600cd98ffcdc76d19fd822e93c7c2166ffa49", + "sources": "fd39f42ebda40c120a450256bbca653d250ff105ea640a530680c1251ced5ca3" + }, + "version": "5.0.2" + }, + "org.springframework.cloud:spring-cloud-context": { + "shasums": { + "jar": "8972e4677e511dc518280d13a16d1a3e6e3ed4ee91e643d3f0c66676f6078f75", + "sources": "3765a79f4a43fe01a1298b09cd8ee51f0e9692971555478fd157bdf456a70c7b" + }, + "version": "5.0.2" + }, + "org.springframework.cloud:spring-cloud-starter": { + "shasums": { + "jar": "7568b8ced4069bc055af52b5455b206092401a44dcbd4f89d6fa00f89df1cc18" + }, + "version": "5.0.2" + }, + "org.springframework.cloud:spring-cloud-starter-bootstrap": { + "shasums": { + "jar": "366aa9da9bd1e8222bed83fa698649b16ba4b2a976a028d565b95afe610735df", + "sources": "46bb02036834b9db0cfe086ca2b4e9581319029e9dff2b420ddf3eb8094f3d62" + }, + "version": "5.0.2" + }, + "org.springframework.data:spring-data-cassandra": { + "shasums": { + "jar": "d9e4f2656df238d5561d02d0521036f52518b91d0ef840fd8f25d113b4325610", + "sources": "35340468867c3c37447606312f1d2e2ab18b5123885967a364743f77f196bdb7" + }, + "version": "5.0.6" + }, + "org.springframework.data:spring-data-commons": { + "shasums": { + "jar": "626151b9c33ab98ebec7f1a2e9746cfe1aa428b0de513f9bb90383533ab8ba6d", + "sources": "8d08a88e7b6761bfb84a79fadde38bafaeeed90ddf4595ba9cbf71c25ed7e2dd" + }, + "version": "4.0.6" + }, + "org.springframework.security:spring-security-config": { + "shasums": { + "jar": "7aeafd876d48d8b5660356953ed7a607d2d09e8f2b9844acba3fcbc32beb63cc", + "sources": "aeb9131e5cd38ea7ebeb0d348c90da837c807f8b68ae3c0fc3152a46682f16ee" + }, + "version": "7.0.6" + }, + "org.springframework.security:spring-security-core": { + "shasums": { + "jar": "f9e1aebb39e051f6f92be029a6fca31e2977a06d417aa51504bfb298bc2a7c69", + "sources": "73d208a0dd021cad8cbbb85a71c8efc66df0161f49e91cd9d877a55def6bc9d0" + }, + "version": "7.0.6" + }, + "org.springframework.security:spring-security-crypto": { + "shasums": { + "jar": "baf9f76bc5b15d090a82841fd5713fa11b75f91fc86de27029d972ce85d3d2e2", + "sources": "bb183230f96711625bdc1d0fc45398917062c2b6b605f94f8dbf0de6a7a1f862" + }, + "version": "7.0.6" + }, + "org.springframework.security:spring-security-oauth2-client": { + "shasums": { + "jar": "2c50bff8f60f08a46bef837dca50d1270f0dba64a60f551c0b96b33a1f608487", + "sources": "47549b16e028266bf4836b4bf00e9111a46143ae486aaed1ff0370c56ddbe82a" + }, + "version": "7.0.6" + }, + "org.springframework.security:spring-security-oauth2-core": { + "shasums": { + "jar": "01cc03b6f30e5b526e85fc276b32af25f34b119f601bc17ba3cbe023f45b0271", + "sources": "68bc19e0b85c108766d92bc4a9e9948a641d65d23d1d93cca7f724998665f88f" + }, + "version": "7.0.6" + }, + "org.springframework.security:spring-security-oauth2-jose": { + "shasums": { + "jar": "c8cd9a8aefc42a02e34166ff02f3f7def2f6028f555932f04f163dea729bdff9", + "sources": "1a33db514d2ce33222aae9bb3ba41227112de08986aac4e58be857417e7332ea" + }, + "version": "7.0.6" + }, + "org.springframework.security:spring-security-oauth2-resource-server": { + "shasums": { + "jar": "4c53ad5b6a06b9f6272212b5a0a71d003b4ba01dd16de691fd63ddf37554f098", + "sources": "97d33151cd02afcded341ab7ad65f1bcca4798789f5626a5d948809ba529373a" + }, + "version": "7.0.6" + }, + "org.springframework.security:spring-security-test": { + "shasums": { + "jar": "4b65c38c7fcf372793cdf6e57651be1332ec241fff9481b15ed8f3ea2207382c", + "sources": "61886c39c6853ebafa91718c1bc44ebaad6f834dcb8d0524e509135033c9498c" + }, + "version": "7.0.6" + }, + "org.springframework.security:spring-security-web": { + "shasums": { + "jar": "6ef060f97271218c0bff56273dc2edb8e2e001a253a0291278d5fdafa5d70573", + "sources": "33298fd169429984bb6cebf9f4a6176ae9eee047e8b5a3ab6b3d752526db03d9" + }, + "version": "7.0.6" + }, + "org.springframework:spring-aop": { + "shasums": { + "jar": "1178f039e087884174e2affc46e484f4a8bd7f2a4e011d33dd9137709f740f80", + "sources": "580610d9e5e2418ea48f64850673ed1d1fdc2d9c8e5cf6e9cfaece1e61b70522" + }, + "version": "7.0.8" + }, + "org.springframework:spring-beans": { + "shasums": { + "jar": "6ec2e361a8872a71d8b1ff66f1bcb8cfa29fcc437931998919da7cecfb59b45b", + "sources": "d75bdcfe142b1576f72356748292cad5c21872a52be2c7f2920a9795bb3c52a5" + }, + "version": "7.0.8" + }, + "org.springframework:spring-context": { + "shasums": { + "jar": "1eb7d552414ebac00e30ab3e809138d810785f6d2c4271db77cdf0181f308f19", + "sources": "a28b30679b51bcf8aac7f06cb564a379cc2d6c4891b2e2dfc738ddd750c6278e" + }, + "version": "7.0.8" + }, + "org.springframework:spring-core": { + "shasums": { + "jar": "726ba2a5130833644bdf267a55ff26e1f52e8dcc9aa1ffa06904ca9c14619f25", + "sources": "3cbdaed9f2b1eea10d8ac27148ac5e6407d2861fa2d373253a09a1220a232919" + }, + "version": "7.0.8" + }, + "org.springframework:spring-expression": { + "shasums": { + "jar": "3c97c38ab59c77ee886e08ccf8096f6bb58a1245f68dfed7a40e93f41c435f9a", + "sources": "35517249c504d1d4550186808665587c8bb5be953cb6cbbb3856804194e790e9" + }, + "version": "7.0.8" + }, + "org.springframework:spring-test": { + "shasums": { + "jar": "6ffb7796075a204915edc4bb9e54dc420183cecb520d753004f660f153763c8e", + "sources": "7bc670e2e1c9cc902da5557a857dde0a4d8089c267ccfcc1bb554cbf2a8c5a05" + }, + "version": "7.0.8" + }, + "org.springframework:spring-tx": { + "shasums": { + "jar": "57e8fdb6de949e7ec2617683fec03af0253bdbdf4bf3d2651a926a94413df283", + "sources": "7887541d74a7221ca92e21d1a2ecc13e8f98767b1603b3b6bb81d7bbd5aede48" + }, + "version": "7.0.8" + }, + "org.springframework:spring-web": { + "shasums": { + "jar": "4d4ed7ecb0453d25d735ea27d025ea36b003c3d29cb7d006bedd6d5188a2f5c0", + "sources": "281cbbd965844cdf2e08396924eacd8a369cd38f56fdfb9519c7492217d8b411" + }, + "version": "7.0.8" + }, + "org.springframework:spring-webflux": { + "shasums": { + "jar": "3e48db9c30d3768ac14898cfad4bad21f4cfc6a8979a12071b75e725143e5eb9", + "sources": "9b00f6ad4a63f3c636e455f3e733d0f75cf5dcdd8225820a1498469b707652ba" + }, + "version": "7.0.8" + }, + "org.springframework:spring-webmvc": { + "shasums": { + "jar": "48f7e1e2d0d46e98ed3fa30d5a64cb1f7ed2aa339a82edcd87289ed8ff216f04", + "sources": "6dcbc3dc4d5222121f83d1eb0d30807e389771b8d233be38b8e413b92b88a106" + }, + "version": "7.0.8" + }, + "org.testcontainers:testcontainers": { + "shasums": { + "jar": "0466f481343d5f350a91274cd7bf984308cbaf90d706247fd1cf4b1a8010c2e1", + "sources": "b4dfdb7d0f8dadc6bfa6d817df703b5c6881b83b6d0452148fd9a00434387e24" + }, + "version": "2.0.5" + }, + "org.testcontainers:testcontainers-cassandra": { + "shasums": { + "jar": "c6ce343636e40330da6ffa317ca4a56bf09affd3e272445d0176498497218cbe", + "sources": "4b2324b4336a0e6d928467abef387ded2b9014ab1353f85cf715f87d1dbb5be3" + }, + "version": "2.0.5" + }, + "org.testcontainers:testcontainers-database-commons": { + "shasums": { + "jar": "0ebbc62bdcfb315cb840a63fbaa148b455927666d9034b5e5c00009d84c755b0", + "sources": "017efc160847bf209b3fdfa3561fa6eb1a5b5b5b82d2214f965caabe9c2cf9ab" + }, + "version": "2.0.5" + }, + "org.testcontainers:testcontainers-junit-jupiter": { + "shasums": { + "jar": "d66eb7f257a85833a8cc973e3814d740967d40a7db1a0de0040653c6ed236748", + "sources": "0dd4463ca900cbce90894cdaafb18fd146ea50b92ee0ee72a9c3e1e48b53a8e6" + }, + "version": "2.0.5" + }, + "org.wiremock:wiremock-standalone": { + "shasums": { + "jar": "d097b19bd483c5038479b13a5c71e9faf8f2f5106584f0c120a7770ab0bdb367", + "sources": "76cda98377991ed09088773fe7127f9787e14f8bd41bcd285f94cbd7cd95546f" + }, + "version": "3.13.2" + }, + "org.xmlunit:xmlunit-core": { + "shasums": { + "jar": "208e0cee82aedd9183937e4b9ae44b83884179f724a706bef5795477acfcca91", + "sources": "bb8dba65e8bc1ade346e4bfd98d7f620f51ae8b9034e9758cd6f3031838e79fd" + }, + "version": "2.10.4" + }, + "org.yaml:snakeyaml": { + "shasums": { + "jar": "e6682acf1ace77508ef13649cbf4f8d09d2cf5457bdb61d25ffb6ac0233d78dd", + "sources": "7a7d307ca9fe1663219a60045a8e5a113a69331566f9ebbe1d3b12c6781909ac" + }, + "version": "2.5" + }, + "software.amazon.awssdk:annotations": { + "shasums": { + "jar": "fa3ba3b1b635dfc4d0b20f3910b325f8b70419d1fdb56b487d2e1c423c85e041", + "sources": "2c15cad3cec83ce99c86b9f135d24f42429c5c9a4d032351adfc42330cde8b97" + }, + "version": "2.40.1" + }, + "software.amazon.awssdk:checksums": { + "shasums": { + "jar": "6770fdd0d970c1869cd869d784cc20963a4a6b2bee09f125da0504ba2c9e818d", + "sources": "3a5de1a7994ab25bef0eda898645ba6f02ab584bd3d904f21014bfd9d7cb98b5" + }, + "version": "2.40.1" + }, + "software.amazon.awssdk:checksums-spi": { + "shasums": { + "jar": "1f9d68cd2f5ec133757e37b794ab06de015d1b35f4c1452b43ab8b612318a8c3", + "sources": "d17d8d92268f9c6773aa6b72564774dc394ae2fb2149bed26152385a9b6751ff" + }, + "version": "2.40.1" + }, + "software.amazon.awssdk:endpoints-spi": { + "shasums": { + "jar": "05a48200f243664fa9ca8f05cf29725cbd059a9a6f3cdd55bac44a8fc12903de", + "sources": "24644eb6a36a38df7a31e81fb9fcd106298f188215b6e2ec178732711fc4b0ba" + }, + "version": "2.40.1" + }, + "software.amazon.awssdk:http-auth-aws": { + "shasums": { + "jar": "9b182f3697acc111b213524126f857f844fed5fdf95f734470d16b96097fcd3a", + "sources": "6de3c527d996a46a4e14e268fc13a32b314383a3b2976e7820720c9ddff483a5" + }, + "version": "2.40.1" + }, + "software.amazon.awssdk:http-auth-spi": { + "shasums": { + "jar": "d0cd6f8dd1ef77a990c4b0ae45132707490f886307d9ee446ae1eae93a80ae5a", + "sources": "6bd36a3bfbce87b5550d73ad7ff6d0950dc6aec1baf071b0c47bd02cd98daa3d" + }, + "version": "2.40.1" + }, + "software.amazon.awssdk:http-client-spi": { + "shasums": { + "jar": "87c6fc3ec6c79e088ebfcc818963715bc0a5e103f5612bd4b6d5c49720bb06e3", + "sources": "d6667c353cc231efee460dae061be2b654d3319ffb66d16804da30f5a8475d84" + }, + "version": "2.40.1" + }, + "software.amazon.awssdk:identity-spi": { + "shasums": { + "jar": "b4693f3832b3669850a11f29608a2a3d6e0150ab1528d01cad2a7a32848db591", + "sources": "56ab003dea16ded5f70c1a3af840433c6f5f8fd33435500535e7b888cdf8c923" + }, + "version": "2.40.1" + }, + "software.amazon.awssdk:json-utils": { + "shasums": { + "jar": "f565187ae223ab13a4b959f213933540475652269c414b0c82f33cab45977a74", + "sources": "3fbd4a882a672587b93b9cdd2ee7c2c1faa0f5a848509d3d3d7931ef714d6d95" + }, + "version": "2.40.1" + }, + "software.amazon.awssdk:metrics-spi": { + "shasums": { + "jar": "033b5d20384c9b4ac98a17eba0656711738da94a9d33a292b414aa0905177471", + "sources": "373fbebacc328596dda847d8183f22b9e6abef85f7c6287d7c71615cab3d4939" + }, + "version": "2.40.1" + }, + "software.amazon.awssdk:profiles": { + "shasums": { + "jar": "602cac04531cf13d4c06d8d70d7b5b0e109517c73a4c91473058886fbe574cc1", + "sources": "e498cf7ef147b8fc789a448554561b5706daae1062a5e23bc4870149b42d8002" + }, + "version": "2.40.1" + }, + "software.amazon.awssdk:regions": { + "shasums": { + "jar": "6b1c788306fd7a4fac6bc788a8f5d2300be13049197adacfca072d1b69eb9ddb", + "sources": "1bae6ad3cb124a6850fbede87c9dcd72f7c7eab1f570c9ae71a98f3597c4b59f" + }, + "version": "2.40.1" + }, + "software.amazon.awssdk:retries": { + "shasums": { + "jar": "198f5f0202fe8e861f3ad2fa8ecb70d0a8180dd568f4d136c898f824b3cd0dd3", + "sources": "2305b334eceb894749d281a3f48be9198e9305f09cb3b40b948a5c661c20c41a" + }, + "version": "2.40.1" + }, + "software.amazon.awssdk:retries-spi": { + "shasums": { + "jar": "af1c67e4212fffe7d215b41fb74e6994c36a0499234e325954c38db6b14e0e28", + "sources": "c8e5f28924cc8e0cb017a2a25c370a0d0ed9223cfb0051c6a1b0c769a5a46e0b" + }, + "version": "2.40.1" + }, + "software.amazon.awssdk:sdk-core": { + "shasums": { + "jar": "6c6b1a49b18538060d1f9a797998ca8d589910b274b345bbf0a61c4540e41f27", + "sources": "560156fe956a48cd171077edc2ccb1bcfe2f93c09e3ce62667018228b6144450" + }, + "version": "2.40.1" + }, + "software.amazon.awssdk:third-party-jackson-core": { + "shasums": { + "jar": "9939a77038dd0d53675a44fc06afb9b34805cef8fc7b3641d2e861740c1655fc", + "sources": "92ce15d5817f97d935c595b780135666d4674eaf3aeb94ae13b1e4e553f93e42" + }, + "version": "2.40.1" + }, + "software.amazon.awssdk:utils": { + "shasums": { + "jar": "40f19e6ce26acc6a78204aa493833f578e2245cc0bc9749cc9ba431bb8f855e1", + "sources": "2ddd7c56fbc36d7c4e0c84739d68388faff130f51855ce2b80466c8784cf1b25" + }, + "version": "2.40.1" + }, + "tools.jackson.core:jackson-core": { + "shasums": { + "jar": "3bda1cd6eff0a8d47bdfcaeae7c2bd5311d6c8ed494ef5f3e51029bb44aa9bdf", + "sources": "5aa481c1c120505fc1d204510ec201a40c2bb0bb6bdea24560e0b5fb66484e60" + }, + "version": "3.1.4" + }, + "tools.jackson.core:jackson-databind": { + "shasums": { + "jar": "14034bfdf392b6ebec1b4bb6c1de29d604f0aa97251259a19d5f19af8719bb20", + "sources": "109baa39968ff6fdcc4389dd4249f04d2edcab7387421ea17bfb51bf18e24189" + }, + "version": "3.1.4" + }, + "tools.jackson.module:jackson-module-blackbird": { + "shasums": { + "jar": "d93aef324acdbffeb4e943e75ed0772f43101930b70fe37219147e5d3b84b3cd", + "sources": "5c7f6900e8b888c6c3edad9b13cd4df0d11f5bd8307064bb79881cb4edd389ef" + }, + "version": "3.1.4" + } + }, + "conflict_resolution": { + "com.github.jnr:jnr-ffi:2.2.11": "com.github.jnr:jnr-ffi:2.1.7", + "com.github.jnr:jnr-posix:3.0.44": "com.github.jnr:jnr-posix:3.1.15", + "org.jetbrains:annotations:13.0": "org.jetbrains:annotations:17.0.0", + "org.ow2.asm:asm-commons:5.0.3": "org.ow2.asm:asm-commons:9.9", + "org.ow2.asm:asm-tree:5.0.3": "org.ow2.asm:asm-tree:9.9", + "org.ow2.asm:asm:5.0.3": "org.ow2.asm:asm:9.9", + "org.ow2.asm:asm:9.7.1": "org.ow2.asm:asm:9.9" + }, + "dependencies": { + "ch.qos.logback:logback-classic": [ + "ch.qos.logback:logback-core", + "org.slf4j:slf4j-api" + ], + "com.datastax.cassandra:cassandra-driver-core": [ + "com.fasterxml.jackson.core:jackson-databind", + "com.github.jnr:jnr-ffi", + "com.github.jnr:jnr-posix", + "com.google.guava:guava", + "io.dropwizard.metrics:metrics-core", + "io.netty:netty-handler", + "org.slf4j:slf4j-api" + ], + "com.fasterxml.jackson.core:jackson-databind": [ + "com.fasterxml.jackson.core:jackson-annotations", + "com.fasterxml.jackson.core:jackson-core" + ], + "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml": [ + "com.fasterxml.jackson.core:jackson-core", + "com.fasterxml.jackson.core:jackson-databind", + "org.yaml:snakeyaml" + ], + "com.fasterxml.jackson.datatype:jackson-datatype-jsr310": [ + "com.fasterxml.jackson.core:jackson-annotations", + "com.fasterxml.jackson.core:jackson-core", + "com.fasterxml.jackson.core:jackson-databind" + ], + "com.github.ben-manes.caffeine:caffeine": [ + "com.google.errorprone:error_prone_annotations", + "org.jspecify:jspecify" + ], + "com.github.ben-manes.caffeine:guava": [ + "com.github.ben-manes.caffeine:caffeine", + "com.google.guava:guava" + ], + "com.github.docker-java:docker-java-api": [ + "com.fasterxml.jackson.core:jackson-annotations", + "org.slf4j:slf4j-api" + ], + "com.github.docker-java:docker-java-transport-zerodep": [ + "com.github.docker-java:docker-java-transport", + "net.java.dev.jna:jna", + "org.slf4j:slf4j-api" + ], + "com.github.java-json-tools:btf": [ + "com.google.code.findbugs:jsr305" + ], + "com.github.java-json-tools:jackson-coreutils": [ + "com.fasterxml.jackson.core:jackson-databind", + "com.github.java-json-tools:msg-simple", + "com.google.code.findbugs:jsr305" + ], + "com.github.java-json-tools:json-patch": [ + "com.fasterxml.jackson.core:jackson-databind", + "com.github.java-json-tools:jackson-coreutils", + "com.github.java-json-tools:msg-simple" + ], + "com.github.java-json-tools:msg-simple": [ + "com.github.java-json-tools:btf", + "com.google.code.findbugs:jsr305" + ], + "com.github.jnr:jnr-ffi": [ + "com.github.jnr:jffi", + "com.github.jnr:jffi:jar:native", + "com.github.jnr:jnr-x86asm", + "org.ow2.asm:asm", + "org.ow2.asm:asm-analysis", + "org.ow2.asm:asm-commons", + "org.ow2.asm:asm-tree", + "org.ow2.asm:asm-util" + ], + "com.github.jnr:jnr-posix": [ + "com.github.jnr:jnr-constants", + "com.github.jnr:jnr-ffi" + ], + "com.google.guava:guava": [ + "com.google.code.findbugs:jsr305", + "com.google.errorprone:error_prone_annotations", + "com.google.guava:failureaccess", + "com.google.guava:listenablefuture", + "com.google.j2objc:j2objc-annotations", + "org.checkerframework:checker-qual" + ], + "com.jayway.jsonpath:json-path": [ + "net.minidev:json-smart", + "org.slf4j:slf4j-api" + ], + "com.nimbusds:oauth2-oidc-sdk": [ + "com.github.stephenc.jcip:jcip-annotations", + "com.nimbusds:content-type", + "com.nimbusds:lang-tag", + "com.nimbusds:nimbus-jose-jwt", + "net.minidev:json-smart" + ], + "com.squareup.okhttp3:okhttp-jvm": [ + "com.squareup.okio:okio-jvm", + "org.jetbrains.kotlin:kotlin-stdlib" + ], + "com.squareup.okio:okio-jvm": [ + "org.jetbrains.kotlin:kotlin-stdlib" + ], + "io.cloudevents:cloudevents-core": [ + "io.cloudevents:cloudevents-api" + ], + "io.cloudevents:cloudevents-json-jackson": [ + "com.fasterxml.jackson.core:jackson-core", + "com.fasterxml.jackson.core:jackson-databind", + "io.cloudevents:cloudevents-core" + ], + "io.dropwizard.metrics:metrics-core": [ + "org.slf4j:slf4j-api" + ], + "io.micrometer:context-propagation": [ + "org.jspecify:jspecify" + ], + "io.micrometer:micrometer-commons": [ + "org.jspecify:jspecify" + ], + "io.micrometer:micrometer-core": [ + "io.micrometer:micrometer-commons", + "io.micrometer:micrometer-observation", + "org.hdrhistogram:HdrHistogram", + "org.jspecify:jspecify", + "org.latencyutils:LatencyUtils" + ], + "io.micrometer:micrometer-jakarta9": [ + "io.micrometer:micrometer-commons", + "io.micrometer:micrometer-core", + "io.micrometer:micrometer-observation", + "org.jspecify:jspecify" + ], + "io.micrometer:micrometer-observation": [ + "io.micrometer:micrometer-commons", + "org.jspecify:jspecify" + ], + "io.micrometer:micrometer-observation-test": [ + "io.micrometer:micrometer-observation", + "org.assertj:assertj-core", + "org.jspecify:jspecify", + "org.junit.jupiter:junit-jupiter", + "org.mockito:mockito-core" + ], + "io.micrometer:micrometer-tracing": [ + "aopalliance:aopalliance", + "io.micrometer:context-propagation", + "io.micrometer:micrometer-observation", + "org.jspecify:jspecify" + ], + "io.micrometer:micrometer-tracing-bridge-otel": [ + "io.micrometer:micrometer-observation", + "io.micrometer:micrometer-tracing", + "io.opentelemetry.semconv:opentelemetry-semconv", + "io.opentelemetry:opentelemetry-api", + "io.opentelemetry:opentelemetry-extension-trace-propagators", + "io.opentelemetry:opentelemetry-sdk", + "io.opentelemetry:opentelemetry-sdk-common", + "io.opentelemetry:opentelemetry-sdk-trace", + "org.jspecify:jspecify", + "org.slf4j:slf4j-api" + ], + "io.nats:jnats": [ + "org.bouncycastle:bcprov-lts8on", + "org.jspecify:jspecify" + ], + "io.netty:netty-buffer": [ + "io.netty:netty-common" + ], + "io.netty:netty-codec-base": [ + "io.netty:netty-buffer", + "io.netty:netty-common", + "io.netty:netty-transport" + ], + "io.netty:netty-codec-compression": [ + "io.netty:netty-buffer", + "io.netty:netty-codec-base", + "io.netty:netty-common", + "io.netty:netty-transport" + ], + "io.netty:netty-codec-dns": [ + "io.netty:netty-buffer", + "io.netty:netty-codec-base", + "io.netty:netty-common", + "io.netty:netty-transport" + ], + "io.netty:netty-codec-http": [ + "io.netty:netty-buffer", + "io.netty:netty-codec-base", + "io.netty:netty-codec-compression", + "io.netty:netty-common", + "io.netty:netty-handler", + "io.netty:netty-transport" + ], + "io.netty:netty-codec-http2": [ + "io.netty:netty-buffer", + "io.netty:netty-codec-base", + "io.netty:netty-codec-http", + "io.netty:netty-common", + "io.netty:netty-handler", + "io.netty:netty-transport" + ], + "io.netty:netty-codec-http3": [ + "io.netty:netty-buffer", + "io.netty:netty-codec-base", + "io.netty:netty-codec-classes-quic", + "io.netty:netty-codec-compression", + "io.netty:netty-codec-http", + "io.netty:netty-codec-native-quic:jar:linux-aarch_64", + "io.netty:netty-codec-native-quic:jar:linux-x86_64", + "io.netty:netty-codec-native-quic:jar:osx-aarch_64", + "io.netty:netty-codec-native-quic:jar:osx-x86_64", + "io.netty:netty-codec-native-quic:jar:windows-x86_64", + "io.netty:netty-common", + "io.netty:netty-handler", + "io.netty:netty-resolver", + "io.netty:netty-transport", + "io.netty:netty-transport-native-unix-common" + ], + "io.netty:netty-codec-native-quic:jar:linux-aarch_64": [ + "io.netty:netty-codec-classes-quic" + ], + "io.netty:netty-codec-native-quic:jar:linux-x86_64": [ + "io.netty:netty-codec-classes-quic" + ], + "io.netty:netty-codec-native-quic:jar:osx-aarch_64": [ + "io.netty:netty-codec-classes-quic" + ], + "io.netty:netty-codec-native-quic:jar:osx-x86_64": [ + "io.netty:netty-codec-classes-quic" + ], + "io.netty:netty-codec-native-quic:jar:windows-x86_64": [ + "io.netty:netty-codec-classes-quic" + ], + "io.netty:netty-codec-socks": [ + "io.netty:netty-buffer", + "io.netty:netty-codec-base", + "io.netty:netty-common", + "io.netty:netty-transport" + ], + "io.netty:netty-handler": [ + "io.netty:netty-buffer", + "io.netty:netty-codec-base", + "io.netty:netty-common", + "io.netty:netty-resolver", + "io.netty:netty-transport", + "io.netty:netty-transport-native-unix-common" + ], + "io.netty:netty-handler-proxy": [ + "io.netty:netty-buffer", + "io.netty:netty-codec-base", + "io.netty:netty-codec-http", + "io.netty:netty-codec-socks", + "io.netty:netty-common", + "io.netty:netty-handler", + "io.netty:netty-transport" + ], + "io.netty:netty-resolver": [ + "io.netty:netty-common" + ], + "io.netty:netty-resolver-dns": [ + "io.netty:netty-buffer", + "io.netty:netty-codec-base", + "io.netty:netty-codec-dns", + "io.netty:netty-common", + "io.netty:netty-handler", + "io.netty:netty-resolver", + "io.netty:netty-transport" + ], + "io.netty:netty-resolver-dns-classes-macos": [ + "io.netty:netty-common", + "io.netty:netty-resolver-dns", + "io.netty:netty-transport-native-unix-common" + ], + "io.netty:netty-resolver-dns-native-macos:jar:osx-x86_64": [ + "io.netty:netty-resolver-dns-classes-macos" + ], + "io.netty:netty-transport": [ + "io.netty:netty-buffer", + "io.netty:netty-common", + "io.netty:netty-resolver" + ], + "io.netty:netty-transport-classes-epoll": [ + "io.netty:netty-buffer", + "io.netty:netty-common", + "io.netty:netty-transport", + "io.netty:netty-transport-native-unix-common" + ], + "io.netty:netty-transport-native-epoll:jar:linux-x86_64": [ + "io.netty:netty-buffer", + "io.netty:netty-common", + "io.netty:netty-transport", + "io.netty:netty-transport-classes-epoll", + "io.netty:netty-transport-native-unix-common" + ], + "io.netty:netty-transport-native-unix-common": [ + "io.netty:netty-buffer", + "io.netty:netty-common", + "io.netty:netty-transport" + ], + "io.opentelemetry:opentelemetry-api": [ + "io.opentelemetry:opentelemetry-context" + ], + "io.opentelemetry:opentelemetry-context": [ + "io.opentelemetry:opentelemetry-common" + ], + "io.opentelemetry:opentelemetry-exporter-common": [ + "io.opentelemetry:opentelemetry-api", + "io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi" + ], + "io.opentelemetry:opentelemetry-exporter-otlp": [ + "io.opentelemetry:opentelemetry-exporter-otlp-common", + "io.opentelemetry:opentelemetry-exporter-sender-okhttp", + "io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi", + "io.opentelemetry:opentelemetry-sdk-logs", + "io.opentelemetry:opentelemetry-sdk-metrics", + "io.opentelemetry:opentelemetry-sdk-trace" + ], + "io.opentelemetry:opentelemetry-exporter-otlp-common": [ + "io.opentelemetry:opentelemetry-exporter-common" + ], + "io.opentelemetry:opentelemetry-exporter-sender-okhttp": [ + "com.squareup.okhttp3:okhttp-jvm", + "io.opentelemetry:opentelemetry-exporter-common", + "io.opentelemetry:opentelemetry-sdk-common" + ], + "io.opentelemetry:opentelemetry-extension-trace-propagators": [ + "io.opentelemetry:opentelemetry-api" + ], + "io.opentelemetry:opentelemetry-sdk": [ + "io.opentelemetry:opentelemetry-api", + "io.opentelemetry:opentelemetry-sdk-common", + "io.opentelemetry:opentelemetry-sdk-logs", + "io.opentelemetry:opentelemetry-sdk-metrics", + "io.opentelemetry:opentelemetry-sdk-trace" + ], + "io.opentelemetry:opentelemetry-sdk-common": [ + "io.opentelemetry:opentelemetry-api" + ], + "io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi": [ + "io.opentelemetry:opentelemetry-sdk" + ], + "io.opentelemetry:opentelemetry-sdk-logs": [ + "io.opentelemetry:opentelemetry-api", + "io.opentelemetry:opentelemetry-sdk-common" + ], + "io.opentelemetry:opentelemetry-sdk-metrics": [ + "io.opentelemetry:opentelemetry-api", + "io.opentelemetry:opentelemetry-sdk-common" + ], + "io.opentelemetry:opentelemetry-sdk-testing": [ + "io.opentelemetry:opentelemetry-api", + "io.opentelemetry:opentelemetry-sdk" + ], + "io.opentelemetry:opentelemetry-sdk-trace": [ + "io.opentelemetry:opentelemetry-api", + "io.opentelemetry:opentelemetry-sdk-common" + ], + "io.projectreactor.netty:reactor-netty-core": [ + "io.netty:netty-handler", + "io.netty:netty-handler-proxy", + "io.netty:netty-resolver-dns", + "io.netty:netty-resolver-dns-native-macos:jar:osx-x86_64", + "io.netty:netty-transport-native-epoll:jar:linux-x86_64", + "io.projectreactor:reactor-core", + "org.jspecify:jspecify" + ], + "io.projectreactor.netty:reactor-netty-http": [ + "io.netty:netty-codec-http", + "io.netty:netty-codec-http2", + "io.netty:netty-codec-http3", + "io.netty:netty-resolver-dns", + "io.netty:netty-resolver-dns-native-macos:jar:osx-x86_64", + "io.netty:netty-transport-native-epoll:jar:linux-x86_64", + "io.projectreactor.netty:reactor-netty-core", + "io.projectreactor:reactor-core", + "org.jspecify:jspecify" + ], + "io.projectreactor:reactor-core": [ + "org.jspecify:jspecify", + "org.reactivestreams:reactive-streams" + ], + "io.projectreactor:reactor-test": [ + "io.projectreactor:reactor-core", + "org.jspecify:jspecify" + ], + "io.swagger.core.v3:swagger-core-jakarta": [ + "com.fasterxml.jackson.core:jackson-annotations", + "com.fasterxml.jackson.core:jackson-databind", + "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml", + "com.fasterxml.jackson.datatype:jackson-datatype-jsr310", + "io.swagger.core.v3:swagger-annotations-jakarta", + "io.swagger.core.v3:swagger-models-jakarta", + "jakarta.validation:jakarta.validation-api", + "jakarta.xml.bind:jakarta.xml.bind-api", + "org.apache.commons:commons-lang3", + "org.slf4j:slf4j-api", + "org.yaml:snakeyaml" + ], + "io.swagger.core.v3:swagger-models-jakarta": [ + "com.fasterxml.jackson.core:jackson-annotations" + ], + "jakarta.xml.bind:jakarta.xml.bind-api": [ + "jakarta.activation:jakarta.activation-api" + ], + "net.minidev:accessors-smart": [ + "org.ow2.asm:asm" + ], + "net.minidev:json-smart": [ + "net.minidev:accessors-smart" + ], + "org.apache.cassandra:java-driver-core": [ + "com.datastax.oss:native-protocol", + "com.fasterxml.jackson.core:jackson-core", + "com.fasterxml.jackson.core:jackson-databind", + "com.github.jnr:jnr-posix", + "com.typesafe:config", + "io.netty:netty-handler", + "org.apache.cassandra:java-driver-guava-shaded", + "org.reactivestreams:reactive-streams", + "org.slf4j:slf4j-api" + ], + "org.apache.cassandra:java-driver-metrics-micrometer": [ + "io.micrometer:micrometer-core", + "org.apache.cassandra:java-driver-core" + ], + "org.apache.cassandra:java-driver-query-builder": [ + "org.apache.cassandra:java-driver-core", + "org.apache.cassandra:java-driver-guava-shaded" + ], + "org.apache.commons:commons-compress": [ + "commons-codec:commons-codec", + "commons-io:commons-io", + "org.apache.commons:commons-lang3" + ], + "org.apache.logging.log4j:log4j-to-slf4j": [ + "org.apache.logging.log4j:log4j-api", + "org.slf4j:slf4j-api" + ], + "org.apache.tomcat.embed:tomcat-embed-websocket": [ + "org.apache.tomcat.embed:tomcat-embed-core" + ], + "org.assertj:assertj-core": [ + "net.bytebuddy:byte-buddy" + ], + "org.awaitility:awaitility": [ + "org.hamcrest:hamcrest" + ], + "org.hibernate.validator:hibernate-validator": [ + "com.fasterxml:classmate", + "jakarta.validation:jakarta.validation-api", + "org.jboss.logging:jboss-logging" + ], + "org.jacoco:org.jacoco.cli": [ + "args4j:args4j", + "org.jacoco:org.jacoco.core", + "org.jacoco:org.jacoco.report" + ], + "org.jacoco:org.jacoco.core": [ + "org.ow2.asm:asm", + "org.ow2.asm:asm-commons", + "org.ow2.asm:asm-tree" + ], + "org.jacoco:org.jacoco.report": [ + "org.jacoco:org.jacoco.core" + ], + "org.jetbrains.kotlin:kotlin-stdlib": [ + "org.jetbrains:annotations" + ], + "org.junit.jupiter:junit-jupiter": [ + "org.junit.jupiter:junit-jupiter-api", + "org.junit.jupiter:junit-jupiter-engine", + "org.junit.jupiter:junit-jupiter-params" + ], + "org.junit.jupiter:junit-jupiter-api": [ + "org.apiguardian:apiguardian-api", + "org.jspecify:jspecify", + "org.junit.platform:junit-platform-commons", + "org.opentest4j:opentest4j" + ], + "org.junit.jupiter:junit-jupiter-engine": [ + "org.apiguardian:apiguardian-api", + "org.jspecify:jspecify", + "org.junit.jupiter:junit-jupiter-api", + "org.junit.platform:junit-platform-engine" + ], + "org.junit.jupiter:junit-jupiter-params": [ + "org.apiguardian:apiguardian-api", + "org.jspecify:jspecify", + "org.junit.jupiter:junit-jupiter-api" + ], + "org.junit.platform:junit-platform-commons": [ + "org.apiguardian:apiguardian-api", + "org.jspecify:jspecify" + ], + "org.junit.platform:junit-platform-engine": [ + "org.apiguardian:apiguardian-api", + "org.jspecify:jspecify", + "org.junit.platform:junit-platform-commons", + "org.opentest4j:opentest4j" + ], + "org.junit.platform:junit-platform-launcher": [ + "org.apiguardian:apiguardian-api", + "org.jspecify:jspecify", + "org.junit.platform:junit-platform-engine" + ], + "org.junit.platform:junit-platform-reporting": [ + "org.apiguardian:apiguardian-api", + "org.jspecify:jspecify", + "org.junit.platform:junit-platform-launcher", + "org.opentest4j.reporting:open-test-reporting-tooling-spi" + ], + "org.mockito:mockito-core": [ + "net.bytebuddy:byte-buddy", + "net.bytebuddy:byte-buddy-agent", + "org.objenesis:objenesis" + ], + "org.mockito:mockito-junit-jupiter": [ + "org.junit.jupiter:junit-jupiter-api", + "org.mockito:mockito-core" + ], + "org.opentest4j.reporting:open-test-reporting-tooling-spi": [ + "org.apiguardian:apiguardian-api" + ], + "org.ow2.asm:asm-analysis": [ + "org.ow2.asm:asm-tree" + ], + "org.ow2.asm:asm-commons": [ + "org.ow2.asm:asm", + "org.ow2.asm:asm-tree" + ], + "org.ow2.asm:asm-tree": [ + "org.ow2.asm:asm" + ], + "org.ow2.asm:asm-util": [ + "org.ow2.asm:asm", + "org.ow2.asm:asm-analysis", + "org.ow2.asm:asm-tree" + ], + "org.rnorth.duct-tape:duct-tape": [ + "org.jetbrains:annotations" + ], + "org.skyscreamer:jsonassert": [ + "com.vaadin.external.google:android-json" + ], + "org.slf4j:jul-to-slf4j": [ + "org.slf4j:slf4j-api" + ], + "org.springdoc:springdoc-openapi-starter-common": [ + "io.swagger.core.v3:swagger-core-jakarta", + "org.springframework.boot:spring-boot-autoconfigure", + "org.springframework.boot:spring-boot-jackson", + "org.springframework.boot:spring-boot-starter", + "org.springframework.boot:spring-boot-validation" + ], + "org.springdoc:springdoc-openapi-starter-webflux-api": [ + "org.springdoc:springdoc-openapi-starter-common", + "org.springframework.boot:spring-boot-web-server", + "org.springframework.boot:spring-boot-webflux" + ], + "org.springdoc:springdoc-openapi-starter-webmvc-api": [ + "org.springdoc:springdoc-openapi-starter-common", + "org.springframework.boot:spring-boot-web-server", + "org.springframework.boot:spring-boot-webmvc" + ], + "org.springframework.boot:spring-boot": [ + "org.springframework:spring-context", + "org.springframework:spring-core" + ], + "org.springframework.boot:spring-boot-actuator": [ + "org.springframework.boot:spring-boot" + ], + "org.springframework.boot:spring-boot-actuator-autoconfigure": [ + "org.springframework.boot:spring-boot-actuator", + "org.springframework.boot:spring-boot-autoconfigure" + ], + "org.springframework.boot:spring-boot-autoconfigure": [ + "org.springframework.boot:spring-boot" + ], + "org.springframework.boot:spring-boot-cassandra": [ + "org.apache.cassandra:java-driver-core", + "org.springframework.boot:spring-boot" + ], + "org.springframework.boot:spring-boot-data-cassandra": [ + "org.springframework.boot:spring-boot-cassandra", + "org.springframework.boot:spring-boot-data-commons", + "org.springframework.data:spring-data-cassandra" + ], + "org.springframework.boot:spring-boot-data-cassandra-test": [ + "org.springframework.boot:spring-boot-data-cassandra", + "org.springframework.boot:spring-boot-test-autoconfigure" + ], + "org.springframework.boot:spring-boot-data-commons": [ + "org.springframework.boot:spring-boot", + "org.springframework.boot:spring-boot-persistence", + "org.springframework.data:spring-data-commons" + ], + "org.springframework.boot:spring-boot-health": [ + "org.springframework.boot:spring-boot" + ], + "org.springframework.boot:spring-boot-http-client": [ + "org.springframework.boot:spring-boot", + "org.springframework.boot:spring-boot-http-converter", + "org.springframework:spring-web" + ], + "org.springframework.boot:spring-boot-http-codec": [ + "org.springframework.boot:spring-boot", + "org.springframework:spring-web" + ], + "org.springframework.boot:spring-boot-http-converter": [ + "org.springframework.boot:spring-boot", + "org.springframework:spring-web" + ], + "org.springframework.boot:spring-boot-jackson": [ + "org.springframework.boot:spring-boot", + "tools.jackson.core:jackson-databind" + ], + "org.springframework.boot:spring-boot-micrometer-metrics": [ + "io.micrometer:micrometer-core", + "org.springframework.boot:spring-boot", + "org.springframework.boot:spring-boot-micrometer-observation" + ], + "org.springframework.boot:spring-boot-micrometer-metrics-test": [ + "io.micrometer:micrometer-observation-test", + "org.springframework.boot:spring-boot-micrometer-metrics", + "org.springframework.boot:spring-boot-test-autoconfigure" + ], + "org.springframework.boot:spring-boot-micrometer-observation": [ + "io.micrometer:micrometer-observation", + "org.springframework.boot:spring-boot" + ], + "org.springframework.boot:spring-boot-micrometer-tracing": [ + "io.micrometer:micrometer-tracing", + "org.springframework.boot:spring-boot", + "org.springframework.boot:spring-boot-micrometer-observation" + ], + "org.springframework.boot:spring-boot-micrometer-tracing-opentelemetry": [ + "io.micrometer:micrometer-tracing", + "org.springframework.boot:spring-boot", + "org.springframework.boot:spring-boot-micrometer-observation", + "org.springframework.boot:spring-boot-micrometer-tracing", + "org.springframework.boot:spring-boot-opentelemetry" + ], + "org.springframework.boot:spring-boot-netty": [ + "io.netty:netty-common", + "org.springframework.boot:spring-boot" + ], + "org.springframework.boot:spring-boot-opentelemetry": [ + "io.opentelemetry:opentelemetry-api", + "io.opentelemetry:opentelemetry-sdk", + "org.springframework.boot:spring-boot" + ], + "org.springframework.boot:spring-boot-persistence": [ + "org.springframework.boot:spring-boot", + "org.springframework:spring-tx" + ], + "org.springframework.boot:spring-boot-reactor": [ + "io.projectreactor:reactor-core", + "org.springframework.boot:spring-boot" + ], + "org.springframework.boot:spring-boot-reactor-netty": [ + "io.projectreactor.netty:reactor-netty-http", + "org.springframework.boot:spring-boot-netty", + "org.springframework.boot:spring-boot-web-server", + "org.springframework:spring-web" + ], + "org.springframework.boot:spring-boot-restclient": [ + "org.springframework.boot:spring-boot", + "org.springframework.boot:spring-boot-http-client", + "org.springframework.boot:spring-boot-http-converter" + ], + "org.springframework.boot:spring-boot-resttestclient": [ + "org.springframework.boot:spring-boot-http-converter", + "org.springframework.boot:spring-boot-test", + "org.springframework:spring-web" + ], + "org.springframework.boot:spring-boot-security": [ + "org.springframework.boot:spring-boot", + "org.springframework.security:spring-security-config", + "org.springframework.security:spring-security-web" + ], + "org.springframework.boot:spring-boot-security-oauth2-client": [ + "org.springframework.boot:spring-boot", + "org.springframework.boot:spring-boot-security", + "org.springframework.security:spring-security-oauth2-client" + ], + "org.springframework.boot:spring-boot-security-oauth2-resource-server": [ + "org.springframework.boot:spring-boot", + "org.springframework.boot:spring-boot-security", + "org.springframework.security:spring-security-oauth2-jose", + "org.springframework.security:spring-security-oauth2-resource-server" + ], + "org.springframework.boot:spring-boot-security-test": [ + "org.springframework.boot:spring-boot-security", + "org.springframework.boot:spring-boot-test-autoconfigure", + "org.springframework.security:spring-security-test" + ], + "org.springframework.boot:spring-boot-servlet": [ + "org.springframework.boot:spring-boot", + "org.springframework:spring-web" + ], + "org.springframework.boot:spring-boot-starter": [ + "jakarta.annotation:jakarta.annotation-api", + "org.springframework.boot:spring-boot-autoconfigure", + "org.springframework.boot:spring-boot-starter-logging", + "org.yaml:snakeyaml" + ], + "org.springframework.boot:spring-boot-starter-actuator": [ + "io.micrometer:micrometer-jakarta9", + "io.micrometer:micrometer-observation", + "org.springframework.boot:spring-boot-actuator-autoconfigure", + "org.springframework.boot:spring-boot-health", + "org.springframework.boot:spring-boot-starter", + "org.springframework.boot:spring-boot-starter-micrometer-metrics" + ], + "org.springframework.boot:spring-boot-starter-actuator-test": [ + "org.springframework.boot:spring-boot-starter-actuator", + "org.springframework.boot:spring-boot-starter-micrometer-metrics-test", + "org.springframework.boot:spring-boot-starter-test" + ], + "org.springframework.boot:spring-boot-starter-data-cassandra": [ + "org.springframework.boot:spring-boot-cassandra", + "org.springframework.boot:spring-boot-data-cassandra", + "org.springframework.boot:spring-boot-starter" + ], + "org.springframework.boot:spring-boot-starter-data-cassandra-test": [ + "org.springframework.boot:spring-boot-data-cassandra-test", + "org.springframework.boot:spring-boot-starter-data-cassandra", + "org.springframework.boot:spring-boot-starter-test" + ], + "org.springframework.boot:spring-boot-starter-jackson": [ + "org.springframework.boot:spring-boot-jackson", + "org.springframework.boot:spring-boot-starter" + ], + "org.springframework.boot:spring-boot-starter-jackson-test": [ + "org.springframework.boot:spring-boot-starter-jackson", + "org.springframework.boot:spring-boot-starter-test" + ], + "org.springframework.boot:spring-boot-starter-logging": [ + "ch.qos.logback:logback-classic", + "org.apache.logging.log4j:log4j-to-slf4j", + "org.slf4j:jul-to-slf4j" + ], + "org.springframework.boot:spring-boot-starter-micrometer-metrics": [ + "org.springframework.boot:spring-boot-micrometer-metrics", + "org.springframework.boot:spring-boot-starter" + ], + "org.springframework.boot:spring-boot-starter-micrometer-metrics-test": [ + "org.springframework.boot:spring-boot-micrometer-metrics-test", + "org.springframework.boot:spring-boot-starter-micrometer-metrics", + "org.springframework.boot:spring-boot-starter-test" + ], + "org.springframework.boot:spring-boot-starter-reactor-netty": [ + "org.springframework.boot:spring-boot-reactor", + "org.springframework.boot:spring-boot-reactor-netty", + "org.springframework.boot:spring-boot-starter" + ], + "org.springframework.boot:spring-boot-starter-security": [ + "org.springframework.boot:spring-boot-security", + "org.springframework.boot:spring-boot-starter", + "org.springframework:spring-aop" + ], + "org.springframework.boot:spring-boot-starter-security-oauth2-client": [ + "org.springframework.boot:spring-boot-security-oauth2-client", + "org.springframework.boot:spring-boot-starter", + "org.springframework.boot:spring-boot-starter-security", + "org.springframework.security:spring-security-oauth2-jose" + ], + "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server": [ + "org.springframework.boot:spring-boot-security-oauth2-resource-server", + "org.springframework.boot:spring-boot-starter", + "org.springframework.boot:spring-boot-starter-security" + ], + "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server-test": [ + "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server", + "org.springframework.boot:spring-boot-starter-security-test", + "org.springframework.boot:spring-boot-starter-test" + ], + "org.springframework.boot:spring-boot-starter-security-test": [ + "org.springframework.boot:spring-boot-security-test", + "org.springframework.boot:spring-boot-starter-security", + "org.springframework.boot:spring-boot-starter-test" + ], + "org.springframework.boot:spring-boot-starter-test": [ + "com.jayway.jsonpath:json-path", + "jakarta.xml.bind:jakarta.xml.bind-api", + "net.minidev:json-smart", + "org.assertj:assertj-core", + "org.awaitility:awaitility", + "org.hamcrest:hamcrest", + "org.junit.jupiter:junit-jupiter", + "org.mockito:mockito-core", + "org.mockito:mockito-junit-jupiter", + "org.skyscreamer:jsonassert", + "org.springframework.boot:spring-boot-starter", + "org.springframework.boot:spring-boot-test", + "org.springframework.boot:spring-boot-test-autoconfigure", + "org.springframework:spring-core", + "org.springframework:spring-test", + "org.xmlunit:xmlunit-core" + ], + "org.springframework.boot:spring-boot-starter-tomcat": [ + "org.springframework.boot:spring-boot-starter", + "org.springframework.boot:spring-boot-starter-tomcat-runtime", + "org.springframework.boot:spring-boot-tomcat" + ], + "org.springframework.boot:spring-boot-starter-tomcat-runtime": [ + "jakarta.annotation:jakarta.annotation-api", + "org.apache.tomcat.embed:tomcat-embed-core", + "org.apache.tomcat.embed:tomcat-embed-el", + "org.apache.tomcat.embed:tomcat-embed-websocket", + "org.springframework.boot:spring-boot-tomcat", + "org.springframework.boot:spring-boot-web-server" + ], + "org.springframework.boot:spring-boot-starter-validation": [ + "org.springframework.boot:spring-boot-starter", + "org.springframework.boot:spring-boot-validation" + ], + "org.springframework.boot:spring-boot-starter-webflux": [ + "org.springframework.boot:spring-boot-reactor", + "org.springframework.boot:spring-boot-starter", + "org.springframework.boot:spring-boot-starter-jackson", + "org.springframework.boot:spring-boot-starter-reactor-netty", + "org.springframework.boot:spring-boot-webflux" + ], + "org.springframework.boot:spring-boot-starter-webflux-test": [ + "io.projectreactor:reactor-test", + "org.springframework.boot:spring-boot-starter-jackson-test", + "org.springframework.boot:spring-boot-starter-test", + "org.springframework.boot:spring-boot-starter-webflux", + "org.springframework.boot:spring-boot-webflux-test", + "org.springframework.boot:spring-boot-webtestclient" + ], + "org.springframework.boot:spring-boot-starter-webmvc": [ + "org.springframework.boot:spring-boot-http-converter", + "org.springframework.boot:spring-boot-starter", + "org.springframework.boot:spring-boot-starter-jackson", + "org.springframework.boot:spring-boot-starter-tomcat", + "org.springframework.boot:spring-boot-webmvc" + ], + "org.springframework.boot:spring-boot-starter-webmvc-test": [ + "org.springframework.boot:spring-boot-resttestclient", + "org.springframework.boot:spring-boot-starter-jackson-test", + "org.springframework.boot:spring-boot-starter-test", + "org.springframework.boot:spring-boot-starter-webmvc", + "org.springframework.boot:spring-boot-webmvc-test" + ], + "org.springframework.boot:spring-boot-test": [ + "org.springframework.boot:spring-boot", + "org.springframework:spring-test" + ], + "org.springframework.boot:spring-boot-test-autoconfigure": [ + "org.springframework.boot:spring-boot-test" + ], + "org.springframework.boot:spring-boot-tomcat": [ + "jakarta.annotation:jakarta.annotation-api", + "org.apache.tomcat.embed:tomcat-embed-core", + "org.springframework.boot:spring-boot-web-server" + ], + "org.springframework.boot:spring-boot-validation": [ + "org.apache.tomcat.embed:tomcat-embed-el", + "org.hibernate.validator:hibernate-validator", + "org.springframework.boot:spring-boot" + ], + "org.springframework.boot:spring-boot-web-server": [ + "org.springframework.boot:spring-boot", + "org.springframework:spring-web" + ], + "org.springframework.boot:spring-boot-webclient": [ + "org.springframework.boot:spring-boot", + "org.springframework.boot:spring-boot-http-client", + "org.springframework.boot:spring-boot-http-codec", + "org.springframework:spring-webflux" + ], + "org.springframework.boot:spring-boot-webflux": [ + "org.springframework.boot:spring-boot", + "org.springframework.boot:spring-boot-http-codec", + "org.springframework.boot:spring-boot-web-server", + "org.springframework:spring-webflux" + ], + "org.springframework.boot:spring-boot-webflux-test": [ + "org.springframework.boot:spring-boot-test-autoconfigure", + "org.springframework.boot:spring-boot-webflux", + "org.springframework.boot:spring-boot-webtestclient" + ], + "org.springframework.boot:spring-boot-webmvc": [ + "org.springframework.boot:spring-boot-http-converter", + "org.springframework.boot:spring-boot-servlet", + "org.springframework:spring-web", + "org.springframework:spring-webmvc" + ], + "org.springframework.boot:spring-boot-webmvc-test": [ + "org.springframework.boot:spring-boot-http-converter", + "org.springframework.boot:spring-boot-test-autoconfigure", + "org.springframework.boot:spring-boot-web-server", + "org.springframework.boot:spring-boot-webmvc" + ], + "org.springframework.boot:spring-boot-webtestclient": [ + "org.springframework.boot:spring-boot-http-codec", + "org.springframework.boot:spring-boot-test", + "org.springframework:spring-webflux" + ], + "org.springframework.cloud:spring-cloud-commons": [ + "org.springframework.security:spring-security-crypto" + ], + "org.springframework.cloud:spring-cloud-context": [ + "org.springframework.security:spring-security-crypto" + ], + "org.springframework.cloud:spring-cloud-starter": [ + "org.bouncycastle:bcprov-jdk18on", + "org.springframework.boot:spring-boot-starter", + "org.springframework.cloud:spring-cloud-commons", + "org.springframework.cloud:spring-cloud-context" + ], + "org.springframework.cloud:spring-cloud-starter-bootstrap": [ + "org.springframework.cloud:spring-cloud-starter" + ], + "org.springframework.data:spring-data-cassandra": [ + "org.apache.cassandra:java-driver-core", + "org.apache.cassandra:java-driver-query-builder", + "org.slf4j:slf4j-api", + "org.springframework.data:spring-data-commons", + "org.springframework:spring-beans", + "org.springframework:spring-context", + "org.springframework:spring-core", + "org.springframework:spring-expression", + "org.springframework:spring-tx" + ], + "org.springframework.data:spring-data-commons": [ + "org.slf4j:slf4j-api", + "org.springframework:spring-beans", + "org.springframework:spring-core" + ], + "org.springframework.security:spring-security-config": [ + "org.springframework.security:spring-security-core", + "org.springframework:spring-aop", + "org.springframework:spring-beans", + "org.springframework:spring-context", + "org.springframework:spring-core" + ], + "org.springframework.security:spring-security-core": [ + "io.micrometer:micrometer-observation", + "org.springframework.security:spring-security-crypto", + "org.springframework:spring-aop", + "org.springframework:spring-beans", + "org.springframework:spring-context", + "org.springframework:spring-core", + "org.springframework:spring-expression" + ], + "org.springframework.security:spring-security-oauth2-client": [ + "com.nimbusds:oauth2-oidc-sdk", + "org.springframework.security:spring-security-core", + "org.springframework.security:spring-security-oauth2-core", + "org.springframework.security:spring-security-web", + "org.springframework:spring-core" + ], + "org.springframework.security:spring-security-oauth2-core": [ + "org.springframework.security:spring-security-core", + "org.springframework:spring-core", + "org.springframework:spring-web" + ], + "org.springframework.security:spring-security-oauth2-jose": [ + "com.nimbusds:nimbus-jose-jwt", + "org.springframework.security:spring-security-core", + "org.springframework.security:spring-security-oauth2-core", + "org.springframework:spring-core" + ], + "org.springframework.security:spring-security-oauth2-resource-server": [ + "org.springframework.security:spring-security-core", + "org.springframework.security:spring-security-oauth2-core", + "org.springframework.security:spring-security-web", + "org.springframework:spring-core" + ], + "org.springframework.security:spring-security-test": [ + "org.springframework.security:spring-security-core", + "org.springframework.security:spring-security-web", + "org.springframework:spring-core", + "org.springframework:spring-test" + ], + "org.springframework.security:spring-security-web": [ + "org.springframework.security:spring-security-core", + "org.springframework:spring-aop", + "org.springframework:spring-beans", + "org.springframework:spring-context", + "org.springframework:spring-core", + "org.springframework:spring-expression", + "org.springframework:spring-web" + ], + "org.springframework:spring-aop": [ + "org.springframework:spring-beans", + "org.springframework:spring-core" + ], + "org.springframework:spring-beans": [ + "org.springframework:spring-core" + ], + "org.springframework:spring-context": [ + "io.micrometer:micrometer-observation", + "org.springframework:spring-aop", + "org.springframework:spring-beans", + "org.springframework:spring-core", + "org.springframework:spring-expression" + ], + "org.springframework:spring-core": [ + "commons-logging:commons-logging", + "org.jspecify:jspecify" + ], + "org.springframework:spring-expression": [ + "org.springframework:spring-core" + ], + "org.springframework:spring-test": [ + "org.springframework:spring-core" + ], + "org.springframework:spring-tx": [ + "org.springframework:spring-beans", + "org.springframework:spring-core" + ], + "org.springframework:spring-web": [ + "io.micrometer:micrometer-observation", + "org.springframework:spring-beans", + "org.springframework:spring-core" + ], + "org.springframework:spring-webflux": [ + "io.projectreactor:reactor-core", + "org.springframework:spring-beans", + "org.springframework:spring-core", + "org.springframework:spring-web" + ], + "org.springframework:spring-webmvc": [ + "org.springframework:spring-aop", + "org.springframework:spring-beans", + "org.springframework:spring-context", + "org.springframework:spring-core", + "org.springframework:spring-expression", + "org.springframework:spring-web" + ], + "org.testcontainers:testcontainers": [ + "com.github.docker-java:docker-java-api", + "com.github.docker-java:docker-java-transport-zerodep", + "org.apache.commons:commons-compress", + "org.rnorth.duct-tape:duct-tape", + "org.slf4j:slf4j-api" + ], + "org.testcontainers:testcontainers-cassandra": [ + "com.datastax.cassandra:cassandra-driver-core", + "org.testcontainers:testcontainers-database-commons" + ], + "org.testcontainers:testcontainers-database-commons": [ + "org.testcontainers:testcontainers" + ], + "org.testcontainers:testcontainers-junit-jupiter": [ + "org.testcontainers:testcontainers" + ], + "org.xmlunit:xmlunit-core": [ + "jakarta.xml.bind:jakarta.xml.bind-api" + ], + "software.amazon.awssdk:checksums": [ + "software.amazon.awssdk:annotations", + "software.amazon.awssdk:checksums-spi", + "software.amazon.awssdk:utils" + ], + "software.amazon.awssdk:checksums-spi": [ + "software.amazon.awssdk:annotations" + ], + "software.amazon.awssdk:endpoints-spi": [ + "software.amazon.awssdk:annotations" + ], + "software.amazon.awssdk:http-auth-aws": [ + "software.amazon.awssdk:annotations", + "software.amazon.awssdk:checksums", + "software.amazon.awssdk:checksums-spi", + "software.amazon.awssdk:http-auth-spi", + "software.amazon.awssdk:http-client-spi", + "software.amazon.awssdk:identity-spi", + "software.amazon.awssdk:utils" + ], + "software.amazon.awssdk:http-auth-spi": [ + "org.reactivestreams:reactive-streams", + "software.amazon.awssdk:annotations", + "software.amazon.awssdk:checksums-spi", + "software.amazon.awssdk:http-client-spi", + "software.amazon.awssdk:identity-spi", + "software.amazon.awssdk:utils" + ], + "software.amazon.awssdk:http-client-spi": [ + "org.reactivestreams:reactive-streams", + "software.amazon.awssdk:annotations", + "software.amazon.awssdk:metrics-spi", + "software.amazon.awssdk:utils" + ], + "software.amazon.awssdk:identity-spi": [ + "software.amazon.awssdk:annotations", + "software.amazon.awssdk:utils" + ], + "software.amazon.awssdk:json-utils": [ + "software.amazon.awssdk:annotations", + "software.amazon.awssdk:third-party-jackson-core", + "software.amazon.awssdk:utils" + ], + "software.amazon.awssdk:metrics-spi": [ + "software.amazon.awssdk:annotations", + "software.amazon.awssdk:utils" + ], + "software.amazon.awssdk:profiles": [ + "software.amazon.awssdk:annotations", + "software.amazon.awssdk:utils" + ], + "software.amazon.awssdk:regions": [ + "org.slf4j:slf4j-api", + "software.amazon.awssdk:annotations", + "software.amazon.awssdk:json-utils", + "software.amazon.awssdk:profiles", + "software.amazon.awssdk:sdk-core", + "software.amazon.awssdk:utils" + ], + "software.amazon.awssdk:retries": [ + "software.amazon.awssdk:annotations", + "software.amazon.awssdk:retries-spi", + "software.amazon.awssdk:utils" + ], + "software.amazon.awssdk:retries-spi": [ + "software.amazon.awssdk:annotations", + "software.amazon.awssdk:utils" + ], + "software.amazon.awssdk:sdk-core": [ + "org.reactivestreams:reactive-streams", + "org.slf4j:slf4j-api", + "software.amazon.awssdk:annotations", + "software.amazon.awssdk:checksums", + "software.amazon.awssdk:checksums-spi", + "software.amazon.awssdk:endpoints-spi", + "software.amazon.awssdk:http-auth-aws", + "software.amazon.awssdk:http-auth-spi", + "software.amazon.awssdk:http-client-spi", + "software.amazon.awssdk:identity-spi", + "software.amazon.awssdk:metrics-spi", + "software.amazon.awssdk:profiles", + "software.amazon.awssdk:retries", + "software.amazon.awssdk:retries-spi", + "software.amazon.awssdk:utils" + ], + "software.amazon.awssdk:utils": [ + "org.reactivestreams:reactive-streams", + "org.slf4j:slf4j-api", + "software.amazon.awssdk:annotations" + ], + "tools.jackson.core:jackson-databind": [ + "com.fasterxml.jackson.core:jackson-annotations", + "tools.jackson.core:jackson-core" + ], + "tools.jackson.module:jackson-module-blackbird": [ + "tools.jackson.core:jackson-core", + "tools.jackson.core:jackson-databind" + ] + }, + "packages": { + "aopalliance:aopalliance": [ + "org.aopalliance.aop", + "org.aopalliance.intercept" + ], + "args4j:args4j": [ + "org.kohsuke.args4j", + "org.kohsuke.args4j.spi" + ], + "at.yawk.lz4:lz4-java": [ + "net.jpountz.lz4", + "net.jpountz.util", + "net.jpountz.xxhash" + ], + "ch.qos.logback:logback-classic": [ + "ch.qos.logback.classic", + "ch.qos.logback.classic.boolex", + "ch.qos.logback.classic.encoder", + "ch.qos.logback.classic.filter", + "ch.qos.logback.classic.helpers", + "ch.qos.logback.classic.html", + "ch.qos.logback.classic.joran", + "ch.qos.logback.classic.joran.action", + "ch.qos.logback.classic.joran.sanity", + "ch.qos.logback.classic.joran.serializedModel", + "ch.qos.logback.classic.jul", + "ch.qos.logback.classic.layout", + "ch.qos.logback.classic.log4j", + "ch.qos.logback.classic.model", + "ch.qos.logback.classic.model.processor", + "ch.qos.logback.classic.model.util", + "ch.qos.logback.classic.net", + "ch.qos.logback.classic.net.server", + "ch.qos.logback.classic.pattern", + "ch.qos.logback.classic.pattern.color", + "ch.qos.logback.classic.selector", + "ch.qos.logback.classic.selector.servlet", + "ch.qos.logback.classic.servlet", + "ch.qos.logback.classic.sift", + "ch.qos.logback.classic.spi", + "ch.qos.logback.classic.turbo", + "ch.qos.logback.classic.tyler", + "ch.qos.logback.classic.util" + ], + "ch.qos.logback:logback-core": [ + "ch.qos.logback.core", + "ch.qos.logback.core.boolex", + "ch.qos.logback.core.encoder", + "ch.qos.logback.core.filter", + "ch.qos.logback.core.helpers", + "ch.qos.logback.core.hook", + "ch.qos.logback.core.html", + "ch.qos.logback.core.joran", + "ch.qos.logback.core.joran.action", + "ch.qos.logback.core.joran.conditional", + "ch.qos.logback.core.joran.event", + "ch.qos.logback.core.joran.sanity", + "ch.qos.logback.core.joran.spi", + "ch.qos.logback.core.joran.util", + "ch.qos.logback.core.joran.util.beans", + "ch.qos.logback.core.layout", + "ch.qos.logback.core.model", + "ch.qos.logback.core.model.conditional", + "ch.qos.logback.core.model.processor", + "ch.qos.logback.core.model.processor.conditional", + "ch.qos.logback.core.model.util", + "ch.qos.logback.core.net", + "ch.qos.logback.core.net.ssl", + "ch.qos.logback.core.pattern", + "ch.qos.logback.core.pattern.color", + "ch.qos.logback.core.pattern.parser", + "ch.qos.logback.core.pattern.util", + "ch.qos.logback.core.property", + "ch.qos.logback.core.read", + "ch.qos.logback.core.recovery", + "ch.qos.logback.core.rolling", + "ch.qos.logback.core.rolling.helper", + "ch.qos.logback.core.sift", + "ch.qos.logback.core.spi", + "ch.qos.logback.core.status", + "ch.qos.logback.core.subst", + "ch.qos.logback.core.testUtil", + "ch.qos.logback.core.util" + ], + "com.datastax.cassandra:cassandra-driver-core": [ + "com.datastax.driver.core", + "com.datastax.driver.core.exceptions", + "com.datastax.driver.core.policies", + "com.datastax.driver.core.querybuilder", + "com.datastax.driver.core.schemabuilder", + "com.datastax.driver.core.utils" + ], + "com.datastax.oss:native-protocol": [ + "com.datastax.dse.protocol.internal", + "com.datastax.dse.protocol.internal.request", + "com.datastax.dse.protocol.internal.request.query", + "com.datastax.dse.protocol.internal.response.result", + "com.datastax.oss.protocol.internal", + "com.datastax.oss.protocol.internal.request", + "com.datastax.oss.protocol.internal.request.query", + "com.datastax.oss.protocol.internal.response", + "com.datastax.oss.protocol.internal.response.error", + "com.datastax.oss.protocol.internal.response.event", + "com.datastax.oss.protocol.internal.response.result", + "com.datastax.oss.protocol.internal.util", + "com.datastax.oss.protocol.internal.util.collection" + ], + "com.fasterxml.jackson.core:jackson-annotations": [ + "com.fasterxml.jackson.annotation" + ], + "com.fasterxml.jackson.core:jackson-core": [ + "com.fasterxml.jackson.core", + "com.fasterxml.jackson.core.async", + "com.fasterxml.jackson.core.base", + "com.fasterxml.jackson.core.exc", + "com.fasterxml.jackson.core.filter", + "com.fasterxml.jackson.core.format", + "com.fasterxml.jackson.core.internal.shaded.fdp.v2_21_4", + "com.fasterxml.jackson.core.internal.shaded.fdp.v2_21_4.bte", + "com.fasterxml.jackson.core.internal.shaded.fdp.v2_21_4.chr", + "com.fasterxml.jackson.core.io", + "com.fasterxml.jackson.core.io.schubfach", + "com.fasterxml.jackson.core.json", + "com.fasterxml.jackson.core.json.async", + "com.fasterxml.jackson.core.sym", + "com.fasterxml.jackson.core.type", + "com.fasterxml.jackson.core.util" + ], + "com.fasterxml.jackson.core:jackson-databind": [ + "com.fasterxml.jackson.databind", + "com.fasterxml.jackson.databind.annotation", + "com.fasterxml.jackson.databind.cfg", + "com.fasterxml.jackson.databind.deser", + "com.fasterxml.jackson.databind.deser.impl", + "com.fasterxml.jackson.databind.deser.std", + "com.fasterxml.jackson.databind.exc", + "com.fasterxml.jackson.databind.ext", + "com.fasterxml.jackson.databind.introspect", + "com.fasterxml.jackson.databind.jdk14", + "com.fasterxml.jackson.databind.json", + "com.fasterxml.jackson.databind.jsonFormatVisitors", + "com.fasterxml.jackson.databind.jsonschema", + "com.fasterxml.jackson.databind.jsontype", + "com.fasterxml.jackson.databind.jsontype.impl", + "com.fasterxml.jackson.databind.module", + "com.fasterxml.jackson.databind.node", + "com.fasterxml.jackson.databind.ser", + "com.fasterxml.jackson.databind.ser.impl", + "com.fasterxml.jackson.databind.ser.std", + "com.fasterxml.jackson.databind.type", + "com.fasterxml.jackson.databind.util", + "com.fasterxml.jackson.databind.util.internal" + ], + "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml": [ + "com.fasterxml.jackson.dataformat.yaml", + "com.fasterxml.jackson.dataformat.yaml.snakeyaml.error", + "com.fasterxml.jackson.dataformat.yaml.util" + ], + "com.fasterxml.jackson.datatype:jackson-datatype-jsr310": [ + "com.fasterxml.jackson.datatype.jsr310", + "com.fasterxml.jackson.datatype.jsr310.deser", + "com.fasterxml.jackson.datatype.jsr310.deser.key", + "com.fasterxml.jackson.datatype.jsr310.ser", + "com.fasterxml.jackson.datatype.jsr310.ser.key", + "com.fasterxml.jackson.datatype.jsr310.util" + ], + "com.fasterxml:classmate": [ + "com.fasterxml.classmate", + "com.fasterxml.classmate.members", + "com.fasterxml.classmate.types", + "com.fasterxml.classmate.util" + ], + "com.github.ben-manes.caffeine:caffeine": [ + "com.github.benmanes.caffeine.cache", + "com.github.benmanes.caffeine.cache.stats" + ], + "com.github.ben-manes.caffeine:guava": [ + "com.github.benmanes.caffeine.guava" + ], + "com.github.docker-java:docker-java-api": [ + "com.github.dockerjava.api", + "com.github.dockerjava.api.async", + "com.github.dockerjava.api.command", + "com.github.dockerjava.api.exception", + "com.github.dockerjava.api.model" + ], + "com.github.docker-java:docker-java-transport": [ + "com.github.dockerjava.transport" + ], + "com.github.docker-java:docker-java-transport-zerodep": [ + "com.github.dockerjava.zerodep", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.async", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.async.methods", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.auth", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.classic", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.classic.methods", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.config", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.cookie", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.entity", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.entity.mime", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.impl", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.impl.async", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.impl.auth", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.impl.classic", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.impl.compat", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.impl.cookie", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.impl.io", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.impl.nio", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.impl.routing", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.io", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.nio", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.protocol", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.psl", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.routing", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.socket", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.ssl", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.utils", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.validator", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.annotation", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.concurrent", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.function", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.config", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.impl", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.impl.bootstrap", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.impl.io", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.impl.nio", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.impl.routing", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.io", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.io.entity", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.io.ssl", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.io.support", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.message", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.nio", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.nio.command", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.nio.entity", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.nio.ssl", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.nio.support", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.nio.support.classic", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.protocol", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.ssl", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.support", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http2", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http2.config", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http2.frame", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http2.hpack", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http2.impl", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http2.impl.io", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http2.impl.nio", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http2.impl.nio.bootstrap", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http2.nio", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http2.nio.command", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http2.nio.pool", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http2.nio.support", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http2.protocol", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http2.ssl", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.io", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.net", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.pool", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.reactor", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.reactor.ssl", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.ssl", + "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.util" + ], + "com.github.java-json-tools:btf": [ + "com.github.fge" + ], + "com.github.java-json-tools:jackson-coreutils": [ + "com.github.fge.jackson", + "com.github.fge.jackson.jsonpointer" + ], + "com.github.java-json-tools:json-patch": [ + "com.github.fge.jsonpatch", + "com.github.fge.jsonpatch.diff", + "com.github.fge.jsonpatch.mergepatch" + ], + "com.github.java-json-tools:msg-simple": [ + "com.github.fge.msgsimple", + "com.github.fge.msgsimple.bundle", + "com.github.fge.msgsimple.load", + "com.github.fge.msgsimple.locale", + "com.github.fge.msgsimple.provider", + "com.github.fge.msgsimple.source" + ], + "com.github.jnr:jffi": [ + "com.kenai.jffi", + "com.kenai.jffi.internal" + ], + "com.github.jnr:jnr-constants": [ + "jnr.constants", + "jnr.constants.platform", + "jnr.constants.platform.aix", + "jnr.constants.platform.darwin", + "jnr.constants.platform.dragonflybsd", + "jnr.constants.platform.fake", + "jnr.constants.platform.freebsd", + "jnr.constants.platform.freebsd.aarch64", + "jnr.constants.platform.linux", + "jnr.constants.platform.linux.aarch64", + "jnr.constants.platform.linux.loongarch64", + "jnr.constants.platform.linux.mips64el", + "jnr.constants.platform.linux.powerpc64", + "jnr.constants.platform.linux.s390x", + "jnr.constants.platform.openbsd", + "jnr.constants.platform.solaris", + "jnr.constants.platform.windows" + ], + "com.github.jnr:jnr-ffi": [ + "jnr.ffi", + "jnr.ffi.annotations", + "jnr.ffi.byref", + "jnr.ffi.mapper", + "jnr.ffi.provider", + "jnr.ffi.provider.converters", + "jnr.ffi.provider.jffi", + "jnr.ffi.provider.jffi.platform.aarch64.linux", + "jnr.ffi.provider.jffi.platform.arm.linux", + "jnr.ffi.provider.jffi.platform.i386.darwin", + "jnr.ffi.provider.jffi.platform.i386.freebsd", + "jnr.ffi.provider.jffi.platform.i386.linux", + "jnr.ffi.provider.jffi.platform.i386.openbsd", + "jnr.ffi.provider.jffi.platform.i386.solaris", + "jnr.ffi.provider.jffi.platform.i386.windows", + "jnr.ffi.provider.jffi.platform.mips.linux", + "jnr.ffi.provider.jffi.platform.mipsel.linux", + "jnr.ffi.provider.jffi.platform.ppc.aix", + "jnr.ffi.provider.jffi.platform.ppc.darwin", + "jnr.ffi.provider.jffi.platform.ppc.linux", + "jnr.ffi.provider.jffi.platform.ppc64.linux", + "jnr.ffi.provider.jffi.platform.ppc64le.linux", + "jnr.ffi.provider.jffi.platform.s390.linux", + "jnr.ffi.provider.jffi.platform.s390x.linux", + "jnr.ffi.provider.jffi.platform.sparc.solaris", + "jnr.ffi.provider.jffi.platform.sparcv9.linux", + "jnr.ffi.provider.jffi.platform.sparcv9.solaris", + "jnr.ffi.provider.jffi.platform.x86_64.darwin", + "jnr.ffi.provider.jffi.platform.x86_64.freebsd", + "jnr.ffi.provider.jffi.platform.x86_64.linux", + "jnr.ffi.provider.jffi.platform.x86_64.openbsd", + "jnr.ffi.provider.jffi.platform.x86_64.solaris", + "jnr.ffi.provider.jffi.platform.x86_64.windows", + "jnr.ffi.types", + "jnr.ffi.util", + "jnr.ffi.util.ref", + "jnr.ffi.util.ref.internal" + ], + "com.github.jnr:jnr-posix": [ + "jnr.posix", + "jnr.posix.util", + "jnr.posix.windows" + ], + "com.github.jnr:jnr-x86asm": [ + "com.kenai.jnr.x86asm", + "jnr.x86asm" + ], + "com.github.stephenc.jcip:jcip-annotations": [ + "net.jcip.annotations" + ], + "com.google.code.findbugs:jsr305": [ + "javax.annotation", + "javax.annotation.concurrent", + "javax.annotation.meta" + ], + "com.google.code.gson:gson": [ + "com.google.gson", + "com.google.gson.annotations", + "com.google.gson.internal", + "com.google.gson.internal.bind", + "com.google.gson.internal.bind.util", + "com.google.gson.internal.reflect", + "com.google.gson.internal.sql", + "com.google.gson.reflect", + "com.google.gson.stream" + ], + "com.google.errorprone:error_prone_annotations": [ + "com.google.errorprone.annotations", + "com.google.errorprone.annotations.concurrent" + ], + "com.google.guava:failureaccess": [ + "com.google.common.util.concurrent.internal" + ], + "com.google.guava:guava": [ + "com.google.common.annotations", + "com.google.common.base", + "com.google.common.base.internal", + "com.google.common.cache", + "com.google.common.collect", + "com.google.common.escape", + "com.google.common.eventbus", + "com.google.common.graph", + "com.google.common.hash", + "com.google.common.html", + "com.google.common.io", + "com.google.common.math", + "com.google.common.net", + "com.google.common.primitives", + "com.google.common.reflect", + "com.google.common.util.concurrent", + "com.google.common.xml", + "com.google.thirdparty.publicsuffix" + ], + "com.google.j2objc:j2objc-annotations": [ + "com.google.j2objc.annotations" + ], + "com.jayway.jsonpath:json-path": [ + "com.jayway.jsonpath", + "com.jayway.jsonpath.internal", + "com.jayway.jsonpath.internal.filter", + "com.jayway.jsonpath.internal.function", + "com.jayway.jsonpath.internal.function.json", + "com.jayway.jsonpath.internal.function.latebinding", + "com.jayway.jsonpath.internal.function.numeric", + "com.jayway.jsonpath.internal.function.sequence", + "com.jayway.jsonpath.internal.function.text", + "com.jayway.jsonpath.internal.path", + "com.jayway.jsonpath.spi.cache", + "com.jayway.jsonpath.spi.json", + "com.jayway.jsonpath.spi.mapper" + ], + "com.nimbusds:content-type": [ + "com.nimbusds.common.contenttype" + ], + "com.nimbusds:lang-tag": [ + "com.nimbusds.langtag" + ], + "com.nimbusds:nimbus-jose-jwt": [ + "com.nimbusds.jose", + "com.nimbusds.jose.crypto", + "com.nimbusds.jose.crypto.bc", + "com.nimbusds.jose.crypto.factories", + "com.nimbusds.jose.crypto.impl", + "com.nimbusds.jose.crypto.opts", + "com.nimbusds.jose.crypto.utils", + "com.nimbusds.jose.jca", + "com.nimbusds.jose.jwk", + "com.nimbusds.jose.jwk.gen", + "com.nimbusds.jose.jwk.source", + "com.nimbusds.jose.mint", + "com.nimbusds.jose.proc", + "com.nimbusds.jose.produce", + "com.nimbusds.jose.shaded.gson", + "com.nimbusds.jose.shaded.gson.annotations", + "com.nimbusds.jose.shaded.gson.internal", + "com.nimbusds.jose.shaded.gson.internal.bind", + "com.nimbusds.jose.shaded.gson.internal.bind.util", + "com.nimbusds.jose.shaded.gson.internal.reflect", + "com.nimbusds.jose.shaded.gson.internal.sql", + "com.nimbusds.jose.shaded.gson.reflect", + "com.nimbusds.jose.shaded.gson.stream", + "com.nimbusds.jose.shaded.jcip", + "com.nimbusds.jose.util", + "com.nimbusds.jose.util.cache", + "com.nimbusds.jose.util.events", + "com.nimbusds.jose.util.health", + "com.nimbusds.jwt", + "com.nimbusds.jwt.proc", + "com.nimbusds.jwt.util" + ], + "com.nimbusds:oauth2-oidc-sdk": [ + "com.nimbusds.oauth2.sdk", + "com.nimbusds.oauth2.sdk.as", + "com.nimbusds.oauth2.sdk.assertions", + "com.nimbusds.oauth2.sdk.assertions.jwt", + "com.nimbusds.oauth2.sdk.assertions.saml2", + "com.nimbusds.oauth2.sdk.auth", + "com.nimbusds.oauth2.sdk.auth.verifier", + "com.nimbusds.oauth2.sdk.ciba", + "com.nimbusds.oauth2.sdk.client", + "com.nimbusds.oauth2.sdk.cnf", + "com.nimbusds.oauth2.sdk.device", + "com.nimbusds.oauth2.sdk.dpop", + "com.nimbusds.oauth2.sdk.dpop.verifiers", + "com.nimbusds.oauth2.sdk.http", + "com.nimbusds.oauth2.sdk.id", + "com.nimbusds.oauth2.sdk.jarm", + "com.nimbusds.oauth2.sdk.jose", + "com.nimbusds.oauth2.sdk.pkce", + "com.nimbusds.oauth2.sdk.rar", + "com.nimbusds.oauth2.sdk.token", + "com.nimbusds.oauth2.sdk.tokenexchange", + "com.nimbusds.oauth2.sdk.util", + "com.nimbusds.oauth2.sdk.util.date", + "com.nimbusds.oauth2.sdk.util.singleuse", + "com.nimbusds.oauth2.sdk.util.tls", + "com.nimbusds.openid.connect.sdk", + "com.nimbusds.openid.connect.sdk.assurance", + "com.nimbusds.openid.connect.sdk.assurance.claims", + "com.nimbusds.openid.connect.sdk.assurance.evidences", + "com.nimbusds.openid.connect.sdk.assurance.evidences.attachment", + "com.nimbusds.openid.connect.sdk.assurance.request", + "com.nimbusds.openid.connect.sdk.claims", + "com.nimbusds.openid.connect.sdk.federation", + "com.nimbusds.openid.connect.sdk.federation.api", + "com.nimbusds.openid.connect.sdk.federation.config", + "com.nimbusds.openid.connect.sdk.federation.entities", + "com.nimbusds.openid.connect.sdk.federation.policy", + "com.nimbusds.openid.connect.sdk.federation.policy.language", + "com.nimbusds.openid.connect.sdk.federation.policy.operations", + "com.nimbusds.openid.connect.sdk.federation.registration", + "com.nimbusds.openid.connect.sdk.federation.trust", + "com.nimbusds.openid.connect.sdk.federation.trust.constraints", + "com.nimbusds.openid.connect.sdk.federation.trust.marks", + "com.nimbusds.openid.connect.sdk.federation.utils", + "com.nimbusds.openid.connect.sdk.id", + "com.nimbusds.openid.connect.sdk.nativesso", + "com.nimbusds.openid.connect.sdk.op", + "com.nimbusds.openid.connect.sdk.rp", + "com.nimbusds.openid.connect.sdk.rp.statement", + "com.nimbusds.openid.connect.sdk.token", + "com.nimbusds.openid.connect.sdk.validators", + "com.nimbusds.secevent.sdk.claims" + ], + "com.squareup.okhttp3:okhttp-jvm": [ + "okhttp3", + "okhttp3.internal", + "okhttp3.internal.authenticator", + "okhttp3.internal.cache", + "okhttp3.internal.cache2", + "okhttp3.internal.concurrent", + "okhttp3.internal.connection", + "okhttp3.internal.graal", + "okhttp3.internal.http", + "okhttp3.internal.http1", + "okhttp3.internal.http2", + "okhttp3.internal.http2.flowcontrol", + "okhttp3.internal.idn", + "okhttp3.internal.platform", + "okhttp3.internal.proxy", + "okhttp3.internal.publicsuffix", + "okhttp3.internal.tls", + "okhttp3.internal.url", + "okhttp3.internal.ws" + ], + "com.squareup.okio:okio-jvm": [ + "okio", + "okio.internal" + ], + "com.typesafe:config": [ + "com.typesafe.config", + "com.typesafe.config.impl", + "com.typesafe.config.parser" + ], + "com.vaadin.external.google:android-json": [ + "org.json" + ], + "commons-codec:commons-codec": [ + "org.apache.commons.codec", + "org.apache.commons.codec.binary", + "org.apache.commons.codec.cli", + "org.apache.commons.codec.digest", + "org.apache.commons.codec.language", + "org.apache.commons.codec.language.bm", + "org.apache.commons.codec.net" + ], + "commons-io:commons-io": [ + "org.apache.commons.io", + "org.apache.commons.io.build", + "org.apache.commons.io.channels", + "org.apache.commons.io.charset", + "org.apache.commons.io.comparator", + "org.apache.commons.io.file", + "org.apache.commons.io.file.attribute", + "org.apache.commons.io.file.spi", + "org.apache.commons.io.filefilter", + "org.apache.commons.io.function", + "org.apache.commons.io.input", + "org.apache.commons.io.input.buffer", + "org.apache.commons.io.monitor", + "org.apache.commons.io.output", + "org.apache.commons.io.serialization" + ], + "commons-logging:commons-logging": [ + "org.apache.commons.logging", + "org.apache.commons.logging.impl" + ], + "io.cloudevents:cloudevents-api": [ + "io.cloudevents", + "io.cloudevents.lang", + "io.cloudevents.rw", + "io.cloudevents.types" + ], + "io.cloudevents:cloudevents-core": [ + "io.cloudevents.core", + "io.cloudevents.core.builder", + "io.cloudevents.core.data", + "io.cloudevents.core.extensions", + "io.cloudevents.core.extensions.impl", + "io.cloudevents.core.format", + "io.cloudevents.core.impl", + "io.cloudevents.core.message", + "io.cloudevents.core.message.impl", + "io.cloudevents.core.provider", + "io.cloudevents.core.v03", + "io.cloudevents.core.v1", + "io.cloudevents.core.validator" + ], + "io.cloudevents:cloudevents-json-jackson": [ + "io.cloudevents.jackson" + ], + "io.dropwizard.metrics:metrics-core": [ + "com.codahale.metrics" + ], + "io.micrometer:context-propagation": [ + "io.micrometer.context", + "io.micrometer.context.integration" + ], + "io.micrometer:micrometer-commons": [ + "io.micrometer.common", + "io.micrometer.common.annotation", + "io.micrometer.common.docs", + "io.micrometer.common.lang", + "io.micrometer.common.lang.internal", + "io.micrometer.common.util", + "io.micrometer.common.util.internal.logging" + ], + "io.micrometer:micrometer-core": [ + "io.micrometer.core.annotation", + "io.micrometer.core.aop", + "io.micrometer.core.instrument", + "io.micrometer.core.instrument.binder", + "io.micrometer.core.instrument.binder.cache", + "io.micrometer.core.instrument.binder.commonspool2", + "io.micrometer.core.instrument.binder.db", + "io.micrometer.core.instrument.binder.grpc", + "io.micrometer.core.instrument.binder.http", + "io.micrometer.core.instrument.binder.httpcomponents", + "io.micrometer.core.instrument.binder.httpcomponents.hc5", + "io.micrometer.core.instrument.binder.hystrix", + "io.micrometer.core.instrument.binder.jersey.server", + "io.micrometer.core.instrument.binder.jetty", + "io.micrometer.core.instrument.binder.jpa", + "io.micrometer.core.instrument.binder.jvm", + "io.micrometer.core.instrument.binder.jvm.convention", + "io.micrometer.core.instrument.binder.jvm.convention.micrometer", + "io.micrometer.core.instrument.binder.jvm.convention.otel", + "io.micrometer.core.instrument.binder.kafka", + "io.micrometer.core.instrument.binder.logging", + "io.micrometer.core.instrument.binder.mongodb", + "io.micrometer.core.instrument.binder.netty4", + "io.micrometer.core.instrument.binder.okhttp3", + "io.micrometer.core.instrument.binder.system", + "io.micrometer.core.instrument.binder.tomcat", + "io.micrometer.core.instrument.composite", + "io.micrometer.core.instrument.config", + "io.micrometer.core.instrument.config.validate", + "io.micrometer.core.instrument.cumulative", + "io.micrometer.core.instrument.distribution", + "io.micrometer.core.instrument.distribution.pause", + "io.micrometer.core.instrument.docs", + "io.micrometer.core.instrument.dropwizard", + "io.micrometer.core.instrument.internal", + "io.micrometer.core.instrument.kotlin", + "io.micrometer.core.instrument.logging", + "io.micrometer.core.instrument.noop", + "io.micrometer.core.instrument.observation", + "io.micrometer.core.instrument.push", + "io.micrometer.core.instrument.search", + "io.micrometer.core.instrument.simple", + "io.micrometer.core.instrument.step", + "io.micrometer.core.instrument.util", + "io.micrometer.core.ipc.http", + "io.micrometer.core.util.internal.logging" + ], + "io.micrometer:micrometer-jakarta9": [ + "io.micrometer.jakarta9.instrument.jms", + "io.micrometer.jakarta9.instrument.mail" + ], + "io.micrometer:micrometer-observation": [ + "io.micrometer.observation", + "io.micrometer.observation.annotation", + "io.micrometer.observation.aop", + "io.micrometer.observation.contextpropagation", + "io.micrometer.observation.docs", + "io.micrometer.observation.transport" + ], + "io.micrometer:micrometer-observation-test": [ + "io.micrometer.observation.tck" + ], + "io.micrometer:micrometer-tracing": [ + "io.micrometer.tracing", + "io.micrometer.tracing.annotation", + "io.micrometer.tracing.contextpropagation", + "io.micrometer.tracing.contextpropagation.reactor", + "io.micrometer.tracing.docs", + "io.micrometer.tracing.exporter", + "io.micrometer.tracing.handler", + "io.micrometer.tracing.internal", + "io.micrometer.tracing.propagation" + ], + "io.micrometer:micrometer-tracing-bridge-otel": [ + "io.micrometer.tracing.otel", + "io.micrometer.tracing.otel.bridge", + "io.micrometer.tracing.otel.propagation" + ], + "io.nats:jnats": [ + "io.nats.client", + "io.nats.client.api", + "io.nats.client.impl", + "io.nats.client.support", + "io.nats.service" + ], + "io.netty:netty-buffer": [ + "io.netty.buffer", + "io.netty.buffer.search" + ], + "io.netty:netty-codec-base": [ + "io.netty.handler.codec", + "io.netty.handler.codec.base64", + "io.netty.handler.codec.bytes", + "io.netty.handler.codec.json", + "io.netty.handler.codec.serialization", + "io.netty.handler.codec.string" + ], + "io.netty:netty-codec-classes-quic": [ + "io.netty.handler.codec.quic" + ], + "io.netty:netty-codec-compression": [ + "io.netty.handler.codec.compression" + ], + "io.netty:netty-codec-dns": [ + "io.netty.handler.codec.dns" + ], + "io.netty:netty-codec-http": [ + "io.netty.handler.codec.http", + "io.netty.handler.codec.http.cookie", + "io.netty.handler.codec.http.cors", + "io.netty.handler.codec.http.multipart", + "io.netty.handler.codec.http.websocketx", + "io.netty.handler.codec.http.websocketx.extensions", + "io.netty.handler.codec.http.websocketx.extensions.compression", + "io.netty.handler.codec.rtsp", + "io.netty.handler.codec.spdy" + ], + "io.netty:netty-codec-http2": [ + "io.netty.handler.codec.http2" + ], + "io.netty:netty-codec-http3": [ + "io.netty.handler.codec.http3" + ], + "io.netty:netty-codec-socks": [ + "io.netty.handler.codec.socks", + "io.netty.handler.codec.socksx", + "io.netty.handler.codec.socksx.v4", + "io.netty.handler.codec.socksx.v5" + ], + "io.netty:netty-common": [ + "io.netty.util", + "io.netty.util.collection", + "io.netty.util.concurrent", + "io.netty.util.internal", + "io.netty.util.internal.logging", + "io.netty.util.internal.shaded.org.jctools.counters", + "io.netty.util.internal.shaded.org.jctools.maps", + "io.netty.util.internal.shaded.org.jctools.queues", + "io.netty.util.internal.shaded.org.jctools.queues.atomic", + "io.netty.util.internal.shaded.org.jctools.queues.atomic.unpadded", + "io.netty.util.internal.shaded.org.jctools.queues.unpadded", + "io.netty.util.internal.shaded.org.jctools.util", + "io.netty.util.internal.svm" + ], + "io.netty:netty-handler": [ + "io.netty.handler.address", + "io.netty.handler.flow", + "io.netty.handler.flush", + "io.netty.handler.ipfilter", + "io.netty.handler.logging", + "io.netty.handler.pcap", + "io.netty.handler.ssl", + "io.netty.handler.ssl.util", + "io.netty.handler.stream", + "io.netty.handler.timeout", + "io.netty.handler.traffic" + ], + "io.netty:netty-handler-proxy": [ + "io.netty.handler.proxy" + ], + "io.netty:netty-resolver": [ + "io.netty.resolver" + ], + "io.netty:netty-resolver-dns": [ + "io.netty.resolver.dns" + ], + "io.netty:netty-resolver-dns-classes-macos": [ + "io.netty.resolver.dns.macos" + ], + "io.netty:netty-transport": [ + "io.netty.bootstrap", + "io.netty.channel", + "io.netty.channel.embedded", + "io.netty.channel.group", + "io.netty.channel.internal", + "io.netty.channel.local", + "io.netty.channel.nio", + "io.netty.channel.oio", + "io.netty.channel.pool", + "io.netty.channel.socket", + "io.netty.channel.socket.nio", + "io.netty.channel.socket.oio" + ], + "io.netty:netty-transport-classes-epoll": [ + "io.netty.channel.epoll" + ], + "io.netty:netty-transport-native-unix-common": [ + "io.netty.channel.unix" + ], + "io.opentelemetry.semconv:opentelemetry-semconv": [ + "io.opentelemetry.semconv" + ], + "io.opentelemetry:opentelemetry-api": [ + "io.opentelemetry.api", + "io.opentelemetry.api.baggage", + "io.opentelemetry.api.baggage.propagation", + "io.opentelemetry.api.common", + "io.opentelemetry.api.internal", + "io.opentelemetry.api.logs", + "io.opentelemetry.api.metrics", + "io.opentelemetry.api.trace", + "io.opentelemetry.api.trace.propagation", + "io.opentelemetry.api.trace.propagation.internal" + ], + "io.opentelemetry:opentelemetry-common": [ + "io.opentelemetry.common" + ], + "io.opentelemetry:opentelemetry-context": [ + "io.opentelemetry.context", + "io.opentelemetry.context.internal.shaded", + "io.opentelemetry.context.propagation", + "io.opentelemetry.context.propagation.internal" + ], + "io.opentelemetry:opentelemetry-exporter-common": [ + "io.opentelemetry.exporter.internal", + "io.opentelemetry.exporter.internal.compression", + "io.opentelemetry.exporter.internal.grpc", + "io.opentelemetry.exporter.internal.http", + "io.opentelemetry.exporter.internal.marshal", + "io.opentelemetry.exporter.internal.metrics" + ], + "io.opentelemetry:opentelemetry-exporter-otlp": [ + "io.opentelemetry.exporter.otlp.all.internal", + "io.opentelemetry.exporter.otlp.http.logs", + "io.opentelemetry.exporter.otlp.http.metrics", + "io.opentelemetry.exporter.otlp.http.trace", + "io.opentelemetry.exporter.otlp.internal", + "io.opentelemetry.exporter.otlp.logs", + "io.opentelemetry.exporter.otlp.metrics", + "io.opentelemetry.exporter.otlp.trace" + ], + "io.opentelemetry:opentelemetry-exporter-otlp-common": [ + "io.opentelemetry.exporter.internal.otlp", + "io.opentelemetry.exporter.internal.otlp.logs", + "io.opentelemetry.exporter.internal.otlp.metrics", + "io.opentelemetry.exporter.internal.otlp.traces", + "io.opentelemetry.proto.collector.logs.v1.internal", + "io.opentelemetry.proto.collector.metrics.v1.internal", + "io.opentelemetry.proto.collector.profiles.v1development.internal", + "io.opentelemetry.proto.collector.trace.v1.internal", + "io.opentelemetry.proto.common.v1.internal", + "io.opentelemetry.proto.logs.v1.internal", + "io.opentelemetry.proto.metrics.v1.internal", + "io.opentelemetry.proto.profiles.v1development.internal", + "io.opentelemetry.proto.resource.v1.internal", + "io.opentelemetry.proto.trace.v1.internal" + ], + "io.opentelemetry:opentelemetry-exporter-sender-okhttp": [ + "io.opentelemetry.exporter.sender.okhttp.internal" + ], + "io.opentelemetry:opentelemetry-extension-trace-propagators": [ + "io.opentelemetry.extension.trace.propagation", + "io.opentelemetry.extension.trace.propagation.internal" + ], + "io.opentelemetry:opentelemetry-sdk": [ + "io.opentelemetry.sdk" + ], + "io.opentelemetry:opentelemetry-sdk-common": [ + "io.opentelemetry.sdk.common", + "io.opentelemetry.sdk.common.export", + "io.opentelemetry.sdk.common.internal", + "io.opentelemetry.sdk.internal", + "io.opentelemetry.sdk.resources" + ], + "io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi": [ + "io.opentelemetry.sdk.autoconfigure.spi", + "io.opentelemetry.sdk.autoconfigure.spi.internal", + "io.opentelemetry.sdk.autoconfigure.spi.logs", + "io.opentelemetry.sdk.autoconfigure.spi.metrics", + "io.opentelemetry.sdk.autoconfigure.spi.traces" + ], + "io.opentelemetry:opentelemetry-sdk-logs": [ + "io.opentelemetry.sdk.logs", + "io.opentelemetry.sdk.logs.data", + "io.opentelemetry.sdk.logs.data.internal", + "io.opentelemetry.sdk.logs.export", + "io.opentelemetry.sdk.logs.internal" + ], + "io.opentelemetry:opentelemetry-sdk-metrics": [ + "io.opentelemetry.sdk.metrics", + "io.opentelemetry.sdk.metrics.data", + "io.opentelemetry.sdk.metrics.export", + "io.opentelemetry.sdk.metrics.internal", + "io.opentelemetry.sdk.metrics.internal.aggregator", + "io.opentelemetry.sdk.metrics.internal.concurrent", + "io.opentelemetry.sdk.metrics.internal.data", + "io.opentelemetry.sdk.metrics.internal.debug", + "io.opentelemetry.sdk.metrics.internal.descriptor", + "io.opentelemetry.sdk.metrics.internal.exemplar", + "io.opentelemetry.sdk.metrics.internal.export", + "io.opentelemetry.sdk.metrics.internal.state", + "io.opentelemetry.sdk.metrics.internal.view" + ], + "io.opentelemetry:opentelemetry-sdk-testing": [ + "io.opentelemetry.sdk.testing.assertj", + "io.opentelemetry.sdk.testing.context", + "io.opentelemetry.sdk.testing.exporter", + "io.opentelemetry.sdk.testing.junit4", + "io.opentelemetry.sdk.testing.junit5", + "io.opentelemetry.sdk.testing.logs", + "io.opentelemetry.sdk.testing.logs.internal", + "io.opentelemetry.sdk.testing.metrics", + "io.opentelemetry.sdk.testing.time", + "io.opentelemetry.sdk.testing.trace" + ], + "io.opentelemetry:opentelemetry-sdk-trace": [ + "io.opentelemetry.internal.shaded.jctools.counters", + "io.opentelemetry.internal.shaded.jctools.maps", + "io.opentelemetry.internal.shaded.jctools.queues", + "io.opentelemetry.internal.shaded.jctools.queues.atomic", + "io.opentelemetry.internal.shaded.jctools.queues.atomic.unpadded", + "io.opentelemetry.internal.shaded.jctools.queues.unpadded", + "io.opentelemetry.internal.shaded.jctools.util", + "io.opentelemetry.sdk.trace", + "io.opentelemetry.sdk.trace.data", + "io.opentelemetry.sdk.trace.export", + "io.opentelemetry.sdk.trace.internal", + "io.opentelemetry.sdk.trace.samplers" + ], + "io.projectreactor.netty:reactor-netty-core": [ + "reactor.netty", + "reactor.netty.channel", + "reactor.netty.contextpropagation", + "reactor.netty.internal.shaded.reactor.pool", + "reactor.netty.internal.shaded.reactor.pool.decorators", + "reactor.netty.internal.shaded.reactor.pool.introspection", + "reactor.netty.internal.util", + "reactor.netty.observability", + "reactor.netty.resources", + "reactor.netty.tcp", + "reactor.netty.transport", + "reactor.netty.transport.logging", + "reactor.netty.udp" + ], + "io.projectreactor.netty:reactor-netty-http": [ + "reactor.netty.http", + "reactor.netty.http.client", + "reactor.netty.http.internal", + "reactor.netty.http.logging", + "reactor.netty.http.observability", + "reactor.netty.http.server", + "reactor.netty.http.server.compression", + "reactor.netty.http.server.logging", + "reactor.netty.http.server.logging.error", + "reactor.netty.http.websocket" + ], + "io.projectreactor:reactor-core": [ + "reactor.adapter", + "reactor.core", + "reactor.core.observability", + "reactor.core.publisher", + "reactor.core.scheduler", + "reactor.util", + "reactor.util.annotation", + "reactor.util.concurrent", + "reactor.util.context", + "reactor.util.function", + "reactor.util.repeat", + "reactor.util.retry" + ], + "io.projectreactor:reactor-test": [ + "reactor.test", + "reactor.test.publisher", + "reactor.test.scheduler", + "reactor.test.subscriber", + "reactor.test.util" + ], + "io.swagger.core.v3:swagger-annotations-jakarta": [ + "io.swagger.v3.oas.annotations", + "io.swagger.v3.oas.annotations.callbacks", + "io.swagger.v3.oas.annotations.enums", + "io.swagger.v3.oas.annotations.extensions", + "io.swagger.v3.oas.annotations.headers", + "io.swagger.v3.oas.annotations.info", + "io.swagger.v3.oas.annotations.links", + "io.swagger.v3.oas.annotations.media", + "io.swagger.v3.oas.annotations.parameters", + "io.swagger.v3.oas.annotations.responses", + "io.swagger.v3.oas.annotations.security", + "io.swagger.v3.oas.annotations.servers", + "io.swagger.v3.oas.annotations.tags" + ], + "io.swagger.core.v3:swagger-core-jakarta": [ + "io.swagger.v3.core.converter", + "io.swagger.v3.core.filter", + "io.swagger.v3.core.jackson", + "io.swagger.v3.core.jackson.mixin", + "io.swagger.v3.core.model", + "io.swagger.v3.core.util" + ], + "io.swagger.core.v3:swagger-models-jakarta": [ + "io.swagger.v3.oas.models", + "io.swagger.v3.oas.models.annotations", + "io.swagger.v3.oas.models.callbacks", + "io.swagger.v3.oas.models.examples", + "io.swagger.v3.oas.models.headers", + "io.swagger.v3.oas.models.info", + "io.swagger.v3.oas.models.links", + "io.swagger.v3.oas.models.media", + "io.swagger.v3.oas.models.parameters", + "io.swagger.v3.oas.models.responses", + "io.swagger.v3.oas.models.security", + "io.swagger.v3.oas.models.servers", + "io.swagger.v3.oas.models.tags" + ], + "jakarta.activation:jakarta.activation-api": [ + "jakarta.activation", + "jakarta.activation.spi" + ], + "jakarta.annotation:jakarta.annotation-api": [ + "jakarta.annotation", + "jakarta.annotation.security", + "jakarta.annotation.sql" + ], + "jakarta.servlet:jakarta.servlet-api": [ + "jakarta.servlet", + "jakarta.servlet.annotation", + "jakarta.servlet.descriptor", + "jakarta.servlet.http" + ], + "jakarta.validation:jakarta.validation-api": [ + "jakarta.validation", + "jakarta.validation.bootstrap", + "jakarta.validation.constraints", + "jakarta.validation.constraintvalidation", + "jakarta.validation.executable", + "jakarta.validation.groups", + "jakarta.validation.metadata", + "jakarta.validation.spi", + "jakarta.validation.valueextraction" + ], + "jakarta.xml.bind:jakarta.xml.bind-api": [ + "jakarta.xml.bind", + "jakarta.xml.bind.annotation", + "jakarta.xml.bind.annotation.adapters", + "jakarta.xml.bind.attachment", + "jakarta.xml.bind.helpers", + "jakarta.xml.bind.util" + ], + "net.bytebuddy:byte-buddy": [ + "net.bytebuddy", + "net.bytebuddy.agent.builder", + "net.bytebuddy.asm", + "net.bytebuddy.build", + "net.bytebuddy.description", + "net.bytebuddy.description.annotation", + "net.bytebuddy.description.enumeration", + "net.bytebuddy.description.field", + "net.bytebuddy.description.method", + "net.bytebuddy.description.modifier", + "net.bytebuddy.description.type", + "net.bytebuddy.dynamic", + "net.bytebuddy.dynamic.loading", + "net.bytebuddy.dynamic.scaffold", + "net.bytebuddy.dynamic.scaffold.inline", + "net.bytebuddy.dynamic.scaffold.subclass", + "net.bytebuddy.implementation", + "net.bytebuddy.implementation.attribute", + "net.bytebuddy.implementation.auxiliary", + "net.bytebuddy.implementation.bind", + "net.bytebuddy.implementation.bind.annotation", + "net.bytebuddy.implementation.bytecode", + "net.bytebuddy.implementation.bytecode.assign", + "net.bytebuddy.implementation.bytecode.assign.primitive", + "net.bytebuddy.implementation.bytecode.assign.reference", + "net.bytebuddy.implementation.bytecode.collection", + "net.bytebuddy.implementation.bytecode.constant", + "net.bytebuddy.implementation.bytecode.member", + "net.bytebuddy.jar.asm", + "net.bytebuddy.jar.asm.commons", + "net.bytebuddy.jar.asm.signature", + "net.bytebuddy.jar.asmjdkbridge", + "net.bytebuddy.matcher", + "net.bytebuddy.pool", + "net.bytebuddy.utility", + "net.bytebuddy.utility.dispatcher", + "net.bytebuddy.utility.nullability", + "net.bytebuddy.utility.privilege", + "net.bytebuddy.utility.visitor" + ], + "net.bytebuddy:byte-buddy-agent": [ + "net.bytebuddy.agent", + "net.bytebuddy.agent.utility.nullability" + ], + "net.java.dev.jna:jna": [ + "com.sun.jna", + "com.sun.jna.internal", + "com.sun.jna.ptr", + "com.sun.jna.win32" + ], + "net.minidev:accessors-smart": [ + "net.minidev.asm", + "net.minidev.asm.ex" + ], + "net.minidev:json-smart": [ + "net.minidev.json", + "net.minidev.json.annotate", + "net.minidev.json.parser", + "net.minidev.json.reader", + "net.minidev.json.writer" + ], + "org.apache.cassandra:java-driver-core": [ + "com.datastax.dse.driver.api.core", + "com.datastax.dse.driver.api.core.auth", + "com.datastax.dse.driver.api.core.config", + "com.datastax.dse.driver.api.core.cql.continuous", + "com.datastax.dse.driver.api.core.cql.continuous.reactive", + "com.datastax.dse.driver.api.core.cql.reactive", + "com.datastax.dse.driver.api.core.data.geometry", + "com.datastax.dse.driver.api.core.data.time", + "com.datastax.dse.driver.api.core.graph", + "com.datastax.dse.driver.api.core.graph.predicates", + "com.datastax.dse.driver.api.core.graph.reactive", + "com.datastax.dse.driver.api.core.metadata", + "com.datastax.dse.driver.api.core.metadata.schema", + "com.datastax.dse.driver.api.core.metrics", + "com.datastax.dse.driver.api.core.servererrors", + "com.datastax.dse.driver.api.core.type", + "com.datastax.dse.driver.api.core.type.codec", + "com.datastax.dse.driver.internal.core", + "com.datastax.dse.driver.internal.core.auth", + "com.datastax.dse.driver.internal.core.cql", + "com.datastax.dse.driver.internal.core.cql.continuous", + "com.datastax.dse.driver.internal.core.cql.continuous.reactive", + "com.datastax.dse.driver.internal.core.cql.reactive", + "com.datastax.dse.driver.internal.core.data.geometry", + "com.datastax.dse.driver.internal.core.graph", + "com.datastax.dse.driver.internal.core.graph.binary", + "com.datastax.dse.driver.internal.core.graph.binary.buffer", + "com.datastax.dse.driver.internal.core.graph.reactive", + "com.datastax.dse.driver.internal.core.insights", + "com.datastax.dse.driver.internal.core.insights.configuration", + "com.datastax.dse.driver.internal.core.insights.exceptions", + "com.datastax.dse.driver.internal.core.insights.schema", + "com.datastax.dse.driver.internal.core.loadbalancing", + "com.datastax.dse.driver.internal.core.metadata.schema", + "com.datastax.dse.driver.internal.core.metadata.schema.parsing", + "com.datastax.dse.driver.internal.core.protocol", + "com.datastax.dse.driver.internal.core.search", + "com.datastax.dse.driver.internal.core.session", + "com.datastax.dse.driver.internal.core.type.codec", + "com.datastax.dse.driver.internal.core.type.codec.geometry", + "com.datastax.dse.driver.internal.core.type.codec.time", + "com.datastax.dse.driver.internal.core.util.concurrent", + "com.datastax.oss.driver.api.core", + "com.datastax.oss.driver.api.core.addresstranslation", + "com.datastax.oss.driver.api.core.auth", + "com.datastax.oss.driver.api.core.config", + "com.datastax.oss.driver.api.core.connection", + "com.datastax.oss.driver.api.core.context", + "com.datastax.oss.driver.api.core.cql", + "com.datastax.oss.driver.api.core.data", + "com.datastax.oss.driver.api.core.detach", + "com.datastax.oss.driver.api.core.loadbalancing", + "com.datastax.oss.driver.api.core.metadata", + "com.datastax.oss.driver.api.core.metadata.schema", + "com.datastax.oss.driver.api.core.metadata.token", + "com.datastax.oss.driver.api.core.metrics", + "com.datastax.oss.driver.api.core.paging", + "com.datastax.oss.driver.api.core.retry", + "com.datastax.oss.driver.api.core.servererrors", + "com.datastax.oss.driver.api.core.session", + "com.datastax.oss.driver.api.core.session.throttling", + "com.datastax.oss.driver.api.core.specex", + "com.datastax.oss.driver.api.core.ssl", + "com.datastax.oss.driver.api.core.time", + "com.datastax.oss.driver.api.core.tracker", + "com.datastax.oss.driver.api.core.type", + "com.datastax.oss.driver.api.core.type.codec", + "com.datastax.oss.driver.api.core.type.codec.registry", + "com.datastax.oss.driver.api.core.type.reflect", + "com.datastax.oss.driver.api.core.uuid", + "com.datastax.oss.driver.internal.core", + "com.datastax.oss.driver.internal.core.addresstranslation", + "com.datastax.oss.driver.internal.core.adminrequest", + "com.datastax.oss.driver.internal.core.auth", + "com.datastax.oss.driver.internal.core.channel", + "com.datastax.oss.driver.internal.core.config", + "com.datastax.oss.driver.internal.core.config.cloud", + "com.datastax.oss.driver.internal.core.config.composite", + "com.datastax.oss.driver.internal.core.config.map", + "com.datastax.oss.driver.internal.core.config.typesafe", + "com.datastax.oss.driver.internal.core.connection", + "com.datastax.oss.driver.internal.core.context", + "com.datastax.oss.driver.internal.core.control", + "com.datastax.oss.driver.internal.core.cql", + "com.datastax.oss.driver.internal.core.data", + "com.datastax.oss.driver.internal.core.loadbalancing", + "com.datastax.oss.driver.internal.core.loadbalancing.helper", + "com.datastax.oss.driver.internal.core.loadbalancing.nodeset", + "com.datastax.oss.driver.internal.core.metadata", + "com.datastax.oss.driver.internal.core.metadata.schema", + "com.datastax.oss.driver.internal.core.metadata.schema.events", + "com.datastax.oss.driver.internal.core.metadata.schema.parsing", + "com.datastax.oss.driver.internal.core.metadata.schema.queries", + "com.datastax.oss.driver.internal.core.metadata.schema.refresh", + "com.datastax.oss.driver.internal.core.metadata.token", + "com.datastax.oss.driver.internal.core.metrics", + "com.datastax.oss.driver.internal.core.os", + "com.datastax.oss.driver.internal.core.pool", + "com.datastax.oss.driver.internal.core.protocol", + "com.datastax.oss.driver.internal.core.retry", + "com.datastax.oss.driver.internal.core.servererrors", + "com.datastax.oss.driver.internal.core.session", + "com.datastax.oss.driver.internal.core.session.throttling", + "com.datastax.oss.driver.internal.core.specex", + "com.datastax.oss.driver.internal.core.ssl", + "com.datastax.oss.driver.internal.core.time", + "com.datastax.oss.driver.internal.core.tracker", + "com.datastax.oss.driver.internal.core.type", + "com.datastax.oss.driver.internal.core.type.codec", + "com.datastax.oss.driver.internal.core.type.codec.extras", + "com.datastax.oss.driver.internal.core.type.codec.extras.array", + "com.datastax.oss.driver.internal.core.type.codec.extras.enums", + "com.datastax.oss.driver.internal.core.type.codec.extras.json", + "com.datastax.oss.driver.internal.core.type.codec.extras.time", + "com.datastax.oss.driver.internal.core.type.codec.extras.vector", + "com.datastax.oss.driver.internal.core.type.codec.registry", + "com.datastax.oss.driver.internal.core.type.util", + "com.datastax.oss.driver.internal.core.util", + "com.datastax.oss.driver.internal.core.util.collection", + "com.datastax.oss.driver.internal.core.util.concurrent" + ], + "org.apache.cassandra:java-driver-guava-shaded": [ + "com.datastax.oss.driver.shaded.guava.common.annotations", + "com.datastax.oss.driver.shaded.guava.common.base", + "com.datastax.oss.driver.shaded.guava.common.base.internal", + "com.datastax.oss.driver.shaded.guava.common.cache", + "com.datastax.oss.driver.shaded.guava.common.collect", + "com.datastax.oss.driver.shaded.guava.common.escape", + "com.datastax.oss.driver.shaded.guava.common.eventbus", + "com.datastax.oss.driver.shaded.guava.common.graph", + "com.datastax.oss.driver.shaded.guava.common.hash", + "com.datastax.oss.driver.shaded.guava.common.html", + "com.datastax.oss.driver.shaded.guava.common.io", + "com.datastax.oss.driver.shaded.guava.common.math", + "com.datastax.oss.driver.shaded.guava.common.net", + "com.datastax.oss.driver.shaded.guava.common.primitives", + "com.datastax.oss.driver.shaded.guava.common.reflect", + "com.datastax.oss.driver.shaded.guava.common.util.concurrent", + "com.datastax.oss.driver.shaded.guava.common.util.concurrent.internal", + "com.datastax.oss.driver.shaded.guava.common.xml", + "com.datastax.oss.driver.shaded.guava.j2objc.annotations", + "com.datastax.oss.driver.shaded.guava.thirdparty.publicsuffix" + ], + "org.apache.cassandra:java-driver-metrics-micrometer": [ + "com.datastax.oss.driver.internal.metrics.micrometer" + ], + "org.apache.cassandra:java-driver-query-builder": [ + "com.datastax.dse.driver.api.querybuilder", + "com.datastax.dse.driver.api.querybuilder.schema", + "com.datastax.dse.driver.internal.querybuilder.schema", + "com.datastax.oss.driver.api.querybuilder", + "com.datastax.oss.driver.api.querybuilder.condition", + "com.datastax.oss.driver.api.querybuilder.delete", + "com.datastax.oss.driver.api.querybuilder.insert", + "com.datastax.oss.driver.api.querybuilder.relation", + "com.datastax.oss.driver.api.querybuilder.schema", + "com.datastax.oss.driver.api.querybuilder.schema.compaction", + "com.datastax.oss.driver.api.querybuilder.select", + "com.datastax.oss.driver.api.querybuilder.term", + "com.datastax.oss.driver.api.querybuilder.truncate", + "com.datastax.oss.driver.api.querybuilder.update", + "com.datastax.oss.driver.internal.querybuilder", + "com.datastax.oss.driver.internal.querybuilder.condition", + "com.datastax.oss.driver.internal.querybuilder.delete", + "com.datastax.oss.driver.internal.querybuilder.insert", + "com.datastax.oss.driver.internal.querybuilder.lhs", + "com.datastax.oss.driver.internal.querybuilder.relation", + "com.datastax.oss.driver.internal.querybuilder.schema", + "com.datastax.oss.driver.internal.querybuilder.schema.compaction", + "com.datastax.oss.driver.internal.querybuilder.select", + "com.datastax.oss.driver.internal.querybuilder.term", + "com.datastax.oss.driver.internal.querybuilder.truncate", + "com.datastax.oss.driver.internal.querybuilder.update" + ], + "org.apache.commons:commons-compress": [ + "org.apache.commons.compress", + "org.apache.commons.compress.archivers", + "org.apache.commons.compress.archivers.ar", + "org.apache.commons.compress.archivers.arj", + "org.apache.commons.compress.archivers.cpio", + "org.apache.commons.compress.archivers.dump", + "org.apache.commons.compress.archivers.examples", + "org.apache.commons.compress.archivers.jar", + "org.apache.commons.compress.archivers.sevenz", + "org.apache.commons.compress.archivers.tar", + "org.apache.commons.compress.archivers.zip", + "org.apache.commons.compress.changes", + "org.apache.commons.compress.compressors", + "org.apache.commons.compress.compressors.brotli", + "org.apache.commons.compress.compressors.bzip2", + "org.apache.commons.compress.compressors.deflate", + "org.apache.commons.compress.compressors.deflate64", + "org.apache.commons.compress.compressors.gzip", + "org.apache.commons.compress.compressors.lz4", + "org.apache.commons.compress.compressors.lz77support", + "org.apache.commons.compress.compressors.lzma", + "org.apache.commons.compress.compressors.lzw", + "org.apache.commons.compress.compressors.pack200", + "org.apache.commons.compress.compressors.snappy", + "org.apache.commons.compress.compressors.xz", + "org.apache.commons.compress.compressors.z", + "org.apache.commons.compress.compressors.zstandard", + "org.apache.commons.compress.harmony", + "org.apache.commons.compress.harmony.archive.internal.nls", + "org.apache.commons.compress.harmony.pack200", + "org.apache.commons.compress.harmony.unpack200", + "org.apache.commons.compress.harmony.unpack200.bytecode", + "org.apache.commons.compress.harmony.unpack200.bytecode.forms", + "org.apache.commons.compress.java.util.jar", + "org.apache.commons.compress.parallel", + "org.apache.commons.compress.utils" + ], + "org.apache.commons:commons-lang3": [ + "org.apache.commons.lang3", + "org.apache.commons.lang3.arch", + "org.apache.commons.lang3.builder", + "org.apache.commons.lang3.compare", + "org.apache.commons.lang3.concurrent", + "org.apache.commons.lang3.concurrent.locks", + "org.apache.commons.lang3.event", + "org.apache.commons.lang3.exception", + "org.apache.commons.lang3.function", + "org.apache.commons.lang3.math", + "org.apache.commons.lang3.mutable", + "org.apache.commons.lang3.reflect", + "org.apache.commons.lang3.stream", + "org.apache.commons.lang3.text", + "org.apache.commons.lang3.text.translate", + "org.apache.commons.lang3.time", + "org.apache.commons.lang3.tuple", + "org.apache.commons.lang3.util" + ], + "org.apache.logging.log4j:log4j-api": [ + "org.apache.logging.log4j", + "org.apache.logging.log4j.internal", + "org.apache.logging.log4j.internal.annotation", + "org.apache.logging.log4j.internal.map", + "org.apache.logging.log4j.message", + "org.apache.logging.log4j.simple", + "org.apache.logging.log4j.simple.internal", + "org.apache.logging.log4j.spi", + "org.apache.logging.log4j.status", + "org.apache.logging.log4j.util", + "org.apache.logging.log4j.util.internal" + ], + "org.apache.logging.log4j:log4j-to-slf4j": [ + "org.apache.logging.slf4j" + ], + "org.apache.tomcat.embed:tomcat-embed-core": [ + "jakarta.security.auth.message", + "jakarta.security.auth.message.callback", + "jakarta.security.auth.message.config", + "jakarta.security.auth.message.module", + "jakarta.servlet", + "jakarta.servlet.annotation", + "jakarta.servlet.descriptor", + "jakarta.servlet.http", + "org.apache.catalina", + "org.apache.catalina.authenticator", + "org.apache.catalina.authenticator.jaspic", + "org.apache.catalina.connector", + "org.apache.catalina.core", + "org.apache.catalina.deploy", + "org.apache.catalina.filters", + "org.apache.catalina.loader", + "org.apache.catalina.manager", + "org.apache.catalina.manager.host", + "org.apache.catalina.manager.util", + "org.apache.catalina.mapper", + "org.apache.catalina.mbeans", + "org.apache.catalina.realm", + "org.apache.catalina.security", + "org.apache.catalina.servlets", + "org.apache.catalina.session", + "org.apache.catalina.startup", + "org.apache.catalina.users", + "org.apache.catalina.util", + "org.apache.catalina.valves", + "org.apache.catalina.valves.rewrite", + "org.apache.catalina.webresources", + "org.apache.catalina.webresources.war", + "org.apache.coyote", + "org.apache.coyote.ajp", + "org.apache.coyote.http11", + "org.apache.coyote.http11.filters", + "org.apache.coyote.http11.upgrade", + "org.apache.coyote.http2", + "org.apache.juli", + "org.apache.juli.logging", + "org.apache.naming", + "org.apache.naming.factory", + "org.apache.naming.java", + "org.apache.tomcat", + "org.apache.tomcat.jni", + "org.apache.tomcat.util", + "org.apache.tomcat.util.bcel", + "org.apache.tomcat.util.bcel.classfile", + "org.apache.tomcat.util.buf", + "org.apache.tomcat.util.collections", + "org.apache.tomcat.util.compat", + "org.apache.tomcat.util.concurrent", + "org.apache.tomcat.util.descriptor", + "org.apache.tomcat.util.descriptor.tagplugin", + "org.apache.tomcat.util.descriptor.web", + "org.apache.tomcat.util.digester", + "org.apache.tomcat.util.file", + "org.apache.tomcat.util.http", + "org.apache.tomcat.util.http.fileupload", + "org.apache.tomcat.util.http.fileupload.disk", + "org.apache.tomcat.util.http.fileupload.impl", + "org.apache.tomcat.util.http.fileupload.servlet", + "org.apache.tomcat.util.http.fileupload.util", + "org.apache.tomcat.util.http.fileupload.util.mime", + "org.apache.tomcat.util.http.parser", + "org.apache.tomcat.util.json", + "org.apache.tomcat.util.log", + "org.apache.tomcat.util.modeler", + "org.apache.tomcat.util.modeler.modules", + "org.apache.tomcat.util.net", + "org.apache.tomcat.util.net.jsse", + "org.apache.tomcat.util.net.openssl", + "org.apache.tomcat.util.net.openssl.ciphers", + "org.apache.tomcat.util.res", + "org.apache.tomcat.util.scan", + "org.apache.tomcat.util.security", + "org.apache.tomcat.util.threads" + ], + "org.apache.tomcat.embed:tomcat-embed-el": [ + "jakarta.el", + "org.apache.el", + "org.apache.el.lang", + "org.apache.el.parser", + "org.apache.el.stream", + "org.apache.el.util" + ], + "org.apache.tomcat.embed:tomcat-embed-websocket": [ + "jakarta.websocket", + "jakarta.websocket.server", + "org.apache.tomcat.websocket", + "org.apache.tomcat.websocket.pojo", + "org.apache.tomcat.websocket.server" + ], + "org.apiguardian:apiguardian-api": [ + "org.apiguardian.api" + ], + "org.assertj:assertj-core": [ + "org.assertj.core.annotation", + "org.assertj.core.annotations", + "org.assertj.core.api", + "org.assertj.core.api.exception", + "org.assertj.core.api.filter", + "org.assertj.core.api.iterable", + "org.assertj.core.api.junit.jupiter", + "org.assertj.core.api.recursive", + "org.assertj.core.api.recursive.assertion", + "org.assertj.core.api.recursive.comparison", + "org.assertj.core.condition", + "org.assertj.core.configuration", + "org.assertj.core.data", + "org.assertj.core.description", + "org.assertj.core.error", + "org.assertj.core.error.array2d", + "org.assertj.core.error.future", + "org.assertj.core.error.uri", + "org.assertj.core.extractor", + "org.assertj.core.groups", + "org.assertj.core.internal", + "org.assertj.core.internal.annotation", + "org.assertj.core.matcher", + "org.assertj.core.presentation", + "org.assertj.core.util", + "org.assertj.core.util.diff", + "org.assertj.core.util.diff.myers", + "org.assertj.core.util.introspection", + "org.assertj.core.util.xml" + ], + "org.awaitility:awaitility": [ + "org.awaitility", + "org.awaitility.classpath", + "org.awaitility.constraint", + "org.awaitility.core", + "org.awaitility.pollinterval", + "org.awaitility.reflect", + "org.awaitility.reflect.exception", + "org.awaitility.spi" + ], + "org.bouncycastle:bcprov-jdk18on": [ + "org.bouncycastle", + "org.bouncycastle.asn1", + "org.bouncycastle.asn1.anssi", + "org.bouncycastle.asn1.bc", + "org.bouncycastle.asn1.cryptopro", + "org.bouncycastle.asn1.gm", + "org.bouncycastle.asn1.nist", + "org.bouncycastle.asn1.ocsp", + "org.bouncycastle.asn1.pkcs", + "org.bouncycastle.asn1.sec", + "org.bouncycastle.asn1.teletrust", + "org.bouncycastle.asn1.ua", + "org.bouncycastle.asn1.util", + "org.bouncycastle.asn1.x500", + "org.bouncycastle.asn1.x500.style", + "org.bouncycastle.asn1.x509", + "org.bouncycastle.asn1.x509.qualified", + "org.bouncycastle.asn1.x509.sigi", + "org.bouncycastle.asn1.x9", + "org.bouncycastle.crypto", + "org.bouncycastle.crypto.agreement", + "org.bouncycastle.crypto.agreement.ecjpake", + "org.bouncycastle.crypto.agreement.jpake", + "org.bouncycastle.crypto.agreement.kdf", + "org.bouncycastle.crypto.agreement.srp", + "org.bouncycastle.crypto.commitments", + "org.bouncycastle.crypto.constraints", + "org.bouncycastle.crypto.digests", + "org.bouncycastle.crypto.ec", + "org.bouncycastle.crypto.encodings", + "org.bouncycastle.crypto.engines", + "org.bouncycastle.crypto.examples", + "org.bouncycastle.crypto.fpe", + "org.bouncycastle.crypto.generators", + "org.bouncycastle.crypto.hash2curve", + "org.bouncycastle.crypto.hash2curve.data", + "org.bouncycastle.crypto.hash2curve.impl", + "org.bouncycastle.crypto.hpke", + "org.bouncycastle.crypto.io", + "org.bouncycastle.crypto.kems", + "org.bouncycastle.crypto.kems.mlkem", + "org.bouncycastle.crypto.macs", + "org.bouncycastle.crypto.modes", + "org.bouncycastle.crypto.modes.gcm", + "org.bouncycastle.crypto.modes.kgcm", + "org.bouncycastle.crypto.paddings", + "org.bouncycastle.crypto.params", + "org.bouncycastle.crypto.parsers", + "org.bouncycastle.crypto.prng", + "org.bouncycastle.crypto.prng.drbg", + "org.bouncycastle.crypto.signers", + "org.bouncycastle.crypto.signers.mldsa", + "org.bouncycastle.crypto.signers.slhdsa", + "org.bouncycastle.crypto.threshold", + "org.bouncycastle.crypto.tls", + "org.bouncycastle.crypto.util", + "org.bouncycastle.i18n", + "org.bouncycastle.i18n.filter", + "org.bouncycastle.iana", + "org.bouncycastle.internal.asn1.bsi", + "org.bouncycastle.internal.asn1.cms", + "org.bouncycastle.internal.asn1.cryptlib", + "org.bouncycastle.internal.asn1.eac", + "org.bouncycastle.internal.asn1.edec", + "org.bouncycastle.internal.asn1.gnu", + "org.bouncycastle.internal.asn1.iana", + "org.bouncycastle.internal.asn1.isara", + "org.bouncycastle.internal.asn1.isismtt", + "org.bouncycastle.internal.asn1.iso", + "org.bouncycastle.internal.asn1.kisa", + "org.bouncycastle.internal.asn1.microsoft", + "org.bouncycastle.internal.asn1.misc", + "org.bouncycastle.internal.asn1.nsri", + "org.bouncycastle.internal.asn1.ntt", + "org.bouncycastle.internal.asn1.oiw", + "org.bouncycastle.internal.asn1.rosstandart", + "org.bouncycastle.jcajce", + "org.bouncycastle.jcajce.interfaces", + "org.bouncycastle.jcajce.io", + "org.bouncycastle.jcajce.provider.asymmetric", + "org.bouncycastle.jcajce.provider.asymmetric.compositesignatures", + "org.bouncycastle.jcajce.provider.asymmetric.dh", + "org.bouncycastle.jcajce.provider.asymmetric.dsa", + "org.bouncycastle.jcajce.provider.asymmetric.dstu", + "org.bouncycastle.jcajce.provider.asymmetric.ec", + "org.bouncycastle.jcajce.provider.asymmetric.ecgost", + "org.bouncycastle.jcajce.provider.asymmetric.ecgost12", + "org.bouncycastle.jcajce.provider.asymmetric.edec", + "org.bouncycastle.jcajce.provider.asymmetric.elgamal", + "org.bouncycastle.jcajce.provider.asymmetric.gost", + "org.bouncycastle.jcajce.provider.asymmetric.ies", + "org.bouncycastle.jcajce.provider.asymmetric.mldsa", + "org.bouncycastle.jcajce.provider.asymmetric.mlkem", + "org.bouncycastle.jcajce.provider.asymmetric.rsa", + "org.bouncycastle.jcajce.provider.asymmetric.slhdsa", + "org.bouncycastle.jcajce.provider.asymmetric.util", + "org.bouncycastle.jcajce.provider.asymmetric.x509", + "org.bouncycastle.jcajce.provider.config", + "org.bouncycastle.jcajce.provider.digest", + "org.bouncycastle.jcajce.provider.drbg", + "org.bouncycastle.jcajce.provider.kdf", + "org.bouncycastle.jcajce.provider.kdf.hkdf", + "org.bouncycastle.jcajce.provider.kdf.pbkdf2", + "org.bouncycastle.jcajce.provider.kdf.scrypt", + "org.bouncycastle.jcajce.provider.keystore", + "org.bouncycastle.jcajce.provider.keystore.bc", + "org.bouncycastle.jcajce.provider.keystore.bcfks", + "org.bouncycastle.jcajce.provider.keystore.pkcs12", + "org.bouncycastle.jcajce.provider.keystore.util", + "org.bouncycastle.jcajce.provider.symmetric", + "org.bouncycastle.jcajce.provider.symmetric.util", + "org.bouncycastle.jcajce.provider.util", + "org.bouncycastle.jcajce.spec", + "org.bouncycastle.jcajce.util", + "org.bouncycastle.jce", + "org.bouncycastle.jce.exception", + "org.bouncycastle.jce.interfaces", + "org.bouncycastle.jce.netscape", + "org.bouncycastle.jce.provider", + "org.bouncycastle.jce.spec", + "org.bouncycastle.ldap", + "org.bouncycastle.math", + "org.bouncycastle.math.ec", + "org.bouncycastle.math.ec.custom.djb", + "org.bouncycastle.math.ec.custom.gm", + "org.bouncycastle.math.ec.custom.sec", + "org.bouncycastle.math.ec.endo", + "org.bouncycastle.math.ec.rfc7748", + "org.bouncycastle.math.ec.rfc8032", + "org.bouncycastle.math.ec.tools", + "org.bouncycastle.math.field", + "org.bouncycastle.math.raw", + "org.bouncycastle.pqc.asn1", + "org.bouncycastle.pqc.crypto", + "org.bouncycastle.pqc.crypto.cmce", + "org.bouncycastle.pqc.crypto.crystals.dilithium", + "org.bouncycastle.pqc.crypto.falcon", + "org.bouncycastle.pqc.crypto.frodo", + "org.bouncycastle.pqc.crypto.hqc", + "org.bouncycastle.pqc.crypto.lms", + "org.bouncycastle.pqc.crypto.mayo", + "org.bouncycastle.pqc.crypto.mldsa", + "org.bouncycastle.pqc.crypto.mlkem", + "org.bouncycastle.pqc.crypto.newhope", + "org.bouncycastle.pqc.crypto.ntru", + "org.bouncycastle.pqc.crypto.ntruplus", + "org.bouncycastle.pqc.crypto.ntruprime", + "org.bouncycastle.pqc.crypto.saber", + "org.bouncycastle.pqc.crypto.slhdsa", + "org.bouncycastle.pqc.crypto.snova", + "org.bouncycastle.pqc.crypto.sphincs", + "org.bouncycastle.pqc.crypto.util", + "org.bouncycastle.pqc.crypto.xmss", + "org.bouncycastle.pqc.crypto.xwing", + "org.bouncycastle.pqc.jcajce.interfaces", + "org.bouncycastle.pqc.jcajce.provider", + "org.bouncycastle.pqc.jcajce.provider.bike", + "org.bouncycastle.pqc.jcajce.provider.cmce", + "org.bouncycastle.pqc.jcajce.provider.dilithium", + "org.bouncycastle.pqc.jcajce.provider.falcon", + "org.bouncycastle.pqc.jcajce.provider.frodo", + "org.bouncycastle.pqc.jcajce.provider.hqc", + "org.bouncycastle.pqc.jcajce.provider.kyber", + "org.bouncycastle.pqc.jcajce.provider.lms", + "org.bouncycastle.pqc.jcajce.provider.mayo", + "org.bouncycastle.pqc.jcajce.provider.newhope", + "org.bouncycastle.pqc.jcajce.provider.ntru", + "org.bouncycastle.pqc.jcajce.provider.ntruplus", + "org.bouncycastle.pqc.jcajce.provider.ntruprime", + "org.bouncycastle.pqc.jcajce.provider.picnic", + "org.bouncycastle.pqc.jcajce.provider.saber", + "org.bouncycastle.pqc.jcajce.provider.snova", + "org.bouncycastle.pqc.jcajce.provider.sphincs", + "org.bouncycastle.pqc.jcajce.provider.sphincsplus", + "org.bouncycastle.pqc.jcajce.provider.util", + "org.bouncycastle.pqc.jcajce.provider.xmss", + "org.bouncycastle.pqc.jcajce.spec", + "org.bouncycastle.pqc.legacy.bike", + "org.bouncycastle.pqc.legacy.picnic", + "org.bouncycastle.pqc.legacy.rainbow", + "org.bouncycastle.pqc.legacy.sphincsplus", + "org.bouncycastle.pqc.math.ntru", + "org.bouncycastle.pqc.math.ntru.parameters", + "org.bouncycastle.util", + "org.bouncycastle.util.encoders", + "org.bouncycastle.util.io", + "org.bouncycastle.util.io.pem", + "org.bouncycastle.util.test", + "org.bouncycastle.x509", + "org.bouncycastle.x509.extension", + "org.bouncycastle.x509.util" + ], + "org.bouncycastle:bcprov-lts8on": [ + "org.bouncycastle", + "org.bouncycastle.asn1", + "org.bouncycastle.asn1.anssi", + "org.bouncycastle.asn1.bc", + "org.bouncycastle.asn1.cryptlib", + "org.bouncycastle.asn1.cryptopro", + "org.bouncycastle.asn1.edec", + "org.bouncycastle.asn1.gm", + "org.bouncycastle.asn1.gnu", + "org.bouncycastle.asn1.iana", + "org.bouncycastle.asn1.isara", + "org.bouncycastle.asn1.iso", + "org.bouncycastle.asn1.kisa", + "org.bouncycastle.asn1.microsoft", + "org.bouncycastle.asn1.misc", + "org.bouncycastle.asn1.mozilla", + "org.bouncycastle.asn1.nist", + "org.bouncycastle.asn1.nsri", + "org.bouncycastle.asn1.ntt", + "org.bouncycastle.asn1.ocsp", + "org.bouncycastle.asn1.oiw", + "org.bouncycastle.asn1.pkcs", + "org.bouncycastle.asn1.rosstandart", + "org.bouncycastle.asn1.sec", + "org.bouncycastle.asn1.teletrust", + "org.bouncycastle.asn1.ua", + "org.bouncycastle.asn1.util", + "org.bouncycastle.asn1.x500", + "org.bouncycastle.asn1.x500.style", + "org.bouncycastle.asn1.x509", + "org.bouncycastle.asn1.x509.qualified", + "org.bouncycastle.asn1.x509.sigi", + "org.bouncycastle.asn1.x9", + "org.bouncycastle.crypto", + "org.bouncycastle.crypto.agreement", + "org.bouncycastle.crypto.agreement.ecjpake", + "org.bouncycastle.crypto.agreement.jpake", + "org.bouncycastle.crypto.agreement.kdf", + "org.bouncycastle.crypto.agreement.srp", + "org.bouncycastle.crypto.commitments", + "org.bouncycastle.crypto.constraints", + "org.bouncycastle.crypto.digests", + "org.bouncycastle.crypto.ec", + "org.bouncycastle.crypto.encodings", + "org.bouncycastle.crypto.engines", + "org.bouncycastle.crypto.fpe", + "org.bouncycastle.crypto.generators", + "org.bouncycastle.crypto.hpke", + "org.bouncycastle.crypto.io", + "org.bouncycastle.crypto.kems", + "org.bouncycastle.crypto.macs", + "org.bouncycastle.crypto.modes", + "org.bouncycastle.crypto.modes.gcm", + "org.bouncycastle.crypto.modes.kgcm", + "org.bouncycastle.crypto.paddings", + "org.bouncycastle.crypto.params", + "org.bouncycastle.crypto.parsers", + "org.bouncycastle.crypto.prng", + "org.bouncycastle.crypto.prng.drbg", + "org.bouncycastle.crypto.signers", + "org.bouncycastle.crypto.tls", + "org.bouncycastle.crypto.util", + "org.bouncycastle.iana", + "org.bouncycastle.internal.asn1.bsi", + "org.bouncycastle.internal.asn1.cms", + "org.bouncycastle.internal.asn1.cryptlib", + "org.bouncycastle.internal.asn1.eac", + "org.bouncycastle.internal.asn1.edec", + "org.bouncycastle.internal.asn1.gnu", + "org.bouncycastle.internal.asn1.iana", + "org.bouncycastle.internal.asn1.isara", + "org.bouncycastle.internal.asn1.isismtt", + "org.bouncycastle.internal.asn1.iso", + "org.bouncycastle.internal.asn1.kisa", + "org.bouncycastle.internal.asn1.microsoft", + "org.bouncycastle.internal.asn1.misc", + "org.bouncycastle.internal.asn1.nsri", + "org.bouncycastle.internal.asn1.ntt", + "org.bouncycastle.internal.asn1.oiw", + "org.bouncycastle.internal.asn1.rosstandart", + "org.bouncycastle.jcajce", + "org.bouncycastle.jcajce.interfaces", + "org.bouncycastle.jcajce.io", + "org.bouncycastle.jcajce.provider.asymmetric", + "org.bouncycastle.jcajce.provider.asymmetric.compositesignatures", + "org.bouncycastle.jcajce.provider.asymmetric.dh", + "org.bouncycastle.jcajce.provider.asymmetric.dsa", + "org.bouncycastle.jcajce.provider.asymmetric.dstu", + "org.bouncycastle.jcajce.provider.asymmetric.ec", + "org.bouncycastle.jcajce.provider.asymmetric.ecgost", + "org.bouncycastle.jcajce.provider.asymmetric.ecgost12", + "org.bouncycastle.jcajce.provider.asymmetric.edec", + "org.bouncycastle.jcajce.provider.asymmetric.elgamal", + "org.bouncycastle.jcajce.provider.asymmetric.gost", + "org.bouncycastle.jcajce.provider.asymmetric.ies", + "org.bouncycastle.jcajce.provider.asymmetric.mldsa", + "org.bouncycastle.jcajce.provider.asymmetric.mlkem", + "org.bouncycastle.jcajce.provider.asymmetric.rsa", + "org.bouncycastle.jcajce.provider.asymmetric.slhdsa", + "org.bouncycastle.jcajce.provider.asymmetric.util", + "org.bouncycastle.jcajce.provider.asymmetric.x509", + "org.bouncycastle.jcajce.provider.config", + "org.bouncycastle.jcajce.provider.digest", + "org.bouncycastle.jcajce.provider.drbg", + "org.bouncycastle.jcajce.provider.keystore", + "org.bouncycastle.jcajce.provider.keystore.bc", + "org.bouncycastle.jcajce.provider.keystore.bcfks", + "org.bouncycastle.jcajce.provider.keystore.pkcs12", + "org.bouncycastle.jcajce.provider.keystore.util", + "org.bouncycastle.jcajce.provider.symmetric", + "org.bouncycastle.jcajce.provider.symmetric.util", + "org.bouncycastle.jcajce.provider.util", + "org.bouncycastle.jcajce.spec", + "org.bouncycastle.jcajce.util", + "org.bouncycastle.jce", + "org.bouncycastle.jce.exception", + "org.bouncycastle.jce.interfaces", + "org.bouncycastle.jce.netscape", + "org.bouncycastle.jce.provider", + "org.bouncycastle.jce.spec", + "org.bouncycastle.math", + "org.bouncycastle.math.ec", + "org.bouncycastle.math.ec.custom.djb", + "org.bouncycastle.math.ec.custom.gm", + "org.bouncycastle.math.ec.custom.sec", + "org.bouncycastle.math.ec.endo", + "org.bouncycastle.math.ec.rfc7748", + "org.bouncycastle.math.ec.rfc8032", + "org.bouncycastle.math.ec.tools", + "org.bouncycastle.math.field", + "org.bouncycastle.math.raw", + "org.bouncycastle.pqc.crypto", + "org.bouncycastle.pqc.crypto.lms", + "org.bouncycastle.pqc.crypto.mldsa", + "org.bouncycastle.pqc.crypto.mlkem", + "org.bouncycastle.pqc.crypto.slhdsa", + "org.bouncycastle.pqc.crypto.util", + "org.bouncycastle.pqc.jcajce.interfaces", + "org.bouncycastle.pqc.jcajce.provider.lms", + "org.bouncycastle.pqc.jcajce.provider.util", + "org.bouncycastle.pqc.jcajce.spec", + "org.bouncycastle.util", + "org.bouncycastle.util.dispose", + "org.bouncycastle.util.encoders", + "org.bouncycastle.util.io", + "org.bouncycastle.util.io.pem", + "org.bouncycastle.util.test" + ], + "org.checkerframework:checker-qual": [ + "org.checkerframework.checker.builder.qual", + "org.checkerframework.checker.calledmethods.qual", + "org.checkerframework.checker.compilermsgs.qual", + "org.checkerframework.checker.fenum.qual", + "org.checkerframework.checker.formatter.qual", + "org.checkerframework.checker.guieffect.qual", + "org.checkerframework.checker.i18n.qual", + "org.checkerframework.checker.i18nformatter.qual", + "org.checkerframework.checker.index.qual", + "org.checkerframework.checker.initialization.qual", + "org.checkerframework.checker.interning.qual", + "org.checkerframework.checker.lock.qual", + "org.checkerframework.checker.mustcall.qual", + "org.checkerframework.checker.nullness.qual", + "org.checkerframework.checker.optional.qual", + "org.checkerframework.checker.propkey.qual", + "org.checkerframework.checker.regex.qual", + "org.checkerframework.checker.signature.qual", + "org.checkerframework.checker.signedness.qual", + "org.checkerframework.checker.tainting.qual", + "org.checkerframework.checker.units.qual", + "org.checkerframework.common.aliasing.qual", + "org.checkerframework.common.initializedfields.qual", + "org.checkerframework.common.reflection.qual", + "org.checkerframework.common.returnsreceiver.qual", + "org.checkerframework.common.subtyping.qual", + "org.checkerframework.common.util.report.qual", + "org.checkerframework.common.value.qual", + "org.checkerframework.dataflow.qual", + "org.checkerframework.framework.qual" + ], + "org.hamcrest:hamcrest": [ + "org.hamcrest", + "org.hamcrest.beans", + "org.hamcrest.collection", + "org.hamcrest.comparator", + "org.hamcrest.core", + "org.hamcrest.internal", + "org.hamcrest.io", + "org.hamcrest.number", + "org.hamcrest.object", + "org.hamcrest.text", + "org.hamcrest.xml" + ], + "org.hdrhistogram:HdrHistogram": [ + "org.HdrHistogram", + "org.HdrHistogram.packedarray" + ], + "org.hibernate.validator:hibernate-validator": [ + "org.hibernate.validator", + "org.hibernate.validator.cfg", + "org.hibernate.validator.cfg.context", + "org.hibernate.validator.cfg.defs", + "org.hibernate.validator.cfg.defs.br", + "org.hibernate.validator.cfg.defs.kor", + "org.hibernate.validator.cfg.defs.pl", + "org.hibernate.validator.cfg.defs.ru", + "org.hibernate.validator.constraints", + "org.hibernate.validator.constraints.br", + "org.hibernate.validator.constraints.kor", + "org.hibernate.validator.constraints.pl", + "org.hibernate.validator.constraints.ru", + "org.hibernate.validator.constraints.time", + "org.hibernate.validator.constraintvalidation", + "org.hibernate.validator.constraintvalidation.spi", + "org.hibernate.validator.constraintvalidators", + "org.hibernate.validator.engine", + "org.hibernate.validator.group", + "org.hibernate.validator.internal", + "org.hibernate.validator.internal.cfg", + "org.hibernate.validator.internal.cfg.context", + "org.hibernate.validator.internal.constraintvalidators", + "org.hibernate.validator.internal.constraintvalidators.bv", + "org.hibernate.validator.internal.constraintvalidators.bv.money", + "org.hibernate.validator.internal.constraintvalidators.bv.notempty", + "org.hibernate.validator.internal.constraintvalidators.bv.number", + "org.hibernate.validator.internal.constraintvalidators.bv.number.bound", + "org.hibernate.validator.internal.constraintvalidators.bv.number.bound.decimal", + "org.hibernate.validator.internal.constraintvalidators.bv.number.sign", + "org.hibernate.validator.internal.constraintvalidators.bv.size", + "org.hibernate.validator.internal.constraintvalidators.bv.time", + "org.hibernate.validator.internal.constraintvalidators.bv.time.future", + "org.hibernate.validator.internal.constraintvalidators.bv.time.futureorpresent", + "org.hibernate.validator.internal.constraintvalidators.bv.time.past", + "org.hibernate.validator.internal.constraintvalidators.bv.time.pastorpresent", + "org.hibernate.validator.internal.constraintvalidators.hv", + "org.hibernate.validator.internal.constraintvalidators.hv.br", + "org.hibernate.validator.internal.constraintvalidators.hv.kor", + "org.hibernate.validator.internal.constraintvalidators.hv.pl", + "org.hibernate.validator.internal.constraintvalidators.hv.ru", + "org.hibernate.validator.internal.constraintvalidators.hv.time", + "org.hibernate.validator.internal.engine", + "org.hibernate.validator.internal.engine.constraintdefinition", + "org.hibernate.validator.internal.engine.constraintvalidation", + "org.hibernate.validator.internal.engine.groups", + "org.hibernate.validator.internal.engine.messageinterpolation", + "org.hibernate.validator.internal.engine.messageinterpolation.el", + "org.hibernate.validator.internal.engine.messageinterpolation.parser", + "org.hibernate.validator.internal.engine.messageinterpolation.util", + "org.hibernate.validator.internal.engine.path", + "org.hibernate.validator.internal.engine.resolver", + "org.hibernate.validator.internal.engine.scripting", + "org.hibernate.validator.internal.engine.validationcontext", + "org.hibernate.validator.internal.engine.valuecontext", + "org.hibernate.validator.internal.engine.valueextraction", + "org.hibernate.validator.internal.metadata", + "org.hibernate.validator.internal.metadata.aggregated", + "org.hibernate.validator.internal.metadata.aggregated.rule", + "org.hibernate.validator.internal.metadata.core", + "org.hibernate.validator.internal.metadata.descriptor", + "org.hibernate.validator.internal.metadata.facets", + "org.hibernate.validator.internal.metadata.location", + "org.hibernate.validator.internal.metadata.provider", + "org.hibernate.validator.internal.metadata.raw", + "org.hibernate.validator.internal.properties", + "org.hibernate.validator.internal.properties.javabean", + "org.hibernate.validator.internal.util", + "org.hibernate.validator.internal.util.actions", + "org.hibernate.validator.internal.util.annotation", + "org.hibernate.validator.internal.util.classhierarchy", + "org.hibernate.validator.internal.util.logging", + "org.hibernate.validator.internal.util.logging.formatter", + "org.hibernate.validator.internal.util.stereotypes", + "org.hibernate.validator.internal.xml", + "org.hibernate.validator.internal.xml.config", + "org.hibernate.validator.internal.xml.mapping", + "org.hibernate.validator.messageinterpolation", + "org.hibernate.validator.metadata", + "org.hibernate.validator.parameternameprovider", + "org.hibernate.validator.path", + "org.hibernate.validator.resourceloading", + "org.hibernate.validator.spi.cfg", + "org.hibernate.validator.spi.group", + "org.hibernate.validator.spi.messageinterpolation", + "org.hibernate.validator.spi.nodenameprovider", + "org.hibernate.validator.spi.properties", + "org.hibernate.validator.spi.resourceloading", + "org.hibernate.validator.spi.scripting" + ], + "org.jacoco:org.jacoco.agent:jar:runtime": [ + "com.vladium.emma.rt", + "org.jacoco.agent.rt", + "org.jacoco.agent.rt.internal_29a6edd", + "org.jacoco.agent.rt.internal_29a6edd.asm", + "org.jacoco.agent.rt.internal_29a6edd.asm.commons", + "org.jacoco.agent.rt.internal_29a6edd.asm.tree", + "org.jacoco.agent.rt.internal_29a6edd.core", + "org.jacoco.agent.rt.internal_29a6edd.core.analysis", + "org.jacoco.agent.rt.internal_29a6edd.core.data", + "org.jacoco.agent.rt.internal_29a6edd.core.instr", + "org.jacoco.agent.rt.internal_29a6edd.core.internal", + "org.jacoco.agent.rt.internal_29a6edd.core.internal.analysis", + "org.jacoco.agent.rt.internal_29a6edd.core.internal.analysis.filter", + "org.jacoco.agent.rt.internal_29a6edd.core.internal.data", + "org.jacoco.agent.rt.internal_29a6edd.core.internal.flow", + "org.jacoco.agent.rt.internal_29a6edd.core.internal.instr", + "org.jacoco.agent.rt.internal_29a6edd.core.runtime", + "org.jacoco.agent.rt.internal_29a6edd.core.tools", + "org.jacoco.agent.rt.internal_29a6edd.output" + ], + "org.jacoco:org.jacoco.cli": [ + "org.jacoco.cli.internal", + "org.jacoco.cli.internal.commands" + ], + "org.jacoco:org.jacoco.core": [ + "org.jacoco.core", + "org.jacoco.core.analysis", + "org.jacoco.core.data", + "org.jacoco.core.instr", + "org.jacoco.core.internal", + "org.jacoco.core.internal.analysis", + "org.jacoco.core.internal.analysis.filter", + "org.jacoco.core.internal.data", + "org.jacoco.core.internal.flow", + "org.jacoco.core.internal.instr", + "org.jacoco.core.runtime", + "org.jacoco.core.tools" + ], + "org.jacoco:org.jacoco.report": [ + "org.jacoco.report", + "org.jacoco.report.check", + "org.jacoco.report.csv", + "org.jacoco.report.html", + "org.jacoco.report.internal", + "org.jacoco.report.internal.html", + "org.jacoco.report.internal.html.index", + "org.jacoco.report.internal.html.page", + "org.jacoco.report.internal.html.resources", + "org.jacoco.report.internal.html.table", + "org.jacoco.report.internal.xml", + "org.jacoco.report.xml" + ], + "org.jboss.logging:jboss-logging": [ + "org.jboss.logging" + ], + "org.jetbrains.kotlin:kotlin-stdlib": [ + "kotlin", + "kotlin.annotation", + "kotlin.collections", + "kotlin.collections.builders", + "kotlin.collections.jdk8", + "kotlin.collections.unsigned", + "kotlin.comparisons", + "kotlin.concurrent", + "kotlin.concurrent.atomics", + "kotlin.concurrent.internal", + "kotlin.contracts", + "kotlin.coroutines", + "kotlin.coroutines.cancellation", + "kotlin.coroutines.intrinsics", + "kotlin.coroutines.jvm.internal", + "kotlin.enums", + "kotlin.experimental", + "kotlin.internal", + "kotlin.internal.jdk7", + "kotlin.internal.jdk8", + "kotlin.io", + "kotlin.io.encoding", + "kotlin.io.path", + "kotlin.jdk7", + "kotlin.js", + "kotlin.jvm", + "kotlin.jvm.functions", + "kotlin.jvm.internal", + "kotlin.jvm.internal.markers", + "kotlin.jvm.internal.unsafe", + "kotlin.jvm.jdk8", + "kotlin.jvm.optionals", + "kotlin.math", + "kotlin.properties", + "kotlin.random", + "kotlin.random.jdk8", + "kotlin.ranges", + "kotlin.reflect", + "kotlin.sequences", + "kotlin.streams.jdk8", + "kotlin.system", + "kotlin.text", + "kotlin.text.jdk8", + "kotlin.time", + "kotlin.time.jdk8", + "kotlin.uuid" + ], + "org.jetbrains:annotations": [ + "org.intellij.lang.annotations", + "org.jetbrains.annotations" + ], + "org.jspecify:jspecify": [ + "org.jspecify.annotations" + ], + "org.junit.jupiter:junit-jupiter-api": [ + "org.junit.jupiter.api", + "org.junit.jupiter.api.condition", + "org.junit.jupiter.api.extension", + "org.junit.jupiter.api.extension.support", + "org.junit.jupiter.api.function", + "org.junit.jupiter.api.io", + "org.junit.jupiter.api.parallel", + "org.junit.jupiter.api.util" + ], + "org.junit.jupiter:junit-jupiter-engine": [ + "org.junit.jupiter.engine", + "org.junit.jupiter.engine.config", + "org.junit.jupiter.engine.descriptor", + "org.junit.jupiter.engine.discovery", + "org.junit.jupiter.engine.discovery.predicates", + "org.junit.jupiter.engine.execution", + "org.junit.jupiter.engine.extension", + "org.junit.jupiter.engine.support" + ], + "org.junit.jupiter:junit-jupiter-params": [ + "org.junit.jupiter.params", + "org.junit.jupiter.params.aggregator", + "org.junit.jupiter.params.converter", + "org.junit.jupiter.params.provider", + "org.junit.jupiter.params.shadow.de.siegmar.fastcsv.reader", + "org.junit.jupiter.params.shadow.de.siegmar.fastcsv.util", + "org.junit.jupiter.params.shadow.de.siegmar.fastcsv.writer", + "org.junit.jupiter.params.support" + ], + "org.junit.platform:junit-platform-commons": [ + "org.junit.platform.commons", + "org.junit.platform.commons.annotation", + "org.junit.platform.commons.function", + "org.junit.platform.commons.io", + "org.junit.platform.commons.logging", + "org.junit.platform.commons.support", + "org.junit.platform.commons.support.conversion", + "org.junit.platform.commons.support.scanning", + "org.junit.platform.commons.util" + ], + "org.junit.platform:junit-platform-console-standalone": [ + "junit.extensions", + "junit.framework", + "junit.runner", + "junit.textui", + "org.apiguardian.api", + "org.hamcrest", + "org.hamcrest.core", + "org.hamcrest.internal", + "org.junit", + "org.junit.experimental", + "org.junit.experimental.categories", + "org.junit.experimental.max", + "org.junit.experimental.results", + "org.junit.experimental.runners", + "org.junit.experimental.theories", + "org.junit.experimental.theories.internal", + "org.junit.experimental.theories.suppliers", + "org.junit.function", + "org.junit.internal", + "org.junit.internal.builders", + "org.junit.internal.management", + "org.junit.internal.matchers", + "org.junit.internal.requests", + "org.junit.internal.runners", + "org.junit.internal.runners.model", + "org.junit.internal.runners.rules", + "org.junit.internal.runners.statements", + "org.junit.jupiter.api", + "org.junit.jupiter.api.condition", + "org.junit.jupiter.api.extension", + "org.junit.jupiter.api.extension.support", + "org.junit.jupiter.api.function", + "org.junit.jupiter.api.io", + "org.junit.jupiter.api.parallel", + "org.junit.jupiter.api.util", + "org.junit.jupiter.engine", + "org.junit.jupiter.engine.config", + "org.junit.jupiter.engine.descriptor", + "org.junit.jupiter.engine.discovery", + "org.junit.jupiter.engine.discovery.predicates", + "org.junit.jupiter.engine.execution", + "org.junit.jupiter.engine.extension", + "org.junit.jupiter.engine.support", + "org.junit.jupiter.params", + "org.junit.jupiter.params.aggregator", + "org.junit.jupiter.params.converter", + "org.junit.jupiter.params.provider", + "org.junit.jupiter.params.shadow.de.siegmar.fastcsv.reader", + "org.junit.jupiter.params.shadow.de.siegmar.fastcsv.util", + "org.junit.jupiter.params.shadow.de.siegmar.fastcsv.writer", + "org.junit.jupiter.params.support", + "org.junit.matchers", + "org.junit.platform.commons", + "org.junit.platform.commons.annotation", + "org.junit.platform.commons.function", + "org.junit.platform.commons.io", + "org.junit.platform.commons.logging", + "org.junit.platform.commons.support", + "org.junit.platform.commons.support.conversion", + "org.junit.platform.commons.support.scanning", + "org.junit.platform.commons.util", + "org.junit.platform.console", + "org.junit.platform.console.command", + "org.junit.platform.console.options", + "org.junit.platform.console.output", + "org.junit.platform.console.shadow.picocli", + "org.junit.platform.engine", + "org.junit.platform.engine.discovery", + "org.junit.platform.engine.reporting", + "org.junit.platform.engine.support.config", + "org.junit.platform.engine.support.descriptor", + "org.junit.platform.engine.support.discovery", + "org.junit.platform.engine.support.hierarchical", + "org.junit.platform.engine.support.store", + "org.junit.platform.launcher", + "org.junit.platform.launcher.core", + "org.junit.platform.launcher.jfr", + "org.junit.platform.launcher.listeners", + "org.junit.platform.launcher.listeners.discovery", + "org.junit.platform.launcher.listeners.session", + "org.junit.platform.launcher.tagexpression", + "org.junit.platform.reporting", + "org.junit.platform.reporting.legacy", + "org.junit.platform.reporting.legacy.xml", + "org.junit.platform.reporting.open.xml", + "org.junit.platform.reporting.shadow.org.opentest4j.reporting.events.api", + "org.junit.platform.reporting.shadow.org.opentest4j.reporting.events.core", + "org.junit.platform.reporting.shadow.org.opentest4j.reporting.events.git", + "org.junit.platform.reporting.shadow.org.opentest4j.reporting.events.java", + "org.junit.platform.reporting.shadow.org.opentest4j.reporting.events.root", + "org.junit.platform.reporting.shadow.org.opentest4j.reporting.schema", + "org.junit.platform.suite.api", + "org.junit.platform.suite.engine", + "org.junit.rules", + "org.junit.runner", + "org.junit.runner.manipulation", + "org.junit.runner.notification", + "org.junit.runners", + "org.junit.runners.model", + "org.junit.runners.parameterized", + "org.junit.validator", + "org.junit.vintage.engine", + "org.junit.vintage.engine.descriptor", + "org.junit.vintage.engine.discovery", + "org.junit.vintage.engine.execution", + "org.junit.vintage.engine.support", + "org.opentest4j", + "org.opentest4j.reporting.tooling.spi.htmlreport" + ], + "org.junit.platform:junit-platform-engine": [ + "org.junit.platform.engine", + "org.junit.platform.engine.discovery", + "org.junit.platform.engine.reporting", + "org.junit.platform.engine.support.config", + "org.junit.platform.engine.support.descriptor", + "org.junit.platform.engine.support.discovery", + "org.junit.platform.engine.support.hierarchical", + "org.junit.platform.engine.support.store" + ], + "org.junit.platform:junit-platform-launcher": [ + "org.junit.platform.launcher", + "org.junit.platform.launcher.core", + "org.junit.platform.launcher.jfr", + "org.junit.platform.launcher.listeners", + "org.junit.platform.launcher.listeners.discovery", + "org.junit.platform.launcher.listeners.session", + "org.junit.platform.launcher.tagexpression" + ], + "org.junit.platform:junit-platform-reporting": [ + "org.junit.platform.reporting", + "org.junit.platform.reporting.legacy", + "org.junit.platform.reporting.legacy.xml", + "org.junit.platform.reporting.open.xml", + "org.junit.platform.reporting.shadow.org.opentest4j.reporting.events.api", + "org.junit.platform.reporting.shadow.org.opentest4j.reporting.events.core", + "org.junit.platform.reporting.shadow.org.opentest4j.reporting.events.git", + "org.junit.platform.reporting.shadow.org.opentest4j.reporting.events.java", + "org.junit.platform.reporting.shadow.org.opentest4j.reporting.events.root", + "org.junit.platform.reporting.shadow.org.opentest4j.reporting.schema" + ], + "org.latencyutils:LatencyUtils": [ + "org.LatencyUtils" + ], + "org.mockito:mockito-core": [ + "org.mockito", + "org.mockito.configuration", + "org.mockito.creation.instance", + "org.mockito.exceptions.base", + "org.mockito.exceptions.misusing", + "org.mockito.exceptions.stacktrace", + "org.mockito.exceptions.verification", + "org.mockito.exceptions.verification.junit", + "org.mockito.exceptions.verification.opentest4j", + "org.mockito.hamcrest", + "org.mockito.internal", + "org.mockito.internal.configuration", + "org.mockito.internal.configuration.injection", + "org.mockito.internal.configuration.injection.filter", + "org.mockito.internal.configuration.injection.scanner", + "org.mockito.internal.configuration.plugins", + "org.mockito.internal.creation", + "org.mockito.internal.creation.bytebuddy", + "org.mockito.internal.creation.bytebuddy.access", + "org.mockito.internal.creation.bytebuddy.codegen", + "org.mockito.internal.creation.instance", + "org.mockito.internal.creation.proxy", + "org.mockito.internal.creation.settings", + "org.mockito.internal.creation.util", + "org.mockito.internal.debugging", + "org.mockito.internal.exceptions", + "org.mockito.internal.exceptions.stacktrace", + "org.mockito.internal.exceptions.util", + "org.mockito.internal.framework", + "org.mockito.internal.hamcrest", + "org.mockito.internal.handler", + "org.mockito.internal.invocation", + "org.mockito.internal.invocation.finder", + "org.mockito.internal.invocation.mockref", + "org.mockito.internal.junit", + "org.mockito.internal.listeners", + "org.mockito.internal.matchers", + "org.mockito.internal.matchers.apachecommons", + "org.mockito.internal.matchers.text", + "org.mockito.internal.progress", + "org.mockito.internal.reporting", + "org.mockito.internal.runners", + "org.mockito.internal.runners.util", + "org.mockito.internal.session", + "org.mockito.internal.stubbing", + "org.mockito.internal.stubbing.answers", + "org.mockito.internal.stubbing.defaultanswers", + "org.mockito.internal.util", + "org.mockito.internal.util.collections", + "org.mockito.internal.util.concurrent", + "org.mockito.internal.util.io", + "org.mockito.internal.util.reflection", + "org.mockito.internal.verification", + "org.mockito.internal.verification.api", + "org.mockito.internal.verification.argumentmatching", + "org.mockito.internal.verification.checkers", + "org.mockito.invocation", + "org.mockito.junit", + "org.mockito.listeners", + "org.mockito.mock", + "org.mockito.plugins", + "org.mockito.quality", + "org.mockito.session", + "org.mockito.stubbing", + "org.mockito.verification" + ], + "org.mockito:mockito-junit-jupiter": [ + "org.mockito.junit.jupiter", + "org.mockito.junit.jupiter.resolver" + ], + "org.objenesis:objenesis": [ + "org.objenesis", + "org.objenesis.instantiator", + "org.objenesis.instantiator.android", + "org.objenesis.instantiator.annotations", + "org.objenesis.instantiator.basic", + "org.objenesis.instantiator.gcj", + "org.objenesis.instantiator.perc", + "org.objenesis.instantiator.sun", + "org.objenesis.instantiator.util", + "org.objenesis.strategy" + ], + "org.opentest4j.reporting:open-test-reporting-tooling-spi": [ + "org.opentest4j.reporting.tooling.spi.htmlreport" + ], + "org.opentest4j:opentest4j": [ + "org.opentest4j" + ], + "org.ow2.asm:asm": [ + "org.objectweb.asm", + "org.objectweb.asm.signature" + ], + "org.ow2.asm:asm-analysis": [ + "org.objectweb.asm.tree.analysis" + ], + "org.ow2.asm:asm-commons": [ + "org.objectweb.asm.commons" + ], + "org.ow2.asm:asm-tree": [ + "org.objectweb.asm.tree" + ], + "org.ow2.asm:asm-util": [ + "org.objectweb.asm.util" + ], + "org.projectlombok:lombok": [ + "lombok", + "lombok.delombok.ant", + "lombok.experimental", + "lombok.extern.apachecommons", + "lombok.extern.flogger", + "lombok.extern.jackson", + "lombok.extern.java", + "lombok.extern.jbosslog", + "lombok.extern.log4j", + "lombok.extern.slf4j", + "lombok.javac.apt", + "lombok.launch" + ], + "org.reactivestreams:reactive-streams": [ + "org.reactivestreams" + ], + "org.rnorth.duct-tape:duct-tape": [ + "org.rnorth.ducttape", + "org.rnorth.ducttape.circuitbreakers", + "org.rnorth.ducttape.inconsistents", + "org.rnorth.ducttape.ratelimits", + "org.rnorth.ducttape.timeouts", + "org.rnorth.ducttape.unreliables" + ], + "org.skyscreamer:jsonassert": [ + "org.json", + "org.skyscreamer.jsonassert", + "org.skyscreamer.jsonassert.comparator" + ], + "org.slf4j:jul-to-slf4j": [ + "org.slf4j.bridge" + ], + "org.slf4j:slf4j-api": [ + "org.slf4j", + "org.slf4j.event", + "org.slf4j.helpers", + "org.slf4j.spi" + ], + "org.springdoc:springdoc-openapi-starter-common": [ + "org.springdoc.api", + "org.springdoc.core.annotations", + "org.springdoc.core.conditions", + "org.springdoc.core.configuration", + "org.springdoc.core.configuration.hints", + "org.springdoc.core.configuration.oauth2", + "org.springdoc.core.configurer", + "org.springdoc.core.converters", + "org.springdoc.core.converters.models", + "org.springdoc.core.customizers", + "org.springdoc.core.data", + "org.springdoc.core.discoverer", + "org.springdoc.core.events", + "org.springdoc.core.extractor", + "org.springdoc.core.filters", + "org.springdoc.core.fn", + "org.springdoc.core.fn.builders.apiresponse", + "org.springdoc.core.fn.builders.arrayschema", + "org.springdoc.core.fn.builders.content", + "org.springdoc.core.fn.builders.discriminatormapping", + "org.springdoc.core.fn.builders.encoding", + "org.springdoc.core.fn.builders.exampleobject", + "org.springdoc.core.fn.builders.extension", + "org.springdoc.core.fn.builders.extensionproperty", + "org.springdoc.core.fn.builders.externaldocumentation", + "org.springdoc.core.fn.builders.header", + "org.springdoc.core.fn.builders.link", + "org.springdoc.core.fn.builders.linkparameter", + "org.springdoc.core.fn.builders.operation", + "org.springdoc.core.fn.builders.parameter", + "org.springdoc.core.fn.builders.requestbody", + "org.springdoc.core.fn.builders.schema", + "org.springdoc.core.fn.builders.securityrequirement", + "org.springdoc.core.fn.builders.server", + "org.springdoc.core.fn.builders.servervariable", + "org.springdoc.core.mixins", + "org.springdoc.core.models", + "org.springdoc.core.properties", + "org.springdoc.core.providers", + "org.springdoc.core.service", + "org.springdoc.core.utils", + "org.springdoc.core.versions", + "org.springdoc.scalar", + "org.springdoc.ui" + ], + "org.springdoc:springdoc-openapi-starter-webflux-api": [ + "org.springdoc.webflux.api", + "org.springdoc.webflux.core.configuration", + "org.springdoc.webflux.core.configuration.hints", + "org.springdoc.webflux.core.fn", + "org.springdoc.webflux.core.providers", + "org.springdoc.webflux.core.service", + "org.springdoc.webflux.core.visitor" + ], + "org.springdoc:springdoc-openapi-starter-webmvc-api": [ + "org.springdoc.webmvc.api", + "org.springdoc.webmvc.core.configuration", + "org.springdoc.webmvc.core.configuration.hints", + "org.springdoc.webmvc.core.fn", + "org.springdoc.webmvc.core.providers", + "org.springdoc.webmvc.core.service" + ], + "org.springframework.boot:spring-boot": [ + "org.springframework.boot", + "org.springframework.boot.admin", + "org.springframework.boot.ansi", + "org.springframework.boot.availability", + "org.springframework.boot.bootstrap", + "org.springframework.boot.builder", + "org.springframework.boot.cloud", + "org.springframework.boot.context", + "org.springframework.boot.context.annotation", + "org.springframework.boot.context.config", + "org.springframework.boot.context.event", + "org.springframework.boot.context.logging", + "org.springframework.boot.context.metrics.buffering", + "org.springframework.boot.context.properties", + "org.springframework.boot.context.properties.bind", + "org.springframework.boot.context.properties.bind.handler", + "org.springframework.boot.context.properties.bind.validation", + "org.springframework.boot.context.properties.source", + "org.springframework.boot.convert", + "org.springframework.boot.diagnostics", + "org.springframework.boot.diagnostics.analyzer", + "org.springframework.boot.env", + "org.springframework.boot.info", + "org.springframework.boot.io", + "org.springframework.boot.json", + "org.springframework.boot.logging", + "org.springframework.boot.logging.java", + "org.springframework.boot.logging.log4j2", + "org.springframework.boot.logging.logback", + "org.springframework.boot.logging.structured", + "org.springframework.boot.origin", + "org.springframework.boot.retry", + "org.springframework.boot.ssl", + "org.springframework.boot.ssl.jks", + "org.springframework.boot.ssl.pem", + "org.springframework.boot.support", + "org.springframework.boot.system", + "org.springframework.boot.task", + "org.springframework.boot.thread", + "org.springframework.boot.util", + "org.springframework.boot.validation", + "org.springframework.boot.validation.beanvalidation", + "org.springframework.boot.web.context.reactive", + "org.springframework.boot.web.context.servlet", + "org.springframework.boot.web.error", + "org.springframework.boot.web.servlet", + "org.springframework.boot.web.servlet.support" + ], + "org.springframework.boot:spring-boot-actuator": [ + "org.springframework.boot.actuate.audit", + "org.springframework.boot.actuate.audit.listener", + "org.springframework.boot.actuate.beans", + "org.springframework.boot.actuate.context", + "org.springframework.boot.actuate.context.properties", + "org.springframework.boot.actuate.endpoint", + "org.springframework.boot.actuate.endpoint.annotation", + "org.springframework.boot.actuate.endpoint.invoke", + "org.springframework.boot.actuate.endpoint.invoke.convert", + "org.springframework.boot.actuate.endpoint.invoke.reflect", + "org.springframework.boot.actuate.endpoint.invoker.cache", + "org.springframework.boot.actuate.endpoint.jackson", + "org.springframework.boot.actuate.endpoint.jmx", + "org.springframework.boot.actuate.endpoint.jmx.annotation", + "org.springframework.boot.actuate.endpoint.web", + "org.springframework.boot.actuate.endpoint.web.annotation", + "org.springframework.boot.actuate.env", + "org.springframework.boot.actuate.info", + "org.springframework.boot.actuate.logging", + "org.springframework.boot.actuate.management", + "org.springframework.boot.actuate.sbom", + "org.springframework.boot.actuate.scheduling", + "org.springframework.boot.actuate.security", + "org.springframework.boot.actuate.startup", + "org.springframework.boot.actuate.web.exchanges", + "org.springframework.boot.actuate.web.mappings" + ], + "org.springframework.boot:spring-boot-actuator-autoconfigure": [ + "org.springframework.boot.actuate.autoconfigure", + "org.springframework.boot.actuate.autoconfigure.audit", + "org.springframework.boot.actuate.autoconfigure.beans", + "org.springframework.boot.actuate.autoconfigure.condition", + "org.springframework.boot.actuate.autoconfigure.context", + "org.springframework.boot.actuate.autoconfigure.context.properties", + "org.springframework.boot.actuate.autoconfigure.endpoint", + "org.springframework.boot.actuate.autoconfigure.endpoint.condition", + "org.springframework.boot.actuate.autoconfigure.endpoint.expose", + "org.springframework.boot.actuate.autoconfigure.endpoint.jackson", + "org.springframework.boot.actuate.autoconfigure.endpoint.jmx", + "org.springframework.boot.actuate.autoconfigure.endpoint.web", + "org.springframework.boot.actuate.autoconfigure.env", + "org.springframework.boot.actuate.autoconfigure.info", + "org.springframework.boot.actuate.autoconfigure.logging", + "org.springframework.boot.actuate.autoconfigure.management", + "org.springframework.boot.actuate.autoconfigure.sbom", + "org.springframework.boot.actuate.autoconfigure.scheduling", + "org.springframework.boot.actuate.autoconfigure.startup", + "org.springframework.boot.actuate.autoconfigure.web", + "org.springframework.boot.actuate.autoconfigure.web.exchanges", + "org.springframework.boot.actuate.autoconfigure.web.mappings", + "org.springframework.boot.actuate.autoconfigure.web.server" + ], + "org.springframework.boot:spring-boot-autoconfigure": [ + "org.springframework.boot.autoconfigure", + "org.springframework.boot.autoconfigure.admin", + "org.springframework.boot.autoconfigure.aop", + "org.springframework.boot.autoconfigure.availability", + "org.springframework.boot.autoconfigure.cache", + "org.springframework.boot.autoconfigure.condition", + "org.springframework.boot.autoconfigure.container", + "org.springframework.boot.autoconfigure.context", + "org.springframework.boot.autoconfigure.data", + "org.springframework.boot.autoconfigure.diagnostics.analyzer", + "org.springframework.boot.autoconfigure.info", + "org.springframework.boot.autoconfigure.jmx", + "org.springframework.boot.autoconfigure.logging", + "org.springframework.boot.autoconfigure.preinitialize", + "org.springframework.boot.autoconfigure.service.connection", + "org.springframework.boot.autoconfigure.ssl", + "org.springframework.boot.autoconfigure.task", + "org.springframework.boot.autoconfigure.template", + "org.springframework.boot.autoconfigure.web", + "org.springframework.boot.autoconfigure.web.format" + ], + "org.springframework.boot:spring-boot-cassandra": [ + "org.springframework.boot.cassandra.autoconfigure", + "org.springframework.boot.cassandra.autoconfigure.health", + "org.springframework.boot.cassandra.docker.compose", + "org.springframework.boot.cassandra.health", + "org.springframework.boot.cassandra.testcontainers" + ], + "org.springframework.boot:spring-boot-data-cassandra": [ + "org.springframework.boot.data.cassandra.autoconfigure" + ], + "org.springframework.boot:spring-boot-data-cassandra-test": [ + "org.springframework.boot.data.cassandra.test.autoconfigure" + ], + "org.springframework.boot:spring-boot-data-commons": [ + "org.springframework.boot.data.autoconfigure.metrics", + "org.springframework.boot.data.autoconfigure.web", + "org.springframework.boot.data.metrics" + ], + "org.springframework.boot:spring-boot-health": [ + "org.springframework.boot.health.actuate.endpoint", + "org.springframework.boot.health.application", + "org.springframework.boot.health.autoconfigure.actuate.endpoint", + "org.springframework.boot.health.autoconfigure.application", + "org.springframework.boot.health.autoconfigure.contributor", + "org.springframework.boot.health.autoconfigure.registry", + "org.springframework.boot.health.contributor", + "org.springframework.boot.health.registry" + ], + "org.springframework.boot:spring-boot-http-client": [ + "org.springframework.boot.http.client", + "org.springframework.boot.http.client.autoconfigure", + "org.springframework.boot.http.client.autoconfigure.imperative", + "org.springframework.boot.http.client.autoconfigure.metrics", + "org.springframework.boot.http.client.autoconfigure.reactive", + "org.springframework.boot.http.client.autoconfigure.service", + "org.springframework.boot.http.client.reactive" + ], + "org.springframework.boot:spring-boot-http-codec": [ + "org.springframework.boot.http.codec", + "org.springframework.boot.http.codec.autoconfigure" + ], + "org.springframework.boot:spring-boot-http-converter": [ + "org.springframework.boot.http.converter.autoconfigure" + ], + "org.springframework.boot:spring-boot-jackson": [ + "org.springframework.boot.jackson", + "org.springframework.boot.jackson.autoconfigure" + ], + "org.springframework.boot:spring-boot-micrometer-metrics": [ + "org.springframework.boot.micrometer.metrics", + "org.springframework.boot.micrometer.metrics.actuate.endpoint", + "org.springframework.boot.micrometer.metrics.autoconfigure", + "org.springframework.boot.micrometer.metrics.autoconfigure.export", + "org.springframework.boot.micrometer.metrics.autoconfigure.export.appoptics", + "org.springframework.boot.micrometer.metrics.autoconfigure.export.atlas", + "org.springframework.boot.micrometer.metrics.autoconfigure.export.datadog", + "org.springframework.boot.micrometer.metrics.autoconfigure.export.dynatrace", + "org.springframework.boot.micrometer.metrics.autoconfigure.export.elastic", + "org.springframework.boot.micrometer.metrics.autoconfigure.export.ganglia", + "org.springframework.boot.micrometer.metrics.autoconfigure.export.graphite", + "org.springframework.boot.micrometer.metrics.autoconfigure.export.humio", + "org.springframework.boot.micrometer.metrics.autoconfigure.export.influx", + "org.springframework.boot.micrometer.metrics.autoconfigure.export.jmx", + "org.springframework.boot.micrometer.metrics.autoconfigure.export.kairos", + "org.springframework.boot.micrometer.metrics.autoconfigure.export.newrelic", + "org.springframework.boot.micrometer.metrics.autoconfigure.export.otlp", + "org.springframework.boot.micrometer.metrics.autoconfigure.export.prometheus", + "org.springframework.boot.micrometer.metrics.autoconfigure.export.properties", + "org.springframework.boot.micrometer.metrics.autoconfigure.export.simple", + "org.springframework.boot.micrometer.metrics.autoconfigure.export.stackdriver", + "org.springframework.boot.micrometer.metrics.autoconfigure.export.statsd", + "org.springframework.boot.micrometer.metrics.autoconfigure.jvm", + "org.springframework.boot.micrometer.metrics.autoconfigure.logging.log4j2", + "org.springframework.boot.micrometer.metrics.autoconfigure.logging.logback", + "org.springframework.boot.micrometer.metrics.autoconfigure.ssl", + "org.springframework.boot.micrometer.metrics.autoconfigure.startup", + "org.springframework.boot.micrometer.metrics.autoconfigure.system", + "org.springframework.boot.micrometer.metrics.autoconfigure.task", + "org.springframework.boot.micrometer.metrics.docker.compose.otlp", + "org.springframework.boot.micrometer.metrics.export.prometheus", + "org.springframework.boot.micrometer.metrics.export.prometheus.endpoint", + "org.springframework.boot.micrometer.metrics.startup", + "org.springframework.boot.micrometer.metrics.system", + "org.springframework.boot.micrometer.metrics.testcontainers.otlp" + ], + "org.springframework.boot:spring-boot-micrometer-metrics-test": [ + "org.springframework.boot.micrometer.metrics.test.autoconfigure" + ], + "org.springframework.boot:spring-boot-micrometer-observation": [ + "org.springframework.boot.micrometer.observation.autoconfigure" + ], + "org.springframework.boot:spring-boot-micrometer-tracing": [ + "org.springframework.boot.micrometer.tracing.autoconfigure", + "org.springframework.boot.micrometer.tracing.autoconfigure.prometheus" + ], + "org.springframework.boot:spring-boot-micrometer-tracing-opentelemetry": [ + "org.springframework.boot.micrometer.tracing.opentelemetry.autoconfigure", + "org.springframework.boot.micrometer.tracing.opentelemetry.autoconfigure.otlp", + "org.springframework.boot.micrometer.tracing.opentelemetry.autoconfigure.zipkin", + "org.springframework.boot.micrometer.tracing.opentelemetry.docker.compose.otlp", + "org.springframework.boot.micrometer.tracing.opentelemetry.testcontainers.otlp" + ], + "org.springframework.boot:spring-boot-netty": [ + "org.springframework.boot.netty.autoconfigure" + ], + "org.springframework.boot:spring-boot-opentelemetry": [ + "org.springframework.boot.opentelemetry.autoconfigure", + "org.springframework.boot.opentelemetry.autoconfigure.logging", + "org.springframework.boot.opentelemetry.autoconfigure.logging.otlp", + "org.springframework.boot.opentelemetry.docker.compose", + "org.springframework.boot.opentelemetry.testcontainers" + ], + "org.springframework.boot:spring-boot-persistence": [ + "org.springframework.boot.persistence.autoconfigure" + ], + "org.springframework.boot:spring-boot-reactor": [ + "org.springframework.boot.reactor", + "org.springframework.boot.reactor.autoconfigure" + ], + "org.springframework.boot:spring-boot-reactor-netty": [ + "org.springframework.boot.reactor.netty", + "org.springframework.boot.reactor.netty.autoconfigure", + "org.springframework.boot.reactor.netty.autoconfigure.actuate.web.server" + ], + "org.springframework.boot:spring-boot-restclient": [ + "org.springframework.boot.restclient", + "org.springframework.boot.restclient.autoconfigure", + "org.springframework.boot.restclient.autoconfigure.service", + "org.springframework.boot.restclient.observation" + ], + "org.springframework.boot:spring-boot-resttestclient": [ + "org.springframework.boot.resttestclient", + "org.springframework.boot.resttestclient.autoconfigure" + ], + "org.springframework.boot:spring-boot-security": [ + "org.springframework.boot.security.autoconfigure", + "org.springframework.boot.security.autoconfigure.actuate.web.reactive", + "org.springframework.boot.security.autoconfigure.actuate.web.servlet", + "org.springframework.boot.security.autoconfigure.rsocket", + "org.springframework.boot.security.autoconfigure.web", + "org.springframework.boot.security.autoconfigure.web.reactive", + "org.springframework.boot.security.autoconfigure.web.servlet", + "org.springframework.boot.security.web.reactive", + "org.springframework.boot.security.web.servlet" + ], + "org.springframework.boot:spring-boot-security-oauth2-client": [ + "org.springframework.boot.security.oauth2.client.autoconfigure", + "org.springframework.boot.security.oauth2.client.autoconfigure.reactive", + "org.springframework.boot.security.oauth2.client.autoconfigure.servlet" + ], + "org.springframework.boot:spring-boot-security-oauth2-resource-server": [ + "org.springframework.boot.security.oauth2.server.resource.autoconfigure", + "org.springframework.boot.security.oauth2.server.resource.autoconfigure.reactive", + "org.springframework.boot.security.oauth2.server.resource.autoconfigure.servlet" + ], + "org.springframework.boot:spring-boot-security-test": [ + "org.springframework.boot.security.test.autoconfigure.webflux", + "org.springframework.boot.security.test.autoconfigure.webmvc" + ], + "org.springframework.boot:spring-boot-servlet": [ + "org.springframework.boot.servlet", + "org.springframework.boot.servlet.actuate.web.exchanges", + "org.springframework.boot.servlet.actuate.web.mappings", + "org.springframework.boot.servlet.autoconfigure", + "org.springframework.boot.servlet.autoconfigure.actuate.web", + "org.springframework.boot.servlet.autoconfigure.actuate.web.exchanges", + "org.springframework.boot.servlet.autoconfigure.actuate.web.mappings", + "org.springframework.boot.servlet.filter" + ], + "org.springframework.boot:spring-boot-test": [ + "org.springframework.boot.test.context", + "org.springframework.boot.test.context.assertj", + "org.springframework.boot.test.context.filter", + "org.springframework.boot.test.context.filter.annotation", + "org.springframework.boot.test.context.runner", + "org.springframework.boot.test.http.client", + "org.springframework.boot.test.http.server", + "org.springframework.boot.test.json", + "org.springframework.boot.test.mock.web", + "org.springframework.boot.test.system", + "org.springframework.boot.test.util", + "org.springframework.boot.test.web.htmlunit", + "org.springframework.boot.test.web.server" + ], + "org.springframework.boot:spring-boot-test-autoconfigure": [ + "org.springframework.boot.test.autoconfigure", + "org.springframework.boot.test.autoconfigure.jdbc", + "org.springframework.boot.test.autoconfigure.json" + ], + "org.springframework.boot:spring-boot-tomcat": [ + "org.springframework.boot.tomcat", + "org.springframework.boot.tomcat.autoconfigure", + "org.springframework.boot.tomcat.autoconfigure.actuate.web.server", + "org.springframework.boot.tomcat.autoconfigure.metrics", + "org.springframework.boot.tomcat.autoconfigure.reactive", + "org.springframework.boot.tomcat.autoconfigure.servlet", + "org.springframework.boot.tomcat.metrics", + "org.springframework.boot.tomcat.reactive", + "org.springframework.boot.tomcat.servlet" + ], + "org.springframework.boot:spring-boot-validation": [ + "org.springframework.boot.validation.autoconfigure" + ], + "org.springframework.boot:spring-boot-web-server": [ + "org.springframework.boot.web.server", + "org.springframework.boot.web.server.autoconfigure", + "org.springframework.boot.web.server.autoconfigure.reactive", + "org.springframework.boot.web.server.autoconfigure.servlet", + "org.springframework.boot.web.server.context", + "org.springframework.boot.web.server.reactive", + "org.springframework.boot.web.server.reactive.context", + "org.springframework.boot.web.server.servlet", + "org.springframework.boot.web.server.servlet.context" + ], + "org.springframework.boot:spring-boot-webclient": [ + "org.springframework.boot.webclient", + "org.springframework.boot.webclient.autoconfigure", + "org.springframework.boot.webclient.autoconfigure.service", + "org.springframework.boot.webclient.observation" + ], + "org.springframework.boot:spring-boot-webflux": [ + "org.springframework.boot.webflux", + "org.springframework.boot.webflux.actuate.endpoint.web", + "org.springframework.boot.webflux.actuate.web.exchanges", + "org.springframework.boot.webflux.actuate.web.mappings", + "org.springframework.boot.webflux.autoconfigure", + "org.springframework.boot.webflux.autoconfigure.actuate.endpoint.web", + "org.springframework.boot.webflux.autoconfigure.actuate.web", + "org.springframework.boot.webflux.autoconfigure.actuate.web.exchanges", + "org.springframework.boot.webflux.autoconfigure.actuate.web.mappings", + "org.springframework.boot.webflux.autoconfigure.error", + "org.springframework.boot.webflux.error", + "org.springframework.boot.webflux.filter" + ], + "org.springframework.boot:spring-boot-webflux-test": [ + "org.springframework.boot.webflux.test.autoconfigure" + ], + "org.springframework.boot:spring-boot-webmvc": [ + "org.springframework.boot.webmvc", + "org.springframework.boot.webmvc.actuate.endpoint.web", + "org.springframework.boot.webmvc.actuate.web.mappings", + "org.springframework.boot.webmvc.autoconfigure", + "org.springframework.boot.webmvc.autoconfigure.actuate.endpoint.web", + "org.springframework.boot.webmvc.autoconfigure.actuate.web", + "org.springframework.boot.webmvc.autoconfigure.actuate.web.mappings", + "org.springframework.boot.webmvc.autoconfigure.error", + "org.springframework.boot.webmvc.error" + ], + "org.springframework.boot:spring-boot-webmvc-test": [ + "org.springframework.boot.webmvc.test.autoconfigure" + ], + "org.springframework.boot:spring-boot-webtestclient": [ + "org.springframework.boot.webtestclient.autoconfigure" + ], + "org.springframework.cloud:spring-cloud-commons": [ + "org.springframework.cloud.client", + "org.springframework.cloud.client.actuator", + "org.springframework.cloud.client.circuitbreaker", + "org.springframework.cloud.client.circuitbreaker.httpservice", + "org.springframework.cloud.client.circuitbreaker.observation", + "org.springframework.cloud.client.discovery", + "org.springframework.cloud.client.discovery.composite", + "org.springframework.cloud.client.discovery.composite.reactive", + "org.springframework.cloud.client.discovery.event", + "org.springframework.cloud.client.discovery.health", + "org.springframework.cloud.client.discovery.health.reactive", + "org.springframework.cloud.client.discovery.simple", + "org.springframework.cloud.client.discovery.simple.reactive", + "org.springframework.cloud.client.hypermedia", + "org.springframework.cloud.client.loadbalancer", + "org.springframework.cloud.client.loadbalancer.reactive", + "org.springframework.cloud.client.serviceregistry", + "org.springframework.cloud.client.serviceregistry.endpoint", + "org.springframework.cloud.commons", + "org.springframework.cloud.commons.config", + "org.springframework.cloud.commons.publisher", + "org.springframework.cloud.commons.security", + "org.springframework.cloud.commons.util", + "org.springframework.cloud.configuration" + ], + "org.springframework.cloud:spring-cloud-context": [ + "org.springframework.cloud.autoconfigure", + "org.springframework.cloud.bootstrap", + "org.springframework.cloud.bootstrap.config", + "org.springframework.cloud.bootstrap.encrypt", + "org.springframework.cloud.bootstrap.support", + "org.springframework.cloud.context", + "org.springframework.cloud.context.config", + "org.springframework.cloud.context.config.annotation", + "org.springframework.cloud.context.encrypt", + "org.springframework.cloud.context.environment", + "org.springframework.cloud.context.named", + "org.springframework.cloud.context.properties", + "org.springframework.cloud.context.refresh", + "org.springframework.cloud.context.restart", + "org.springframework.cloud.context.scope", + "org.springframework.cloud.context.scope.refresh", + "org.springframework.cloud.context.scope.thread", + "org.springframework.cloud.endpoint", + "org.springframework.cloud.endpoint.event", + "org.springframework.cloud.env", + "org.springframework.cloud.health", + "org.springframework.cloud.logging", + "org.springframework.cloud.util", + "org.springframework.cloud.util.random" + ], + "org.springframework.cloud:spring-cloud-starter-bootstrap": [ + "org.springframework.cloud.bootstrap.marker" + ], + "org.springframework.data:spring-data-cassandra": [ + "org.springframework.data.cassandra", + "org.springframework.data.cassandra.aot", + "org.springframework.data.cassandra.config", + "org.springframework.data.cassandra.core", + "org.springframework.data.cassandra.core.convert", + "org.springframework.data.cassandra.core.cql", + "org.springframework.data.cassandra.core.cql.converter", + "org.springframework.data.cassandra.core.cql.generator", + "org.springframework.data.cassandra.core.cql.keyspace", + "org.springframework.data.cassandra.core.cql.session", + "org.springframework.data.cassandra.core.cql.session.init", + "org.springframework.data.cassandra.core.cql.session.lookup", + "org.springframework.data.cassandra.core.cql.util", + "org.springframework.data.cassandra.core.mapping", + "org.springframework.data.cassandra.core.mapping.event", + "org.springframework.data.cassandra.core.query", + "org.springframework.data.cassandra.observability", + "org.springframework.data.cassandra.repository", + "org.springframework.data.cassandra.repository.aot", + "org.springframework.data.cassandra.repository.cdi", + "org.springframework.data.cassandra.repository.config", + "org.springframework.data.cassandra.repository.query", + "org.springframework.data.cassandra.repository.support", + "org.springframework.data.cassandra.util" + ], + "org.springframework.data:spring-data-commons": [ + "org.springframework.data.annotation", + "org.springframework.data.aot", + "org.springframework.data.auditing", + "org.springframework.data.auditing.config", + "org.springframework.data.config", + "org.springframework.data.convert", + "org.springframework.data.core", + "org.springframework.data.crossstore", + "org.springframework.data.domain", + "org.springframework.data.domain.jaxb", + "org.springframework.data.expression", + "org.springframework.data.geo", + "org.springframework.data.geo.format", + "org.springframework.data.history", + "org.springframework.data.javapoet", + "org.springframework.data.mapping", + "org.springframework.data.mapping.callback", + "org.springframework.data.mapping.context", + "org.springframework.data.mapping.model", + "org.springframework.data.projection", + "org.springframework.data.querydsl", + "org.springframework.data.querydsl.aot", + "org.springframework.data.querydsl.binding", + "org.springframework.data.repository", + "org.springframework.data.repository.aot.generate", + "org.springframework.data.repository.aot.hint", + "org.springframework.data.repository.cdi", + "org.springframework.data.repository.config", + "org.springframework.data.repository.core", + "org.springframework.data.repository.core.support", + "org.springframework.data.repository.history", + "org.springframework.data.repository.history.support", + "org.springframework.data.repository.init", + "org.springframework.data.repository.kotlin", + "org.springframework.data.repository.query", + "org.springframework.data.repository.query.parser", + "org.springframework.data.repository.reactive", + "org.springframework.data.repository.support", + "org.springframework.data.repository.util", + "org.springframework.data.spel", + "org.springframework.data.spel.spi", + "org.springframework.data.support", + "org.springframework.data.transaction", + "org.springframework.data.util", + "org.springframework.data.web", + "org.springframework.data.web.aot", + "org.springframework.data.web.config", + "org.springframework.data.web.querydsl" + ], + "org.springframework.security:spring-security-config": [ + "org.springframework.security.config", + "org.springframework.security.config.annotation", + "org.springframework.security.config.annotation.authentication", + "org.springframework.security.config.annotation.authentication.builders", + "org.springframework.security.config.annotation.authentication.configuration", + "org.springframework.security.config.annotation.authentication.configurers.ldap", + "org.springframework.security.config.annotation.authentication.configurers.provisioning", + "org.springframework.security.config.annotation.authentication.configurers.userdetails", + "org.springframework.security.config.annotation.authorization", + "org.springframework.security.config.annotation.configuration", + "org.springframework.security.config.annotation.method.configuration", + "org.springframework.security.config.annotation.rsocket", + "org.springframework.security.config.annotation.web", + "org.springframework.security.config.annotation.web.builders", + "org.springframework.security.config.annotation.web.configuration", + "org.springframework.security.config.annotation.web.configurers", + "org.springframework.security.config.annotation.web.configurers.oauth2.client", + "org.springframework.security.config.annotation.web.configurers.oauth2.server.authorization", + "org.springframework.security.config.annotation.web.configurers.oauth2.server.resource", + "org.springframework.security.config.annotation.web.configurers.ott", + "org.springframework.security.config.annotation.web.configurers.saml2", + "org.springframework.security.config.annotation.web.headers", + "org.springframework.security.config.annotation.web.oauth2.client", + "org.springframework.security.config.annotation.web.oauth2.login", + "org.springframework.security.config.annotation.web.oauth2.resourceserver", + "org.springframework.security.config.annotation.web.reactive", + "org.springframework.security.config.annotation.web.saml2", + "org.springframework.security.config.annotation.web.servlet.configuration", + "org.springframework.security.config.annotation.web.session", + "org.springframework.security.config.annotation.web.socket", + "org.springframework.security.config.aot.hint", + "org.springframework.security.config.authentication", + "org.springframework.security.config.core", + "org.springframework.security.config.core.userdetails", + "org.springframework.security.config.crypto", + "org.springframework.security.config.debug", + "org.springframework.security.config.http", + "org.springframework.security.config.ldap", + "org.springframework.security.config.method", + "org.springframework.security.config.oauth2.client", + "org.springframework.security.config.observation", + "org.springframework.security.config.provisioning", + "org.springframework.security.config.saml2", + "org.springframework.security.config.web", + "org.springframework.security.config.web.messaging", + "org.springframework.security.config.web.server", + "org.springframework.security.config.websocket" + ], + "org.springframework.security:spring-security-core": [ + "org.springframework.security.access", + "org.springframework.security.access.annotation", + "org.springframework.security.access.expression", + "org.springframework.security.access.expression.method", + "org.springframework.security.access.hierarchicalroles", + "org.springframework.security.access.prepost", + "org.springframework.security.aot.hint", + "org.springframework.security.authentication", + "org.springframework.security.authentication.dao", + "org.springframework.security.authentication.event", + "org.springframework.security.authentication.jaas", + "org.springframework.security.authentication.jaas.event", + "org.springframework.security.authentication.jaas.memory", + "org.springframework.security.authentication.ott", + "org.springframework.security.authentication.ott.reactive", + "org.springframework.security.authentication.password", + "org.springframework.security.authorization", + "org.springframework.security.authorization.event", + "org.springframework.security.authorization.method", + "org.springframework.security.concurrent", + "org.springframework.security.context", + "org.springframework.security.converter", + "org.springframework.security.core", + "org.springframework.security.core.annotation", + "org.springframework.security.core.authority", + "org.springframework.security.core.authority.mapping", + "org.springframework.security.core.context", + "org.springframework.security.core.parameters", + "org.springframework.security.core.session", + "org.springframework.security.core.token", + "org.springframework.security.core.userdetails", + "org.springframework.security.core.userdetails.cache", + "org.springframework.security.core.userdetails.jdbc", + "org.springframework.security.core.userdetails.memory", + "org.springframework.security.jackson", + "org.springframework.security.jackson2", + "org.springframework.security.provisioning", + "org.springframework.security.scheduling", + "org.springframework.security.task", + "org.springframework.security.util" + ], + "org.springframework.security:spring-security-crypto": [ + "org.springframework.security.crypto.argon2", + "org.springframework.security.crypto.bcrypt", + "org.springframework.security.crypto.codec", + "org.springframework.security.crypto.encrypt", + "org.springframework.security.crypto.factory", + "org.springframework.security.crypto.keygen", + "org.springframework.security.crypto.password", + "org.springframework.security.crypto.password4j", + "org.springframework.security.crypto.scrypt", + "org.springframework.security.crypto.util" + ], + "org.springframework.security:spring-security-oauth2-client": [ + "org.springframework.security.oauth2.client", + "org.springframework.security.oauth2.client.annotation", + "org.springframework.security.oauth2.client.aot.hint", + "org.springframework.security.oauth2.client.authentication", + "org.springframework.security.oauth2.client.endpoint", + "org.springframework.security.oauth2.client.event", + "org.springframework.security.oauth2.client.http", + "org.springframework.security.oauth2.client.jackson", + "org.springframework.security.oauth2.client.jackson2", + "org.springframework.security.oauth2.client.oidc.authentication", + "org.springframework.security.oauth2.client.oidc.authentication.event", + "org.springframework.security.oauth2.client.oidc.authentication.logout", + "org.springframework.security.oauth2.client.oidc.server.session", + "org.springframework.security.oauth2.client.oidc.session", + "org.springframework.security.oauth2.client.oidc.userinfo", + "org.springframework.security.oauth2.client.oidc.web.logout", + "org.springframework.security.oauth2.client.oidc.web.server.logout", + "org.springframework.security.oauth2.client.registration", + "org.springframework.security.oauth2.client.userinfo", + "org.springframework.security.oauth2.client.web", + "org.springframework.security.oauth2.client.web.client", + "org.springframework.security.oauth2.client.web.client.support", + "org.springframework.security.oauth2.client.web.method.annotation", + "org.springframework.security.oauth2.client.web.reactive.function.client", + "org.springframework.security.oauth2.client.web.reactive.function.client.support", + "org.springframework.security.oauth2.client.web.reactive.result.method.annotation", + "org.springframework.security.oauth2.client.web.server", + "org.springframework.security.oauth2.client.web.server.authentication" + ], + "org.springframework.security:spring-security-oauth2-core": [ + "org.springframework.security.oauth2.core", + "org.springframework.security.oauth2.core.authorization", + "org.springframework.security.oauth2.core.converter", + "org.springframework.security.oauth2.core.endpoint", + "org.springframework.security.oauth2.core.http.converter", + "org.springframework.security.oauth2.core.oidc", + "org.springframework.security.oauth2.core.oidc.endpoint", + "org.springframework.security.oauth2.core.oidc.user", + "org.springframework.security.oauth2.core.user", + "org.springframework.security.oauth2.core.web.reactive.function" + ], + "org.springframework.security:spring-security-oauth2-jose": [ + "org.springframework.security.oauth2.jose", + "org.springframework.security.oauth2.jose.jws", + "org.springframework.security.oauth2.jwt" + ], + "org.springframework.security:spring-security-oauth2-resource-server": [ + "org.springframework.security.oauth2.server.resource", + "org.springframework.security.oauth2.server.resource.authentication", + "org.springframework.security.oauth2.server.resource.introspection", + "org.springframework.security.oauth2.server.resource.web", + "org.springframework.security.oauth2.server.resource.web.access", + "org.springframework.security.oauth2.server.resource.web.access.server", + "org.springframework.security.oauth2.server.resource.web.authentication", + "org.springframework.security.oauth2.server.resource.web.reactive.function.client", + "org.springframework.security.oauth2.server.resource.web.server", + "org.springframework.security.oauth2.server.resource.web.server.authentication" + ], + "org.springframework.security:spring-security-test": [ + "org.springframework.security.test.aot.hint", + "org.springframework.security.test.context", + "org.springframework.security.test.context.annotation", + "org.springframework.security.test.context.support", + "org.springframework.security.test.web.reactive.server", + "org.springframework.security.test.web.servlet.request", + "org.springframework.security.test.web.servlet.response", + "org.springframework.security.test.web.servlet.setup", + "org.springframework.security.test.web.support" + ], + "org.springframework.security:spring-security-web": [ + "org.springframework.security.web", + "org.springframework.security.web.access", + "org.springframework.security.web.access.expression", + "org.springframework.security.web.access.intercept", + "org.springframework.security.web.aot.hint", + "org.springframework.security.web.authentication", + "org.springframework.security.web.authentication.logout", + "org.springframework.security.web.authentication.ott", + "org.springframework.security.web.authentication.password", + "org.springframework.security.web.authentication.preauth", + "org.springframework.security.web.authentication.preauth.j2ee", + "org.springframework.security.web.authentication.preauth.websphere", + "org.springframework.security.web.authentication.preauth.x509", + "org.springframework.security.web.authentication.rememberme", + "org.springframework.security.web.authentication.session", + "org.springframework.security.web.authentication.switchuser", + "org.springframework.security.web.authentication.ui", + "org.springframework.security.web.authentication.www", + "org.springframework.security.web.bind", + "org.springframework.security.web.bind.annotation", + "org.springframework.security.web.bind.support", + "org.springframework.security.web.context", + "org.springframework.security.web.context.request.async", + "org.springframework.security.web.context.support", + "org.springframework.security.web.csrf", + "org.springframework.security.web.debug", + "org.springframework.security.web.firewall", + "org.springframework.security.web.header", + "org.springframework.security.web.header.writers", + "org.springframework.security.web.header.writers.frameoptions", + "org.springframework.security.web.http", + "org.springframework.security.web.jaasapi", + "org.springframework.security.web.jackson", + "org.springframework.security.web.jackson2", + "org.springframework.security.web.method.annotation", + "org.springframework.security.web.reactive.result.method.annotation", + "org.springframework.security.web.reactive.result.view", + "org.springframework.security.web.savedrequest", + "org.springframework.security.web.server", + "org.springframework.security.web.server.authentication", + "org.springframework.security.web.server.authentication.logout", + "org.springframework.security.web.server.authentication.ott", + "org.springframework.security.web.server.authorization", + "org.springframework.security.web.server.context", + "org.springframework.security.web.server.csrf", + "org.springframework.security.web.server.firewall", + "org.springframework.security.web.server.header", + "org.springframework.security.web.server.jackson", + "org.springframework.security.web.server.jackson2", + "org.springframework.security.web.server.savedrequest", + "org.springframework.security.web.server.transport", + "org.springframework.security.web.server.ui", + "org.springframework.security.web.server.util.matcher", + "org.springframework.security.web.servlet.support.csrf", + "org.springframework.security.web.servlet.util.matcher", + "org.springframework.security.web.servletapi", + "org.springframework.security.web.session", + "org.springframework.security.web.transport", + "org.springframework.security.web.util", + "org.springframework.security.web.util.matcher" + ], + "org.springframework:spring-aop": [ + "org.aopalliance", + "org.aopalliance.aop", + "org.aopalliance.intercept", + "org.springframework.aop", + "org.springframework.aop.aspectj", + "org.springframework.aop.aspectj.annotation", + "org.springframework.aop.aspectj.autoproxy", + "org.springframework.aop.config", + "org.springframework.aop.framework", + "org.springframework.aop.framework.adapter", + "org.springframework.aop.framework.autoproxy", + "org.springframework.aop.framework.autoproxy.target", + "org.springframework.aop.interceptor", + "org.springframework.aop.scope", + "org.springframework.aop.support", + "org.springframework.aop.support.annotation", + "org.springframework.aop.target", + "org.springframework.aop.target.dynamic" + ], + "org.springframework:spring-beans": [ + "org.springframework.beans", + "org.springframework.beans.factory", + "org.springframework.beans.factory.annotation", + "org.springframework.beans.factory.aot", + "org.springframework.beans.factory.config", + "org.springframework.beans.factory.groovy", + "org.springframework.beans.factory.parsing", + "org.springframework.beans.factory.serviceloader", + "org.springframework.beans.factory.support", + "org.springframework.beans.factory.wiring", + "org.springframework.beans.factory.xml", + "org.springframework.beans.propertyeditors", + "org.springframework.beans.support" + ], + "org.springframework:spring-context": [ + "org.springframework.cache", + "org.springframework.cache.annotation", + "org.springframework.cache.concurrent", + "org.springframework.cache.config", + "org.springframework.cache.interceptor", + "org.springframework.cache.support", + "org.springframework.context", + "org.springframework.context.annotation", + "org.springframework.context.aot", + "org.springframework.context.config", + "org.springframework.context.event", + "org.springframework.context.expression", + "org.springframework.context.i18n", + "org.springframework.context.index", + "org.springframework.context.support", + "org.springframework.context.weaving", + "org.springframework.ejb.config", + "org.springframework.format", + "org.springframework.format.annotation", + "org.springframework.format.datetime", + "org.springframework.format.datetime.standard", + "org.springframework.format.number", + "org.springframework.format.number.money", + "org.springframework.format.support", + "org.springframework.instrument.classloading", + "org.springframework.instrument.classloading.glassfish", + "org.springframework.instrument.classloading.jboss", + "org.springframework.instrument.classloading.tomcat", + "org.springframework.jmx", + "org.springframework.jmx.access", + "org.springframework.jmx.export", + "org.springframework.jmx.export.annotation", + "org.springframework.jmx.export.assembler", + "org.springframework.jmx.export.metadata", + "org.springframework.jmx.export.naming", + "org.springframework.jmx.export.notification", + "org.springframework.jmx.support", + "org.springframework.jndi", + "org.springframework.jndi.support", + "org.springframework.resilience", + "org.springframework.resilience.annotation", + "org.springframework.resilience.retry", + "org.springframework.scheduling", + "org.springframework.scheduling.annotation", + "org.springframework.scheduling.concurrent", + "org.springframework.scheduling.config", + "org.springframework.scheduling.support", + "org.springframework.scripting", + "org.springframework.scripting.bsh", + "org.springframework.scripting.config", + "org.springframework.scripting.groovy", + "org.springframework.scripting.support", + "org.springframework.stereotype", + "org.springframework.ui", + "org.springframework.validation", + "org.springframework.validation.annotation", + "org.springframework.validation.beanvalidation", + "org.springframework.validation.method", + "org.springframework.validation.support" + ], + "org.springframework:spring-core": [ + "org.springframework.aot", + "org.springframework.aot.generate", + "org.springframework.aot.hint", + "org.springframework.aot.hint.annotation", + "org.springframework.aot.hint.predicate", + "org.springframework.aot.hint.support", + "org.springframework.aot.nativex", + "org.springframework.aot.nativex.feature", + "org.springframework.asm", + "org.springframework.cglib", + "org.springframework.cglib.beans", + "org.springframework.cglib.core", + "org.springframework.cglib.core.internal", + "org.springframework.cglib.proxy", + "org.springframework.cglib.reflect", + "org.springframework.cglib.transform", + "org.springframework.cglib.transform.impl", + "org.springframework.cglib.util", + "org.springframework.core", + "org.springframework.core.annotation", + "org.springframework.core.codec", + "org.springframework.core.convert", + "org.springframework.core.convert.converter", + "org.springframework.core.convert.support", + "org.springframework.core.env", + "org.springframework.core.io", + "org.springframework.core.io.buffer", + "org.springframework.core.io.support", + "org.springframework.core.log", + "org.springframework.core.metrics", + "org.springframework.core.metrics.jfr", + "org.springframework.core.retry", + "org.springframework.core.retry.support", + "org.springframework.core.serializer", + "org.springframework.core.serializer.support", + "org.springframework.core.style", + "org.springframework.core.task", + "org.springframework.core.task.support", + "org.springframework.core.type", + "org.springframework.core.type.classreading", + "org.springframework.core.type.filter", + "org.springframework.javapoet", + "org.springframework.lang", + "org.springframework.objenesis", + "org.springframework.objenesis.instantiator", + "org.springframework.objenesis.instantiator.android", + "org.springframework.objenesis.instantiator.annotations", + "org.springframework.objenesis.instantiator.basic", + "org.springframework.objenesis.instantiator.gcj", + "org.springframework.objenesis.instantiator.perc", + "org.springframework.objenesis.instantiator.sun", + "org.springframework.objenesis.instantiator.util", + "org.springframework.objenesis.strategy", + "org.springframework.util", + "org.springframework.util.backoff", + "org.springframework.util.comparator", + "org.springframework.util.concurrent", + "org.springframework.util.function", + "org.springframework.util.unit", + "org.springframework.util.xml" + ], + "org.springframework:spring-expression": [ + "org.springframework.expression", + "org.springframework.expression.common", + "org.springframework.expression.spel", + "org.springframework.expression.spel.ast", + "org.springframework.expression.spel.standard", + "org.springframework.expression.spel.support" + ], + "org.springframework:spring-test": [ + "org.springframework.mock.env", + "org.springframework.mock.http", + "org.springframework.mock.http.client", + "org.springframework.mock.http.client.reactive", + "org.springframework.mock.http.server.reactive", + "org.springframework.mock.web", + "org.springframework.mock.web.reactive.function.server", + "org.springframework.mock.web.server", + "org.springframework.test.annotation", + "org.springframework.test.context", + "org.springframework.test.context.aot", + "org.springframework.test.context.bean.override", + "org.springframework.test.context.bean.override.convention", + "org.springframework.test.context.bean.override.mockito", + "org.springframework.test.context.cache", + "org.springframework.test.context.event", + "org.springframework.test.context.event.annotation", + "org.springframework.test.context.hint", + "org.springframework.test.context.jdbc", + "org.springframework.test.context.junit.jupiter", + "org.springframework.test.context.junit.jupiter.web", + "org.springframework.test.context.junit4", + "org.springframework.test.context.junit4.rules", + "org.springframework.test.context.junit4.statements", + "org.springframework.test.context.observation", + "org.springframework.test.context.support", + "org.springframework.test.context.testng", + "org.springframework.test.context.transaction", + "org.springframework.test.context.util", + "org.springframework.test.context.web", + "org.springframework.test.context.web.socket", + "org.springframework.test.http", + "org.springframework.test.jdbc", + "org.springframework.test.json", + "org.springframework.test.util", + "org.springframework.test.validation", + "org.springframework.test.web", + "org.springframework.test.web.client", + "org.springframework.test.web.client.match", + "org.springframework.test.web.client.response", + "org.springframework.test.web.reactive.server", + "org.springframework.test.web.reactive.server.assertj", + "org.springframework.test.web.servlet", + "org.springframework.test.web.servlet.assertj", + "org.springframework.test.web.servlet.client", + "org.springframework.test.web.servlet.client.assertj", + "org.springframework.test.web.servlet.htmlunit", + "org.springframework.test.web.servlet.htmlunit.webdriver", + "org.springframework.test.web.servlet.request", + "org.springframework.test.web.servlet.result", + "org.springframework.test.web.servlet.setup", + "org.springframework.test.web.support" + ], + "org.springframework:spring-tx": [ + "org.springframework.dao", + "org.springframework.dao.annotation", + "org.springframework.dao.support", + "org.springframework.jca.endpoint", + "org.springframework.jca.support", + "org.springframework.transaction", + "org.springframework.transaction.annotation", + "org.springframework.transaction.config", + "org.springframework.transaction.event", + "org.springframework.transaction.interceptor", + "org.springframework.transaction.jta", + "org.springframework.transaction.reactive", + "org.springframework.transaction.support" + ], + "org.springframework:spring-web": [ + "org.springframework.http", + "org.springframework.http.client", + "org.springframework.http.client.observation", + "org.springframework.http.client.reactive", + "org.springframework.http.client.support", + "org.springframework.http.codec", + "org.springframework.http.codec.cbor", + "org.springframework.http.codec.json", + "org.springframework.http.codec.multipart", + "org.springframework.http.codec.protobuf", + "org.springframework.http.codec.smile", + "org.springframework.http.codec.support", + "org.springframework.http.codec.xml", + "org.springframework.http.converter", + "org.springframework.http.converter.cbor", + "org.springframework.http.converter.feed", + "org.springframework.http.converter.json", + "org.springframework.http.converter.protobuf", + "org.springframework.http.converter.smile", + "org.springframework.http.converter.support", + "org.springframework.http.converter.xml", + "org.springframework.http.converter.yaml", + "org.springframework.http.server", + "org.springframework.http.server.observation", + "org.springframework.http.server.reactive", + "org.springframework.http.server.reactive.observation", + "org.springframework.http.support", + "org.springframework.web", + "org.springframework.web.accept", + "org.springframework.web.bind", + "org.springframework.web.bind.annotation", + "org.springframework.web.bind.support", + "org.springframework.web.client", + "org.springframework.web.client.support", + "org.springframework.web.context", + "org.springframework.web.context.annotation", + "org.springframework.web.context.request", + "org.springframework.web.context.request.async", + "org.springframework.web.context.support", + "org.springframework.web.cors", + "org.springframework.web.cors.reactive", + "org.springframework.web.filter", + "org.springframework.web.filter.reactive", + "org.springframework.web.jsf", + "org.springframework.web.jsf.el", + "org.springframework.web.method", + "org.springframework.web.method.annotation", + "org.springframework.web.method.support", + "org.springframework.web.multipart", + "org.springframework.web.multipart.support", + "org.springframework.web.server", + "org.springframework.web.server.adapter", + "org.springframework.web.server.handler", + "org.springframework.web.server.i18n", + "org.springframework.web.server.session", + "org.springframework.web.service", + "org.springframework.web.service.annotation", + "org.springframework.web.service.invoker", + "org.springframework.web.service.registry", + "org.springframework.web.util", + "org.springframework.web.util.pattern" + ], + "org.springframework:spring-webflux": [ + "org.springframework.web.reactive", + "org.springframework.web.reactive.accept", + "org.springframework.web.reactive.config", + "org.springframework.web.reactive.function", + "org.springframework.web.reactive.function.client", + "org.springframework.web.reactive.function.client.support", + "org.springframework.web.reactive.function.server", + "org.springframework.web.reactive.function.server.support", + "org.springframework.web.reactive.handler", + "org.springframework.web.reactive.resource", + "org.springframework.web.reactive.result", + "org.springframework.web.reactive.result.condition", + "org.springframework.web.reactive.result.method", + "org.springframework.web.reactive.result.method.annotation", + "org.springframework.web.reactive.result.view", + "org.springframework.web.reactive.result.view.freemarker", + "org.springframework.web.reactive.result.view.script", + "org.springframework.web.reactive.socket", + "org.springframework.web.reactive.socket.adapter", + "org.springframework.web.reactive.socket.client", + "org.springframework.web.reactive.socket.server", + "org.springframework.web.reactive.socket.server.support", + "org.springframework.web.reactive.socket.server.upgrade" + ], + "org.springframework:spring-webmvc": [ + "org.springframework.web.servlet", + "org.springframework.web.servlet.config", + "org.springframework.web.servlet.config.annotation", + "org.springframework.web.servlet.function", + "org.springframework.web.servlet.function.support", + "org.springframework.web.servlet.handler", + "org.springframework.web.servlet.i18n", + "org.springframework.web.servlet.mvc", + "org.springframework.web.servlet.mvc.annotation", + "org.springframework.web.servlet.mvc.condition", + "org.springframework.web.servlet.mvc.method", + "org.springframework.web.servlet.mvc.method.annotation", + "org.springframework.web.servlet.mvc.support", + "org.springframework.web.servlet.resource", + "org.springframework.web.servlet.support", + "org.springframework.web.servlet.tags", + "org.springframework.web.servlet.tags.form", + "org.springframework.web.servlet.view", + "org.springframework.web.servlet.view.document", + "org.springframework.web.servlet.view.feed", + "org.springframework.web.servlet.view.freemarker", + "org.springframework.web.servlet.view.groovy", + "org.springframework.web.servlet.view.json", + "org.springframework.web.servlet.view.script", + "org.springframework.web.servlet.view.xml", + "org.springframework.web.servlet.view.xslt" + ], + "org.testcontainers:testcontainers": [ + "org.testcontainers", + "org.testcontainers.containers", + "org.testcontainers.containers.output", + "org.testcontainers.containers.startupcheck", + "org.testcontainers.containers.traits", + "org.testcontainers.containers.wait.internal", + "org.testcontainers.containers.wait.strategy", + "org.testcontainers.core", + "org.testcontainers.dockerclient", + "org.testcontainers.images", + "org.testcontainers.images.builder", + "org.testcontainers.images.builder.dockerfile", + "org.testcontainers.images.builder.dockerfile.statement", + "org.testcontainers.images.builder.dockerfile.traits", + "org.testcontainers.images.builder.traits", + "org.testcontainers.jib", + "org.testcontainers.lifecycle", + "org.testcontainers.shaded.com.fasterxml.jackson.core", + "org.testcontainers.shaded.com.fasterxml.jackson.core.async", + "org.testcontainers.shaded.com.fasterxml.jackson.core.base", + "org.testcontainers.shaded.com.fasterxml.jackson.core.exc", + "org.testcontainers.shaded.com.fasterxml.jackson.core.filter", + "org.testcontainers.shaded.com.fasterxml.jackson.core.format", + "org.testcontainers.shaded.com.fasterxml.jackson.core.internal.shaded.fdp.v2_18_4", + "org.testcontainers.shaded.com.fasterxml.jackson.core.io", + "org.testcontainers.shaded.com.fasterxml.jackson.core.io.schubfach", + "org.testcontainers.shaded.com.fasterxml.jackson.core.json", + "org.testcontainers.shaded.com.fasterxml.jackson.core.json.async", + "org.testcontainers.shaded.com.fasterxml.jackson.core.sym", + "org.testcontainers.shaded.com.fasterxml.jackson.core.type", + "org.testcontainers.shaded.com.fasterxml.jackson.core.util", + "org.testcontainers.shaded.com.fasterxml.jackson.databind", + "org.testcontainers.shaded.com.fasterxml.jackson.databind.annotation", + "org.testcontainers.shaded.com.fasterxml.jackson.databind.cfg", + "org.testcontainers.shaded.com.fasterxml.jackson.databind.deser", + "org.testcontainers.shaded.com.fasterxml.jackson.databind.deser.impl", + "org.testcontainers.shaded.com.fasterxml.jackson.databind.deser.std", + "org.testcontainers.shaded.com.fasterxml.jackson.databind.exc", + "org.testcontainers.shaded.com.fasterxml.jackson.databind.ext", + "org.testcontainers.shaded.com.fasterxml.jackson.databind.introspect", + "org.testcontainers.shaded.com.fasterxml.jackson.databind.jdk14", + "org.testcontainers.shaded.com.fasterxml.jackson.databind.json", + "org.testcontainers.shaded.com.fasterxml.jackson.databind.jsonFormatVisitors", + "org.testcontainers.shaded.com.fasterxml.jackson.databind.jsonschema", + "org.testcontainers.shaded.com.fasterxml.jackson.databind.jsontype", + "org.testcontainers.shaded.com.fasterxml.jackson.databind.jsontype.impl", + "org.testcontainers.shaded.com.fasterxml.jackson.databind.module", + "org.testcontainers.shaded.com.fasterxml.jackson.databind.node", + "org.testcontainers.shaded.com.fasterxml.jackson.databind.ser", + "org.testcontainers.shaded.com.fasterxml.jackson.databind.ser.impl", + "org.testcontainers.shaded.com.fasterxml.jackson.databind.ser.std", + "org.testcontainers.shaded.com.fasterxml.jackson.databind.type", + "org.testcontainers.shaded.com.fasterxml.jackson.databind.util", + "org.testcontainers.shaded.com.fasterxml.jackson.databind.util.internal", + "org.testcontainers.shaded.com.github.dockerjava.core", + "org.testcontainers.shaded.com.github.dockerjava.core.async", + "org.testcontainers.shaded.com.github.dockerjava.core.command", + "org.testcontainers.shaded.com.github.dockerjava.core.dockerfile", + "org.testcontainers.shaded.com.github.dockerjava.core.exception", + "org.testcontainers.shaded.com.github.dockerjava.core.exec", + "org.testcontainers.shaded.com.github.dockerjava.core.util", + "org.testcontainers.shaded.com.google.common.annotations", + "org.testcontainers.shaded.com.google.common.base", + "org.testcontainers.shaded.com.google.common.base.internal", + "org.testcontainers.shaded.com.google.common.cache", + "org.testcontainers.shaded.com.google.common.collect", + "org.testcontainers.shaded.com.google.common.escape", + "org.testcontainers.shaded.com.google.common.eventbus", + "org.testcontainers.shaded.com.google.common.graph", + "org.testcontainers.shaded.com.google.common.hash", + "org.testcontainers.shaded.com.google.common.html", + "org.testcontainers.shaded.com.google.common.io", + "org.testcontainers.shaded.com.google.common.math", + "org.testcontainers.shaded.com.google.common.net", + "org.testcontainers.shaded.com.google.common.primitives", + "org.testcontainers.shaded.com.google.common.reflect", + "org.testcontainers.shaded.com.google.common.util.concurrent", + "org.testcontainers.shaded.com.google.common.util.concurrent.internal", + "org.testcontainers.shaded.com.google.common.xml", + "org.testcontainers.shaded.com.google.errorprone.annotations", + "org.testcontainers.shaded.com.google.errorprone.annotations.concurrent", + "org.testcontainers.shaded.com.google.thirdparty.publicsuffix", + "org.testcontainers.shaded.com.trilead.ssh2", + "org.testcontainers.shaded.com.trilead.ssh2.auth", + "org.testcontainers.shaded.com.trilead.ssh2.channel", + "org.testcontainers.shaded.com.trilead.ssh2.crypto", + "org.testcontainers.shaded.com.trilead.ssh2.crypto.cipher", + "org.testcontainers.shaded.com.trilead.ssh2.crypto.dh", + "org.testcontainers.shaded.com.trilead.ssh2.crypto.digest", + "org.testcontainers.shaded.com.trilead.ssh2.log", + "org.testcontainers.shaded.com.trilead.ssh2.packets", + "org.testcontainers.shaded.com.trilead.ssh2.sftp", + "org.testcontainers.shaded.com.trilead.ssh2.signature", + "org.testcontainers.shaded.com.trilead.ssh2.transport", + "org.testcontainers.shaded.com.trilead.ssh2.util", + "org.testcontainers.shaded.org.awaitility", + "org.testcontainers.shaded.org.awaitility.classpath", + "org.testcontainers.shaded.org.awaitility.constraint", + "org.testcontainers.shaded.org.awaitility.core", + "org.testcontainers.shaded.org.awaitility.pollinterval", + "org.testcontainers.shaded.org.awaitility.reflect", + "org.testcontainers.shaded.org.awaitility.reflect.exception", + "org.testcontainers.shaded.org.awaitility.spi", + "org.testcontainers.shaded.org.bouncycastle", + "org.testcontainers.shaded.org.bouncycastle.asn1", + "org.testcontainers.shaded.org.bouncycastle.asn1.anssi", + "org.testcontainers.shaded.org.bouncycastle.asn1.bc", + "org.testcontainers.shaded.org.bouncycastle.asn1.bsi", + "org.testcontainers.shaded.org.bouncycastle.asn1.cmc", + "org.testcontainers.shaded.org.bouncycastle.asn1.cmp", + "org.testcontainers.shaded.org.bouncycastle.asn1.cms", + "org.testcontainers.shaded.org.bouncycastle.asn1.cms.ecc", + "org.testcontainers.shaded.org.bouncycastle.asn1.crmf", + "org.testcontainers.shaded.org.bouncycastle.asn1.cryptlib", + "org.testcontainers.shaded.org.bouncycastle.asn1.cryptopro", + "org.testcontainers.shaded.org.bouncycastle.asn1.dvcs", + "org.testcontainers.shaded.org.bouncycastle.asn1.eac", + "org.testcontainers.shaded.org.bouncycastle.asn1.edec", + "org.testcontainers.shaded.org.bouncycastle.asn1.esf", + "org.testcontainers.shaded.org.bouncycastle.asn1.ess", + "org.testcontainers.shaded.org.bouncycastle.asn1.est", + "org.testcontainers.shaded.org.bouncycastle.asn1.gm", + "org.testcontainers.shaded.org.bouncycastle.asn1.gnu", + "org.testcontainers.shaded.org.bouncycastle.asn1.iana", + "org.testcontainers.shaded.org.bouncycastle.asn1.icao", + "org.testcontainers.shaded.org.bouncycastle.asn1.isara", + "org.testcontainers.shaded.org.bouncycastle.asn1.isismtt", + "org.testcontainers.shaded.org.bouncycastle.asn1.isismtt.ocsp", + "org.testcontainers.shaded.org.bouncycastle.asn1.isismtt.x509", + "org.testcontainers.shaded.org.bouncycastle.asn1.iso", + "org.testcontainers.shaded.org.bouncycastle.asn1.kisa", + "org.testcontainers.shaded.org.bouncycastle.asn1.microsoft", + "org.testcontainers.shaded.org.bouncycastle.asn1.misc", + "org.testcontainers.shaded.org.bouncycastle.asn1.mod", + "org.testcontainers.shaded.org.bouncycastle.asn1.mozilla", + "org.testcontainers.shaded.org.bouncycastle.asn1.nist", + "org.testcontainers.shaded.org.bouncycastle.asn1.nsri", + "org.testcontainers.shaded.org.bouncycastle.asn1.ntt", + "org.testcontainers.shaded.org.bouncycastle.asn1.ocsp", + "org.testcontainers.shaded.org.bouncycastle.asn1.oiw", + "org.testcontainers.shaded.org.bouncycastle.asn1.pkcs", + "org.testcontainers.shaded.org.bouncycastle.asn1.rosstandart", + "org.testcontainers.shaded.org.bouncycastle.asn1.sec", + "org.testcontainers.shaded.org.bouncycastle.asn1.smime", + "org.testcontainers.shaded.org.bouncycastle.asn1.teletrust", + "org.testcontainers.shaded.org.bouncycastle.asn1.tsp", + "org.testcontainers.shaded.org.bouncycastle.asn1.ua", + "org.testcontainers.shaded.org.bouncycastle.asn1.util", + "org.testcontainers.shaded.org.bouncycastle.asn1.x500", + "org.testcontainers.shaded.org.bouncycastle.asn1.x500.style", + "org.testcontainers.shaded.org.bouncycastle.asn1.x509", + "org.testcontainers.shaded.org.bouncycastle.asn1.x509.qualified", + "org.testcontainers.shaded.org.bouncycastle.asn1.x509.sigi", + "org.testcontainers.shaded.org.bouncycastle.asn1.x9", + "org.testcontainers.shaded.org.bouncycastle.cert", + "org.testcontainers.shaded.org.bouncycastle.cert.bc", + "org.testcontainers.shaded.org.bouncycastle.cert.cmp", + "org.testcontainers.shaded.org.bouncycastle.cert.crmf", + "org.testcontainers.shaded.org.bouncycastle.cert.crmf.bc", + "org.testcontainers.shaded.org.bouncycastle.cert.crmf.jcajce", + "org.testcontainers.shaded.org.bouncycastle.cert.dane", + "org.testcontainers.shaded.org.bouncycastle.cert.dane.fetcher", + "org.testcontainers.shaded.org.bouncycastle.cert.jcajce", + "org.testcontainers.shaded.org.bouncycastle.cert.ocsp", + "org.testcontainers.shaded.org.bouncycastle.cert.ocsp.jcajce", + "org.testcontainers.shaded.org.bouncycastle.cert.path", + "org.testcontainers.shaded.org.bouncycastle.cert.path.validations", + "org.testcontainers.shaded.org.bouncycastle.cert.selector", + "org.testcontainers.shaded.org.bouncycastle.cert.selector.jcajce", + "org.testcontainers.shaded.org.bouncycastle.cmc", + "org.testcontainers.shaded.org.bouncycastle.cms", + "org.testcontainers.shaded.org.bouncycastle.cms.bc", + "org.testcontainers.shaded.org.bouncycastle.cms.jcajce", + "org.testcontainers.shaded.org.bouncycastle.crypto", + "org.testcontainers.shaded.org.bouncycastle.crypto.agreement", + "org.testcontainers.shaded.org.bouncycastle.crypto.agreement.ecjpake", + "org.testcontainers.shaded.org.bouncycastle.crypto.agreement.jpake", + "org.testcontainers.shaded.org.bouncycastle.crypto.agreement.kdf", + "org.testcontainers.shaded.org.bouncycastle.crypto.agreement.srp", + "org.testcontainers.shaded.org.bouncycastle.crypto.commitments", + "org.testcontainers.shaded.org.bouncycastle.crypto.constraints", + "org.testcontainers.shaded.org.bouncycastle.crypto.digests", + "org.testcontainers.shaded.org.bouncycastle.crypto.ec", + "org.testcontainers.shaded.org.bouncycastle.crypto.encodings", + "org.testcontainers.shaded.org.bouncycastle.crypto.engines", + "org.testcontainers.shaded.org.bouncycastle.crypto.examples", + "org.testcontainers.shaded.org.bouncycastle.crypto.fpe", + "org.testcontainers.shaded.org.bouncycastle.crypto.generators", + "org.testcontainers.shaded.org.bouncycastle.crypto.hpke", + "org.testcontainers.shaded.org.bouncycastle.crypto.io", + "org.testcontainers.shaded.org.bouncycastle.crypto.kems", + "org.testcontainers.shaded.org.bouncycastle.crypto.macs", + "org.testcontainers.shaded.org.bouncycastle.crypto.modes", + "org.testcontainers.shaded.org.bouncycastle.crypto.modes.gcm", + "org.testcontainers.shaded.org.bouncycastle.crypto.modes.kgcm", + "org.testcontainers.shaded.org.bouncycastle.crypto.paddings", + "org.testcontainers.shaded.org.bouncycastle.crypto.params", + "org.testcontainers.shaded.org.bouncycastle.crypto.parsers", + "org.testcontainers.shaded.org.bouncycastle.crypto.prng", + "org.testcontainers.shaded.org.bouncycastle.crypto.prng.drbg", + "org.testcontainers.shaded.org.bouncycastle.crypto.signers", + "org.testcontainers.shaded.org.bouncycastle.crypto.threshold", + "org.testcontainers.shaded.org.bouncycastle.crypto.tls", + "org.testcontainers.shaded.org.bouncycastle.crypto.util", + "org.testcontainers.shaded.org.bouncycastle.dvcs", + "org.testcontainers.shaded.org.bouncycastle.eac", + "org.testcontainers.shaded.org.bouncycastle.eac.jcajce", + "org.testcontainers.shaded.org.bouncycastle.eac.operator", + "org.testcontainers.shaded.org.bouncycastle.eac.operator.jcajce", + "org.testcontainers.shaded.org.bouncycastle.est", + "org.testcontainers.shaded.org.bouncycastle.est.jcajce", + "org.testcontainers.shaded.org.bouncycastle.i18n", + "org.testcontainers.shaded.org.bouncycastle.i18n.filter", + "org.testcontainers.shaded.org.bouncycastle.iana", + "org.testcontainers.shaded.org.bouncycastle.internal.asn1.bsi", + "org.testcontainers.shaded.org.bouncycastle.internal.asn1.cms", + "org.testcontainers.shaded.org.bouncycastle.internal.asn1.cryptlib", + "org.testcontainers.shaded.org.bouncycastle.internal.asn1.eac", + "org.testcontainers.shaded.org.bouncycastle.internal.asn1.edec", + "org.testcontainers.shaded.org.bouncycastle.internal.asn1.gnu", + "org.testcontainers.shaded.org.bouncycastle.internal.asn1.iana", + "org.testcontainers.shaded.org.bouncycastle.internal.asn1.isara", + "org.testcontainers.shaded.org.bouncycastle.internal.asn1.isismtt", + "org.testcontainers.shaded.org.bouncycastle.internal.asn1.iso", + "org.testcontainers.shaded.org.bouncycastle.internal.asn1.kisa", + "org.testcontainers.shaded.org.bouncycastle.internal.asn1.microsoft", + "org.testcontainers.shaded.org.bouncycastle.internal.asn1.misc", + "org.testcontainers.shaded.org.bouncycastle.internal.asn1.nsri", + "org.testcontainers.shaded.org.bouncycastle.internal.asn1.ntt", + "org.testcontainers.shaded.org.bouncycastle.internal.asn1.oiw", + "org.testcontainers.shaded.org.bouncycastle.internal.asn1.rosstandart", + "org.testcontainers.shaded.org.bouncycastle.its", + "org.testcontainers.shaded.org.bouncycastle.its.bc", + "org.testcontainers.shaded.org.bouncycastle.its.jcajce", + "org.testcontainers.shaded.org.bouncycastle.its.operator", + "org.testcontainers.shaded.org.bouncycastle.jcajce", + "org.testcontainers.shaded.org.bouncycastle.jcajce.interfaces", + "org.testcontainers.shaded.org.bouncycastle.jcajce.io", + "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.asymmetric", + "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.asymmetric.compositesignatures", + "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.asymmetric.dh", + "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.asymmetric.dsa", + "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.asymmetric.dstu", + "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.asymmetric.ec", + "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.asymmetric.ecgost", + "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.asymmetric.ecgost12", + "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.asymmetric.edec", + "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.asymmetric.elgamal", + "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.asymmetric.gost", + "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.asymmetric.ies", + "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.asymmetric.mldsa", + "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.asymmetric.mlkem", + "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.asymmetric.rsa", + "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.asymmetric.slhdsa", + "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.asymmetric.util", + "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.asymmetric.x509", + "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.config", + "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.digest", + "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.drbg", + "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.keystore", + "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.keystore.bc", + "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.keystore.bcfks", + "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.keystore.pkcs12", + "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.keystore.util", + "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.symmetric", + "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.symmetric.util", + "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.util", + "org.testcontainers.shaded.org.bouncycastle.jcajce.spec", + "org.testcontainers.shaded.org.bouncycastle.jcajce.util", + "org.testcontainers.shaded.org.bouncycastle.jce", + "org.testcontainers.shaded.org.bouncycastle.jce.exception", + "org.testcontainers.shaded.org.bouncycastle.jce.interfaces", + "org.testcontainers.shaded.org.bouncycastle.jce.netscape", + "org.testcontainers.shaded.org.bouncycastle.jce.provider", + "org.testcontainers.shaded.org.bouncycastle.jce.spec", + "org.testcontainers.shaded.org.bouncycastle.math", + "org.testcontainers.shaded.org.bouncycastle.math.ec", + "org.testcontainers.shaded.org.bouncycastle.math.ec.custom.djb", + "org.testcontainers.shaded.org.bouncycastle.math.ec.custom.gm", + "org.testcontainers.shaded.org.bouncycastle.math.ec.custom.sec", + "org.testcontainers.shaded.org.bouncycastle.math.ec.endo", + "org.testcontainers.shaded.org.bouncycastle.math.ec.rfc7748", + "org.testcontainers.shaded.org.bouncycastle.math.ec.rfc8032", + "org.testcontainers.shaded.org.bouncycastle.math.ec.tools", + "org.testcontainers.shaded.org.bouncycastle.math.field", + "org.testcontainers.shaded.org.bouncycastle.math.raw", + "org.testcontainers.shaded.org.bouncycastle.mime", + "org.testcontainers.shaded.org.bouncycastle.mime.encoding", + "org.testcontainers.shaded.org.bouncycastle.mime.smime", + "org.testcontainers.shaded.org.bouncycastle.mozilla", + "org.testcontainers.shaded.org.bouncycastle.mozilla.jcajce", + "org.testcontainers.shaded.org.bouncycastle.oer", + "org.testcontainers.shaded.org.bouncycastle.oer.its", + "org.testcontainers.shaded.org.bouncycastle.oer.its.etsi102941", + "org.testcontainers.shaded.org.bouncycastle.oer.its.etsi102941.basetypes", + "org.testcontainers.shaded.org.bouncycastle.oer.its.etsi103097", + "org.testcontainers.shaded.org.bouncycastle.oer.its.etsi103097.extension", + "org.testcontainers.shaded.org.bouncycastle.oer.its.ieee1609dot2", + "org.testcontainers.shaded.org.bouncycastle.oer.its.ieee1609dot2.basetypes", + "org.testcontainers.shaded.org.bouncycastle.oer.its.ieee1609dot2dot1", + "org.testcontainers.shaded.org.bouncycastle.oer.its.template.etsi102941", + "org.testcontainers.shaded.org.bouncycastle.oer.its.template.etsi102941.basetypes", + "org.testcontainers.shaded.org.bouncycastle.oer.its.template.etsi103097", + "org.testcontainers.shaded.org.bouncycastle.oer.its.template.etsi103097.extension", + "org.testcontainers.shaded.org.bouncycastle.oer.its.template.ieee1609dot2", + "org.testcontainers.shaded.org.bouncycastle.oer.its.template.ieee1609dot2.basetypes", + "org.testcontainers.shaded.org.bouncycastle.oer.its.template.ieee1609dot2dot1", + "org.testcontainers.shaded.org.bouncycastle.openssl", + "org.testcontainers.shaded.org.bouncycastle.openssl.bc", + "org.testcontainers.shaded.org.bouncycastle.openssl.jcajce", + "org.testcontainers.shaded.org.bouncycastle.operator", + "org.testcontainers.shaded.org.bouncycastle.operator.bc", + "org.testcontainers.shaded.org.bouncycastle.operator.jcajce", + "org.testcontainers.shaded.org.bouncycastle.pkcs", + "org.testcontainers.shaded.org.bouncycastle.pkcs.bc", + "org.testcontainers.shaded.org.bouncycastle.pkcs.jcajce", + "org.testcontainers.shaded.org.bouncycastle.pkix", + "org.testcontainers.shaded.org.bouncycastle.pkix.jcajce", + "org.testcontainers.shaded.org.bouncycastle.pkix.util", + "org.testcontainers.shaded.org.bouncycastle.pkix.util.filter", + "org.testcontainers.shaded.org.bouncycastle.pqc.asn1", + "org.testcontainers.shaded.org.bouncycastle.pqc.crypto", + "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.bike", + "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.cmce", + "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.crystals.dilithium", + "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.falcon", + "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.frodo", + "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.hqc", + "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.lms", + "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.mayo", + "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.mldsa", + "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.mlkem", + "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.newhope", + "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.ntru", + "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.ntruprime", + "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.picnic", + "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.rainbow", + "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.saber", + "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.slhdsa", + "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.snova", + "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.sphincs", + "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.sphincsplus", + "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.util", + "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.xmss", + "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.xwing", + "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.interfaces", + "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider", + "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider.bike", + "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider.cmce", + "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider.dilithium", + "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider.falcon", + "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider.frodo", + "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider.hqc", + "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider.kyber", + "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider.lms", + "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider.mayo", + "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider.newhope", + "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider.ntru", + "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider.ntruprime", + "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider.picnic", + "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider.saber", + "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider.snova", + "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider.sphincs", + "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider.sphincsplus", + "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider.util", + "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider.xmss", + "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.spec", + "org.testcontainers.shaded.org.bouncycastle.pqc.math.ntru", + "org.testcontainers.shaded.org.bouncycastle.pqc.math.ntru.parameters", + "org.testcontainers.shaded.org.bouncycastle.tsp", + "org.testcontainers.shaded.org.bouncycastle.tsp.cms", + "org.testcontainers.shaded.org.bouncycastle.tsp.ers", + "org.testcontainers.shaded.org.bouncycastle.util", + "org.testcontainers.shaded.org.bouncycastle.util.encoders", + "org.testcontainers.shaded.org.bouncycastle.util.io", + "org.testcontainers.shaded.org.bouncycastle.util.io.pem", + "org.testcontainers.shaded.org.bouncycastle.util.test", + "org.testcontainers.shaded.org.bouncycastle.voms", + "org.testcontainers.shaded.org.bouncycastle.x509", + "org.testcontainers.shaded.org.bouncycastle.x509.extension", + "org.testcontainers.shaded.org.bouncycastle.x509.util", + "org.testcontainers.shaded.org.checkerframework.checker.builder.qual", + "org.testcontainers.shaded.org.checkerframework.checker.calledmethods.qual", + "org.testcontainers.shaded.org.checkerframework.checker.compilermsgs.qual", + "org.testcontainers.shaded.org.checkerframework.checker.fenum.qual", + "org.testcontainers.shaded.org.checkerframework.checker.formatter.qual", + "org.testcontainers.shaded.org.checkerframework.checker.guieffect.qual", + "org.testcontainers.shaded.org.checkerframework.checker.i18n.qual", + "org.testcontainers.shaded.org.checkerframework.checker.i18nformatter.qual", + "org.testcontainers.shaded.org.checkerframework.checker.index.qual", + "org.testcontainers.shaded.org.checkerframework.checker.initialization.qual", + "org.testcontainers.shaded.org.checkerframework.checker.interning.qual", + "org.testcontainers.shaded.org.checkerframework.checker.lock.qual", + "org.testcontainers.shaded.org.checkerframework.checker.mustcall.qual", + "org.testcontainers.shaded.org.checkerframework.checker.nullness.qual", + "org.testcontainers.shaded.org.checkerframework.checker.optional.qual", + "org.testcontainers.shaded.org.checkerframework.checker.propkey.qual", + "org.testcontainers.shaded.org.checkerframework.checker.regex.qual", + "org.testcontainers.shaded.org.checkerframework.checker.signature.qual", + "org.testcontainers.shaded.org.checkerframework.checker.signedness.qual", + "org.testcontainers.shaded.org.checkerframework.checker.tainting.qual", + "org.testcontainers.shaded.org.checkerframework.checker.units.qual", + "org.testcontainers.shaded.org.checkerframework.common.aliasing.qual", + "org.testcontainers.shaded.org.checkerframework.common.initializedfields.qual", + "org.testcontainers.shaded.org.checkerframework.common.reflection.qual", + "org.testcontainers.shaded.org.checkerframework.common.returnsreceiver.qual", + "org.testcontainers.shaded.org.checkerframework.common.subtyping.qual", + "org.testcontainers.shaded.org.checkerframework.common.util.count.report.qual", + "org.testcontainers.shaded.org.checkerframework.common.value.qual", + "org.testcontainers.shaded.org.checkerframework.dataflow.qual", + "org.testcontainers.shaded.org.checkerframework.framework.qual", + "org.testcontainers.shaded.org.hamcrest", + "org.testcontainers.shaded.org.hamcrest.beans", + "org.testcontainers.shaded.org.hamcrest.collection", + "org.testcontainers.shaded.org.hamcrest.comparator", + "org.testcontainers.shaded.org.hamcrest.core", + "org.testcontainers.shaded.org.hamcrest.internal", + "org.testcontainers.shaded.org.hamcrest.io", + "org.testcontainers.shaded.org.hamcrest.number", + "org.testcontainers.shaded.org.hamcrest.object", + "org.testcontainers.shaded.org.hamcrest.text", + "org.testcontainers.shaded.org.hamcrest.xml", + "org.testcontainers.shaded.org.yaml.snakeyaml", + "org.testcontainers.shaded.org.yaml.snakeyaml.comments", + "org.testcontainers.shaded.org.yaml.snakeyaml.composer", + "org.testcontainers.shaded.org.yaml.snakeyaml.constructor", + "org.testcontainers.shaded.org.yaml.snakeyaml.emitter", + "org.testcontainers.shaded.org.yaml.snakeyaml.env", + "org.testcontainers.shaded.org.yaml.snakeyaml.error", + "org.testcontainers.shaded.org.yaml.snakeyaml.events", + "org.testcontainers.shaded.org.yaml.snakeyaml.extensions.compactnotation", + "org.testcontainers.shaded.org.yaml.snakeyaml.external.com.google.gdata.util.common.base", + "org.testcontainers.shaded.org.yaml.snakeyaml.inspector", + "org.testcontainers.shaded.org.yaml.snakeyaml.internal", + "org.testcontainers.shaded.org.yaml.snakeyaml.introspector", + "org.testcontainers.shaded.org.yaml.snakeyaml.nodes", + "org.testcontainers.shaded.org.yaml.snakeyaml.parser", + "org.testcontainers.shaded.org.yaml.snakeyaml.reader", + "org.testcontainers.shaded.org.yaml.snakeyaml.representer", + "org.testcontainers.shaded.org.yaml.snakeyaml.resolver", + "org.testcontainers.shaded.org.yaml.snakeyaml.scanner", + "org.testcontainers.shaded.org.yaml.snakeyaml.serializer", + "org.testcontainers.shaded.org.yaml.snakeyaml.tokens", + "org.testcontainers.shaded.org.yaml.snakeyaml.util", + "org.testcontainers.shaded.org.zeroturnaround.exec", + "org.testcontainers.shaded.org.zeroturnaround.exec.close", + "org.testcontainers.shaded.org.zeroturnaround.exec.listener", + "org.testcontainers.shaded.org.zeroturnaround.exec.stop", + "org.testcontainers.shaded.org.zeroturnaround.exec.stream", + "org.testcontainers.shaded.org.zeroturnaround.exec.stream.slf4j", + "org.testcontainers.utility" + ], + "org.testcontainers:testcontainers-cassandra": [ + "org.testcontainers.cassandra", + "org.testcontainers.containers", + "org.testcontainers.containers.delegate", + "org.testcontainers.containers.wait" + ], + "org.testcontainers:testcontainers-database-commons": [ + "org.testcontainers.delegate", + "org.testcontainers.exception", + "org.testcontainers.ext" + ], + "org.testcontainers:testcontainers-junit-jupiter": [ + "org.testcontainers.junit.jupiter" + ], + "org.wiremock:wiremock-standalone": [ + "com.github.tomakehurst.wiremock", + "com.github.tomakehurst.wiremock.admin", + "com.github.tomakehurst.wiremock.admin.model", + "com.github.tomakehurst.wiremock.admin.tasks", + "com.github.tomakehurst.wiremock.client", + "com.github.tomakehurst.wiremock.common", + "com.github.tomakehurst.wiremock.common.filemaker", + "com.github.tomakehurst.wiremock.common.ssl", + "com.github.tomakehurst.wiremock.common.url", + "com.github.tomakehurst.wiremock.common.xml", + "com.github.tomakehurst.wiremock.core", + "com.github.tomakehurst.wiremock.direct", + "com.github.tomakehurst.wiremock.extension", + "com.github.tomakehurst.wiremock.extension.requestfilter", + "com.github.tomakehurst.wiremock.extension.responsetemplating", + "com.github.tomakehurst.wiremock.extension.responsetemplating.helpers", + "com.github.tomakehurst.wiremock.global", + "com.github.tomakehurst.wiremock.http", + "com.github.tomakehurst.wiremock.http.client", + "com.github.tomakehurst.wiremock.http.multipart", + "com.github.tomakehurst.wiremock.http.ssl", + "com.github.tomakehurst.wiremock.http.trafficlistener", + "com.github.tomakehurst.wiremock.jetty", + "com.github.tomakehurst.wiremock.jetty11", + "com.github.tomakehurst.wiremock.junit", + "com.github.tomakehurst.wiremock.junit5", + "com.github.tomakehurst.wiremock.matching", + "com.github.tomakehurst.wiremock.recording", + "com.github.tomakehurst.wiremock.security", + "com.github.tomakehurst.wiremock.servlet", + "com.github.tomakehurst.wiremock.standalone", + "com.github.tomakehurst.wiremock.store", + "com.github.tomakehurst.wiremock.store.files", + "com.github.tomakehurst.wiremock.stubbing", + "com.github.tomakehurst.wiremock.verification", + "com.github.tomakehurst.wiremock.verification.diff", + "com.github.tomakehurst.wiremock.verification.notmatched", + "org.jspecify.annotations", + "org.wiremock.annotations", + "org.wiremock.webhooks", + "wiremock", + "wiremock.com.ethlo.time", + "wiremock.com.ethlo.time.internal", + "wiremock.com.ethlo.time.internal.fixed", + "wiremock.com.ethlo.time.internal.token", + "wiremock.com.ethlo.time.internal.util", + "wiremock.com.ethlo.time.token", + "wiremock.com.fasterxml.jackson.annotation", + "wiremock.com.fasterxml.jackson.core", + "wiremock.com.fasterxml.jackson.core.async", + "wiremock.com.fasterxml.jackson.core.base", + "wiremock.com.fasterxml.jackson.core.exc", + "wiremock.com.fasterxml.jackson.core.filter", + "wiremock.com.fasterxml.jackson.core.format", + "wiremock.com.fasterxml.jackson.core.internal.shaded.fdp.v2_20_1", + "wiremock.com.fasterxml.jackson.core.internal.shaded.fdp.v2_20_1.bte", + "wiremock.com.fasterxml.jackson.core.internal.shaded.fdp.v2_20_1.chr", + "wiremock.com.fasterxml.jackson.core.io", + "wiremock.com.fasterxml.jackson.core.io.schubfach", + "wiremock.com.fasterxml.jackson.core.json", + "wiremock.com.fasterxml.jackson.core.json.async", + "wiremock.com.fasterxml.jackson.core.sym", + "wiremock.com.fasterxml.jackson.core.type", + "wiremock.com.fasterxml.jackson.core.util", + "wiremock.com.fasterxml.jackson.databind", + "wiremock.com.fasterxml.jackson.databind.annotation", + "wiremock.com.fasterxml.jackson.databind.cfg", + "wiremock.com.fasterxml.jackson.databind.deser", + "wiremock.com.fasterxml.jackson.databind.deser.impl", + "wiremock.com.fasterxml.jackson.databind.deser.std", + "wiremock.com.fasterxml.jackson.databind.exc", + "wiremock.com.fasterxml.jackson.databind.ext", + "wiremock.com.fasterxml.jackson.databind.introspect", + "wiremock.com.fasterxml.jackson.databind.jdk14", + "wiremock.com.fasterxml.jackson.databind.json", + "wiremock.com.fasterxml.jackson.databind.jsonFormatVisitors", + "wiremock.com.fasterxml.jackson.databind.jsonschema", + "wiremock.com.fasterxml.jackson.databind.jsontype", + "wiremock.com.fasterxml.jackson.databind.jsontype.impl", + "wiremock.com.fasterxml.jackson.databind.module", + "wiremock.com.fasterxml.jackson.databind.node", + "wiremock.com.fasterxml.jackson.databind.ser", + "wiremock.com.fasterxml.jackson.databind.ser.impl", + "wiremock.com.fasterxml.jackson.databind.ser.std", + "wiremock.com.fasterxml.jackson.databind.type", + "wiremock.com.fasterxml.jackson.databind.util", + "wiremock.com.fasterxml.jackson.databind.util.internal", + "wiremock.com.fasterxml.jackson.dataformat.yaml", + "wiremock.com.fasterxml.jackson.dataformat.yaml.snakeyaml.error", + "wiremock.com.fasterxml.jackson.dataformat.yaml.util", + "wiremock.com.fasterxml.jackson.datatype.jsr310", + "wiremock.com.fasterxml.jackson.datatype.jsr310.deser", + "wiremock.com.fasterxml.jackson.datatype.jsr310.deser.key", + "wiremock.com.fasterxml.jackson.datatype.jsr310.ser", + "wiremock.com.fasterxml.jackson.datatype.jsr310.ser.key", + "wiremock.com.fasterxml.jackson.datatype.jsr310.util", + "wiremock.com.github.jknack.handlebars", + "wiremock.com.github.jknack.handlebars.cache", + "wiremock.com.github.jknack.handlebars.context", + "wiremock.com.github.jknack.handlebars.helper", + "wiremock.com.github.jknack.handlebars.internal", + "wiremock.com.github.jknack.handlebars.internal.antlr", + "wiremock.com.github.jknack.handlebars.internal.antlr.atn", + "wiremock.com.github.jknack.handlebars.internal.antlr.dfa", + "wiremock.com.github.jknack.handlebars.internal.antlr.misc", + "wiremock.com.github.jknack.handlebars.internal.antlr.tree", + "wiremock.com.github.jknack.handlebars.internal.antlr.tree.pattern", + "wiremock.com.github.jknack.handlebars.internal.antlr.tree.xpath", + "wiremock.com.github.jknack.handlebars.internal.lang3", + "wiremock.com.github.jknack.handlebars.internal.lang3.builder", + "wiremock.com.github.jknack.handlebars.internal.lang3.exception", + "wiremock.com.github.jknack.handlebars.internal.lang3.function", + "wiremock.com.github.jknack.handlebars.internal.lang3.math", + "wiremock.com.github.jknack.handlebars.internal.lang3.mutable", + "wiremock.com.github.jknack.handlebars.internal.lang3.text", + "wiremock.com.github.jknack.handlebars.internal.lang3.text.translate", + "wiremock.com.github.jknack.handlebars.internal.lang3.time", + "wiremock.com.github.jknack.handlebars.internal.lang3.tuple", + "wiremock.com.github.jknack.handlebars.internal.path", + "wiremock.com.github.jknack.handlebars.internal.text", + "wiremock.com.github.jknack.handlebars.internal.text.diff", + "wiremock.com.github.jknack.handlebars.internal.text.io", + "wiremock.com.github.jknack.handlebars.internal.text.lookup", + "wiremock.com.github.jknack.handlebars.internal.text.matcher", + "wiremock.com.github.jknack.handlebars.internal.text.numbers", + "wiremock.com.github.jknack.handlebars.internal.text.similarity", + "wiremock.com.github.jknack.handlebars.internal.text.translate", + "wiremock.com.github.jknack.handlebars.io", + "wiremock.com.google.common.annotations", + "wiremock.com.google.common.base", + "wiremock.com.google.common.base.internal", + "wiremock.com.google.common.cache", + "wiremock.com.google.common.collect", + "wiremock.com.google.common.escape", + "wiremock.com.google.common.eventbus", + "wiremock.com.google.common.graph", + "wiremock.com.google.common.hash", + "wiremock.com.google.common.html", + "wiremock.com.google.common.io", + "wiremock.com.google.common.math", + "wiremock.com.google.common.net", + "wiremock.com.google.common.primitives", + "wiremock.com.google.common.reflect", + "wiremock.com.google.common.util.concurrent", + "wiremock.com.google.common.util.concurrent.internal", + "wiremock.com.google.common.xml", + "wiremock.com.google.errorprone.annotations", + "wiremock.com.google.errorprone.annotations.concurrent", + "wiremock.com.google.j2objc.annotations", + "wiremock.com.google.thirdparty.publicsuffix", + "wiremock.com.jayway.jsonpath", + "wiremock.com.jayway.jsonpath.internal", + "wiremock.com.jayway.jsonpath.internal.filter", + "wiremock.com.jayway.jsonpath.internal.function", + "wiremock.com.jayway.jsonpath.internal.function.json", + "wiremock.com.jayway.jsonpath.internal.function.latebinding", + "wiremock.com.jayway.jsonpath.internal.function.numeric", + "wiremock.com.jayway.jsonpath.internal.function.sequence", + "wiremock.com.jayway.jsonpath.internal.function.text", + "wiremock.com.jayway.jsonpath.internal.path", + "wiremock.com.jayway.jsonpath.spi.cache", + "wiremock.com.jayway.jsonpath.spi.json", + "wiremock.com.jayway.jsonpath.spi.mapper", + "wiremock.com.networknt.org.apache.commons.validator.routines", + "wiremock.com.networknt.schema", + "wiremock.com.networknt.schema.annotation", + "wiremock.com.networknt.schema.format", + "wiremock.com.networknt.schema.i18n", + "wiremock.com.networknt.schema.oas", + "wiremock.com.networknt.schema.output", + "wiremock.com.networknt.schema.regex", + "wiremock.com.networknt.schema.resource", + "wiremock.com.networknt.schema.result", + "wiremock.com.networknt.schema.serialization", + "wiremock.com.networknt.schema.serialization.node", + "wiremock.com.networknt.schema.utils", + "wiremock.com.networknt.schema.walk", + "wiremock.jakarta.servlet", + "wiremock.jakarta.servlet.annotation", + "wiremock.jakarta.servlet.descriptor", + "wiremock.jakarta.servlet.http", + "wiremock.joptsimple", + "wiremock.joptsimple.internal", + "wiremock.joptsimple.util", + "wiremock.net.javacrumbs.jsonunit.core", + "wiremock.net.javacrumbs.jsonunit.core.internal", + "wiremock.net.javacrumbs.jsonunit.core.internal.matchers", + "wiremock.net.javacrumbs.jsonunit.core.listener", + "wiremock.net.javacrumbs.jsonunit.core.util", + "wiremock.net.javacrumbs.jsonunit.providers", + "wiremock.net.minidev.asm", + "wiremock.net.minidev.asm.ex", + "wiremock.net.minidev.json", + "wiremock.net.minidev.json.annotate", + "wiremock.net.minidev.json.parser", + "wiremock.net.minidev.json.reader", + "wiremock.net.minidev.json.writer", + "wiremock.org.apache.commons.fileupload", + "wiremock.org.apache.commons.fileupload.disk", + "wiremock.org.apache.commons.fileupload.portlet", + "wiremock.org.apache.commons.fileupload.servlet", + "wiremock.org.apache.commons.fileupload.util", + "wiremock.org.apache.commons.fileupload.util.mime", + "wiremock.org.apache.commons.io", + "wiremock.org.apache.commons.io.build", + "wiremock.org.apache.commons.io.channels", + "wiremock.org.apache.commons.io.charset", + "wiremock.org.apache.commons.io.comparator", + "wiremock.org.apache.commons.io.file", + "wiremock.org.apache.commons.io.file.attribute", + "wiremock.org.apache.commons.io.file.spi", + "wiremock.org.apache.commons.io.filefilter", + "wiremock.org.apache.commons.io.function", + "wiremock.org.apache.commons.io.input", + "wiremock.org.apache.commons.io.input.buffer", + "wiremock.org.apache.commons.io.monitor", + "wiremock.org.apache.commons.io.output", + "wiremock.org.apache.commons.io.serialization", + "wiremock.org.apache.hc.client5.http", + "wiremock.org.apache.hc.client5.http.async", + "wiremock.org.apache.hc.client5.http.async.methods", + "wiremock.org.apache.hc.client5.http.auth", + "wiremock.org.apache.hc.client5.http.classic", + "wiremock.org.apache.hc.client5.http.classic.methods", + "wiremock.org.apache.hc.client5.http.config", + "wiremock.org.apache.hc.client5.http.cookie", + "wiremock.org.apache.hc.client5.http.entity", + "wiremock.org.apache.hc.client5.http.entity.mime", + "wiremock.org.apache.hc.client5.http.impl", + "wiremock.org.apache.hc.client5.http.impl.async", + "wiremock.org.apache.hc.client5.http.impl.auth", + "wiremock.org.apache.hc.client5.http.impl.classic", + "wiremock.org.apache.hc.client5.http.impl.compat", + "wiremock.org.apache.hc.client5.http.impl.cookie", + "wiremock.org.apache.hc.client5.http.impl.io", + "wiremock.org.apache.hc.client5.http.impl.nio", + "wiremock.org.apache.hc.client5.http.impl.routing", + "wiremock.org.apache.hc.client5.http.io", + "wiremock.org.apache.hc.client5.http.nio", + "wiremock.org.apache.hc.client5.http.protocol", + "wiremock.org.apache.hc.client5.http.psl", + "wiremock.org.apache.hc.client5.http.routing", + "wiremock.org.apache.hc.client5.http.socket", + "wiremock.org.apache.hc.client5.http.ssl", + "wiremock.org.apache.hc.client5.http.utils", + "wiremock.org.apache.hc.client5.http.validator", + "wiremock.org.apache.hc.core5.annotation", + "wiremock.org.apache.hc.core5.concurrent", + "wiremock.org.apache.hc.core5.function", + "wiremock.org.apache.hc.core5.http", + "wiremock.org.apache.hc.core5.http.config", + "wiremock.org.apache.hc.core5.http.impl", + "wiremock.org.apache.hc.core5.http.impl.bootstrap", + "wiremock.org.apache.hc.core5.http.impl.io", + "wiremock.org.apache.hc.core5.http.impl.nio", + "wiremock.org.apache.hc.core5.http.impl.routing", + "wiremock.org.apache.hc.core5.http.io", + "wiremock.org.apache.hc.core5.http.io.entity", + "wiremock.org.apache.hc.core5.http.io.ssl", + "wiremock.org.apache.hc.core5.http.io.support", + "wiremock.org.apache.hc.core5.http.message", + "wiremock.org.apache.hc.core5.http.nio", + "wiremock.org.apache.hc.core5.http.nio.command", + "wiremock.org.apache.hc.core5.http.nio.entity", + "wiremock.org.apache.hc.core5.http.nio.ssl", + "wiremock.org.apache.hc.core5.http.nio.support", + "wiremock.org.apache.hc.core5.http.nio.support.classic", + "wiremock.org.apache.hc.core5.http.protocol", + "wiremock.org.apache.hc.core5.http.ssl", + "wiremock.org.apache.hc.core5.http.support", + "wiremock.org.apache.hc.core5.http2", + "wiremock.org.apache.hc.core5.http2.config", + "wiremock.org.apache.hc.core5.http2.frame", + "wiremock.org.apache.hc.core5.http2.hpack", + "wiremock.org.apache.hc.core5.http2.impl", + "wiremock.org.apache.hc.core5.http2.impl.io", + "wiremock.org.apache.hc.core5.http2.impl.nio", + "wiremock.org.apache.hc.core5.http2.impl.nio.bootstrap", + "wiremock.org.apache.hc.core5.http2.nio", + "wiremock.org.apache.hc.core5.http2.nio.command", + "wiremock.org.apache.hc.core5.http2.nio.pool", + "wiremock.org.apache.hc.core5.http2.nio.support", + "wiremock.org.apache.hc.core5.http2.protocol", + "wiremock.org.apache.hc.core5.http2.ssl", + "wiremock.org.apache.hc.core5.io", + "wiremock.org.apache.hc.core5.net", + "wiremock.org.apache.hc.core5.pool", + "wiremock.org.apache.hc.core5.reactor", + "wiremock.org.apache.hc.core5.reactor.ssl", + "wiremock.org.apache.hc.core5.ssl", + "wiremock.org.apache.hc.core5.util", + "wiremock.org.custommonkey.xmlunit", + "wiremock.org.custommonkey.xmlunit.examples", + "wiremock.org.custommonkey.xmlunit.exceptions", + "wiremock.org.custommonkey.xmlunit.jaxp13", + "wiremock.org.custommonkey.xmlunit.util", + "wiremock.org.eclipse.jetty.alpn.client", + "wiremock.org.eclipse.jetty.alpn.java.client", + "wiremock.org.eclipse.jetty.alpn.java.server", + "wiremock.org.eclipse.jetty.alpn.server", + "wiremock.org.eclipse.jetty.client", + "wiremock.org.eclipse.jetty.client.api", + "wiremock.org.eclipse.jetty.client.dynamic", + "wiremock.org.eclipse.jetty.client.http", + "wiremock.org.eclipse.jetty.client.internal", + "wiremock.org.eclipse.jetty.client.jmx", + "wiremock.org.eclipse.jetty.client.util", + "wiremock.org.eclipse.jetty.http", + "wiremock.org.eclipse.jetty.http.compression", + "wiremock.org.eclipse.jetty.http.pathmap", + "wiremock.org.eclipse.jetty.http2", + "wiremock.org.eclipse.jetty.http2.api", + "wiremock.org.eclipse.jetty.http2.api.server", + "wiremock.org.eclipse.jetty.http2.frames", + "wiremock.org.eclipse.jetty.http2.generator", + "wiremock.org.eclipse.jetty.http2.hpack", + "wiremock.org.eclipse.jetty.http2.parser", + "wiremock.org.eclipse.jetty.http2.server", + "wiremock.org.eclipse.jetty.io", + "wiremock.org.eclipse.jetty.io.jmx", + "wiremock.org.eclipse.jetty.io.ssl", + "wiremock.org.eclipse.jetty.proxy", + "wiremock.org.eclipse.jetty.security", + "wiremock.org.eclipse.jetty.security.authentication", + "wiremock.org.eclipse.jetty.server", + "wiremock.org.eclipse.jetty.server.handler", + "wiremock.org.eclipse.jetty.server.handler.gzip", + "wiremock.org.eclipse.jetty.server.handler.jmx", + "wiremock.org.eclipse.jetty.server.jmx", + "wiremock.org.eclipse.jetty.server.resource", + "wiremock.org.eclipse.jetty.server.session", + "wiremock.org.eclipse.jetty.servlet", + "wiremock.org.eclipse.jetty.servlet.jmx", + "wiremock.org.eclipse.jetty.servlet.listener", + "wiremock.org.eclipse.jetty.servlets", + "wiremock.org.eclipse.jetty.util", + "wiremock.org.eclipse.jetty.util.annotation", + "wiremock.org.eclipse.jetty.util.component", + "wiremock.org.eclipse.jetty.util.compression", + "wiremock.org.eclipse.jetty.util.log", + "wiremock.org.eclipse.jetty.util.preventers", + "wiremock.org.eclipse.jetty.util.resource", + "wiremock.org.eclipse.jetty.util.security", + "wiremock.org.eclipse.jetty.util.ssl", + "wiremock.org.eclipse.jetty.util.statistic", + "wiremock.org.eclipse.jetty.util.thread", + "wiremock.org.eclipse.jetty.util.thread.strategy", + "wiremock.org.eclipse.jetty.webapp", + "wiremock.org.eclipse.jetty.xml", + "wiremock.org.hamcrest", + "wiremock.org.hamcrest.beans", + "wiremock.org.hamcrest.collection", + "wiremock.org.hamcrest.comparator", + "wiremock.org.hamcrest.core", + "wiremock.org.hamcrest.core.deprecated", + "wiremock.org.hamcrest.internal", + "wiremock.org.hamcrest.io", + "wiremock.org.hamcrest.number", + "wiremock.org.hamcrest.object", + "wiremock.org.hamcrest.text", + "wiremock.org.hamcrest.xml", + "wiremock.org.slf4j", + "wiremock.org.slf4j.event", + "wiremock.org.slf4j.helpers", + "wiremock.org.slf4j.spi", + "wiremock.org.xmlunit", + "wiremock.org.xmlunit.builder", + "wiremock.org.xmlunit.builder.javax_jaxb", + "wiremock.org.xmlunit.diff", + "wiremock.org.xmlunit.input", + "wiremock.org.xmlunit.placeholder", + "wiremock.org.xmlunit.transform", + "wiremock.org.xmlunit.util", + "wiremock.org.xmlunit.validation", + "wiremock.org.xmlunit.xpath", + "wiremock.org.yaml.snakeyaml", + "wiremock.org.yaml.snakeyaml.comments", + "wiremock.org.yaml.snakeyaml.composer", + "wiremock.org.yaml.snakeyaml.constructor", + "wiremock.org.yaml.snakeyaml.emitter", + "wiremock.org.yaml.snakeyaml.env", + "wiremock.org.yaml.snakeyaml.error", + "wiremock.org.yaml.snakeyaml.events", + "wiremock.org.yaml.snakeyaml.extensions.compactnotation", + "wiremock.org.yaml.snakeyaml.external.com.google.gdata.util.common.base", + "wiremock.org.yaml.snakeyaml.inspector", + "wiremock.org.yaml.snakeyaml.internal", + "wiremock.org.yaml.snakeyaml.introspector", + "wiremock.org.yaml.snakeyaml.nodes", + "wiremock.org.yaml.snakeyaml.parser", + "wiremock.org.yaml.snakeyaml.reader", + "wiremock.org.yaml.snakeyaml.representer", + "wiremock.org.yaml.snakeyaml.resolver", + "wiremock.org.yaml.snakeyaml.scanner", + "wiremock.org.yaml.snakeyaml.serializer", + "wiremock.org.yaml.snakeyaml.tokens", + "wiremock.org.yaml.snakeyaml.util" + ], + "org.xmlunit:xmlunit-core": [ + "org.xmlunit", + "org.xmlunit.builder", + "org.xmlunit.builder.javax_jaxb", + "org.xmlunit.diff", + "org.xmlunit.input", + "org.xmlunit.transform", + "org.xmlunit.util", + "org.xmlunit.validation", + "org.xmlunit.xpath" + ], + "org.yaml:snakeyaml": [ + "org.yaml.snakeyaml", + "org.yaml.snakeyaml.comments", + "org.yaml.snakeyaml.composer", + "org.yaml.snakeyaml.constructor", + "org.yaml.snakeyaml.emitter", + "org.yaml.snakeyaml.env", + "org.yaml.snakeyaml.error", + "org.yaml.snakeyaml.events", + "org.yaml.snakeyaml.extensions.compactnotation", + "org.yaml.snakeyaml.external.com.google.gdata.util.common.base", + "org.yaml.snakeyaml.inspector", + "org.yaml.snakeyaml.internal", + "org.yaml.snakeyaml.introspector", + "org.yaml.snakeyaml.nodes", + "org.yaml.snakeyaml.parser", + "org.yaml.snakeyaml.reader", + "org.yaml.snakeyaml.representer", + "org.yaml.snakeyaml.resolver", + "org.yaml.snakeyaml.scanner", + "org.yaml.snakeyaml.serializer", + "org.yaml.snakeyaml.tokens", + "org.yaml.snakeyaml.util" + ], + "software.amazon.awssdk:annotations": [ + "software.amazon.awssdk.annotations" + ], + "software.amazon.awssdk:checksums": [ + "software.amazon.awssdk.checksums", + "software.amazon.awssdk.checksums.internal" + ], + "software.amazon.awssdk:checksums-spi": [ + "software.amazon.awssdk.checksums.spi" + ], + "software.amazon.awssdk:endpoints-spi": [ + "software.amazon.awssdk.endpoints" + ], + "software.amazon.awssdk:http-auth-aws": [ + "software.amazon.awssdk.http.auth.aws.crt.internal.io", + "software.amazon.awssdk.http.auth.aws.crt.internal.signer", + "software.amazon.awssdk.http.auth.aws.crt.internal.util", + "software.amazon.awssdk.http.auth.aws.eventstream.internal.io", + "software.amazon.awssdk.http.auth.aws.eventstream.internal.signer", + "software.amazon.awssdk.http.auth.aws.internal.scheme", + "software.amazon.awssdk.http.auth.aws.internal.signer", + "software.amazon.awssdk.http.auth.aws.internal.signer.checksums", + "software.amazon.awssdk.http.auth.aws.internal.signer.chunkedencoding", + "software.amazon.awssdk.http.auth.aws.internal.signer.io", + "software.amazon.awssdk.http.auth.aws.internal.signer.util", + "software.amazon.awssdk.http.auth.aws.scheme", + "software.amazon.awssdk.http.auth.aws.signer" + ], + "software.amazon.awssdk:http-auth-spi": [ + "software.amazon.awssdk.http.auth.spi.internal.scheme", + "software.amazon.awssdk.http.auth.spi.internal.signer", + "software.amazon.awssdk.http.auth.spi.scheme", + "software.amazon.awssdk.http.auth.spi.signer" + ], + "software.amazon.awssdk:http-client-spi": [ + "software.amazon.awssdk.http", + "software.amazon.awssdk.http.async", + "software.amazon.awssdk.internal.http" + ], + "software.amazon.awssdk:identity-spi": [ + "software.amazon.awssdk.identity.spi", + "software.amazon.awssdk.identity.spi.internal" + ], + "software.amazon.awssdk:json-utils": [ + "software.amazon.awssdk.protocols.jsoncore", + "software.amazon.awssdk.protocols.jsoncore.internal" + ], + "software.amazon.awssdk:metrics-spi": [ + "software.amazon.awssdk.metrics", + "software.amazon.awssdk.metrics.internal" + ], + "software.amazon.awssdk:profiles": [ + "software.amazon.awssdk.profiles", + "software.amazon.awssdk.profiles.internal" + ], + "software.amazon.awssdk:regions": [ + "software.amazon.awssdk.regions", + "software.amazon.awssdk.regions.internal", + "software.amazon.awssdk.regions.internal.util", + "software.amazon.awssdk.regions.partitionmetadata", + "software.amazon.awssdk.regions.providers", + "software.amazon.awssdk.regions.regionmetadata", + "software.amazon.awssdk.regions.servicemetadata", + "software.amazon.awssdk.regions.util" + ], + "software.amazon.awssdk:retries": [ + "software.amazon.awssdk.retries", + "software.amazon.awssdk.retries.internal", + "software.amazon.awssdk.retries.internal.circuitbreaker", + "software.amazon.awssdk.retries.internal.ratelimiter" + ], + "software.amazon.awssdk:retries-spi": [ + "software.amazon.awssdk.retries.api", + "software.amazon.awssdk.retries.api.internal", + "software.amazon.awssdk.retries.api.internal.backoff" + ], + "software.amazon.awssdk:sdk-core": [ + "software.amazon.awssdk.core", + "software.amazon.awssdk.core.adapter", + "software.amazon.awssdk.core.async", + "software.amazon.awssdk.core.async.listener", + "software.amazon.awssdk.core.checksums", + "software.amazon.awssdk.core.client.builder", + "software.amazon.awssdk.core.client.config", + "software.amazon.awssdk.core.client.handler", + "software.amazon.awssdk.core.document", + "software.amazon.awssdk.core.document.internal", + "software.amazon.awssdk.core.endpointdiscovery", + "software.amazon.awssdk.core.endpointdiscovery.providers", + "software.amazon.awssdk.core.exception", + "software.amazon.awssdk.core.http", + "software.amazon.awssdk.core.identity", + "software.amazon.awssdk.core.interceptor", + "software.amazon.awssdk.core.interceptor.trait", + "software.amazon.awssdk.core.internal", + "software.amazon.awssdk.core.internal.async", + "software.amazon.awssdk.core.internal.capacity", + "software.amazon.awssdk.core.internal.checksums", + "software.amazon.awssdk.core.internal.chunked", + "software.amazon.awssdk.core.internal.compression", + "software.amazon.awssdk.core.internal.handler", + "software.amazon.awssdk.core.internal.http", + "software.amazon.awssdk.core.internal.http.async", + "software.amazon.awssdk.core.internal.http.loader", + "software.amazon.awssdk.core.internal.http.pipeline", + "software.amazon.awssdk.core.internal.http.pipeline.stages", + "software.amazon.awssdk.core.internal.http.pipeline.stages.utils", + "software.amazon.awssdk.core.internal.http.timers", + "software.amazon.awssdk.core.internal.interceptor", + "software.amazon.awssdk.core.internal.interceptor.trait", + "software.amazon.awssdk.core.internal.io", + "software.amazon.awssdk.core.internal.metrics", + "software.amazon.awssdk.core.internal.pagination.async", + "software.amazon.awssdk.core.internal.retry", + "software.amazon.awssdk.core.internal.signer", + "software.amazon.awssdk.core.internal.sync", + "software.amazon.awssdk.core.internal.transform", + "software.amazon.awssdk.core.internal.useragent", + "software.amazon.awssdk.core.internal.util", + "software.amazon.awssdk.core.internal.waiters", + "software.amazon.awssdk.core.io", + "software.amazon.awssdk.core.metrics", + "software.amazon.awssdk.core.pagination.async", + "software.amazon.awssdk.core.pagination.sync", + "software.amazon.awssdk.core.protocol", + "software.amazon.awssdk.core.retry", + "software.amazon.awssdk.core.retry.backoff", + "software.amazon.awssdk.core.retry.conditions", + "software.amazon.awssdk.core.runtime", + "software.amazon.awssdk.core.runtime.transform", + "software.amazon.awssdk.core.signer", + "software.amazon.awssdk.core.sync", + "software.amazon.awssdk.core.traits", + "software.amazon.awssdk.core.useragent", + "software.amazon.awssdk.core.util", + "software.amazon.awssdk.core.waiters" + ], + "software.amazon.awssdk:third-party-jackson-core": [ + "software.amazon.awssdk.thirdparty.jackson.core", + "software.amazon.awssdk.thirdparty.jackson.core.async", + "software.amazon.awssdk.thirdparty.jackson.core.base", + "software.amazon.awssdk.thirdparty.jackson.core.exc", + "software.amazon.awssdk.thirdparty.jackson.core.filter", + "software.amazon.awssdk.thirdparty.jackson.core.format", + "software.amazon.awssdk.thirdparty.jackson.core.internal.shaded.fdp.v2_19_4", + "software.amazon.awssdk.thirdparty.jackson.core.io", + "software.amazon.awssdk.thirdparty.jackson.core.io.schubfach", + "software.amazon.awssdk.thirdparty.jackson.core.json", + "software.amazon.awssdk.thirdparty.jackson.core.json.async", + "software.amazon.awssdk.thirdparty.jackson.core.sym", + "software.amazon.awssdk.thirdparty.jackson.core.type", + "software.amazon.awssdk.thirdparty.jackson.core.util" + ], + "software.amazon.awssdk:utils": [ + "software.amazon.awssdk.utils", + "software.amazon.awssdk.utils.async", + "software.amazon.awssdk.utils.builder", + "software.amazon.awssdk.utils.cache", + "software.amazon.awssdk.utils.cache.bounded", + "software.amazon.awssdk.utils.cache.lru", + "software.amazon.awssdk.utils.http", + "software.amazon.awssdk.utils.internal", + "software.amazon.awssdk.utils.internal.async", + "software.amazon.awssdk.utils.internal.proxy", + "software.amazon.awssdk.utils.io", + "software.amazon.awssdk.utils.uri", + "software.amazon.awssdk.utils.uri.internal" + ], + "tools.jackson.core:jackson-core": [ + "tools.jackson.core", + "tools.jackson.core.async", + "tools.jackson.core.base", + "tools.jackson.core.exc", + "tools.jackson.core.filter", + "tools.jackson.core.internal.shaded.fdp", + "tools.jackson.core.internal.shaded.fdp.bte", + "tools.jackson.core.internal.shaded.fdp.chr", + "tools.jackson.core.io", + "tools.jackson.core.io.schubfach", + "tools.jackson.core.json", + "tools.jackson.core.json.async", + "tools.jackson.core.sym", + "tools.jackson.core.tree", + "tools.jackson.core.type", + "tools.jackson.core.util" + ], + "tools.jackson.core:jackson-databind": [ + "tools.jackson.databind", + "tools.jackson.databind.annotation", + "tools.jackson.databind.cfg", + "tools.jackson.databind.deser", + "tools.jackson.databind.deser.bean", + "tools.jackson.databind.deser.impl", + "tools.jackson.databind.deser.jackson", + "tools.jackson.databind.deser.jdk", + "tools.jackson.databind.deser.std", + "tools.jackson.databind.exc", + "tools.jackson.databind.ext", + "tools.jackson.databind.ext.beans", + "tools.jackson.databind.ext.javatime", + "tools.jackson.databind.ext.javatime.deser", + "tools.jackson.databind.ext.javatime.deser.key", + "tools.jackson.databind.ext.javatime.ser", + "tools.jackson.databind.ext.javatime.ser.key", + "tools.jackson.databind.ext.javatime.util", + "tools.jackson.databind.ext.jdk8", + "tools.jackson.databind.ext.sql", + "tools.jackson.databind.introspect", + "tools.jackson.databind.json", + "tools.jackson.databind.jsonFormatVisitors", + "tools.jackson.databind.jsontype", + "tools.jackson.databind.jsontype.impl", + "tools.jackson.databind.module", + "tools.jackson.databind.node", + "tools.jackson.databind.ser", + "tools.jackson.databind.ser.bean", + "tools.jackson.databind.ser.impl", + "tools.jackson.databind.ser.jackson", + "tools.jackson.databind.ser.jdk", + "tools.jackson.databind.ser.std", + "tools.jackson.databind.type", + "tools.jackson.databind.util", + "tools.jackson.databind.util.internal" + ], + "tools.jackson.module:jackson-module-blackbird": [ + "tools.jackson.module.blackbird", + "tools.jackson.module.blackbird.deser", + "tools.jackson.module.blackbird.ser", + "tools.jackson.module.blackbird.util" + ] + }, + "repositories": { + "https://maven-central.storage-download.googleapis.com/maven2/": [ + "aopalliance:aopalliance", + "aopalliance:aopalliance:jar:sources", + "args4j:args4j", + "args4j:args4j:jar:sources", + "at.yawk.lz4:lz4-java", + "at.yawk.lz4:lz4-java:jar:sources", + "ch.qos.logback:logback-classic", + "ch.qos.logback:logback-classic:jar:sources", + "ch.qos.logback:logback-core", + "ch.qos.logback:logback-core:jar:sources", + "com.datastax.cassandra:cassandra-driver-core", + "com.datastax.cassandra:cassandra-driver-core:jar:sources", + "com.datastax.oss:native-protocol", + "com.datastax.oss:native-protocol:jar:sources", + "com.fasterxml.jackson.core:jackson-annotations", + "com.fasterxml.jackson.core:jackson-annotations:jar:sources", + "com.fasterxml.jackson.core:jackson-core", + "com.fasterxml.jackson.core:jackson-core:jar:sources", + "com.fasterxml.jackson.core:jackson-databind", + "com.fasterxml.jackson.core:jackson-databind:jar:sources", + "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml", + "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:jar:sources", + "com.fasterxml.jackson.datatype:jackson-datatype-jsr310", + "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:jar:sources", + "com.fasterxml:classmate", + "com.fasterxml:classmate:jar:sources", + "com.github.ben-manes.caffeine:caffeine", + "com.github.ben-manes.caffeine:caffeine:jar:sources", + "com.github.ben-manes.caffeine:guava", + "com.github.ben-manes.caffeine:guava:jar:sources", + "com.github.docker-java:docker-java-api", + "com.github.docker-java:docker-java-api:jar:sources", + "com.github.docker-java:docker-java-transport", + "com.github.docker-java:docker-java-transport-zerodep", + "com.github.docker-java:docker-java-transport-zerodep:jar:sources", + "com.github.docker-java:docker-java-transport:jar:sources", + "com.github.java-json-tools:btf", + "com.github.java-json-tools:btf:jar:sources", + "com.github.java-json-tools:jackson-coreutils", + "com.github.java-json-tools:jackson-coreutils:jar:sources", + "com.github.java-json-tools:json-patch", + "com.github.java-json-tools:json-patch:jar:sources", + "com.github.java-json-tools:msg-simple", + "com.github.java-json-tools:msg-simple:jar:sources", + "com.github.jnr:jffi", + "com.github.jnr:jffi:jar:native", + "com.github.jnr:jffi:jar:sources", + "com.github.jnr:jnr-constants", + "com.github.jnr:jnr-constants:jar:sources", + "com.github.jnr:jnr-ffi", + "com.github.jnr:jnr-ffi:jar:sources", + "com.github.jnr:jnr-posix", + "com.github.jnr:jnr-posix:jar:sources", + "com.github.jnr:jnr-x86asm", + "com.github.jnr:jnr-x86asm:jar:sources", + "com.github.stephenc.jcip:jcip-annotations", + "com.github.stephenc.jcip:jcip-annotations:jar:sources", + "com.google.code.findbugs:jsr305", + "com.google.code.findbugs:jsr305:jar:sources", + "com.google.code.gson:gson", + "com.google.code.gson:gson:jar:sources", + "com.google.errorprone:error_prone_annotations", + "com.google.errorprone:error_prone_annotations:jar:sources", + "com.google.guava:failureaccess", + "com.google.guava:failureaccess:jar:sources", + "com.google.guava:guava", + "com.google.guava:guava:jar:sources", + "com.google.guava:listenablefuture", + "com.google.j2objc:j2objc-annotations", + "com.google.j2objc:j2objc-annotations:jar:sources", + "com.jayway.jsonpath:json-path", + "com.jayway.jsonpath:json-path:jar:sources", + "com.nimbusds:content-type", + "com.nimbusds:content-type:jar:sources", + "com.nimbusds:lang-tag", + "com.nimbusds:lang-tag:jar:sources", + "com.nimbusds:nimbus-jose-jwt", + "com.nimbusds:nimbus-jose-jwt:jar:sources", + "com.nimbusds:oauth2-oidc-sdk", + "com.nimbusds:oauth2-oidc-sdk:jar:sources", + "com.squareup.okhttp3:okhttp-jvm", + "com.squareup.okhttp3:okhttp-jvm:jar:sources", + "com.squareup.okio:okio-jvm", + "com.squareup.okio:okio-jvm:jar:sources", + "com.typesafe:config", + "com.typesafe:config:jar:sources", + "com.vaadin.external.google:android-json", + "com.vaadin.external.google:android-json:jar:sources", + "commons-codec:commons-codec", + "commons-codec:commons-codec:jar:sources", + "commons-io:commons-io", + "commons-io:commons-io:jar:sources", + "commons-logging:commons-logging", + "commons-logging:commons-logging:jar:sources", + "io.cloudevents:cloudevents-api", + "io.cloudevents:cloudevents-api:jar:sources", + "io.cloudevents:cloudevents-core", + "io.cloudevents:cloudevents-core:jar:sources", + "io.cloudevents:cloudevents-json-jackson", + "io.cloudevents:cloudevents-json-jackson:jar:sources", + "io.dropwizard.metrics:metrics-core", + "io.dropwizard.metrics:metrics-core:jar:sources", + "io.micrometer:context-propagation", + "io.micrometer:context-propagation:jar:sources", + "io.micrometer:micrometer-commons", + "io.micrometer:micrometer-commons:jar:sources", + "io.micrometer:micrometer-core", + "io.micrometer:micrometer-core:jar:sources", + "io.micrometer:micrometer-jakarta9", + "io.micrometer:micrometer-jakarta9:jar:sources", + "io.micrometer:micrometer-observation", + "io.micrometer:micrometer-observation-test", + "io.micrometer:micrometer-observation-test:jar:sources", + "io.micrometer:micrometer-observation:jar:sources", + "io.micrometer:micrometer-tracing", + "io.micrometer:micrometer-tracing-bridge-otel", + "io.micrometer:micrometer-tracing-bridge-otel:jar:sources", + "io.micrometer:micrometer-tracing:jar:sources", + "io.nats:jnats", + "io.nats:jnats:jar:sources", + "io.netty:netty-buffer", + "io.netty:netty-buffer:jar:sources", + "io.netty:netty-codec-base", + "io.netty:netty-codec-base:jar:sources", + "io.netty:netty-codec-classes-quic", + "io.netty:netty-codec-classes-quic:jar:sources", + "io.netty:netty-codec-compression", + "io.netty:netty-codec-compression:jar:sources", + "io.netty:netty-codec-dns", + "io.netty:netty-codec-dns:jar:sources", + "io.netty:netty-codec-http", + "io.netty:netty-codec-http2", + "io.netty:netty-codec-http2:jar:sources", + "io.netty:netty-codec-http3", + "io.netty:netty-codec-http3:jar:sources", + "io.netty:netty-codec-http:jar:sources", + "io.netty:netty-codec-native-quic:jar:linux-aarch_64", + "io.netty:netty-codec-native-quic:jar:linux-x86_64", + "io.netty:netty-codec-native-quic:jar:osx-aarch_64", + "io.netty:netty-codec-native-quic:jar:osx-x86_64", + "io.netty:netty-codec-native-quic:jar:sources", + "io.netty:netty-codec-native-quic:jar:windows-x86_64", + "io.netty:netty-codec-socks", + "io.netty:netty-codec-socks:jar:sources", + "io.netty:netty-common", + "io.netty:netty-common:jar:sources", + "io.netty:netty-handler", + "io.netty:netty-handler-proxy", + "io.netty:netty-handler-proxy:jar:sources", + "io.netty:netty-handler:jar:sources", + "io.netty:netty-resolver", + "io.netty:netty-resolver-dns", + "io.netty:netty-resolver-dns-classes-macos", + "io.netty:netty-resolver-dns-classes-macos:jar:sources", + "io.netty:netty-resolver-dns-native-macos:jar:osx-x86_64", + "io.netty:netty-resolver-dns-native-macos:jar:sources", + "io.netty:netty-resolver-dns:jar:sources", + "io.netty:netty-resolver:jar:sources", + "io.netty:netty-transport", + "io.netty:netty-transport-classes-epoll", + "io.netty:netty-transport-classes-epoll:jar:sources", + "io.netty:netty-transport-native-epoll:jar:linux-x86_64", + "io.netty:netty-transport-native-epoll:jar:sources", + "io.netty:netty-transport-native-unix-common", + "io.netty:netty-transport-native-unix-common:jar:sources", + "io.netty:netty-transport:jar:sources", + "io.opentelemetry.semconv:opentelemetry-semconv", + "io.opentelemetry.semconv:opentelemetry-semconv:jar:sources", + "io.opentelemetry:opentelemetry-api", + "io.opentelemetry:opentelemetry-api:jar:sources", + "io.opentelemetry:opentelemetry-common", + "io.opentelemetry:opentelemetry-common:jar:sources", + "io.opentelemetry:opentelemetry-context", + "io.opentelemetry:opentelemetry-context:jar:sources", + "io.opentelemetry:opentelemetry-exporter-common", + "io.opentelemetry:opentelemetry-exporter-common:jar:sources", + "io.opentelemetry:opentelemetry-exporter-otlp", + "io.opentelemetry:opentelemetry-exporter-otlp-common", + "io.opentelemetry:opentelemetry-exporter-otlp-common:jar:sources", + "io.opentelemetry:opentelemetry-exporter-otlp:jar:sources", + "io.opentelemetry:opentelemetry-exporter-sender-okhttp", + "io.opentelemetry:opentelemetry-exporter-sender-okhttp:jar:sources", + "io.opentelemetry:opentelemetry-extension-trace-propagators", + "io.opentelemetry:opentelemetry-extension-trace-propagators:jar:sources", + "io.opentelemetry:opentelemetry-sdk", + "io.opentelemetry:opentelemetry-sdk-common", + "io.opentelemetry:opentelemetry-sdk-common:jar:sources", + "io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi", + "io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi:jar:sources", + "io.opentelemetry:opentelemetry-sdk-logs", + "io.opentelemetry:opentelemetry-sdk-logs:jar:sources", + "io.opentelemetry:opentelemetry-sdk-metrics", + "io.opentelemetry:opentelemetry-sdk-metrics:jar:sources", + "io.opentelemetry:opentelemetry-sdk-testing", + "io.opentelemetry:opentelemetry-sdk-testing:jar:sources", + "io.opentelemetry:opentelemetry-sdk-trace", + "io.opentelemetry:opentelemetry-sdk-trace:jar:sources", + "io.opentelemetry:opentelemetry-sdk:jar:sources", + "io.projectreactor.netty:reactor-netty-core", + "io.projectreactor.netty:reactor-netty-core:jar:sources", + "io.projectreactor.netty:reactor-netty-http", + "io.projectreactor.netty:reactor-netty-http:jar:sources", + "io.projectreactor:reactor-core", + "io.projectreactor:reactor-core:jar:sources", + "io.projectreactor:reactor-test", + "io.projectreactor:reactor-test:jar:sources", + "io.swagger.core.v3:swagger-annotations-jakarta", + "io.swagger.core.v3:swagger-annotations-jakarta:jar:sources", + "io.swagger.core.v3:swagger-core-jakarta", + "io.swagger.core.v3:swagger-core-jakarta:jar:sources", + "io.swagger.core.v3:swagger-models-jakarta", + "io.swagger.core.v3:swagger-models-jakarta:jar:sources", + "jakarta.activation:jakarta.activation-api", + "jakarta.activation:jakarta.activation-api:jar:sources", + "jakarta.annotation:jakarta.annotation-api", + "jakarta.annotation:jakarta.annotation-api:jar:sources", + "jakarta.servlet:jakarta.servlet-api", + "jakarta.servlet:jakarta.servlet-api:jar:sources", + "jakarta.validation:jakarta.validation-api", + "jakarta.validation:jakarta.validation-api:jar:sources", + "jakarta.xml.bind:jakarta.xml.bind-api", + "jakarta.xml.bind:jakarta.xml.bind-api:jar:sources", + "net.bytebuddy:byte-buddy", + "net.bytebuddy:byte-buddy-agent", + "net.bytebuddy:byte-buddy-agent:jar:sources", + "net.bytebuddy:byte-buddy:jar:sources", + "net.java.dev.jna:jna", + "net.java.dev.jna:jna:jar:sources", + "net.minidev:accessors-smart", + "net.minidev:accessors-smart:jar:sources", + "net.minidev:json-smart", + "net.minidev:json-smart:jar:sources", + "org.apache.cassandra:java-driver-core", + "org.apache.cassandra:java-driver-core:jar:sources", + "org.apache.cassandra:java-driver-guava-shaded", + "org.apache.cassandra:java-driver-guava-shaded:jar:sources", + "org.apache.cassandra:java-driver-metrics-micrometer", + "org.apache.cassandra:java-driver-metrics-micrometer:jar:sources", + "org.apache.cassandra:java-driver-query-builder", + "org.apache.cassandra:java-driver-query-builder:jar:sources", + "org.apache.commons:commons-compress", + "org.apache.commons:commons-compress:jar:sources", + "org.apache.commons:commons-lang3", + "org.apache.commons:commons-lang3:jar:sources", + "org.apache.logging.log4j:log4j-api", + "org.apache.logging.log4j:log4j-api:jar:sources", + "org.apache.logging.log4j:log4j-to-slf4j", + "org.apache.logging.log4j:log4j-to-slf4j:jar:sources", + "org.apache.tomcat.embed:tomcat-embed-core", + "org.apache.tomcat.embed:tomcat-embed-core:jar:sources", + "org.apache.tomcat.embed:tomcat-embed-el", + "org.apache.tomcat.embed:tomcat-embed-el:jar:sources", + "org.apache.tomcat.embed:tomcat-embed-websocket", + "org.apache.tomcat.embed:tomcat-embed-websocket:jar:sources", + "org.apiguardian:apiguardian-api", + "org.apiguardian:apiguardian-api:jar:sources", + "org.assertj:assertj-core", + "org.assertj:assertj-core:jar:sources", + "org.awaitility:awaitility", + "org.awaitility:awaitility:jar:sources", + "org.bouncycastle:bcprov-jdk18on", + "org.bouncycastle:bcprov-jdk18on:jar:sources", + "org.bouncycastle:bcprov-lts8on", + "org.bouncycastle:bcprov-lts8on:jar:sources", + "org.checkerframework:checker-qual", + "org.checkerframework:checker-qual:jar:sources", + "org.hamcrest:hamcrest", + "org.hamcrest:hamcrest:jar:sources", + "org.hdrhistogram:HdrHistogram", + "org.hdrhistogram:HdrHistogram:jar:sources", + "org.hibernate.validator:hibernate-validator", + "org.hibernate.validator:hibernate-validator:jar:sources", + "org.jacoco:org.jacoco.agent:jar:runtime", + "org.jacoco:org.jacoco.agent:jar:sources", + "org.jacoco:org.jacoco.cli", + "org.jacoco:org.jacoco.cli:jar:sources", + "org.jacoco:org.jacoco.core", + "org.jacoco:org.jacoco.core:jar:sources", + "org.jacoco:org.jacoco.report", + "org.jacoco:org.jacoco.report:jar:sources", + "org.jboss.logging:jboss-logging", + "org.jboss.logging:jboss-logging:jar:sources", + "org.jetbrains.kotlin:kotlin-stdlib", + "org.jetbrains.kotlin:kotlin-stdlib:jar:sources", + "org.jetbrains:annotations", + "org.jetbrains:annotations:jar:sources", + "org.jspecify:jspecify", + "org.jspecify:jspecify:jar:sources", + "org.junit.jupiter:junit-jupiter", + "org.junit.jupiter:junit-jupiter-api", + "org.junit.jupiter:junit-jupiter-api:jar:sources", + "org.junit.jupiter:junit-jupiter-engine", + "org.junit.jupiter:junit-jupiter-engine:jar:sources", + "org.junit.jupiter:junit-jupiter-params", + "org.junit.jupiter:junit-jupiter-params:jar:sources", + "org.junit.jupiter:junit-jupiter:jar:sources", + "org.junit.platform:junit-platform-commons", + "org.junit.platform:junit-platform-commons:jar:sources", + "org.junit.platform:junit-platform-console-standalone", + "org.junit.platform:junit-platform-console-standalone:jar:sources", + "org.junit.platform:junit-platform-engine", + "org.junit.platform:junit-platform-engine:jar:sources", + "org.junit.platform:junit-platform-launcher", + "org.junit.platform:junit-platform-launcher:jar:sources", + "org.junit.platform:junit-platform-reporting", + "org.junit.platform:junit-platform-reporting:jar:sources", + "org.latencyutils:LatencyUtils", + "org.latencyutils:LatencyUtils:jar:sources", + "org.mockito:mockito-core", + "org.mockito:mockito-core:jar:sources", + "org.mockito:mockito-junit-jupiter", + "org.mockito:mockito-junit-jupiter:jar:sources", + "org.objenesis:objenesis", + "org.objenesis:objenesis:jar:sources", + "org.opentest4j.reporting:open-test-reporting-tooling-spi", + "org.opentest4j.reporting:open-test-reporting-tooling-spi:jar:sources", + "org.opentest4j:opentest4j", + "org.opentest4j:opentest4j:jar:sources", + "org.ow2.asm:asm", + "org.ow2.asm:asm-analysis", + "org.ow2.asm:asm-analysis:jar:sources", + "org.ow2.asm:asm-commons", + "org.ow2.asm:asm-commons:jar:sources", + "org.ow2.asm:asm-tree", + "org.ow2.asm:asm-tree:jar:sources", + "org.ow2.asm:asm-util", + "org.ow2.asm:asm-util:jar:sources", + "org.ow2.asm:asm:jar:sources", + "org.projectlombok:lombok", + "org.projectlombok:lombok:jar:sources", + "org.reactivestreams:reactive-streams", + "org.reactivestreams:reactive-streams:jar:sources", + "org.rnorth.duct-tape:duct-tape", + "org.rnorth.duct-tape:duct-tape:jar:sources", + "org.skyscreamer:jsonassert", + "org.skyscreamer:jsonassert:jar:sources", + "org.slf4j:jul-to-slf4j", + "org.slf4j:jul-to-slf4j:jar:sources", + "org.slf4j:slf4j-api", + "org.slf4j:slf4j-api:jar:sources", + "org.springdoc:springdoc-openapi-starter-common", + "org.springdoc:springdoc-openapi-starter-common:jar:sources", + "org.springdoc:springdoc-openapi-starter-webflux-api", + "org.springdoc:springdoc-openapi-starter-webflux-api:jar:sources", + "org.springdoc:springdoc-openapi-starter-webmvc-api", + "org.springdoc:springdoc-openapi-starter-webmvc-api:jar:sources", + "org.springframework.boot:spring-boot", + "org.springframework.boot:spring-boot-actuator", + "org.springframework.boot:spring-boot-actuator-autoconfigure", + "org.springframework.boot:spring-boot-actuator-autoconfigure:jar:sources", + "org.springframework.boot:spring-boot-actuator:jar:sources", + "org.springframework.boot:spring-boot-autoconfigure", + "org.springframework.boot:spring-boot-autoconfigure:jar:sources", + "org.springframework.boot:spring-boot-cassandra", + "org.springframework.boot:spring-boot-cassandra:jar:sources", + "org.springframework.boot:spring-boot-data-cassandra", + "org.springframework.boot:spring-boot-data-cassandra-test", + "org.springframework.boot:spring-boot-data-cassandra-test:jar:sources", + "org.springframework.boot:spring-boot-data-cassandra:jar:sources", + "org.springframework.boot:spring-boot-data-commons", + "org.springframework.boot:spring-boot-data-commons:jar:sources", + "org.springframework.boot:spring-boot-health", + "org.springframework.boot:spring-boot-health:jar:sources", + "org.springframework.boot:spring-boot-http-client", + "org.springframework.boot:spring-boot-http-client:jar:sources", + "org.springframework.boot:spring-boot-http-codec", + "org.springframework.boot:spring-boot-http-codec:jar:sources", + "org.springframework.boot:spring-boot-http-converter", + "org.springframework.boot:spring-boot-http-converter:jar:sources", + "org.springframework.boot:spring-boot-jackson", + "org.springframework.boot:spring-boot-jackson:jar:sources", + "org.springframework.boot:spring-boot-micrometer-metrics", + "org.springframework.boot:spring-boot-micrometer-metrics-test", + "org.springframework.boot:spring-boot-micrometer-metrics-test:jar:sources", + "org.springframework.boot:spring-boot-micrometer-metrics:jar:sources", + "org.springframework.boot:spring-boot-micrometer-observation", + "org.springframework.boot:spring-boot-micrometer-observation:jar:sources", + "org.springframework.boot:spring-boot-micrometer-tracing", + "org.springframework.boot:spring-boot-micrometer-tracing-opentelemetry", + "org.springframework.boot:spring-boot-micrometer-tracing-opentelemetry:jar:sources", + "org.springframework.boot:spring-boot-micrometer-tracing:jar:sources", + "org.springframework.boot:spring-boot-netty", + "org.springframework.boot:spring-boot-netty:jar:sources", + "org.springframework.boot:spring-boot-opentelemetry", + "org.springframework.boot:spring-boot-opentelemetry:jar:sources", + "org.springframework.boot:spring-boot-persistence", + "org.springframework.boot:spring-boot-persistence:jar:sources", + "org.springframework.boot:spring-boot-reactor", + "org.springframework.boot:spring-boot-reactor-netty", + "org.springframework.boot:spring-boot-reactor-netty:jar:sources", + "org.springframework.boot:spring-boot-reactor:jar:sources", + "org.springframework.boot:spring-boot-restclient", + "org.springframework.boot:spring-boot-restclient:jar:sources", + "org.springframework.boot:spring-boot-resttestclient", + "org.springframework.boot:spring-boot-resttestclient:jar:sources", + "org.springframework.boot:spring-boot-security", + "org.springframework.boot:spring-boot-security-oauth2-client", + "org.springframework.boot:spring-boot-security-oauth2-client:jar:sources", + "org.springframework.boot:spring-boot-security-oauth2-resource-server", + "org.springframework.boot:spring-boot-security-oauth2-resource-server:jar:sources", + "org.springframework.boot:spring-boot-security-test", + "org.springframework.boot:spring-boot-security-test:jar:sources", + "org.springframework.boot:spring-boot-security:jar:sources", + "org.springframework.boot:spring-boot-servlet", + "org.springframework.boot:spring-boot-servlet:jar:sources", + "org.springframework.boot:spring-boot-starter", + "org.springframework.boot:spring-boot-starter-actuator", + "org.springframework.boot:spring-boot-starter-actuator-test", + "org.springframework.boot:spring-boot-starter-actuator-test:jar:sources", + "org.springframework.boot:spring-boot-starter-actuator:jar:sources", + "org.springframework.boot:spring-boot-starter-data-cassandra", + "org.springframework.boot:spring-boot-starter-data-cassandra-test", + "org.springframework.boot:spring-boot-starter-data-cassandra-test:jar:sources", + "org.springframework.boot:spring-boot-starter-data-cassandra:jar:sources", + "org.springframework.boot:spring-boot-starter-jackson", + "org.springframework.boot:spring-boot-starter-jackson-test", + "org.springframework.boot:spring-boot-starter-jackson-test:jar:sources", + "org.springframework.boot:spring-boot-starter-jackson:jar:sources", + "org.springframework.boot:spring-boot-starter-logging", + "org.springframework.boot:spring-boot-starter-logging:jar:sources", + "org.springframework.boot:spring-boot-starter-micrometer-metrics", + "org.springframework.boot:spring-boot-starter-micrometer-metrics-test", + "org.springframework.boot:spring-boot-starter-micrometer-metrics-test:jar:sources", + "org.springframework.boot:spring-boot-starter-micrometer-metrics:jar:sources", + "org.springframework.boot:spring-boot-starter-reactor-netty", + "org.springframework.boot:spring-boot-starter-reactor-netty:jar:sources", + "org.springframework.boot:spring-boot-starter-security", + "org.springframework.boot:spring-boot-starter-security-oauth2-client", + "org.springframework.boot:spring-boot-starter-security-oauth2-client:jar:sources", + "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server", + "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server-test", + "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server-test:jar:sources", + "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server:jar:sources", + "org.springframework.boot:spring-boot-starter-security-test", + "org.springframework.boot:spring-boot-starter-security-test:jar:sources", + "org.springframework.boot:spring-boot-starter-security:jar:sources", + "org.springframework.boot:spring-boot-starter-test", + "org.springframework.boot:spring-boot-starter-test:jar:sources", + "org.springframework.boot:spring-boot-starter-tomcat", + "org.springframework.boot:spring-boot-starter-tomcat-runtime", + "org.springframework.boot:spring-boot-starter-tomcat-runtime:jar:sources", + "org.springframework.boot:spring-boot-starter-tomcat:jar:sources", + "org.springframework.boot:spring-boot-starter-validation", + "org.springframework.boot:spring-boot-starter-validation:jar:sources", + "org.springframework.boot:spring-boot-starter-webflux", + "org.springframework.boot:spring-boot-starter-webflux-test", + "org.springframework.boot:spring-boot-starter-webflux-test:jar:sources", + "org.springframework.boot:spring-boot-starter-webflux:jar:sources", + "org.springframework.boot:spring-boot-starter-webmvc", + "org.springframework.boot:spring-boot-starter-webmvc-test", + "org.springframework.boot:spring-boot-starter-webmvc-test:jar:sources", + "org.springframework.boot:spring-boot-starter-webmvc:jar:sources", + "org.springframework.boot:spring-boot-starter:jar:sources", + "org.springframework.boot:spring-boot-test", + "org.springframework.boot:spring-boot-test-autoconfigure", + "org.springframework.boot:spring-boot-test-autoconfigure:jar:sources", + "org.springframework.boot:spring-boot-test:jar:sources", + "org.springframework.boot:spring-boot-tomcat", + "org.springframework.boot:spring-boot-tomcat:jar:sources", + "org.springframework.boot:spring-boot-validation", + "org.springframework.boot:spring-boot-validation:jar:sources", + "org.springframework.boot:spring-boot-web-server", + "org.springframework.boot:spring-boot-web-server:jar:sources", + "org.springframework.boot:spring-boot-webclient", + "org.springframework.boot:spring-boot-webclient:jar:sources", + "org.springframework.boot:spring-boot-webflux", + "org.springframework.boot:spring-boot-webflux-test", + "org.springframework.boot:spring-boot-webflux-test:jar:sources", + "org.springframework.boot:spring-boot-webflux:jar:sources", + "org.springframework.boot:spring-boot-webmvc", + "org.springframework.boot:spring-boot-webmvc-test", + "org.springframework.boot:spring-boot-webmvc-test:jar:sources", + "org.springframework.boot:spring-boot-webmvc:jar:sources", + "org.springframework.boot:spring-boot-webtestclient", + "org.springframework.boot:spring-boot-webtestclient:jar:sources", + "org.springframework.boot:spring-boot:jar:sources", + "org.springframework.cloud:spring-cloud-commons", + "org.springframework.cloud:spring-cloud-commons:jar:sources", + "org.springframework.cloud:spring-cloud-context", + "org.springframework.cloud:spring-cloud-context:jar:sources", + "org.springframework.cloud:spring-cloud-starter", + "org.springframework.cloud:spring-cloud-starter-bootstrap", + "org.springframework.cloud:spring-cloud-starter-bootstrap:jar:sources", + "org.springframework.data:spring-data-cassandra", + "org.springframework.data:spring-data-cassandra:jar:sources", + "org.springframework.data:spring-data-commons", + "org.springframework.data:spring-data-commons:jar:sources", + "org.springframework.security:spring-security-config", + "org.springframework.security:spring-security-config:jar:sources", + "org.springframework.security:spring-security-core", + "org.springframework.security:spring-security-core:jar:sources", + "org.springframework.security:spring-security-crypto", + "org.springframework.security:spring-security-crypto:jar:sources", + "org.springframework.security:spring-security-oauth2-client", + "org.springframework.security:spring-security-oauth2-client:jar:sources", + "org.springframework.security:spring-security-oauth2-core", + "org.springframework.security:spring-security-oauth2-core:jar:sources", + "org.springframework.security:spring-security-oauth2-jose", + "org.springframework.security:spring-security-oauth2-jose:jar:sources", + "org.springframework.security:spring-security-oauth2-resource-server", + "org.springframework.security:spring-security-oauth2-resource-server:jar:sources", + "org.springframework.security:spring-security-test", + "org.springframework.security:spring-security-test:jar:sources", + "org.springframework.security:spring-security-web", + "org.springframework.security:spring-security-web:jar:sources", + "org.springframework:spring-aop", + "org.springframework:spring-aop:jar:sources", + "org.springframework:spring-beans", + "org.springframework:spring-beans:jar:sources", + "org.springframework:spring-context", + "org.springframework:spring-context:jar:sources", + "org.springframework:spring-core", + "org.springframework:spring-core:jar:sources", + "org.springframework:spring-expression", + "org.springframework:spring-expression:jar:sources", + "org.springframework:spring-test", + "org.springframework:spring-test:jar:sources", + "org.springframework:spring-tx", + "org.springframework:spring-tx:jar:sources", + "org.springframework:spring-web", + "org.springframework:spring-web:jar:sources", + "org.springframework:spring-webflux", + "org.springframework:spring-webflux:jar:sources", + "org.springframework:spring-webmvc", + "org.springframework:spring-webmvc:jar:sources", + "org.testcontainers:testcontainers", + "org.testcontainers:testcontainers-cassandra", + "org.testcontainers:testcontainers-cassandra:jar:sources", + "org.testcontainers:testcontainers-database-commons", + "org.testcontainers:testcontainers-database-commons:jar:sources", + "org.testcontainers:testcontainers-junit-jupiter", + "org.testcontainers:testcontainers-junit-jupiter:jar:sources", + "org.testcontainers:testcontainers:jar:sources", + "org.wiremock:wiremock-standalone", + "org.wiremock:wiremock-standalone:jar:sources", + "org.xmlunit:xmlunit-core", + "org.xmlunit:xmlunit-core:jar:sources", + "org.yaml:snakeyaml", + "org.yaml:snakeyaml:jar:sources", + "software.amazon.awssdk:annotations", + "software.amazon.awssdk:annotations:jar:sources", + "software.amazon.awssdk:checksums", + "software.amazon.awssdk:checksums-spi", + "software.amazon.awssdk:checksums-spi:jar:sources", + "software.amazon.awssdk:checksums:jar:sources", + "software.amazon.awssdk:endpoints-spi", + "software.amazon.awssdk:endpoints-spi:jar:sources", + "software.amazon.awssdk:http-auth-aws", + "software.amazon.awssdk:http-auth-aws:jar:sources", + "software.amazon.awssdk:http-auth-spi", + "software.amazon.awssdk:http-auth-spi:jar:sources", + "software.amazon.awssdk:http-client-spi", + "software.amazon.awssdk:http-client-spi:jar:sources", + "software.amazon.awssdk:identity-spi", + "software.amazon.awssdk:identity-spi:jar:sources", + "software.amazon.awssdk:json-utils", + "software.amazon.awssdk:json-utils:jar:sources", + "software.amazon.awssdk:metrics-spi", + "software.amazon.awssdk:metrics-spi:jar:sources", + "software.amazon.awssdk:profiles", + "software.amazon.awssdk:profiles:jar:sources", + "software.amazon.awssdk:regions", + "software.amazon.awssdk:regions:jar:sources", + "software.amazon.awssdk:retries", + "software.amazon.awssdk:retries-spi", + "software.amazon.awssdk:retries-spi:jar:sources", + "software.amazon.awssdk:retries:jar:sources", + "software.amazon.awssdk:sdk-core", + "software.amazon.awssdk:sdk-core:jar:sources", + "software.amazon.awssdk:third-party-jackson-core", + "software.amazon.awssdk:third-party-jackson-core:jar:sources", + "software.amazon.awssdk:utils", + "software.amazon.awssdk:utils:jar:sources", + "tools.jackson.core:jackson-core", + "tools.jackson.core:jackson-core:jar:sources", + "tools.jackson.core:jackson-databind", + "tools.jackson.core:jackson-databind:jar:sources", + "tools.jackson.module:jackson-module-blackbird", + "tools.jackson.module:jackson-module-blackbird:jar:sources" + ], + "https://repo.maven.apache.org/maven2/": [ + "aopalliance:aopalliance", + "aopalliance:aopalliance:jar:sources", + "args4j:args4j", + "args4j:args4j:jar:sources", + "at.yawk.lz4:lz4-java", + "at.yawk.lz4:lz4-java:jar:sources", + "ch.qos.logback:logback-classic", + "ch.qos.logback:logback-classic:jar:sources", + "ch.qos.logback:logback-core", + "ch.qos.logback:logback-core:jar:sources", + "com.datastax.cassandra:cassandra-driver-core", + "com.datastax.cassandra:cassandra-driver-core:jar:sources", + "com.datastax.oss:native-protocol", + "com.datastax.oss:native-protocol:jar:sources", + "com.fasterxml.jackson.core:jackson-annotations", + "com.fasterxml.jackson.core:jackson-annotations:jar:sources", + "com.fasterxml.jackson.core:jackson-core", + "com.fasterxml.jackson.core:jackson-core:jar:sources", + "com.fasterxml.jackson.core:jackson-databind", + "com.fasterxml.jackson.core:jackson-databind:jar:sources", + "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml", + "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:jar:sources", + "com.fasterxml.jackson.datatype:jackson-datatype-jsr310", + "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:jar:sources", + "com.fasterxml:classmate", + "com.fasterxml:classmate:jar:sources", + "com.github.ben-manes.caffeine:caffeine", + "com.github.ben-manes.caffeine:caffeine:jar:sources", + "com.github.ben-manes.caffeine:guava", + "com.github.ben-manes.caffeine:guava:jar:sources", + "com.github.docker-java:docker-java-api", + "com.github.docker-java:docker-java-api:jar:sources", + "com.github.docker-java:docker-java-transport", + "com.github.docker-java:docker-java-transport-zerodep", + "com.github.docker-java:docker-java-transport-zerodep:jar:sources", + "com.github.docker-java:docker-java-transport:jar:sources", + "com.github.java-json-tools:btf", + "com.github.java-json-tools:btf:jar:sources", + "com.github.java-json-tools:jackson-coreutils", + "com.github.java-json-tools:jackson-coreutils:jar:sources", + "com.github.java-json-tools:json-patch", + "com.github.java-json-tools:json-patch:jar:sources", + "com.github.java-json-tools:msg-simple", + "com.github.java-json-tools:msg-simple:jar:sources", + "com.github.jnr:jffi", + "com.github.jnr:jffi:jar:native", + "com.github.jnr:jffi:jar:sources", + "com.github.jnr:jnr-constants", + "com.github.jnr:jnr-constants:jar:sources", + "com.github.jnr:jnr-ffi", + "com.github.jnr:jnr-ffi:jar:sources", + "com.github.jnr:jnr-posix", + "com.github.jnr:jnr-posix:jar:sources", + "com.github.jnr:jnr-x86asm", + "com.github.jnr:jnr-x86asm:jar:sources", + "com.github.stephenc.jcip:jcip-annotations", + "com.github.stephenc.jcip:jcip-annotations:jar:sources", + "com.google.code.findbugs:jsr305", + "com.google.code.findbugs:jsr305:jar:sources", + "com.google.code.gson:gson", + "com.google.code.gson:gson:jar:sources", + "com.google.errorprone:error_prone_annotations", + "com.google.errorprone:error_prone_annotations:jar:sources", + "com.google.guava:failureaccess", + "com.google.guava:failureaccess:jar:sources", + "com.google.guava:guava", + "com.google.guava:guava:jar:sources", + "com.google.guava:listenablefuture", + "com.google.j2objc:j2objc-annotations", + "com.google.j2objc:j2objc-annotations:jar:sources", + "com.jayway.jsonpath:json-path", + "com.jayway.jsonpath:json-path:jar:sources", + "com.nimbusds:content-type", + "com.nimbusds:content-type:jar:sources", + "com.nimbusds:lang-tag", + "com.nimbusds:lang-tag:jar:sources", + "com.nimbusds:nimbus-jose-jwt", + "com.nimbusds:nimbus-jose-jwt:jar:sources", + "com.nimbusds:oauth2-oidc-sdk", + "com.nimbusds:oauth2-oidc-sdk:jar:sources", + "com.squareup.okhttp3:okhttp-jvm", + "com.squareup.okhttp3:okhttp-jvm:jar:sources", + "com.squareup.okio:okio-jvm", + "com.squareup.okio:okio-jvm:jar:sources", + "com.typesafe:config", + "com.typesafe:config:jar:sources", + "com.vaadin.external.google:android-json", + "com.vaadin.external.google:android-json:jar:sources", + "commons-codec:commons-codec", + "commons-codec:commons-codec:jar:sources", + "commons-io:commons-io", + "commons-io:commons-io:jar:sources", + "commons-logging:commons-logging", + "commons-logging:commons-logging:jar:sources", + "io.cloudevents:cloudevents-api", + "io.cloudevents:cloudevents-api:jar:sources", + "io.cloudevents:cloudevents-core", + "io.cloudevents:cloudevents-core:jar:sources", + "io.cloudevents:cloudevents-json-jackson", + "io.cloudevents:cloudevents-json-jackson:jar:sources", + "io.dropwizard.metrics:metrics-core", + "io.dropwizard.metrics:metrics-core:jar:sources", + "io.micrometer:context-propagation", + "io.micrometer:context-propagation:jar:sources", + "io.micrometer:micrometer-commons", + "io.micrometer:micrometer-commons:jar:sources", + "io.micrometer:micrometer-core", + "io.micrometer:micrometer-core:jar:sources", + "io.micrometer:micrometer-jakarta9", + "io.micrometer:micrometer-jakarta9:jar:sources", + "io.micrometer:micrometer-observation", + "io.micrometer:micrometer-observation-test", + "io.micrometer:micrometer-observation-test:jar:sources", + "io.micrometer:micrometer-observation:jar:sources", + "io.micrometer:micrometer-tracing", + "io.micrometer:micrometer-tracing-bridge-otel", + "io.micrometer:micrometer-tracing-bridge-otel:jar:sources", + "io.micrometer:micrometer-tracing:jar:sources", + "io.nats:jnats", + "io.nats:jnats:jar:sources", + "io.netty:netty-buffer", + "io.netty:netty-buffer:jar:sources", + "io.netty:netty-codec-base", + "io.netty:netty-codec-base:jar:sources", + "io.netty:netty-codec-classes-quic", + "io.netty:netty-codec-classes-quic:jar:sources", + "io.netty:netty-codec-compression", + "io.netty:netty-codec-compression:jar:sources", + "io.netty:netty-codec-dns", + "io.netty:netty-codec-dns:jar:sources", + "io.netty:netty-codec-http", + "io.netty:netty-codec-http2", + "io.netty:netty-codec-http2:jar:sources", + "io.netty:netty-codec-http3", + "io.netty:netty-codec-http3:jar:sources", + "io.netty:netty-codec-http:jar:sources", + "io.netty:netty-codec-native-quic:jar:linux-aarch_64", + "io.netty:netty-codec-native-quic:jar:linux-x86_64", + "io.netty:netty-codec-native-quic:jar:osx-aarch_64", + "io.netty:netty-codec-native-quic:jar:osx-x86_64", + "io.netty:netty-codec-native-quic:jar:sources", + "io.netty:netty-codec-native-quic:jar:windows-x86_64", + "io.netty:netty-codec-socks", + "io.netty:netty-codec-socks:jar:sources", + "io.netty:netty-common", + "io.netty:netty-common:jar:sources", + "io.netty:netty-handler", + "io.netty:netty-handler-proxy", + "io.netty:netty-handler-proxy:jar:sources", + "io.netty:netty-handler:jar:sources", + "io.netty:netty-resolver", + "io.netty:netty-resolver-dns", + "io.netty:netty-resolver-dns-classes-macos", + "io.netty:netty-resolver-dns-classes-macos:jar:sources", + "io.netty:netty-resolver-dns-native-macos:jar:osx-x86_64", + "io.netty:netty-resolver-dns-native-macos:jar:sources", + "io.netty:netty-resolver-dns:jar:sources", + "io.netty:netty-resolver:jar:sources", + "io.netty:netty-transport", + "io.netty:netty-transport-classes-epoll", + "io.netty:netty-transport-classes-epoll:jar:sources", + "io.netty:netty-transport-native-epoll:jar:linux-x86_64", + "io.netty:netty-transport-native-epoll:jar:sources", + "io.netty:netty-transport-native-unix-common", + "io.netty:netty-transport-native-unix-common:jar:sources", + "io.netty:netty-transport:jar:sources", + "io.opentelemetry.semconv:opentelemetry-semconv", + "io.opentelemetry.semconv:opentelemetry-semconv:jar:sources", + "io.opentelemetry:opentelemetry-api", + "io.opentelemetry:opentelemetry-api:jar:sources", + "io.opentelemetry:opentelemetry-common", + "io.opentelemetry:opentelemetry-common:jar:sources", + "io.opentelemetry:opentelemetry-context", + "io.opentelemetry:opentelemetry-context:jar:sources", + "io.opentelemetry:opentelemetry-exporter-common", + "io.opentelemetry:opentelemetry-exporter-common:jar:sources", + "io.opentelemetry:opentelemetry-exporter-otlp", + "io.opentelemetry:opentelemetry-exporter-otlp-common", + "io.opentelemetry:opentelemetry-exporter-otlp-common:jar:sources", + "io.opentelemetry:opentelemetry-exporter-otlp:jar:sources", + "io.opentelemetry:opentelemetry-exporter-sender-okhttp", + "io.opentelemetry:opentelemetry-exporter-sender-okhttp:jar:sources", + "io.opentelemetry:opentelemetry-extension-trace-propagators", + "io.opentelemetry:opentelemetry-extension-trace-propagators:jar:sources", + "io.opentelemetry:opentelemetry-sdk", + "io.opentelemetry:opentelemetry-sdk-common", + "io.opentelemetry:opentelemetry-sdk-common:jar:sources", + "io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi", + "io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi:jar:sources", + "io.opentelemetry:opentelemetry-sdk-logs", + "io.opentelemetry:opentelemetry-sdk-logs:jar:sources", + "io.opentelemetry:opentelemetry-sdk-metrics", + "io.opentelemetry:opentelemetry-sdk-metrics:jar:sources", + "io.opentelemetry:opentelemetry-sdk-testing", + "io.opentelemetry:opentelemetry-sdk-testing:jar:sources", + "io.opentelemetry:opentelemetry-sdk-trace", + "io.opentelemetry:opentelemetry-sdk-trace:jar:sources", + "io.opentelemetry:opentelemetry-sdk:jar:sources", + "io.projectreactor.netty:reactor-netty-core", + "io.projectreactor.netty:reactor-netty-core:jar:sources", + "io.projectreactor.netty:reactor-netty-http", + "io.projectreactor.netty:reactor-netty-http:jar:sources", + "io.projectreactor:reactor-core", + "io.projectreactor:reactor-core:jar:sources", + "io.projectreactor:reactor-test", + "io.projectreactor:reactor-test:jar:sources", + "io.swagger.core.v3:swagger-annotations-jakarta", + "io.swagger.core.v3:swagger-annotations-jakarta:jar:sources", + "io.swagger.core.v3:swagger-core-jakarta", + "io.swagger.core.v3:swagger-core-jakarta:jar:sources", + "io.swagger.core.v3:swagger-models-jakarta", + "io.swagger.core.v3:swagger-models-jakarta:jar:sources", + "jakarta.activation:jakarta.activation-api", + "jakarta.activation:jakarta.activation-api:jar:sources", + "jakarta.annotation:jakarta.annotation-api", + "jakarta.annotation:jakarta.annotation-api:jar:sources", + "jakarta.servlet:jakarta.servlet-api", + "jakarta.servlet:jakarta.servlet-api:jar:sources", + "jakarta.validation:jakarta.validation-api", + "jakarta.validation:jakarta.validation-api:jar:sources", + "jakarta.xml.bind:jakarta.xml.bind-api", + "jakarta.xml.bind:jakarta.xml.bind-api:jar:sources", + "net.bytebuddy:byte-buddy", + "net.bytebuddy:byte-buddy-agent", + "net.bytebuddy:byte-buddy-agent:jar:sources", + "net.bytebuddy:byte-buddy:jar:sources", + "net.java.dev.jna:jna", + "net.java.dev.jna:jna:jar:sources", + "net.minidev:accessors-smart", + "net.minidev:accessors-smart:jar:sources", + "net.minidev:json-smart", + "net.minidev:json-smart:jar:sources", + "org.apache.cassandra:java-driver-core", + "org.apache.cassandra:java-driver-core:jar:sources", + "org.apache.cassandra:java-driver-guava-shaded", + "org.apache.cassandra:java-driver-guava-shaded:jar:sources", + "org.apache.cassandra:java-driver-metrics-micrometer", + "org.apache.cassandra:java-driver-metrics-micrometer:jar:sources", + "org.apache.cassandra:java-driver-query-builder", + "org.apache.cassandra:java-driver-query-builder:jar:sources", + "org.apache.commons:commons-compress", + "org.apache.commons:commons-compress:jar:sources", + "org.apache.commons:commons-lang3", + "org.apache.commons:commons-lang3:jar:sources", + "org.apache.logging.log4j:log4j-api", + "org.apache.logging.log4j:log4j-api:jar:sources", + "org.apache.logging.log4j:log4j-to-slf4j", + "org.apache.logging.log4j:log4j-to-slf4j:jar:sources", + "org.apache.tomcat.embed:tomcat-embed-core", + "org.apache.tomcat.embed:tomcat-embed-core:jar:sources", + "org.apache.tomcat.embed:tomcat-embed-el", + "org.apache.tomcat.embed:tomcat-embed-el:jar:sources", + "org.apache.tomcat.embed:tomcat-embed-websocket", + "org.apache.tomcat.embed:tomcat-embed-websocket:jar:sources", + "org.apiguardian:apiguardian-api", + "org.apiguardian:apiguardian-api:jar:sources", + "org.assertj:assertj-core", + "org.assertj:assertj-core:jar:sources", + "org.awaitility:awaitility", + "org.awaitility:awaitility:jar:sources", + "org.bouncycastle:bcprov-jdk18on", + "org.bouncycastle:bcprov-jdk18on:jar:sources", + "org.bouncycastle:bcprov-lts8on", + "org.bouncycastle:bcprov-lts8on:jar:sources", + "org.checkerframework:checker-qual", + "org.checkerframework:checker-qual:jar:sources", + "org.hamcrest:hamcrest", + "org.hamcrest:hamcrest:jar:sources", + "org.hdrhistogram:HdrHistogram", + "org.hdrhistogram:HdrHistogram:jar:sources", + "org.hibernate.validator:hibernate-validator", + "org.hibernate.validator:hibernate-validator:jar:sources", + "org.jacoco:org.jacoco.agent:jar:runtime", + "org.jacoco:org.jacoco.agent:jar:sources", + "org.jacoco:org.jacoco.cli", + "org.jacoco:org.jacoco.cli:jar:sources", + "org.jacoco:org.jacoco.core", + "org.jacoco:org.jacoco.core:jar:sources", + "org.jacoco:org.jacoco.report", + "org.jacoco:org.jacoco.report:jar:sources", + "org.jboss.logging:jboss-logging", + "org.jboss.logging:jboss-logging:jar:sources", + "org.jetbrains.kotlin:kotlin-stdlib", + "org.jetbrains.kotlin:kotlin-stdlib:jar:sources", + "org.jetbrains:annotations", + "org.jetbrains:annotations:jar:sources", + "org.jspecify:jspecify", + "org.jspecify:jspecify:jar:sources", + "org.junit.jupiter:junit-jupiter", + "org.junit.jupiter:junit-jupiter-api", + "org.junit.jupiter:junit-jupiter-api:jar:sources", + "org.junit.jupiter:junit-jupiter-engine", + "org.junit.jupiter:junit-jupiter-engine:jar:sources", + "org.junit.jupiter:junit-jupiter-params", + "org.junit.jupiter:junit-jupiter-params:jar:sources", + "org.junit.jupiter:junit-jupiter:jar:sources", + "org.junit.platform:junit-platform-commons", + "org.junit.platform:junit-platform-commons:jar:sources", + "org.junit.platform:junit-platform-console-standalone", + "org.junit.platform:junit-platform-console-standalone:jar:sources", + "org.junit.platform:junit-platform-engine", + "org.junit.platform:junit-platform-engine:jar:sources", + "org.junit.platform:junit-platform-launcher", + "org.junit.platform:junit-platform-launcher:jar:sources", + "org.junit.platform:junit-platform-reporting", + "org.junit.platform:junit-platform-reporting:jar:sources", + "org.latencyutils:LatencyUtils", + "org.latencyutils:LatencyUtils:jar:sources", + "org.mockito:mockito-core", + "org.mockito:mockito-core:jar:sources", + "org.mockito:mockito-junit-jupiter", + "org.mockito:mockito-junit-jupiter:jar:sources", + "org.objenesis:objenesis", + "org.objenesis:objenesis:jar:sources", + "org.opentest4j.reporting:open-test-reporting-tooling-spi", + "org.opentest4j.reporting:open-test-reporting-tooling-spi:jar:sources", + "org.opentest4j:opentest4j", + "org.opentest4j:opentest4j:jar:sources", + "org.ow2.asm:asm", + "org.ow2.asm:asm-analysis", + "org.ow2.asm:asm-analysis:jar:sources", + "org.ow2.asm:asm-commons", + "org.ow2.asm:asm-commons:jar:sources", + "org.ow2.asm:asm-tree", + "org.ow2.asm:asm-tree:jar:sources", + "org.ow2.asm:asm-util", + "org.ow2.asm:asm-util:jar:sources", + "org.ow2.asm:asm:jar:sources", + "org.projectlombok:lombok", + "org.projectlombok:lombok:jar:sources", + "org.reactivestreams:reactive-streams", + "org.reactivestreams:reactive-streams:jar:sources", + "org.rnorth.duct-tape:duct-tape", + "org.rnorth.duct-tape:duct-tape:jar:sources", + "org.skyscreamer:jsonassert", + "org.skyscreamer:jsonassert:jar:sources", + "org.slf4j:jul-to-slf4j", + "org.slf4j:jul-to-slf4j:jar:sources", + "org.slf4j:slf4j-api", + "org.slf4j:slf4j-api:jar:sources", + "org.springdoc:springdoc-openapi-starter-common", + "org.springdoc:springdoc-openapi-starter-common:jar:sources", + "org.springdoc:springdoc-openapi-starter-webflux-api", + "org.springdoc:springdoc-openapi-starter-webflux-api:jar:sources", + "org.springdoc:springdoc-openapi-starter-webmvc-api", + "org.springdoc:springdoc-openapi-starter-webmvc-api:jar:sources", + "org.springframework.boot:spring-boot", + "org.springframework.boot:spring-boot-actuator", + "org.springframework.boot:spring-boot-actuator-autoconfigure", + "org.springframework.boot:spring-boot-actuator-autoconfigure:jar:sources", + "org.springframework.boot:spring-boot-actuator:jar:sources", + "org.springframework.boot:spring-boot-autoconfigure", + "org.springframework.boot:spring-boot-autoconfigure:jar:sources", + "org.springframework.boot:spring-boot-cassandra", + "org.springframework.boot:spring-boot-cassandra:jar:sources", + "org.springframework.boot:spring-boot-data-cassandra", + "org.springframework.boot:spring-boot-data-cassandra-test", + "org.springframework.boot:spring-boot-data-cassandra-test:jar:sources", + "org.springframework.boot:spring-boot-data-cassandra:jar:sources", + "org.springframework.boot:spring-boot-data-commons", + "org.springframework.boot:spring-boot-data-commons:jar:sources", + "org.springframework.boot:spring-boot-health", + "org.springframework.boot:spring-boot-health:jar:sources", + "org.springframework.boot:spring-boot-http-client", + "org.springframework.boot:spring-boot-http-client:jar:sources", + "org.springframework.boot:spring-boot-http-codec", + "org.springframework.boot:spring-boot-http-codec:jar:sources", + "org.springframework.boot:spring-boot-http-converter", + "org.springframework.boot:spring-boot-http-converter:jar:sources", + "org.springframework.boot:spring-boot-jackson", + "org.springframework.boot:spring-boot-jackson:jar:sources", + "org.springframework.boot:spring-boot-micrometer-metrics", + "org.springframework.boot:spring-boot-micrometer-metrics-test", + "org.springframework.boot:spring-boot-micrometer-metrics-test:jar:sources", + "org.springframework.boot:spring-boot-micrometer-metrics:jar:sources", + "org.springframework.boot:spring-boot-micrometer-observation", + "org.springframework.boot:spring-boot-micrometer-observation:jar:sources", + "org.springframework.boot:spring-boot-micrometer-tracing", + "org.springframework.boot:spring-boot-micrometer-tracing-opentelemetry", + "org.springframework.boot:spring-boot-micrometer-tracing-opentelemetry:jar:sources", + "org.springframework.boot:spring-boot-micrometer-tracing:jar:sources", + "org.springframework.boot:spring-boot-netty", + "org.springframework.boot:spring-boot-netty:jar:sources", + "org.springframework.boot:spring-boot-opentelemetry", + "org.springframework.boot:spring-boot-opentelemetry:jar:sources", + "org.springframework.boot:spring-boot-persistence", + "org.springframework.boot:spring-boot-persistence:jar:sources", + "org.springframework.boot:spring-boot-reactor", + "org.springframework.boot:spring-boot-reactor-netty", + "org.springframework.boot:spring-boot-reactor-netty:jar:sources", + "org.springframework.boot:spring-boot-reactor:jar:sources", + "org.springframework.boot:spring-boot-restclient", + "org.springframework.boot:spring-boot-restclient:jar:sources", + "org.springframework.boot:spring-boot-resttestclient", + "org.springframework.boot:spring-boot-resttestclient:jar:sources", + "org.springframework.boot:spring-boot-security", + "org.springframework.boot:spring-boot-security-oauth2-client", + "org.springframework.boot:spring-boot-security-oauth2-client:jar:sources", + "org.springframework.boot:spring-boot-security-oauth2-resource-server", + "org.springframework.boot:spring-boot-security-oauth2-resource-server:jar:sources", + "org.springframework.boot:spring-boot-security-test", + "org.springframework.boot:spring-boot-security-test:jar:sources", + "org.springframework.boot:spring-boot-security:jar:sources", + "org.springframework.boot:spring-boot-servlet", + "org.springframework.boot:spring-boot-servlet:jar:sources", + "org.springframework.boot:spring-boot-starter", + "org.springframework.boot:spring-boot-starter-actuator", + "org.springframework.boot:spring-boot-starter-actuator-test", + "org.springframework.boot:spring-boot-starter-actuator-test:jar:sources", + "org.springframework.boot:spring-boot-starter-actuator:jar:sources", + "org.springframework.boot:spring-boot-starter-data-cassandra", + "org.springframework.boot:spring-boot-starter-data-cassandra-test", + "org.springframework.boot:spring-boot-starter-data-cassandra-test:jar:sources", + "org.springframework.boot:spring-boot-starter-data-cassandra:jar:sources", + "org.springframework.boot:spring-boot-starter-jackson", + "org.springframework.boot:spring-boot-starter-jackson-test", + "org.springframework.boot:spring-boot-starter-jackson-test:jar:sources", + "org.springframework.boot:spring-boot-starter-jackson:jar:sources", + "org.springframework.boot:spring-boot-starter-logging", + "org.springframework.boot:spring-boot-starter-logging:jar:sources", + "org.springframework.boot:spring-boot-starter-micrometer-metrics", + "org.springframework.boot:spring-boot-starter-micrometer-metrics-test", + "org.springframework.boot:spring-boot-starter-micrometer-metrics-test:jar:sources", + "org.springframework.boot:spring-boot-starter-micrometer-metrics:jar:sources", + "org.springframework.boot:spring-boot-starter-reactor-netty", + "org.springframework.boot:spring-boot-starter-reactor-netty:jar:sources", + "org.springframework.boot:spring-boot-starter-security", + "org.springframework.boot:spring-boot-starter-security-oauth2-client", + "org.springframework.boot:spring-boot-starter-security-oauth2-client:jar:sources", + "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server", + "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server-test", + "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server-test:jar:sources", + "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server:jar:sources", + "org.springframework.boot:spring-boot-starter-security-test", + "org.springframework.boot:spring-boot-starter-security-test:jar:sources", + "org.springframework.boot:spring-boot-starter-security:jar:sources", + "org.springframework.boot:spring-boot-starter-test", + "org.springframework.boot:spring-boot-starter-test:jar:sources", + "org.springframework.boot:spring-boot-starter-tomcat", + "org.springframework.boot:spring-boot-starter-tomcat-runtime", + "org.springframework.boot:spring-boot-starter-tomcat-runtime:jar:sources", + "org.springframework.boot:spring-boot-starter-tomcat:jar:sources", + "org.springframework.boot:spring-boot-starter-validation", + "org.springframework.boot:spring-boot-starter-validation:jar:sources", + "org.springframework.boot:spring-boot-starter-webflux", + "org.springframework.boot:spring-boot-starter-webflux-test", + "org.springframework.boot:spring-boot-starter-webflux-test:jar:sources", + "org.springframework.boot:spring-boot-starter-webflux:jar:sources", + "org.springframework.boot:spring-boot-starter-webmvc", + "org.springframework.boot:spring-boot-starter-webmvc-test", + "org.springframework.boot:spring-boot-starter-webmvc-test:jar:sources", + "org.springframework.boot:spring-boot-starter-webmvc:jar:sources", + "org.springframework.boot:spring-boot-starter:jar:sources", + "org.springframework.boot:spring-boot-test", + "org.springframework.boot:spring-boot-test-autoconfigure", + "org.springframework.boot:spring-boot-test-autoconfigure:jar:sources", + "org.springframework.boot:spring-boot-test:jar:sources", + "org.springframework.boot:spring-boot-tomcat", + "org.springframework.boot:spring-boot-tomcat:jar:sources", + "org.springframework.boot:spring-boot-validation", + "org.springframework.boot:spring-boot-validation:jar:sources", + "org.springframework.boot:spring-boot-web-server", + "org.springframework.boot:spring-boot-web-server:jar:sources", + "org.springframework.boot:spring-boot-webclient", + "org.springframework.boot:spring-boot-webclient:jar:sources", + "org.springframework.boot:spring-boot-webflux", + "org.springframework.boot:spring-boot-webflux-test", + "org.springframework.boot:spring-boot-webflux-test:jar:sources", + "org.springframework.boot:spring-boot-webflux:jar:sources", + "org.springframework.boot:spring-boot-webmvc", + "org.springframework.boot:spring-boot-webmvc-test", + "org.springframework.boot:spring-boot-webmvc-test:jar:sources", + "org.springframework.boot:spring-boot-webmvc:jar:sources", + "org.springframework.boot:spring-boot-webtestclient", + "org.springframework.boot:spring-boot-webtestclient:jar:sources", + "org.springframework.boot:spring-boot:jar:sources", + "org.springframework.cloud:spring-cloud-commons", + "org.springframework.cloud:spring-cloud-commons:jar:sources", + "org.springframework.cloud:spring-cloud-context", + "org.springframework.cloud:spring-cloud-context:jar:sources", + "org.springframework.cloud:spring-cloud-starter", + "org.springframework.cloud:spring-cloud-starter-bootstrap", + "org.springframework.cloud:spring-cloud-starter-bootstrap:jar:sources", + "org.springframework.data:spring-data-cassandra", + "org.springframework.data:spring-data-cassandra:jar:sources", + "org.springframework.data:spring-data-commons", + "org.springframework.data:spring-data-commons:jar:sources", + "org.springframework.security:spring-security-config", + "org.springframework.security:spring-security-config:jar:sources", + "org.springframework.security:spring-security-core", + "org.springframework.security:spring-security-core:jar:sources", + "org.springframework.security:spring-security-crypto", + "org.springframework.security:spring-security-crypto:jar:sources", + "org.springframework.security:spring-security-oauth2-client", + "org.springframework.security:spring-security-oauth2-client:jar:sources", + "org.springframework.security:spring-security-oauth2-core", + "org.springframework.security:spring-security-oauth2-core:jar:sources", + "org.springframework.security:spring-security-oauth2-jose", + "org.springframework.security:spring-security-oauth2-jose:jar:sources", + "org.springframework.security:spring-security-oauth2-resource-server", + "org.springframework.security:spring-security-oauth2-resource-server:jar:sources", + "org.springframework.security:spring-security-test", + "org.springframework.security:spring-security-test:jar:sources", + "org.springframework.security:spring-security-web", + "org.springframework.security:spring-security-web:jar:sources", + "org.springframework:spring-aop", + "org.springframework:spring-aop:jar:sources", + "org.springframework:spring-beans", + "org.springframework:spring-beans:jar:sources", + "org.springframework:spring-context", + "org.springframework:spring-context:jar:sources", + "org.springframework:spring-core", + "org.springframework:spring-core:jar:sources", + "org.springframework:spring-expression", + "org.springframework:spring-expression:jar:sources", + "org.springframework:spring-test", + "org.springframework:spring-test:jar:sources", + "org.springframework:spring-tx", + "org.springframework:spring-tx:jar:sources", + "org.springframework:spring-web", + "org.springframework:spring-web:jar:sources", + "org.springframework:spring-webflux", + "org.springframework:spring-webflux:jar:sources", + "org.springframework:spring-webmvc", + "org.springframework:spring-webmvc:jar:sources", + "org.testcontainers:testcontainers", + "org.testcontainers:testcontainers-cassandra", + "org.testcontainers:testcontainers-cassandra:jar:sources", + "org.testcontainers:testcontainers-database-commons", + "org.testcontainers:testcontainers-database-commons:jar:sources", + "org.testcontainers:testcontainers-junit-jupiter", + "org.testcontainers:testcontainers-junit-jupiter:jar:sources", + "org.testcontainers:testcontainers:jar:sources", + "org.wiremock:wiremock-standalone", + "org.wiremock:wiremock-standalone:jar:sources", + "org.xmlunit:xmlunit-core", + "org.xmlunit:xmlunit-core:jar:sources", + "org.yaml:snakeyaml", + "org.yaml:snakeyaml:jar:sources", + "software.amazon.awssdk:annotations", + "software.amazon.awssdk:annotations:jar:sources", + "software.amazon.awssdk:checksums", + "software.amazon.awssdk:checksums-spi", + "software.amazon.awssdk:checksums-spi:jar:sources", + "software.amazon.awssdk:checksums:jar:sources", + "software.amazon.awssdk:endpoints-spi", + "software.amazon.awssdk:endpoints-spi:jar:sources", + "software.amazon.awssdk:http-auth-aws", + "software.amazon.awssdk:http-auth-aws:jar:sources", + "software.amazon.awssdk:http-auth-spi", + "software.amazon.awssdk:http-auth-spi:jar:sources", + "software.amazon.awssdk:http-client-spi", + "software.amazon.awssdk:http-client-spi:jar:sources", + "software.amazon.awssdk:identity-spi", + "software.amazon.awssdk:identity-spi:jar:sources", + "software.amazon.awssdk:json-utils", + "software.amazon.awssdk:json-utils:jar:sources", + "software.amazon.awssdk:metrics-spi", + "software.amazon.awssdk:metrics-spi:jar:sources", + "software.amazon.awssdk:profiles", + "software.amazon.awssdk:profiles:jar:sources", + "software.amazon.awssdk:regions", + "software.amazon.awssdk:regions:jar:sources", + "software.amazon.awssdk:retries", + "software.amazon.awssdk:retries-spi", + "software.amazon.awssdk:retries-spi:jar:sources", + "software.amazon.awssdk:retries:jar:sources", + "software.amazon.awssdk:sdk-core", + "software.amazon.awssdk:sdk-core:jar:sources", + "software.amazon.awssdk:third-party-jackson-core", + "software.amazon.awssdk:third-party-jackson-core:jar:sources", + "software.amazon.awssdk:utils", + "software.amazon.awssdk:utils:jar:sources", + "tools.jackson.core:jackson-core", + "tools.jackson.core:jackson-core:jar:sources", + "tools.jackson.core:jackson-databind", + "tools.jackson.core:jackson-databind:jar:sources", + "tools.jackson.module:jackson-module-blackbird", + "tools.jackson.module:jackson-module-blackbird:jar:sources" + ] + }, + "services": { + "ch.qos.logback:logback-classic": { + "jakarta.servlet.ServletContainerInitializer": [ + "ch.qos.logback.classic.servlet.LogbackServletContainerInitializer" + ], + "org.slf4j.spi.SLF4JServiceProvider": [ + "ch.qos.logback.classic.spi.LogbackServiceProvider" + ] + }, + "com.fasterxml.jackson.core:jackson-core": { + "com.fasterxml.jackson.core.JsonFactory": [ + "com.fasterxml.jackson.core.JsonFactory" + ] + }, + "com.fasterxml.jackson.core:jackson-databind": { + "com.fasterxml.jackson.core.ObjectCodec": [ + "com.fasterxml.jackson.databind.ObjectMapper" + ] + }, + "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml": { + "com.fasterxml.jackson.core.JsonFactory": [ + "com.fasterxml.jackson.dataformat.yaml.YAMLFactory" + ], + "com.fasterxml.jackson.core.ObjectCodec": [ + "com.fasterxml.jackson.dataformat.yaml.YAMLMapper" + ] + }, + "com.fasterxml.jackson.datatype:jackson-datatype-jsr310": { + "com.fasterxml.jackson.databind.Module": [ + "com.fasterxml.jackson.datatype.jsr310.JavaTimeModule" + ] + }, + "io.cloudevents:cloudevents-json-jackson": { + "io.cloudevents.core.format.EventFormat": [ + "io.cloudevents.jackson.JsonFormat" + ] + }, + "io.micrometer:micrometer-observation": { + "io.micrometer.context.ThreadLocalAccessor": [ + "io.micrometer.observation.contextpropagation.ObservationThreadLocalAccessor" + ] + }, + "io.netty:netty-common": { + "reactor.blockhound.integration.BlockHoundIntegration": [ + "io.netty.util.internal.Hidden$NettyBlockHoundIntegration" + ] + }, + "io.opentelemetry:opentelemetry-exporter-otlp": { + "io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider": [ + "io.opentelemetry.exporter.otlp.internal.OtlpGrpcLogRecordExporterComponentProvider", + "io.opentelemetry.exporter.otlp.internal.OtlpGrpcMetricExporterComponentProvider", + "io.opentelemetry.exporter.otlp.internal.OtlpGrpcSpanExporterComponentProvider", + "io.opentelemetry.exporter.otlp.internal.OtlpHttpLogRecordExporterComponentProvider", + "io.opentelemetry.exporter.otlp.internal.OtlpHttpMetricExporterComponentProvider", + "io.opentelemetry.exporter.otlp.internal.OtlpHttpSpanExporterComponentProvider" + ], + "io.opentelemetry.sdk.autoconfigure.spi.logs.ConfigurableLogRecordExporterProvider": [ + "io.opentelemetry.exporter.otlp.internal.OtlpLogRecordExporterProvider" + ], + "io.opentelemetry.sdk.autoconfigure.spi.metrics.ConfigurableMetricExporterProvider": [ + "io.opentelemetry.exporter.otlp.internal.OtlpMetricExporterProvider" + ], + "io.opentelemetry.sdk.autoconfigure.spi.traces.ConfigurableSpanExporterProvider": [ + "io.opentelemetry.exporter.otlp.internal.OtlpSpanExporterProvider" + ] + }, + "io.opentelemetry:opentelemetry-exporter-sender-okhttp": { + "io.opentelemetry.exporter.internal.grpc.GrpcSenderProvider": [ + "io.opentelemetry.exporter.sender.okhttp.internal.OkHttpGrpcSenderProvider" + ], + "io.opentelemetry.exporter.internal.http.HttpSenderProvider": [ + "io.opentelemetry.exporter.sender.okhttp.internal.OkHttpHttpSenderProvider" + ] + }, + "io.opentelemetry:opentelemetry-extension-trace-propagators": { + "io.opentelemetry.sdk.autoconfigure.spi.ConfigurablePropagatorProvider": [ + "io.opentelemetry.extension.trace.propagation.B3ConfigurablePropagator", + "io.opentelemetry.extension.trace.propagation.B3MultiConfigurablePropagator", + "io.opentelemetry.extension.trace.propagation.JaegerConfigurablePropagator", + "io.opentelemetry.extension.trace.propagation.OtTraceConfigurablePropagator" + ], + "io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider": [ + "io.opentelemetry.extension.trace.propagation.internal.B3ComponentProvider", + "io.opentelemetry.extension.trace.propagation.internal.B3MultiComponentProvider", + "io.opentelemetry.extension.trace.propagation.internal.JaegerComponentProvider", + "io.opentelemetry.extension.trace.propagation.internal.OtTraceComponentProvider" + ] + }, + "io.opentelemetry:opentelemetry-sdk-testing": { + "io.opentelemetry.context.ContextStorageProvider": [ + "io.opentelemetry.sdk.testing.context.SettableContextStorageProvider" + ] + }, + "io.projectreactor.netty:reactor-netty-core": { + "io.micrometer.context.ContextAccessor": [ + "reactor.netty.contextpropagation.ChannelContextAccessor" + ] + }, + "io.projectreactor:reactor-core": { + "io.micrometer.context.ContextAccessor": [ + "reactor.util.context.ReactorContextAccessor" + ], + "reactor.blockhound.integration.BlockHoundIntegration": [ + "reactor.core.scheduler.ReactorBlockHoundIntegration" + ] + }, + "org.apache.cassandra:java-driver-core": { + "reactor.blockhound.integration.BlockHoundIntegration": [ + "com.datastax.oss.driver.internal.core.util.concurrent.DriverBlockHoundIntegration" + ] + }, + "org.apache.logging.log4j:log4j-api": { + "org.apache.logging.log4j.util.PropertySource": [ + "org.apache.logging.log4j.util.EnvironmentPropertySource", + "org.apache.logging.log4j.util.SystemPropertiesPropertySource" + ] + }, + "org.apache.logging.log4j:log4j-to-slf4j": { + "org.apache.logging.log4j.spi.Provider": [ + "org.apache.logging.slf4j.SLF4JProvider" + ] + }, + "org.apache.tomcat.embed:tomcat-embed-el": { + "jakarta.el.ExpressionFactory": [ + "org.apache.el.ExpressionFactoryImpl" + ] + }, + "org.apache.tomcat.embed:tomcat-embed-websocket": { + "jakarta.servlet.ServletContainerInitializer": [ + "org.apache.tomcat.websocket.server.WsSci" + ], + "jakarta.websocket.ContainerProvider": [ + "org.apache.tomcat.websocket.WsContainerProvider" + ], + "jakarta.websocket.server.ServerEndpointConfig$Configurator": [ + "org.apache.tomcat.websocket.server.DefaultServerEndpointConfigurator" + ] + }, + "org.bouncycastle:bcprov-jdk18on": { + "java.security.Provider": [ + "org.bouncycastle.jce.provider.BouncyCastleProvider", + "org.bouncycastle.pqc.jcajce.provider.BouncyCastlePQCProvider" + ] + }, + "org.bouncycastle:bcprov-lts8on": { + "java.security.Provider": [ + "org.bouncycastle.jce.provider.BouncyCastleProvider", + "org.bouncycastle.pqc.jcajce.provider.BouncyCastlePQCProvider" + ] + }, + "org.hibernate.validator:hibernate-validator": { + "jakarta.validation.spi.ValidationProvider": [ + "org.hibernate.validator.HibernateValidator" + ] + }, + "org.junit.jupiter:junit-jupiter-engine": { + "org.junit.platform.engine.TestEngine": [ + "org.junit.jupiter.engine.JupiterTestEngine" + ] + }, + "org.junit.platform:junit-platform-console-standalone": { + "java.util.spi.ToolProvider": [ + "org.junit.platform.console.ConsoleLauncherToolProvider" + ], + "org.junit.platform.engine.TestEngine": [ + "org.junit.jupiter.engine.JupiterTestEngine", + "org.junit.platform.suite.engine.SuiteTestEngine", + "org.junit.vintage.engine.VintageTestEngine" + ], + "org.junit.platform.engine.discovery.DiscoverySelectorIdentifierParser": [ + "org.junit.platform.engine.discovery.ClassSelector$IdentifierParser", + "org.junit.platform.engine.discovery.ClasspathResourceSelector$IdentifierParser", + "org.junit.platform.engine.discovery.ClasspathRootSelector$IdentifierParser", + "org.junit.platform.engine.discovery.DirectorySelector$IdentifierParser", + "org.junit.platform.engine.discovery.FileSelector$IdentifierParser", + "org.junit.platform.engine.discovery.IterationSelector$IdentifierParser", + "org.junit.platform.engine.discovery.MethodSelector$IdentifierParser", + "org.junit.platform.engine.discovery.ModuleSelector$IdentifierParser", + "org.junit.platform.engine.discovery.NestedClassSelector$IdentifierParser", + "org.junit.platform.engine.discovery.NestedMethodSelector$IdentifierParser", + "org.junit.platform.engine.discovery.PackageSelector$IdentifierParser", + "org.junit.platform.engine.discovery.UniqueIdSelector$IdentifierParser", + "org.junit.platform.engine.discovery.UriSelector$IdentifierParser" + ], + "org.junit.platform.launcher.TestExecutionListener": [ + "org.junit.platform.launcher.listeners.UniqueIdTrackingListener", + "org.junit.platform.reporting.open.xml.OpenTestReportGeneratingListener" + ], + "org.opentest4j.reporting.tooling.spi.htmlreport.Contributor": [ + "org.junit.platform.reporting.open.xml.JUnitContributor" + ] + }, + "org.junit.platform:junit-platform-engine": { + "org.junit.platform.engine.discovery.DiscoverySelectorIdentifierParser": [ + "org.junit.platform.engine.discovery.ClassSelector$IdentifierParser", + "org.junit.platform.engine.discovery.ClasspathResourceSelector$IdentifierParser", + "org.junit.platform.engine.discovery.ClasspathRootSelector$IdentifierParser", + "org.junit.platform.engine.discovery.DirectorySelector$IdentifierParser", + "org.junit.platform.engine.discovery.FileSelector$IdentifierParser", + "org.junit.platform.engine.discovery.IterationSelector$IdentifierParser", + "org.junit.platform.engine.discovery.MethodSelector$IdentifierParser", + "org.junit.platform.engine.discovery.ModuleSelector$IdentifierParser", + "org.junit.platform.engine.discovery.NestedClassSelector$IdentifierParser", + "org.junit.platform.engine.discovery.NestedMethodSelector$IdentifierParser", + "org.junit.platform.engine.discovery.PackageSelector$IdentifierParser", + "org.junit.platform.engine.discovery.UniqueIdSelector$IdentifierParser", + "org.junit.platform.engine.discovery.UriSelector$IdentifierParser" + ] + }, + "org.junit.platform:junit-platform-launcher": { + "org.junit.platform.launcher.TestExecutionListener": [ + "org.junit.platform.launcher.listeners.UniqueIdTrackingListener" + ] + }, + "org.junit.platform:junit-platform-reporting": { + "org.junit.platform.launcher.TestExecutionListener": [ + "org.junit.platform.reporting.open.xml.OpenTestReportGeneratingListener" + ], + "org.opentest4j.reporting.tooling.spi.htmlreport.Contributor": [ + "org.junit.platform.reporting.open.xml.JUnitContributor" + ] + }, + "org.projectlombok:lombok": { + "javax.annotation.processing.Processor": [ + "lombok.launch.AnnotationProcessorHider$AnnotationProcessor", + "lombok.launch.AnnotationProcessorHider$ClaimingProcessor" + ], + "lombok.core.LombokApp": [ + "lombok.bytecode.PoolConstantsApp", + "lombok.bytecode.PostCompilerApp", + "lombok.core.Main$LicenseApp", + "lombok.core.Main$VersionApp", + "lombok.core.PublicApiCreatorApp", + "lombok.core.configuration.ConfigurationApp", + "lombok.core.runtimeDependencies.CreateLombokRuntimeApp", + "lombok.delombok.DelombokApp", + "lombok.eclipse.agent.MavenEcjBootstrapApp", + "lombok.installer.Installer$CommandLineInstallerApp", + "lombok.installer.Installer$CommandLineUninstallerApp", + "lombok.installer.Installer$GraphicalInstallerApp" + ], + "lombok.core.PostCompilerTransformation": [ + "lombok.bytecode.PreventNullAnalysisRemover", + "lombok.bytecode.SneakyThrowsRemover" + ], + "lombok.core.runtimeDependencies.RuntimeDependencyInfo": [ + "lombok.core.handlers.SneakyThrowsAndCleanupDependencyInfo" + ], + "lombok.eclipse.EclipseASTVisitor": [ + "lombok.eclipse.handlers.HandleFieldDefaults", + "lombok.eclipse.handlers.HandleVal" + ], + "lombok.eclipse.EclipseAnnotationHandler": [ + "lombok.eclipse.handlers.HandleAccessors", + "lombok.eclipse.handlers.HandleBuilder", + "lombok.eclipse.handlers.HandleBuilderDefault", + "lombok.eclipse.handlers.HandleCleanup", + "lombok.eclipse.handlers.HandleConstructor$HandleAllArgsConstructor", + "lombok.eclipse.handlers.HandleConstructor$HandleNoArgsConstructor", + "lombok.eclipse.handlers.HandleConstructor$HandleRequiredArgsConstructor", + "lombok.eclipse.handlers.HandleData", + "lombok.eclipse.handlers.HandleDelegate", + "lombok.eclipse.handlers.HandleEqualsAndHashCode", + "lombok.eclipse.handlers.HandleExtensionMethod", + "lombok.eclipse.handlers.HandleFieldNameConstants", + "lombok.eclipse.handlers.HandleGetter", + "lombok.eclipse.handlers.HandleHelper", + "lombok.eclipse.handlers.HandleJacksonized", + "lombok.eclipse.handlers.HandleLocked", + "lombok.eclipse.handlers.HandleLockedRead", + "lombok.eclipse.handlers.HandleLockedWrite", + "lombok.eclipse.handlers.HandleLog$HandleCommonsLog", + "lombok.eclipse.handlers.HandleLog$HandleCustomLog", + "lombok.eclipse.handlers.HandleLog$HandleFloggerLog", + "lombok.eclipse.handlers.HandleLog$HandleJBossLog", + "lombok.eclipse.handlers.HandleLog$HandleJulLog", + "lombok.eclipse.handlers.HandleLog$HandleLog4j2Log", + "lombok.eclipse.handlers.HandleLog$HandleLog4jLog", + "lombok.eclipse.handlers.HandleLog$HandleSlf4jLog", + "lombok.eclipse.handlers.HandleLog$HandleXSlf4jLog", + "lombok.eclipse.handlers.HandleNonNull", + "lombok.eclipse.handlers.HandlePrintAST", + "lombok.eclipse.handlers.HandleSetter", + "lombok.eclipse.handlers.HandleSneakyThrows", + "lombok.eclipse.handlers.HandleStandardException", + "lombok.eclipse.handlers.HandleSuperBuilder", + "lombok.eclipse.handlers.HandleSynchronized", + "lombok.eclipse.handlers.HandleToString", + "lombok.eclipse.handlers.HandleUtilityClass", + "lombok.eclipse.handlers.HandleValue", + "lombok.eclipse.handlers.HandleWith", + "lombok.eclipse.handlers.HandleWithBy" + ], + "lombok.eclipse.handlers.EclipseSingularsRecipes$EclipseSingularizer": [ + "lombok.eclipse.handlers.singulars.EclipseGuavaMapSingularizer", + "lombok.eclipse.handlers.singulars.EclipseGuavaSetListSingularizer", + "lombok.eclipse.handlers.singulars.EclipseGuavaTableSingularizer", + "lombok.eclipse.handlers.singulars.EclipseJavaUtilListSingularizer", + "lombok.eclipse.handlers.singulars.EclipseJavaUtilMapSingularizer", + "lombok.eclipse.handlers.singulars.EclipseJavaUtilSetSingularizer" + ], + "lombok.installer.IdeLocationProvider": [ + "lombok.installer.eclipse.AngularIDELocationProvider", + "lombok.installer.eclipse.EclipseLocationProvider", + "lombok.installer.eclipse.JbdsLocationProvider", + "lombok.installer.eclipse.MyEclipseLocationProvider", + "lombok.installer.eclipse.RhcrLocationProvider", + "lombok.installer.eclipse.RhdsLocationProvider", + "lombok.installer.eclipse.STS4LocationProvider", + "lombok.installer.eclipse.STS5LocationProvider", + "lombok.installer.eclipse.STSLocationProvider" + ], + "lombok.javac.JavacASTVisitor": [ + "lombok.javac.handlers.HandleFieldDefaults", + "lombok.javac.handlers.HandleVal" + ], + "lombok.javac.JavacAnnotationHandler": [ + "lombok.javac.handlers.HandleAccessors", + "lombok.javac.handlers.HandleBuilder", + "lombok.javac.handlers.HandleBuilderDefault", + "lombok.javac.handlers.HandleBuilderDefaultRemove", + "lombok.javac.handlers.HandleBuilderRemove", + "lombok.javac.handlers.HandleCleanup", + "lombok.javac.handlers.HandleConstructor$HandleAllArgsConstructor", + "lombok.javac.handlers.HandleConstructor$HandleNoArgsConstructor", + "lombok.javac.handlers.HandleConstructor$HandleRequiredArgsConstructor", + "lombok.javac.handlers.HandleData", + "lombok.javac.handlers.HandleDelegate", + "lombok.javac.handlers.HandleEqualsAndHashCode", + "lombok.javac.handlers.HandleExtensionMethod", + "lombok.javac.handlers.HandleFieldNameConstants", + "lombok.javac.handlers.HandleGetter", + "lombok.javac.handlers.HandleHelper", + "lombok.javac.handlers.HandleJacksonized", + "lombok.javac.handlers.HandleLocked", + "lombok.javac.handlers.HandleLockedRead", + "lombok.javac.handlers.HandleLockedWrite", + "lombok.javac.handlers.HandleLog$HandleCommonsLog", + "lombok.javac.handlers.HandleLog$HandleCustomLog", + "lombok.javac.handlers.HandleLog$HandleFloggerLog", + "lombok.javac.handlers.HandleLog$HandleJBossLog", + "lombok.javac.handlers.HandleLog$HandleJulLog", + "lombok.javac.handlers.HandleLog$HandleLog4j2Log", + "lombok.javac.handlers.HandleLog$HandleLog4jLog", + "lombok.javac.handlers.HandleLog$HandleSlf4jLog", + "lombok.javac.handlers.HandleLog$HandleXSlf4jLog", + "lombok.javac.handlers.HandleNonNull", + "lombok.javac.handlers.HandlePrintAST", + "lombok.javac.handlers.HandleSetter", + "lombok.javac.handlers.HandleSingularRemove", + "lombok.javac.handlers.HandleSneakyThrows", + "lombok.javac.handlers.HandleStandardException", + "lombok.javac.handlers.HandleSuperBuilder", + "lombok.javac.handlers.HandleSuperBuilderRemove", + "lombok.javac.handlers.HandleSynchronized", + "lombok.javac.handlers.HandleToString", + "lombok.javac.handlers.HandleUtilityClass", + "lombok.javac.handlers.HandleValue", + "lombok.javac.handlers.HandleWith", + "lombok.javac.handlers.HandleWithBy" + ], + "lombok.javac.handlers.JavacSingularsRecipes$JavacSingularizer": [ + "lombok.javac.handlers.singulars.JavacGuavaMapSingularizer", + "lombok.javac.handlers.singulars.JavacGuavaSetListSingularizer", + "lombok.javac.handlers.singulars.JavacGuavaTableSingularizer", + "lombok.javac.handlers.singulars.JavacJavaUtilListSingularizer", + "lombok.javac.handlers.singulars.JavacJavaUtilMapSingularizer", + "lombok.javac.handlers.singulars.JavacJavaUtilSetSingularizer" + ] + }, + "org.springframework.boot:spring-boot": { + "ch.qos.logback.classic.spi.Configurator": [ + "org.springframework.boot.logging.logback.RootLogLevelConfigurator" + ], + "org.apache.logging.log4j.util.PropertySource": [ + "org.springframework.boot.logging.log4j2.SpringBootPropertySource" + ] + }, + "org.springframework.boot:spring-boot-micrometer-tracing-opentelemetry": { + "org.junit.platform.launcher.TestExecutionListener": [ + "org.springframework.boot.micrometer.tracing.opentelemetry.autoconfigure.OpenTelemetryEventPublisherBeansTestExecutionListener" + ] + }, + "org.springframework.data:spring-data-cassandra": { + "jakarta.enterprise.inject.spi.Extension": [ + "org.springframework.data.cassandra.repository.cdi.CassandraRepositoryExtension" + ] + }, + "org.springframework.security:spring-security-core": { + "io.micrometer.context.ThreadLocalAccessor": [ + "org.springframework.security.core.context.ReactiveSecurityContextHolderThreadLocalAccessor", + "org.springframework.security.core.context.SecurityContextHolderThreadLocalAccessor" + ] + }, + "org.springframework.security:spring-security-web": { + "io.micrometer.context.ThreadLocalAccessor": [ + "org.springframework.security.web.server.ServerWebExchangeThreadLocalAccessor" + ] + }, + "org.springframework:spring-core": { + "reactor.blockhound.integration.BlockHoundIntegration": [ + "org.springframework.core.ReactiveAdapterRegistry$SpringCoreBlockHoundIntegration" + ] + }, + "org.springframework:spring-web": { + "jakarta.servlet.ServletContainerInitializer": [ + "org.springframework.web.SpringServletContainerInitializer" + ], + "reactor.blockhound.integration.BlockHoundIntegration": [ + "org.springframework.web.server.adapter.WebHttpHandlerBuilder$SpringWebBlockHoundIntegration" + ] + }, + "org.testcontainers:testcontainers": { + "org.testcontainers.dockerclient.DockerClientProviderStrategy": [ + "org.testcontainers.dockerclient.DockerDesktopClientProviderStrategy", + "org.testcontainers.dockerclient.DockerMachineClientProviderStrategy", + "org.testcontainers.dockerclient.EnvironmentAndSystemPropertyClientProviderStrategy", + "org.testcontainers.dockerclient.NpipeSocketClientProviderStrategy", + "org.testcontainers.dockerclient.RootlessDockerClientProviderStrategy", + "org.testcontainers.dockerclient.TestcontainersHostPropertyClientProviderStrategy", + "org.testcontainers.dockerclient.UnixSocketClientProviderStrategy" + ], + "org.testcontainers.shaded.com.fasterxml.jackson.core.JsonFactory": [ + "org.testcontainers.shaded.com.fasterxml.jackson.core.JsonFactory" + ], + "org.testcontainers.shaded.com.fasterxml.jackson.core.ObjectCodec": [ + "org.testcontainers.shaded.com.fasterxml.jackson.databind.ObjectMapper" + ] + }, + "org.wiremock:wiremock-standalone": { + "wiremock.com.fasterxml.jackson.core.JsonFactory": [ + "wiremock.com.fasterxml.jackson.core.JsonFactory", + "wiremock.com.fasterxml.jackson.dataformat.yaml.YAMLFactory" + ], + "wiremock.com.fasterxml.jackson.core.ObjectCodec": [ + "wiremock.com.fasterxml.jackson.databind.ObjectMapper", + "wiremock.com.fasterxml.jackson.dataformat.yaml.YAMLMapper" + ], + "wiremock.com.fasterxml.jackson.databind.Module": [ + "wiremock.com.fasterxml.jackson.datatype.jsr310.JavaTimeModule" + ], + "wiremock.org.eclipse.jetty.http.HttpFieldPreEncoder": [ + "wiremock.org.eclipse.jetty.http.Http1FieldPreEncoder", + "wiremock.org.eclipse.jetty.http2.hpack.HpackFieldPreEncoder" + ], + "wiremock.org.eclipse.jetty.io.ssl.ALPNProcessor$Client": [ + "wiremock.org.eclipse.jetty.alpn.java.client.JDK9ClientALPNProcessor" + ], + "wiremock.org.eclipse.jetty.io.ssl.ALPNProcessor$Server": [ + "wiremock.org.eclipse.jetty.alpn.java.server.JDK9ServerALPNProcessor" + ], + "wiremock.org.eclipse.jetty.webapp.Configuration": [ + "wiremock.org.eclipse.jetty.webapp.FragmentConfiguration", + "wiremock.org.eclipse.jetty.webapp.JaasConfiguration", + "wiremock.org.eclipse.jetty.webapp.JaspiConfiguration", + "wiremock.org.eclipse.jetty.webapp.JettyWebXmlConfiguration", + "wiremock.org.eclipse.jetty.webapp.JmxConfiguration", + "wiremock.org.eclipse.jetty.webapp.JndiConfiguration", + "wiremock.org.eclipse.jetty.webapp.JspConfiguration", + "wiremock.org.eclipse.jetty.webapp.MetaInfConfiguration", + "wiremock.org.eclipse.jetty.webapp.ServletsConfiguration", + "wiremock.org.eclipse.jetty.webapp.WebAppConfiguration", + "wiremock.org.eclipse.jetty.webapp.WebInfConfiguration", + "wiremock.org.eclipse.jetty.webapp.WebXmlConfiguration" + ], + "wiremock.org.slf4j.spi.SLF4JServiceProvider": [ + "wiremock.org.slf4j.helpers.NOP_FallbackServiceProvider" + ], + "wiremock.org.xmlunit.placeholder.PlaceholderHandler": [ + "wiremock.org.xmlunit.placeholder.IgnorePlaceholderHandler", + "wiremock.org.xmlunit.placeholder.IsDateTimePlaceholderHandler", + "wiremock.org.xmlunit.placeholder.IsNumberPlaceholderHandler", + "wiremock.org.xmlunit.placeholder.MatchesRegexPlaceholderHandler" + ] + }, + "software.amazon.awssdk:third-party-jackson-core": { + "software.amazon.awssdk.thirdparty.jackson.core.JsonFactory": [ + "software.amazon.awssdk.thirdparty.jackson.core.JsonFactory" + ] + }, + "tools.jackson.core:jackson-core": { + "tools.jackson.core.TokenStreamFactory": [ + "tools.jackson.core.json.JsonFactory" + ] + }, + "tools.jackson.core:jackson-databind": { + "tools.jackson.databind.ObjectMapper": [ + "tools.jackson.databind.json.JsonMapper" + ] + }, + "tools.jackson.module:jackson-module-blackbird": { + "tools.jackson.databind.JacksonModule": [ + "tools.jackson.module.blackbird.BlackbirdModule" + ] + } + }, + "skipped": [], + "version": "3" +} diff --git a/src/libraries/java/nv-boot-parent/nv-boot-mock-servers-test/BUILD.bazel b/src/libraries/java/nv-boot-parent/nv-boot-mock-servers-test/BUILD.bazel index 29aa85795..a89ecf6bd 100644 --- a/src/libraries/java/nv-boot-parent/nv-boot-mock-servers-test/BUILD.bazel +++ b/src/libraries/java/nv-boot-parent/nv-boot-mock-servers-test/BUILD.bazel @@ -1,22 +1,22 @@ -load("//src/libraries/java/nv-boot-parent/tools/bazel:java.bzl", "nv_boot_library", "nv_boot_library_test") +load("//tools/bazel:java.bzl", "nv_boot_library", "nv_boot_library_test") MOCK_SERVERS_COMPILE_DEPS = [ - "@nv_third_party_deps//:com_fasterxml_jackson_core_jackson_annotations", - "@nv_third_party_deps//:com_nimbusds_nimbus_jose_jwt", - "@nv_third_party_deps//:jakarta_annotation_jakarta_annotation_api", - "@nv_third_party_deps//:jakarta_validation_jakarta_validation_api", - "@nv_third_party_deps//:org_apache_commons_commons_lang3", - "@nv_third_party_deps//:org_apache_logging_log4j_log4j_api", - "@nv_third_party_deps//:org_slf4j_slf4j_api", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_autoconfigure", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_jackson", - "@nv_third_party_deps//:org_springframework_cloud_spring_cloud_context", - "@nv_third_party_deps//:org_springframework_security_spring_security_oauth2_core", - "@nv_third_party_deps//:org_springframework_security_spring_security_oauth2_jose", - "@nv_third_party_deps//:org_springframework_spring_context", - "@nv_third_party_deps//:org_springframework_spring_web", - "@nv_third_party_deps//:org_wiremock_wiremock_standalone", - "@nv_third_party_deps//:tools_jackson_core_jackson_databind", + "@maven//:com_fasterxml_jackson_core_jackson_annotations", + "@maven//:com_nimbusds_nimbus_jose_jwt", + "@maven//:jakarta_annotation_jakarta_annotation_api", + "@maven//:jakarta_validation_jakarta_validation_api", + "@maven//:org_apache_commons_commons_lang3", + "@maven//:org_apache_logging_log4j_log4j_api", + "@maven//:org_slf4j_slf4j_api", + "@maven//:org_springframework_boot_spring_boot_autoconfigure", + "@maven//:org_springframework_boot_spring_boot_starter_jackson", + "@maven//:org_springframework_cloud_spring_cloud_context", + "@maven//:org_springframework_security_spring_security_oauth2_core", + "@maven//:org_springframework_security_spring_security_oauth2_jose", + "@maven//:org_springframework_spring_context", + "@maven//:org_springframework_spring_web", + "@maven//:org_wiremock_wiremock_standalone", + "@maven//:tools_jackson_core_jackson_databind", ] nv_boot_library( diff --git a/src/libraries/java/nv-boot-parent/nv-boot-starter-audit/BUILD.bazel b/src/libraries/java/nv-boot-parent/nv-boot-starter-audit/BUILD.bazel index 83dc87abf..2adccbeb8 100644 --- a/src/libraries/java/nv-boot-parent/nv-boot-starter-audit/BUILD.bazel +++ b/src/libraries/java/nv-boot-parent/nv-boot-starter-audit/BUILD.bazel @@ -1,33 +1,33 @@ load("@rules_java//java:defs.bzl", "java_library") -load("//src/libraries/java/nv-boot-parent/tools/bazel:java.bzl", "nv_boot_library", "nv_boot_library_test", "nv_boot_runtime_classpath_test") +load("//tools/bazel:java.bzl", "nv_boot_library", "nv_boot_library_test", "nv_boot_runtime_classpath_test") AUDIT_REQUIRED_DEPS = [ - "@nv_third_party_deps//:com_fasterxml_jackson_core_jackson_annotations", - "@nv_third_party_deps//:com_fasterxml_jackson_core_jackson_databind", - "@nv_third_party_deps//:com_github_java_json_tools_json_patch", - "@nv_third_party_deps//:org_apache_commons_commons_lang3", - "@nv_third_party_deps//:org_bouncycastle_bcprov_jdk18on", - "@nv_third_party_deps//:org_slf4j_slf4j_api", - "@nv_third_party_deps//:org_springframework_boot_spring_boot", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_autoconfigure", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_jackson", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_jackson", - "@nv_third_party_deps//:org_springframework_security_spring_security_core", - "@nv_third_party_deps//:org_springframework_spring_beans", - "@nv_third_party_deps//:org_springframework_spring_context", - "@nv_third_party_deps//:org_springframework_spring_core", - "@nv_third_party_deps//:tools_jackson_core_jackson_core", - "@nv_third_party_deps//:tools_jackson_core_jackson_databind", + "@maven//:com_fasterxml_jackson_core_jackson_annotations", + "@maven//:com_fasterxml_jackson_core_jackson_databind", + "@maven//:com_github_java_json_tools_json_patch", + "@maven//:org_apache_commons_commons_lang3", + "@maven//:org_bouncycastle_bcprov_jdk18on", + "@maven//:org_slf4j_slf4j_api", + "@maven//:org_springframework_boot_spring_boot", + "@maven//:org_springframework_boot_spring_boot_autoconfigure", + "@maven//:org_springframework_boot_spring_boot_jackson", + "@maven//:org_springframework_boot_spring_boot_starter", + "@maven//:org_springframework_boot_spring_boot_starter_jackson", + "@maven//:org_springframework_security_spring_security_core", + "@maven//:org_springframework_spring_beans", + "@maven//:org_springframework_spring_context", + "@maven//:org_springframework_spring_core", + "@maven//:tools_jackson_core_jackson_core", + "@maven//:tools_jackson_core_jackson_databind", ] # The OAuth2 resource-server starter is optional in Maven. Keep its APIs on # this module's compile/test classpaths without exporting them at runtime. AUDIT_OPTIONAL_COMPILE_DEPS = [ - "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_security_oauth2_resource_server", - "@nv_third_party_deps//:org_springframework_security_spring_security_oauth2_core", - "@nv_third_party_deps//:org_springframework_security_spring_security_oauth2_jose", - "@nv_third_party_deps//:org_springframework_security_spring_security_oauth2_resource_server", + "@maven//:org_springframework_boot_spring_boot_starter_security_oauth2_resource_server", + "@maven//:org_springframework_security_spring_security_oauth2_core", + "@maven//:org_springframework_security_spring_security_oauth2_jose", + "@maven//:org_springframework_security_spring_security_oauth2_resource_server", ] java_library( @@ -40,7 +40,7 @@ java_library( nv_boot_library( name = "nv_boot_starter_audit", srcs = glob(["src/main/java/**/*.java"]), - resource_strip_prefix = "src/libraries/java/nv-boot-parent/nv-boot-starter-audit/src/main/resources", + resource_strip_prefix = "nv-boot-starter-audit/src/main/resources", resources = glob(["src/main/resources/**"]), visibility = ["//visibility:public"], deps = AUDIT_REQUIRED_DEPS + [":optional_compile_deps"], @@ -62,9 +62,9 @@ nv_boot_library_test( coverage_library = ":nv_boot_starter_audit", deps = [ ":nv_boot_starter_audit", - "@nv_third_party_deps//:ch_qos_logback_logback_classic", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_security_oauth2_resource_server_test", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_test", - "@nv_third_party_deps//:org_springframework_security_spring_security_test", + "@maven//:ch_qos_logback_logback_classic", + "@maven//:org_springframework_boot_spring_boot_starter_security_oauth2_resource_server_test", + "@maven//:org_springframework_boot_spring_boot_starter_test", + "@maven//:org_springframework_security_spring_security_test", ] + AUDIT_REQUIRED_DEPS + AUDIT_OPTIONAL_COMPILE_DEPS, ) diff --git a/src/libraries/java/nv-boot-parent/nv-boot-starter-cassandra/BUILD.bazel b/src/libraries/java/nv-boot-parent/nv-boot-starter-cassandra/BUILD.bazel index 2f68d4a3c..014ae1837 100644 --- a/src/libraries/java/nv-boot-parent/nv-boot-starter-cassandra/BUILD.bazel +++ b/src/libraries/java/nv-boot-parent/nv-boot-starter-cassandra/BUILD.bazel @@ -1,53 +1,53 @@ -load("//src/libraries/java/nv-boot-parent/tools/bazel:java.bzl", "nv_boot_library", "nv_boot_library_test") +load("//tools/bazel:java.bzl", "nv_boot_library", "nv_boot_library_test") CASSANDRA_COMPILE_DEPS = [ - "@nv_third_party_deps//:at_yawk_lz4_lz4_java", - "@nv_third_party_deps//:com_github_ben_manes_caffeine_guava", - "@nv_third_party_deps//:com_google_guava_guava", - "@nv_third_party_deps//:io_micrometer_micrometer_commons", - "@nv_third_party_deps//:io_micrometer_micrometer_core", - "@nv_third_party_deps//:io_micrometer_micrometer_observation", - "@nv_third_party_deps//:jakarta_annotation_jakarta_annotation_api", - "@nv_third_party_deps//:jakarta_validation_jakarta_validation_api", - "@nv_third_party_deps//:org_apache_cassandra_java_driver_core", - "@nv_third_party_deps//:org_apache_cassandra_java_driver_metrics_micrometer", - "@nv_third_party_deps//:org_apache_commons_commons_lang3", - "@nv_third_party_deps//:org_jspecify_jspecify", - "@nv_third_party_deps//:org_slf4j_slf4j_api", - "@nv_third_party_deps//:org_springframework_boot_spring_boot", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_actuator", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_actuator_autoconfigure", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_autoconfigure", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_cassandra", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_data_cassandra", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_health", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_actuator", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_data_cassandra", - "@nv_third_party_deps//:org_springframework_cloud_spring_cloud_context", - "@nv_third_party_deps//:org_springframework_data_spring_data_cassandra", - "@nv_third_party_deps//:org_springframework_data_spring_data_commons", - "@nv_third_party_deps//:org_springframework_spring_beans", - "@nv_third_party_deps//:org_springframework_spring_context", - "@nv_third_party_deps//:org_springframework_spring_core", + "@maven//:at_yawk_lz4_lz4_java", + "@maven//:com_github_ben_manes_caffeine_guava", + "@maven//:com_google_guava_guava", + "@maven//:io_micrometer_micrometer_commons", + "@maven//:io_micrometer_micrometer_core", + "@maven//:io_micrometer_micrometer_observation", + "@maven//:jakarta_annotation_jakarta_annotation_api", + "@maven//:jakarta_validation_jakarta_validation_api", + "@maven//:org_apache_cassandra_java_driver_core", + "@maven//:org_apache_cassandra_java_driver_metrics_micrometer", + "@maven//:org_apache_commons_commons_lang3", + "@maven//:org_jspecify_jspecify", + "@maven//:org_slf4j_slf4j_api", + "@maven//:org_springframework_boot_spring_boot", + "@maven//:org_springframework_boot_spring_boot_actuator", + "@maven//:org_springframework_boot_spring_boot_actuator_autoconfigure", + "@maven//:org_springframework_boot_spring_boot_autoconfigure", + "@maven//:org_springframework_boot_spring_boot_cassandra", + "@maven//:org_springframework_boot_spring_boot_data_cassandra", + "@maven//:org_springframework_boot_spring_boot_health", + "@maven//:org_springframework_boot_spring_boot_starter_actuator", + "@maven//:org_springframework_boot_spring_boot_starter_data_cassandra", + "@maven//:org_springframework_cloud_spring_cloud_context", + "@maven//:org_springframework_data_spring_data_cassandra", + "@maven//:org_springframework_data_spring_data_commons", + "@maven//:org_springframework_spring_beans", + "@maven//:org_springframework_spring_context", + "@maven//:org_springframework_spring_core", ] CASSANDRA_TEST_DEPS = [ ":nv_boot_starter_cassandra", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_actuator_test", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_data_cassandra_test", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_webmvc_test", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_webmvc_test", - "@nv_third_party_deps//:org_springframework_spring_aop", - "@nv_third_party_deps//:org_springframework_spring_web", - "@nv_third_party_deps//:org_testcontainers_testcontainers", - "@nv_third_party_deps//:org_testcontainers_testcontainers_cassandra", - "@nv_third_party_deps//:org_testcontainers_testcontainers_junit_jupiter", + "@maven//:org_springframework_boot_spring_boot_starter_actuator_test", + "@maven//:org_springframework_boot_spring_boot_starter_data_cassandra_test", + "@maven//:org_springframework_boot_spring_boot_starter_webmvc_test", + "@maven//:org_springframework_boot_spring_boot_webmvc_test", + "@maven//:org_springframework_spring_aop", + "@maven//:org_springframework_spring_web", + "@maven//:org_testcontainers_testcontainers", + "@maven//:org_testcontainers_testcontainers_cassandra", + "@maven//:org_testcontainers_testcontainers_junit_jupiter", ] + CASSANDRA_COMPILE_DEPS nv_boot_library( name = "nv_boot_starter_cassandra", srcs = glob(["src/main/java/**/*.java"]), - resource_strip_prefix = "src/libraries/java/nv-boot-parent/nv-boot-starter-cassandra/src/main/resources", + resource_strip_prefix = "nv-boot-starter-cassandra/src/main/resources", resources = glob(["src/main/resources/**"]), visibility = ["//visibility:public"], deps = CASSANDRA_COMPILE_DEPS, @@ -57,7 +57,7 @@ nv_boot_library_test( name = "tests", srcs = glob(["src/test/java/**/*.java"]), coverage_library = ":nv_boot_starter_cassandra", - resource_strip_prefix = "src/libraries/java/nv-boot-parent/nv-boot-starter-cassandra/src/test/resources", + resource_strip_prefix = "nv-boot-starter-cassandra/src/test/resources", resources = glob(["src/test/resources/**"]), deps = CASSANDRA_TEST_DEPS, size = "large", diff --git a/src/libraries/java/nv-boot-parent/nv-boot-starter-core/BUILD.bazel b/src/libraries/java/nv-boot-parent/nv-boot-starter-core/BUILD.bazel index 9ad6e524a..fe628e591 100644 --- a/src/libraries/java/nv-boot-parent/nv-boot-starter-core/BUILD.bazel +++ b/src/libraries/java/nv-boot-parent/nv-boot-starter-core/BUILD.bazel @@ -1,34 +1,34 @@ load("@rules_java//java:defs.bzl", "java_library") -load("//src/libraries/java/nv-boot-parent/tools/bazel:java.bzl", "nv_boot_library", "nv_boot_library_test", "nv_boot_runtime_classpath_test") +load("//tools/bazel:java.bzl", "nv_boot_library", "nv_boot_library_test", "nv_boot_runtime_classpath_test") CORE_REQUIRED_DEPS = [ - "@nv_third_party_deps//:com_github_ben_manes_caffeine_guava", - "@nv_third_party_deps//:com_google_guava_guava", - "@nv_third_party_deps//:jakarta_annotation_jakarta_annotation_api", - "@nv_third_party_deps//:org_apache_commons_commons_lang3", - "@nv_third_party_deps//:org_slf4j_slf4j_api", - "@nv_third_party_deps//:org_springframework_boot_spring_boot", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_actuator_autoconfigure", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_autoconfigure", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_health", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_actuator", - "@nv_third_party_deps//:org_springframework_cloud_spring_cloud_context", - "@nv_third_party_deps//:org_springframework_spring_beans", - "@nv_third_party_deps//:org_springframework_spring_context", - "@nv_third_party_deps//:org_springframework_spring_core", + "@maven//:com_github_ben_manes_caffeine_guava", + "@maven//:com_google_guava_guava", + "@maven//:jakarta_annotation_jakarta_annotation_api", + "@maven//:org_apache_commons_commons_lang3", + "@maven//:org_slf4j_slf4j_api", + "@maven//:org_springframework_boot_spring_boot", + "@maven//:org_springframework_boot_spring_boot_actuator_autoconfigure", + "@maven//:org_springframework_boot_spring_boot_autoconfigure", + "@maven//:org_springframework_boot_spring_boot_health", + "@maven//:org_springframework_boot_spring_boot_starter", + "@maven//:org_springframework_boot_spring_boot_starter_actuator", + "@maven//:org_springframework_cloud_spring_cloud_context", + "@maven//:org_springframework_spring_beans", + "@maven//:org_springframework_spring_context", + "@maven//:org_springframework_spring_core", ] # Maven optional/provided integrations must compile with the starter, but they # must not become runtime dependencies of every downstream Bazel application. CORE_OPTIONAL_COMPILE_DEPS = [ - "@nv_third_party_deps//:io_swagger_core_v3_swagger_models_jakarta", - "@nv_third_party_deps//:jakarta_servlet_jakarta_servlet_api", - "@nv_third_party_deps//:org_springdoc_springdoc_openapi_starter_webflux_api", - "@nv_third_party_deps//:org_springdoc_springdoc_openapi_starter_webmvc_api", - "@nv_third_party_deps//:org_springframework_spring_web", - "@nv_third_party_deps//:org_springframework_spring_webflux", - "@nv_third_party_deps//:org_springframework_spring_webmvc", + "@maven//:io_swagger_core_v3_swagger_models_jakarta", + "@maven//:jakarta_servlet_jakarta_servlet_api", + "@maven//:org_springdoc_springdoc_openapi_starter_webflux_api", + "@maven//:org_springdoc_springdoc_openapi_starter_webmvc_api", + "@maven//:org_springframework_spring_web", + "@maven//:org_springframework_spring_webflux", + "@maven//:org_springframework_spring_webmvc", ] java_library( @@ -41,7 +41,7 @@ java_library( nv_boot_library( name = "nv_boot_starter_core", srcs = glob(["src/main/java/**/*.java"]), - resource_strip_prefix = "src/libraries/java/nv-boot-parent/nv-boot-starter-core/src/main/resources", + resource_strip_prefix = "nv-boot-starter-core/src/main/resources", resources = glob(["src/main/resources/**"]), visibility = ["//visibility:public"], deps = CORE_REQUIRED_DEPS + [":optional_compile_deps"], @@ -65,14 +65,14 @@ nv_boot_library_test( name = "tests", srcs = glob(["src/test/java/**/*.java"]), coverage_library = ":nv_boot_starter_core", - resource_strip_prefix = "src/libraries/java/nv-boot-parent/nv-boot-starter-core/src/test/resources", + resource_strip_prefix = "nv-boot-starter-core/src/test/resources", resources = glob(["src/test/resources/**"]), deps = [ ":nv_boot_starter_core", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_actuator_test", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_webflux_test", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_webmvc_test", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_webmvc_test", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_webtestclient", + "@maven//:org_springframework_boot_spring_boot_starter_actuator_test", + "@maven//:org_springframework_boot_spring_boot_starter_webflux_test", + "@maven//:org_springframework_boot_spring_boot_starter_webmvc_test", + "@maven//:org_springframework_boot_spring_boot_webmvc_test", + "@maven//:org_springframework_boot_spring_boot_webtestclient", ] + CORE_REQUIRED_DEPS + CORE_OPTIONAL_COMPILE_DEPS, ) diff --git a/src/libraries/java/nv-boot-parent/nv-boot-starter-data-migration-notification/BUILD.bazel b/src/libraries/java/nv-boot-parent/nv-boot-starter-data-migration-notification/BUILD.bazel index 39b7b73cd..c02b707e1 100644 --- a/src/libraries/java/nv-boot-parent/nv-boot-starter-data-migration-notification/BUILD.bazel +++ b/src/libraries/java/nv-boot-parent/nv-boot-starter-data-migration-notification/BUILD.bazel @@ -1,30 +1,30 @@ -load("//src/libraries/java/nv-boot-parent/tools/bazel:java.bzl", "nv_boot_library", "nv_boot_library_test") +load("//tools/bazel:java.bzl", "nv_boot_library", "nv_boot_library_test") DATA_MIGRATION_NOTIFICATION_COMPILE_DEPS = [ - "@nv_third_party_deps//:io_cloudevents_cloudevents_api", - "@nv_third_party_deps//:io_cloudevents_cloudevents_core", - "@nv_third_party_deps//:io_cloudevents_cloudevents_json_jackson", - "@nv_third_party_deps//:io_nats_jnats", - "@nv_third_party_deps//:jakarta_annotation_jakarta_annotation_api", - "@nv_third_party_deps//:jakarta_validation_jakarta_validation_api", - "@nv_third_party_deps//:org_apache_commons_commons_lang3", - "@nv_third_party_deps//:org_slf4j_slf4j_api", - "@nv_third_party_deps//:org_springframework_boot_spring_boot", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_autoconfigure", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_jackson", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_jackson", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_validation", - "@nv_third_party_deps//:org_springframework_spring_beans", - "@nv_third_party_deps//:org_springframework_spring_context", - "@nv_third_party_deps//:org_springframework_spring_core", - "@nv_third_party_deps//:tools_jackson_core_jackson_databind", + "@maven//:io_cloudevents_cloudevents_api", + "@maven//:io_cloudevents_cloudevents_core", + "@maven//:io_cloudevents_cloudevents_json_jackson", + "@maven//:io_nats_jnats", + "@maven//:jakarta_annotation_jakarta_annotation_api", + "@maven//:jakarta_validation_jakarta_validation_api", + "@maven//:org_apache_commons_commons_lang3", + "@maven//:org_slf4j_slf4j_api", + "@maven//:org_springframework_boot_spring_boot", + "@maven//:org_springframework_boot_spring_boot_autoconfigure", + "@maven//:org_springframework_boot_spring_boot_jackson", + "@maven//:org_springframework_boot_spring_boot_starter", + "@maven//:org_springframework_boot_spring_boot_starter_jackson", + "@maven//:org_springframework_boot_spring_boot_starter_validation", + "@maven//:org_springframework_spring_beans", + "@maven//:org_springframework_spring_context", + "@maven//:org_springframework_spring_core", + "@maven//:tools_jackson_core_jackson_databind", ] nv_boot_library( name = "nv_boot_starter_data_migration_notification", srcs = glob(["src/main/java/**/*.java"]), - resource_strip_prefix = "src/libraries/java/nv-boot-parent/nv-boot-starter-data-migration-notification/src/main/resources", + resource_strip_prefix = "nv-boot-starter-data-migration-notification/src/main/resources", resources = glob(["src/main/resources/**"]), visibility = ["//visibility:public"], deps = DATA_MIGRATION_NOTIFICATION_COMPILE_DEPS, @@ -36,6 +36,6 @@ nv_boot_library_test( coverage_library = ":nv_boot_starter_data_migration_notification", deps = [ ":nv_boot_starter_data_migration_notification", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_test", + "@maven//:org_springframework_boot_spring_boot_starter_test", ] + DATA_MIGRATION_NOTIFICATION_COMPILE_DEPS, ) diff --git a/src/libraries/java/nv-boot-parent/nv-boot-starter-exceptions/BUILD.bazel b/src/libraries/java/nv-boot-parent/nv-boot-starter-exceptions/BUILD.bazel index fe3126253..a3cc5ef8f 100644 --- a/src/libraries/java/nv-boot-parent/nv-boot-starter-exceptions/BUILD.bazel +++ b/src/libraries/java/nv-boot-parent/nv-boot-starter-exceptions/BUILD.bazel @@ -1,25 +1,25 @@ load("@rules_java//java:defs.bzl", "java_library") -load("//src/libraries/java/nv-boot-parent/tools/bazel:java.bzl", "nv_boot_library", "nv_boot_library_test", "nv_boot_runtime_classpath_test") +load("//tools/bazel:java.bzl", "nv_boot_library", "nv_boot_library_test", "nv_boot_runtime_classpath_test") EXCEPTIONS_REQUIRED_DEPS = [ - "@nv_third_party_deps//:jakarta_annotation_jakarta_annotation_api", - "@nv_third_party_deps//:org_slf4j_slf4j_api", + "@maven//:jakarta_annotation_jakarta_annotation_api", + "@maven//:org_slf4j_slf4j_api", ] # Maven marks the Spring MVC, WebFlux, Security, and autoconfiguration APIs as # optional/provided. They compile conditional handlers but must not select a # downstream application's web stack or security runtime. EXCEPTIONS_OPTIONAL_COMPILE_DEPS = [ - "@nv_third_party_deps//:io_projectreactor_reactor_core", - "@nv_third_party_deps//:org_jspecify_jspecify", - "@nv_third_party_deps//:org_springframework_boot_spring_boot", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_autoconfigure", - "@nv_third_party_deps//:org_springframework_security_spring_security_core", - "@nv_third_party_deps//:org_springframework_spring_context", - "@nv_third_party_deps//:org_springframework_spring_core", - "@nv_third_party_deps//:org_springframework_spring_web", - "@nv_third_party_deps//:org_springframework_spring_webflux", - "@nv_third_party_deps//:org_springframework_spring_webmvc", + "@maven//:io_projectreactor_reactor_core", + "@maven//:org_jspecify_jspecify", + "@maven//:org_springframework_boot_spring_boot", + "@maven//:org_springframework_boot_spring_boot_autoconfigure", + "@maven//:org_springframework_security_spring_security_core", + "@maven//:org_springframework_spring_context", + "@maven//:org_springframework_spring_core", + "@maven//:org_springframework_spring_web", + "@maven//:org_springframework_spring_webflux", + "@maven//:org_springframework_spring_webmvc", ] java_library( @@ -32,7 +32,7 @@ java_library( nv_boot_library( name = "nv_boot_starter_exceptions", srcs = glob(["src/main/java/**/*.java"]), - resource_strip_prefix = "src/libraries/java/nv-boot-parent/nv-boot-starter-exceptions/src/main/resources", + resource_strip_prefix = "nv-boot-starter-exceptions/src/main/resources", resources = glob(["src/main/resources/**"]), visibility = ["//visibility:public"], deps = EXCEPTIONS_REQUIRED_DEPS + [":optional_compile_deps"], @@ -55,11 +55,11 @@ nv_boot_library_test( name = "tests", srcs = glob(["src/test/java/**/*.java"]), coverage_library = ":nv_boot_starter_exceptions", - resource_strip_prefix = "src/libraries/java/nv-boot-parent/nv-boot-starter-exceptions/src/test/resources", + resource_strip_prefix = "nv-boot-starter-exceptions/src/test/resources", resources = glob(["src/test/resources/**"]), deps = [ ":nv_boot_starter_exceptions", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_webflux_test", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_webmvc_test", + "@maven//:org_springframework_boot_spring_boot_starter_webflux_test", + "@maven//:org_springframework_boot_spring_boot_starter_webmvc_test", ] + EXCEPTIONS_REQUIRED_DEPS + EXCEPTIONS_OPTIONAL_COMPILE_DEPS, ) diff --git a/src/libraries/java/nv-boot-parent/nv-boot-starter-jwt/BUILD.bazel b/src/libraries/java/nv-boot-parent/nv-boot-starter-jwt/BUILD.bazel index 8e2b15054..622f23af8 100644 --- a/src/libraries/java/nv-boot-parent/nv-boot-starter-jwt/BUILD.bazel +++ b/src/libraries/java/nv-boot-parent/nv-boot-starter-jwt/BUILD.bazel @@ -1,35 +1,35 @@ -load("//src/libraries/java/nv-boot-parent/tools/bazel:java.bzl", "nv_boot_library", "nv_boot_library_test") +load("//tools/bazel:java.bzl", "nv_boot_library", "nv_boot_library_test") JWT_COMPILE_DEPS = [ - "@nv_third_party_deps//:com_fasterxml_jackson_core_jackson_annotations", - "@nv_third_party_deps//:com_github_ben_manes_caffeine_guava", - "@nv_third_party_deps//:com_google_guava_guava", - "@nv_third_party_deps//:com_nimbusds_nimbus_jose_jwt", - "@nv_third_party_deps//:io_opentelemetry_opentelemetry_api", - "@nv_third_party_deps//:org_apache_commons_commons_lang3", - "@nv_third_party_deps//:org_bouncycastle_bcprov_jdk18on", - "@nv_third_party_deps//:org_slf4j_slf4j_api", - "@nv_third_party_deps//:org_springframework_boot_spring_boot", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_autoconfigure", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_jackson", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_jackson", - "@nv_third_party_deps//:org_springframework_cloud_spring_cloud_context", - "@nv_third_party_deps//:org_springframework_security_spring_security_oauth2_core", - "@nv_third_party_deps//:org_springframework_security_spring_security_oauth2_jose", - "@nv_third_party_deps//:org_springframework_spring_beans", - "@nv_third_party_deps//:org_springframework_spring_context", - "@nv_third_party_deps//:org_springframework_spring_core", - "@nv_third_party_deps//:org_springframework_spring_web", - "@nv_third_party_deps//:tools_jackson_core_jackson_core", - "@nv_third_party_deps//:tools_jackson_core_jackson_databind", - "@nv_third_party_deps//:tools_jackson_module_jackson_module_blackbird", + "@maven//:com_fasterxml_jackson_core_jackson_annotations", + "@maven//:com_github_ben_manes_caffeine_guava", + "@maven//:com_google_guava_guava", + "@maven//:com_nimbusds_nimbus_jose_jwt", + "@maven//:io_opentelemetry_opentelemetry_api", + "@maven//:org_apache_commons_commons_lang3", + "@maven//:org_bouncycastle_bcprov_jdk18on", + "@maven//:org_slf4j_slf4j_api", + "@maven//:org_springframework_boot_spring_boot", + "@maven//:org_springframework_boot_spring_boot_autoconfigure", + "@maven//:org_springframework_boot_spring_boot_jackson", + "@maven//:org_springframework_boot_spring_boot_starter", + "@maven//:org_springframework_boot_spring_boot_starter_jackson", + "@maven//:org_springframework_cloud_spring_cloud_context", + "@maven//:org_springframework_security_spring_security_oauth2_core", + "@maven//:org_springframework_security_spring_security_oauth2_jose", + "@maven//:org_springframework_spring_beans", + "@maven//:org_springframework_spring_context", + "@maven//:org_springframework_spring_core", + "@maven//:org_springframework_spring_web", + "@maven//:tools_jackson_core_jackson_core", + "@maven//:tools_jackson_core_jackson_databind", + "@maven//:tools_jackson_module_jackson_module_blackbird", ] nv_boot_library( name = "nv_boot_starter_jwt", srcs = glob(["src/main/java/**/*.java"]), - resource_strip_prefix = "src/libraries/java/nv-boot-parent/nv-boot-starter-jwt/src/main/resources", + resource_strip_prefix = "nv-boot-starter-jwt/src/main/resources", resources = glob(["src/main/resources/**"]), visibility = ["//visibility:public"], deps = JWT_COMPILE_DEPS, @@ -39,10 +39,10 @@ nv_boot_library_test( name = "tests", srcs = glob(["src/test/java/**/*.java"]), coverage_library = ":nv_boot_starter_jwt", - resource_strip_prefix = "src/libraries/java/nv-boot-parent/nv-boot-starter-jwt/src/test/resources", + resource_strip_prefix = "nv-boot-starter-jwt/src/test/resources", resources = glob(["src/test/resources/**"]), deps = [ ":nv_boot_starter_jwt", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_webmvc_test", + "@maven//:org_springframework_boot_spring_boot_starter_webmvc_test", ] + JWT_COMPILE_DEPS, ) diff --git a/src/libraries/java/nv-boot-parent/nv-boot-starter-observability/BUILD.bazel b/src/libraries/java/nv-boot-parent/nv-boot-starter-observability/BUILD.bazel index cc4df6788..0fcc1585a 100644 --- a/src/libraries/java/nv-boot-parent/nv-boot-starter-observability/BUILD.bazel +++ b/src/libraries/java/nv-boot-parent/nv-boot-starter-observability/BUILD.bazel @@ -1,52 +1,52 @@ load("@rules_java//java:defs.bzl", "java_library") -load("//src/libraries/java/nv-boot-parent/tools/bazel:java.bzl", "nv_boot_library", "nv_boot_library_test", "nv_boot_runtime_classpath_test") +load("//tools/bazel:java.bzl", "nv_boot_library", "nv_boot_library_test", "nv_boot_runtime_classpath_test") OBSERVABILITY_REQUIRED_DEPS = [ - "@nv_third_party_deps//:ch_qos_logback_logback_classic", - "@nv_third_party_deps//:ch_qos_logback_logback_core", - "@nv_third_party_deps//:io_micrometer_micrometer_commons", - "@nv_third_party_deps//:io_micrometer_micrometer_core", - "@nv_third_party_deps//:io_micrometer_micrometer_observation", - "@nv_third_party_deps//:io_micrometer_micrometer_tracing", - "@nv_third_party_deps//:io_micrometer_micrometer_tracing_bridge_otel", - "@nv_third_party_deps//:io_opentelemetry_opentelemetry_api", - "@nv_third_party_deps//:io_opentelemetry_opentelemetry_sdk_common", - "@nv_third_party_deps//:io_opentelemetry_opentelemetry_sdk_trace", - "@nv_third_party_deps//:io_opentelemetry_semconv_opentelemetry_semconv", - "@nv_third_party_deps//:org_apache_commons_commons_lang3", - "@nv_third_party_deps//:org_slf4j_slf4j_api", - "@nv_third_party_deps//:org_springframework_boot_spring_boot", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_actuator", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_actuator_autoconfigure", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_autoconfigure", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_health", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_micrometer_metrics", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_micrometer_observation", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_micrometer_tracing", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_micrometer_tracing_opentelemetry", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_opentelemetry", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_actuator", - "@nv_third_party_deps//:org_springframework_spring_beans", - "@nv_third_party_deps//:org_springframework_spring_context", - "@nv_third_party_deps//:org_springframework_spring_core", + "@maven//:ch_qos_logback_logback_classic", + "@maven//:ch_qos_logback_logback_core", + "@maven//:io_micrometer_micrometer_commons", + "@maven//:io_micrometer_micrometer_core", + "@maven//:io_micrometer_micrometer_observation", + "@maven//:io_micrometer_micrometer_tracing", + "@maven//:io_micrometer_micrometer_tracing_bridge_otel", + "@maven//:io_opentelemetry_opentelemetry_api", + "@maven//:io_opentelemetry_opentelemetry_sdk_common", + "@maven//:io_opentelemetry_opentelemetry_sdk_trace", + "@maven//:io_opentelemetry_semconv_opentelemetry_semconv", + "@maven//:org_apache_commons_commons_lang3", + "@maven//:org_slf4j_slf4j_api", + "@maven//:org_springframework_boot_spring_boot", + "@maven//:org_springframework_boot_spring_boot_actuator", + "@maven//:org_springframework_boot_spring_boot_actuator_autoconfigure", + "@maven//:org_springframework_boot_spring_boot_autoconfigure", + "@maven//:org_springframework_boot_spring_boot_health", + "@maven//:org_springframework_boot_spring_boot_micrometer_metrics", + "@maven//:org_springframework_boot_spring_boot_micrometer_observation", + "@maven//:org_springframework_boot_spring_boot_micrometer_tracing", + "@maven//:org_springframework_boot_spring_boot_micrometer_tracing_opentelemetry", + "@maven//:org_springframework_boot_spring_boot_opentelemetry", + "@maven//:org_springframework_boot_spring_boot_starter_actuator", + "@maven//:org_springframework_spring_beans", + "@maven//:org_springframework_spring_context", + "@maven//:org_springframework_spring_core", ] # Cassandra, Spring Cloud, servlet, MVC, and WebFlux support is optional in the # Maven POM. Keep those APIs available to compile/test conditional integration # code without adding those frameworks to every downstream runtime classpath. OBSERVABILITY_OPTIONAL_COMPILE_DEPS = [ - "@nv_third_party_deps//:jakarta_servlet_jakarta_servlet_api", - "@nv_third_party_deps//:org_apache_cassandra_java_driver_core", - "@nv_third_party_deps//:org_apache_cassandra_java_driver_guava_shaded", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_cassandra", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_data_cassandra", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_data_cassandra", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_web_server", - "@nv_third_party_deps//:org_springframework_cloud_spring_cloud_commons", - "@nv_third_party_deps//:org_springframework_data_spring_data_cassandra", - "@nv_third_party_deps//:org_springframework_spring_web", - "@nv_third_party_deps//:org_springframework_spring_webflux", - "@nv_third_party_deps//:org_springframework_spring_webmvc", + "@maven//:jakarta_servlet_jakarta_servlet_api", + "@maven//:org_apache_cassandra_java_driver_core", + "@maven//:org_apache_cassandra_java_driver_guava_shaded", + "@maven//:org_springframework_boot_spring_boot_cassandra", + "@maven//:org_springframework_boot_spring_boot_data_cassandra", + "@maven//:org_springframework_boot_spring_boot_starter_data_cassandra", + "@maven//:org_springframework_boot_spring_boot_web_server", + "@maven//:org_springframework_cloud_spring_cloud_commons", + "@maven//:org_springframework_data_spring_data_cassandra", + "@maven//:org_springframework_spring_web", + "@maven//:org_springframework_spring_webflux", + "@maven//:org_springframework_spring_webmvc", ] java_library( @@ -59,7 +59,7 @@ java_library( nv_boot_library( name = "nv_boot_starter_observability", srcs = glob(["src/main/java/**/*.java"]), - resource_strip_prefix = "src/libraries/java/nv-boot-parent/nv-boot-starter-observability/src/main/resources", + resource_strip_prefix = "nv-boot-starter-observability/src/main/resources", resources = glob(["src/main/resources/**"]), visibility = ["//visibility:public"], deps = OBSERVABILITY_REQUIRED_DEPS + [":optional_compile_deps"], @@ -84,18 +84,18 @@ nv_boot_library_test( name = "tests", srcs = glob(["src/test/java/**/*.java"]), coverage_library = ":nv_boot_starter_observability", - resource_strip_prefix = "src/libraries/java/nv-boot-parent/nv-boot-starter-observability/src/test/resources", + resource_strip_prefix = "nv-boot-starter-observability/src/test/resources", resources = glob(["src/test/resources/**"]), deps = [ ":nv_boot_starter_observability", - "@nv_third_party_deps//:io_opentelemetry_opentelemetry_sdk_testing", - "@nv_third_party_deps//:org_awaitility_awaitility", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_restclient", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_resttestclient", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_actuator_test", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_webflux_test", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_webmvc_test", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_webmvc_test", + "@maven//:io_opentelemetry_opentelemetry_sdk_testing", + "@maven//:org_awaitility_awaitility", + "@maven//:org_springframework_boot_spring_boot_restclient", + "@maven//:org_springframework_boot_spring_boot_resttestclient", + "@maven//:org_springframework_boot_spring_boot_starter_actuator_test", + "@maven//:org_springframework_boot_spring_boot_starter_webflux_test", + "@maven//:org_springframework_boot_spring_boot_starter_webmvc_test", + "@maven//:org_springframework_boot_spring_boot_webmvc_test", ] + OBSERVABILITY_REQUIRED_DEPS + OBSERVABILITY_OPTIONAL_COMPILE_DEPS, size = "medium", timeout = "moderate", diff --git a/src/libraries/java/nv-boot-parent/nv-boot-starter-registries/BUILD.bazel b/src/libraries/java/nv-boot-parent/nv-boot-starter-registries/BUILD.bazel index 733da3cc8..8fe4515cb 100644 --- a/src/libraries/java/nv-boot-parent/nv-boot-starter-registries/BUILD.bazel +++ b/src/libraries/java/nv-boot-parent/nv-boot-starter-registries/BUILD.bazel @@ -1,54 +1,54 @@ -load("//src/libraries/java/nv-boot-parent/tools/bazel:java.bzl", "nv_boot_library", "nv_boot_library_test") +load("//tools/bazel:java.bzl", "nv_boot_library", "nv_boot_library_test") REGISTRIES_COMPILE_DEPS = [ - "//src/libraries/java/nv-boot-parent/nv-boot-starter-exceptions:nv_boot_starter_exceptions", - "@nv_third_party_deps//:com_fasterxml_jackson_core_jackson_annotations", - "@nv_third_party_deps//:com_github_ben_manes_caffeine_caffeine", - "@nv_third_party_deps//:com_github_ben_manes_caffeine_guava", - "@nv_third_party_deps//:com_google_guava_guava", - "@nv_third_party_deps//:com_nimbusds_nimbus_jose_jwt", - "@nv_third_party_deps//:commons_codec_commons_codec", - "@nv_third_party_deps//:io_micrometer_micrometer_commons", - "@nv_third_party_deps//:io_netty_netty_common", - "@nv_third_party_deps//:io_netty_netty_handler", - "@nv_third_party_deps//:io_netty_netty_transport", - "@nv_third_party_deps//:io_projectreactor_netty_reactor_netty_core", - "@nv_third_party_deps//:io_projectreactor_netty_reactor_netty_http", - "@nv_third_party_deps//:io_projectreactor_reactor_core", - "@nv_third_party_deps//:jakarta_annotation_jakarta_annotation_api", - "@nv_third_party_deps//:jakarta_validation_jakarta_validation_api", - "@nv_third_party_deps//:org_apache_commons_commons_lang3", - "@nv_third_party_deps//:org_apache_logging_log4j_log4j_api", - "@nv_third_party_deps//:org_jspecify_jspecify", - "@nv_third_party_deps//:org_slf4j_slf4j_api", - "@nv_third_party_deps//:org_springframework_boot_spring_boot", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_autoconfigure", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_jackson", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_jackson", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_security_oauth2_client", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_validation", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_webclient", - "@nv_third_party_deps//:org_springframework_cloud_spring_cloud_context", - "@nv_third_party_deps//:org_springframework_security_spring_security_config", - "@nv_third_party_deps//:org_springframework_security_spring_security_core", - "@nv_third_party_deps//:org_springframework_security_spring_security_oauth2_client", - "@nv_third_party_deps//:org_springframework_security_spring_security_oauth2_core", - "@nv_third_party_deps//:org_springframework_security_spring_security_oauth2_jose", - "@nv_third_party_deps//:org_springframework_security_spring_security_web", - "@nv_third_party_deps//:org_springframework_spring_beans", - "@nv_third_party_deps//:org_springframework_spring_context", - "@nv_third_party_deps//:org_springframework_spring_core", - "@nv_third_party_deps//:org_springframework_spring_web", - "@nv_third_party_deps//:org_springframework_spring_webflux", - "@nv_third_party_deps//:software_amazon_awssdk_regions", - "@nv_third_party_deps//:tools_jackson_core_jackson_core", - "@nv_third_party_deps//:tools_jackson_core_jackson_databind", + "//nv-boot-starter-exceptions:nv_boot_starter_exceptions", + "@maven//:com_fasterxml_jackson_core_jackson_annotations", + "@maven//:com_github_ben_manes_caffeine_caffeine", + "@maven//:com_github_ben_manes_caffeine_guava", + "@maven//:com_google_guava_guava", + "@maven//:com_nimbusds_nimbus_jose_jwt", + "@maven//:commons_codec_commons_codec", + "@maven//:io_micrometer_micrometer_commons", + "@maven//:io_netty_netty_common", + "@maven//:io_netty_netty_handler", + "@maven//:io_netty_netty_transport", + "@maven//:io_projectreactor_netty_reactor_netty_core", + "@maven//:io_projectreactor_netty_reactor_netty_http", + "@maven//:io_projectreactor_reactor_core", + "@maven//:jakarta_annotation_jakarta_annotation_api", + "@maven//:jakarta_validation_jakarta_validation_api", + "@maven//:org_apache_commons_commons_lang3", + "@maven//:org_apache_logging_log4j_log4j_api", + "@maven//:org_jspecify_jspecify", + "@maven//:org_slf4j_slf4j_api", + "@maven//:org_springframework_boot_spring_boot", + "@maven//:org_springframework_boot_spring_boot_autoconfigure", + "@maven//:org_springframework_boot_spring_boot_jackson", + "@maven//:org_springframework_boot_spring_boot_starter_jackson", + "@maven//:org_springframework_boot_spring_boot_starter_security_oauth2_client", + "@maven//:org_springframework_boot_spring_boot_starter_validation", + "@maven//:org_springframework_boot_spring_boot_webclient", + "@maven//:org_springframework_cloud_spring_cloud_context", + "@maven//:org_springframework_security_spring_security_config", + "@maven//:org_springframework_security_spring_security_core", + "@maven//:org_springframework_security_spring_security_oauth2_client", + "@maven//:org_springframework_security_spring_security_oauth2_core", + "@maven//:org_springframework_security_spring_security_oauth2_jose", + "@maven//:org_springframework_security_spring_security_web", + "@maven//:org_springframework_spring_beans", + "@maven//:org_springframework_spring_context", + "@maven//:org_springframework_spring_core", + "@maven//:org_springframework_spring_web", + "@maven//:org_springframework_spring_webflux", + "@maven//:software_amazon_awssdk_regions", + "@maven//:tools_jackson_core_jackson_core", + "@maven//:tools_jackson_core_jackson_databind", ] nv_boot_library( name = "nv_boot_starter_registries", srcs = glob(["src/main/java/**/*.java"]), - resource_strip_prefix = "src/libraries/java/nv-boot-parent/nv-boot-starter-registries/src/main/resources", + resource_strip_prefix = "nv-boot-starter-registries/src/main/resources", resources = glob(["src/main/resources/**"]), visibility = ["//visibility:public"], deps = REGISTRIES_COMPILE_DEPS, @@ -58,13 +58,13 @@ nv_boot_library_test( name = "tests", srcs = glob(["src/test/java/**/*.java"]), coverage_library = ":nv_boot_starter_registries", - resource_strip_prefix = "src/libraries/java/nv-boot-parent/nv-boot-starter-registries/src/test/resources", + resource_strip_prefix = "nv-boot-starter-registries/src/test/resources", resources = glob(["src/test/resources/**"]), deps = [ ":nv_boot_starter_registries", - "//src/libraries/java/nv-boot-parent/nv-boot-mock-servers-test:nv_boot_mock_servers_test", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_webflux_test", - "@nv_third_party_deps//:org_wiremock_wiremock_standalone", + "//nv-boot-mock-servers-test:nv_boot_mock_servers_test", + "@maven//:org_springframework_boot_spring_boot_starter_webflux_test", + "@maven//:org_wiremock_wiremock_standalone", ] + REGISTRIES_COMPILE_DEPS, size = "medium", tags = ["exclusive"], diff --git a/src/libraries/java/nv-boot-parent/nv-boot-starter-reloadable-properties/BUILD.bazel b/src/libraries/java/nv-boot-parent/nv-boot-starter-reloadable-properties/BUILD.bazel index 9fd2ad9a6..072c9e01d 100644 --- a/src/libraries/java/nv-boot-parent/nv-boot-starter-reloadable-properties/BUILD.bazel +++ b/src/libraries/java/nv-boot-parent/nv-boot-starter-reloadable-properties/BUILD.bazel @@ -1,18 +1,18 @@ -load("//src/libraries/java/nv-boot-parent/tools/bazel:java.bzl", "nv_boot_library", "nv_boot_library_test", "nv_boot_workspace_runfiles") +load("//tools/bazel:java.bzl", "nv_boot_library", "nv_boot_library_test", "nv_boot_workspace_runfiles") RELOADABLE_PROPERTIES_COMPILE_DEPS = [ - "@nv_third_party_deps//:com_github_ben_manes_caffeine_guava", - "@nv_third_party_deps//:com_google_guava_guava", - "@nv_third_party_deps//:jakarta_annotation_jakarta_annotation_api", - "@nv_third_party_deps//:org_apache_commons_commons_lang3", - "@nv_third_party_deps//:org_slf4j_slf4j_api", - "@nv_third_party_deps//:org_springframework_boot_spring_boot", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_autoconfigure", - "@nv_third_party_deps//:org_springframework_cloud_spring_cloud_context", - "@nv_third_party_deps//:org_springframework_cloud_spring_cloud_starter_bootstrap", - "@nv_third_party_deps//:org_springframework_spring_beans", - "@nv_third_party_deps//:org_springframework_spring_context", - "@nv_third_party_deps//:org_springframework_spring_core", + "@maven//:com_github_ben_manes_caffeine_guava", + "@maven//:com_google_guava_guava", + "@maven//:jakarta_annotation_jakarta_annotation_api", + "@maven//:org_apache_commons_commons_lang3", + "@maven//:org_slf4j_slf4j_api", + "@maven//:org_springframework_boot_spring_boot", + "@maven//:org_springframework_boot_spring_boot_autoconfigure", + "@maven//:org_springframework_cloud_spring_cloud_context", + "@maven//:org_springframework_cloud_spring_cloud_starter_bootstrap", + "@maven//:org_springframework_spring_beans", + "@maven//:org_springframework_spring_context", + "@maven//:org_springframework_spring_core", ] filegroup( @@ -23,13 +23,13 @@ filegroup( nv_boot_workspace_runfiles( name = "reloadable_properties_test_resources", srcs = [":test_resource_files"], - strip_prefix = "src/libraries/java/nv-boot-parent/nv-boot-starter-reloadable-properties/", + strip_prefix = "nv-boot-starter-reloadable-properties/", ) nv_boot_library( name = "nv_boot_starter_reloadable_properties", srcs = glob(["src/main/java/**/*.java"]), - resource_strip_prefix = "src/libraries/java/nv-boot-parent/nv-boot-starter-reloadable-properties/src/main/resources", + resource_strip_prefix = "nv-boot-starter-reloadable-properties/src/main/resources", resources = glob(["src/main/resources/**"]), visibility = ["//visibility:public"], deps = RELOADABLE_PROPERTIES_COMPILE_DEPS, @@ -41,13 +41,13 @@ nv_boot_library_test( coverage_library = ":nv_boot_starter_reloadable_properties", data = [":reloadable_properties_test_resources"], junit_classpath = ["src/test/resources"], - resource_strip_prefix = "src/libraries/java/nv-boot-parent/nv-boot-starter-reloadable-properties/src/test/resources", + resource_strip_prefix = "nv-boot-starter-reloadable-properties/src/test/resources", resources = glob(["src/test/resources/**"]), deps = [ ":nv_boot_starter_reloadable_properties", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_jackson", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_jackson", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_webmvc_test", - "@nv_third_party_deps//:tools_jackson_core_jackson_databind", + "@maven//:org_springframework_boot_spring_boot_jackson", + "@maven//:org_springframework_boot_spring_boot_starter_jackson", + "@maven//:org_springframework_boot_spring_boot_starter_webmvc_test", + "@maven//:tools_jackson_core_jackson_databind", ] + RELOADABLE_PROPERTIES_COMPILE_DEPS, ) diff --git a/src/libraries/java/nv-boot-parent/nv-boot-starter-telemetry/BUILD.bazel b/src/libraries/java/nv-boot-parent/nv-boot-starter-telemetry/BUILD.bazel index 0bf2c4e7f..42d454c30 100644 --- a/src/libraries/java/nv-boot-parent/nv-boot-starter-telemetry/BUILD.bazel +++ b/src/libraries/java/nv-boot-parent/nv-boot-starter-telemetry/BUILD.bazel @@ -1,36 +1,36 @@ -load("//src/libraries/java/nv-boot-parent/tools/bazel:java.bzl", "nv_boot_library", "nv_boot_library_test") +load("//tools/bazel:java.bzl", "nv_boot_library", "nv_boot_library_test") TELEMETRY_COMPILE_DEPS = [ - "@nv_third_party_deps//:io_cloudevents_cloudevents_api", - "@nv_third_party_deps//:io_cloudevents_cloudevents_core", - "@nv_third_party_deps//:io_cloudevents_cloudevents_json_jackson", - "@nv_third_party_deps//:io_netty_netty_common", - "@nv_third_party_deps//:io_netty_netty_transport", - "@nv_third_party_deps//:io_projectreactor_netty_reactor_netty_http", - "@nv_third_party_deps//:io_projectreactor_reactor_core", - "@nv_third_party_deps//:jakarta_validation_jakarta_validation_api", - "@nv_third_party_deps//:org_apache_commons_commons_lang3", - "@nv_third_party_deps//:org_slf4j_slf4j_api", - "@nv_third_party_deps//:org_springframework_boot_spring_boot", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_autoconfigure", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_jackson", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_jackson", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_validation", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_webflux", - "@nv_third_party_deps//:org_springframework_security_spring_security_core", - "@nv_third_party_deps//:org_springframework_spring_beans", - "@nv_third_party_deps//:org_springframework_spring_context", - "@nv_third_party_deps//:org_springframework_spring_core", - "@nv_third_party_deps//:org_springframework_spring_web", - "@nv_third_party_deps//:org_springframework_spring_webflux", - "@nv_third_party_deps//:tools_jackson_core_jackson_databind", + "@maven//:io_cloudevents_cloudevents_api", + "@maven//:io_cloudevents_cloudevents_core", + "@maven//:io_cloudevents_cloudevents_json_jackson", + "@maven//:io_netty_netty_common", + "@maven//:io_netty_netty_transport", + "@maven//:io_projectreactor_netty_reactor_netty_http", + "@maven//:io_projectreactor_reactor_core", + "@maven//:jakarta_validation_jakarta_validation_api", + "@maven//:org_apache_commons_commons_lang3", + "@maven//:org_slf4j_slf4j_api", + "@maven//:org_springframework_boot_spring_boot", + "@maven//:org_springframework_boot_spring_boot_autoconfigure", + "@maven//:org_springframework_boot_spring_boot_jackson", + "@maven//:org_springframework_boot_spring_boot_starter", + "@maven//:org_springframework_boot_spring_boot_starter_jackson", + "@maven//:org_springframework_boot_spring_boot_starter_validation", + "@maven//:org_springframework_boot_spring_boot_starter_webflux", + "@maven//:org_springframework_security_spring_security_core", + "@maven//:org_springframework_spring_beans", + "@maven//:org_springframework_spring_context", + "@maven//:org_springframework_spring_core", + "@maven//:org_springframework_spring_web", + "@maven//:org_springframework_spring_webflux", + "@maven//:tools_jackson_core_jackson_databind", ] nv_boot_library( name = "nv_boot_starter_telemetry", srcs = glob(["src/main/java/**/*.java"]), - resource_strip_prefix = "src/libraries/java/nv-boot-parent/nv-boot-starter-telemetry/src/main/resources", + resource_strip_prefix = "nv-boot-starter-telemetry/src/main/resources", resources = glob(["src/main/resources/**"]), visibility = ["//visibility:public"], deps = TELEMETRY_COMPILE_DEPS, @@ -42,10 +42,10 @@ nv_boot_library_test( coverage_library = ":nv_boot_starter_telemetry", deps = [ ":nv_boot_starter_telemetry", - "@nv_third_party_deps//:org_hibernate_validator_hibernate_validator", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_webflux_test", - "@nv_third_party_deps//:org_springframework_security_spring_security_test", - "@nv_third_party_deps//:org_wiremock_wiremock_standalone", + "@maven//:org_hibernate_validator_hibernate_validator", + "@maven//:org_springframework_boot_spring_boot_starter_webflux_test", + "@maven//:org_springframework_security_spring_security_test", + "@maven//:org_wiremock_wiremock_standalone", ] + TELEMETRY_COMPILE_DEPS, size = "medium", timeout = "moderate", diff --git a/src/libraries/java/nv-boot-parent/tools/bazel/BUILD.bazel b/src/libraries/java/nv-boot-parent/tools/bazel/BUILD.bazel index 5dca0ab32..114bc1153 100644 --- a/src/libraries/java/nv-boot-parent/tools/bazel/BUILD.bazel +++ b/src/libraries/java/nv-boot-parent/tools/bazel/BUILD.bazel @@ -35,7 +35,7 @@ sh_test( # nv-boot-parent's own NOTICE (its Java closure), not the aggregate root # NOTICE which also covers the Go/Rust subtrees and can never match a # Java-only regeneration. - "//src/libraries/java/nv-boot-parent:NOTICE", + "//:NOTICE", "//:maven_install.json", ":notice_roots.json", ], @@ -45,17 +45,17 @@ java_plugin( name = "lombok_plugin", generates_api = True, processor_class = "lombok.launch.AnnotationProcessorHider$AnnotationProcessor", - deps = ["@nv_third_party_deps//:org_projectlombok_lombok"], + deps = ["@maven//:org_projectlombok_lombok"], ) java_binary( name = "jacoco_cli", main_class = "org.jacoco.cli.internal.Main", - runtime_deps = ["@nv_third_party_deps//:org_jacoco_org_jacoco_cli"], + runtime_deps = ["@maven//:org_jacoco_org_jacoco_cli"], ) java_library( name = "lombok_annotations", - exports = ["@nv_third_party_deps//:org_projectlombok_lombok"], + exports = ["@maven//:org_projectlombok_lombok"], neverlink = True, ) diff --git a/src/libraries/java/nv-boot-parent/tools/bazel/java.bzl b/src/libraries/java/nv-boot-parent/tools/bazel/java.bzl index ef2558f31..733097dd0 100644 --- a/src/libraries/java/nv-boot-parent/tools/bazel/java.bzl +++ b/src/libraries/java/nv-boot-parent/tools/bazel/java.bzl @@ -7,11 +7,11 @@ NV_JAVA_JAVACOPTS = [ ] NV_LOMBOK_COMPILE_DEPS = [ - "//src/libraries/java/nv-boot-parent/tools/bazel:lombok_annotations", + "//tools/bazel:lombok_annotations", ] NV_LOMBOK_PLUGINS = [ - "//src/libraries/java/nv-boot-parent/tools/bazel:lombok_plugin", + "//tools/bazel:lombok_plugin", ] NV_JUNIT5_ARGS = [ @@ -24,21 +24,21 @@ NV_JUNIT5_ARGS = [ ] NV_JUNIT5_RUNTIME_DEPS = [ - "@nv_third_party_deps//:org_junit_platform_junit_platform_console_standalone", + "@maven//:org_junit_platform_junit_platform_console_standalone", ] NV_JUNIT5_COMPILE_DEPS = [ - "@nv_third_party_deps//:org_assertj_assertj_core", - "@nv_third_party_deps//:org_junit_jupiter_junit_jupiter_api", - "@nv_third_party_deps//:org_junit_jupiter_junit_jupiter_params", - "@nv_third_party_deps//:org_mockito_mockito_core", - "@nv_third_party_deps//:org_mockito_mockito_junit_jupiter", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_test", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_test_autoconfigure", - "@nv_third_party_deps//:org_springframework_spring_test", + "@maven//:org_assertj_assertj_core", + "@maven//:org_junit_jupiter_junit_jupiter_api", + "@maven//:org_junit_jupiter_junit_jupiter_params", + "@maven//:org_mockito_mockito_core", + "@maven//:org_mockito_mockito_junit_jupiter", + "@maven//:org_springframework_boot_spring_boot_test", + "@maven//:org_springframework_boot_spring_boot_test_autoconfigure", + "@maven//:org_springframework_spring_test", ] -NV_MOCKITO_CORE = "@nv_third_party_deps//:org_mockito_mockito_core" +NV_MOCKITO_CORE = "@maven//:org_mockito_mockito_core" NV_MOCKITO_AGENT_DATA = [ NV_MOCKITO_CORE, @@ -48,7 +48,7 @@ NV_MOCKITO_AGENT_JVM_FLAGS = [ "-javaagent:$(location %s)" % NV_MOCKITO_CORE, ] -NV_JACOCO_AGENT = "@nv_third_party_deps//:org_jacoco_org_jacoco_agent_runtime" +NV_JACOCO_AGENT = "@maven//:org_jacoco_org_jacoco_agent_runtime" NV_JACOCO_AGENT_DATA = [ NV_JACOCO_AGENT, @@ -184,13 +184,13 @@ def nv_boot_library_test( _sh_test( name = name, - srcs = ["//src/libraries/java/nv-boot-parent/tools/bazel:jacoco_test_runner.sh"], + srcs = ["//tools/bazel:jacoco_test_runner.sh"], args = [ "$(location :%s)" % junit_runner, "$(location %s)" % coverage_library, coverage_source_root if coverage_sourcefiles else "", native.package_name(), - "$(location //src/libraries/java/nv-boot-parent/tools/bazel:jacoco_cli)", + "$(location //tools/bazel:jacoco_cli)", ] + NV_JUNIT5_ARGS + [ "--class-path=$(location :%s.jar)" % junit_runner, "--scan-classpath=$(location :%s.jar)" % junit_runner, @@ -202,7 +202,7 @@ def nv_boot_library_test( ":" + junit_runner, ":%s.jar" % junit_runner, coverage_library, - "//src/libraries/java/nv-boot-parent/tools/bazel:jacoco_cli", + "//tools/bazel:jacoco_cli", ] + coverage_sourcefiles, size = size, tags = tags, diff --git a/src/libraries/java/nv-boot-parent/tools/bazel/notice_check_test.sh b/src/libraries/java/nv-boot-parent/tools/bazel/notice_check_test.sh index 8e8a3dc8a..527fffd71 100755 --- a/src/libraries/java/nv-boot-parent/tools/bazel/notice_check_test.sh +++ b/src/libraries/java/nv-boot-parent/tools/bazel/notice_check_test.sh @@ -46,10 +46,10 @@ find_workspace() { } workspace="$(find_workspace)" -# nv-boot-parent is a subtree of the monorepo, not the workspace root, so its -# notice tooling and its own NOTICE live under this prefix rather than at the -# repo root. The Maven lock, however, is the single root maven_install.json. -nvboot="${workspace}/src/libraries/java/nv-boot-parent" +# nv-boot-parent is its own standalone Bazel module: its module root is the +# nv-boot-parent directory, so the notice tooling, its NOTICE, and its +# maven_install.json all live at the workspace root. +nvboot="${workspace}" PYTHONPATH="${nvboot}/tools/bazel" python3 - <<'PY' import pathlib From a1bcbb59c42f2cbd0ab02ef7531c228302bee2e7 Mon Sep 17 00:00:00 2001 From: Balaji Ganesan <bganesan@nvidia.com> Date: Wed, 22 Jul 2026 22:10:48 -0700 Subject: [PATCH 13/29] fix(java): use the image-local JDK 25 instead of a hermetic remotejdk download The standalone Java modules pinned --java_runtime_version=remotejdk_25, so Bazel downloaded its own JDK 25 on every cold CI runner even though the bazel-ci image already ships Temurin 25 at JAVA_HOME. Point Bazel at that JDK via local_jdk, so there is no per-build JDK download and the image carries a single JDK. Also reverts the ci/Dockerfile.bazel + bazel-ci-image.yml prewarm changes: they are no longer needed because the image is unchanged and local_jdk uses the existing 0.12.0 Temurin. Supersedes the GitLab bazel-ci prewarm MR and the 0.13.0 image bump. Reproducibility now comes from the pinned CI image tag; local dev needs a JDK 25 on JAVA_HOME (to be revisited later). Co-authored-by: Balaji Ganesan <bganesan@nvidia.com> --- .github/workflows/bazel-ci-image.yml | 8 +----- ci/Dockerfile.bazel | 27 +------------------ examples/java-spring-boot-service/.bazelrc | 8 +++--- rules/java/.bazelrc | 8 +++--- .../cloud-tasks/.bazelrc | 8 +++--- src/libraries/java/nv-boot-parent/.bazelrc | 8 +++--- 6 files changed, 18 insertions(+), 49 deletions(-) diff --git a/.github/workflows/bazel-ci-image.yml b/.github/workflows/bazel-ci-image.yml index 48cd1fa45..6c169a123 100644 --- a/.github/workflows/bazel-ci-image.yml +++ b/.github/workflows/bazel-ci-image.yml @@ -38,13 +38,7 @@ permissions: env: # Keep in lockstep with BAZEL_CI_VERSION in .gitlab-ci.yml and the # container.image tag in .github/workflows/bazel.yml. - # - # 0.13.0 adds the remotejdk_25 + Bazel 9.1.1 pre-warm for the standalone Java - # modules (see ci/Dockerfile.bazel). This workflow builds (and, on merge to - # main, publishes) the tag; .github/workflows/bazel.yml is bumped to 0.13.0 in - # a fast-follow once the tag is published, so the bazel matrix never pins an - # unpublished image. Tracked in NVIDIA/nvcf#372. - BAZEL_CI_VERSION: "0.13.0" + BAZEL_CI_VERSION: "0.8.0" IMAGE: ghcr.io/nvidia/nvcf/bazel-ci jobs: diff --git a/ci/Dockerfile.bazel b/ci/Dockerfile.bazel index c1d1d5973..849d84551 100644 --- a/ci/Dockerfile.bazel +++ b/ci/Dockerfile.bazel @@ -130,29 +130,4 @@ RUN mkdir /tmp/warmup && cd /tmp/warmup \ && bazel version \ && rm -rf /tmp/warmup -# Pre-warm the hermetic JDK the standalone Java modules build against. The -# nvcf_java_rules / nv_boot_parent / cloud-tasks / java-spring-boot-service -# modules pin Bazel ${JAVA_MODULE_BAZEL_VERSION} and compile against -# remotejdk_${JAVA_MODULE_JDK_VERSION} (fetched hermetically by rules_java), -# both re-downloaded on a cold runner. Compiling a throwaway class with those -# pins fills the shared Bazel repository cache (the JDK archive) and bazelisk's -# ${JAVA_MODULE_BAZEL_VERSION} binary, so the Java matrix rows start warm instead -# of cold-fetching the JDK. Additive: it only populates caches the Java rows -# reuse; no other subtree row's inputs change. Maven jars are intentionally not -# baked (see .github/workflows/bazel.yml and NVIDIA/nvcf#373). -ARG JAVA_MODULE_BAZEL_VERSION=9.1.1 -ARG JAVA_MODULE_JDK_VERSION=25 -RUN mkdir /tmp/jdkwarm && cd /tmp/jdkwarm \ - && echo "${JAVA_MODULE_BAZEL_VERSION}" > .bazelversion \ - && echo 'bazel_dep(name = "rules_java", version = "9.3.0")' > MODULE.bazel \ - && printf 'load("@rules_java//java:defs.bzl", "java_library")\njava_library(name = "warm", srcs = ["Warm.java"])\n' > BUILD.bazel \ - && echo 'public class Warm {}' > Warm.java \ - && bazel build //:warm \ - --java_language_version="${JAVA_MODULE_JDK_VERSION}" \ - --java_runtime_version="remotejdk_${JAVA_MODULE_JDK_VERSION}" \ - --tool_java_language_version="${JAVA_MODULE_JDK_VERSION}" \ - --tool_java_runtime_version="remotejdk_${JAVA_MODULE_JDK_VERSION}" \ - --java_header_compilation=false \ - && rm -rf /tmp/jdkwarm - -LABEL description="NVCF monorepo Bazel CI image - Ubuntu 24.04 + Bazel ${BAZEL_VERSION} + kubebuilder-tools ${KUBEBUILDER_TOOLS_VERSION} + remotejdk_${JAVA_MODULE_JDK_VERSION} prewarm" +LABEL description="NVCF monorepo Bazel CI image - Ubuntu 24.04 + Bazel ${BAZEL_VERSION} + kubebuilder-tools ${KUBEBUILDER_TOOLS_VERSION}" diff --git a/examples/java-spring-boot-service/.bazelrc b/examples/java-spring-boot-service/.bazelrc index 3dcfdd132..38ab37cda 100644 --- a/examples/java-spring-boot-service/.bazelrc +++ b/examples/java-spring-boot-service/.bazelrc @@ -26,12 +26,12 @@ build --incompatible_strict_action_env # public builds go straight to Maven Central (try-import is a no-op when absent). try-import %workspace%/tools/bazel/internal.bazelrc -# Java: hermetic remotejdk 25 regardless of the host JDK, matching the root -# module so builds are reproducible everywhere. +# Java: use the image-provided local JDK 25 (Temurin at JAVA_HOME) instead of a +# hermetic remotejdk download; the bazel-ci image ships Temurin 25 (no download). build --java_language_version=25 -build --java_runtime_version=remotejdk_25 +build --java_runtime_version=local_jdk build --tool_java_language_version=25 -build --tool_java_runtime_version=remotejdk_25 +build --tool_java_runtime_version=local_jdk build --java_header_compilation=false test --test_output=errors diff --git a/rules/java/.bazelrc b/rules/java/.bazelrc index 3dcfdd132..38ab37cda 100644 --- a/rules/java/.bazelrc +++ b/rules/java/.bazelrc @@ -26,12 +26,12 @@ build --incompatible_strict_action_env # public builds go straight to Maven Central (try-import is a no-op when absent). try-import %workspace%/tools/bazel/internal.bazelrc -# Java: hermetic remotejdk 25 regardless of the host JDK, matching the root -# module so builds are reproducible everywhere. +# Java: use the image-provided local JDK 25 (Temurin at JAVA_HOME) instead of a +# hermetic remotejdk download; the bazel-ci image ships Temurin 25 (no download). build --java_language_version=25 -build --java_runtime_version=remotejdk_25 +build --java_runtime_version=local_jdk build --tool_java_language_version=25 -build --tool_java_runtime_version=remotejdk_25 +build --tool_java_runtime_version=local_jdk build --java_header_compilation=false test --test_output=errors diff --git a/src/control-plane-services/cloud-tasks/.bazelrc b/src/control-plane-services/cloud-tasks/.bazelrc index 5d096451a..3bf18b80d 100644 --- a/src/control-plane-services/cloud-tasks/.bazelrc +++ b/src/control-plane-services/cloud-tasks/.bazelrc @@ -26,12 +26,12 @@ build --incompatible_strict_action_env # public builds go straight to Maven Central (try-import is a no-op when absent). try-import %workspace%/tools/bazel/internal.bazelrc -# Java: hermetic remotejdk 25 regardless of the host JDK, matching the root -# module so builds are reproducible everywhere. +# Java: use the image-provided local JDK 25 (Temurin at JAVA_HOME) instead of a +# hermetic remotejdk download; the bazel-ci image ships Temurin 25 (no download). build --java_language_version=25 -build --java_runtime_version=remotejdk_25 +build --java_runtime_version=local_jdk build --tool_java_language_version=25 -build --tool_java_runtime_version=remotejdk_25 +build --tool_java_runtime_version=local_jdk build --java_header_compilation=false test --test_output=errors diff --git a/src/libraries/java/nv-boot-parent/.bazelrc b/src/libraries/java/nv-boot-parent/.bazelrc index 3dcfdd132..38ab37cda 100644 --- a/src/libraries/java/nv-boot-parent/.bazelrc +++ b/src/libraries/java/nv-boot-parent/.bazelrc @@ -26,12 +26,12 @@ build --incompatible_strict_action_env # public builds go straight to Maven Central (try-import is a no-op when absent). try-import %workspace%/tools/bazel/internal.bazelrc -# Java: hermetic remotejdk 25 regardless of the host JDK, matching the root -# module so builds are reproducible everywhere. +# Java: use the image-provided local JDK 25 (Temurin at JAVA_HOME) instead of a +# hermetic remotejdk download; the bazel-ci image ships Temurin 25 (no download). build --java_language_version=25 -build --java_runtime_version=remotejdk_25 +build --java_runtime_version=local_jdk build --tool_java_language_version=25 -build --tool_java_runtime_version=remotejdk_25 +build --tool_java_runtime_version=local_jdk build --java_header_compilation=false test --test_output=errors From 257a536444c4c954c2961c45c0e7c8980b97f384 Mon Sep 17 00:00:00 2001 From: Balaji Ganesan <bganesan@nvidia.com> Date: Thu, 23 Jul 2026 09:12:38 -0700 Subject: [PATCH 14/29] fix(java): align cloud-tasks + nv-boot-parent to the canonical single-hub Bazel design Replace the previous divergent Java Bazel structure (per-module @maven hubs, inlined BOMs + bom_alignment_test, a separate nvcf_java_rules module, and a local nv-boot-parent fork) with Sanjay Saxena's canonical feat/bazel design: - nv-boot-parent and cloud-tasks each build through one shared nv_third_party_deps hub (cloud-tasks contributes nv_boot_parent via known_contributing_modules); his tools/bazel macros, per-module BUILD files, and BAZEL.md are restored verbatim. - cloud-tasks consumes nv-boot-parent in-tree via bazel_dep + local_path_override (no GitLab git_override). - maven.install resolves from public Maven Central mirrors only (urm and home-netrc credentials removed); maven_install.json / MODULE.bazel.lock regenerated to record Central URLs. - Delete rules/java, examples/java-spring-boot-service, and the stale docs/bazel-java-architecture.md; drop the example row from .github/workflows/bazel.yml and refresh .bazelignore / root MODULE.bazel comments. - Java runtime uses local_jdk (bazel-ci image ships JDK 25); language version stays 25 and --java_header_compilation=false is preserved for Lombok. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Co-authored-by: Balaji Ganesan <bganesan@nvidia.com> --- .bazelignore | 12 +- .github/workflows/bazel.yml | 20 +- MODULE.bazel | 15 +- docs/bazel-java-architecture.md | 285 -- examples/java-spring-boot-service/.bazelrc | 47 - examples/java-spring-boot-service/.gitignore | 1 - examples/java-spring-boot-service/AGENTS.md | 25 - examples/java-spring-boot-service/BUILD.bazel | 98 - examples/java-spring-boot-service/CLAUDE.md | 1 - .../java-spring-boot-service/MODULE.bazel | 69 - .../MODULE.bazel.lock | 1236 -------- examples/java-spring-boot-service/README.md | 61 - .../maven_install.json | 2589 ----------------- .../nvcf/example/ExampleApplication.java | 27 - .../nvidia/nvcf/example/HelloController.java | 33 - .../nvcf/example/HelloControllerTest.java | 28 - .../nvcf/example/HelloControllerWebTest.java | 50 - rules/java/.bazelrc | 47 - rules/java/.gitignore | 1 - rules/java/AGENTS.md | 47 - rules/java/BUILD.bazel | 16 - rules/java/CLAUDE.md | 1 - rules/java/MODULE.bazel | 71 - rules/java/MODULE.bazel.lock | 296 -- rules/java/README.md | 75 - rules/java/bom_alignment.bzl | 55 - rules/java/defs.bzl | 25 - rules/java/platform.bzl | 53 - rules/java/platforms/BUILD.bazel | 32 - rules/java/private/BUILD.bazel | 16 - rules/java/private/oci.bzl | 162 -- rules/java/private/spring_boot.bzl | 142 - rules/java/scripts/BUILD.bazel | 18 - rules/java/scripts/check_bom_alignment.sh | 31 - .../cloud-tasks/.bazel_downloader_config | 4 + .../cloud-tasks/.bazelignore | 4 + .../cloud-tasks/.bazelrc | 56 +- .../cloud-tasks/.bazelversion | 1 + .../cloud-tasks/.gitignore | 46 +- .../cloud-tasks/AGENTS.md | 48 +- .../cloud-tasks/BAZEL.md | 781 +++++ .../cloud-tasks/BUILD.bazel | 52 +- .../cloud-tasks/MODULE.bazel | 176 +- .../cloud-tasks/MODULE.bazel.lock | 437 +-- .../cloud-tasks/maven_install.json | 432 +-- .../cloud-tasks/nvct-core/BUILD.bazel | 346 +-- .../task/HelmChartBasedTaskCreationTest.java | 2 +- .../cloud-tasks/nvct-service/BUILD.bazel | 129 +- .../src/main/resources/application-ncp.yaml | 4 +- .../cloud-tasks/tools/bazel/BUILD.bazel | 20 +- .../tools/bazel/generate_notice.sh | 21 + .../cloud-tasks/tools/bazel/java.bzl | 177 ++ .../tools/bazel/notice_check_test.sh | 21 + .../cloud-tasks/tools/bazel/runfiles.bzl | 26 - .../cloud-tasks/tools/bazel/spring_boot.bzl | 178 ++ src/libraries/java/nv-boot-parent/.bazelrc | 44 +- .../java/nv-boot-parent/.bazelversion | 1 + src/libraries/java/nv-boot-parent/AGENTS.md | 38 +- src/libraries/java/nv-boot-parent/BUILD.bazel | 23 +- .../java/nv-boot-parent/MODULE.bazel | 106 +- .../java/nv-boot-parent/MODULE.bazel.lock | 421 +-- src/libraries/java/nv-boot-parent/NOTICE | 13 +- .../java/nv-boot-parent/maven_install.json | 245 +- .../nv-boot-mock-servers-test/BUILD.bazel | 32 +- .../nv-boot-starter-audit/BUILD.bazel | 50 +- .../nv-boot-starter-cassandra/BUILD.bazel | 74 +- .../nv-boot-starter-core/BUILD.bazel | 54 +- .../BUILD.bazel | 38 +- .../nv-boot-starter-exceptions/BUILD.bazel | 28 +- .../nv-boot-starter-jwt/BUILD.bazel | 48 +- .../nv-boot-starter-observability/BUILD.bazel | 94 +- .../nv-boot-starter-registries/BUILD.bazel | 86 +- .../client/ngc/NgcArtifactRegistryClient.java | 3 +- .../BUILD.bazel | 32 +- .../nv-boot-starter-telemetry/BUILD.bazel | 56 +- src/libraries/java/nv-boot-parent/pom.xml | 42 +- .../nv-boot-parent/tools/bazel/BUILD.bazel | 9 +- .../java/nv-boot-parent/tools/bazel/java.bzl | 22 +- .../tools/bazel/notice_check_test.sh | 14 +- 79 files changed, 2192 insertions(+), 8027 deletions(-) delete mode 100644 docs/bazel-java-architecture.md delete mode 100644 examples/java-spring-boot-service/.bazelrc delete mode 100644 examples/java-spring-boot-service/.gitignore delete mode 100644 examples/java-spring-boot-service/AGENTS.md delete mode 100644 examples/java-spring-boot-service/BUILD.bazel delete mode 100644 examples/java-spring-boot-service/CLAUDE.md delete mode 100644 examples/java-spring-boot-service/MODULE.bazel delete mode 100644 examples/java-spring-boot-service/MODULE.bazel.lock delete mode 100644 examples/java-spring-boot-service/README.md delete mode 100755 examples/java-spring-boot-service/maven_install.json delete mode 100644 examples/java-spring-boot-service/src/main/java/com/nvidia/nvcf/example/ExampleApplication.java delete mode 100644 examples/java-spring-boot-service/src/main/java/com/nvidia/nvcf/example/HelloController.java delete mode 100644 examples/java-spring-boot-service/src/test/java/com/nvidia/nvcf/example/HelloControllerTest.java delete mode 100644 examples/java-spring-boot-service/src/test/java/com/nvidia/nvcf/example/HelloControllerWebTest.java delete mode 100644 rules/java/.bazelrc delete mode 100644 rules/java/.gitignore delete mode 100644 rules/java/AGENTS.md delete mode 100644 rules/java/BUILD.bazel delete mode 100644 rules/java/CLAUDE.md delete mode 100644 rules/java/MODULE.bazel delete mode 100644 rules/java/MODULE.bazel.lock delete mode 100644 rules/java/README.md delete mode 100644 rules/java/bom_alignment.bzl delete mode 100644 rules/java/defs.bzl delete mode 100644 rules/java/platform.bzl delete mode 100644 rules/java/platforms/BUILD.bazel delete mode 100644 rules/java/private/BUILD.bazel delete mode 100644 rules/java/private/oci.bzl delete mode 100644 rules/java/private/spring_boot.bzl delete mode 100644 rules/java/scripts/BUILD.bazel delete mode 100755 rules/java/scripts/check_bom_alignment.sh create mode 100644 src/control-plane-services/cloud-tasks/.bazel_downloader_config create mode 100644 src/control-plane-services/cloud-tasks/.bazelignore create mode 100644 src/control-plane-services/cloud-tasks/.bazelversion create mode 100644 src/control-plane-services/cloud-tasks/BAZEL.md mode change 100755 => 100644 src/control-plane-services/cloud-tasks/maven_install.json create mode 100755 src/control-plane-services/cloud-tasks/tools/bazel/generate_notice.sh create mode 100644 src/control-plane-services/cloud-tasks/tools/bazel/java.bzl create mode 100755 src/control-plane-services/cloud-tasks/tools/bazel/notice_check_test.sh delete mode 100644 src/control-plane-services/cloud-tasks/tools/bazel/runfiles.bzl create mode 100644 src/control-plane-services/cloud-tasks/tools/bazel/spring_boot.bzl create mode 100644 src/libraries/java/nv-boot-parent/.bazelversion diff --git a/.bazelignore b/.bazelignore index 548ae431e..bb26af335 100644 --- a/.bazelignore +++ b/.bazelignore @@ -52,15 +52,13 @@ infra migrations tools -# Standalone Java modules. Each has its own MODULE.bazel, @maven hub, and CI -# matrix row in .github/workflows/bazel.yml; their BUILD files reference -# module-local repos (@maven, @nvcf_java_rules, @nv_boot_parent) that the root -# module does not define, so the root build must not recurse into them. rules/java -# (module nvcf_java_rules) is intentionally NOT listed: its BUILD files declare no -# targets that reference the root workspace, so it stays loadable at the root. +# Standalone Java modules. Each has its own MODULE.bazel, its own +# nv_third_party_deps hub, and a CI matrix row in .github/workflows/bazel.yml; +# their BUILD files reference module-local repos (@nv_third_party_deps, +# @nv_boot_parent) that the root module does not define, so the root build must +# not recurse into them. src/libraries/java/nv-boot-parent src/control-plane-services/cloud-tasks -examples/java-spring-boot-service # Vendored dependencies inside the two Phase 1 subtrees. Bazel resolves these # from MODULE.bazel via Gazelle's go_deps extension, not from on-disk vendor. diff --git a/.github/workflows/bazel.yml b/.github/workflows/bazel.yml index 3acb76ecf..9c4a3b962 100644 --- a/.github/workflows/bazel.yml +++ b/.github/workflows/bazel.yml @@ -117,18 +117,18 @@ jobs: helm-reval|src/control-plane-services/helm-reval|false stargate|src/libraries/rust/stargate|false nv-boot-parent|src/libraries/java/nv-boot-parent|false - cloud-tasks|src/control-plane-services/cloud-tasks|false - java-spring-boot-service|examples/java-spring-boot-service|false' - # Standalone Java modules. Each has its own MODULE.bazel and @maven - # hub, so it builds+tests in its own module dir. Like every non-root - # row they do NOT set --config=remote; the build/test steps below - # inject --remote_cache/--tls_certificate/--remote_header from the - # EC2 Buildbarn secrets, so these rows warm from and hit that shared - # cache rather than cold-building (see NVIDIA/nvcf#372). + cloud-tasks|src/control-plane-services/cloud-tasks|false' + # Standalone Java modules. Each has its own MODULE.bazel and its own + # nv_third_party_deps hub, so it builds+tests in its own module dir. + # Like every non-root row they do NOT set --config=remote; the + # build/test steps below inject --remote_cache/--tls_certificate/ + # --remote_header from the EC2 Buildbarn secrets, so these rows warm + # from and hit that shared cache rather than cold-building (see + # NVIDIA/nvcf#372). # Paths that affect the root-module workspace build (native root # subtrees plus the shared Bazel scaffold). Java and stargate no longer - # ride the root row: nv-boot-parent, cloud-tasks, the example, and - # stargate are their own module rows, so src/libraries/ is narrowed to + # ride the root row: nv-boot-parent, cloud-tasks, and stargate are + # their own module rows, so src/libraries/ is narrowed to # src/libraries/go/ and cloud-tasks is dropped here. ROOT_GLOBS=(MODULE.bazel .bazelrc .bazelversion BUILD.bazel rules/ platforms/ tools/ ci/ src/clis/ src/libraries/go/ .github/bazel-root-test-quarantine.txt) diff --git a/MODULE.bazel b/MODULE.bazel index 4231093ec..03a069e92 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -148,16 +148,17 @@ use_repo( # Java / JVM # # Foundation for Spring Boot (and plain Java) services: Maven dependency -# resolution via rules_jvm_external, JUnit 5 test support via contrib_rules_jvm, -# and the nvcf_spring_boot_image macro in //rules/java. A new Java service wires -# in by adding its Maven coordinates to maven.install below (re-pin with -# `bazel run @maven//:pin`) and calling the macro from its BUILD.bazel. +# resolution via rules_jvm_external and JUnit 5 test support via +# contrib_rules_jvm. A new root-workspace Java target wires in by adding its +# Maven coordinates to maven.install below and re-pinning with +# `bazel run @nv_third_party_deps//:pin`. # # The pinned lock file (//:maven_install.json) makes resolution reproducible and # lets `bazel mod` run offline. Repositories intentionally lists only Maven # Central so the foundation builds anywhere, including the public GitHub mirror. -# Internal services that depend on nv-boot add the internal Artifactory virtual -# repo here; see rules/java/README.md. +# Standalone Java modules (src/libraries/java/nv-boot-parent, +# src/control-plane-services/cloud-tasks) instead own their own MODULE.bazel and +# nv_third_party_deps hub and are ignored by the root build (see .bazelignore). # ============================================================================ bazel_dep(name = "rules_java", version = "9.3.0") bazel_dep(name = "rules_jvm_external", version = "7.0") @@ -289,7 +290,7 @@ maven.install( "org.wiremock:wiremock-standalone:3.13.2", "software.amazon.awssdk:regions:2.40.1", "tools.jackson.module:jackson-module-blackbird", - # examples/java-spring-boot-service (versions from the Spring Boot BOM). + # General Java test/web roots (versions from the Spring Boot BOM). "org.springframework.boot:spring-boot-starter-web", "org.junit.jupiter:junit-jupiter-api", "org.junit.jupiter:junit-jupiter-engine", diff --git a/docs/bazel-java-architecture.md b/docs/bazel-java-architecture.md deleted file mode 100644 index 0014f8326..000000000 --- a/docs/bazel-java-architecture.md +++ /dev/null @@ -1,285 +0,0 @@ -# Java in the NVCF Monorepo: Target Bazel Architecture - -Status: target architecture. Supersedes the interim root-workspace setup where -all Java code shared one root Maven hub and one lockfile. - -## Goals - -- Every Java library and service is an independent Bazel module. Each builds, - tests, and pins its dependencies on its own: `cd <module> && bazel build //...` - works with no reference to the repo root. -- A service can be consumed from outside the monorepo by module name, pulling - only its subtree, via `git_override` with `strip_prefix`. -- One shared source of truth for the Spring Boot platform (BOM plus common - starters) so 10+ services do not each re-declare and drift on versions. -- Parity with the rest of the repo: Go and Rust services are already - self-contained nested modules with their own `MODULE.bazel` and CI matrix - row. Java stops being the exception. - -## Non-goals - -- No shared root Maven hub. `@nv_third_party_deps` at the root and the root - `//:maven_install.json` are retired for Java. -- No cross-module dependence through absolute source labels - (`//src/libraries/java/nv-boot-parent/...`). Cross-module edges go through - `bazel_dep`. - -## Topology - -``` -rules/java/ module: nvcf_java_rules (shared macros) - MODULE.bazel - defs.bzl nvcf_java_library, nvcf_spring_boot_image, - platform.bzl java_junit5_test, SPRING_BOOT_BOM, versions -src/libraries/java/ - nv-boot-parent/ module: nv_boot_parent (platform library) - MODULE.bazel owns the Spring BOM + shared starters - maven_install.json its own lockfile - nv-boot-*/BUILD.bazel java_library targets, public -src/control-plane-services/ - cloud-tasks/ module: nvct_cloud_tasks (service) - MODULE.bazel bazel_dep nv_boot_parent + nvcf_java_rules - maven_install.json its own lockfile: service-only deltas - nvct-core/BUILD.bazel - nvct-service/BUILD.bazel nvcf_spring_boot_image -> OCI image - <next java service>/ same shape, one per service -``` - -Three module kinds: - -- Rules module (`nvcf_java_rules`, at `rules/java`). Holds the macros and the - single versions/BOM definition. No application code. Consumed by every Java - module via `bazel_dep` + `local_path_override`. This mirrors how - `rules/oci-destinations` (module `nvcf_nvcr_destinations`) is already - consumed by infra/cassandra. -- Platform library module (`nv_boot_parent`). Owns the canonical Spring Boot - BOM and the shared `nv-boot-*` starters as `java_library` targets. It has its - own Maven hub. Services depend on it, not on raw Spring coordinates it - already provides. -- Service modules (`nvct_cloud_tasks`, and each future service). One image per - service via `nvcf_spring_boot_image`. Depends on `nv_boot_parent` and - `nvcf_java_rules`. Declares only the Maven coordinates it uses directly and - that the platform does not already export. - -## Dependency edges - -In-monorepo builds resolve cross-module edges with `local_path_override`, so -local source always wins over any registry copy. Paths are relative to the -consuming module directory. - -`rules/java/MODULE.bazel`: - -```python -module(name = "nvcf_java_rules", version = "0.1.0") -bazel_dep(name = "rules_java", version = "9.3.0") -bazel_dep(name = "rules_jvm_external", version = "7.0") -bazel_dep(name = "contrib_rules_jvm", version = "0.27.0") -bazel_dep(name = "rules_oci", version = "2.2.7") -bazel_dep(name = "rules_pkg", version = "1.2.0") -``` - -`src/libraries/java/nv-boot-parent/MODULE.bazel`: - -```python -module(name = "nv_boot_parent", version = "1.4.1") - -bazel_dep(name = "nvcf_java_rules", version = "0.1.0") -local_path_override(module_name = "nvcf_java_rules", path = "../../../../rules/java") - -bazel_dep(name = "rules_java", version = "9.3.0") -bazel_dep(name = "rules_jvm_external", version = "7.0") - -maven = use_extension("@rules_jvm_external//:extensions.bzl", "maven") -maven.install( - name = "maven", - lock_file = "//:maven_install.json", - # load() is forbidden in MODULE.bazel, so the BOM cannot reference - # SPRING_BOOT_BOM here. The list is inlined verbatim and guarded by - # //:bom_alignment_test, which fails if it drifts from platform.bzl. - boms = [ - "org.springframework.boot:spring-boot-dependencies:4.0.7", - "org.springframework.cloud:spring-cloud-dependencies:2025.1.2", - "org.testcontainers:testcontainers-bom:2.0.5", - "net.javacrumbs.shedlock:shedlock-bom:7.7.0", - ], - artifacts = [ ... shared starter coordinates ... ], - repositories = [ ... same two public Central mirrors ... ], -) -use_repo(maven, "maven") -``` - -`src/control-plane-services/cloud-tasks/MODULE.bazel`: - -```python -module(name = "nvct_cloud_tasks", version = "1.1.0") - -bazel_dep(name = "nvcf_java_rules", version = "0.1.0") -local_path_override(module_name = "nvcf_java_rules", path = "../../../rules/java") - -bazel_dep(name = "nv_boot_parent", version = "1.4.1") -local_path_override(module_name = "nv_boot_parent", path = "../../libraries/java/nv-boot-parent") - -maven = use_extension("@rules_jvm_external//:extensions.bzl", "maven") -maven.install( - name = "maven", - lock_file = "//:maven_install.json", - # Same inlined BOM list as every other Java module (see the note above); - # //:bom_alignment_test keeps it aligned with platform.bzl. - boms = [ ... the four canonical BOMs ... ], - artifacts = [ ... only coordinates cloud-tasks uses directly ... ], - repositories = [ ... same two public Central mirrors ... ], -) -use_repo(maven, "maven") -``` - -Service BUILD files then reference `@nv_boot_parent//nv-boot-registries:...` -for platform targets and `@maven//:...` for the service's own deps. The old -`@nv_third_party_deps//:...` labels are replaced by the module-local `@maven`. - -## Maven strategy: one BOM, many hubs - -Each module resolves its own Maven graph and writes its own -`maven_install.json`. That is what makes a module independently buildable. The -risk is version drift: two modules pinning different Spring versions put two -copies on a transitive classpath. - -Rule: the Spring Boot BOM and any other shared BOMs are defined once, in -`@nvcf_java_rules//:platform.bzl`, as a loadable list: - -```python -# rules/java/platform.bzl -SPRING_BOOT_VERSION = "3.5.11" -SPRING_BOOT_BOM = ["org.springframework.boot:spring-boot-dependencies:%s" % SPRING_BOOT_VERSION] -MAVEN_REPOSITORIES = [ - "https://repo1.maven.org/maven2", - # internal mirrors appended by the private overlay, never in the OSS tree -] -``` - -`load()` is forbidden in `MODULE.bazel`, so a module cannot write -`boms = SPRING_BOOT_BOM` directly. Instead every Java module inlines the same -literal BOM list in its `maven.install` and lists BOM-managed coordinates -without a version. The alignment is enforced, not trusted: each module calls -`bom_alignment_test` (from `@nvcf_java_rules//:bom_alignment.bzl`), which -materializes `SPRING_BOOT_BOM` from `platform.bzl` and fails the build if any -canonical coordinate is missing from that module's `MODULE.bazel`. Bumping Spring -is then a one-line change in `platform.bzl`, the matching edit to each module's -inlined list, and a re-pin; a module left un-aligned fails its own test. Because -the BOM is identical everywhere, the independent resolutions agree. - -The platform module (`nv_boot_parent`) additionally exports the common -starters as `java_library` targets. A service that depends on -`@nv_boot_parent//nv-boot-web:...` gets those starters and their transitive -Maven deps without re-declaring them. A service only lists a coordinate in its -own `maven.install` when it uses that library directly and the platform does -not already export it. - -## Independent build contract - -For every Java module: - -- `MODULE.bazel` at the module root, with a unique `module(name=...)`. -- Committed `maven_install.json` (or `<name>_install.json`) lockfile. -- `.bazelrc` with the Java toolchain (`--java_language_version=21`, - `--java_runtime_version=remotejdk_21`) and a `build:release` config. -- `bazel build //...` and `bazel test //...` pass from the module directory - with no `--override_module` flags on the command line. -- The repo root lists the module path in `.bazelignore` so the root workspace - does not recurse into it (same as `infra/cassandra`, stargate, - function-autoscaler). - -## CI: one matrix row per module - -`.github/workflows/bazel.yml` derives a matrix row from each nested -`MODULE.bazel`. After migration: - -- `bazel (nv-boot-parent)`, `bazel (cloud-tasks)`, and one row per future - service, each running `bazel build //... && bazel test //...` in the module - directory. -- Java paths are removed from `ROOT_GLOBS`. Java no longer rides the - `bazel (root)` row. -- Add each module to the ROWS list: - `nv-boot-parent|src/libraries/java/nv-boot-parent|false`, - `cloud-tasks|src/control-plane-services/cloud-tasks|false`. - -Isolated rows mean a failing service does not block the others, and build time -scales out instead of piling onto one root job. - -## External and managed-side consumption - -Because `nv_boot_parent` is a real module rooted at its own subtree, an -out-of-tree Bazel workspace consumes it without vendoring the monorepo: - -```python -bazel_dep(name = "nv_boot_parent", version = "1.4.1") -git_override( - module_name = "nv_boot_parent", - remote = "https://github.com/NVIDIA/nvcf.git", - commit = "<pinned sha>", - strip_prefix = "src/libraries/java/nv-boot-parent", -) -``` - -`strip_prefix` requires `MODULE.bazel` at that subdirectory. The platform -library only needs public BCR modules (`rules_java`, `rules_jvm_external`) plus -its Maven hub, so it resolves for external consumers with no access to internal -rules. Services are consumable the same way when needed. - -For in-monorepo builds the same modules use `local_path_override` instead of -`git_override`, so local edits are always authoritative and no network fetch of -the monorepo occurs. - -## Versioning and pinning - -- `module(version=...)` tracks the artifact version. `git_override` and - `local_path_override` ignore it (they pin by commit or path), so it is - informational for in-tree builds and meaningful only if a module is ever - published to a registry. -- Re-pin a module after changing its `maven.install`: - `REPIN=1 bazel run @maven//:pin` from the module directory. Commit the - updated lockfile. -- Bumping a shared version (Spring, JUnit) is a change in - `@nvcf_java_rules//:platform.bzl` followed by a re-pin of every Java module. - CI catches any module left un-repinned. - -## NOTICE and license - -Each module generates its NOTICE from its own lockfile. The `nv-boot-parent` -notice tooling that currently reads the root `//:maven_install.json` is -repointed at the module-local lockfile. Services generate their own NOTICE the -same way. There is no root aggregate lockfile for Java to depend on. - -## Adding a new Java service - -1. Create the module directory with `MODULE.bazel` - (`module(name = "nvct_<svc>", ...)`), `bazel_dep` + `local_path_override` - for `nvcf_java_rules` and `nv_boot_parent`, and a `maven.install` loading - `SPRING_BOOT_BOM` plus only the service's direct coordinates. -2. Add `.bazelrc` (Java toolchain + `build:release`) and a `CLAUDE.md` - (`@AGENTS.md`) plus `AGENTS.md` for the subtree. -3. Write `BUILD.bazel` using `nvcf_java_library`, `nvcf_spring_boot_image`, and - `java_junit5_test` from `@nvcf_java_rules//rules/java:defs.bzl`. -4. `REPIN=1 bazel run @maven//:pin`; commit `maven_install.json`. -5. Add the module path to root `.bazelignore` and to the `bazel.yml` ROWS list. -6. `cd <module> && bazel build //... && bazel test //...` must pass. - -## Migration from the interim setup - -Order matters: the rules module and platform must land before services can -point at them. - -1. `rules/java`: add `MODULE.bazel` (`nvcf_java_rules`) and `platform.bzl` - (`SPRING_BOOT_BOM`, `MAVEN_REPOSITORIES`, shared version constants). -2. `nv-boot-parent`: add `MODULE.bazel` (`nv_boot_parent`) and its own - `maven.install` seeded from the shared coordinates it owns; re-pin; move its - notice tooling to the module-local lockfile. Verify - `cd src/libraries/java/nv-boot-parent && bazel build //...`. -3. `cloud-tasks`: add `MODULE.bazel` (`nvct_cloud_tasks`), replace - `@nv_third_party_deps//:...` with `@maven//:...`, replace - `//src/libraries/java/nv-boot-parent/...` source labels with - `@nv_boot_parent//...`, re-pin. Verify standalone build and image target. -4. Remove Java coordinates from the root `MODULE.bazel` `nv_third_party_deps` - hub and the root `//:maven_install.json`; drop Java from `ROOT_GLOBS`; add - the two module rows to `.bazelignore` and `bazel.yml`. -5. Repeat step 3 for each remaining Java service as it onboards. -``` diff --git a/examples/java-spring-boot-service/.bazelrc b/examples/java-spring-boot-service/.bazelrc deleted file mode 100644 index 38ab37cda..000000000 --- a/examples/java-spring-boot-service/.bazelrc +++ /dev/null @@ -1,47 +0,0 @@ -# SPDX-FileCopyrightText: Copyright (c) NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# 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. - -# Standalone module .bazelrc. `cd rules/java && bazel build //...` must work with -# no reference to the repo root. The caller supplies any remote cache endpoint; -# no cache config is baked in (parity with the other nested modules). - -common --enable_bzlmod -common --enable_platform_specific_config -build --incompatible_strict_action_env - -# Route public Maven Central through an internal Artifactory mirror on internal -# builds only. The target host lives in an un-mirrored internal bazelrc, so -# public builds go straight to Maven Central (try-import is a no-op when absent). -try-import %workspace%/tools/bazel/internal.bazelrc - -# Java: use the image-provided local JDK 25 (Temurin at JAVA_HOME) instead of a -# hermetic remotejdk download; the bazel-ci image ships Temurin 25 (no download). -build --java_language_version=25 -build --java_runtime_version=local_jdk -build --tool_java_language_version=25 -build --tool_java_runtime_version=local_jdk -build --java_header_compilation=false - -test --test_output=errors -test --test_env=HOME=/tmp -test --test_env=XDG_CACHE_HOME=/tmp/.cache - -startup --host_jvm_args=-Xmx4g - -build:release --compilation_mode=opt -build:release --strip=always - -try-import %workspace%/user.bazelrc -try-import %user.home%/.bazelrc.user diff --git a/examples/java-spring-boot-service/.gitignore b/examples/java-spring-boot-service/.gitignore deleted file mode 100644 index a6ef824c1..000000000 --- a/examples/java-spring-boot-service/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/bazel-* diff --git a/examples/java-spring-boot-service/AGENTS.md b/examples/java-spring-boot-service/AGENTS.md deleted file mode 100644 index 2a1f2af99..000000000 --- a/examples/java-spring-boot-service/AGENTS.md +++ /dev/null @@ -1,25 +0,0 @@ -# AGENTS.md - nvcf_java_example - -Reference Spring Boot service, as a standalone Bazel module -(`module(name = "nvcf_java_example")`). The copy-me template for a new NVCF Java -service module. - -## Build and test (from this directory) - -``` -cd examples/java-spring-boot-service -bazel build //... -bazel test //... -``` - -Depends only on `nvcf_java_rules` (macros + multi-arch image helper) via -`bazel_dep` + `local_path_override`, plus its own `@maven` hub and committed -`maven_install.json`. A real service additionally `bazel_dep`s `nv_boot_parent` -and adds the internal Maven overlay. Re-pin after editing `maven.install`: - -``` -REPIN=1 bazel run @maven//:pin -``` - -The `boms` list must stay identical to `SPRING_BOOT_BOM` in -`@nvcf_java_rules//:platform.bzl`; `//:bom_alignment_test` enforces it. diff --git a/examples/java-spring-boot-service/BUILD.bazel b/examples/java-spring-boot-service/BUILD.bazel deleted file mode 100644 index e3732c605..000000000 --- a/examples/java-spring-boot-service/BUILD.bazel +++ /dev/null @@ -1,98 +0,0 @@ -# SPDX-FileCopyrightText: Copyright (c) NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# 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. - -# Reference Spring Boot service. Doubles as the template a new Java service -# copies: a java_library for the app, nvcf_spring_boot_image for the multi-arch -# container, and a JUnit 5 test. To publish images, add a registry = ... to the -# image target and a release: block in tools/ci/subproject-validations.yaml -# (see the grpc-proxy entry). See README.md for the nv-boot / internal Maven -# wiring a real service adds. - -load("@contrib_rules_jvm//java:defs.bzl", "java_junit5_test") -load("@nvcf_java_rules//:bom_alignment.bzl", "bom_alignment_test") -load("@nvcf_java_rules//:defs.bzl", "nvcf_java_library", "nvcf_spring_boot_image") - -exports_files(["MODULE.bazel"]) - -# Fails the build if this module's inlined maven.install boms drift from the -# canonical SPRING_BOOT_BOM in @nvcf_java_rules//:platform.bzl. -bom_alignment_test( - name = "bom_alignment_test", -) - -nvcf_java_library( - name = "example_lib", - srcs = glob(["src/main/java/**/*.java"]), - visibility = ["//visibility:public"], - # The starter carries the full runtime (embedded Tomcat, Jackson, ...); - # the concrete artifacts below are the ones the code imports directly, so - # the strict-deps header compiler sees them on the direct classpath. - deps = [ - "@maven//:org_springframework_boot_spring_boot", - "@maven//:org_springframework_boot_spring_boot_autoconfigure", - "@maven//:org_springframework_boot_spring_boot_starter_web", - "@maven//:org_springframework_spring_web", - ], -) - -# Multi-arch OCI image: :image (host arch), :image_index (amd64 + arm64), -# :image_load (docker load), :image.tar. A registry = ... would also emit -# :image_push. Tagged "manual", so bazel build //... skips it; the CI entry -# builds :image_index explicitly. -nvcf_spring_boot_image( - name = "image", - main_class = "com.nvidia.nvcf.example.ExampleApplication", - visibility = ["//visibility:public"], - deps = [":example_lib"], -) - -java_junit5_test( - name = "hello_controller_test", - srcs = ["src/test/java/com/nvidia/nvcf/example/HelloControllerTest.java"], - test_class = "com.nvidia.nvcf.example.HelloControllerTest", - runtime_deps = [ - "@maven//:org_junit_jupiter_junit_jupiter_engine", - "@maven//:org_junit_platform_junit_platform_launcher", - "@maven//:org_junit_platform_junit_platform_reporting", - ], - deps = [ - ":example_lib", - "@maven//:org_junit_jupiter_junit_jupiter_api", - ], -) - -# Boots the full Spring context and hits /hello through MockMvc. This is the -# test that actually exercises the exploded-classpath design: starting the -# context reads each dependency jar's auto-configuration metadata, so a broken -# classpath assembly fails here where the plain unit test above cannot. -java_junit5_test( - name = "hello_controller_web_test", - srcs = ["src/test/java/com/nvidia/nvcf/example/HelloControllerWebTest.java"], - test_class = "com.nvidia.nvcf.example.HelloControllerWebTest", - runtime_deps = [ - "@maven//:org_junit_jupiter_junit_jupiter_engine", - "@maven//:org_junit_platform_junit_platform_launcher", - "@maven//:org_junit_platform_junit_platform_reporting", - ], - deps = [ - ":example_lib", - "@maven//:org_junit_jupiter_junit_jupiter_api", - "@maven//:org_springframework_boot_spring_boot_test", - "@maven//:org_springframework_boot_spring_boot_test_autoconfigure", - "@maven//:org_springframework_boot_spring_boot_webmvc_test", - "@maven//:org_springframework_spring_beans", - "@maven//:org_springframework_spring_test", - ], -) diff --git a/examples/java-spring-boot-service/CLAUDE.md b/examples/java-spring-boot-service/CLAUDE.md deleted file mode 100644 index 43c994c2d..000000000 --- a/examples/java-spring-boot-service/CLAUDE.md +++ /dev/null @@ -1 +0,0 @@ -@AGENTS.md diff --git a/examples/java-spring-boot-service/MODULE.bazel b/examples/java-spring-boot-service/MODULE.bazel deleted file mode 100644 index 1c462b3c9..000000000 --- a/examples/java-spring-boot-service/MODULE.bazel +++ /dev/null @@ -1,69 +0,0 @@ -# SPDX-FileCopyrightText: Copyright (c) NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# 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. - -"""nvcf_java_example: reference Spring Boot service, as a standalone module. - -The copy-me template for a new NVCF Java service module: bazel_dep on -nvcf_java_rules, a java_library for the app, nvcf_spring_boot_image for the -multi-arch container, and JUnit 5 tests. A real service also bazel_deps -nv_boot_parent and adds the internal Maven overlay; see README.md. -""" - -module( - name = "nvcf_java_example", - version = "4.0.7", -) - -bazel_dep(name = "nvcf_java_rules", version = "0.1.0") -local_path_override( - module_name = "nvcf_java_rules", - path = "../../rules/java", -) - -bazel_dep(name = "rules_java", version = "9.3.0") -bazel_dep(name = "rules_jvm_external", version = "7.0") -bazel_dep(name = "contrib_rules_jvm", version = "0.33.0") - -maven = use_extension("@rules_jvm_external//:extensions.bzl", "maven") -maven.install( - name = "maven", - artifacts = [ - "org.springframework.boot:spring-boot-starter-web", - "org.springframework.boot:spring-boot-starter-test", - "org.springframework.boot:spring-boot-webmvc-test", - "org.junit.jupiter:junit-jupiter-api", - "org.junit.jupiter:junit-jupiter-engine", - "org.junit.platform:junit-platform-launcher", - "org.junit.platform:junit-platform-reporting", - ], - boms = [ - # Keep identical to SPRING_BOOT_BOM in @nvcf_java_rules//:platform.bzl. - # //:bom_alignment_test fails the build if these drift. - "org.springframework.boot:spring-boot-dependencies:4.0.7", - "org.springframework.cloud:spring-cloud-dependencies:2025.1.2", - "org.testcontainers:testcontainers-bom:2.0.5", - "net.javacrumbs.shedlock:shedlock-bom:7.7.0", - ], - fail_on_missing_checksum = True, - fetch_sources = True, - known_contributing_modules = ["protobuf"], - lock_file = "//:maven_install.json", - repositories = [ - "https://maven-central.storage-download.googleapis.com/maven2", - "https://repo.maven.apache.org/maven2", - ], - resolver = "maven", -) -use_repo(maven, "maven") diff --git a/examples/java-spring-boot-service/MODULE.bazel.lock b/examples/java-spring-boot-service/MODULE.bazel.lock deleted file mode 100644 index 3a653bd7d..000000000 --- a/examples/java-spring-boot-service/MODULE.bazel.lock +++ /dev/null @@ -1,1236 +0,0 @@ -{ - "lockFileVersion": 28, - "registryFileHashes": { - "https://bcr.bazel.build/bazel_registry.json": "8a28e4aff06ee60aed2a8c281907fb8bcbf3b753c91fb5a5c57da3215d5b3497", - "https://bcr.bazel.build/modules/abseil-cpp/20210324.2/MODULE.bazel": "7cd0312e064fde87c8d1cd79ba06c876bd23630c83466e9500321be55c96ace2", - "https://bcr.bazel.build/modules/abseil-cpp/20211102.0/MODULE.bazel": "70390338f7a5106231d20620712f7cccb659cd0e9d073d1991c038eb9fc57589", - "https://bcr.bazel.build/modules/abseil-cpp/20230125.1/MODULE.bazel": "89047429cb0207707b2dface14ba7f8df85273d484c2572755be4bab7ce9c3a0", - "https://bcr.bazel.build/modules/abseil-cpp/20230802.0.bcr.1/MODULE.bazel": "1c8cec495288dccd14fdae6e3f95f772c1c91857047a098fad772034264cc8cb", - "https://bcr.bazel.build/modules/abseil-cpp/20230802.0/MODULE.bazel": "d253ae36a8bd9ee3c5955384096ccb6baf16a1b1e93e858370da0a3b94f77c16", - "https://bcr.bazel.build/modules/abseil-cpp/20230802.1/MODULE.bazel": "fa92e2eb41a04df73cdabeec37107316f7e5272650f81d6cc096418fe647b915", - "https://bcr.bazel.build/modules/abseil-cpp/20240116.1/MODULE.bazel": "37bcdb4440fbb61df6a1c296ae01b327f19e9bb521f9b8e26ec854b6f97309ed", - "https://bcr.bazel.build/modules/abseil-cpp/20240116.2/MODULE.bazel": "73939767a4686cd9a520d16af5ab440071ed75cec1a876bf2fcfaf1f71987a16", - "https://bcr.bazel.build/modules/abseil-cpp/20250127.0/MODULE.bazel": "d1086e248cda6576862b4b3fe9ad76a214e08c189af5b42557a6e1888812c5d5", - "https://bcr.bazel.build/modules/abseil-cpp/20250127.1/MODULE.bazel": "c4a89e7ceb9bf1e25cf84a9f830ff6b817b72874088bf5141b314726e46a57c1", - "https://bcr.bazel.build/modules/abseil-cpp/20250512.1/MODULE.bazel": "d209fdb6f36ffaf61c509fcc81b19e81b411a999a934a032e10cd009a0226215", - "https://bcr.bazel.build/modules/abseil-cpp/20250814.1/MODULE.bazel": "51f2312901470cdab0dbdf3b88c40cd21c62a7ed58a3de45b365ddc5b11bcab2", - "https://bcr.bazel.build/modules/abseil-cpp/20250814.1/source.json": "cea3901d7e299da7320700abbaafe57a65d039f10d0d7ea601c4a66938ea4b0c", - "https://bcr.bazel.build/modules/abseil-py/2.1.0/MODULE.bazel": "5ebe5bf853769c65707e5c28f216798f7a4b1042015e6a36e6d03094d94bec8a", - "https://bcr.bazel.build/modules/abseil-py/2.1.0/source.json": "0e8fc4f088ce07099c1cd6594c20c7ddbb48b4b3c0849b7d94ba94be88ff042b", - "https://bcr.bazel.build/modules/apple_rules_lint/0.4.0/MODULE.bazel": "c59831c3a5389430516203777816527f257329a5da363994e1d62b9ae6729f71", - "https://bcr.bazel.build/modules/apple_rules_lint/0.4.0/source.json": "105883202602181f43f109372e1b9ea19e89bbe3bce4bc1fe9bb0baa51eb61ae", - "https://bcr.bazel.build/modules/apple_support/1.11.1/MODULE.bazel": "1843d7cd8a58369a444fc6000e7304425fba600ff641592161d9f15b179fb896", - "https://bcr.bazel.build/modules/apple_support/1.15.1/MODULE.bazel": "a0556fefca0b1bb2de8567b8827518f94db6a6e7e7d632b4c48dc5f865bc7c85", - "https://bcr.bazel.build/modules/apple_support/1.21.0/MODULE.bazel": "ac1824ed5edf17dee2fdd4927ada30c9f8c3b520be1b5fd02a5da15bc10bff3e", - "https://bcr.bazel.build/modules/apple_support/1.21.1/MODULE.bazel": "5809fa3efab15d1f3c3c635af6974044bac8a4919c62238cce06acee8a8c11f1", - "https://bcr.bazel.build/modules/apple_support/1.24.2/MODULE.bazel": "0e62471818affb9f0b26f128831d5c40b074d32e6dda5a0d3852847215a41ca4", - "https://bcr.bazel.build/modules/apple_support/1.24.2/source.json": "2c22c9827093250406c5568da6c54e6fdf0ef06238def3d99c71b12feb057a8d", - "https://bcr.bazel.build/modules/aspect_bazel_lib/2.14.0/MODULE.bazel": "2b31ffcc9bdc8295b2167e07a757dbbc9ac8906e7028e5170a3708cecaac119f", - "https://bcr.bazel.build/modules/aspect_bazel_lib/2.19.3/MODULE.bazel": "253d739ba126f62a5767d832765b12b59e9f8d2bc88cc1572f4a73e46eb298ca", - "https://bcr.bazel.build/modules/aspect_bazel_lib/2.19.3/source.json": "ffab9254c65ba945f8369297ad97ca0dec213d3adc6e07877e23a48624a8b456", - "https://bcr.bazel.build/modules/aspect_bazel_lib/2.7.2/MODULE.bazel": "780d1a6522b28f5edb7ea09630748720721dfe27690d65a2d33aa7509de77e07", - "https://bcr.bazel.build/modules/aspect_bazel_lib/2.8.1/MODULE.bazel": "812d2dd42f65dca362152101fbec418029cc8fd34cbad1a2fde905383d705838", - "https://bcr.bazel.build/modules/bazel_features/1.1.0/MODULE.bazel": "cfd42ff3b815a5f39554d97182657f8c4b9719568eb7fded2b9135f084bf760b", - "https://bcr.bazel.build/modules/bazel_features/1.1.1/MODULE.bazel": "27b8c79ef57efe08efccbd9dd6ef70d61b4798320b8d3c134fd571f78963dbcd", - "https://bcr.bazel.build/modules/bazel_features/1.10.0/MODULE.bazel": "f75e8807570484a99be90abcd52b5e1f390362c258bcb73106f4544957a48101", - "https://bcr.bazel.build/modules/bazel_features/1.11.0/MODULE.bazel": "f9382337dd5a474c3b7d334c2f83e50b6eaedc284253334cf823044a26de03e8", - "https://bcr.bazel.build/modules/bazel_features/1.13.0/MODULE.bazel": "c14c33c7c3c730612bdbe14ebbb5e61936b6f11322ea95a6e91cd1ba962f94df", - "https://bcr.bazel.build/modules/bazel_features/1.15.0/MODULE.bazel": "d38ff6e517149dc509406aca0db3ad1efdd890a85e049585b7234d04238e2a4d", - "https://bcr.bazel.build/modules/bazel_features/1.17.0/MODULE.bazel": "039de32d21b816b47bd42c778e0454217e9c9caac4a3cf8e15c7231ee3ddee4d", - "https://bcr.bazel.build/modules/bazel_features/1.18.0/MODULE.bazel": "1be0ae2557ab3a72a57aeb31b29be347bcdc5d2b1eb1e70f39e3851a7e97041a", - "https://bcr.bazel.build/modules/bazel_features/1.19.0/MODULE.bazel": "59adcdf28230d220f0067b1f435b8537dd033bfff8db21335ef9217919c7fb58", - "https://bcr.bazel.build/modules/bazel_features/1.21.0/MODULE.bazel": "675642261665d8eea09989aa3b8afb5c37627f1be178382c320d1b46afba5e3b", - "https://bcr.bazel.build/modules/bazel_features/1.23.0/MODULE.bazel": "fd1ac84bc4e97a5a0816b7fd7d4d4f6d837b0047cf4cbd81652d616af3a6591a", - "https://bcr.bazel.build/modules/bazel_features/1.25.0/MODULE.bazel": "e2e60a10a6da64bbf533f15ca652bf61a033e41c2ed734d79a9a08ba87f68c1a", - "https://bcr.bazel.build/modules/bazel_features/1.27.0/MODULE.bazel": "621eeee06c4458a9121d1f104efb80f39d34deff4984e778359c60eaf1a8cb65", - "https://bcr.bazel.build/modules/bazel_features/1.28.0/MODULE.bazel": "4b4200e6cbf8fa335b2c3f43e1d6ef3e240319c33d43d60cc0fbd4b87ece299d", - "https://bcr.bazel.build/modules/bazel_features/1.3.0/MODULE.bazel": "cdcafe83ec318cda34e02948e81d790aab8df7a929cec6f6969f13a489ccecd9", - "https://bcr.bazel.build/modules/bazel_features/1.30.0/MODULE.bazel": "a14b62d05969a293b80257e72e597c2da7f717e1e69fa8b339703ed6731bec87", - "https://bcr.bazel.build/modules/bazel_features/1.33.0/MODULE.bazel": "8b8dc9d2a4c88609409c3191165bccec0e4cb044cd7a72ccbe826583303459f6", - "https://bcr.bazel.build/modules/bazel_features/1.4.1/MODULE.bazel": "e45b6bb2350aff3e442ae1111c555e27eac1d915e77775f6fdc4b351b758b5d7", - "https://bcr.bazel.build/modules/bazel_features/1.42.1/MODULE.bazel": "275a59b5406ff18c01739860aa70ad7ccb3cfb474579411decca11c93b951080", - "https://bcr.bazel.build/modules/bazel_features/1.42.1/source.json": "fcd4396b2df85f64f2b3bb436ad870793ecf39180f1d796f913cc9276d355309", - "https://bcr.bazel.build/modules/bazel_features/1.9.0/MODULE.bazel": "885151d58d90d8d9c811eb75e3288c11f850e1d6b481a8c9f766adee4712358b", - "https://bcr.bazel.build/modules/bazel_features/1.9.1/MODULE.bazel": "8f679097876a9b609ad1f60249c49d68bfab783dd9be012faf9d82547b14815a", - "https://bcr.bazel.build/modules/bazel_lib/3.0.0/MODULE.bazel": "22b70b80ac89ad3f3772526cd9feee2fa412c2b01933fea7ed13238a448d370d", - "https://bcr.bazel.build/modules/bazel_lib/3.0.0/source.json": "895f21909c6fba01d7c17914bb6c8e135982275a1b18cdaa4e62272217ef1751", - "https://bcr.bazel.build/modules/bazel_skylib/1.0.3/MODULE.bazel": "bcb0fd896384802d1ad283b4e4eb4d718eebd8cb820b0a2c3a347fb971afd9d8", - "https://bcr.bazel.build/modules/bazel_skylib/1.1.1/MODULE.bazel": "1add3e7d93ff2e6998f9e118022c84d163917d912f5afafb3058e3d2f1545b5e", - "https://bcr.bazel.build/modules/bazel_skylib/1.2.0/MODULE.bazel": "44fe84260e454ed94ad326352a698422dbe372b21a1ac9f3eab76eb531223686", - "https://bcr.bazel.build/modules/bazel_skylib/1.2.1/MODULE.bazel": "f35baf9da0efe45fa3da1696ae906eea3d615ad41e2e3def4aeb4e8bc0ef9a7a", - "https://bcr.bazel.build/modules/bazel_skylib/1.3.0/MODULE.bazel": "20228b92868bf5cfc41bda7afc8a8ba2a543201851de39d990ec957b513579c5", - "https://bcr.bazel.build/modules/bazel_skylib/1.4.1/MODULE.bazel": "a0dcb779424be33100dcae821e9e27e4f2901d9dfd5333efe5ac6a8d7ab75e1d", - "https://bcr.bazel.build/modules/bazel_skylib/1.4.2/MODULE.bazel": "3bd40978e7a1fac911d5989e6b09d8f64921865a45822d8b09e815eaa726a651", - "https://bcr.bazel.build/modules/bazel_skylib/1.5.0/MODULE.bazel": "32880f5e2945ce6a03d1fbd588e9198c0a959bb42297b2cfaf1685b7bc32e138", - "https://bcr.bazel.build/modules/bazel_skylib/1.6.1/MODULE.bazel": "8fdee2dbaace6c252131c00e1de4b165dc65af02ea278476187765e1a617b917", - "https://bcr.bazel.build/modules/bazel_skylib/1.7.0/MODULE.bazel": "0db596f4563de7938de764cc8deeabec291f55e8ec15299718b93c4423e9796d", - "https://bcr.bazel.build/modules/bazel_skylib/1.7.1/MODULE.bazel": "3120d80c5861aa616222ec015332e5f8d3171e062e3e804a2a0253e1be26e59b", - "https://bcr.bazel.build/modules/bazel_skylib/1.8.1/MODULE.bazel": "88ade7293becda963e0e3ea33e7d54d3425127e0a326e0d17da085a5f1f03ff6", - "https://bcr.bazel.build/modules/bazel_skylib/1.8.2/MODULE.bazel": "69ad6927098316848b34a9142bcc975e018ba27f08c4ff403f50c1b6e646ca67", - "https://bcr.bazel.build/modules/bazel_skylib/1.8.2/source.json": "34a3c8bcf233b835eb74be9d628899bb32999d3e0eadef1947a0a562a2b16ffb", - "https://bcr.bazel.build/modules/bazel_worker_api/0.0.1/MODULE.bazel": "02a13b77321773b2042e70ee5e4c5e099c8ddee4cf2da9cd420442c36938d4bd", - "https://bcr.bazel.build/modules/bazel_worker_api/0.0.4/MODULE.bazel": "460aa12d01231a80cce03c548287b433b321d205b0028ae596728c35e5ee442e", - "https://bcr.bazel.build/modules/bazel_worker_api/0.0.8/MODULE.bazel": "396c1ef53835aafe3d42ce6619080531ee770648303731f16cfaa33fa056bf0c", - "https://bcr.bazel.build/modules/bazel_worker_api/0.0.8/source.json": "abaf8ac9d2ab2f47bda9af4c0c080ff7907378888e1f4bc62a0539dd13ba61e8", - "https://bcr.bazel.build/modules/bazel_worker_java/0.0.4/MODULE.bazel": "82494a01018bb7ef06d4a17ec4cd7a758721f10eb8b6c820a818e70d669500db", - "https://bcr.bazel.build/modules/bazel_worker_java/0.0.8/MODULE.bazel": "e76479eae70bd4e8f5f4c2dfc5d03ab971cfb18750246c7b3f3454c5c2ee6629", - "https://bcr.bazel.build/modules/bazel_worker_java/0.0.8/source.json": "9395c4679444bc47bf7e51a710366a4480aa371c6f6bed01868e2fabcf11acec", - "https://bcr.bazel.build/modules/buildozer/8.5.1/MODULE.bazel": "a35d9561b3fc5b18797c330793e99e3b834a473d5fbd3d7d7634aafc9bdb6f8f", - "https://bcr.bazel.build/modules/buildozer/8.5.1/source.json": "e3386e6ff4529f2442800dee47ad28d3e6487f36a1f75ae39ae56c70f0cd2fbd", - "https://bcr.bazel.build/modules/contrib_rules_jvm/0.33.0/MODULE.bazel": "1aba514585748372ee392484b2645f0bbcb13ad4271d5b7cace018280f15bae1", - "https://bcr.bazel.build/modules/contrib_rules_jvm/0.33.0/source.json": "e52d62ce2a2b8a513d6afe9178acc06a4349c9b0b4c0934d59085ed9df4b4de0", - "https://bcr.bazel.build/modules/gazelle/0.32.0/MODULE.bazel": "b499f58a5d0d3537f3cf5b76d8ada18242f64ec474d8391247438bf04f58c7b8", - "https://bcr.bazel.build/modules/gazelle/0.33.0/MODULE.bazel": "a13a0f279b462b784fb8dd52a4074526c4a2afe70e114c7d09066097a46b3350", - "https://bcr.bazel.build/modules/gazelle/0.34.0/MODULE.bazel": "abdd8ce4d70978933209db92e436deb3a8b737859e9354fb5fd11fb5c2004c8a", - "https://bcr.bazel.build/modules/gazelle/0.36.0/MODULE.bazel": "e375d5d6e9a6ca59b0cb38b0540bc9a05b6aa926d322f2de268ad267a2ee74c0", - "https://bcr.bazel.build/modules/gazelle/0.40.0/MODULE.bazel": "42ba5378ebe845fca43989a53186ab436d956db498acde790685fe0e8f9c6146", - "https://bcr.bazel.build/modules/gazelle/0.42.0/MODULE.bazel": "fa140a7c019f3a22779ba7c6132ffff9d2d10a51dba2f3304dee61523d11fef4", - "https://bcr.bazel.build/modules/gazelle/0.47.0/MODULE.bazel": "b61bb007c4efad134aa30ee7f4a8e2a39b22aa5685f005edaa022fbd1de43ebc", - "https://bcr.bazel.build/modules/gazelle/0.47.0/source.json": "aeb2e5df14b7fb298625d75d08b9c65bdb0b56014c5eb89da9e5dd0572280ae6", - "https://bcr.bazel.build/modules/google_benchmark/1.8.2/MODULE.bazel": "a70cf1bba851000ba93b58ae2f6d76490a9feb74192e57ab8e8ff13c34ec50cb", - "https://bcr.bazel.build/modules/googletest/1.11.0/MODULE.bazel": "3a83f095183f66345ca86aa13c58b59f9f94a2f81999c093d4eeaa2d262d12f4", - "https://bcr.bazel.build/modules/googletest/1.14.0.bcr.1/MODULE.bazel": "22c31a561553727960057361aa33bf20fb2e98584bc4fec007906e27053f80c6", - "https://bcr.bazel.build/modules/googletest/1.14.0/MODULE.bazel": "cfbcbf3e6eac06ef9d85900f64424708cc08687d1b527f0ef65aa7517af8118f", - "https://bcr.bazel.build/modules/googletest/1.15.2/MODULE.bazel": "6de1edc1d26cafb0ea1a6ab3f4d4192d91a312fd2d360b63adaa213cd00b2108", - "https://bcr.bazel.build/modules/googletest/1.17.0/MODULE.bazel": "dbec758171594a705933a29fcf69293d2468c49ec1f2ebca65c36f504d72df46", - "https://bcr.bazel.build/modules/googletest/1.17.0/source.json": "38e4454b25fc30f15439c0378e57909ab1fd0a443158aa35aec685da727cd713", - "https://bcr.bazel.build/modules/jq.bzl/0.1.0/MODULE.bazel": "2ce69b1af49952cd4121a9c3055faa679e748ce774c7f1fda9657f936cae902f", - "https://bcr.bazel.build/modules/jq.bzl/0.1.0/source.json": "746bf13cac0860f091df5e4911d0c593971cd8796b5ad4e809b2f8e133eee3d5", - "https://bcr.bazel.build/modules/jsoncpp/1.9.5/MODULE.bazel": "31271aedc59e815656f5736f282bb7509a97c7ecb43e927ac1a37966e0578075", - "https://bcr.bazel.build/modules/jsoncpp/1.9.6/MODULE.bazel": "2f8d20d3b7d54143213c4dfc3d98225c42de7d666011528dc8fe91591e2e17b0", - "https://bcr.bazel.build/modules/jsoncpp/1.9.6/source.json": "a04756d367a2126c3541682864ecec52f92cdee80a35735a3cb249ce015ca000", - "https://bcr.bazel.build/modules/libpfm/4.11.0/MODULE.bazel": "45061ff025b301940f1e30d2c16bea596c25b176c8b6b3087e92615adbd52902", - "https://bcr.bazel.build/modules/nlohmann_json/3.6.1/MODULE.bazel": "6f7b417dcc794d9add9e556673ad25cb3ba835224290f4f848f8e2db1e1fca74", - "https://bcr.bazel.build/modules/nlohmann_json/3.6.1/source.json": "f448c6e8963fdfa7eb831457df83ad63d3d6355018f6574fb017e8169deb43a9", - "https://bcr.bazel.build/modules/package_metadata/0.0.2/MODULE.bazel": "fb8d25550742674d63d7b250063d4580ca530499f045d70748b1b142081ebb92", - "https://bcr.bazel.build/modules/package_metadata/0.0.3/MODULE.bazel": "77890552ecea9e284b5424c9de827a58099348763a4359e975c359a83d4faa83", - "https://bcr.bazel.build/modules/package_metadata/0.0.5/MODULE.bazel": "ef4f9439e3270fdd6b9fd4dbc3d2f29d13888e44c529a1b243f7a31dfbc2e8e4", - "https://bcr.bazel.build/modules/package_metadata/0.0.7/MODULE.bazel": "7adb03933fc8401f495800cf4eafcff0edc6da0ff55c7db223ef69d19f689486", - "https://bcr.bazel.build/modules/package_metadata/0.0.7/source.json": "50639625e937b56115012674c797cca7a05a96b4878c87d803c13dc2b31de8a0", - "https://bcr.bazel.build/modules/platforms/0.0.10/MODULE.bazel": "8cb8efaf200bdeb2150d93e162c40f388529a25852b332cec879373771e48ed5", - "https://bcr.bazel.build/modules/platforms/0.0.11/MODULE.bazel": "0daefc49732e227caa8bfa834d65dc52e8cc18a2faf80df25e8caea151a9413f", - "https://bcr.bazel.build/modules/platforms/0.0.4/MODULE.bazel": "9b328e31ee156f53f3c416a64f8491f7eb731742655a47c9eec4703a71644aee", - "https://bcr.bazel.build/modules/platforms/0.0.5/MODULE.bazel": "5733b54ea419d5eaf7997054bb55f6a1d0b5ff8aedf0176fef9eea44f3acda37", - "https://bcr.bazel.build/modules/platforms/0.0.6/MODULE.bazel": "ad6eeef431dc52aefd2d77ed20a4b353f8ebf0f4ecdd26a807d2da5aa8cd0615", - "https://bcr.bazel.build/modules/platforms/0.0.7/MODULE.bazel": "72fd4a0ede9ee5c021f6a8dd92b503e089f46c227ba2813ff183b71616034814", - "https://bcr.bazel.build/modules/platforms/0.0.8/MODULE.bazel": "9f142c03e348f6d263719f5074b21ef3adf0b139ee4c5133e2aa35664da9eb2d", - "https://bcr.bazel.build/modules/platforms/0.0.9/MODULE.bazel": "4a87a60c927b56ddd67db50c89acaa62f4ce2a1d2149ccb63ffd871d5ce29ebc", - "https://bcr.bazel.build/modules/platforms/1.0.0/MODULE.bazel": "f05feb42b48f1b3c225e4ccf351f367be0371411a803198ec34a389fb22aa580", - "https://bcr.bazel.build/modules/platforms/1.0.0/source.json": "f4ff1fd412e0246fd38c82328eb209130ead81d62dcd5a9e40910f867f733d96", - "https://bcr.bazel.build/modules/protobuf/21.7/MODULE.bazel": "a5a29bb89544f9b97edce05642fac225a808b5b7be74038ea3640fae2f8e66a7", - "https://bcr.bazel.build/modules/protobuf/23.1/MODULE.bazel": "88b393b3eb4101d18129e5db51847cd40a5517a53e81216144a8c32dfeeca52a", - "https://bcr.bazel.build/modules/protobuf/24.4/MODULE.bazel": "7bc7ce5f2abf36b3b7b7c8218d3acdebb9426aeb35c2257c96445756f970eb12", - "https://bcr.bazel.build/modules/protobuf/27.0/MODULE.bazel": "7873b60be88844a0a1d8f80b9d5d20cfbd8495a689b8763e76c6372998d3f64c", - "https://bcr.bazel.build/modules/protobuf/27.1/MODULE.bazel": "703a7b614728bb06647f965264967a8ef1c39e09e8f167b3ca0bb1fd80449c0d", - "https://bcr.bazel.build/modules/protobuf/27.2/MODULE.bazel": "32450b50673882e4c8c3d10a83f3bc82161b213ed2f80d17e38bece8f165c295", - "https://bcr.bazel.build/modules/protobuf/29.0-rc2.bcr.1/MODULE.bazel": "52f4126f63a2f0bbf36b99c2a87648f08467a4eaf92ba726bc7d6a500bbf770c", - "https://bcr.bazel.build/modules/protobuf/29.0-rc2/MODULE.bazel": "6241d35983510143049943fc0d57937937122baf1b287862f9dc8590fc4c37df", - "https://bcr.bazel.build/modules/protobuf/29.0-rc3/MODULE.bazel": "33c2dfa286578573afc55a7acaea3cada4122b9631007c594bf0729f41c8de92", - "https://bcr.bazel.build/modules/protobuf/29.0/MODULE.bazel": "319dc8bf4c679ff87e71b1ccfb5a6e90a6dbc4693501d471f48662ac46d04e4e", - "https://bcr.bazel.build/modules/protobuf/29.1/MODULE.bazel": "557c3457560ff49e122ed76c0bc3397a64af9574691cb8201b4e46d4ab2ecb95", - "https://bcr.bazel.build/modules/protobuf/29.3/MODULE.bazel": "77480eea5fb5541903e49683f24dc3e09f4a79e0eea247414887bb9fc0066e94", - "https://bcr.bazel.build/modules/protobuf/3.19.0/MODULE.bazel": "6b5fbb433f760a99a22b18b6850ed5784ef0e9928a72668b66e4d7ccd47db9b0", - "https://bcr.bazel.build/modules/protobuf/3.19.2/MODULE.bazel": "532ffe5f2186b69fdde039efe6df13ba726ff338c6bc82275ad433013fa10573", - "https://bcr.bazel.build/modules/protobuf/3.19.6/MODULE.bazel": "9233edc5e1f2ee276a60de3eaa47ac4132302ef9643238f23128fea53ea12858", - "https://bcr.bazel.build/modules/protobuf/31.1/MODULE.bazel": "379a389bb330b7b8c1cdf331cc90bf3e13de5614799b3b52cdb7c6f389f6b38e", - "https://bcr.bazel.build/modules/protobuf/32.1/MODULE.bazel": "89cd2866a9cb07fee9ff74c41ceace11554f32e0d849de4e23ac55515cfada4d", - "https://bcr.bazel.build/modules/protobuf/33.4/MODULE.bazel": "114775b816b38b6d0ca620450d6b02550c60ceedfdc8d9a229833b34a223dc42", - "https://bcr.bazel.build/modules/protobuf/33.4/source.json": "555f8686b4c7d6b5ba731fbea13bf656b4bfd9a7ff629c1d9d3f6e1d6155de79", - "https://bcr.bazel.build/modules/pybind11_bazel/2.11.1/MODULE.bazel": "88af1c246226d87e65be78ed49ecd1e6f5e98648558c14ce99176da041dc378e", - "https://bcr.bazel.build/modules/pybind11_bazel/2.12.0/MODULE.bazel": "e6f4c20442eaa7c90d7190d8dc539d0ab422f95c65a57cc59562170c58ae3d34", - "https://bcr.bazel.build/modules/pybind11_bazel/2.12.0/source.json": "6900fdc8a9e95866b8c0d4ad4aba4d4236317b5c1cd04c502df3f0d33afed680", - "https://bcr.bazel.build/modules/re2/2023-09-01/MODULE.bazel": "cb3d511531b16cfc78a225a9e2136007a48cf8a677e4264baeab57fe78a80206", - "https://bcr.bazel.build/modules/re2/2024-07-02.bcr.1/MODULE.bazel": "b4963dda9b31080be1905ef085ecd7dd6cd47c05c79b9cdf83ade83ab2ab271a", - "https://bcr.bazel.build/modules/re2/2024-07-02.bcr.1/source.json": "2ff292be6ef3340325ce8a045ecc326e92cbfab47c7cbab4bd85d28971b97ac4", - "https://bcr.bazel.build/modules/re2/2024-07-02/MODULE.bazel": "0eadc4395959969297cbcf31a249ff457f2f1d456228c67719480205aa306daa", - "https://bcr.bazel.build/modules/rules_android/0.1.1/MODULE.bazel": "48809ab0091b07ad0182defb787c4c5328bd3a278938415c00a7b69b50c4d3a8", - "https://bcr.bazel.build/modules/rules_android/0.6.4/MODULE.bazel": "b4cde12d506dd65d82b2be39761f49f5797303343a3d5b4ee191c0cdf9ef387c", - "https://bcr.bazel.build/modules/rules_android/0.6.6/MODULE.bazel": "b0fb569752aab65ab1a9db0a8f6cfaf5aa1754965e17e95dcf0e4d88e192a68d", - "https://bcr.bazel.build/modules/rules_android/0.7.1/MODULE.bazel": "a806fc382a774252f228a40e3b11b9fcc6276f8778c7fb33e9f72937c6258363", - "https://bcr.bazel.build/modules/rules_android/0.7.1/source.json": "151440aed3f0f73a00d4ed5cec5d31f63a6fef9b95d8fab1eb1810150fa525f2", - "https://bcr.bazel.build/modules/rules_apple/3.16.0/MODULE.bazel": "0d1caf0b8375942ce98ea944be754a18874041e4e0459401d925577624d3a54a", - "https://bcr.bazel.build/modules/rules_apple/4.1.0/MODULE.bazel": "76e10fd4a48038d3fc7c5dc6e63b7063bbf5304a2e3bd42edda6ec660eebea68", - "https://bcr.bazel.build/modules/rules_apple/4.1.0/source.json": "8ee81e1708756f81b343a5eb2b2f0b953f1d25c4ab3d4a68dc02754872e80715", - "https://bcr.bazel.build/modules/rules_cc/0.0.1/MODULE.bazel": "cb2aa0747f84c6c3a78dad4e2049c154f08ab9d166b1273835a8174940365647", - "https://bcr.bazel.build/modules/rules_cc/0.0.10/MODULE.bazel": "ec1705118f7eaedd6e118508d3d26deba2a4e76476ada7e0e3965211be012002", - "https://bcr.bazel.build/modules/rules_cc/0.0.13/MODULE.bazel": "0e8529ed7b323dad0775ff924d2ae5af7640b23553dfcd4d34344c7e7a867191", - "https://bcr.bazel.build/modules/rules_cc/0.0.15/MODULE.bazel": "6704c35f7b4a72502ee81f61bf88706b54f06b3cbe5558ac17e2e14666cd5dcc", - "https://bcr.bazel.build/modules/rules_cc/0.0.16/MODULE.bazel": "7661303b8fc1b4d7f532e54e9d6565771fea666fbdf839e0a86affcd02defe87", - "https://bcr.bazel.build/modules/rules_cc/0.0.17/MODULE.bazel": "2ae1d8f4238ec67d7185d8861cb0a2cdf4bc608697c331b95bf990e69b62e64a", - "https://bcr.bazel.build/modules/rules_cc/0.0.2/MODULE.bazel": "6915987c90970493ab97393024c156ea8fb9f3bea953b2f3ec05c34f19b5695c", - "https://bcr.bazel.build/modules/rules_cc/0.0.6/MODULE.bazel": "abf360251023dfe3efcef65ab9d56beefa8394d4176dd29529750e1c57eaa33f", - "https://bcr.bazel.build/modules/rules_cc/0.0.8/MODULE.bazel": "964c85c82cfeb6f3855e6a07054fdb159aced38e99a5eecf7bce9d53990afa3e", - "https://bcr.bazel.build/modules/rules_cc/0.0.9/MODULE.bazel": "836e76439f354b89afe6a911a7adf59a6b2518fafb174483ad78a2a2fde7b1c5", - "https://bcr.bazel.build/modules/rules_cc/0.1.1/MODULE.bazel": "2f0222a6f229f0bf44cd711dc13c858dad98c62d52bd51d8fc3a764a83125513", - "https://bcr.bazel.build/modules/rules_cc/0.1.2/MODULE.bazel": "557ddc3a96858ec0d465a87c0a931054d7dcfd6583af2c7ed3baf494407fd8d0", - "https://bcr.bazel.build/modules/rules_cc/0.1.5/MODULE.bazel": "88dfc9361e8b5ae1008ac38f7cdfd45ad738e4fa676a3ad67d19204f045a1fd8", - "https://bcr.bazel.build/modules/rules_cc/0.2.0/MODULE.bazel": "b5c17f90458caae90d2ccd114c81970062946f49f355610ed89bebf954f5783c", - "https://bcr.bazel.build/modules/rules_cc/0.2.13/MODULE.bazel": "eecdd666eda6be16a8d9dc15e44b5c75133405e820f620a234acc4b1fdc5aa37", - "https://bcr.bazel.build/modules/rules_cc/0.2.14/MODULE.bazel": "353c99ed148887ee89c54a17d4100ae7e7e436593d104b668476019023b58df8", - "https://bcr.bazel.build/modules/rules_cc/0.2.17/MODULE.bazel": "1849602c86cb60da8613d2de887f9566a6d354a6df6d7009f9d04a14402f9a84", - "https://bcr.bazel.build/modules/rules_cc/0.2.17/source.json": "3832f45d145354049137c0090df04629d9c2b5493dc5c2bf46f1834040133a07", - "https://bcr.bazel.build/modules/rules_cc/0.2.8/MODULE.bazel": "f1df20f0bf22c28192a794f29b501ee2018fa37a3862a1a2132ae2940a23a642", - "https://bcr.bazel.build/modules/rules_foreign_cc/0.9.0/MODULE.bazel": "c9e8c682bf75b0e7c704166d79b599f93b72cfca5ad7477df596947891feeef6", - "https://bcr.bazel.build/modules/rules_fuzzing/0.5.2/MODULE.bazel": "40c97d1144356f52905566c55811f13b299453a14ac7769dfba2ac38192337a8", - "https://bcr.bazel.build/modules/rules_go/0.41.0/MODULE.bazel": "55861d8e8bb0e62cbd2896f60ff303f62ffcb0eddb74ecb0e5c0cbe36fc292c8", - "https://bcr.bazel.build/modules/rules_go/0.42.0/MODULE.bazel": "8cfa875b9aa8c6fce2b2e5925e73c1388173ea3c32a0db4d2b4804b453c14270", - "https://bcr.bazel.build/modules/rules_go/0.46.0/MODULE.bazel": "3477df8bdcc49e698b9d25f734c4f3a9f5931ff34ee48a2c662be168f5f2d3fd", - "https://bcr.bazel.build/modules/rules_go/0.50.1/MODULE.bazel": "b91a308dc5782bb0a8021ad4330c81fea5bda77f96b9e4c117b9b9c8f6665ee0", - "https://bcr.bazel.build/modules/rules_go/0.51.0-rc2/MODULE.bazel": "edfc3a9cea7bedb0eaaff37b0d7817c1a4bf72b3c615580b0ffcee6c52690fd4", - "https://bcr.bazel.build/modules/rules_go/0.52.0/MODULE.bazel": "0cf080a2706aa8fc9abf64286cee60fdf0238db37b7f1793b0f7d550d59ea3ae", - "https://bcr.bazel.build/modules/rules_go/0.53.0/MODULE.bazel": "a4ed760d3ac0dbc0d7b967631a9a3fd9100d28f7d9fcf214b4df87d4bfff5f9a", - "https://bcr.bazel.build/modules/rules_go/0.59.0/MODULE.bazel": "b7e43e7414a3139a7547d1b4909b29085fbe5182b6c58cbe1ed4c6272815aeae", - "https://bcr.bazel.build/modules/rules_go/0.59.0/source.json": "1df17bb7865cfc029492c30163cee891d0dd8658ea0d5bfdf252c4b6db5c1ef6", - "https://bcr.bazel.build/modules/rules_java/4.0.0/MODULE.bazel": "5a78a7ae82cd1a33cef56dc578c7d2a46ed0dca12643ee45edbb8417899e6f74", - "https://bcr.bazel.build/modules/rules_java/5.3.5/MODULE.bazel": "a4ec4f2db570171e3e5eb753276ee4b389bae16b96207e9d3230895c99644b86", - "https://bcr.bazel.build/modules/rules_java/6.3.0/MODULE.bazel": "a97c7678c19f236a956ad260d59c86e10a463badb7eb2eda787490f4c969b963", - "https://bcr.bazel.build/modules/rules_java/6.5.2/MODULE.bazel": "1d440d262d0e08453fa0c4d8f699ba81609ed0e9a9a0f02cd10b3e7942e61e31", - "https://bcr.bazel.build/modules/rules_java/7.1.0/MODULE.bazel": "30d9135a2b6561c761bd67bd4990da591e6bdc128790ce3e7afd6a3558b2fb64", - "https://bcr.bazel.build/modules/rules_java/7.10.0/MODULE.bazel": "530c3beb3067e870561739f1144329a21c851ff771cd752a49e06e3dc9c2e71a", - "https://bcr.bazel.build/modules/rules_java/7.12.2/MODULE.bazel": "579c505165ee757a4280ef83cda0150eea193eed3bef50b1004ba88b99da6de6", - "https://bcr.bazel.build/modules/rules_java/7.2.0/MODULE.bazel": "06c0334c9be61e6cef2c8c84a7800cef502063269a5af25ceb100b192453d4ab", - "https://bcr.bazel.build/modules/rules_java/7.4.0/MODULE.bazel": "a592852f8a3dd539e82ee6542013bf2cadfc4c6946be8941e189d224500a8934", - "https://bcr.bazel.build/modules/rules_java/7.6.1/MODULE.bazel": "2f14b7e8a1aa2f67ae92bc69d1ec0fa8d9f827c4e17ff5e5f02e91caa3b2d0fe", - "https://bcr.bazel.build/modules/rules_java/8.13.0/MODULE.bazel": "0444ebf737d144cf2bb2ccb368e7f1cce735264285f2a3711785827c1686625e", - "https://bcr.bazel.build/modules/rules_java/8.15.2/MODULE.bazel": "5cc6698c822b2f9ef90ca5558599851bed8c3b13f1f8eb140d9bfec638d2acb4", - "https://bcr.bazel.build/modules/rules_java/8.3.2/MODULE.bazel": "7336d5511ad5af0b8615fdc7477535a2e4e723a357b6713af439fe8cf0195017", - "https://bcr.bazel.build/modules/rules_java/8.5.1/MODULE.bazel": "d8a9e38cc5228881f7055a6079f6f7821a073df3744d441978e7a43e20226939", - "https://bcr.bazel.build/modules/rules_java/8.6.0/MODULE.bazel": "9c064c434606d75a086f15ade5edb514308cccd1544c2b2a89bbac4310e41c71", - "https://bcr.bazel.build/modules/rules_java/8.6.1/MODULE.bazel": "f4808e2ab5b0197f094cabce9f4b006a27766beb6a9975931da07099560ca9c2", - "https://bcr.bazel.build/modules/rules_java/8.6.3/MODULE.bazel": "e90505b7a931d194245ffcfb6ff4ca8ef9d46b4e830d12e64817752e0198e2ed", - "https://bcr.bazel.build/modules/rules_java/8.9.0/MODULE.bazel": "e17c876cb53dcd817b7b7f0d2985b710610169729e8c371b2221cacdcd3dce4a", - "https://bcr.bazel.build/modules/rules_java/9.1.0/MODULE.bazel": "ee63f27e36a3fada80342869361182f120a9819c74320e8e65b1e04ba0cd7a9d", - "https://bcr.bazel.build/modules/rules_java/9.3.0/MODULE.bazel": "f657c72d65ac449caae9abf2e68e66c0d36f9416848c4c4903d0b3234229e7f2", - "https://bcr.bazel.build/modules/rules_java/9.3.0/source.json": "59ae7e662c3c7042b88bbb42ad12483523e234c65ebe4c51611baa43e85cb248", - "https://bcr.bazel.build/modules/rules_jvm_external/4.4.2/MODULE.bazel": "a56b85e418c83eb1839819f0b515c431010160383306d13ec21959ac412d2fe7", - "https://bcr.bazel.build/modules/rules_jvm_external/5.1/MODULE.bazel": "33f6f999e03183f7d088c9be518a63467dfd0be94a11d0055fe2d210f89aa909", - "https://bcr.bazel.build/modules/rules_jvm_external/5.2/MODULE.bazel": "d9351ba35217ad0de03816ef3ed63f89d411349353077348a45348b096615036", - "https://bcr.bazel.build/modules/rules_jvm_external/6.10/MODULE.bazel": "33e636ca6bc9ee0fa090a38aa33c631ded2d8cf6fead4124181d1b35dc474f7c", - "https://bcr.bazel.build/modules/rules_jvm_external/6.2/MODULE.bazel": "36a6e52487a855f33cb960724eb56547fa87e2c98a0474c3acad94339d7f8e99", - "https://bcr.bazel.build/modules/rules_jvm_external/6.3/MODULE.bazel": "c998e060b85f71e00de5ec552019347c8bca255062c990ac02d051bb80a38df0", - "https://bcr.bazel.build/modules/rules_jvm_external/6.6/MODULE.bazel": "153042249c7060536dc95b6bb9f9bb8063b8a0b0cb7acdb381bddbc2374aed55", - "https://bcr.bazel.build/modules/rules_jvm_external/6.7/MODULE.bazel": "e717beabc4d091ecb2c803c2d341b88590e9116b8bf7947915eeb33aab4f96dd", - "https://bcr.bazel.build/modules/rules_jvm_external/6.9/MODULE.bazel": "07c5db05527db7744a54fcffd653e1550d40e0540207a7f7e6d0a4de5bef8274", - "https://bcr.bazel.build/modules/rules_jvm_external/7.0/MODULE.bazel": "421482bdbcf05709f933c96b867a599deb517f2804ceb3e74511880610cfbf71", - "https://bcr.bazel.build/modules/rules_jvm_external/7.0/source.json": "714cd003eadf5be5c83268311fe8e951db39f802babeaddc536b3560dc8f6faf", - "https://bcr.bazel.build/modules/rules_kotlin/1.9.5/MODULE.bazel": "043a16a572f610558ec2030db3ff0c9938574e7dd9f58bded1bb07c0192ef025", - "https://bcr.bazel.build/modules/rules_kotlin/1.9.6/MODULE.bazel": "d269a01a18ee74d0335450b10f62c9ed81f2321d7958a2934e44272fe82dcef3", - "https://bcr.bazel.build/modules/rules_kotlin/2.1.3/MODULE.bazel": "ce7def6d576aa8d3a9c6d10e13b4d157296229674371f67dbf788dae0afae3d5", - "https://bcr.bazel.build/modules/rules_kotlin/2.2.2/MODULE.bazel": "00d39c5e0fa78cd86193946265bb849e7878c24e44260f9525108428852b315c", - "https://bcr.bazel.build/modules/rules_kotlin/2.2.2/source.json": "7a32c2259c79ae0c9a036121f120de825e3ba5f0f3a209ffbbdccf4dc62489b9", - "https://bcr.bazel.build/modules/rules_license/0.0.3/MODULE.bazel": "627e9ab0247f7d1e05736b59dbb1b6871373de5ad31c3011880b4133cafd4bd0", - "https://bcr.bazel.build/modules/rules_license/0.0.7/MODULE.bazel": "088fbeb0b6a419005b89cf93fe62d9517c0a2b8bb56af3244af65ecfe37e7d5d", - "https://bcr.bazel.build/modules/rules_license/1.0.0/MODULE.bazel": "a7fda60eefdf3d8c827262ba499957e4df06f659330bbe6cdbdb975b768bb65c", - "https://bcr.bazel.build/modules/rules_license/1.0.0/source.json": "a52c89e54cc311196e478f8382df91c15f7a2bfdf4c6cd0e2675cc2ff0b56efb", - "https://bcr.bazel.build/modules/rules_oci/2.2.7/MODULE.bazel": "f6150e4b224d459f7f6523ef65967464ca4efdd266c7fbf2f5a2a51011957e0c", - "https://bcr.bazel.build/modules/rules_oci/2.2.7/source.json": "b099f02af330f47f19dc67fc9300ef6e1937a8c86882690db0e7a2fcea8c7f6b", - "https://bcr.bazel.build/modules/rules_pkg/0.7.0/MODULE.bazel": "df99f03fc7934a4737122518bb87e667e62d780b610910f0447665a7e2be62dc", - "https://bcr.bazel.build/modules/rules_pkg/1.0.1/MODULE.bazel": "5b1df97dbc29623bccdf2b0dcd0f5cb08e2f2c9050aab1092fd39a41e82686ff", - "https://bcr.bazel.build/modules/rules_pkg/1.2.0/MODULE.bazel": "c7db3c2b407e673c7a39e3625dc05dc9f12d6682cbd82a3a5924a13b491eda7e", - "https://bcr.bazel.build/modules/rules_pkg/1.2.0/source.json": "9062e00845bf91a4247465d371baa837adf9b6ff44c542f73ba084f07667e1dc", - "https://bcr.bazel.build/modules/rules_proto/4.0.0/MODULE.bazel": "a7a7b6ce9bee418c1a760b3d84f83a299ad6952f9903c67f19e4edd964894e06", - "https://bcr.bazel.build/modules/rules_proto/5.3.0-21.7/MODULE.bazel": "e8dff86b0971688790ae75528fe1813f71809b5afd57facb44dad9e8eca631b7", - "https://bcr.bazel.build/modules/rules_proto/6.0.0-rc1/MODULE.bazel": "1e5b502e2e1a9e825eef74476a5a1ee524a92297085015a052510b09a1a09483", - "https://bcr.bazel.build/modules/rules_proto/6.0.0/MODULE.bazel": "b531d7f09f58dce456cd61b4579ce8c86b38544da75184eadaf0a7cb7966453f", - "https://bcr.bazel.build/modules/rules_proto/6.0.2/MODULE.bazel": "ce916b775a62b90b61888052a416ccdda405212b6aaeb39522f7dc53431a5e73", - "https://bcr.bazel.build/modules/rules_proto/7.0.2/MODULE.bazel": "bf81793bd6d2ad89a37a40693e56c61b0ee30f7a7fdbaf3eabbf5f39de47dea2", - "https://bcr.bazel.build/modules/rules_proto/7.1.0/MODULE.bazel": "002d62d9108f75bb807cd56245d45648f38275cb3a99dcd45dfb864c5d74cb96", - "https://bcr.bazel.build/modules/rules_proto/7.1.0/source.json": "39f89066c12c24097854e8f57ab8558929f9c8d474d34b2c00ac04630ad8940e", - "https://bcr.bazel.build/modules/rules_python/0.10.2/MODULE.bazel": "cc82bc96f2997baa545ab3ce73f196d040ffb8756fd2d66125a530031cd90e5f", - "https://bcr.bazel.build/modules/rules_python/0.23.1/MODULE.bazel": "49ffccf0511cb8414de28321f5fcf2a31312b47c40cc21577144b7447f2bf300", - "https://bcr.bazel.build/modules/rules_python/0.25.0/MODULE.bazel": "72f1506841c920a1afec76975b35312410eea3aa7b63267436bfb1dd91d2d382", - "https://bcr.bazel.build/modules/rules_python/0.28.0/MODULE.bazel": "cba2573d870babc976664a912539b320cbaa7114cd3e8f053c720171cde331ed", - "https://bcr.bazel.build/modules/rules_python/0.31.0/MODULE.bazel": "93a43dc47ee570e6ec9f5779b2e64c1476a6ce921c48cc9a1678a91dd5f8fd58", - "https://bcr.bazel.build/modules/rules_python/0.33.2/MODULE.bazel": "3e036c4ad8d804a4dad897d333d8dce200d943df4827cb849840055be8d2e937", - "https://bcr.bazel.build/modules/rules_python/0.37.1/MODULE.bazel": "3faeb2d9fa0a81f8980643ee33f212308f4d93eea4b9ce6f36d0b742e71e9500", - "https://bcr.bazel.build/modules/rules_python/0.37.2/MODULE.bazel": "b5ffde91410745750b6c13be1c5dc4555ef5bc50562af4a89fd77807fdde626a", - "https://bcr.bazel.build/modules/rules_python/0.4.0/MODULE.bazel": "9208ee05fd48bf09ac60ed269791cf17fb343db56c8226a720fbb1cdf467166c", - "https://bcr.bazel.build/modules/rules_python/1.0.0/MODULE.bazel": "898a3d999c22caa585eb062b600f88654bf92efb204fa346fb55f6f8edffca43", - "https://bcr.bazel.build/modules/rules_python/1.3.0/MODULE.bazel": "8361d57eafb67c09b75bf4bbe6be360e1b8f4f18118ab48037f2bd50aa2ccb13", - "https://bcr.bazel.build/modules/rules_python/1.4.1/MODULE.bazel": "8991ad45bdc25018301d6b7e1d3626afc3c8af8aaf4bc04f23d0b99c938b73a6", - "https://bcr.bazel.build/modules/rules_python/1.6.0/MODULE.bazel": "7e04ad8f8d5bea40451cf80b1bd8262552aa73f841415d20db96b7241bd027d8", - "https://bcr.bazel.build/modules/rules_python/1.7.0/MODULE.bazel": "d01f995ecd137abf30238ad9ce97f8fc3ac57289c8b24bd0bf53324d937a14f8", - "https://bcr.bazel.build/modules/rules_python/1.7.0/source.json": "028a084b65dcf8f4dc4f82f8778dbe65df133f234b316828a82e060d81bdce32", - "https://bcr.bazel.build/modules/rules_robolectric/4.14.1.2/MODULE.bazel": "d44fec647d0aeb67b9f3b980cf68ba634976f3ae7ccd6c07d790b59b87a4f251", - "https://bcr.bazel.build/modules/rules_robolectric/4.14.1.2/source.json": "37c10335f2361c337c5c1f34ed36d2da70534c23088062b33a8bdaab68aa9dea", - "https://bcr.bazel.build/modules/rules_shell/0.1.2/MODULE.bazel": "66e4ca3ce084b04af0b9ff05ff14cab4e5df7503973818bb91cbc6cda08d32fc", - "https://bcr.bazel.build/modules/rules_shell/0.2.0/MODULE.bazel": "fda8a652ab3c7d8fee214de05e7a9916d8b28082234e8d2c0094505c5268ed3c", - "https://bcr.bazel.build/modules/rules_shell/0.3.0/MODULE.bazel": "de4402cd12f4cc8fda2354fce179fdb068c0b9ca1ec2d2b17b3e21b24c1a937b", - "https://bcr.bazel.build/modules/rules_shell/0.4.1/MODULE.bazel": "00e501db01bbf4e3e1dd1595959092c2fadf2087b2852d3f553b5370f5633592", - "https://bcr.bazel.build/modules/rules_shell/0.6.1/MODULE.bazel": "72e76b0eea4e81611ef5452aa82b3da34caca0c8b7b5c0c9584338aa93bae26b", - "https://bcr.bazel.build/modules/rules_shell/0.8.0/MODULE.bazel": "f6a89f1d6a669a26f28fe814503857055d76306b79cfc11d12399af08d0b80ae", - "https://bcr.bazel.build/modules/rules_shell/0.8.0/source.json": "eb53cc815bc503c6683c5fe12d943f98883f81fc22f51403ec8a95610cba4195", - "https://bcr.bazel.build/modules/rules_swift/1.16.0/MODULE.bazel": "4a09f199545a60d09895e8281362b1ff3bb08bbde69c6fc87aff5b92fcc916ca", - "https://bcr.bazel.build/modules/rules_swift/2.1.1/MODULE.bazel": "494900a80f944fc7aa61500c2073d9729dff0b764f0e89b824eb746959bc1046", - "https://bcr.bazel.build/modules/rules_swift/2.4.0/MODULE.bazel": "1639617eb1ede28d774d967a738b4a68b0accb40650beadb57c21846beab5efd", - "https://bcr.bazel.build/modules/rules_swift/3.1.2/MODULE.bazel": "72c8f5cf9d26427cee6c76c8e3853eb46ce6b0412a081b2b6db6e8ad56267400", - "https://bcr.bazel.build/modules/rules_swift/3.1.2/source.json": "e85761f3098a6faf40b8187695e3de6d97944e98abd0d8ce579cb2daf6319a66", - "https://bcr.bazel.build/modules/stardoc/0.5.1/MODULE.bazel": "1a05d92974d0c122f5ccf09291442580317cdd859f07a8655f1db9a60374f9f8", - "https://bcr.bazel.build/modules/stardoc/0.5.3/MODULE.bazel": "c7f6948dae6999bf0db32c1858ae345f112cacf98f174c7a8bb707e41b974f1c", - "https://bcr.bazel.build/modules/stardoc/0.5.4/MODULE.bazel": "6569966df04610b8520957cb8e97cf2e9faac2c0309657c537ab51c16c18a2a4", - "https://bcr.bazel.build/modules/stardoc/0.6.2/MODULE.bazel": "7060193196395f5dd668eda046ccbeacebfd98efc77fed418dbe2b82ffaa39fd", - "https://bcr.bazel.build/modules/stardoc/0.7.0/MODULE.bazel": "05e3d6d30c099b6770e97da986c53bd31844d7f13d41412480ea265ac9e8079c", - "https://bcr.bazel.build/modules/stardoc/0.7.2/MODULE.bazel": "fc152419aa2ea0f51c29583fab1e8c99ddefd5b3778421845606ee628629e0e5", - "https://bcr.bazel.build/modules/stardoc/0.7.2/source.json": "58b029e5e901d6802967754adf0a9056747e8176f017cfe3607c0851f4d42216", - "https://bcr.bazel.build/modules/swift_argument_parser/1.3.1.1/MODULE.bazel": "5e463fbfba7b1701d957555ed45097d7f984211330106ccd1352c6e0af0dcf91", - "https://bcr.bazel.build/modules/swift_argument_parser/1.3.1.2/MODULE.bazel": "75aab2373a4bbe2a1260b9bf2a1ebbdbf872d3bd36f80bff058dccd82e89422f", - "https://bcr.bazel.build/modules/swift_argument_parser/1.3.1.2/source.json": "5fba48bbe0ba48761f9e9f75f92876cafb5d07c0ce059cc7a8027416de94a05b", - "https://bcr.bazel.build/modules/tar.bzl/0.2.1/MODULE.bazel": "52d1c00a80a8cc67acbd01649e83d8dd6a9dc426a6c0b754a04fe8c219c76468", - "https://bcr.bazel.build/modules/tar.bzl/0.2.1/source.json": "600ac6ff61744667a439e7b814ae59c1f29632c3984fccf8000c64c9db8d7bb6", - "https://bcr.bazel.build/modules/toml.bzl/0.3.0/MODULE.bazel": "5016e5dd1ad2200e119a4b28b2b3935e276c4b480f2fe3e952bea7eeba88f578", - "https://bcr.bazel.build/modules/toml.bzl/0.3.0/source.json": "0cf7c878c419b37ddb55f3dd93dd7c0c409bd7c4efacb3da504e0748780b2fa9", - "https://bcr.bazel.build/modules/upb/0.0.0-20220923-a547704/MODULE.bazel": "7298990c00040a0e2f121f6c32544bab27d4452f80d9ce51349b1a28f3005c43", - "https://bcr.bazel.build/modules/upb/0.0.0-20230516-61a97ef/MODULE.bazel": "c0df5e35ad55e264160417fd0875932ee3c9dda63d9fccace35ac62f45e1b6f9", - "https://bcr.bazel.build/modules/yq.bzl/0.1.1/MODULE.bazel": "9039681f9bcb8958ee2c87ffc74bdafba9f4369096a2b5634b88abc0eaefa072", - "https://bcr.bazel.build/modules/yq.bzl/0.1.1/source.json": "2d2bad780a9f2b9195a4a370314d2c17ae95eaa745cefc2e12fbc49759b15aa3", - "https://bcr.bazel.build/modules/zlib/1.2.11/MODULE.bazel": "07b389abc85fdbca459b69e2ec656ae5622873af3f845e1c9d80fe179f3effa0", - "https://bcr.bazel.build/modules/zlib/1.2.12/MODULE.bazel": "3b1a8834ada2a883674be8cbd36ede1b6ec481477ada359cd2d3ddc562340b27", - "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.5/MODULE.bazel": "eec517b5bbe5492629466e11dae908d043364302283de25581e3eb944326c4ca", - "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.5/source.json": "22bc55c47af97246cfc093d0acf683a7869377de362b5d1c552c2c2e16b7a806", - "https://bcr.bazel.build/modules/zlib/1.3.1/MODULE.bazel": "751c9940dcfe869f5f7274e1295422a34623555916eb98c174c1e945594bf198" - }, - "selectedYankedVersions": {}, - "moduleExtensions": { - "@@apple_rules_lint+//lint:extensions.bzl%linter": { - "general": { - "bzlTransitiveDigest": "g7izj5kLCmsajh8IospHh4ZQ35dyM0FIrA8D4HapAsM=", - "usagesDigest": "4RWlIKR/sSQ9MqPQRCROVLeGPbvTKmkbEpxkI3mbaCI=", - "recordedInputs": [], - "generatedRepoSpecs": { - "apple_linters": { - "repoRuleId": "@@apple_rules_lint+//lint/private:register_linters.bzl%register_linters", - "attributes": { - "linters": {} - } - } - } - } - }, - "@@rules_android+//rules/android_sdk_repository:rule.bzl%android_sdk_repository_extension": { - "general": { - "bzlTransitiveDigest": "+rMrzIrv7sImYmkbXJYv+gFpTJQ79X3MpwwMLI2A+oA=", - "usagesDigest": "iEGI2aNDMkHt9LXCdViLNUUOslpiVj2DrevWWXZEFnU=", - "recordedInputs": [], - "generatedRepoSpecs": { - "androidsdk": { - "repoRuleId": "@@rules_android+//rules/android_sdk_repository:rule.bzl%_android_sdk_repository", - "attributes": {} - } - } - } - }, - "@@rules_oci+//oci:extensions.bzl%oci": { - "general": { - "bzlTransitiveDigest": "pt4oC5w4SZXivjOVNAFM5W2NyEaU5cCGwrSOmM0x9wQ=", - "usagesDigest": "YV/my4HWfeIYZH762GR/gbfyrtmoU6x5X9/fNcX4Ioo=", - "recordedInputs": [ - "REPO_MAPPING:aspect_bazel_lib+,bazel_tools bazel_tools", - "REPO_MAPPING:bazel_features+,bazel_tools bazel_tools", - "REPO_MAPPING:rules_oci+,aspect_bazel_lib aspect_bazel_lib+", - "REPO_MAPPING:rules_oci+,bazel_features bazel_features+", - "REPO_MAPPING:rules_oci+,bazel_skylib bazel_skylib+" - ], - "generatedRepoSpecs": { - "temurin_jre_linux_arm64_v8": { - "repoRuleId": "@@rules_oci+//oci/private:pull.bzl%oci_pull", - "attributes": { - "www_authenticate_challenges": {}, - "scheme": "https", - "registry": "public.ecr.aws", - "repository": "docker/library/eclipse-temurin", - "identifier": "21-jre", - "platform": "linux/arm64/v8", - "target_name": "temurin_jre_linux_arm64_v8", - "bazel_tags": [] - } - }, - "temurin_jre_linux_amd64": { - "repoRuleId": "@@rules_oci+//oci/private:pull.bzl%oci_pull", - "attributes": { - "www_authenticate_challenges": {}, - "scheme": "https", - "registry": "public.ecr.aws", - "repository": "docker/library/eclipse-temurin", - "identifier": "21-jre", - "platform": "linux/amd64", - "target_name": "temurin_jre_linux_amd64", - "bazel_tags": [] - } - }, - "temurin_jre": { - "repoRuleId": "@@rules_oci+//oci/private:pull.bzl%oci_alias", - "attributes": { - "target_name": "temurin_jre", - "www_authenticate_challenges": {}, - "scheme": "https", - "registry": "public.ecr.aws", - "repository": "docker/library/eclipse-temurin", - "identifier": "21-jre", - "platforms": { - "@@platforms//cpu:arm64": "@temurin_jre_linux_arm64_v8", - "@@platforms//cpu:x86_64": "@temurin_jre_linux_amd64" - }, - "bzlmod_repository": "temurin_jre", - "reproducible": true - } - }, - "ubuntu_noble_linux_arm64_v8": { - "repoRuleId": "@@rules_oci+//oci/private:pull.bzl%oci_pull", - "attributes": { - "www_authenticate_challenges": {}, - "scheme": "https", - "registry": "public.ecr.aws", - "repository": "ubuntu/ubuntu", - "identifier": "sha256:ef59d9e82939bbce08973bdffb8761b025f75369fb7d2882cdc4938b5a9e992e", - "platform": "linux/arm64/v8", - "target_name": "ubuntu_noble_linux_arm64_v8", - "bazel_tags": [] - } - }, - "ubuntu_noble_linux_amd64": { - "repoRuleId": "@@rules_oci+//oci/private:pull.bzl%oci_pull", - "attributes": { - "www_authenticate_challenges": {}, - "scheme": "https", - "registry": "public.ecr.aws", - "repository": "ubuntu/ubuntu", - "identifier": "sha256:ef59d9e82939bbce08973bdffb8761b025f75369fb7d2882cdc4938b5a9e992e", - "platform": "linux/amd64", - "target_name": "ubuntu_noble_linux_amd64", - "bazel_tags": [] - } - }, - "ubuntu_noble": { - "repoRuleId": "@@rules_oci+//oci/private:pull.bzl%oci_alias", - "attributes": { - "target_name": "ubuntu_noble", - "www_authenticate_challenges": {}, - "scheme": "https", - "registry": "public.ecr.aws", - "repository": "ubuntu/ubuntu", - "identifier": "sha256:ef59d9e82939bbce08973bdffb8761b025f75369fb7d2882cdc4938b5a9e992e", - "platforms": { - "@@platforms//cpu:arm64": "@ubuntu_noble_linux_arm64_v8", - "@@platforms//cpu:x86_64": "@ubuntu_noble_linux_amd64" - }, - "bzlmod_repository": "ubuntu_noble", - "reproducible": true - } - }, - "oci_crane_darwin_amd64": { - "repoRuleId": "@@rules_oci+//oci:repositories.bzl%crane_repositories", - "attributes": { - "platform": "darwin_amd64", - "crane_version": "v0.18.0" - } - }, - "oci_crane_darwin_arm64": { - "repoRuleId": "@@rules_oci+//oci:repositories.bzl%crane_repositories", - "attributes": { - "platform": "darwin_arm64", - "crane_version": "v0.18.0" - } - }, - "oci_crane_linux_arm64": { - "repoRuleId": "@@rules_oci+//oci:repositories.bzl%crane_repositories", - "attributes": { - "platform": "linux_arm64", - "crane_version": "v0.18.0" - } - }, - "oci_crane_linux_armv6": { - "repoRuleId": "@@rules_oci+//oci:repositories.bzl%crane_repositories", - "attributes": { - "platform": "linux_armv6", - "crane_version": "v0.18.0" - } - }, - "oci_crane_linux_i386": { - "repoRuleId": "@@rules_oci+//oci:repositories.bzl%crane_repositories", - "attributes": { - "platform": "linux_i386", - "crane_version": "v0.18.0" - } - }, - "oci_crane_linux_s390x": { - "repoRuleId": "@@rules_oci+//oci:repositories.bzl%crane_repositories", - "attributes": { - "platform": "linux_s390x", - "crane_version": "v0.18.0" - } - }, - "oci_crane_linux_amd64": { - "repoRuleId": "@@rules_oci+//oci:repositories.bzl%crane_repositories", - "attributes": { - "platform": "linux_amd64", - "crane_version": "v0.18.0" - } - }, - "oci_crane_windows_armv6": { - "repoRuleId": "@@rules_oci+//oci:repositories.bzl%crane_repositories", - "attributes": { - "platform": "windows_armv6", - "crane_version": "v0.18.0" - } - }, - "oci_crane_windows_amd64": { - "repoRuleId": "@@rules_oci+//oci:repositories.bzl%crane_repositories", - "attributes": { - "platform": "windows_amd64", - "crane_version": "v0.18.0" - } - }, - "oci_crane_toolchains": { - "repoRuleId": "@@rules_oci+//oci/private:toolchains_repo.bzl%toolchains_repo", - "attributes": { - "toolchain_type": "@rules_oci//oci:crane_toolchain_type", - "toolchain": "@oci_crane_{platform}//:crane_toolchain" - } - }, - "oci_regctl_darwin_amd64": { - "repoRuleId": "@@rules_oci+//oci:repositories.bzl%regctl_repositories", - "attributes": { - "platform": "darwin_amd64" - } - }, - "oci_regctl_darwin_arm64": { - "repoRuleId": "@@rules_oci+//oci:repositories.bzl%regctl_repositories", - "attributes": { - "platform": "darwin_arm64" - } - }, - "oci_regctl_linux_arm64": { - "repoRuleId": "@@rules_oci+//oci:repositories.bzl%regctl_repositories", - "attributes": { - "platform": "linux_arm64" - } - }, - "oci_regctl_linux_s390x": { - "repoRuleId": "@@rules_oci+//oci:repositories.bzl%regctl_repositories", - "attributes": { - "platform": "linux_s390x" - } - }, - "oci_regctl_linux_amd64": { - "repoRuleId": "@@rules_oci+//oci:repositories.bzl%regctl_repositories", - "attributes": { - "platform": "linux_amd64" - } - }, - "oci_regctl_windows_amd64": { - "repoRuleId": "@@rules_oci+//oci:repositories.bzl%regctl_repositories", - "attributes": { - "platform": "windows_amd64" - } - }, - "oci_regctl_toolchains": { - "repoRuleId": "@@rules_oci+//oci/private:toolchains_repo.bzl%toolchains_repo", - "attributes": { - "toolchain_type": "@rules_oci//oci:regctl_toolchain_type", - "toolchain": "@oci_regctl_{platform}//:regctl_toolchain" - } - } - }, - "moduleExtensionMetadata": { - "explicitRootModuleDirectDeps": [], - "explicitRootModuleDirectDevDeps": [], - "useAllRepos": "NO", - "reproducible": false - } - } - }, - "@@rules_python+//python/extensions:config.bzl%config": { - "general": { - "bzlTransitiveDigest": "dzD8Q2YmrP3fz8saWLHPmlwPLO91ImtTmP/c9JKTStM=", - "usagesDigest": "ZVSXMAGpD+xzVNPuvF1IoLBkty7TROO0+akMapt1pAg=", - "recordedInputs": [ - "REPO_MAPPING:rules_python+,bazel_tools bazel_tools", - "REPO_MAPPING:rules_python+,pypi__build rules_python++config+pypi__build", - "REPO_MAPPING:rules_python+,pypi__click rules_python++config+pypi__click", - "REPO_MAPPING:rules_python+,pypi__colorama rules_python++config+pypi__colorama", - "REPO_MAPPING:rules_python+,pypi__importlib_metadata rules_python++config+pypi__importlib_metadata", - "REPO_MAPPING:rules_python+,pypi__installer rules_python++config+pypi__installer", - "REPO_MAPPING:rules_python+,pypi__more_itertools rules_python++config+pypi__more_itertools", - "REPO_MAPPING:rules_python+,pypi__packaging rules_python++config+pypi__packaging", - "REPO_MAPPING:rules_python+,pypi__pep517 rules_python++config+pypi__pep517", - "REPO_MAPPING:rules_python+,pypi__pip rules_python++config+pypi__pip", - "REPO_MAPPING:rules_python+,pypi__pip_tools rules_python++config+pypi__pip_tools", - "REPO_MAPPING:rules_python+,pypi__pyproject_hooks rules_python++config+pypi__pyproject_hooks", - "REPO_MAPPING:rules_python+,pypi__setuptools rules_python++config+pypi__setuptools", - "REPO_MAPPING:rules_python+,pypi__tomli rules_python++config+pypi__tomli", - "REPO_MAPPING:rules_python+,pypi__wheel rules_python++config+pypi__wheel", - "REPO_MAPPING:rules_python+,pypi__zipp rules_python++config+pypi__zipp" - ], - "generatedRepoSpecs": { - "rules_python_internal": { - "repoRuleId": "@@rules_python+//python/private:internal_config_repo.bzl%internal_config_repo", - "attributes": { - "transition_setting_generators": {}, - "transition_settings": [] - } - }, - "pypi__build": { - "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", - "attributes": { - "url": "https://files.pythonhosted.org/packages/e2/03/f3c8ba0a6b6e30d7d18c40faab90807c9bb5e9a1e3b2fe2008af624a9c97/build-1.2.1-py3-none-any.whl", - "sha256": "75e10f767a433d9a86e50d83f418e83efc18ede923ee5ff7df93b6cb0306c5d4", - "type": "zip", - "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" - } - }, - "pypi__click": { - "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", - "attributes": { - "url": "https://files.pythonhosted.org/packages/00/2e/d53fa4befbf2cfa713304affc7ca780ce4fc1fd8710527771b58311a3229/click-8.1.7-py3-none-any.whl", - "sha256": "ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", - "type": "zip", - "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" - } - }, - "pypi__colorama": { - "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", - "attributes": { - "url": "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", - "sha256": "4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", - "type": "zip", - "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" - } - }, - "pypi__importlib_metadata": { - "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", - "attributes": { - "url": "https://files.pythonhosted.org/packages/2d/0a/679461c511447ffaf176567d5c496d1de27cbe34a87df6677d7171b2fbd4/importlib_metadata-7.1.0-py3-none-any.whl", - "sha256": "30962b96c0c223483ed6cc7280e7f0199feb01a0e40cfae4d4450fc6fab1f570", - "type": "zip", - "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" - } - }, - "pypi__installer": { - "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", - "attributes": { - "url": "https://files.pythonhosted.org/packages/e5/ca/1172b6638d52f2d6caa2dd262ec4c811ba59eee96d54a7701930726bce18/installer-0.7.0-py3-none-any.whl", - "sha256": "05d1933f0a5ba7d8d6296bb6d5018e7c94fa473ceb10cf198a92ccea19c27b53", - "type": "zip", - "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" - } - }, - "pypi__more_itertools": { - "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", - "attributes": { - "url": "https://files.pythonhosted.org/packages/50/e2/8e10e465ee3987bb7c9ab69efb91d867d93959095f4807db102d07995d94/more_itertools-10.2.0-py3-none-any.whl", - "sha256": "686b06abe565edfab151cb8fd385a05651e1fdf8f0a14191e4439283421f8684", - "type": "zip", - "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" - } - }, - "pypi__packaging": { - "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", - "attributes": { - "url": "https://files.pythonhosted.org/packages/49/df/1fceb2f8900f8639e278b056416d49134fb8d84c5942ffaa01ad34782422/packaging-24.0-py3-none-any.whl", - "sha256": "2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5", - "type": "zip", - "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" - } - }, - "pypi__pep517": { - "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", - "attributes": { - "url": "https://files.pythonhosted.org/packages/25/6e/ca4a5434eb0e502210f591b97537d322546e4833dcb4d470a48c375c5540/pep517-0.13.1-py3-none-any.whl", - "sha256": "31b206f67165b3536dd577c5c3f1518e8fbaf38cbc57efff8369a392feff1721", - "type": "zip", - "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" - } - }, - "pypi__pip": { - "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", - "attributes": { - "url": "https://files.pythonhosted.org/packages/8a/6a/19e9fe04fca059ccf770861c7d5721ab4c2aebc539889e97c7977528a53b/pip-24.0-py3-none-any.whl", - "sha256": "ba0d021a166865d2265246961bec0152ff124de910c5cc39f1156ce3fa7c69dc", - "type": "zip", - "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" - } - }, - "pypi__pip_tools": { - "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", - "attributes": { - "url": "https://files.pythonhosted.org/packages/0d/dc/38f4ce065e92c66f058ea7a368a9c5de4e702272b479c0992059f7693941/pip_tools-7.4.1-py3-none-any.whl", - "sha256": "4c690e5fbae2f21e87843e89c26191f0d9454f362d8acdbd695716493ec8b3a9", - "type": "zip", - "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" - } - }, - "pypi__pyproject_hooks": { - "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", - "attributes": { - "url": "https://files.pythonhosted.org/packages/ae/f3/431b9d5fe7d14af7a32340792ef43b8a714e7726f1d7b69cc4e8e7a3f1d7/pyproject_hooks-1.1.0-py3-none-any.whl", - "sha256": "7ceeefe9aec63a1064c18d939bdc3adf2d8aa1988a510afec15151578b232aa2", - "type": "zip", - "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" - } - }, - "pypi__setuptools": { - "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", - "attributes": { - "url": "https://files.pythonhosted.org/packages/90/99/158ad0609729111163fc1f674a5a42f2605371a4cf036d0441070e2f7455/setuptools-78.1.1-py3-none-any.whl", - "sha256": "c3a9c4211ff4c309edb8b8c4f1cbfa7ae324c4ba9f91ff254e3d305b9fd54561", - "type": "zip", - "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" - } - }, - "pypi__tomli": { - "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", - "attributes": { - "url": "https://files.pythonhosted.org/packages/97/75/10a9ebee3fd790d20926a90a2547f0bf78f371b2f13aa822c759680ca7b9/tomli-2.0.1-py3-none-any.whl", - "sha256": "939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc", - "type": "zip", - "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" - } - }, - "pypi__wheel": { - "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", - "attributes": { - "url": "https://files.pythonhosted.org/packages/7d/cd/d7460c9a869b16c3dd4e1e403cce337df165368c71d6af229a74699622ce/wheel-0.43.0-py3-none-any.whl", - "sha256": "55c570405f142630c6b9f72fe09d9b67cf1477fcf543ae5b8dcb1f5b7377da81", - "type": "zip", - "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" - } - }, - "pypi__zipp": { - "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", - "attributes": { - "url": "https://files.pythonhosted.org/packages/da/55/a03fd7240714916507e1fcf7ae355bd9d9ed2e6db492595f1a67f61681be/zipp-3.18.2-py3-none-any.whl", - "sha256": "dce197b859eb796242b0622af1b8beb0a722d52aa2f57133ead08edd5bf5374e", - "type": "zip", - "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" - } - } - } - } - }, - "@@rules_python+//python/uv:uv.bzl%uv": { - "general": { - "bzlTransitiveDigest": "ijW9KS7qsIY+yBVvJ+Nr1mzwQox09j13DnE3iIwaeTM=", - "usagesDigest": "H8dQoNZcoqP+Mu0tHZTi4KHATzvNkM5ePuEqoQdklIU=", - "recordedInputs": [ - "REPO_MAPPING:rules_python+,bazel_tools bazel_tools", - "REPO_MAPPING:rules_python+,platforms platforms" - ], - "generatedRepoSpecs": { - "uv": { - "repoRuleId": "@@rules_python+//python/uv/private:uv_toolchains_repo.bzl%uv_toolchains_repo", - "attributes": { - "toolchain_type": "'@@rules_python+//python/uv:uv_toolchain_type'", - "toolchain_names": [ - "none" - ], - "toolchain_implementations": { - "none": "'@@rules_python+//python:none'" - }, - "toolchain_compatible_with": { - "none": [ - "@platforms//:incompatible" - ] - }, - "toolchain_target_settings": {} - } - } - } - } - } - }, - "facts": { - "@@rules_go+//go:extensions.bzl%go_sdk": { - "1.22.4": { - "aix_ppc64": [ - "go1.22.4.aix-ppc64.tar.gz", - "b9647fa9fc83a0cc5d4f092a19eaeaecf45f063a5aa7d4962fde65aeb7ae6ce1" - ], - "darwin_amd64": [ - "go1.22.4.darwin-amd64.tar.gz", - "c95967f50aa4ace34af0c236cbdb49a9a3e80ee2ad09d85775cb4462a5c19ed3" - ], - "darwin_arm64": [ - "go1.22.4.darwin-arm64.tar.gz", - "242b78dc4c8f3d5435d28a0d2cec9b4c1aa999b601fb8aa59fb4e5a1364bf827" - ], - "dragonfly_amd64": [ - "go1.22.4.dragonfly-amd64.tar.gz", - "f2fbb51af4719d3616efb482d6ed2b96579b474156f85a7ddc6f126764feec4b" - ], - "freebsd_386": [ - "go1.22.4.freebsd-386.tar.gz", - "7c54884bb9f274884651d41e61d1bc12738863ad1497e97ea19ad0e9aa6bf7b5" - ], - "freebsd_amd64": [ - "go1.22.4.freebsd-amd64.tar.gz", - "88d44500e1701dd35797619774d6dd51bf60f45a8338b0a82ddc018e4e63fb78" - ], - "freebsd_arm64": [ - "go1.22.4.freebsd-arm64.tar.gz", - "726dc093cf020277be45debf03c3b02b43c2efb3e2a5d4fba8f52579d65327dc" - ], - "freebsd_armv6l": [ - "go1.22.4.freebsd-arm.tar.gz", - "3d9efe47db142a22679aba46b1772e3900b0d87ae13bd2b3bc80dbf2ac0b2cd6" - ], - "freebsd_riscv64": [ - "go1.22.4.freebsd-riscv64.tar.gz", - "5f6b67e5e32f1d6ccb2d4dcb44934a5e2e870a877ba7443d86ec43cfc28afa71" - ], - "illumos_amd64": [ - "go1.22.4.illumos-amd64.tar.gz", - "d56ecc2f85b6418a21ef83879594d0c42ab4f65391a676bb12254870e6690d63" - ], - "linux_386": [ - "go1.22.4.linux-386.tar.gz", - "47a2a8d249a91eb8605c33bceec63aedda0441a43eac47b4721e3975ff916cec" - ], - "linux_amd64": [ - "go1.22.4.linux-amd64.tar.gz", - "ba79d4526102575196273416239cca418a651e049c2b099f3159db85e7bade7d" - ], - "linux_arm64": [ - "go1.22.4.linux-arm64.tar.gz", - "a8e177c354d2e4a1b61020aca3562e27ea3e8f8247eca3170e3fa1e0c2f9e771" - ], - "linux_armv6l": [ - "go1.22.4.linux-armv6l.tar.gz", - "e2b143fbacbc9cbd448e9ef41ac3981f0488ce849af1cf37e2341d09670661de" - ], - "linux_loong64": [ - "go1.22.4.linux-loong64.tar.gz", - "e2ff9436e4b34bf6926b06d97916e26d67a909a2effec17967245900f0816f1d" - ], - "linux_mips": [ - "go1.22.4.linux-mips.tar.gz", - "73f0dcc60458c4770593b05a7bc01cc0d31fc98f948c0c2334812c7a1f2fc3f1" - ], - "linux_mips64": [ - "go1.22.4.linux-mips64.tar.gz", - "417af97fc2630a647052375768be4c38adcc5af946352ea5b28613ea81ca5d45" - ], - "linux_mips64le": [ - "go1.22.4.linux-mips64le.tar.gz", - "7486e2d7dd8c98eb44df815ace35a7fe7f30b7c02326e3741bd934077508139b" - ], - "linux_mipsle": [ - "go1.22.4.linux-mipsle.tar.gz", - "69479c8aad301e459a8365b40cad1074a0dbba5defb9291669f94809c4c4be6e" - ], - "linux_ppc64": [ - "go1.22.4.linux-ppc64.tar.gz", - "dd238847e65bc3e2745caca475a5db6522a2fcf85cf6c38fc36a06642b19efd7" - ], - "linux_ppc64le": [ - "go1.22.4.linux-ppc64le.tar.gz", - "a3e5834657ef92523f570f798fed42f1f87bc18222a16815ec76b84169649ec4" - ], - "linux_riscv64": [ - "go1.22.4.linux-riscv64.tar.gz", - "56a827ff7dc6245bcd7a1e9288dffaa1d8b0fd7468562264c1523daf3b4f1b4a" - ], - "linux_s390x": [ - "go1.22.4.linux-s390x.tar.gz", - "7590c3e278e2dc6040aae0a39da3ca1eb2e3921673a7304cc34d588c45889eec" - ], - "netbsd_386": [ - "go1.22.4.netbsd-386.tar.gz", - "ddd2eebe34471a2502de6c5dad04ab27c9fc80cbde7a9ad5b3c66ecec4504e1d" - ], - "netbsd_amd64": [ - "go1.22.4.netbsd-amd64.tar.gz", - "33af79f6f935f6fbacc5d23876450b3567b79348fc065beef8e64081127dd234" - ], - "netbsd_arm64": [ - "go1.22.4.netbsd-arm64.tar.gz", - "c9a2971dec9f6d320c6f2b049b2353c6d0a2d35e87b8a4b2d78a2f0d62545f8e" - ], - "netbsd_armv6l": [ - "go1.22.4.netbsd-arm.tar.gz", - "fa3550ebd5375a70b3bcd342b5a71f4bd271dcbbfaf4eabefa2144ab5d8924b6" - ], - "openbsd_386": [ - "go1.22.4.openbsd-386.tar.gz", - "d21af022331bfdc2b5b161d616c3a1a4573d33cf7a30416ee509a8f3641deb47" - ], - "openbsd_amd64": [ - "go1.22.4.openbsd-amd64.tar.gz", - "72c0094c43f7e5722ec49c2a3e9dfa7a1123ac43a5f3a63eecf3e3795d3ff0ae" - ], - "openbsd_arm64": [ - "go1.22.4.openbsd-arm64.tar.gz", - "a7ab8d4e0b02bf06ed144ba42c61c0e93ee00f2b433415dfd4ad4b6e79f31650" - ], - "openbsd_armv6l": [ - "go1.22.4.openbsd-arm.tar.gz", - "1096831ea3c5ea3ca57d14251d9eda3786889531eb40d7d6775dcaa324d4b065" - ], - "openbsd_ppc64": [ - "go1.22.4.openbsd-ppc64.tar.gz", - "9716327c8a628358798898dc5148c49dbbeb5196bf2cbf088e550721a6e4f60b" - ], - "plan9_386": [ - "go1.22.4.plan9-386.tar.gz", - "a8dd4503c95c32a502a616ab78870a19889c9325fe9bd31eb16dd69346e4bfa8" - ], - "plan9_amd64": [ - "go1.22.4.plan9-amd64.tar.gz", - "5423a25808d76fe5aca8607a2e5ac5673abf45446b168cb5e9d8519ee9fe39a1" - ], - "plan9_armv6l": [ - "go1.22.4.plan9-arm.tar.gz", - "6af939ad583f5c85c09c53728ab7d38c3cc2b39167562d6c18a07c5c6608b370" - ], - "solaris_amd64": [ - "go1.22.4.solaris-amd64.tar.gz", - "e8cabe69c03085725afdb32a6f9998191a3e55a747b270d835fd05000d56abba" - ], - "windows_386": [ - "go1.22.4.windows-386.zip", - "aca4e2c37278a10f1c70dd0df142f7d66b50334fcee48978d409202d308d6d25" - ], - "windows_amd64": [ - "go1.22.4.windows-amd64.zip", - "26321c4d945a0035d8a5bc4a1965b0df401ff8ceac66ce2daadabf9030419a98" - ], - "windows_arm64": [ - "go1.22.4.windows-arm64.zip", - "8a2daa9ea28cbdafddc6171aefed384f4e5b6e714fb52116fe9ed25a132f37ed" - ], - "windows_armv6l": [ - "go1.22.4.windows-arm.zip", - "5fcd0671a49cecf39b41021621ee1b6e7aa1370f37122b72e80d4fd4185833b6" - ] - }, - "1.23.6": { - "aix_ppc64": [ - "go1.23.6.aix-ppc64.tar.gz", - "adec10f4ba56591f523aa04851f7f6900b1c61508dfa6b80e62717a8e6684a5c" - ], - "darwin_amd64": [ - "go1.23.6.darwin-amd64.tar.gz", - "782da50ce8ec5e98fac2cd3cdc6a1d7130d093294fc310038f651444232a3fb0" - ], - "darwin_arm64": [ - "go1.23.6.darwin-arm64.tar.gz", - "5cae2450a1708aeb0333237a155640d5562abaf195defebc4306054565536221" - ], - "dragonfly_amd64": [ - "go1.23.6.dragonfly-amd64.tar.gz", - "d52efb3020d9332477ade98163c03d2f2fe3e051b0e7e01f0e167412c66de0cb" - ], - "freebsd_386": [ - "go1.23.6.freebsd-386.tar.gz", - "d3287706b5823712ac6cf7dff684a556cff98163ef60e7b275abe3388c17aac7" - ], - "freebsd_amd64": [ - "go1.23.6.freebsd-amd64.tar.gz", - "ebb4c6a9b0673dbdabc439877779ed6add16575e21bd0a7955c33f692789aef6" - ], - "freebsd_arm": [ - "go1.23.6.freebsd-arm.tar.gz", - "b7241584afb0b161c09148f8fde16171bb743e47b99d451fbc5f5217ec7a88b6" - ], - "freebsd_arm64": [ - "go1.23.6.freebsd-arm64.tar.gz", - "004718b53cedd7955d1b1dc4053539fcd1053c031f5f3374334a22befd1f8310" - ], - "freebsd_riscv64": [ - "go1.23.6.freebsd-riscv64.tar.gz", - "ca026ec8a30dd0c18164f40e1ce21bd725e2445f11699177d05815189a38de7a" - ], - "illumos_amd64": [ - "go1.23.6.illumos-amd64.tar.gz", - "7db973efa3fb2e48e45059b855721550fce8e90803e7373d3efd37b88dd821e8" - ], - "linux_386": [ - "go1.23.6.linux-386.tar.gz", - "e61f87693169c0bbcc43363128f1e929b9dff0b7f448573f1bdd4e4a0b9687ba" - ], - "linux_amd64": [ - "go1.23.6.linux-amd64.tar.gz", - "9379441ea310de000f33a4dc767bd966e72ab2826270e038e78b2c53c2e7802d" - ], - "linux_arm64": [ - "go1.23.6.linux-arm64.tar.gz", - "561c780e8f4a8955d32bf72e46af0b5ee5e0debe1e4633df9a03781878219202" - ], - "linux_armv6l": [ - "go1.23.6.linux-armv6l.tar.gz", - "27a4611010c16b8c4f37ade3aada55bd5781998f02f348b164302fd5eea4eb74" - ], - "linux_loong64": [ - "go1.23.6.linux-loong64.tar.gz", - "c459226424372abc2b35957cc8955dad348330714f7605093325dbb73e33c750" - ], - "linux_mips": [ - "go1.23.6.linux-mips.tar.gz", - "e2a0aff70b958a3463a7d47132a2d0238369f64578d4f7f95e679e3a5af05622" - ], - "linux_mips64": [ - "go1.23.6.linux-mips64.tar.gz", - "7d30ec7db056311d420bf930c16abcae13c0f41c26a202868f279721ec3c2f2f" - ], - "linux_mips64le": [ - "go1.23.6.linux-mips64le.tar.gz", - "74ca7bc475bcc084c6718b74df024d7de9612932cea8a6dc75e29d3a5315a23a" - ], - "linux_mipsle": [ - "go1.23.6.linux-mipsle.tar.gz", - "09bf935a14e9f59a20499989438b1655453480016bdbcb10406acf4df2678ccb" - ], - "linux_ppc64": [ - "go1.23.6.linux-ppc64.tar.gz", - "5cb2f6a5090276c72c5eda8a55896f5a3d6ea0f28d10fa1a50e8318640f02d6c" - ], - "linux_ppc64le": [ - "go1.23.6.linux-ppc64le.tar.gz", - "0f817201e83d78ddbfa27f5f78d9b72450b92cc21d5e045145efacd0d3244a99" - ], - "linux_riscv64": [ - "go1.23.6.linux-riscv64.tar.gz", - "f95f7f817ab22ecab4503d0704d6449ea1aa26a595f57bf9b9f94ddf2aa7c1f3" - ], - "linux_s390x": [ - "go1.23.6.linux-s390x.tar.gz", - "321e7ed0d5416f731479c52fa7610b52b8079a8061967bd48cec6d66f671a60e" - ], - "netbsd_386": [ - "go1.23.6.netbsd-386.tar.gz", - "92d678fb8e1eeeb8c6af6f22e4e5494652dcbb4a320113fc08325cb9956a2d4c" - ], - "netbsd_amd64": [ - "go1.23.6.netbsd-amd64.tar.gz", - "86ba51e7bb26b30ea6a8d88ddb79d8e8c83b4116200040ecb7a5a44cf90a8c5c" - ], - "netbsd_arm": [ - "go1.23.6.netbsd-arm.tar.gz", - "4b974c35345100f0be6ea66afab2781de91ee9882117314126eaf0ae90fd3816" - ], - "netbsd_arm64": [ - "go1.23.6.netbsd-arm64.tar.gz", - "53e3589fc38e787a493ea038961f8e40803714dbb42754c1713b00099c12e9b9" - ], - "openbsd_386": [ - "go1.23.6.openbsd-386.tar.gz", - "6d2317b3a8505ccebff8f72d943f2ac9b82c115632e54a53a786eff24ced56d9" - ], - "openbsd_amd64": [ - "go1.23.6.openbsd-amd64.tar.gz", - "f699e707d95a984fcc00361d91aecdb413d3c75e18235156ffba7a89edf68aae" - ], - "openbsd_arm": [ - "go1.23.6.openbsd-arm.tar.gz", - "3c1cf6ab893657d0bf1942e40ce115acfd27cbce1ccb9bc88fd9cd21ca3d489f" - ], - "openbsd_arm64": [ - "go1.23.6.openbsd-arm64.tar.gz", - "cc0875535d14001f2da23ae9af89025b28c466e8f4f4c63f991ebb6f4b02f66c" - ], - "openbsd_ppc64": [ - "go1.23.6.openbsd-ppc64.tar.gz", - "64de80e29ca66cb566cbf8be030bf8599953af4e48402eab724cbe0a08b40602" - ], - "openbsd_riscv64": [ - "go1.23.6.openbsd-riscv64.tar.gz", - "c398a6b43c569f34bb4a2d16b52f8010eaac9a2a82ecac0602b4338e35cef377" - ], - "plan9_386": [ - "go1.23.6.plan9-386.tar.gz", - "10998b6b130bb7b542b407f0db42b86a913b111f8fa86d44394beaace4d45f01" - ], - "plan9_amd64": [ - "go1.23.6.plan9-amd64.tar.gz", - "9fbe8065436d8d12c02f19f64f51c9107da3a7a4ac46ab5777e182e9fe88c32f" - ], - "plan9_arm": [ - "go1.23.6.plan9-arm.tar.gz", - "8e3c826b884daee2de37e3b070d7eac4cea5d68edab8db09910e22201c75db83" - ], - "solaris_amd64": [ - "go1.23.6.solaris-amd64.tar.gz", - "b619eff63fec86daaea92ca170559e448a58b8ba0b92eef1971bc14e92ea86a7" - ], - "windows_386": [ - "go1.23.6.windows-386.zip", - "96820c0f5d464dd694543329e9b4d413b17c821c03a055717a29e6735b44c2d8" - ], - "windows_amd64": [ - "go1.23.6.windows-amd64.zip", - "53fec1586850b2cf5ad6438341ff7adc5f6700dd3ec1cfa3f5e8b141df190243" - ], - "windows_arm": [ - "go1.23.6.windows-arm.zip", - "22c2518c45c20018afa20d5376dc9fd7a7e74367240ed7b5209e79a30b5c4218" - ], - "windows_arm64": [ - "go1.23.6.windows-arm64.zip", - "a2d2ec1b3759552bdd9cdf58858f91dfbfd6ab3a472f00b5255acbed30b1aa41" - ] - }, - "1.25.0": { - "aix_ppc64": [ - "go1.25.0.aix-ppc64.tar.gz", - "e5234a7dac67bc86c528fe9752fc9d63557918627707a733ab4cac1a6faed2d4" - ], - "darwin_amd64": [ - "go1.25.0.darwin-amd64.tar.gz", - "5bd60e823037062c2307c71e8111809865116714d6f6b410597cf5075dfd80ef" - ], - "darwin_arm64": [ - "go1.25.0.darwin-arm64.tar.gz", - "544932844156d8172f7a28f77f2ac9c15a23046698b6243f633b0a0b00c0749c" - ], - "dragonfly_amd64": [ - "go1.25.0.dragonfly-amd64.tar.gz", - "5ed3cf9a810a1483822538674f1336c06b51aa1b94d6d545a1a0319a48177120" - ], - "freebsd_386": [ - "go1.25.0.freebsd-386.tar.gz", - "abea5d5c6697e6b5c224731f2158fe87c602996a2a233ac0c4730cd57bf8374e" - ], - "freebsd_amd64": [ - "go1.25.0.freebsd-amd64.tar.gz", - "86e6fe0a29698d7601c4442052dac48bd58d532c51cccb8f1917df648138730b" - ], - "freebsd_arm": [ - "go1.25.0.freebsd-arm.tar.gz", - "d90b78e41921f72f30e8bbc81d9dec2cff7ff384a33d8d8debb24053e4336bfe" - ], - "freebsd_arm64": [ - "go1.25.0.freebsd-arm64.tar.gz", - "451d0da1affd886bfb291b7c63a6018527b269505db21ce6e14724f22ab0662e" - ], - "freebsd_riscv64": [ - "go1.25.0.freebsd-riscv64.tar.gz", - "7b565f76bd8bda46549eeaaefe0e53b251e644c230577290c0f66b1ecdb3cdbe" - ], - "illumos_amd64": [ - "go1.25.0.illumos-amd64.tar.gz", - "b1e1fdaab1ad25aa1c08d7a36c97d45d74b98b89c3f78c6d2145f77face54a2c" - ], - "linux_386": [ - "go1.25.0.linux-386.tar.gz", - "8c602dd9d99bc9453b3995d20ce4baf382cc50855900a0ece5de9929df4a993a" - ], - "linux_amd64": [ - "go1.25.0.linux-amd64.tar.gz", - "2852af0cb20a13139b3448992e69b868e50ed0f8a1e5940ee1de9e19a123b613" - ], - "linux_arm64": [ - "go1.25.0.linux-arm64.tar.gz", - "05de75d6994a2783699815ee553bd5a9327d8b79991de36e38b66862782f54ae" - ], - "linux_armv6l": [ - "go1.25.0.linux-armv6l.tar.gz", - "a5a8f8198fcf00e1e485b8ecef9ee020778bf32a408a4e8873371bfce458cd09" - ], - "linux_loong64": [ - "go1.25.0.linux-loong64.tar.gz", - "cab86b1cf761b1cb3bac86a8877cfc92e7b036fc0d3084123d77013d61432afc" - ], - "linux_mips": [ - "go1.25.0.linux-mips.tar.gz", - "d66b6fb74c3d91b9829dc95ec10ca1f047ef5e89332152f92e136cf0e2da5be1" - ], - "linux_mips64": [ - "go1.25.0.linux-mips64.tar.gz", - "4082e4381a8661bc2a839ff94ba3daf4f6cde20f8fb771b5b3d4762dc84198a2" - ], - "linux_mips64le": [ - "go1.25.0.linux-mips64le.tar.gz", - "70002c299ec7f7175ac2ef673b1b347eecfa54ae11f34416a6053c17f855afcc" - ], - "linux_mipsle": [ - "go1.25.0.linux-mipsle.tar.gz", - "b00a3a39eff099f6df9f1c7355bf28e4589d0586f42d7d4a394efb763d145a73" - ], - "linux_ppc64": [ - "go1.25.0.linux-ppc64.tar.gz", - "df166f33bd98160662560a72ff0b4ba731f969a80f088922bddcf566a88c1ec1" - ], - "linux_ppc64le": [ - "go1.25.0.linux-ppc64le.tar.gz", - "0f18a89e7576cf2c5fa0b487a1635d9bcbf843df5f110e9982c64df52a983ad0" - ], - "linux_riscv64": [ - "go1.25.0.linux-riscv64.tar.gz", - "c018ff74a2c48d55c8ca9b07c8e24163558ffec8bea08b326d6336905d956b67" - ], - "linux_s390x": [ - "go1.25.0.linux-s390x.tar.gz", - "34e5a2e19f2292fbaf8783e3a241e6e49689276aef6510a8060ea5ef54eee408" - ], - "netbsd_386": [ - "go1.25.0.netbsd-386.tar.gz", - "f8586cdb7aa855657609a5c5f6dbf523efa00c2bbd7c76d3936bec80aa6c0aba" - ], - "netbsd_amd64": [ - "go1.25.0.netbsd-amd64.tar.gz", - "ae8dc1469385b86a157a423bb56304ba45730de8a897615874f57dd096db2c2a" - ], - "netbsd_arm": [ - "go1.25.0.netbsd-arm.tar.gz", - "1ff7e4cc764425fc9dd6825eaee79d02b3c7cafffbb3691687c8d672ade76cb7" - ], - "netbsd_arm64": [ - "go1.25.0.netbsd-arm64.tar.gz", - "e1b310739f26724216aa6d7d7208c4031f9ff54c9b5b9a796ddc8bebcb4a5f16" - ], - "openbsd_386": [ - "go1.25.0.openbsd-386.tar.gz", - "4802a9b20e533da91adb84aab42e94aa56cfe3e5475d0550bed3385b182e69d8" - ], - "openbsd_amd64": [ - "go1.25.0.openbsd-amd64.tar.gz", - "c016cd984bebe317b19a4f297c4f50def120dc9788490540c89f28e42f1dabe1" - ], - "openbsd_arm": [ - "go1.25.0.openbsd-arm.tar.gz", - "a1e31d0bf22172ddde42edf5ec811ef81be43433df0948ece52fecb247ccfd8d" - ], - "openbsd_arm64": [ - "go1.25.0.openbsd-arm64.tar.gz", - "343ea8edd8c218196e15a859c6072d0dd3246fbbb168481ab665eb4c4140458d" - ], - "openbsd_ppc64": [ - "go1.25.0.openbsd-ppc64.tar.gz", - "694c14da1bcaeb5e3332d49bdc2b6d155067648f8fe1540c5de8f3cf8e157154" - ], - "openbsd_riscv64": [ - "go1.25.0.openbsd-riscv64.tar.gz", - "aa510ad25cf54c06cd9c70b6d80ded69cb20188ac6e1735655eef29ff7e7885f" - ], - "plan9_386": [ - "go1.25.0.plan9-386.tar.gz", - "46f8cef02086cf04bf186c5912776b56535178d4cb319cd19c9fdbdd29231986" - ], - "plan9_amd64": [ - "go1.25.0.plan9-amd64.tar.gz", - "29b34391d84095e44608a228f63f2f88113a37b74a79781353ec043dfbcb427b" - ], - "plan9_arm": [ - "go1.25.0.plan9-arm.tar.gz", - "0a047107d13ebe7943aaa6d54b1d7bbd2e45e68ce449b52915a818da715799c2" - ], - "solaris_amd64": [ - "go1.25.0.solaris-amd64.tar.gz", - "9977f9e4351984364a3b2b78f8b88bfd1d339812356d5237678514594b7d3611" - ], - "windows_386": [ - "go1.25.0.windows-386.zip", - "df9f39db82a803af0db639e3613a36681ab7a42866b1384b3f3a1045663961a7" - ], - "windows_amd64": [ - "go1.25.0.windows-amd64.zip", - "89efb4f9b30812eee083cc1770fdd2913c14d301064f6454851428f9707d190b" - ], - "windows_arm64": [ - "go1.25.0.windows-arm64.zip", - "27bab004c72b3d7bd05a69b6ec0fc54a309b4b78cc569dd963d8b3ec28bfdb8c" - ] - } - } - }, - "factsVersions": {} -} diff --git a/examples/java-spring-boot-service/README.md b/examples/java-spring-boot-service/README.md deleted file mode 100644 index ad16be1eb..000000000 --- a/examples/java-spring-boot-service/README.md +++ /dev/null @@ -1,61 +0,0 @@ -# java-spring-boot-service - -Reference Spring Boot service built with Bazel. It exists to exercise and -demonstrate the Java-on-Bazel foundation in `//rules/java` and the Maven wiring -in the root `MODULE.bazel`. Copy it as the starting point for a new Java service. - -## Layout - -``` -BUILD.bazel nvcf_java_library + nvcf_spring_boot_image + JUnit 5 test -src/main/java/com/nvidia/nvcf/example/ - ExampleApplication.java @SpringBootApplication entry point - HelloController.java trivial @RestController -src/test/java/.../HelloControllerTest.java -``` - -## Build and test - -``` -bazel test //examples/java-spring-boot-service:hello_controller_test -bazel build //examples/java-spring-boot-service:image_index -``` - -`nvcf_spring_boot_image` generates the same target set as the Go image macro: - -- `:image` host-arch image -- `:image_index` multi-arch index (amd64 + arm64) -- `:image_load` load into a local Docker daemon -- `:image.tar` tarball -- `:image_push` when the macro is given `registry = ...` - -Run it locally: - -``` -bazel run //examples/java-spring-boot-service:image_load -docker run --rm -p 8080:8080 examples/java-spring-boot-service:latest -curl localhost:8080/hello -``` - -## Creating a new Java service from this template - -1. Copy this directory to `src/<plane>/<your-service>` (or another loadable - path; anything under a directory listed in `.bazelignore` is skipped). -2. Rename the package and `main_class`. -3. Add the Maven coordinates your code imports to `maven.install` in the root - `MODULE.bazel`, then re-pin: `bazel run @maven//:pin`. List the artifacts you - import directly in `deps` so the strict-deps header compiler resolves them. -4. Add a subproject entry in `tools/ci/subproject-validations.yaml` (model it on - `java-example-service`) so the build and test run in CI. -5. To publish images, pass `registry = ...` to `nvcf_spring_boot_image` and add a - `release:` block to the subproject entry (model it on `grpc-proxy`). The - release machinery is image-format agnostic: it stamps and pushes the - `:image_index` the same way it does for Go and Rust services. - -## Using nv-boot or other internal dependencies - -This example depends only on public Maven Central artifacts so it builds -anywhere, including the public GitHub mirror. A real internal service that -depends on nv-boot adds the internal Artifactory Maven virtual repository to the -`repositories` list in `maven.install` and lists the nv-boot coordinates in -`artifacts`. See `//rules/java/README.md` for that wiring. diff --git a/examples/java-spring-boot-service/maven_install.json b/examples/java-spring-boot-service/maven_install.json deleted file mode 100755 index 8e559f14a..000000000 --- a/examples/java-spring-boot-service/maven_install.json +++ /dev/null @@ -1,2589 +0,0 @@ -{ - "__AUTOGENERATED_FILE_DO_NOT_MODIFY_THIS_FILE_MANUALLY": "THERE_IS_NO_DATA_ONLY_ZUUL", - "__INPUT_ARTIFACTS_HASH": { - "com.google.code.findbugs:jsr305": 495355163, - "com.google.code.gson:gson": 597770368, - "com.google.errorprone:error_prone_annotations": -1035138750, - "com.google.guava:guava": 1943808618, - "com.google.j2objc:j2objc-annotations": 2003271689, - "net.javacrumbs.shedlock:shedlock-bom": -1406345450, - "org.junit.jupiter:junit-jupiter-api": 194920406, - "org.junit.jupiter:junit-jupiter-engine": -1886863302, - "org.junit.platform:junit-platform-launcher": -354104948, - "org.junit.platform:junit-platform-reporting": 1896713402, - "org.springframework.boot:spring-boot-dependencies": 70164638, - "org.springframework.boot:spring-boot-starter-test": -1561809354, - "org.springframework.boot:spring-boot-starter-web": -1905796688, - "org.springframework.boot:spring-boot-webmvc-test": -490892141, - "org.springframework.cloud:spring-cloud-dependencies": 46341733, - "org.testcontainers:testcontainers-bom": 483223872, - "repositories": -1624298853 - }, - "__RESOLVED_ARTIFACTS_HASH": { - "ch.qos.logback:logback-classic": -619930806, - "ch.qos.logback:logback-classic:jar:sources": -390128445, - "ch.qos.logback:logback-core": -1554021729, - "ch.qos.logback:logback-core:jar:sources": 77538609, - "com.fasterxml.jackson.core:jackson-annotations": 1407322119, - "com.fasterxml.jackson.core:jackson-annotations:jar:sources": -1408285999, - "com.google.code.findbugs:jsr305": -1038659426, - "com.google.code.findbugs:jsr305:jar:sources": -1300148931, - "com.google.code.gson:gson": 1618556651, - "com.google.code.gson:gson:jar:sources": 389178860, - "com.google.errorprone:error_prone_annotations": 492382488, - "com.google.errorprone:error_prone_annotations:jar:sources": 456515251, - "com.google.guava:failureaccess": -268223546, - "com.google.guava:failureaccess:jar:sources": 2053502918, - "com.google.guava:guava": 1240305771, - "com.google.guava:guava:jar:sources": 1591586943, - "com.google.guava:listenablefuture": 1588902908, - "com.google.j2objc:j2objc-annotations": -596695707, - "com.google.j2objc:j2objc-annotations:jar:sources": 900785715, - "com.jayway.jsonpath:json-path": -317990331, - "com.jayway.jsonpath:json-path:jar:sources": -343427302, - "com.vaadin.external.google:android-json": -1531950165, - "com.vaadin.external.google:android-json:jar:sources": -116078240, - "commons-logging:commons-logging": 1061992981, - "commons-logging:commons-logging:jar:sources": 1867783947, - "io.micrometer:micrometer-commons": 326693391, - "io.micrometer:micrometer-commons:jar:sources": -57818626, - "io.micrometer:micrometer-observation": -319705914, - "io.micrometer:micrometer-observation:jar:sources": 1279306785, - "jakarta.activation:jakarta.activation-api": -1560267684, - "jakarta.activation:jakarta.activation-api:jar:sources": 759160467, - "jakarta.annotation:jakarta.annotation-api": -1904975463, - "jakarta.annotation:jakarta.annotation-api:jar:sources": -247204066, - "jakarta.xml.bind:jakarta.xml.bind-api": 1157993223, - "jakarta.xml.bind:jakarta.xml.bind-api:jar:sources": -945798747, - "net.bytebuddy:byte-buddy": 383637760, - "net.bytebuddy:byte-buddy-agent": -1380713096, - "net.bytebuddy:byte-buddy-agent:jar:sources": 564051985, - "net.bytebuddy:byte-buddy:jar:sources": -1360611642, - "net.minidev:accessors-smart": 826413906, - "net.minidev:accessors-smart:jar:sources": -124254155, - "net.minidev:json-smart": 656696918, - "net.minidev:json-smart:jar:sources": -1084786431, - "org.apache.logging.log4j:log4j-api": 191755139, - "org.apache.logging.log4j:log4j-api:jar:sources": 1226633672, - "org.apache.logging.log4j:log4j-to-slf4j": 357996538, - "org.apache.logging.log4j:log4j-to-slf4j:jar:sources": -1847454236, - "org.apache.tomcat.embed:tomcat-embed-core": -2079786590, - "org.apache.tomcat.embed:tomcat-embed-core:jar:sources": -745705587, - "org.apache.tomcat.embed:tomcat-embed-el": -727131551, - "org.apache.tomcat.embed:tomcat-embed-el:jar:sources": 1938415424, - "org.apache.tomcat.embed:tomcat-embed-websocket": 1876889190, - "org.apache.tomcat.embed:tomcat-embed-websocket:jar:sources": -1809736441, - "org.apiguardian:apiguardian-api": -1579303244, - "org.apiguardian:apiguardian-api:jar:sources": 768152577, - "org.assertj:assertj-core": -536770136, - "org.assertj:assertj-core:jar:sources": -1826278818, - "org.awaitility:awaitility": 755971515, - "org.awaitility:awaitility:jar:sources": -1322650242, - "org.checkerframework:checker-qual": -2018582244, - "org.checkerframework:checker-qual:jar:sources": 2110417205, - "org.hamcrest:hamcrest": 1116842741, - "org.hamcrest:hamcrest:jar:sources": -996443755, - "org.jspecify:jspecify": -1402924792, - "org.jspecify:jspecify:jar:sources": -841008091, - "org.junit.jupiter:junit-jupiter": -313198921, - "org.junit.jupiter:junit-jupiter-api": 80944698, - "org.junit.jupiter:junit-jupiter-api:jar:sources": -1650654944, - "org.junit.jupiter:junit-jupiter-engine": 730848020, - "org.junit.jupiter:junit-jupiter-engine:jar:sources": 1805473715, - "org.junit.jupiter:junit-jupiter-params": -1923494954, - "org.junit.jupiter:junit-jupiter-params:jar:sources": 1561682205, - "org.junit.jupiter:junit-jupiter:jar:sources": 1809716175, - "org.junit.platform:junit-platform-commons": -1304725543, - "org.junit.platform:junit-platform-commons:jar:sources": -139331649, - "org.junit.platform:junit-platform-engine": -748595950, - "org.junit.platform:junit-platform-engine:jar:sources": -191078126, - "org.junit.platform:junit-platform-launcher": 1722101087, - "org.junit.platform:junit-platform-launcher:jar:sources": -717285440, - "org.junit.platform:junit-platform-reporting": 1847654060, - "org.junit.platform:junit-platform-reporting:jar:sources": -1771745730, - "org.mockito:mockito-core": 734095861, - "org.mockito:mockito-core:jar:sources": 1757924088, - "org.mockito:mockito-junit-jupiter": -501680015, - "org.mockito:mockito-junit-jupiter:jar:sources": -1281757309, - "org.objenesis:objenesis": 1083875484, - "org.objenesis:objenesis:jar:sources": 703772823, - "org.opentest4j.reporting:open-test-reporting-tooling-spi": -1639379357, - "org.opentest4j.reporting:open-test-reporting-tooling-spi:jar:sources": 1632689314, - "org.opentest4j:opentest4j": 793813175, - "org.opentest4j:opentest4j:jar:sources": 1210936723, - "org.ow2.asm:asm": -1193893588, - "org.ow2.asm:asm:jar:sources": 95374349, - "org.skyscreamer:jsonassert": -1571197746, - "org.skyscreamer:jsonassert:jar:sources": -392658057, - "org.slf4j:jul-to-slf4j": -911724984, - "org.slf4j:jul-to-slf4j:jar:sources": -662175280, - "org.slf4j:slf4j-api": -1249720338, - "org.slf4j:slf4j-api:jar:sources": -297247278, - "org.springframework.boot:spring-boot": -1519545366, - "org.springframework.boot:spring-boot-autoconfigure": -491644458, - "org.springframework.boot:spring-boot-autoconfigure:jar:sources": 562322138, - "org.springframework.boot:spring-boot-http-converter": -1456188332, - "org.springframework.boot:spring-boot-http-converter:jar:sources": 678862764, - "org.springframework.boot:spring-boot-jackson": -886310726, - "org.springframework.boot:spring-boot-jackson:jar:sources": -928970153, - "org.springframework.boot:spring-boot-servlet": -1040246830, - "org.springframework.boot:spring-boot-servlet:jar:sources": 1162002660, - "org.springframework.boot:spring-boot-starter": 191814674, - "org.springframework.boot:spring-boot-starter-jackson": 211326145, - "org.springframework.boot:spring-boot-starter-jackson:jar:sources": 1689728463, - "org.springframework.boot:spring-boot-starter-logging": 51215582, - "org.springframework.boot:spring-boot-starter-logging:jar:sources": 1271111015, - "org.springframework.boot:spring-boot-starter-test": -1546680330, - "org.springframework.boot:spring-boot-starter-test:jar:sources": -480189945, - "org.springframework.boot:spring-boot-starter-tomcat": -521361670, - "org.springframework.boot:spring-boot-starter-tomcat-runtime": -1912812722, - "org.springframework.boot:spring-boot-starter-tomcat-runtime:jar:sources": 1011838045, - "org.springframework.boot:spring-boot-starter-tomcat:jar:sources": 1319064174, - "org.springframework.boot:spring-boot-starter-web": 1122240419, - "org.springframework.boot:spring-boot-starter-web:jar:sources": -768709610, - "org.springframework.boot:spring-boot-starter:jar:sources": 1138639700, - "org.springframework.boot:spring-boot-test": -927444958, - "org.springframework.boot:spring-boot-test-autoconfigure": -669950838, - "org.springframework.boot:spring-boot-test-autoconfigure:jar:sources": 392165449, - "org.springframework.boot:spring-boot-test:jar:sources": -1764708648, - "org.springframework.boot:spring-boot-tomcat": -1113349252, - "org.springframework.boot:spring-boot-tomcat:jar:sources": -1529683395, - "org.springframework.boot:spring-boot-web-server": 285708094, - "org.springframework.boot:spring-boot-web-server:jar:sources": 990724443, - "org.springframework.boot:spring-boot-webmvc": -2104103221, - "org.springframework.boot:spring-boot-webmvc-test": 749235095, - "org.springframework.boot:spring-boot-webmvc-test:jar:sources": 444837917, - "org.springframework.boot:spring-boot-webmvc:jar:sources": -1895028417, - "org.springframework.boot:spring-boot:jar:sources": 580880564, - "org.springframework:spring-aop": -819786825, - "org.springframework:spring-aop:jar:sources": 1924976574, - "org.springframework:spring-beans": -698130853, - "org.springframework:spring-beans:jar:sources": -2147408778, - "org.springframework:spring-context": -846077202, - "org.springframework:spring-context:jar:sources": -1263444176, - "org.springframework:spring-core": -253727183, - "org.springframework:spring-core:jar:sources": -173347576, - "org.springframework:spring-expression": 1724609785, - "org.springframework:spring-expression:jar:sources": 1135225455, - "org.springframework:spring-test": -279979944, - "org.springframework:spring-test:jar:sources": -6017836, - "org.springframework:spring-web": 2084009704, - "org.springframework:spring-web:jar:sources": 1608360284, - "org.springframework:spring-webmvc": 56813816, - "org.springframework:spring-webmvc:jar:sources": -837106767, - "org.xmlunit:xmlunit-core": 1938864481, - "org.xmlunit:xmlunit-core:jar:sources": -54376142, - "org.yaml:snakeyaml": -1432706414, - "org.yaml:snakeyaml:jar:sources": 393768628, - "tools.jackson.core:jackson-core": -1258054011, - "tools.jackson.core:jackson-core:jar:sources": -1689479769, - "tools.jackson.core:jackson-databind": 1443518747, - "tools.jackson.core:jackson-databind:jar:sources": -871567409 - }, - "artifacts": { - "ch.qos.logback:logback-classic": { - "shasums": { - "jar": "b65e05076a5c1aadb659b4fe4bc5fee31cb26cd70390292eb03e4a7a24cff10f", - "sources": "c2e39cb4d6d9b8c2343c6da2469e21e1d6aef2dde16c2227762c084d549ad0a0" - }, - "version": "1.5.34" - }, - "ch.qos.logback:logback-core": { - "shasums": { - "jar": "42eda264c0c650c2bec59e66151a88b708a8663dc1b49d788202d53e78b8caae", - "sources": "6a9f217ef206caf2880810c505e057fd2bb90a6024013906815e9513c6e488c5" - }, - "version": "1.5.34" - }, - "com.fasterxml.jackson.core:jackson-annotations": { - "shasums": { - "jar": "53ca085f4a150f703f49e1aabd935bd03b43e1ea3d55d135438292af22cef56b", - "sources": "71fe6323d91b16d5d1007fd1e1533fa06bb369abde74f68a42a68c0f8f061a8b" - }, - "version": "2.21" - }, - "com.google.code.findbugs:jsr305": { - "shasums": { - "jar": "766ad2a0783f2687962c8ad74ceecc38a28b9f72a2d085ee438b7813e928d0c7", - "sources": "1c9e85e272d0708c6a591dc74828c71603053b48cc75ae83cce56912a2aa063b" - }, - "version": "3.0.2" - }, - "com.google.code.gson:gson": { - "shasums": { - "jar": "d3999291855de495c94c743761b8ab5176cfeabe281a5ab0d8e8d45326fd703e", - "sources": "ba5bddb1a89eb721fcca39f3b34294532060f851e2407a82d82134a41eec4719" - }, - "version": "2.8.9" - }, - "com.google.errorprone:error_prone_annotations": { - "shasums": { - "jar": "ff80626baaf12a09342befd4e84cba9d50662f5fcd7f7a9b3490a6b7cf87e66c", - "sources": "bf08616e340f5e2ef50aaa84aea8baa086fd7bb2ad310501ff4e88ec77f8f31a" - }, - "version": "2.5.1" - }, - "com.google.guava:failureaccess": { - "shasums": { - "jar": "a171ee4c734dd2da837e4b16be9df4661afab72a41adaf31eb84dfdaf936ca26", - "sources": "092346eebbb1657b51aa7485a246bf602bb464cc0b0e2e1c7e7201fadce1e98f" - }, - "version": "1.0.1" - }, - "com.google.guava:guava": { - "shasums": { - "jar": "bd7fa227591fb8509677d0d1122cf95158f3b8a9f45653f58281d879f6dc48c5", - "sources": "9105dfc522fb440b39ff8da07cc56aacf65a9f765044c7803a9f32e36e05a22b" - }, - "version": "32.0.1-jre" - }, - "com.google.guava:listenablefuture": { - "shasums": { - "jar": "b372a037d4230aa57fbeffdef30fd6123f9c0c2db85d0aced00c91b974f33f99" - }, - "version": "9999.0-empty-to-avoid-conflict-with-guava" - }, - "com.google.j2objc:j2objc-annotations": { - "shasums": { - "jar": "f02a95fa1a5e95edb3ed859fd0fb7df709d121a35290eff8b74dce2ab7f4d6ed", - "sources": "7413eed41f111453a08837f5ac680edded7faed466cbd35745e402e13f4cc3f5" - }, - "version": "2.8" - }, - "com.jayway.jsonpath:json-path": { - "shasums": { - "jar": "890daa95dd3892d34d9fabc27cd5153656e6f369358625c88f4dc7b79cbd6c5a", - "sources": "357f1c52217497c4251fae715ba8ef76ae310b1aae77ea319260bf4c6ad61440" - }, - "version": "2.10.0" - }, - "com.vaadin.external.google:android-json": { - "shasums": { - "jar": "dfb7bae2f404cfe0b72b4d23944698cb716b7665171812a0a4d0f5926c0fac79", - "sources": "54c781eea645c450cbbc4a5a1b5a474745465452cec1354cb567b781ea6622c3" - }, - "version": "0.0.20131108.vaadin1" - }, - "commons-logging:commons-logging": { - "shasums": { - "jar": "f8ead8943401081dea0aa824b5b1ba40a0e4ed297a572a0f02258150a0b62357", - "sources": "6e821e03cfc64e509cc162d428af84697b6c4188eb14c0b137c75b69649976ef" - }, - "version": "1.3.6" - }, - "io.micrometer:micrometer-commons": { - "shasums": { - "jar": "45aff76226830db257f4bc39a5bcff83d633e572fee9dc4e45cfa12af9a0a49a", - "sources": "0e4a336c7bca50bfa6cbea274ea681e42d86bfdac1038af3041301c8454f76ff" - }, - "version": "1.16.6" - }, - "io.micrometer:micrometer-observation": { - "shasums": { - "jar": "4c0826d5e7c8522a8e111470b4e77f77b0a10f520eb5502ddd143fdbcedb2340", - "sources": "ff5525482df358e7502d4c8680fb654ec700e3b01341149d870bd6cfd8ce04c0" - }, - "version": "1.16.6" - }, - "jakarta.activation:jakarta.activation-api": { - "shasums": { - "jar": "c9db52100ce6c8aac95cc39075f95720d2e561b11f8051b81c121ad4effd7004", - "sources": "2aa5a3ba55059b778a3b467269404d7ac3b9485ed4a23ad26d2e63aa769ec35f" - }, - "version": "2.1.4" - }, - "jakarta.annotation:jakarta.annotation-api": { - "shasums": { - "jar": "b01f55552284cfb149411e64eabca75e942d26d2e1786b32914250e4330afaa2", - "sources": "142dfd2343429df2aac3e1cfacfacc21c8393112c0e0280d3628648d9b612470" - }, - "version": "3.0.0" - }, - "jakarta.xml.bind:jakarta.xml.bind-api": { - "shasums": { - "jar": "5e489b6c874c4119e003ff1403db523ee3a8959ec499f3de29e77245efccf216", - "sources": "5bcf811e6719582ab2be21c84bc48f963ba377dfe1dae5ecb2673c1efa00e422" - }, - "version": "4.0.5" - }, - "net.bytebuddy:byte-buddy": { - "shasums": { - "jar": "2b5ddc8c1f4234bdb7cb45338a8e10a13e0e3ca473e91d5d821d681127ea8ba1", - "sources": "5211140f46c380a5e9630a86b2c07b396a9c374128fa603ca1d321b3c7da7449" - }, - "version": "1.17.8" - }, - "net.bytebuddy:byte-buddy-agent": { - "shasums": { - "jar": "5b17113e66e77ca6f8af07ff367c216df964a980f0e9f11e3b1aa793253aa64f", - "sources": "a205437d772e3edaf4a7a1a709e9d59c666e8a05218d0e000deb5651c52de2d2" - }, - "version": "1.17.8" - }, - "net.minidev:accessors-smart": { - "shasums": { - "jar": "222c9f547bb20a99fc486403a398352d1306fb671b38abd7ecab6401df170e61", - "sources": "10880e44ed732de27ae424a9698a041c398102098b5b1bae3cc597ec62dac43e" - }, - "version": "2.6.0" - }, - "net.minidev:json-smart": { - "shasums": { - "jar": "1ae4b561458afb540be8ec5c6dbb4f2e715a319a7ae64854998aaf924770d61b", - "sources": "a4af3f3773286fe3f76f94d38d977611fd2493685f589466b76dd25cf70b400c" - }, - "version": "2.6.0" - }, - "org.apache.logging.log4j:log4j-api": { - "shasums": { - "jar": "c4b642a7f047275215de117e0e3847eb2c7711d84a0aa7433e7b3c096daf341d", - "sources": "b86680bcf8ffa25897b6114cae508bb8e6ecac8081a0fc8985e0c00e27d4f4ec" - }, - "version": "2.25.4" - }, - "org.apache.logging.log4j:log4j-to-slf4j": { - "shasums": { - "jar": "d7b78fc0aaaa5e8ada388b29d718b0ab187e512965bed0b259bb4ab299f13db2", - "sources": "ca9159da173bf88fb621adf745fe1d313ba4074f4c66576ae70f5dd99eab89c9" - }, - "version": "2.25.4" - }, - "org.apache.tomcat.embed:tomcat-embed-core": { - "shasums": { - "jar": "78cd7cd7c104b6b87142c1b0bd902e1ce005b0245c3cefa8a06759148947200b", - "sources": "0bfbdc27e60d4db5b83e0f51193bae5f4bd02ac270fd78b06945e219fc473359" - }, - "version": "11.0.22" - }, - "org.apache.tomcat.embed:tomcat-embed-el": { - "shasums": { - "jar": "1b34c33b858c141df36c501b4d809e68036c406bca3671a86facae297917c7de", - "sources": "da3724004575f5c8fa7e45649f2900ec53e7ecfb502b6ce227ca9cf86b36a156" - }, - "version": "11.0.22" - }, - "org.apache.tomcat.embed:tomcat-embed-websocket": { - "shasums": { - "jar": "210e0c7ab194a76cc7283df0be365276091b042369dae125fb477828ba67e922", - "sources": "711f09af528ac5af172c664244bcba4748eac00811ef7c6b52ddd6836b5a4a28" - }, - "version": "11.0.22" - }, - "org.apiguardian:apiguardian-api": { - "shasums": { - "jar": "b509448ac506d607319f182537f0b35d71007582ec741832a1f111e5b5b70b38", - "sources": "277a7a4315412817beb6655b324dc7276621e95ebff00b8bf65e17a27b685e2d" - }, - "version": "1.1.2" - }, - "org.assertj:assertj-core": { - "shasums": { - "jar": "c4a445426c3c2861666863b842cc4ec7bbb1c4226fefd370b6d2fe83d6c4ff0f", - "sources": "5ba6de05730cf76021001f8437f35db4cb5b513465d4ace8c3a6fcd68d9a19ee" - }, - "version": "3.27.7" - }, - "org.awaitility:awaitility": { - "shasums": { - "jar": "ee58568ea5945dcf988551501655183dc184e23e45a8e013fdfd9036194e6f7b", - "sources": "92d209bd0135b04ca6bb7689c6b921819896ec2d517a5357760f598faafee46c" - }, - "version": "4.3.0" - }, - "org.checkerframework:checker-qual": { - "shasums": { - "jar": "e316255bbfcd9fe50d165314b85abb2b33cb2a66a93c491db648e498a82c2de1", - "sources": "443fa6151982bb4c6ce62e2938f53660085b13a7dceb517202777b87d0dea2c7" - }, - "version": "3.33.0" - }, - "org.hamcrest:hamcrest": { - "shasums": { - "jar": "5d66b6a4a680755cb6ed7cb104fa7835ef644667586ff0737adeb977c39ecdbc", - "sources": "7a4050b1898f7e1aa395cf2be78fb6683f9e2766fcb8e1507926b204fa24d1bf" - }, - "version": "3.0" - }, - "org.jspecify:jspecify": { - "shasums": { - "jar": "1fad6e6be7557781e4d33729d49ae1cdc8fdda6fe477bb0cc68ce351eafdfbab", - "sources": "adf0898191d55937fb3192ba971826f4f294292c4a960740f3c27310e7b70296" - }, - "version": "1.0.0" - }, - "org.junit.jupiter:junit-jupiter": { - "shasums": { - "jar": "784b65815f479a0c99a9d3a573b142e2a525efb6025d97f751b19e72f90aeda3", - "sources": "402f86a4fdce930bb68b592f2ed5a9d57dc4d1b2747aa2d66c0b3cb7a2adceeb" - }, - "version": "6.0.3" - }, - "org.junit.jupiter:junit-jupiter-api": { - "shasums": { - "jar": "d655d7e6f0c7ae07f10a2f3bbaaebb6d30e9b26204a068ad9e9b3950aa28792c", - "sources": "8266d8da51d0c7d6a2ed4895a3cb76e0ec22194907f24364f2a4f3efd05f00a5" - }, - "version": "6.0.3" - }, - "org.junit.jupiter:junit-jupiter-engine": { - "shasums": { - "jar": "1e2fab61ad27ea08fc7c70dd9677cf8c6d1ae5434d42dcfdd633b12c7e7c04d0", - "sources": "35706a9edf1b580bf22d6eca9d6a9165f478f75b0108840ad6f31481cd662d6c" - }, - "version": "6.0.3" - }, - "org.junit.jupiter:junit-jupiter-params": { - "shasums": { - "jar": "cf2947e2302b9f8c8a059259a277881c1cadae8fbc2514c16a925cfeb7beb2e5", - "sources": "f0dcf217100b06b98cd36c2e74fb919c74e3024faad868bac9eba6ff00c7c263" - }, - "version": "6.0.3" - }, - "org.junit.platform:junit-platform-commons": { - "shasums": { - "jar": "39f262d09c3d52719fe0b77f080e90a3695e285d779a41b232e17963ae5da200", - "sources": "06cbe4a4bbd79339c3817983510cf3adc3d6a88a8a556c80c5b84eeb1ebd13dc" - }, - "version": "6.0.3" - }, - "org.junit.platform:junit-platform-engine": { - "shasums": { - "jar": "491e9e4f745f161b8a8e4186a1a7c6a450ea12c70930c9aedae427215301d947", - "sources": "89a893566a97557dbbcb0706d9b5565c4e7a402050841753dc527f3e9139c9ac" - }, - "version": "6.0.3" - }, - "org.junit.platform:junit-platform-launcher": { - "shasums": { - "jar": "315608372e4dc44bca0ccb3ae8a07ecc206b3367033fa05748a03ccd563f1301", - "sources": "4fcbdb81cc882c0c3e73f742878db5884d3d2f86facc08369ca953e32796d144" - }, - "version": "6.0.3" - }, - "org.junit.platform:junit-platform-reporting": { - "shasums": { - "jar": "f19c5be871c37ebed493f3152b67a909f89a44dff67c2db8016dfe34167d5730", - "sources": "bbdda2b9c002dbd1b05cfec144bab91e8cca46ed8d58525f51b547f3a0a84a7d" - }, - "version": "6.0.3" - }, - "org.mockito:mockito-core": { - "shasums": { - "jar": "d1a96d252128d3a4247cfd8a2e76412efa3cc103977be17933c942117a24f374", - "sources": "dcde489c1db6449c162f05105ace4c172850d3dc7f6633bb4f54d47a16a0fd1b" - }, - "version": "5.20.0" - }, - "org.mockito:mockito-junit-jupiter": { - "shasums": { - "jar": "fd6c703c2b00b914f3adbc27b18077a708f3d6992f19242c444e737c6cce024e", - "sources": "3c199479a2319db4395fd9fd209946ecc4530f48fe5cdeed7677c285bf70fbb5" - }, - "version": "5.20.0" - }, - "org.objenesis:objenesis": { - "shasums": { - "jar": "02dfd0b0439a5591e35b708ed2f5474eb0948f53abf74637e959b8e4ef69bfeb", - "sources": "d06164f8ca002c8ef193cef2d682822014dd330505616af93a3fb64226fc131d" - }, - "version": "3.3" - }, - "org.opentest4j.reporting:open-test-reporting-tooling-spi": { - "shasums": { - "jar": "04ac4ecfcaf60abe0e6d5b18e8306320aec7cd9cbf15e59eeac54fa9faa16902", - "sources": "efe9672e74111726c0ff85a2508a0bc78be611a7cbe460560dc7cd429ee0a4ce" - }, - "version": "0.2.4" - }, - "org.opentest4j:opentest4j": { - "shasums": { - "jar": "48e2df636cab6563ced64dcdff8abb2355627cb236ef0bf37598682ddf742f1b", - "sources": "724a24e3a68267d5ebac9411389a15638a71e50c62448ffa58f59c34d5c1ebb2" - }, - "version": "1.3.0" - }, - "org.ow2.asm:asm": { - "shasums": { - "jar": "8cadd43ac5eb6d09de05faecca38b917a040bb9139c7edeb4cc81c740b713281", - "sources": "22e9507b0c494daaedb33b8148c30cd618c6dacc3992be8b50eaaafeb6a8ba8d" - }, - "version": "9.7.1" - }, - "org.skyscreamer:jsonassert": { - "shasums": { - "jar": "719095c07d4203961320da593441d8b3b643c18eb1d81aa98ea933bb7eb351ba", - "sources": "a825c29f8cc40f85ea4e7a431a55d4278a785c34acdeef4cd1be7367f70ea6bb" - }, - "version": "1.5.3" - }, - "org.slf4j:jul-to-slf4j": { - "shasums": { - "jar": "cbb7d1aaaa9e871eb1a06594abd911bf97027152976edf1edc315be75239204e", - "sources": "b6dd2138f3e83d876bf07206d09f2b48ca655bc36a8e80b0c2a32ad19ab8f1d5" - }, - "version": "2.0.18" - }, - "org.slf4j:slf4j-api": { - "shasums": { - "jar": "44508fd1576500688c790b190acdd16fec4f8c79a3e0b900afd70503cf055f55", - "sources": "192e007cf7f2be41d40574e44521fc0b7ce55e01f13dbe0fa8707c8ae3329075" - }, - "version": "2.0.18" - }, - "org.springframework.boot:spring-boot": { - "shasums": { - "jar": "edb984d0bc80d209bed271e6d334fbfbfcf11cc4c1ef5059adc31c5bde7b1d7c", - "sources": "850ec7c91b0ff92c46797e0adcf1f47369d64a0cf4a8427d01b4834df129d0d4" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-autoconfigure": { - "shasums": { - "jar": "1e8a953294fe76727965970de31e3bb08fba2b65e3ca0ee9b8bca492d0818d10", - "sources": "477e9834d7982b080b485c7baeb27ea399fca324d0442dc2f694a473b6a394fd" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-http-converter": { - "shasums": { - "jar": "9f620c36cb98103ef664a9fccad4173ae20120d1abc790b795130be4e02dbb90", - "sources": "9f4378bcb3caa6696d8fe340c519bd673287f2c046098607cbe079ba9aa98874" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-jackson": { - "shasums": { - "jar": "0cdbadd10bcc3b23d32dffd419caceda4a4ed6b3da0262617f543732e9105ece", - "sources": "efe6e9f38861e94fbf36045bb23d23076407d26fed5752efb852ad2accaea3bb" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-servlet": { - "shasums": { - "jar": "fb1af769617daa2808a82921d98ca94efde8cb20fcefc55e71b2e0bf93de1423", - "sources": "172a6736933d75bdeeee725078769e27d8142a826e811940c595aea815913512" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-starter": { - "shasums": { - "jar": "d70f5f300c9e7af18813799bffce38974398f6429c578c825822a32560c4b202", - "sources": "d70f5f300c9e7af18813799bffce38974398f6429c578c825822a32560c4b202" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-starter-jackson": { - "shasums": { - "jar": "bd042218bf291c4ee821d7ec3e86f7f747223d32cd87066aa5e3730a2dd5c3b6", - "sources": "bd042218bf291c4ee821d7ec3e86f7f747223d32cd87066aa5e3730a2dd5c3b6" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-starter-logging": { - "shasums": { - "jar": "b5f1d01cd179ffc24b125a6ce971854b7b141c4e19e9c050a0b82d514983b1f6", - "sources": "b5f1d01cd179ffc24b125a6ce971854b7b141c4e19e9c050a0b82d514983b1f6" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-starter-test": { - "shasums": { - "jar": "e4844ae2375d569711af218763620993ea434b4836d3463cf26d9f6b6e589340", - "sources": "e4844ae2375d569711af218763620993ea434b4836d3463cf26d9f6b6e589340" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-starter-tomcat": { - "shasums": { - "jar": "f4a81ce616baa9c715be0dc0735210d770aa67301f92d3b11942f780056fc7ad", - "sources": "f4a81ce616baa9c715be0dc0735210d770aa67301f92d3b11942f780056fc7ad" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-starter-tomcat-runtime": { - "shasums": { - "jar": "8d0c7cbd6bd43d47e664a9127f70ceddab952828797f20e2b0b93848796d82f2", - "sources": "8d0c7cbd6bd43d47e664a9127f70ceddab952828797f20e2b0b93848796d82f2" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-starter-web": { - "shasums": { - "jar": "1ac009b240450c089df7ef1e5cc9b63df292bea22393ed5c7deca42c85944e3c", - "sources": "1ac009b240450c089df7ef1e5cc9b63df292bea22393ed5c7deca42c85944e3c" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-test": { - "shasums": { - "jar": "8879b4a336972eb498ca6606266e6ecdae911964c0a480d3f4bf37a6c2455b33", - "sources": "4dc67a1a332d75fa3dcf517f4b6dc66ed146793307aa9d23c0ebb5f4b399850a" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-test-autoconfigure": { - "shasums": { - "jar": "99ca7ab8be0dde10fa6c03e1026969619e826fcc914b6bc0d09090e75ba17cb4", - "sources": "f94cf34c24539cc3752fae1a0bf182282086452e9c83cfae5241574f20951eb3" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-tomcat": { - "shasums": { - "jar": "ad7c6527319f5cac0b5638a28820847f64d21282147fb98daaaa1f515ee17323", - "sources": "2388d2eaeb9d413d3d7525983fe14030d3b48bc0cca1530c8c7e9dc73e05e8b5" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-web-server": { - "shasums": { - "jar": "26a13c73ee85e7a851b73eb2d683ed4d3b7a4ca581b608dfd627bd4551997cf2", - "sources": "41e1dddf6e1be5fc35c4849f51639c097e7a8eb9c6627a780791a1d9e430c311" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-webmvc": { - "shasums": { - "jar": "95250948bda9a0a1e1f2ad3f413bd23e36dfedefb89fe59d309d447c6c4c5010", - "sources": "26a04367e170092463c619c886f4f8b688644eecc4a6c91c18d17c242a8f4211" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-webmvc-test": { - "shasums": { - "jar": "06180d3ee7f9019880b0528cc93164f8f038e35007bd99a40fbe52892d96a955", - "sources": "4c5b614a96d50a44fce7c3269b82f26fed6d3d04933140ecf52db5e4d32e2480" - }, - "version": "4.0.7" - }, - "org.springframework:spring-aop": { - "shasums": { - "jar": "1178f039e087884174e2affc46e484f4a8bd7f2a4e011d33dd9137709f740f80", - "sources": "580610d9e5e2418ea48f64850673ed1d1fdc2d9c8e5cf6e9cfaece1e61b70522" - }, - "version": "7.0.8" - }, - "org.springframework:spring-beans": { - "shasums": { - "jar": "6ec2e361a8872a71d8b1ff66f1bcb8cfa29fcc437931998919da7cecfb59b45b", - "sources": "d75bdcfe142b1576f72356748292cad5c21872a52be2c7f2920a9795bb3c52a5" - }, - "version": "7.0.8" - }, - "org.springframework:spring-context": { - "shasums": { - "jar": "1eb7d552414ebac00e30ab3e809138d810785f6d2c4271db77cdf0181f308f19", - "sources": "a28b30679b51bcf8aac7f06cb564a379cc2d6c4891b2e2dfc738ddd750c6278e" - }, - "version": "7.0.8" - }, - "org.springframework:spring-core": { - "shasums": { - "jar": "726ba2a5130833644bdf267a55ff26e1f52e8dcc9aa1ffa06904ca9c14619f25", - "sources": "3cbdaed9f2b1eea10d8ac27148ac5e6407d2861fa2d373253a09a1220a232919" - }, - "version": "7.0.8" - }, - "org.springframework:spring-expression": { - "shasums": { - "jar": "3c97c38ab59c77ee886e08ccf8096f6bb58a1245f68dfed7a40e93f41c435f9a", - "sources": "35517249c504d1d4550186808665587c8bb5be953cb6cbbb3856804194e790e9" - }, - "version": "7.0.8" - }, - "org.springframework:spring-test": { - "shasums": { - "jar": "6ffb7796075a204915edc4bb9e54dc420183cecb520d753004f660f153763c8e", - "sources": "7bc670e2e1c9cc902da5557a857dde0a4d8089c267ccfcc1bb554cbf2a8c5a05" - }, - "version": "7.0.8" - }, - "org.springframework:spring-web": { - "shasums": { - "jar": "4d4ed7ecb0453d25d735ea27d025ea36b003c3d29cb7d006bedd6d5188a2f5c0", - "sources": "281cbbd965844cdf2e08396924eacd8a369cd38f56fdfb9519c7492217d8b411" - }, - "version": "7.0.8" - }, - "org.springframework:spring-webmvc": { - "shasums": { - "jar": "48f7e1e2d0d46e98ed3fa30d5a64cb1f7ed2aa339a82edcd87289ed8ff216f04", - "sources": "6dcbc3dc4d5222121f83d1eb0d30807e389771b8d233be38b8e413b92b88a106" - }, - "version": "7.0.8" - }, - "org.xmlunit:xmlunit-core": { - "shasums": { - "jar": "208e0cee82aedd9183937e4b9ae44b83884179f724a706bef5795477acfcca91", - "sources": "bb8dba65e8bc1ade346e4bfd98d7f620f51ae8b9034e9758cd6f3031838e79fd" - }, - "version": "2.10.4" - }, - "org.yaml:snakeyaml": { - "shasums": { - "jar": "e6682acf1ace77508ef13649cbf4f8d09d2cf5457bdb61d25ffb6ac0233d78dd", - "sources": "7a7d307ca9fe1663219a60045a8e5a113a69331566f9ebbe1d3b12c6781909ac" - }, - "version": "2.5" - }, - "tools.jackson.core:jackson-core": { - "shasums": { - "jar": "3bda1cd6eff0a8d47bdfcaeae7c2bd5311d6c8ed494ef5f3e51029bb44aa9bdf", - "sources": "5aa481c1c120505fc1d204510ec201a40c2bb0bb6bdea24560e0b5fb66484e60" - }, - "version": "3.1.4" - }, - "tools.jackson.core:jackson-databind": { - "shasums": { - "jar": "14034bfdf392b6ebec1b4bb6c1de29d604f0aa97251259a19d5f19af8719bb20", - "sources": "109baa39968ff6fdcc4389dd4249f04d2edcab7387421ea17bfb51bf18e24189" - }, - "version": "3.1.4" - } - }, - "dependencies": { - "ch.qos.logback:logback-classic": [ - "ch.qos.logback:logback-core", - "org.slf4j:slf4j-api" - ], - "com.google.guava:guava": [ - "com.google.code.findbugs:jsr305", - "com.google.errorprone:error_prone_annotations", - "com.google.guava:failureaccess", - "com.google.guava:listenablefuture", - "com.google.j2objc:j2objc-annotations", - "org.checkerframework:checker-qual" - ], - "com.jayway.jsonpath:json-path": [ - "net.minidev:json-smart", - "org.slf4j:slf4j-api" - ], - "io.micrometer:micrometer-commons": [ - "org.jspecify:jspecify" - ], - "io.micrometer:micrometer-observation": [ - "io.micrometer:micrometer-commons", - "org.jspecify:jspecify" - ], - "jakarta.xml.bind:jakarta.xml.bind-api": [ - "jakarta.activation:jakarta.activation-api" - ], - "net.minidev:accessors-smart": [ - "org.ow2.asm:asm" - ], - "net.minidev:json-smart": [ - "net.minidev:accessors-smart" - ], - "org.apache.logging.log4j:log4j-to-slf4j": [ - "org.apache.logging.log4j:log4j-api", - "org.slf4j:slf4j-api" - ], - "org.apache.tomcat.embed:tomcat-embed-websocket": [ - "org.apache.tomcat.embed:tomcat-embed-core" - ], - "org.assertj:assertj-core": [ - "net.bytebuddy:byte-buddy" - ], - "org.awaitility:awaitility": [ - "org.hamcrest:hamcrest" - ], - "org.junit.jupiter:junit-jupiter": [ - "org.junit.jupiter:junit-jupiter-api", - "org.junit.jupiter:junit-jupiter-engine", - "org.junit.jupiter:junit-jupiter-params" - ], - "org.junit.jupiter:junit-jupiter-api": [ - "org.apiguardian:apiguardian-api", - "org.jspecify:jspecify", - "org.junit.platform:junit-platform-commons", - "org.opentest4j:opentest4j" - ], - "org.junit.jupiter:junit-jupiter-engine": [ - "org.apiguardian:apiguardian-api", - "org.jspecify:jspecify", - "org.junit.jupiter:junit-jupiter-api", - "org.junit.platform:junit-platform-engine" - ], - "org.junit.jupiter:junit-jupiter-params": [ - "org.apiguardian:apiguardian-api", - "org.jspecify:jspecify", - "org.junit.jupiter:junit-jupiter-api" - ], - "org.junit.platform:junit-platform-commons": [ - "org.apiguardian:apiguardian-api", - "org.jspecify:jspecify" - ], - "org.junit.platform:junit-platform-engine": [ - "org.apiguardian:apiguardian-api", - "org.jspecify:jspecify", - "org.junit.platform:junit-platform-commons", - "org.opentest4j:opentest4j" - ], - "org.junit.platform:junit-platform-launcher": [ - "org.apiguardian:apiguardian-api", - "org.jspecify:jspecify", - "org.junit.platform:junit-platform-engine" - ], - "org.junit.platform:junit-platform-reporting": [ - "org.apiguardian:apiguardian-api", - "org.jspecify:jspecify", - "org.junit.platform:junit-platform-launcher", - "org.opentest4j.reporting:open-test-reporting-tooling-spi" - ], - "org.mockito:mockito-core": [ - "net.bytebuddy:byte-buddy", - "net.bytebuddy:byte-buddy-agent", - "org.objenesis:objenesis" - ], - "org.mockito:mockito-junit-jupiter": [ - "org.junit.jupiter:junit-jupiter-api", - "org.mockito:mockito-core" - ], - "org.opentest4j.reporting:open-test-reporting-tooling-spi": [ - "org.apiguardian:apiguardian-api" - ], - "org.skyscreamer:jsonassert": [ - "com.vaadin.external.google:android-json" - ], - "org.slf4j:jul-to-slf4j": [ - "org.slf4j:slf4j-api" - ], - "org.springframework.boot:spring-boot": [ - "org.springframework:spring-context", - "org.springframework:spring-core" - ], - "org.springframework.boot:spring-boot-autoconfigure": [ - "org.springframework.boot:spring-boot" - ], - "org.springframework.boot:spring-boot-http-converter": [ - "org.springframework.boot:spring-boot", - "org.springframework:spring-web" - ], - "org.springframework.boot:spring-boot-jackson": [ - "org.springframework.boot:spring-boot", - "tools.jackson.core:jackson-databind" - ], - "org.springframework.boot:spring-boot-servlet": [ - "org.springframework.boot:spring-boot", - "org.springframework:spring-web" - ], - "org.springframework.boot:spring-boot-starter": [ - "jakarta.annotation:jakarta.annotation-api", - "org.springframework.boot:spring-boot-autoconfigure", - "org.springframework.boot:spring-boot-starter-logging", - "org.yaml:snakeyaml" - ], - "org.springframework.boot:spring-boot-starter-jackson": [ - "org.springframework.boot:spring-boot-jackson", - "org.springframework.boot:spring-boot-starter" - ], - "org.springframework.boot:spring-boot-starter-logging": [ - "ch.qos.logback:logback-classic", - "org.apache.logging.log4j:log4j-to-slf4j", - "org.slf4j:jul-to-slf4j" - ], - "org.springframework.boot:spring-boot-starter-test": [ - "com.jayway.jsonpath:json-path", - "jakarta.xml.bind:jakarta.xml.bind-api", - "net.minidev:json-smart", - "org.assertj:assertj-core", - "org.awaitility:awaitility", - "org.hamcrest:hamcrest", - "org.junit.jupiter:junit-jupiter", - "org.mockito:mockito-core", - "org.mockito:mockito-junit-jupiter", - "org.skyscreamer:jsonassert", - "org.springframework.boot:spring-boot-starter", - "org.springframework.boot:spring-boot-test", - "org.springframework.boot:spring-boot-test-autoconfigure", - "org.springframework:spring-core", - "org.springframework:spring-test", - "org.xmlunit:xmlunit-core" - ], - "org.springframework.boot:spring-boot-starter-tomcat": [ - "org.springframework.boot:spring-boot-starter", - "org.springframework.boot:spring-boot-starter-tomcat-runtime", - "org.springframework.boot:spring-boot-tomcat" - ], - "org.springframework.boot:spring-boot-starter-tomcat-runtime": [ - "jakarta.annotation:jakarta.annotation-api", - "org.apache.tomcat.embed:tomcat-embed-core", - "org.apache.tomcat.embed:tomcat-embed-el", - "org.apache.tomcat.embed:tomcat-embed-websocket", - "org.springframework.boot:spring-boot-tomcat", - "org.springframework.boot:spring-boot-web-server" - ], - "org.springframework.boot:spring-boot-starter-web": [ - "org.springframework.boot:spring-boot-http-converter", - "org.springframework.boot:spring-boot-starter-jackson", - "org.springframework.boot:spring-boot-starter-tomcat", - "org.springframework.boot:spring-boot-webmvc" - ], - "org.springframework.boot:spring-boot-test": [ - "org.springframework.boot:spring-boot", - "org.springframework:spring-test" - ], - "org.springframework.boot:spring-boot-test-autoconfigure": [ - "org.springframework.boot:spring-boot-test" - ], - "org.springframework.boot:spring-boot-tomcat": [ - "jakarta.annotation:jakarta.annotation-api", - "org.apache.tomcat.embed:tomcat-embed-core", - "org.springframework.boot:spring-boot-web-server" - ], - "org.springframework.boot:spring-boot-web-server": [ - "org.springframework.boot:spring-boot", - "org.springframework:spring-web" - ], - "org.springframework.boot:spring-boot-webmvc": [ - "org.springframework.boot:spring-boot-http-converter", - "org.springframework.boot:spring-boot-servlet", - "org.springframework:spring-web", - "org.springframework:spring-webmvc" - ], - "org.springframework.boot:spring-boot-webmvc-test": [ - "org.springframework.boot:spring-boot-http-converter", - "org.springframework.boot:spring-boot-test-autoconfigure", - "org.springframework.boot:spring-boot-web-server", - "org.springframework.boot:spring-boot-webmvc" - ], - "org.springframework:spring-aop": [ - "org.springframework:spring-beans", - "org.springframework:spring-core" - ], - "org.springframework:spring-beans": [ - "org.springframework:spring-core" - ], - "org.springframework:spring-context": [ - "io.micrometer:micrometer-observation", - "org.springframework:spring-aop", - "org.springframework:spring-beans", - "org.springframework:spring-core", - "org.springframework:spring-expression" - ], - "org.springframework:spring-core": [ - "commons-logging:commons-logging", - "org.jspecify:jspecify" - ], - "org.springframework:spring-expression": [ - "org.springframework:spring-core" - ], - "org.springframework:spring-test": [ - "org.springframework:spring-core" - ], - "org.springframework:spring-web": [ - "io.micrometer:micrometer-observation", - "org.springframework:spring-beans", - "org.springframework:spring-core" - ], - "org.springframework:spring-webmvc": [ - "org.springframework:spring-aop", - "org.springframework:spring-beans", - "org.springframework:spring-context", - "org.springframework:spring-core", - "org.springframework:spring-expression", - "org.springframework:spring-web" - ], - "org.xmlunit:xmlunit-core": [ - "jakarta.xml.bind:jakarta.xml.bind-api" - ], - "tools.jackson.core:jackson-databind": [ - "com.fasterxml.jackson.core:jackson-annotations", - "tools.jackson.core:jackson-core" - ] - }, - "packages": { - "ch.qos.logback:logback-classic": [ - "ch.qos.logback.classic", - "ch.qos.logback.classic.boolex", - "ch.qos.logback.classic.encoder", - "ch.qos.logback.classic.filter", - "ch.qos.logback.classic.helpers", - "ch.qos.logback.classic.html", - "ch.qos.logback.classic.joran", - "ch.qos.logback.classic.joran.action", - "ch.qos.logback.classic.joran.sanity", - "ch.qos.logback.classic.joran.serializedModel", - "ch.qos.logback.classic.jul", - "ch.qos.logback.classic.layout", - "ch.qos.logback.classic.log4j", - "ch.qos.logback.classic.model", - "ch.qos.logback.classic.model.processor", - "ch.qos.logback.classic.model.util", - "ch.qos.logback.classic.net", - "ch.qos.logback.classic.net.server", - "ch.qos.logback.classic.pattern", - "ch.qos.logback.classic.pattern.color", - "ch.qos.logback.classic.selector", - "ch.qos.logback.classic.selector.servlet", - "ch.qos.logback.classic.servlet", - "ch.qos.logback.classic.sift", - "ch.qos.logback.classic.spi", - "ch.qos.logback.classic.turbo", - "ch.qos.logback.classic.tyler", - "ch.qos.logback.classic.util" - ], - "ch.qos.logback:logback-core": [ - "ch.qos.logback.core", - "ch.qos.logback.core.boolex", - "ch.qos.logback.core.encoder", - "ch.qos.logback.core.filter", - "ch.qos.logback.core.helpers", - "ch.qos.logback.core.hook", - "ch.qos.logback.core.html", - "ch.qos.logback.core.joran", - "ch.qos.logback.core.joran.action", - "ch.qos.logback.core.joran.conditional", - "ch.qos.logback.core.joran.event", - "ch.qos.logback.core.joran.sanity", - "ch.qos.logback.core.joran.spi", - "ch.qos.logback.core.joran.util", - "ch.qos.logback.core.joran.util.beans", - "ch.qos.logback.core.layout", - "ch.qos.logback.core.model", - "ch.qos.logback.core.model.conditional", - "ch.qos.logback.core.model.processor", - "ch.qos.logback.core.model.processor.conditional", - "ch.qos.logback.core.model.util", - "ch.qos.logback.core.net", - "ch.qos.logback.core.net.ssl", - "ch.qos.logback.core.pattern", - "ch.qos.logback.core.pattern.color", - "ch.qos.logback.core.pattern.parser", - "ch.qos.logback.core.pattern.util", - "ch.qos.logback.core.property", - "ch.qos.logback.core.read", - "ch.qos.logback.core.recovery", - "ch.qos.logback.core.rolling", - "ch.qos.logback.core.rolling.helper", - "ch.qos.logback.core.sift", - "ch.qos.logback.core.spi", - "ch.qos.logback.core.status", - "ch.qos.logback.core.subst", - "ch.qos.logback.core.testUtil", - "ch.qos.logback.core.util" - ], - "com.fasterxml.jackson.core:jackson-annotations": [ - "com.fasterxml.jackson.annotation" - ], - "com.google.code.findbugs:jsr305": [ - "javax.annotation", - "javax.annotation.concurrent", - "javax.annotation.meta" - ], - "com.google.code.gson:gson": [ - "com.google.gson", - "com.google.gson.annotations", - "com.google.gson.internal", - "com.google.gson.internal.bind", - "com.google.gson.internal.bind.util", - "com.google.gson.internal.reflect", - "com.google.gson.internal.sql", - "com.google.gson.reflect", - "com.google.gson.stream" - ], - "com.google.errorprone:error_prone_annotations": [ - "com.google.errorprone.annotations", - "com.google.errorprone.annotations.concurrent" - ], - "com.google.guava:failureaccess": [ - "com.google.common.util.concurrent.internal" - ], - "com.google.guava:guava": [ - "com.google.common.annotations", - "com.google.common.base", - "com.google.common.base.internal", - "com.google.common.cache", - "com.google.common.collect", - "com.google.common.escape", - "com.google.common.eventbus", - "com.google.common.graph", - "com.google.common.hash", - "com.google.common.html", - "com.google.common.io", - "com.google.common.math", - "com.google.common.net", - "com.google.common.primitives", - "com.google.common.reflect", - "com.google.common.util.concurrent", - "com.google.common.xml", - "com.google.thirdparty.publicsuffix" - ], - "com.google.j2objc:j2objc-annotations": [ - "com.google.j2objc.annotations" - ], - "com.jayway.jsonpath:json-path": [ - "com.jayway.jsonpath", - "com.jayway.jsonpath.internal", - "com.jayway.jsonpath.internal.filter", - "com.jayway.jsonpath.internal.function", - "com.jayway.jsonpath.internal.function.json", - "com.jayway.jsonpath.internal.function.latebinding", - "com.jayway.jsonpath.internal.function.numeric", - "com.jayway.jsonpath.internal.function.sequence", - "com.jayway.jsonpath.internal.function.text", - "com.jayway.jsonpath.internal.path", - "com.jayway.jsonpath.spi.cache", - "com.jayway.jsonpath.spi.json", - "com.jayway.jsonpath.spi.mapper" - ], - "com.vaadin.external.google:android-json": [ - "org.json" - ], - "commons-logging:commons-logging": [ - "org.apache.commons.logging", - "org.apache.commons.logging.impl" - ], - "io.micrometer:micrometer-commons": [ - "io.micrometer.common", - "io.micrometer.common.annotation", - "io.micrometer.common.docs", - "io.micrometer.common.lang", - "io.micrometer.common.lang.internal", - "io.micrometer.common.util", - "io.micrometer.common.util.internal.logging" - ], - "io.micrometer:micrometer-observation": [ - "io.micrometer.observation", - "io.micrometer.observation.annotation", - "io.micrometer.observation.aop", - "io.micrometer.observation.contextpropagation", - "io.micrometer.observation.docs", - "io.micrometer.observation.transport" - ], - "jakarta.activation:jakarta.activation-api": [ - "jakarta.activation", - "jakarta.activation.spi" - ], - "jakarta.annotation:jakarta.annotation-api": [ - "jakarta.annotation", - "jakarta.annotation.security", - "jakarta.annotation.sql" - ], - "jakarta.xml.bind:jakarta.xml.bind-api": [ - "jakarta.xml.bind", - "jakarta.xml.bind.annotation", - "jakarta.xml.bind.annotation.adapters", - "jakarta.xml.bind.attachment", - "jakarta.xml.bind.helpers", - "jakarta.xml.bind.util" - ], - "net.bytebuddy:byte-buddy": [ - "net.bytebuddy", - "net.bytebuddy.agent.builder", - "net.bytebuddy.asm", - "net.bytebuddy.build", - "net.bytebuddy.description", - "net.bytebuddy.description.annotation", - "net.bytebuddy.description.enumeration", - "net.bytebuddy.description.field", - "net.bytebuddy.description.method", - "net.bytebuddy.description.modifier", - "net.bytebuddy.description.type", - "net.bytebuddy.dynamic", - "net.bytebuddy.dynamic.loading", - "net.bytebuddy.dynamic.scaffold", - "net.bytebuddy.dynamic.scaffold.inline", - "net.bytebuddy.dynamic.scaffold.subclass", - "net.bytebuddy.implementation", - "net.bytebuddy.implementation.attribute", - "net.bytebuddy.implementation.auxiliary", - "net.bytebuddy.implementation.bind", - "net.bytebuddy.implementation.bind.annotation", - "net.bytebuddy.implementation.bytecode", - "net.bytebuddy.implementation.bytecode.assign", - "net.bytebuddy.implementation.bytecode.assign.primitive", - "net.bytebuddy.implementation.bytecode.assign.reference", - "net.bytebuddy.implementation.bytecode.collection", - "net.bytebuddy.implementation.bytecode.constant", - "net.bytebuddy.implementation.bytecode.member", - "net.bytebuddy.jar.asm", - "net.bytebuddy.jar.asm.commons", - "net.bytebuddy.jar.asm.signature", - "net.bytebuddy.jar.asmjdkbridge", - "net.bytebuddy.matcher", - "net.bytebuddy.pool", - "net.bytebuddy.utility", - "net.bytebuddy.utility.dispatcher", - "net.bytebuddy.utility.nullability", - "net.bytebuddy.utility.privilege", - "net.bytebuddy.utility.visitor" - ], - "net.bytebuddy:byte-buddy-agent": [ - "net.bytebuddy.agent", - "net.bytebuddy.agent.utility.nullability" - ], - "net.minidev:accessors-smart": [ - "net.minidev.asm", - "net.minidev.asm.ex" - ], - "net.minidev:json-smart": [ - "net.minidev.json", - "net.minidev.json.annotate", - "net.minidev.json.parser", - "net.minidev.json.reader", - "net.minidev.json.writer" - ], - "org.apache.logging.log4j:log4j-api": [ - "org.apache.logging.log4j", - "org.apache.logging.log4j.internal", - "org.apache.logging.log4j.internal.annotation", - "org.apache.logging.log4j.internal.map", - "org.apache.logging.log4j.message", - "org.apache.logging.log4j.simple", - "org.apache.logging.log4j.simple.internal", - "org.apache.logging.log4j.spi", - "org.apache.logging.log4j.status", - "org.apache.logging.log4j.util", - "org.apache.logging.log4j.util.internal" - ], - "org.apache.logging.log4j:log4j-to-slf4j": [ - "org.apache.logging.slf4j" - ], - "org.apache.tomcat.embed:tomcat-embed-core": [ - "jakarta.security.auth.message", - "jakarta.security.auth.message.callback", - "jakarta.security.auth.message.config", - "jakarta.security.auth.message.module", - "jakarta.servlet", - "jakarta.servlet.annotation", - "jakarta.servlet.descriptor", - "jakarta.servlet.http", - "org.apache.catalina", - "org.apache.catalina.authenticator", - "org.apache.catalina.authenticator.jaspic", - "org.apache.catalina.connector", - "org.apache.catalina.core", - "org.apache.catalina.deploy", - "org.apache.catalina.filters", - "org.apache.catalina.loader", - "org.apache.catalina.manager", - "org.apache.catalina.manager.host", - "org.apache.catalina.manager.util", - "org.apache.catalina.mapper", - "org.apache.catalina.mbeans", - "org.apache.catalina.realm", - "org.apache.catalina.security", - "org.apache.catalina.servlets", - "org.apache.catalina.session", - "org.apache.catalina.startup", - "org.apache.catalina.users", - "org.apache.catalina.util", - "org.apache.catalina.valves", - "org.apache.catalina.valves.rewrite", - "org.apache.catalina.webresources", - "org.apache.catalina.webresources.war", - "org.apache.coyote", - "org.apache.coyote.ajp", - "org.apache.coyote.http11", - "org.apache.coyote.http11.filters", - "org.apache.coyote.http11.upgrade", - "org.apache.coyote.http2", - "org.apache.juli", - "org.apache.juli.logging", - "org.apache.naming", - "org.apache.naming.factory", - "org.apache.naming.java", - "org.apache.tomcat", - "org.apache.tomcat.jni", - "org.apache.tomcat.util", - "org.apache.tomcat.util.bcel", - "org.apache.tomcat.util.bcel.classfile", - "org.apache.tomcat.util.buf", - "org.apache.tomcat.util.collections", - "org.apache.tomcat.util.compat", - "org.apache.tomcat.util.concurrent", - "org.apache.tomcat.util.descriptor", - "org.apache.tomcat.util.descriptor.tagplugin", - "org.apache.tomcat.util.descriptor.web", - "org.apache.tomcat.util.digester", - "org.apache.tomcat.util.file", - "org.apache.tomcat.util.http", - "org.apache.tomcat.util.http.fileupload", - "org.apache.tomcat.util.http.fileupload.disk", - "org.apache.tomcat.util.http.fileupload.impl", - "org.apache.tomcat.util.http.fileupload.servlet", - "org.apache.tomcat.util.http.fileupload.util", - "org.apache.tomcat.util.http.fileupload.util.mime", - "org.apache.tomcat.util.http.parser", - "org.apache.tomcat.util.json", - "org.apache.tomcat.util.log", - "org.apache.tomcat.util.modeler", - "org.apache.tomcat.util.modeler.modules", - "org.apache.tomcat.util.net", - "org.apache.tomcat.util.net.jsse", - "org.apache.tomcat.util.net.openssl", - "org.apache.tomcat.util.net.openssl.ciphers", - "org.apache.tomcat.util.res", - "org.apache.tomcat.util.scan", - "org.apache.tomcat.util.security", - "org.apache.tomcat.util.threads" - ], - "org.apache.tomcat.embed:tomcat-embed-el": [ - "jakarta.el", - "org.apache.el", - "org.apache.el.lang", - "org.apache.el.parser", - "org.apache.el.stream", - "org.apache.el.util" - ], - "org.apache.tomcat.embed:tomcat-embed-websocket": [ - "jakarta.websocket", - "jakarta.websocket.server", - "org.apache.tomcat.websocket", - "org.apache.tomcat.websocket.pojo", - "org.apache.tomcat.websocket.server" - ], - "org.apiguardian:apiguardian-api": [ - "org.apiguardian.api" - ], - "org.assertj:assertj-core": [ - "org.assertj.core.annotation", - "org.assertj.core.annotations", - "org.assertj.core.api", - "org.assertj.core.api.exception", - "org.assertj.core.api.filter", - "org.assertj.core.api.iterable", - "org.assertj.core.api.junit.jupiter", - "org.assertj.core.api.recursive", - "org.assertj.core.api.recursive.assertion", - "org.assertj.core.api.recursive.comparison", - "org.assertj.core.condition", - "org.assertj.core.configuration", - "org.assertj.core.data", - "org.assertj.core.description", - "org.assertj.core.error", - "org.assertj.core.error.array2d", - "org.assertj.core.error.future", - "org.assertj.core.error.uri", - "org.assertj.core.extractor", - "org.assertj.core.groups", - "org.assertj.core.internal", - "org.assertj.core.internal.annotation", - "org.assertj.core.matcher", - "org.assertj.core.presentation", - "org.assertj.core.util", - "org.assertj.core.util.diff", - "org.assertj.core.util.diff.myers", - "org.assertj.core.util.introspection", - "org.assertj.core.util.xml" - ], - "org.awaitility:awaitility": [ - "org.awaitility", - "org.awaitility.classpath", - "org.awaitility.constraint", - "org.awaitility.core", - "org.awaitility.pollinterval", - "org.awaitility.reflect", - "org.awaitility.reflect.exception", - "org.awaitility.spi" - ], - "org.checkerframework:checker-qual": [ - "org.checkerframework.checker.builder.qual", - "org.checkerframework.checker.calledmethods.qual", - "org.checkerframework.checker.compilermsgs.qual", - "org.checkerframework.checker.fenum.qual", - "org.checkerframework.checker.formatter.qual", - "org.checkerframework.checker.guieffect.qual", - "org.checkerframework.checker.i18n.qual", - "org.checkerframework.checker.i18nformatter.qual", - "org.checkerframework.checker.index.qual", - "org.checkerframework.checker.initialization.qual", - "org.checkerframework.checker.interning.qual", - "org.checkerframework.checker.lock.qual", - "org.checkerframework.checker.mustcall.qual", - "org.checkerframework.checker.nullness.qual", - "org.checkerframework.checker.optional.qual", - "org.checkerframework.checker.propkey.qual", - "org.checkerframework.checker.regex.qual", - "org.checkerframework.checker.signature.qual", - "org.checkerframework.checker.signedness.qual", - "org.checkerframework.checker.tainting.qual", - "org.checkerframework.checker.units.qual", - "org.checkerframework.common.aliasing.qual", - "org.checkerframework.common.initializedfields.qual", - "org.checkerframework.common.reflection.qual", - "org.checkerframework.common.returnsreceiver.qual", - "org.checkerframework.common.subtyping.qual", - "org.checkerframework.common.util.report.qual", - "org.checkerframework.common.value.qual", - "org.checkerframework.dataflow.qual", - "org.checkerframework.framework.qual" - ], - "org.hamcrest:hamcrest": [ - "org.hamcrest", - "org.hamcrest.beans", - "org.hamcrest.collection", - "org.hamcrest.comparator", - "org.hamcrest.core", - "org.hamcrest.internal", - "org.hamcrest.io", - "org.hamcrest.number", - "org.hamcrest.object", - "org.hamcrest.text", - "org.hamcrest.xml" - ], - "org.jspecify:jspecify": [ - "org.jspecify.annotations" - ], - "org.junit.jupiter:junit-jupiter-api": [ - "org.junit.jupiter.api", - "org.junit.jupiter.api.condition", - "org.junit.jupiter.api.extension", - "org.junit.jupiter.api.extension.support", - "org.junit.jupiter.api.function", - "org.junit.jupiter.api.io", - "org.junit.jupiter.api.parallel", - "org.junit.jupiter.api.util" - ], - "org.junit.jupiter:junit-jupiter-engine": [ - "org.junit.jupiter.engine", - "org.junit.jupiter.engine.config", - "org.junit.jupiter.engine.descriptor", - "org.junit.jupiter.engine.discovery", - "org.junit.jupiter.engine.discovery.predicates", - "org.junit.jupiter.engine.execution", - "org.junit.jupiter.engine.extension", - "org.junit.jupiter.engine.support" - ], - "org.junit.jupiter:junit-jupiter-params": [ - "org.junit.jupiter.params", - "org.junit.jupiter.params.aggregator", - "org.junit.jupiter.params.converter", - "org.junit.jupiter.params.provider", - "org.junit.jupiter.params.shadow.de.siegmar.fastcsv.reader", - "org.junit.jupiter.params.shadow.de.siegmar.fastcsv.util", - "org.junit.jupiter.params.shadow.de.siegmar.fastcsv.writer", - "org.junit.jupiter.params.support" - ], - "org.junit.platform:junit-platform-commons": [ - "org.junit.platform.commons", - "org.junit.platform.commons.annotation", - "org.junit.platform.commons.function", - "org.junit.platform.commons.io", - "org.junit.platform.commons.logging", - "org.junit.platform.commons.support", - "org.junit.platform.commons.support.conversion", - "org.junit.platform.commons.support.scanning", - "org.junit.platform.commons.util" - ], - "org.junit.platform:junit-platform-engine": [ - "org.junit.platform.engine", - "org.junit.platform.engine.discovery", - "org.junit.platform.engine.reporting", - "org.junit.platform.engine.support.config", - "org.junit.platform.engine.support.descriptor", - "org.junit.platform.engine.support.discovery", - "org.junit.platform.engine.support.hierarchical", - "org.junit.platform.engine.support.store" - ], - "org.junit.platform:junit-platform-launcher": [ - "org.junit.platform.launcher", - "org.junit.platform.launcher.core", - "org.junit.platform.launcher.jfr", - "org.junit.platform.launcher.listeners", - "org.junit.platform.launcher.listeners.discovery", - "org.junit.platform.launcher.listeners.session", - "org.junit.platform.launcher.tagexpression" - ], - "org.junit.platform:junit-platform-reporting": [ - "org.junit.platform.reporting", - "org.junit.platform.reporting.legacy", - "org.junit.platform.reporting.legacy.xml", - "org.junit.platform.reporting.open.xml", - "org.junit.platform.reporting.shadow.org.opentest4j.reporting.events.api", - "org.junit.platform.reporting.shadow.org.opentest4j.reporting.events.core", - "org.junit.platform.reporting.shadow.org.opentest4j.reporting.events.git", - "org.junit.platform.reporting.shadow.org.opentest4j.reporting.events.java", - "org.junit.platform.reporting.shadow.org.opentest4j.reporting.events.root", - "org.junit.platform.reporting.shadow.org.opentest4j.reporting.schema" - ], - "org.mockito:mockito-core": [ - "org.mockito", - "org.mockito.configuration", - "org.mockito.creation.instance", - "org.mockito.exceptions.base", - "org.mockito.exceptions.misusing", - "org.mockito.exceptions.stacktrace", - "org.mockito.exceptions.verification", - "org.mockito.exceptions.verification.junit", - "org.mockito.exceptions.verification.opentest4j", - "org.mockito.hamcrest", - "org.mockito.internal", - "org.mockito.internal.configuration", - "org.mockito.internal.configuration.injection", - "org.mockito.internal.configuration.injection.filter", - "org.mockito.internal.configuration.injection.scanner", - "org.mockito.internal.configuration.plugins", - "org.mockito.internal.creation", - "org.mockito.internal.creation.bytebuddy", - "org.mockito.internal.creation.bytebuddy.access", - "org.mockito.internal.creation.bytebuddy.codegen", - "org.mockito.internal.creation.instance", - "org.mockito.internal.creation.proxy", - "org.mockito.internal.creation.settings", - "org.mockito.internal.creation.util", - "org.mockito.internal.debugging", - "org.mockito.internal.exceptions", - "org.mockito.internal.exceptions.stacktrace", - "org.mockito.internal.exceptions.util", - "org.mockito.internal.framework", - "org.mockito.internal.hamcrest", - "org.mockito.internal.handler", - "org.mockito.internal.invocation", - "org.mockito.internal.invocation.finder", - "org.mockito.internal.invocation.mockref", - "org.mockito.internal.junit", - "org.mockito.internal.listeners", - "org.mockito.internal.matchers", - "org.mockito.internal.matchers.apachecommons", - "org.mockito.internal.matchers.text", - "org.mockito.internal.progress", - "org.mockito.internal.reporting", - "org.mockito.internal.runners", - "org.mockito.internal.runners.util", - "org.mockito.internal.session", - "org.mockito.internal.stubbing", - "org.mockito.internal.stubbing.answers", - "org.mockito.internal.stubbing.defaultanswers", - "org.mockito.internal.util", - "org.mockito.internal.util.collections", - "org.mockito.internal.util.concurrent", - "org.mockito.internal.util.io", - "org.mockito.internal.util.reflection", - "org.mockito.internal.verification", - "org.mockito.internal.verification.api", - "org.mockito.internal.verification.argumentmatching", - "org.mockito.internal.verification.checkers", - "org.mockito.invocation", - "org.mockito.junit", - "org.mockito.listeners", - "org.mockito.mock", - "org.mockito.plugins", - "org.mockito.quality", - "org.mockito.session", - "org.mockito.stubbing", - "org.mockito.verification" - ], - "org.mockito:mockito-junit-jupiter": [ - "org.mockito.junit.jupiter", - "org.mockito.junit.jupiter.resolver" - ], - "org.objenesis:objenesis": [ - "org.objenesis", - "org.objenesis.instantiator", - "org.objenesis.instantiator.android", - "org.objenesis.instantiator.annotations", - "org.objenesis.instantiator.basic", - "org.objenesis.instantiator.gcj", - "org.objenesis.instantiator.perc", - "org.objenesis.instantiator.sun", - "org.objenesis.instantiator.util", - "org.objenesis.strategy" - ], - "org.opentest4j.reporting:open-test-reporting-tooling-spi": [ - "org.opentest4j.reporting.tooling.spi.htmlreport" - ], - "org.opentest4j:opentest4j": [ - "org.opentest4j" - ], - "org.ow2.asm:asm": [ - "org.objectweb.asm", - "org.objectweb.asm.signature" - ], - "org.skyscreamer:jsonassert": [ - "org.json", - "org.skyscreamer.jsonassert", - "org.skyscreamer.jsonassert.comparator" - ], - "org.slf4j:jul-to-slf4j": [ - "org.slf4j.bridge" - ], - "org.slf4j:slf4j-api": [ - "org.slf4j", - "org.slf4j.event", - "org.slf4j.helpers", - "org.slf4j.spi" - ], - "org.springframework.boot:spring-boot": [ - "org.springframework.boot", - "org.springframework.boot.admin", - "org.springframework.boot.ansi", - "org.springframework.boot.availability", - "org.springframework.boot.bootstrap", - "org.springframework.boot.builder", - "org.springframework.boot.cloud", - "org.springframework.boot.context", - "org.springframework.boot.context.annotation", - "org.springframework.boot.context.config", - "org.springframework.boot.context.event", - "org.springframework.boot.context.logging", - "org.springframework.boot.context.metrics.buffering", - "org.springframework.boot.context.properties", - "org.springframework.boot.context.properties.bind", - "org.springframework.boot.context.properties.bind.handler", - "org.springframework.boot.context.properties.bind.validation", - "org.springframework.boot.context.properties.source", - "org.springframework.boot.convert", - "org.springframework.boot.diagnostics", - "org.springframework.boot.diagnostics.analyzer", - "org.springframework.boot.env", - "org.springframework.boot.info", - "org.springframework.boot.io", - "org.springframework.boot.json", - "org.springframework.boot.logging", - "org.springframework.boot.logging.java", - "org.springframework.boot.logging.log4j2", - "org.springframework.boot.logging.logback", - "org.springframework.boot.logging.structured", - "org.springframework.boot.origin", - "org.springframework.boot.retry", - "org.springframework.boot.ssl", - "org.springframework.boot.ssl.jks", - "org.springframework.boot.ssl.pem", - "org.springframework.boot.support", - "org.springframework.boot.system", - "org.springframework.boot.task", - "org.springframework.boot.thread", - "org.springframework.boot.util", - "org.springframework.boot.validation", - "org.springframework.boot.validation.beanvalidation", - "org.springframework.boot.web.context.reactive", - "org.springframework.boot.web.context.servlet", - "org.springframework.boot.web.error", - "org.springframework.boot.web.servlet", - "org.springframework.boot.web.servlet.support" - ], - "org.springframework.boot:spring-boot-autoconfigure": [ - "org.springframework.boot.autoconfigure", - "org.springframework.boot.autoconfigure.admin", - "org.springframework.boot.autoconfigure.aop", - "org.springframework.boot.autoconfigure.availability", - "org.springframework.boot.autoconfigure.cache", - "org.springframework.boot.autoconfigure.condition", - "org.springframework.boot.autoconfigure.container", - "org.springframework.boot.autoconfigure.context", - "org.springframework.boot.autoconfigure.data", - "org.springframework.boot.autoconfigure.diagnostics.analyzer", - "org.springframework.boot.autoconfigure.info", - "org.springframework.boot.autoconfigure.jmx", - "org.springframework.boot.autoconfigure.logging", - "org.springframework.boot.autoconfigure.preinitialize", - "org.springframework.boot.autoconfigure.service.connection", - "org.springframework.boot.autoconfigure.ssl", - "org.springframework.boot.autoconfigure.task", - "org.springframework.boot.autoconfigure.template", - "org.springframework.boot.autoconfigure.web", - "org.springframework.boot.autoconfigure.web.format" - ], - "org.springframework.boot:spring-boot-http-converter": [ - "org.springframework.boot.http.converter.autoconfigure" - ], - "org.springframework.boot:spring-boot-jackson": [ - "org.springframework.boot.jackson", - "org.springframework.boot.jackson.autoconfigure" - ], - "org.springframework.boot:spring-boot-servlet": [ - "org.springframework.boot.servlet", - "org.springframework.boot.servlet.actuate.web.exchanges", - "org.springframework.boot.servlet.actuate.web.mappings", - "org.springframework.boot.servlet.autoconfigure", - "org.springframework.boot.servlet.autoconfigure.actuate.web", - "org.springframework.boot.servlet.autoconfigure.actuate.web.exchanges", - "org.springframework.boot.servlet.autoconfigure.actuate.web.mappings", - "org.springframework.boot.servlet.filter" - ], - "org.springframework.boot:spring-boot-test": [ - "org.springframework.boot.test.context", - "org.springframework.boot.test.context.assertj", - "org.springframework.boot.test.context.filter", - "org.springframework.boot.test.context.filter.annotation", - "org.springframework.boot.test.context.runner", - "org.springframework.boot.test.http.client", - "org.springframework.boot.test.http.server", - "org.springframework.boot.test.json", - "org.springframework.boot.test.mock.web", - "org.springframework.boot.test.system", - "org.springframework.boot.test.util", - "org.springframework.boot.test.web.htmlunit", - "org.springframework.boot.test.web.server" - ], - "org.springframework.boot:spring-boot-test-autoconfigure": [ - "org.springframework.boot.test.autoconfigure", - "org.springframework.boot.test.autoconfigure.jdbc", - "org.springframework.boot.test.autoconfigure.json" - ], - "org.springframework.boot:spring-boot-tomcat": [ - "org.springframework.boot.tomcat", - "org.springframework.boot.tomcat.autoconfigure", - "org.springframework.boot.tomcat.autoconfigure.actuate.web.server", - "org.springframework.boot.tomcat.autoconfigure.metrics", - "org.springframework.boot.tomcat.autoconfigure.reactive", - "org.springframework.boot.tomcat.autoconfigure.servlet", - "org.springframework.boot.tomcat.metrics", - "org.springframework.boot.tomcat.reactive", - "org.springframework.boot.tomcat.servlet" - ], - "org.springframework.boot:spring-boot-web-server": [ - "org.springframework.boot.web.server", - "org.springframework.boot.web.server.autoconfigure", - "org.springframework.boot.web.server.autoconfigure.reactive", - "org.springframework.boot.web.server.autoconfigure.servlet", - "org.springframework.boot.web.server.context", - "org.springframework.boot.web.server.reactive", - "org.springframework.boot.web.server.reactive.context", - "org.springframework.boot.web.server.servlet", - "org.springframework.boot.web.server.servlet.context" - ], - "org.springframework.boot:spring-boot-webmvc": [ - "org.springframework.boot.webmvc", - "org.springframework.boot.webmvc.actuate.endpoint.web", - "org.springframework.boot.webmvc.actuate.web.mappings", - "org.springframework.boot.webmvc.autoconfigure", - "org.springframework.boot.webmvc.autoconfigure.actuate.endpoint.web", - "org.springframework.boot.webmvc.autoconfigure.actuate.web", - "org.springframework.boot.webmvc.autoconfigure.actuate.web.mappings", - "org.springframework.boot.webmvc.autoconfigure.error", - "org.springframework.boot.webmvc.error" - ], - "org.springframework.boot:spring-boot-webmvc-test": [ - "org.springframework.boot.webmvc.test.autoconfigure" - ], - "org.springframework:spring-aop": [ - "org.aopalliance", - "org.aopalliance.aop", - "org.aopalliance.intercept", - "org.springframework.aop", - "org.springframework.aop.aspectj", - "org.springframework.aop.aspectj.annotation", - "org.springframework.aop.aspectj.autoproxy", - "org.springframework.aop.config", - "org.springframework.aop.framework", - "org.springframework.aop.framework.adapter", - "org.springframework.aop.framework.autoproxy", - "org.springframework.aop.framework.autoproxy.target", - "org.springframework.aop.interceptor", - "org.springframework.aop.scope", - "org.springframework.aop.support", - "org.springframework.aop.support.annotation", - "org.springframework.aop.target", - "org.springframework.aop.target.dynamic" - ], - "org.springframework:spring-beans": [ - "org.springframework.beans", - "org.springframework.beans.factory", - "org.springframework.beans.factory.annotation", - "org.springframework.beans.factory.aot", - "org.springframework.beans.factory.config", - "org.springframework.beans.factory.groovy", - "org.springframework.beans.factory.parsing", - "org.springframework.beans.factory.serviceloader", - "org.springframework.beans.factory.support", - "org.springframework.beans.factory.wiring", - "org.springframework.beans.factory.xml", - "org.springframework.beans.propertyeditors", - "org.springframework.beans.support" - ], - "org.springframework:spring-context": [ - "org.springframework.cache", - "org.springframework.cache.annotation", - "org.springframework.cache.concurrent", - "org.springframework.cache.config", - "org.springframework.cache.interceptor", - "org.springframework.cache.support", - "org.springframework.context", - "org.springframework.context.annotation", - "org.springframework.context.aot", - "org.springframework.context.config", - "org.springframework.context.event", - "org.springframework.context.expression", - "org.springframework.context.i18n", - "org.springframework.context.index", - "org.springframework.context.support", - "org.springframework.context.weaving", - "org.springframework.ejb.config", - "org.springframework.format", - "org.springframework.format.annotation", - "org.springframework.format.datetime", - "org.springframework.format.datetime.standard", - "org.springframework.format.number", - "org.springframework.format.number.money", - "org.springframework.format.support", - "org.springframework.instrument.classloading", - "org.springframework.instrument.classloading.glassfish", - "org.springframework.instrument.classloading.jboss", - "org.springframework.instrument.classloading.tomcat", - "org.springframework.jmx", - "org.springframework.jmx.access", - "org.springframework.jmx.export", - "org.springframework.jmx.export.annotation", - "org.springframework.jmx.export.assembler", - "org.springframework.jmx.export.metadata", - "org.springframework.jmx.export.naming", - "org.springframework.jmx.export.notification", - "org.springframework.jmx.support", - "org.springframework.jndi", - "org.springframework.jndi.support", - "org.springframework.resilience", - "org.springframework.resilience.annotation", - "org.springframework.resilience.retry", - "org.springframework.scheduling", - "org.springframework.scheduling.annotation", - "org.springframework.scheduling.concurrent", - "org.springframework.scheduling.config", - "org.springframework.scheduling.support", - "org.springframework.scripting", - "org.springframework.scripting.bsh", - "org.springframework.scripting.config", - "org.springframework.scripting.groovy", - "org.springframework.scripting.support", - "org.springframework.stereotype", - "org.springframework.ui", - "org.springframework.validation", - "org.springframework.validation.annotation", - "org.springframework.validation.beanvalidation", - "org.springframework.validation.method", - "org.springframework.validation.support" - ], - "org.springframework:spring-core": [ - "org.springframework.aot", - "org.springframework.aot.generate", - "org.springframework.aot.hint", - "org.springframework.aot.hint.annotation", - "org.springframework.aot.hint.predicate", - "org.springframework.aot.hint.support", - "org.springframework.aot.nativex", - "org.springframework.aot.nativex.feature", - "org.springframework.asm", - "org.springframework.cglib", - "org.springframework.cglib.beans", - "org.springframework.cglib.core", - "org.springframework.cglib.core.internal", - "org.springframework.cglib.proxy", - "org.springframework.cglib.reflect", - "org.springframework.cglib.transform", - "org.springframework.cglib.transform.impl", - "org.springframework.cglib.util", - "org.springframework.core", - "org.springframework.core.annotation", - "org.springframework.core.codec", - "org.springframework.core.convert", - "org.springframework.core.convert.converter", - "org.springframework.core.convert.support", - "org.springframework.core.env", - "org.springframework.core.io", - "org.springframework.core.io.buffer", - "org.springframework.core.io.support", - "org.springframework.core.log", - "org.springframework.core.metrics", - "org.springframework.core.metrics.jfr", - "org.springframework.core.retry", - "org.springframework.core.retry.support", - "org.springframework.core.serializer", - "org.springframework.core.serializer.support", - "org.springframework.core.style", - "org.springframework.core.task", - "org.springframework.core.task.support", - "org.springframework.core.type", - "org.springframework.core.type.classreading", - "org.springframework.core.type.filter", - "org.springframework.javapoet", - "org.springframework.lang", - "org.springframework.objenesis", - "org.springframework.objenesis.instantiator", - "org.springframework.objenesis.instantiator.android", - "org.springframework.objenesis.instantiator.annotations", - "org.springframework.objenesis.instantiator.basic", - "org.springframework.objenesis.instantiator.gcj", - "org.springframework.objenesis.instantiator.perc", - "org.springframework.objenesis.instantiator.sun", - "org.springframework.objenesis.instantiator.util", - "org.springframework.objenesis.strategy", - "org.springframework.util", - "org.springframework.util.backoff", - "org.springframework.util.comparator", - "org.springframework.util.concurrent", - "org.springframework.util.function", - "org.springframework.util.unit", - "org.springframework.util.xml" - ], - "org.springframework:spring-expression": [ - "org.springframework.expression", - "org.springframework.expression.common", - "org.springframework.expression.spel", - "org.springframework.expression.spel.ast", - "org.springframework.expression.spel.standard", - "org.springframework.expression.spel.support" - ], - "org.springframework:spring-test": [ - "org.springframework.mock.env", - "org.springframework.mock.http", - "org.springframework.mock.http.client", - "org.springframework.mock.http.client.reactive", - "org.springframework.mock.http.server.reactive", - "org.springframework.mock.web", - "org.springframework.mock.web.reactive.function.server", - "org.springframework.mock.web.server", - "org.springframework.test.annotation", - "org.springframework.test.context", - "org.springframework.test.context.aot", - "org.springframework.test.context.bean.override", - "org.springframework.test.context.bean.override.convention", - "org.springframework.test.context.bean.override.mockito", - "org.springframework.test.context.cache", - "org.springframework.test.context.event", - "org.springframework.test.context.event.annotation", - "org.springframework.test.context.hint", - "org.springframework.test.context.jdbc", - "org.springframework.test.context.junit.jupiter", - "org.springframework.test.context.junit.jupiter.web", - "org.springframework.test.context.junit4", - "org.springframework.test.context.junit4.rules", - "org.springframework.test.context.junit4.statements", - "org.springframework.test.context.observation", - "org.springframework.test.context.support", - "org.springframework.test.context.testng", - "org.springframework.test.context.transaction", - "org.springframework.test.context.util", - "org.springframework.test.context.web", - "org.springframework.test.context.web.socket", - "org.springframework.test.http", - "org.springframework.test.jdbc", - "org.springframework.test.json", - "org.springframework.test.util", - "org.springframework.test.validation", - "org.springframework.test.web", - "org.springframework.test.web.client", - "org.springframework.test.web.client.match", - "org.springframework.test.web.client.response", - "org.springframework.test.web.reactive.server", - "org.springframework.test.web.reactive.server.assertj", - "org.springframework.test.web.servlet", - "org.springframework.test.web.servlet.assertj", - "org.springframework.test.web.servlet.client", - "org.springframework.test.web.servlet.client.assertj", - "org.springframework.test.web.servlet.htmlunit", - "org.springframework.test.web.servlet.htmlunit.webdriver", - "org.springframework.test.web.servlet.request", - "org.springframework.test.web.servlet.result", - "org.springframework.test.web.servlet.setup", - "org.springframework.test.web.support" - ], - "org.springframework:spring-web": [ - "org.springframework.http", - "org.springframework.http.client", - "org.springframework.http.client.observation", - "org.springframework.http.client.reactive", - "org.springframework.http.client.support", - "org.springframework.http.codec", - "org.springframework.http.codec.cbor", - "org.springframework.http.codec.json", - "org.springframework.http.codec.multipart", - "org.springframework.http.codec.protobuf", - "org.springframework.http.codec.smile", - "org.springframework.http.codec.support", - "org.springframework.http.codec.xml", - "org.springframework.http.converter", - "org.springframework.http.converter.cbor", - "org.springframework.http.converter.feed", - "org.springframework.http.converter.json", - "org.springframework.http.converter.protobuf", - "org.springframework.http.converter.smile", - "org.springframework.http.converter.support", - "org.springframework.http.converter.xml", - "org.springframework.http.converter.yaml", - "org.springframework.http.server", - "org.springframework.http.server.observation", - "org.springframework.http.server.reactive", - "org.springframework.http.server.reactive.observation", - "org.springframework.http.support", - "org.springframework.web", - "org.springframework.web.accept", - "org.springframework.web.bind", - "org.springframework.web.bind.annotation", - "org.springframework.web.bind.support", - "org.springframework.web.client", - "org.springframework.web.client.support", - "org.springframework.web.context", - "org.springframework.web.context.annotation", - "org.springframework.web.context.request", - "org.springframework.web.context.request.async", - "org.springframework.web.context.support", - "org.springframework.web.cors", - "org.springframework.web.cors.reactive", - "org.springframework.web.filter", - "org.springframework.web.filter.reactive", - "org.springframework.web.jsf", - "org.springframework.web.jsf.el", - "org.springframework.web.method", - "org.springframework.web.method.annotation", - "org.springframework.web.method.support", - "org.springframework.web.multipart", - "org.springframework.web.multipart.support", - "org.springframework.web.server", - "org.springframework.web.server.adapter", - "org.springframework.web.server.handler", - "org.springframework.web.server.i18n", - "org.springframework.web.server.session", - "org.springframework.web.service", - "org.springframework.web.service.annotation", - "org.springframework.web.service.invoker", - "org.springframework.web.service.registry", - "org.springframework.web.util", - "org.springframework.web.util.pattern" - ], - "org.springframework:spring-webmvc": [ - "org.springframework.web.servlet", - "org.springframework.web.servlet.config", - "org.springframework.web.servlet.config.annotation", - "org.springframework.web.servlet.function", - "org.springframework.web.servlet.function.support", - "org.springframework.web.servlet.handler", - "org.springframework.web.servlet.i18n", - "org.springframework.web.servlet.mvc", - "org.springframework.web.servlet.mvc.annotation", - "org.springframework.web.servlet.mvc.condition", - "org.springframework.web.servlet.mvc.method", - "org.springframework.web.servlet.mvc.method.annotation", - "org.springframework.web.servlet.mvc.support", - "org.springframework.web.servlet.resource", - "org.springframework.web.servlet.support", - "org.springframework.web.servlet.tags", - "org.springframework.web.servlet.tags.form", - "org.springframework.web.servlet.view", - "org.springframework.web.servlet.view.document", - "org.springframework.web.servlet.view.feed", - "org.springframework.web.servlet.view.freemarker", - "org.springframework.web.servlet.view.groovy", - "org.springframework.web.servlet.view.json", - "org.springframework.web.servlet.view.script", - "org.springframework.web.servlet.view.xml", - "org.springframework.web.servlet.view.xslt" - ], - "org.xmlunit:xmlunit-core": [ - "org.xmlunit", - "org.xmlunit.builder", - "org.xmlunit.builder.javax_jaxb", - "org.xmlunit.diff", - "org.xmlunit.input", - "org.xmlunit.transform", - "org.xmlunit.util", - "org.xmlunit.validation", - "org.xmlunit.xpath" - ], - "org.yaml:snakeyaml": [ - "org.yaml.snakeyaml", - "org.yaml.snakeyaml.comments", - "org.yaml.snakeyaml.composer", - "org.yaml.snakeyaml.constructor", - "org.yaml.snakeyaml.emitter", - "org.yaml.snakeyaml.env", - "org.yaml.snakeyaml.error", - "org.yaml.snakeyaml.events", - "org.yaml.snakeyaml.extensions.compactnotation", - "org.yaml.snakeyaml.external.com.google.gdata.util.common.base", - "org.yaml.snakeyaml.inspector", - "org.yaml.snakeyaml.internal", - "org.yaml.snakeyaml.introspector", - "org.yaml.snakeyaml.nodes", - "org.yaml.snakeyaml.parser", - "org.yaml.snakeyaml.reader", - "org.yaml.snakeyaml.representer", - "org.yaml.snakeyaml.resolver", - "org.yaml.snakeyaml.scanner", - "org.yaml.snakeyaml.serializer", - "org.yaml.snakeyaml.tokens", - "org.yaml.snakeyaml.util" - ], - "tools.jackson.core:jackson-core": [ - "tools.jackson.core", - "tools.jackson.core.async", - "tools.jackson.core.base", - "tools.jackson.core.exc", - "tools.jackson.core.filter", - "tools.jackson.core.internal.shaded.fdp", - "tools.jackson.core.internal.shaded.fdp.bte", - "tools.jackson.core.internal.shaded.fdp.chr", - "tools.jackson.core.io", - "tools.jackson.core.io.schubfach", - "tools.jackson.core.json", - "tools.jackson.core.json.async", - "tools.jackson.core.sym", - "tools.jackson.core.tree", - "tools.jackson.core.type", - "tools.jackson.core.util" - ], - "tools.jackson.core:jackson-databind": [ - "tools.jackson.databind", - "tools.jackson.databind.annotation", - "tools.jackson.databind.cfg", - "tools.jackson.databind.deser", - "tools.jackson.databind.deser.bean", - "tools.jackson.databind.deser.impl", - "tools.jackson.databind.deser.jackson", - "tools.jackson.databind.deser.jdk", - "tools.jackson.databind.deser.std", - "tools.jackson.databind.exc", - "tools.jackson.databind.ext", - "tools.jackson.databind.ext.beans", - "tools.jackson.databind.ext.javatime", - "tools.jackson.databind.ext.javatime.deser", - "tools.jackson.databind.ext.javatime.deser.key", - "tools.jackson.databind.ext.javatime.ser", - "tools.jackson.databind.ext.javatime.ser.key", - "tools.jackson.databind.ext.javatime.util", - "tools.jackson.databind.ext.jdk8", - "tools.jackson.databind.ext.sql", - "tools.jackson.databind.introspect", - "tools.jackson.databind.json", - "tools.jackson.databind.jsonFormatVisitors", - "tools.jackson.databind.jsontype", - "tools.jackson.databind.jsontype.impl", - "tools.jackson.databind.module", - "tools.jackson.databind.node", - "tools.jackson.databind.ser", - "tools.jackson.databind.ser.bean", - "tools.jackson.databind.ser.impl", - "tools.jackson.databind.ser.jackson", - "tools.jackson.databind.ser.jdk", - "tools.jackson.databind.ser.std", - "tools.jackson.databind.type", - "tools.jackson.databind.util", - "tools.jackson.databind.util.internal" - ] - }, - "repositories": { - "https://maven-central.storage-download.googleapis.com/maven2/": [ - "ch.qos.logback:logback-classic", - "ch.qos.logback:logback-classic:jar:sources", - "ch.qos.logback:logback-core", - "ch.qos.logback:logback-core:jar:sources", - "com.fasterxml.jackson.core:jackson-annotations", - "com.fasterxml.jackson.core:jackson-annotations:jar:sources", - "com.google.code.findbugs:jsr305", - "com.google.code.findbugs:jsr305:jar:sources", - "com.google.code.gson:gson", - "com.google.code.gson:gson:jar:sources", - "com.google.errorprone:error_prone_annotations", - "com.google.errorprone:error_prone_annotations:jar:sources", - "com.google.guava:failureaccess", - "com.google.guava:failureaccess:jar:sources", - "com.google.guava:guava", - "com.google.guava:guava:jar:sources", - "com.google.guava:listenablefuture", - "com.google.j2objc:j2objc-annotations", - "com.google.j2objc:j2objc-annotations:jar:sources", - "com.jayway.jsonpath:json-path", - "com.jayway.jsonpath:json-path:jar:sources", - "com.vaadin.external.google:android-json", - "com.vaadin.external.google:android-json:jar:sources", - "commons-logging:commons-logging", - "commons-logging:commons-logging:jar:sources", - "io.micrometer:micrometer-commons", - "io.micrometer:micrometer-commons:jar:sources", - "io.micrometer:micrometer-observation", - "io.micrometer:micrometer-observation:jar:sources", - "jakarta.activation:jakarta.activation-api", - "jakarta.activation:jakarta.activation-api:jar:sources", - "jakarta.annotation:jakarta.annotation-api", - "jakarta.annotation:jakarta.annotation-api:jar:sources", - "jakarta.xml.bind:jakarta.xml.bind-api", - "jakarta.xml.bind:jakarta.xml.bind-api:jar:sources", - "net.bytebuddy:byte-buddy", - "net.bytebuddy:byte-buddy-agent", - "net.bytebuddy:byte-buddy-agent:jar:sources", - "net.bytebuddy:byte-buddy:jar:sources", - "net.minidev:accessors-smart", - "net.minidev:accessors-smart:jar:sources", - "net.minidev:json-smart", - "net.minidev:json-smart:jar:sources", - "org.apache.logging.log4j:log4j-api", - "org.apache.logging.log4j:log4j-api:jar:sources", - "org.apache.logging.log4j:log4j-to-slf4j", - "org.apache.logging.log4j:log4j-to-slf4j:jar:sources", - "org.apache.tomcat.embed:tomcat-embed-core", - "org.apache.tomcat.embed:tomcat-embed-core:jar:sources", - "org.apache.tomcat.embed:tomcat-embed-el", - "org.apache.tomcat.embed:tomcat-embed-el:jar:sources", - "org.apache.tomcat.embed:tomcat-embed-websocket", - "org.apache.tomcat.embed:tomcat-embed-websocket:jar:sources", - "org.apiguardian:apiguardian-api", - "org.apiguardian:apiguardian-api:jar:sources", - "org.assertj:assertj-core", - "org.assertj:assertj-core:jar:sources", - "org.awaitility:awaitility", - "org.awaitility:awaitility:jar:sources", - "org.checkerframework:checker-qual", - "org.checkerframework:checker-qual:jar:sources", - "org.hamcrest:hamcrest", - "org.hamcrest:hamcrest:jar:sources", - "org.jspecify:jspecify", - "org.jspecify:jspecify:jar:sources", - "org.junit.jupiter:junit-jupiter", - "org.junit.jupiter:junit-jupiter-api", - "org.junit.jupiter:junit-jupiter-api:jar:sources", - "org.junit.jupiter:junit-jupiter-engine", - "org.junit.jupiter:junit-jupiter-engine:jar:sources", - "org.junit.jupiter:junit-jupiter-params", - "org.junit.jupiter:junit-jupiter-params:jar:sources", - "org.junit.jupiter:junit-jupiter:jar:sources", - "org.junit.platform:junit-platform-commons", - "org.junit.platform:junit-platform-commons:jar:sources", - "org.junit.platform:junit-platform-engine", - "org.junit.platform:junit-platform-engine:jar:sources", - "org.junit.platform:junit-platform-launcher", - "org.junit.platform:junit-platform-launcher:jar:sources", - "org.junit.platform:junit-platform-reporting", - "org.junit.platform:junit-platform-reporting:jar:sources", - "org.mockito:mockito-core", - "org.mockito:mockito-core:jar:sources", - "org.mockito:mockito-junit-jupiter", - "org.mockito:mockito-junit-jupiter:jar:sources", - "org.objenesis:objenesis", - "org.objenesis:objenesis:jar:sources", - "org.opentest4j.reporting:open-test-reporting-tooling-spi", - "org.opentest4j.reporting:open-test-reporting-tooling-spi:jar:sources", - "org.opentest4j:opentest4j", - "org.opentest4j:opentest4j:jar:sources", - "org.ow2.asm:asm", - "org.ow2.asm:asm:jar:sources", - "org.skyscreamer:jsonassert", - "org.skyscreamer:jsonassert:jar:sources", - "org.slf4j:jul-to-slf4j", - "org.slf4j:jul-to-slf4j:jar:sources", - "org.slf4j:slf4j-api", - "org.slf4j:slf4j-api:jar:sources", - "org.springframework.boot:spring-boot", - "org.springframework.boot:spring-boot-autoconfigure", - "org.springframework.boot:spring-boot-autoconfigure:jar:sources", - "org.springframework.boot:spring-boot-http-converter", - "org.springframework.boot:spring-boot-http-converter:jar:sources", - "org.springframework.boot:spring-boot-jackson", - "org.springframework.boot:spring-boot-jackson:jar:sources", - "org.springframework.boot:spring-boot-servlet", - "org.springframework.boot:spring-boot-servlet:jar:sources", - "org.springframework.boot:spring-boot-starter", - "org.springframework.boot:spring-boot-starter-jackson", - "org.springframework.boot:spring-boot-starter-jackson:jar:sources", - "org.springframework.boot:spring-boot-starter-logging", - "org.springframework.boot:spring-boot-starter-logging:jar:sources", - "org.springframework.boot:spring-boot-starter-test", - "org.springframework.boot:spring-boot-starter-test:jar:sources", - "org.springframework.boot:spring-boot-starter-tomcat", - "org.springframework.boot:spring-boot-starter-tomcat-runtime", - "org.springframework.boot:spring-boot-starter-tomcat-runtime:jar:sources", - "org.springframework.boot:spring-boot-starter-tomcat:jar:sources", - "org.springframework.boot:spring-boot-starter-web", - "org.springframework.boot:spring-boot-starter-web:jar:sources", - "org.springframework.boot:spring-boot-starter:jar:sources", - "org.springframework.boot:spring-boot-test", - "org.springframework.boot:spring-boot-test-autoconfigure", - "org.springframework.boot:spring-boot-test-autoconfigure:jar:sources", - "org.springframework.boot:spring-boot-test:jar:sources", - "org.springframework.boot:spring-boot-tomcat", - "org.springframework.boot:spring-boot-tomcat:jar:sources", - "org.springframework.boot:spring-boot-web-server", - "org.springframework.boot:spring-boot-web-server:jar:sources", - "org.springframework.boot:spring-boot-webmvc", - "org.springframework.boot:spring-boot-webmvc-test", - "org.springframework.boot:spring-boot-webmvc-test:jar:sources", - "org.springframework.boot:spring-boot-webmvc:jar:sources", - "org.springframework.boot:spring-boot:jar:sources", - "org.springframework:spring-aop", - "org.springframework:spring-aop:jar:sources", - "org.springframework:spring-beans", - "org.springframework:spring-beans:jar:sources", - "org.springframework:spring-context", - "org.springframework:spring-context:jar:sources", - "org.springframework:spring-core", - "org.springframework:spring-core:jar:sources", - "org.springframework:spring-expression", - "org.springframework:spring-expression:jar:sources", - "org.springframework:spring-test", - "org.springframework:spring-test:jar:sources", - "org.springframework:spring-web", - "org.springframework:spring-web:jar:sources", - "org.springframework:spring-webmvc", - "org.springframework:spring-webmvc:jar:sources", - "org.xmlunit:xmlunit-core", - "org.xmlunit:xmlunit-core:jar:sources", - "org.yaml:snakeyaml", - "org.yaml:snakeyaml:jar:sources", - "tools.jackson.core:jackson-core", - "tools.jackson.core:jackson-core:jar:sources", - "tools.jackson.core:jackson-databind", - "tools.jackson.core:jackson-databind:jar:sources" - ], - "https://repo.maven.apache.org/maven2/": [ - "ch.qos.logback:logback-classic", - "ch.qos.logback:logback-classic:jar:sources", - "ch.qos.logback:logback-core", - "ch.qos.logback:logback-core:jar:sources", - "com.fasterxml.jackson.core:jackson-annotations", - "com.fasterxml.jackson.core:jackson-annotations:jar:sources", - "com.google.code.findbugs:jsr305", - "com.google.code.findbugs:jsr305:jar:sources", - "com.google.code.gson:gson", - "com.google.code.gson:gson:jar:sources", - "com.google.errorprone:error_prone_annotations", - "com.google.errorprone:error_prone_annotations:jar:sources", - "com.google.guava:failureaccess", - "com.google.guava:failureaccess:jar:sources", - "com.google.guava:guava", - "com.google.guava:guava:jar:sources", - "com.google.guava:listenablefuture", - "com.google.j2objc:j2objc-annotations", - "com.google.j2objc:j2objc-annotations:jar:sources", - "com.jayway.jsonpath:json-path", - "com.jayway.jsonpath:json-path:jar:sources", - "com.vaadin.external.google:android-json", - "com.vaadin.external.google:android-json:jar:sources", - "commons-logging:commons-logging", - "commons-logging:commons-logging:jar:sources", - "io.micrometer:micrometer-commons", - "io.micrometer:micrometer-commons:jar:sources", - "io.micrometer:micrometer-observation", - "io.micrometer:micrometer-observation:jar:sources", - "jakarta.activation:jakarta.activation-api", - "jakarta.activation:jakarta.activation-api:jar:sources", - "jakarta.annotation:jakarta.annotation-api", - "jakarta.annotation:jakarta.annotation-api:jar:sources", - "jakarta.xml.bind:jakarta.xml.bind-api", - "jakarta.xml.bind:jakarta.xml.bind-api:jar:sources", - "net.bytebuddy:byte-buddy", - "net.bytebuddy:byte-buddy-agent", - "net.bytebuddy:byte-buddy-agent:jar:sources", - "net.bytebuddy:byte-buddy:jar:sources", - "net.minidev:accessors-smart", - "net.minidev:accessors-smart:jar:sources", - "net.minidev:json-smart", - "net.minidev:json-smart:jar:sources", - "org.apache.logging.log4j:log4j-api", - "org.apache.logging.log4j:log4j-api:jar:sources", - "org.apache.logging.log4j:log4j-to-slf4j", - "org.apache.logging.log4j:log4j-to-slf4j:jar:sources", - "org.apache.tomcat.embed:tomcat-embed-core", - "org.apache.tomcat.embed:tomcat-embed-core:jar:sources", - "org.apache.tomcat.embed:tomcat-embed-el", - "org.apache.tomcat.embed:tomcat-embed-el:jar:sources", - "org.apache.tomcat.embed:tomcat-embed-websocket", - "org.apache.tomcat.embed:tomcat-embed-websocket:jar:sources", - "org.apiguardian:apiguardian-api", - "org.apiguardian:apiguardian-api:jar:sources", - "org.assertj:assertj-core", - "org.assertj:assertj-core:jar:sources", - "org.awaitility:awaitility", - "org.awaitility:awaitility:jar:sources", - "org.checkerframework:checker-qual", - "org.checkerframework:checker-qual:jar:sources", - "org.hamcrest:hamcrest", - "org.hamcrest:hamcrest:jar:sources", - "org.jspecify:jspecify", - "org.jspecify:jspecify:jar:sources", - "org.junit.jupiter:junit-jupiter", - "org.junit.jupiter:junit-jupiter-api", - "org.junit.jupiter:junit-jupiter-api:jar:sources", - "org.junit.jupiter:junit-jupiter-engine", - "org.junit.jupiter:junit-jupiter-engine:jar:sources", - "org.junit.jupiter:junit-jupiter-params", - "org.junit.jupiter:junit-jupiter-params:jar:sources", - "org.junit.jupiter:junit-jupiter:jar:sources", - "org.junit.platform:junit-platform-commons", - "org.junit.platform:junit-platform-commons:jar:sources", - "org.junit.platform:junit-platform-engine", - "org.junit.platform:junit-platform-engine:jar:sources", - "org.junit.platform:junit-platform-launcher", - "org.junit.platform:junit-platform-launcher:jar:sources", - "org.junit.platform:junit-platform-reporting", - "org.junit.platform:junit-platform-reporting:jar:sources", - "org.mockito:mockito-core", - "org.mockito:mockito-core:jar:sources", - "org.mockito:mockito-junit-jupiter", - "org.mockito:mockito-junit-jupiter:jar:sources", - "org.objenesis:objenesis", - "org.objenesis:objenesis:jar:sources", - "org.opentest4j.reporting:open-test-reporting-tooling-spi", - "org.opentest4j.reporting:open-test-reporting-tooling-spi:jar:sources", - "org.opentest4j:opentest4j", - "org.opentest4j:opentest4j:jar:sources", - "org.ow2.asm:asm", - "org.ow2.asm:asm:jar:sources", - "org.skyscreamer:jsonassert", - "org.skyscreamer:jsonassert:jar:sources", - "org.slf4j:jul-to-slf4j", - "org.slf4j:jul-to-slf4j:jar:sources", - "org.slf4j:slf4j-api", - "org.slf4j:slf4j-api:jar:sources", - "org.springframework.boot:spring-boot", - "org.springframework.boot:spring-boot-autoconfigure", - "org.springframework.boot:spring-boot-autoconfigure:jar:sources", - "org.springframework.boot:spring-boot-http-converter", - "org.springframework.boot:spring-boot-http-converter:jar:sources", - "org.springframework.boot:spring-boot-jackson", - "org.springframework.boot:spring-boot-jackson:jar:sources", - "org.springframework.boot:spring-boot-servlet", - "org.springframework.boot:spring-boot-servlet:jar:sources", - "org.springframework.boot:spring-boot-starter", - "org.springframework.boot:spring-boot-starter-jackson", - "org.springframework.boot:spring-boot-starter-jackson:jar:sources", - "org.springframework.boot:spring-boot-starter-logging", - "org.springframework.boot:spring-boot-starter-logging:jar:sources", - "org.springframework.boot:spring-boot-starter-test", - "org.springframework.boot:spring-boot-starter-test:jar:sources", - "org.springframework.boot:spring-boot-starter-tomcat", - "org.springframework.boot:spring-boot-starter-tomcat-runtime", - "org.springframework.boot:spring-boot-starter-tomcat-runtime:jar:sources", - "org.springframework.boot:spring-boot-starter-tomcat:jar:sources", - "org.springframework.boot:spring-boot-starter-web", - "org.springframework.boot:spring-boot-starter-web:jar:sources", - "org.springframework.boot:spring-boot-starter:jar:sources", - "org.springframework.boot:spring-boot-test", - "org.springframework.boot:spring-boot-test-autoconfigure", - "org.springframework.boot:spring-boot-test-autoconfigure:jar:sources", - "org.springframework.boot:spring-boot-test:jar:sources", - "org.springframework.boot:spring-boot-tomcat", - "org.springframework.boot:spring-boot-tomcat:jar:sources", - "org.springframework.boot:spring-boot-web-server", - "org.springframework.boot:spring-boot-web-server:jar:sources", - "org.springframework.boot:spring-boot-webmvc", - "org.springframework.boot:spring-boot-webmvc-test", - "org.springframework.boot:spring-boot-webmvc-test:jar:sources", - "org.springframework.boot:spring-boot-webmvc:jar:sources", - "org.springframework.boot:spring-boot:jar:sources", - "org.springframework:spring-aop", - "org.springframework:spring-aop:jar:sources", - "org.springframework:spring-beans", - "org.springframework:spring-beans:jar:sources", - "org.springframework:spring-context", - "org.springframework:spring-context:jar:sources", - "org.springframework:spring-core", - "org.springframework:spring-core:jar:sources", - "org.springframework:spring-expression", - "org.springframework:spring-expression:jar:sources", - "org.springframework:spring-test", - "org.springframework:spring-test:jar:sources", - "org.springframework:spring-web", - "org.springframework:spring-web:jar:sources", - "org.springframework:spring-webmvc", - "org.springframework:spring-webmvc:jar:sources", - "org.xmlunit:xmlunit-core", - "org.xmlunit:xmlunit-core:jar:sources", - "org.yaml:snakeyaml", - "org.yaml:snakeyaml:jar:sources", - "tools.jackson.core:jackson-core", - "tools.jackson.core:jackson-core:jar:sources", - "tools.jackson.core:jackson-databind", - "tools.jackson.core:jackson-databind:jar:sources" - ] - }, - "services": { - "ch.qos.logback:logback-classic": { - "jakarta.servlet.ServletContainerInitializer": [ - "ch.qos.logback.classic.servlet.LogbackServletContainerInitializer" - ], - "org.slf4j.spi.SLF4JServiceProvider": [ - "ch.qos.logback.classic.spi.LogbackServiceProvider" - ] - }, - "io.micrometer:micrometer-observation": { - "io.micrometer.context.ThreadLocalAccessor": [ - "io.micrometer.observation.contextpropagation.ObservationThreadLocalAccessor" - ] - }, - "org.apache.logging.log4j:log4j-api": { - "org.apache.logging.log4j.util.PropertySource": [ - "org.apache.logging.log4j.util.EnvironmentPropertySource", - "org.apache.logging.log4j.util.SystemPropertiesPropertySource" - ] - }, - "org.apache.logging.log4j:log4j-to-slf4j": { - "org.apache.logging.log4j.spi.Provider": [ - "org.apache.logging.slf4j.SLF4JProvider" - ] - }, - "org.apache.tomcat.embed:tomcat-embed-el": { - "jakarta.el.ExpressionFactory": [ - "org.apache.el.ExpressionFactoryImpl" - ] - }, - "org.apache.tomcat.embed:tomcat-embed-websocket": { - "jakarta.servlet.ServletContainerInitializer": [ - "org.apache.tomcat.websocket.server.WsSci" - ], - "jakarta.websocket.ContainerProvider": [ - "org.apache.tomcat.websocket.WsContainerProvider" - ], - "jakarta.websocket.server.ServerEndpointConfig$Configurator": [ - "org.apache.tomcat.websocket.server.DefaultServerEndpointConfigurator" - ] - }, - "org.junit.jupiter:junit-jupiter-engine": { - "org.junit.platform.engine.TestEngine": [ - "org.junit.jupiter.engine.JupiterTestEngine" - ] - }, - "org.junit.platform:junit-platform-engine": { - "org.junit.platform.engine.discovery.DiscoverySelectorIdentifierParser": [ - "org.junit.platform.engine.discovery.ClassSelector$IdentifierParser", - "org.junit.platform.engine.discovery.ClasspathResourceSelector$IdentifierParser", - "org.junit.platform.engine.discovery.ClasspathRootSelector$IdentifierParser", - "org.junit.platform.engine.discovery.DirectorySelector$IdentifierParser", - "org.junit.platform.engine.discovery.FileSelector$IdentifierParser", - "org.junit.platform.engine.discovery.IterationSelector$IdentifierParser", - "org.junit.platform.engine.discovery.MethodSelector$IdentifierParser", - "org.junit.platform.engine.discovery.ModuleSelector$IdentifierParser", - "org.junit.platform.engine.discovery.NestedClassSelector$IdentifierParser", - "org.junit.platform.engine.discovery.NestedMethodSelector$IdentifierParser", - "org.junit.platform.engine.discovery.PackageSelector$IdentifierParser", - "org.junit.platform.engine.discovery.UniqueIdSelector$IdentifierParser", - "org.junit.platform.engine.discovery.UriSelector$IdentifierParser" - ] - }, - "org.junit.platform:junit-platform-launcher": { - "org.junit.platform.launcher.TestExecutionListener": [ - "org.junit.platform.launcher.listeners.UniqueIdTrackingListener" - ] - }, - "org.junit.platform:junit-platform-reporting": { - "org.junit.platform.launcher.TestExecutionListener": [ - "org.junit.platform.reporting.open.xml.OpenTestReportGeneratingListener" - ], - "org.opentest4j.reporting.tooling.spi.htmlreport.Contributor": [ - "org.junit.platform.reporting.open.xml.JUnitContributor" - ] - }, - "org.springframework.boot:spring-boot": { - "ch.qos.logback.classic.spi.Configurator": [ - "org.springframework.boot.logging.logback.RootLogLevelConfigurator" - ], - "org.apache.logging.log4j.util.PropertySource": [ - "org.springframework.boot.logging.log4j2.SpringBootPropertySource" - ] - }, - "org.springframework:spring-core": { - "reactor.blockhound.integration.BlockHoundIntegration": [ - "org.springframework.core.ReactiveAdapterRegistry$SpringCoreBlockHoundIntegration" - ] - }, - "org.springframework:spring-web": { - "jakarta.servlet.ServletContainerInitializer": [ - "org.springframework.web.SpringServletContainerInitializer" - ], - "reactor.blockhound.integration.BlockHoundIntegration": [ - "org.springframework.web.server.adapter.WebHttpHandlerBuilder$SpringWebBlockHoundIntegration" - ] - }, - "tools.jackson.core:jackson-core": { - "tools.jackson.core.TokenStreamFactory": [ - "tools.jackson.core.json.JsonFactory" - ] - }, - "tools.jackson.core:jackson-databind": { - "tools.jackson.databind.ObjectMapper": [ - "tools.jackson.databind.json.JsonMapper" - ] - } - }, - "skipped": [], - "version": "3" -} diff --git a/examples/java-spring-boot-service/src/main/java/com/nvidia/nvcf/example/ExampleApplication.java b/examples/java-spring-boot-service/src/main/java/com/nvidia/nvcf/example/ExampleApplication.java deleted file mode 100644 index 2baf0ec7f..000000000 --- a/examples/java-spring-boot-service/src/main/java/com/nvidia/nvcf/example/ExampleApplication.java +++ /dev/null @@ -1,27 +0,0 @@ -// SPDX-FileCopyrightText: Copyright (c) NVIDIA CORPORATION & AFFILIATES. All rights reserved. -// SPDX-License-Identifier: Apache-2.0 -// -// 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.nvidia.nvcf.example; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; - -/** Minimal Spring Boot service used to exercise the Java-on-Bazel foundation. */ -@SpringBootApplication -public class ExampleApplication { - public static void main(String[] args) { - SpringApplication.run(ExampleApplication.class, args); - } -} diff --git a/examples/java-spring-boot-service/src/main/java/com/nvidia/nvcf/example/HelloController.java b/examples/java-spring-boot-service/src/main/java/com/nvidia/nvcf/example/HelloController.java deleted file mode 100644 index cca333ac5..000000000 --- a/examples/java-spring-boot-service/src/main/java/com/nvidia/nvcf/example/HelloController.java +++ /dev/null @@ -1,33 +0,0 @@ -// SPDX-FileCopyrightText: Copyright (c) NVIDIA CORPORATION & AFFILIATES. All rights reserved. -// SPDX-License-Identifier: Apache-2.0 -// -// 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.nvidia.nvcf.example; - -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RestController; - -/** Trivial REST endpoint so the service exercises Spring Boot auto-configuration. */ -@RestController -public class HelloController { - - @GetMapping("/hello") - public String hello() { - return greeting("world"); - } - - static String greeting(String name) { - return "Hello, " + name + "!"; - } -} diff --git a/examples/java-spring-boot-service/src/test/java/com/nvidia/nvcf/example/HelloControllerTest.java b/examples/java-spring-boot-service/src/test/java/com/nvidia/nvcf/example/HelloControllerTest.java deleted file mode 100644 index ad3aad325..000000000 --- a/examples/java-spring-boot-service/src/test/java/com/nvidia/nvcf/example/HelloControllerTest.java +++ /dev/null @@ -1,28 +0,0 @@ -// SPDX-FileCopyrightText: Copyright (c) NVIDIA CORPORATION & AFFILIATES. All rights reserved. -// SPDX-License-Identifier: Apache-2.0 -// -// 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.nvidia.nvcf.example; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -import org.junit.jupiter.api.Test; - -class HelloControllerTest { - - @Test - void greetingFormatsName() { - assertEquals("Hello, world!", HelloController.greeting("world")); - } -} diff --git a/examples/java-spring-boot-service/src/test/java/com/nvidia/nvcf/example/HelloControllerWebTest.java b/examples/java-spring-boot-service/src/test/java/com/nvidia/nvcf/example/HelloControllerWebTest.java deleted file mode 100644 index fbad34578..000000000 --- a/examples/java-spring-boot-service/src/test/java/com/nvidia/nvcf/example/HelloControllerWebTest.java +++ /dev/null @@ -1,50 +0,0 @@ -// SPDX-FileCopyrightText: Copyright (c) NVIDIA CORPORATION & AFFILIATES. All rights reserved. -// SPDX-License-Identifier: Apache-2.0 -// -// 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.nvidia.nvcf.example; - -import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; -import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; - -import org.junit.jupiter.api.Test; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.test.web.servlet.MockMvc; - -/** - * Boots the full Spring application context and exercises the /hello endpoint through MockMvc. - * - * <p>This is the test that validates the exploded-classpath packaging design: starting the context - * forces Spring to read each dependency jar's META-INF/spring.factories and - * META-INF/spring/*.AutoConfiguration.imports. If the classpath were assembled so that those - * same-path resources collided (as a fat/singlejar would), auto-configuration would be dropped and - * this test would fail. The plain JUnit unit test in HelloControllerTest cannot catch that. - */ -@SpringBootTest -@AutoConfigureMockMvc -class HelloControllerWebTest { - - @Autowired private MockMvc mockMvc; - - @Test - void helloEndpointServesGreeting() throws Exception { - mockMvc - .perform(get("/hello")) - .andExpect(status().isOk()) - .andExpect(content().string("Hello, world!")); - } -} diff --git a/rules/java/.bazelrc b/rules/java/.bazelrc deleted file mode 100644 index 38ab37cda..000000000 --- a/rules/java/.bazelrc +++ /dev/null @@ -1,47 +0,0 @@ -# SPDX-FileCopyrightText: Copyright (c) NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# 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. - -# Standalone module .bazelrc. `cd rules/java && bazel build //...` must work with -# no reference to the repo root. The caller supplies any remote cache endpoint; -# no cache config is baked in (parity with the other nested modules). - -common --enable_bzlmod -common --enable_platform_specific_config -build --incompatible_strict_action_env - -# Route public Maven Central through an internal Artifactory mirror on internal -# builds only. The target host lives in an un-mirrored internal bazelrc, so -# public builds go straight to Maven Central (try-import is a no-op when absent). -try-import %workspace%/tools/bazel/internal.bazelrc - -# Java: use the image-provided local JDK 25 (Temurin at JAVA_HOME) instead of a -# hermetic remotejdk download; the bazel-ci image ships Temurin 25 (no download). -build --java_language_version=25 -build --java_runtime_version=local_jdk -build --tool_java_language_version=25 -build --tool_java_runtime_version=local_jdk -build --java_header_compilation=false - -test --test_output=errors -test --test_env=HOME=/tmp -test --test_env=XDG_CACHE_HOME=/tmp/.cache - -startup --host_jvm_args=-Xmx4g - -build:release --compilation_mode=opt -build:release --strip=always - -try-import %workspace%/user.bazelrc -try-import %user.home%/.bazelrc.user diff --git a/rules/java/.gitignore b/rules/java/.gitignore deleted file mode 100644 index a6ef824c1..000000000 --- a/rules/java/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/bazel-* diff --git a/rules/java/AGENTS.md b/rules/java/AGENTS.md deleted file mode 100644 index 7b8c5f23b..000000000 --- a/rules/java/AGENTS.md +++ /dev/null @@ -1,47 +0,0 @@ -# AGENTS.md - nvcf_java_rules - -Standalone Bazel module (`module(name = "nvcf_java_rules")`) holding the shared -Java build macros and platform constants for every NVCF Java module. No -application code lives here. - -## What this module provides - -- `//:defs.bzl` - `nvcf_java_library`, `nvcf_spring_boot_image`. -- `//:platform.bzl` - `SPRING_BOOT_BOM`, `MAVEN_REPOSITORIES`, and the Spring / - Spring Cloud / Testcontainers / ShedLock version constants. Single source of - truth for the platform. -- `//:bom_alignment.bzl` - `bom_alignment_test`, the guard that keeps each - consuming module's inlined `boms` list identical to `SPRING_BOOT_BOM`. -- `//private:oci.bzl` - vendored `create_oci_image` (multi-arch), so this module - does not depend on the root workspace's `//rules/oci`. -- `//platforms:linux_arm64`, `//platforms:linux_x86_64`. - -## How modules consume it - -A Java module adds, in its `MODULE.bazel`: - -```python -bazel_dep(name = "nvcf_java_rules", version = "0.1.0") -local_path_override(module_name = "nvcf_java_rules", path = "<relpath>/rules/java") -``` - -and inlines the same literal BOM list `SPRING_BOOT_BOM` exposes (load() is -forbidden in MODULE.bazel), guarded by `bom_alignment_test`. - -## BOM / version bumps - -Bumping Spring, Spring Cloud, Testcontainers, or ShedLock is a one-line edit in -`//:platform.bzl`, the matching edit to every Java module's inlined `boms`, then -a re-pin (`REPIN=1 bazel run @maven//:pin`) of each module. `bom_alignment_test` -fails any module left un-aligned. - -## Build - -``` -cd rules/java && bazel build //... -``` - -The module resolves only public BCR modules plus its OCI bases, so it builds on -the public mirror. It is not in the root `.bazelignore` because its BUILD files -declare no targets that reference the root workspace; the root never loads its -`.bzl` files once Java services are their own modules. diff --git a/rules/java/BUILD.bazel b/rules/java/BUILD.bazel deleted file mode 100644 index d3700c347..000000000 --- a/rules/java/BUILD.bazel +++ /dev/null @@ -1,16 +0,0 @@ -# SPDX-FileCopyrightText: Copyright (c) NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# 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. - -# Java build rules (nvcf_spring_boot_image, nvcf_java_library). See defs.bzl. diff --git a/rules/java/CLAUDE.md b/rules/java/CLAUDE.md deleted file mode 100644 index 43c994c2d..000000000 --- a/rules/java/CLAUDE.md +++ /dev/null @@ -1 +0,0 @@ -@AGENTS.md diff --git a/rules/java/MODULE.bazel b/rules/java/MODULE.bazel deleted file mode 100644 index 84a13cc25..000000000 --- a/rules/java/MODULE.bazel +++ /dev/null @@ -1,71 +0,0 @@ -# SPDX-FileCopyrightText: Copyright (c) NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# 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. - -"""nvcf_java_rules: shared Bazel macros and platform constants for NVCF Java. - -Standalone module. Holds no application code. Every Java library and service -module consumes it via bazel_dep + local_path_override, loads the shared Spring -Boot BOM and version constants from //:platform.bzl, and builds images with the -nvcf_spring_boot_image macro. See //:platform.bzl for the single source of truth -on Spring/Cloud/Testcontainers versions. -""" - -module( - name = "nvcf_java_rules", - version = "0.1.0", -) - -bazel_dep(name = "rules_java", version = "9.3.0") -bazel_dep(name = "rules_jvm_external", version = "7.0") -bazel_dep(name = "contrib_rules_jvm", version = "0.33.0") -bazel_dep(name = "rules_oci", version = "2.2.7") -bazel_dep(name = "rules_pkg", version = "1.2.0") -bazel_dep(name = "aspect_bazel_lib", version = "2.19.3") -bazel_dep(name = "rules_shell", version = "0.8.0") -bazel_dep(name = "platforms", version = "1.0.0") - -# OCI base images for the vendored create_oci_image helper (used by the -# nvcf_spring_boot_image macro). These are declared here so a consuming Java -# service module inherits them transitively and does not re-pin the bases. -# Both mirror the root module's pins: the AWS public ECR mirrors avoid Docker -# Hub anonymous pull limits and resolve on the public GitHub mirror. -oci = use_extension("@rules_oci//oci:extensions.bzl", "oci") -oci.pull( - name = "temurin_jre", - image = "public.ecr.aws/docker/library/eclipse-temurin", - platforms = [ - "linux/arm64/v8", - "linux/amd64", - ], - tag = "21-jre", -) -oci.pull( - name = "ubuntu_noble", - digest = "sha256:ef59d9e82939bbce08973bdffb8761b025f75369fb7d2882cdc4938b5a9e992e", - image = "public.ecr.aws/ubuntu/ubuntu", - platforms = [ - "linux/arm64/v8", - "linux/amd64", - ], -) -use_repo( - oci, - "temurin_jre", - "temurin_jre_linux_amd64", - "temurin_jre_linux_arm64_v8", - "ubuntu_noble", - "ubuntu_noble_linux_amd64", - "ubuntu_noble_linux_arm64_v8", -) diff --git a/rules/java/MODULE.bazel.lock b/rules/java/MODULE.bazel.lock deleted file mode 100644 index 41ddc67af..000000000 --- a/rules/java/MODULE.bazel.lock +++ /dev/null @@ -1,296 +0,0 @@ -{ - "lockFileVersion": 28, - "registryFileHashes": { - "https://bcr.bazel.build/bazel_registry.json": "8a28e4aff06ee60aed2a8c281907fb8bcbf3b753c91fb5a5c57da3215d5b3497", - "https://bcr.bazel.build/modules/abseil-cpp/20210324.2/MODULE.bazel": "7cd0312e064fde87c8d1cd79ba06c876bd23630c83466e9500321be55c96ace2", - "https://bcr.bazel.build/modules/abseil-cpp/20211102.0/MODULE.bazel": "70390338f7a5106231d20620712f7cccb659cd0e9d073d1991c038eb9fc57589", - "https://bcr.bazel.build/modules/abseil-cpp/20230125.1/MODULE.bazel": "89047429cb0207707b2dface14ba7f8df85273d484c2572755be4bab7ce9c3a0", - "https://bcr.bazel.build/modules/abseil-cpp/20230802.0.bcr.1/MODULE.bazel": "1c8cec495288dccd14fdae6e3f95f772c1c91857047a098fad772034264cc8cb", - "https://bcr.bazel.build/modules/abseil-cpp/20230802.0/MODULE.bazel": "d253ae36a8bd9ee3c5955384096ccb6baf16a1b1e93e858370da0a3b94f77c16", - "https://bcr.bazel.build/modules/abseil-cpp/20230802.1/MODULE.bazel": "fa92e2eb41a04df73cdabeec37107316f7e5272650f81d6cc096418fe647b915", - "https://bcr.bazel.build/modules/abseil-cpp/20240116.1/MODULE.bazel": "37bcdb4440fbb61df6a1c296ae01b327f19e9bb521f9b8e26ec854b6f97309ed", - "https://bcr.bazel.build/modules/abseil-cpp/20240116.2/MODULE.bazel": "73939767a4686cd9a520d16af5ab440071ed75cec1a876bf2fcfaf1f71987a16", - "https://bcr.bazel.build/modules/abseil-cpp/20250127.0/MODULE.bazel": "d1086e248cda6576862b4b3fe9ad76a214e08c189af5b42557a6e1888812c5d5", - "https://bcr.bazel.build/modules/abseil-cpp/20250127.1/MODULE.bazel": "c4a89e7ceb9bf1e25cf84a9f830ff6b817b72874088bf5141b314726e46a57c1", - "https://bcr.bazel.build/modules/abseil-cpp/20250512.1/MODULE.bazel": "d209fdb6f36ffaf61c509fcc81b19e81b411a999a934a032e10cd009a0226215", - "https://bcr.bazel.build/modules/abseil-cpp/20250814.1/MODULE.bazel": "51f2312901470cdab0dbdf3b88c40cd21c62a7ed58a3de45b365ddc5b11bcab2", - "https://bcr.bazel.build/modules/abseil-cpp/20250814.1/source.json": "cea3901d7e299da7320700abbaafe57a65d039f10d0d7ea601c4a66938ea4b0c", - "https://bcr.bazel.build/modules/abseil-py/2.1.0/MODULE.bazel": "5ebe5bf853769c65707e5c28f216798f7a4b1042015e6a36e6d03094d94bec8a", - "https://bcr.bazel.build/modules/abseil-py/2.1.0/source.json": "0e8fc4f088ce07099c1cd6594c20c7ddbb48b4b3c0849b7d94ba94be88ff042b", - "https://bcr.bazel.build/modules/apple_rules_lint/0.4.0/MODULE.bazel": "c59831c3a5389430516203777816527f257329a5da363994e1d62b9ae6729f71", - "https://bcr.bazel.build/modules/apple_rules_lint/0.4.0/source.json": "105883202602181f43f109372e1b9ea19e89bbe3bce4bc1fe9bb0baa51eb61ae", - "https://bcr.bazel.build/modules/apple_support/1.11.1/MODULE.bazel": "1843d7cd8a58369a444fc6000e7304425fba600ff641592161d9f15b179fb896", - "https://bcr.bazel.build/modules/apple_support/1.15.1/MODULE.bazel": "a0556fefca0b1bb2de8567b8827518f94db6a6e7e7d632b4c48dc5f865bc7c85", - "https://bcr.bazel.build/modules/apple_support/1.21.0/MODULE.bazel": "ac1824ed5edf17dee2fdd4927ada30c9f8c3b520be1b5fd02a5da15bc10bff3e", - "https://bcr.bazel.build/modules/apple_support/1.21.1/MODULE.bazel": "5809fa3efab15d1f3c3c635af6974044bac8a4919c62238cce06acee8a8c11f1", - "https://bcr.bazel.build/modules/apple_support/1.24.2/MODULE.bazel": "0e62471818affb9f0b26f128831d5c40b074d32e6dda5a0d3852847215a41ca4", - "https://bcr.bazel.build/modules/apple_support/1.24.2/source.json": "2c22c9827093250406c5568da6c54e6fdf0ef06238def3d99c71b12feb057a8d", - "https://bcr.bazel.build/modules/aspect_bazel_lib/2.14.0/MODULE.bazel": "2b31ffcc9bdc8295b2167e07a757dbbc9ac8906e7028e5170a3708cecaac119f", - "https://bcr.bazel.build/modules/aspect_bazel_lib/2.19.3/MODULE.bazel": "253d739ba126f62a5767d832765b12b59e9f8d2bc88cc1572f4a73e46eb298ca", - "https://bcr.bazel.build/modules/aspect_bazel_lib/2.19.3/source.json": "ffab9254c65ba945f8369297ad97ca0dec213d3adc6e07877e23a48624a8b456", - "https://bcr.bazel.build/modules/aspect_bazel_lib/2.7.2/MODULE.bazel": "780d1a6522b28f5edb7ea09630748720721dfe27690d65a2d33aa7509de77e07", - "https://bcr.bazel.build/modules/aspect_bazel_lib/2.8.1/MODULE.bazel": "812d2dd42f65dca362152101fbec418029cc8fd34cbad1a2fde905383d705838", - "https://bcr.bazel.build/modules/bazel_features/1.1.0/MODULE.bazel": "cfd42ff3b815a5f39554d97182657f8c4b9719568eb7fded2b9135f084bf760b", - "https://bcr.bazel.build/modules/bazel_features/1.1.1/MODULE.bazel": "27b8c79ef57efe08efccbd9dd6ef70d61b4798320b8d3c134fd571f78963dbcd", - "https://bcr.bazel.build/modules/bazel_features/1.10.0/MODULE.bazel": "f75e8807570484a99be90abcd52b5e1f390362c258bcb73106f4544957a48101", - "https://bcr.bazel.build/modules/bazel_features/1.11.0/MODULE.bazel": "f9382337dd5a474c3b7d334c2f83e50b6eaedc284253334cf823044a26de03e8", - "https://bcr.bazel.build/modules/bazel_features/1.13.0/MODULE.bazel": "c14c33c7c3c730612bdbe14ebbb5e61936b6f11322ea95a6e91cd1ba962f94df", - "https://bcr.bazel.build/modules/bazel_features/1.15.0/MODULE.bazel": "d38ff6e517149dc509406aca0db3ad1efdd890a85e049585b7234d04238e2a4d", - "https://bcr.bazel.build/modules/bazel_features/1.17.0/MODULE.bazel": "039de32d21b816b47bd42c778e0454217e9c9caac4a3cf8e15c7231ee3ddee4d", - "https://bcr.bazel.build/modules/bazel_features/1.18.0/MODULE.bazel": "1be0ae2557ab3a72a57aeb31b29be347bcdc5d2b1eb1e70f39e3851a7e97041a", - "https://bcr.bazel.build/modules/bazel_features/1.19.0/MODULE.bazel": "59adcdf28230d220f0067b1f435b8537dd033bfff8db21335ef9217919c7fb58", - "https://bcr.bazel.build/modules/bazel_features/1.21.0/MODULE.bazel": "675642261665d8eea09989aa3b8afb5c37627f1be178382c320d1b46afba5e3b", - "https://bcr.bazel.build/modules/bazel_features/1.23.0/MODULE.bazel": "fd1ac84bc4e97a5a0816b7fd7d4d4f6d837b0047cf4cbd81652d616af3a6591a", - "https://bcr.bazel.build/modules/bazel_features/1.25.0/MODULE.bazel": "e2e60a10a6da64bbf533f15ca652bf61a033e41c2ed734d79a9a08ba87f68c1a", - "https://bcr.bazel.build/modules/bazel_features/1.27.0/MODULE.bazel": "621eeee06c4458a9121d1f104efb80f39d34deff4984e778359c60eaf1a8cb65", - "https://bcr.bazel.build/modules/bazel_features/1.28.0/MODULE.bazel": "4b4200e6cbf8fa335b2c3f43e1d6ef3e240319c33d43d60cc0fbd4b87ece299d", - "https://bcr.bazel.build/modules/bazel_features/1.3.0/MODULE.bazel": "cdcafe83ec318cda34e02948e81d790aab8df7a929cec6f6969f13a489ccecd9", - "https://bcr.bazel.build/modules/bazel_features/1.30.0/MODULE.bazel": "a14b62d05969a293b80257e72e597c2da7f717e1e69fa8b339703ed6731bec87", - "https://bcr.bazel.build/modules/bazel_features/1.33.0/MODULE.bazel": "8b8dc9d2a4c88609409c3191165bccec0e4cb044cd7a72ccbe826583303459f6", - "https://bcr.bazel.build/modules/bazel_features/1.4.1/MODULE.bazel": "e45b6bb2350aff3e442ae1111c555e27eac1d915e77775f6fdc4b351b758b5d7", - "https://bcr.bazel.build/modules/bazel_features/1.42.1/MODULE.bazel": "275a59b5406ff18c01739860aa70ad7ccb3cfb474579411decca11c93b951080", - "https://bcr.bazel.build/modules/bazel_features/1.42.1/source.json": "fcd4396b2df85f64f2b3bb436ad870793ecf39180f1d796f913cc9276d355309", - "https://bcr.bazel.build/modules/bazel_features/1.9.0/MODULE.bazel": "885151d58d90d8d9c811eb75e3288c11f850e1d6b481a8c9f766adee4712358b", - "https://bcr.bazel.build/modules/bazel_features/1.9.1/MODULE.bazel": "8f679097876a9b609ad1f60249c49d68bfab783dd9be012faf9d82547b14815a", - "https://bcr.bazel.build/modules/bazel_lib/3.0.0/MODULE.bazel": "22b70b80ac89ad3f3772526cd9feee2fa412c2b01933fea7ed13238a448d370d", - "https://bcr.bazel.build/modules/bazel_lib/3.0.0/source.json": "895f21909c6fba01d7c17914bb6c8e135982275a1b18cdaa4e62272217ef1751", - "https://bcr.bazel.build/modules/bazel_skylib/1.0.3/MODULE.bazel": "bcb0fd896384802d1ad283b4e4eb4d718eebd8cb820b0a2c3a347fb971afd9d8", - "https://bcr.bazel.build/modules/bazel_skylib/1.1.1/MODULE.bazel": "1add3e7d93ff2e6998f9e118022c84d163917d912f5afafb3058e3d2f1545b5e", - "https://bcr.bazel.build/modules/bazel_skylib/1.2.0/MODULE.bazel": "44fe84260e454ed94ad326352a698422dbe372b21a1ac9f3eab76eb531223686", - "https://bcr.bazel.build/modules/bazel_skylib/1.2.1/MODULE.bazel": "f35baf9da0efe45fa3da1696ae906eea3d615ad41e2e3def4aeb4e8bc0ef9a7a", - "https://bcr.bazel.build/modules/bazel_skylib/1.3.0/MODULE.bazel": "20228b92868bf5cfc41bda7afc8a8ba2a543201851de39d990ec957b513579c5", - "https://bcr.bazel.build/modules/bazel_skylib/1.4.1/MODULE.bazel": "a0dcb779424be33100dcae821e9e27e4f2901d9dfd5333efe5ac6a8d7ab75e1d", - "https://bcr.bazel.build/modules/bazel_skylib/1.4.2/MODULE.bazel": "3bd40978e7a1fac911d5989e6b09d8f64921865a45822d8b09e815eaa726a651", - "https://bcr.bazel.build/modules/bazel_skylib/1.5.0/MODULE.bazel": "32880f5e2945ce6a03d1fbd588e9198c0a959bb42297b2cfaf1685b7bc32e138", - "https://bcr.bazel.build/modules/bazel_skylib/1.6.1/MODULE.bazel": "8fdee2dbaace6c252131c00e1de4b165dc65af02ea278476187765e1a617b917", - "https://bcr.bazel.build/modules/bazel_skylib/1.7.0/MODULE.bazel": "0db596f4563de7938de764cc8deeabec291f55e8ec15299718b93c4423e9796d", - "https://bcr.bazel.build/modules/bazel_skylib/1.7.1/MODULE.bazel": "3120d80c5861aa616222ec015332e5f8d3171e062e3e804a2a0253e1be26e59b", - "https://bcr.bazel.build/modules/bazel_skylib/1.8.1/MODULE.bazel": "88ade7293becda963e0e3ea33e7d54d3425127e0a326e0d17da085a5f1f03ff6", - "https://bcr.bazel.build/modules/bazel_skylib/1.8.2/MODULE.bazel": "69ad6927098316848b34a9142bcc975e018ba27f08c4ff403f50c1b6e646ca67", - "https://bcr.bazel.build/modules/bazel_skylib/1.8.2/source.json": "34a3c8bcf233b835eb74be9d628899bb32999d3e0eadef1947a0a562a2b16ffb", - "https://bcr.bazel.build/modules/bazel_worker_api/0.0.1/MODULE.bazel": "02a13b77321773b2042e70ee5e4c5e099c8ddee4cf2da9cd420442c36938d4bd", - "https://bcr.bazel.build/modules/bazel_worker_api/0.0.4/MODULE.bazel": "460aa12d01231a80cce03c548287b433b321d205b0028ae596728c35e5ee442e", - "https://bcr.bazel.build/modules/bazel_worker_api/0.0.8/MODULE.bazel": "396c1ef53835aafe3d42ce6619080531ee770648303731f16cfaa33fa056bf0c", - "https://bcr.bazel.build/modules/bazel_worker_api/0.0.8/source.json": "abaf8ac9d2ab2f47bda9af4c0c080ff7907378888e1f4bc62a0539dd13ba61e8", - "https://bcr.bazel.build/modules/bazel_worker_java/0.0.4/MODULE.bazel": "82494a01018bb7ef06d4a17ec4cd7a758721f10eb8b6c820a818e70d669500db", - "https://bcr.bazel.build/modules/bazel_worker_java/0.0.8/MODULE.bazel": "e76479eae70bd4e8f5f4c2dfc5d03ab971cfb18750246c7b3f3454c5c2ee6629", - "https://bcr.bazel.build/modules/bazel_worker_java/0.0.8/source.json": "9395c4679444bc47bf7e51a710366a4480aa371c6f6bed01868e2fabcf11acec", - "https://bcr.bazel.build/modules/buildozer/8.5.1/MODULE.bazel": "a35d9561b3fc5b18797c330793e99e3b834a473d5fbd3d7d7634aafc9bdb6f8f", - "https://bcr.bazel.build/modules/buildozer/8.5.1/source.json": "e3386e6ff4529f2442800dee47ad28d3e6487f36a1f75ae39ae56c70f0cd2fbd", - "https://bcr.bazel.build/modules/contrib_rules_jvm/0.33.0/MODULE.bazel": "1aba514585748372ee392484b2645f0bbcb13ad4271d5b7cace018280f15bae1", - "https://bcr.bazel.build/modules/contrib_rules_jvm/0.33.0/source.json": "e52d62ce2a2b8a513d6afe9178acc06a4349c9b0b4c0934d59085ed9df4b4de0", - "https://bcr.bazel.build/modules/gazelle/0.32.0/MODULE.bazel": "b499f58a5d0d3537f3cf5b76d8ada18242f64ec474d8391247438bf04f58c7b8", - "https://bcr.bazel.build/modules/gazelle/0.33.0/MODULE.bazel": "a13a0f279b462b784fb8dd52a4074526c4a2afe70e114c7d09066097a46b3350", - "https://bcr.bazel.build/modules/gazelle/0.34.0/MODULE.bazel": "abdd8ce4d70978933209db92e436deb3a8b737859e9354fb5fd11fb5c2004c8a", - "https://bcr.bazel.build/modules/gazelle/0.36.0/MODULE.bazel": "e375d5d6e9a6ca59b0cb38b0540bc9a05b6aa926d322f2de268ad267a2ee74c0", - "https://bcr.bazel.build/modules/gazelle/0.40.0/MODULE.bazel": "42ba5378ebe845fca43989a53186ab436d956db498acde790685fe0e8f9c6146", - "https://bcr.bazel.build/modules/gazelle/0.42.0/MODULE.bazel": "fa140a7c019f3a22779ba7c6132ffff9d2d10a51dba2f3304dee61523d11fef4", - "https://bcr.bazel.build/modules/gazelle/0.47.0/MODULE.bazel": "b61bb007c4efad134aa30ee7f4a8e2a39b22aa5685f005edaa022fbd1de43ebc", - "https://bcr.bazel.build/modules/gazelle/0.47.0/source.json": "aeb2e5df14b7fb298625d75d08b9c65bdb0b56014c5eb89da9e5dd0572280ae6", - "https://bcr.bazel.build/modules/google_benchmark/1.8.2/MODULE.bazel": "a70cf1bba851000ba93b58ae2f6d76490a9feb74192e57ab8e8ff13c34ec50cb", - "https://bcr.bazel.build/modules/googletest/1.11.0/MODULE.bazel": "3a83f095183f66345ca86aa13c58b59f9f94a2f81999c093d4eeaa2d262d12f4", - "https://bcr.bazel.build/modules/googletest/1.14.0.bcr.1/MODULE.bazel": "22c31a561553727960057361aa33bf20fb2e98584bc4fec007906e27053f80c6", - "https://bcr.bazel.build/modules/googletest/1.14.0/MODULE.bazel": "cfbcbf3e6eac06ef9d85900f64424708cc08687d1b527f0ef65aa7517af8118f", - "https://bcr.bazel.build/modules/googletest/1.15.2/MODULE.bazel": "6de1edc1d26cafb0ea1a6ab3f4d4192d91a312fd2d360b63adaa213cd00b2108", - "https://bcr.bazel.build/modules/googletest/1.17.0/MODULE.bazel": "dbec758171594a705933a29fcf69293d2468c49ec1f2ebca65c36f504d72df46", - "https://bcr.bazel.build/modules/googletest/1.17.0/source.json": "38e4454b25fc30f15439c0378e57909ab1fd0a443158aa35aec685da727cd713", - "https://bcr.bazel.build/modules/jq.bzl/0.1.0/MODULE.bazel": "2ce69b1af49952cd4121a9c3055faa679e748ce774c7f1fda9657f936cae902f", - "https://bcr.bazel.build/modules/jq.bzl/0.1.0/source.json": "746bf13cac0860f091df5e4911d0c593971cd8796b5ad4e809b2f8e133eee3d5", - "https://bcr.bazel.build/modules/jsoncpp/1.9.5/MODULE.bazel": "31271aedc59e815656f5736f282bb7509a97c7ecb43e927ac1a37966e0578075", - "https://bcr.bazel.build/modules/jsoncpp/1.9.6/MODULE.bazel": "2f8d20d3b7d54143213c4dfc3d98225c42de7d666011528dc8fe91591e2e17b0", - "https://bcr.bazel.build/modules/jsoncpp/1.9.6/source.json": "a04756d367a2126c3541682864ecec52f92cdee80a35735a3cb249ce015ca000", - "https://bcr.bazel.build/modules/libpfm/4.11.0/MODULE.bazel": "45061ff025b301940f1e30d2c16bea596c25b176c8b6b3087e92615adbd52902", - "https://bcr.bazel.build/modules/nlohmann_json/3.6.1/MODULE.bazel": "6f7b417dcc794d9add9e556673ad25cb3ba835224290f4f848f8e2db1e1fca74", - "https://bcr.bazel.build/modules/nlohmann_json/3.6.1/source.json": "f448c6e8963fdfa7eb831457df83ad63d3d6355018f6574fb017e8169deb43a9", - "https://bcr.bazel.build/modules/package_metadata/0.0.2/MODULE.bazel": "fb8d25550742674d63d7b250063d4580ca530499f045d70748b1b142081ebb92", - "https://bcr.bazel.build/modules/package_metadata/0.0.3/MODULE.bazel": "77890552ecea9e284b5424c9de827a58099348763a4359e975c359a83d4faa83", - "https://bcr.bazel.build/modules/package_metadata/0.0.5/MODULE.bazel": "ef4f9439e3270fdd6b9fd4dbc3d2f29d13888e44c529a1b243f7a31dfbc2e8e4", - "https://bcr.bazel.build/modules/package_metadata/0.0.7/MODULE.bazel": "7adb03933fc8401f495800cf4eafcff0edc6da0ff55c7db223ef69d19f689486", - "https://bcr.bazel.build/modules/package_metadata/0.0.7/source.json": "50639625e937b56115012674c797cca7a05a96b4878c87d803c13dc2b31de8a0", - "https://bcr.bazel.build/modules/platforms/0.0.10/MODULE.bazel": "8cb8efaf200bdeb2150d93e162c40f388529a25852b332cec879373771e48ed5", - "https://bcr.bazel.build/modules/platforms/0.0.11/MODULE.bazel": "0daefc49732e227caa8bfa834d65dc52e8cc18a2faf80df25e8caea151a9413f", - "https://bcr.bazel.build/modules/platforms/0.0.4/MODULE.bazel": "9b328e31ee156f53f3c416a64f8491f7eb731742655a47c9eec4703a71644aee", - "https://bcr.bazel.build/modules/platforms/0.0.5/MODULE.bazel": "5733b54ea419d5eaf7997054bb55f6a1d0b5ff8aedf0176fef9eea44f3acda37", - "https://bcr.bazel.build/modules/platforms/0.0.6/MODULE.bazel": "ad6eeef431dc52aefd2d77ed20a4b353f8ebf0f4ecdd26a807d2da5aa8cd0615", - "https://bcr.bazel.build/modules/platforms/0.0.7/MODULE.bazel": "72fd4a0ede9ee5c021f6a8dd92b503e089f46c227ba2813ff183b71616034814", - "https://bcr.bazel.build/modules/platforms/0.0.8/MODULE.bazel": "9f142c03e348f6d263719f5074b21ef3adf0b139ee4c5133e2aa35664da9eb2d", - "https://bcr.bazel.build/modules/platforms/0.0.9/MODULE.bazel": "4a87a60c927b56ddd67db50c89acaa62f4ce2a1d2149ccb63ffd871d5ce29ebc", - "https://bcr.bazel.build/modules/platforms/1.0.0/MODULE.bazel": "f05feb42b48f1b3c225e4ccf351f367be0371411a803198ec34a389fb22aa580", - "https://bcr.bazel.build/modules/platforms/1.0.0/source.json": "f4ff1fd412e0246fd38c82328eb209130ead81d62dcd5a9e40910f867f733d96", - "https://bcr.bazel.build/modules/protobuf/21.7/MODULE.bazel": "a5a29bb89544f9b97edce05642fac225a808b5b7be74038ea3640fae2f8e66a7", - "https://bcr.bazel.build/modules/protobuf/23.1/MODULE.bazel": "88b393b3eb4101d18129e5db51847cd40a5517a53e81216144a8c32dfeeca52a", - "https://bcr.bazel.build/modules/protobuf/24.4/MODULE.bazel": "7bc7ce5f2abf36b3b7b7c8218d3acdebb9426aeb35c2257c96445756f970eb12", - "https://bcr.bazel.build/modules/protobuf/27.0/MODULE.bazel": "7873b60be88844a0a1d8f80b9d5d20cfbd8495a689b8763e76c6372998d3f64c", - "https://bcr.bazel.build/modules/protobuf/27.1/MODULE.bazel": "703a7b614728bb06647f965264967a8ef1c39e09e8f167b3ca0bb1fd80449c0d", - "https://bcr.bazel.build/modules/protobuf/27.2/MODULE.bazel": "32450b50673882e4c8c3d10a83f3bc82161b213ed2f80d17e38bece8f165c295", - "https://bcr.bazel.build/modules/protobuf/29.0-rc2.bcr.1/MODULE.bazel": "52f4126f63a2f0bbf36b99c2a87648f08467a4eaf92ba726bc7d6a500bbf770c", - "https://bcr.bazel.build/modules/protobuf/29.0-rc2/MODULE.bazel": "6241d35983510143049943fc0d57937937122baf1b287862f9dc8590fc4c37df", - "https://bcr.bazel.build/modules/protobuf/29.0-rc3/MODULE.bazel": "33c2dfa286578573afc55a7acaea3cada4122b9631007c594bf0729f41c8de92", - "https://bcr.bazel.build/modules/protobuf/29.0/MODULE.bazel": "319dc8bf4c679ff87e71b1ccfb5a6e90a6dbc4693501d471f48662ac46d04e4e", - "https://bcr.bazel.build/modules/protobuf/29.1/MODULE.bazel": "557c3457560ff49e122ed76c0bc3397a64af9574691cb8201b4e46d4ab2ecb95", - "https://bcr.bazel.build/modules/protobuf/29.3/MODULE.bazel": "77480eea5fb5541903e49683f24dc3e09f4a79e0eea247414887bb9fc0066e94", - "https://bcr.bazel.build/modules/protobuf/3.19.0/MODULE.bazel": "6b5fbb433f760a99a22b18b6850ed5784ef0e9928a72668b66e4d7ccd47db9b0", - "https://bcr.bazel.build/modules/protobuf/3.19.2/MODULE.bazel": "532ffe5f2186b69fdde039efe6df13ba726ff338c6bc82275ad433013fa10573", - "https://bcr.bazel.build/modules/protobuf/3.19.6/MODULE.bazel": "9233edc5e1f2ee276a60de3eaa47ac4132302ef9643238f23128fea53ea12858", - "https://bcr.bazel.build/modules/protobuf/31.1/MODULE.bazel": "379a389bb330b7b8c1cdf331cc90bf3e13de5614799b3b52cdb7c6f389f6b38e", - "https://bcr.bazel.build/modules/protobuf/32.1/MODULE.bazel": "89cd2866a9cb07fee9ff74c41ceace11554f32e0d849de4e23ac55515cfada4d", - "https://bcr.bazel.build/modules/protobuf/33.4/MODULE.bazel": "114775b816b38b6d0ca620450d6b02550c60ceedfdc8d9a229833b34a223dc42", - "https://bcr.bazel.build/modules/protobuf/33.4/source.json": "555f8686b4c7d6b5ba731fbea13bf656b4bfd9a7ff629c1d9d3f6e1d6155de79", - "https://bcr.bazel.build/modules/pybind11_bazel/2.11.1/MODULE.bazel": "88af1c246226d87e65be78ed49ecd1e6f5e98648558c14ce99176da041dc378e", - "https://bcr.bazel.build/modules/pybind11_bazel/2.12.0/MODULE.bazel": "e6f4c20442eaa7c90d7190d8dc539d0ab422f95c65a57cc59562170c58ae3d34", - "https://bcr.bazel.build/modules/pybind11_bazel/2.12.0/source.json": "6900fdc8a9e95866b8c0d4ad4aba4d4236317b5c1cd04c502df3f0d33afed680", - "https://bcr.bazel.build/modules/re2/2023-09-01/MODULE.bazel": "cb3d511531b16cfc78a225a9e2136007a48cf8a677e4264baeab57fe78a80206", - "https://bcr.bazel.build/modules/re2/2024-07-02.bcr.1/MODULE.bazel": "b4963dda9b31080be1905ef085ecd7dd6cd47c05c79b9cdf83ade83ab2ab271a", - "https://bcr.bazel.build/modules/re2/2024-07-02.bcr.1/source.json": "2ff292be6ef3340325ce8a045ecc326e92cbfab47c7cbab4bd85d28971b97ac4", - "https://bcr.bazel.build/modules/re2/2024-07-02/MODULE.bazel": "0eadc4395959969297cbcf31a249ff457f2f1d456228c67719480205aa306daa", - "https://bcr.bazel.build/modules/rules_android/0.1.1/MODULE.bazel": "48809ab0091b07ad0182defb787c4c5328bd3a278938415c00a7b69b50c4d3a8", - "https://bcr.bazel.build/modules/rules_android/0.6.4/MODULE.bazel": "b4cde12d506dd65d82b2be39761f49f5797303343a3d5b4ee191c0cdf9ef387c", - "https://bcr.bazel.build/modules/rules_android/0.6.6/MODULE.bazel": "b0fb569752aab65ab1a9db0a8f6cfaf5aa1754965e17e95dcf0e4d88e192a68d", - "https://bcr.bazel.build/modules/rules_android/0.7.1/MODULE.bazel": "a806fc382a774252f228a40e3b11b9fcc6276f8778c7fb33e9f72937c6258363", - "https://bcr.bazel.build/modules/rules_android/0.7.1/source.json": "151440aed3f0f73a00d4ed5cec5d31f63a6fef9b95d8fab1eb1810150fa525f2", - "https://bcr.bazel.build/modules/rules_apple/3.16.0/MODULE.bazel": "0d1caf0b8375942ce98ea944be754a18874041e4e0459401d925577624d3a54a", - "https://bcr.bazel.build/modules/rules_apple/4.1.0/MODULE.bazel": "76e10fd4a48038d3fc7c5dc6e63b7063bbf5304a2e3bd42edda6ec660eebea68", - "https://bcr.bazel.build/modules/rules_apple/4.1.0/source.json": "8ee81e1708756f81b343a5eb2b2f0b953f1d25c4ab3d4a68dc02754872e80715", - "https://bcr.bazel.build/modules/rules_cc/0.0.1/MODULE.bazel": "cb2aa0747f84c6c3a78dad4e2049c154f08ab9d166b1273835a8174940365647", - "https://bcr.bazel.build/modules/rules_cc/0.0.10/MODULE.bazel": "ec1705118f7eaedd6e118508d3d26deba2a4e76476ada7e0e3965211be012002", - "https://bcr.bazel.build/modules/rules_cc/0.0.13/MODULE.bazel": "0e8529ed7b323dad0775ff924d2ae5af7640b23553dfcd4d34344c7e7a867191", - "https://bcr.bazel.build/modules/rules_cc/0.0.15/MODULE.bazel": "6704c35f7b4a72502ee81f61bf88706b54f06b3cbe5558ac17e2e14666cd5dcc", - "https://bcr.bazel.build/modules/rules_cc/0.0.16/MODULE.bazel": "7661303b8fc1b4d7f532e54e9d6565771fea666fbdf839e0a86affcd02defe87", - "https://bcr.bazel.build/modules/rules_cc/0.0.17/MODULE.bazel": "2ae1d8f4238ec67d7185d8861cb0a2cdf4bc608697c331b95bf990e69b62e64a", - "https://bcr.bazel.build/modules/rules_cc/0.0.2/MODULE.bazel": "6915987c90970493ab97393024c156ea8fb9f3bea953b2f3ec05c34f19b5695c", - "https://bcr.bazel.build/modules/rules_cc/0.0.6/MODULE.bazel": "abf360251023dfe3efcef65ab9d56beefa8394d4176dd29529750e1c57eaa33f", - "https://bcr.bazel.build/modules/rules_cc/0.0.8/MODULE.bazel": "964c85c82cfeb6f3855e6a07054fdb159aced38e99a5eecf7bce9d53990afa3e", - "https://bcr.bazel.build/modules/rules_cc/0.0.9/MODULE.bazel": "836e76439f354b89afe6a911a7adf59a6b2518fafb174483ad78a2a2fde7b1c5", - "https://bcr.bazel.build/modules/rules_cc/0.1.1/MODULE.bazel": "2f0222a6f229f0bf44cd711dc13c858dad98c62d52bd51d8fc3a764a83125513", - "https://bcr.bazel.build/modules/rules_cc/0.1.2/MODULE.bazel": "557ddc3a96858ec0d465a87c0a931054d7dcfd6583af2c7ed3baf494407fd8d0", - "https://bcr.bazel.build/modules/rules_cc/0.1.5/MODULE.bazel": "88dfc9361e8b5ae1008ac38f7cdfd45ad738e4fa676a3ad67d19204f045a1fd8", - "https://bcr.bazel.build/modules/rules_cc/0.2.0/MODULE.bazel": "b5c17f90458caae90d2ccd114c81970062946f49f355610ed89bebf954f5783c", - "https://bcr.bazel.build/modules/rules_cc/0.2.13/MODULE.bazel": "eecdd666eda6be16a8d9dc15e44b5c75133405e820f620a234acc4b1fdc5aa37", - "https://bcr.bazel.build/modules/rules_cc/0.2.14/MODULE.bazel": "353c99ed148887ee89c54a17d4100ae7e7e436593d104b668476019023b58df8", - "https://bcr.bazel.build/modules/rules_cc/0.2.17/MODULE.bazel": "1849602c86cb60da8613d2de887f9566a6d354a6df6d7009f9d04a14402f9a84", - "https://bcr.bazel.build/modules/rules_cc/0.2.17/source.json": "3832f45d145354049137c0090df04629d9c2b5493dc5c2bf46f1834040133a07", - "https://bcr.bazel.build/modules/rules_cc/0.2.8/MODULE.bazel": "f1df20f0bf22c28192a794f29b501ee2018fa37a3862a1a2132ae2940a23a642", - "https://bcr.bazel.build/modules/rules_foreign_cc/0.9.0/MODULE.bazel": "c9e8c682bf75b0e7c704166d79b599f93b72cfca5ad7477df596947891feeef6", - "https://bcr.bazel.build/modules/rules_fuzzing/0.5.2/MODULE.bazel": "40c97d1144356f52905566c55811f13b299453a14ac7769dfba2ac38192337a8", - "https://bcr.bazel.build/modules/rules_go/0.41.0/MODULE.bazel": "55861d8e8bb0e62cbd2896f60ff303f62ffcb0eddb74ecb0e5c0cbe36fc292c8", - "https://bcr.bazel.build/modules/rules_go/0.42.0/MODULE.bazel": "8cfa875b9aa8c6fce2b2e5925e73c1388173ea3c32a0db4d2b4804b453c14270", - "https://bcr.bazel.build/modules/rules_go/0.46.0/MODULE.bazel": "3477df8bdcc49e698b9d25f734c4f3a9f5931ff34ee48a2c662be168f5f2d3fd", - "https://bcr.bazel.build/modules/rules_go/0.50.1/MODULE.bazel": "b91a308dc5782bb0a8021ad4330c81fea5bda77f96b9e4c117b9b9c8f6665ee0", - "https://bcr.bazel.build/modules/rules_go/0.51.0-rc2/MODULE.bazel": "edfc3a9cea7bedb0eaaff37b0d7817c1a4bf72b3c615580b0ffcee6c52690fd4", - "https://bcr.bazel.build/modules/rules_go/0.52.0/MODULE.bazel": "0cf080a2706aa8fc9abf64286cee60fdf0238db37b7f1793b0f7d550d59ea3ae", - "https://bcr.bazel.build/modules/rules_go/0.53.0/MODULE.bazel": "a4ed760d3ac0dbc0d7b967631a9a3fd9100d28f7d9fcf214b4df87d4bfff5f9a", - "https://bcr.bazel.build/modules/rules_go/0.59.0/MODULE.bazel": "b7e43e7414a3139a7547d1b4909b29085fbe5182b6c58cbe1ed4c6272815aeae", - "https://bcr.bazel.build/modules/rules_go/0.59.0/source.json": "1df17bb7865cfc029492c30163cee891d0dd8658ea0d5bfdf252c4b6db5c1ef6", - "https://bcr.bazel.build/modules/rules_java/4.0.0/MODULE.bazel": "5a78a7ae82cd1a33cef56dc578c7d2a46ed0dca12643ee45edbb8417899e6f74", - "https://bcr.bazel.build/modules/rules_java/5.3.5/MODULE.bazel": "a4ec4f2db570171e3e5eb753276ee4b389bae16b96207e9d3230895c99644b86", - "https://bcr.bazel.build/modules/rules_java/6.3.0/MODULE.bazel": "a97c7678c19f236a956ad260d59c86e10a463badb7eb2eda787490f4c969b963", - "https://bcr.bazel.build/modules/rules_java/6.5.2/MODULE.bazel": "1d440d262d0e08453fa0c4d8f699ba81609ed0e9a9a0f02cd10b3e7942e61e31", - "https://bcr.bazel.build/modules/rules_java/7.1.0/MODULE.bazel": "30d9135a2b6561c761bd67bd4990da591e6bdc128790ce3e7afd6a3558b2fb64", - "https://bcr.bazel.build/modules/rules_java/7.10.0/MODULE.bazel": "530c3beb3067e870561739f1144329a21c851ff771cd752a49e06e3dc9c2e71a", - "https://bcr.bazel.build/modules/rules_java/7.12.2/MODULE.bazel": "579c505165ee757a4280ef83cda0150eea193eed3bef50b1004ba88b99da6de6", - "https://bcr.bazel.build/modules/rules_java/7.2.0/MODULE.bazel": "06c0334c9be61e6cef2c8c84a7800cef502063269a5af25ceb100b192453d4ab", - "https://bcr.bazel.build/modules/rules_java/7.4.0/MODULE.bazel": "a592852f8a3dd539e82ee6542013bf2cadfc4c6946be8941e189d224500a8934", - "https://bcr.bazel.build/modules/rules_java/7.6.1/MODULE.bazel": "2f14b7e8a1aa2f67ae92bc69d1ec0fa8d9f827c4e17ff5e5f02e91caa3b2d0fe", - "https://bcr.bazel.build/modules/rules_java/8.13.0/MODULE.bazel": "0444ebf737d144cf2bb2ccb368e7f1cce735264285f2a3711785827c1686625e", - "https://bcr.bazel.build/modules/rules_java/8.15.2/MODULE.bazel": "5cc6698c822b2f9ef90ca5558599851bed8c3b13f1f8eb140d9bfec638d2acb4", - "https://bcr.bazel.build/modules/rules_java/8.3.2/MODULE.bazel": "7336d5511ad5af0b8615fdc7477535a2e4e723a357b6713af439fe8cf0195017", - "https://bcr.bazel.build/modules/rules_java/8.5.1/MODULE.bazel": "d8a9e38cc5228881f7055a6079f6f7821a073df3744d441978e7a43e20226939", - "https://bcr.bazel.build/modules/rules_java/8.6.0/MODULE.bazel": "9c064c434606d75a086f15ade5edb514308cccd1544c2b2a89bbac4310e41c71", - "https://bcr.bazel.build/modules/rules_java/8.6.1/MODULE.bazel": "f4808e2ab5b0197f094cabce9f4b006a27766beb6a9975931da07099560ca9c2", - "https://bcr.bazel.build/modules/rules_java/8.6.3/MODULE.bazel": "e90505b7a931d194245ffcfb6ff4ca8ef9d46b4e830d12e64817752e0198e2ed", - "https://bcr.bazel.build/modules/rules_java/8.9.0/MODULE.bazel": "e17c876cb53dcd817b7b7f0d2985b710610169729e8c371b2221cacdcd3dce4a", - "https://bcr.bazel.build/modules/rules_java/9.1.0/MODULE.bazel": "ee63f27e36a3fada80342869361182f120a9819c74320e8e65b1e04ba0cd7a9d", - "https://bcr.bazel.build/modules/rules_java/9.3.0/MODULE.bazel": "f657c72d65ac449caae9abf2e68e66c0d36f9416848c4c4903d0b3234229e7f2", - "https://bcr.bazel.build/modules/rules_java/9.3.0/source.json": "59ae7e662c3c7042b88bbb42ad12483523e234c65ebe4c51611baa43e85cb248", - "https://bcr.bazel.build/modules/rules_jvm_external/4.4.2/MODULE.bazel": "a56b85e418c83eb1839819f0b515c431010160383306d13ec21959ac412d2fe7", - "https://bcr.bazel.build/modules/rules_jvm_external/5.1/MODULE.bazel": "33f6f999e03183f7d088c9be518a63467dfd0be94a11d0055fe2d210f89aa909", - "https://bcr.bazel.build/modules/rules_jvm_external/5.2/MODULE.bazel": "d9351ba35217ad0de03816ef3ed63f89d411349353077348a45348b096615036", - "https://bcr.bazel.build/modules/rules_jvm_external/6.10/MODULE.bazel": "33e636ca6bc9ee0fa090a38aa33c631ded2d8cf6fead4124181d1b35dc474f7c", - "https://bcr.bazel.build/modules/rules_jvm_external/6.2/MODULE.bazel": "36a6e52487a855f33cb960724eb56547fa87e2c98a0474c3acad94339d7f8e99", - "https://bcr.bazel.build/modules/rules_jvm_external/6.3/MODULE.bazel": "c998e060b85f71e00de5ec552019347c8bca255062c990ac02d051bb80a38df0", - "https://bcr.bazel.build/modules/rules_jvm_external/6.6/MODULE.bazel": "153042249c7060536dc95b6bb9f9bb8063b8a0b0cb7acdb381bddbc2374aed55", - "https://bcr.bazel.build/modules/rules_jvm_external/6.7/MODULE.bazel": "e717beabc4d091ecb2c803c2d341b88590e9116b8bf7947915eeb33aab4f96dd", - "https://bcr.bazel.build/modules/rules_jvm_external/6.9/MODULE.bazel": "07c5db05527db7744a54fcffd653e1550d40e0540207a7f7e6d0a4de5bef8274", - "https://bcr.bazel.build/modules/rules_jvm_external/7.0/MODULE.bazel": "421482bdbcf05709f933c96b867a599deb517f2804ceb3e74511880610cfbf71", - "https://bcr.bazel.build/modules/rules_jvm_external/7.0/source.json": "714cd003eadf5be5c83268311fe8e951db39f802babeaddc536b3560dc8f6faf", - "https://bcr.bazel.build/modules/rules_kotlin/1.9.5/MODULE.bazel": "043a16a572f610558ec2030db3ff0c9938574e7dd9f58bded1bb07c0192ef025", - "https://bcr.bazel.build/modules/rules_kotlin/1.9.6/MODULE.bazel": "d269a01a18ee74d0335450b10f62c9ed81f2321d7958a2934e44272fe82dcef3", - "https://bcr.bazel.build/modules/rules_kotlin/2.1.3/MODULE.bazel": "ce7def6d576aa8d3a9c6d10e13b4d157296229674371f67dbf788dae0afae3d5", - "https://bcr.bazel.build/modules/rules_kotlin/2.2.2/MODULE.bazel": "00d39c5e0fa78cd86193946265bb849e7878c24e44260f9525108428852b315c", - "https://bcr.bazel.build/modules/rules_kotlin/2.2.2/source.json": "7a32c2259c79ae0c9a036121f120de825e3ba5f0f3a209ffbbdccf4dc62489b9", - "https://bcr.bazel.build/modules/rules_license/0.0.3/MODULE.bazel": "627e9ab0247f7d1e05736b59dbb1b6871373de5ad31c3011880b4133cafd4bd0", - "https://bcr.bazel.build/modules/rules_license/0.0.7/MODULE.bazel": "088fbeb0b6a419005b89cf93fe62d9517c0a2b8bb56af3244af65ecfe37e7d5d", - "https://bcr.bazel.build/modules/rules_license/1.0.0/MODULE.bazel": "a7fda60eefdf3d8c827262ba499957e4df06f659330bbe6cdbdb975b768bb65c", - "https://bcr.bazel.build/modules/rules_license/1.0.0/source.json": "a52c89e54cc311196e478f8382df91c15f7a2bfdf4c6cd0e2675cc2ff0b56efb", - "https://bcr.bazel.build/modules/rules_oci/2.2.7/MODULE.bazel": "f6150e4b224d459f7f6523ef65967464ca4efdd266c7fbf2f5a2a51011957e0c", - "https://bcr.bazel.build/modules/rules_oci/2.2.7/source.json": "b099f02af330f47f19dc67fc9300ef6e1937a8c86882690db0e7a2fcea8c7f6b", - "https://bcr.bazel.build/modules/rules_pkg/0.7.0/MODULE.bazel": "df99f03fc7934a4737122518bb87e667e62d780b610910f0447665a7e2be62dc", - "https://bcr.bazel.build/modules/rules_pkg/1.0.1/MODULE.bazel": "5b1df97dbc29623bccdf2b0dcd0f5cb08e2f2c9050aab1092fd39a41e82686ff", - "https://bcr.bazel.build/modules/rules_pkg/1.2.0/MODULE.bazel": "c7db3c2b407e673c7a39e3625dc05dc9f12d6682cbd82a3a5924a13b491eda7e", - "https://bcr.bazel.build/modules/rules_pkg/1.2.0/source.json": "9062e00845bf91a4247465d371baa837adf9b6ff44c542f73ba084f07667e1dc", - "https://bcr.bazel.build/modules/rules_proto/4.0.0/MODULE.bazel": "a7a7b6ce9bee418c1a760b3d84f83a299ad6952f9903c67f19e4edd964894e06", - "https://bcr.bazel.build/modules/rules_proto/5.3.0-21.7/MODULE.bazel": "e8dff86b0971688790ae75528fe1813f71809b5afd57facb44dad9e8eca631b7", - "https://bcr.bazel.build/modules/rules_proto/6.0.0-rc1/MODULE.bazel": "1e5b502e2e1a9e825eef74476a5a1ee524a92297085015a052510b09a1a09483", - "https://bcr.bazel.build/modules/rules_proto/6.0.0/MODULE.bazel": "b531d7f09f58dce456cd61b4579ce8c86b38544da75184eadaf0a7cb7966453f", - "https://bcr.bazel.build/modules/rules_proto/6.0.2/MODULE.bazel": "ce916b775a62b90b61888052a416ccdda405212b6aaeb39522f7dc53431a5e73", - "https://bcr.bazel.build/modules/rules_proto/7.0.2/MODULE.bazel": "bf81793bd6d2ad89a37a40693e56c61b0ee30f7a7fdbaf3eabbf5f39de47dea2", - "https://bcr.bazel.build/modules/rules_proto/7.1.0/MODULE.bazel": "002d62d9108f75bb807cd56245d45648f38275cb3a99dcd45dfb864c5d74cb96", - "https://bcr.bazel.build/modules/rules_proto/7.1.0/source.json": "39f89066c12c24097854e8f57ab8558929f9c8d474d34b2c00ac04630ad8940e", - "https://bcr.bazel.build/modules/rules_python/0.10.2/MODULE.bazel": "cc82bc96f2997baa545ab3ce73f196d040ffb8756fd2d66125a530031cd90e5f", - "https://bcr.bazel.build/modules/rules_python/0.23.1/MODULE.bazel": "49ffccf0511cb8414de28321f5fcf2a31312b47c40cc21577144b7447f2bf300", - "https://bcr.bazel.build/modules/rules_python/0.25.0/MODULE.bazel": "72f1506841c920a1afec76975b35312410eea3aa7b63267436bfb1dd91d2d382", - "https://bcr.bazel.build/modules/rules_python/0.28.0/MODULE.bazel": "cba2573d870babc976664a912539b320cbaa7114cd3e8f053c720171cde331ed", - "https://bcr.bazel.build/modules/rules_python/0.31.0/MODULE.bazel": "93a43dc47ee570e6ec9f5779b2e64c1476a6ce921c48cc9a1678a91dd5f8fd58", - "https://bcr.bazel.build/modules/rules_python/0.33.2/MODULE.bazel": "3e036c4ad8d804a4dad897d333d8dce200d943df4827cb849840055be8d2e937", - "https://bcr.bazel.build/modules/rules_python/0.37.1/MODULE.bazel": "3faeb2d9fa0a81f8980643ee33f212308f4d93eea4b9ce6f36d0b742e71e9500", - "https://bcr.bazel.build/modules/rules_python/0.37.2/MODULE.bazel": "b5ffde91410745750b6c13be1c5dc4555ef5bc50562af4a89fd77807fdde626a", - "https://bcr.bazel.build/modules/rules_python/0.4.0/MODULE.bazel": "9208ee05fd48bf09ac60ed269791cf17fb343db56c8226a720fbb1cdf467166c", - "https://bcr.bazel.build/modules/rules_python/1.0.0/MODULE.bazel": "898a3d999c22caa585eb062b600f88654bf92efb204fa346fb55f6f8edffca43", - "https://bcr.bazel.build/modules/rules_python/1.3.0/MODULE.bazel": "8361d57eafb67c09b75bf4bbe6be360e1b8f4f18118ab48037f2bd50aa2ccb13", - "https://bcr.bazel.build/modules/rules_python/1.4.1/MODULE.bazel": "8991ad45bdc25018301d6b7e1d3626afc3c8af8aaf4bc04f23d0b99c938b73a6", - "https://bcr.bazel.build/modules/rules_python/1.6.0/MODULE.bazel": "7e04ad8f8d5bea40451cf80b1bd8262552aa73f841415d20db96b7241bd027d8", - "https://bcr.bazel.build/modules/rules_python/1.7.0/MODULE.bazel": "d01f995ecd137abf30238ad9ce97f8fc3ac57289c8b24bd0bf53324d937a14f8", - "https://bcr.bazel.build/modules/rules_python/1.7.0/source.json": "028a084b65dcf8f4dc4f82f8778dbe65df133f234b316828a82e060d81bdce32", - "https://bcr.bazel.build/modules/rules_robolectric/4.14.1.2/MODULE.bazel": "d44fec647d0aeb67b9f3b980cf68ba634976f3ae7ccd6c07d790b59b87a4f251", - "https://bcr.bazel.build/modules/rules_robolectric/4.14.1.2/source.json": "37c10335f2361c337c5c1f34ed36d2da70534c23088062b33a8bdaab68aa9dea", - "https://bcr.bazel.build/modules/rules_shell/0.1.2/MODULE.bazel": "66e4ca3ce084b04af0b9ff05ff14cab4e5df7503973818bb91cbc6cda08d32fc", - "https://bcr.bazel.build/modules/rules_shell/0.2.0/MODULE.bazel": "fda8a652ab3c7d8fee214de05e7a9916d8b28082234e8d2c0094505c5268ed3c", - "https://bcr.bazel.build/modules/rules_shell/0.3.0/MODULE.bazel": "de4402cd12f4cc8fda2354fce179fdb068c0b9ca1ec2d2b17b3e21b24c1a937b", - "https://bcr.bazel.build/modules/rules_shell/0.4.1/MODULE.bazel": "00e501db01bbf4e3e1dd1595959092c2fadf2087b2852d3f553b5370f5633592", - "https://bcr.bazel.build/modules/rules_shell/0.6.1/MODULE.bazel": "72e76b0eea4e81611ef5452aa82b3da34caca0c8b7b5c0c9584338aa93bae26b", - "https://bcr.bazel.build/modules/rules_shell/0.8.0/MODULE.bazel": "f6a89f1d6a669a26f28fe814503857055d76306b79cfc11d12399af08d0b80ae", - "https://bcr.bazel.build/modules/rules_shell/0.8.0/source.json": "eb53cc815bc503c6683c5fe12d943f98883f81fc22f51403ec8a95610cba4195", - "https://bcr.bazel.build/modules/rules_swift/1.16.0/MODULE.bazel": "4a09f199545a60d09895e8281362b1ff3bb08bbde69c6fc87aff5b92fcc916ca", - "https://bcr.bazel.build/modules/rules_swift/2.1.1/MODULE.bazel": "494900a80f944fc7aa61500c2073d9729dff0b764f0e89b824eb746959bc1046", - "https://bcr.bazel.build/modules/rules_swift/2.4.0/MODULE.bazel": "1639617eb1ede28d774d967a738b4a68b0accb40650beadb57c21846beab5efd", - "https://bcr.bazel.build/modules/rules_swift/3.1.2/MODULE.bazel": "72c8f5cf9d26427cee6c76c8e3853eb46ce6b0412a081b2b6db6e8ad56267400", - "https://bcr.bazel.build/modules/rules_swift/3.1.2/source.json": "e85761f3098a6faf40b8187695e3de6d97944e98abd0d8ce579cb2daf6319a66", - "https://bcr.bazel.build/modules/stardoc/0.5.1/MODULE.bazel": "1a05d92974d0c122f5ccf09291442580317cdd859f07a8655f1db9a60374f9f8", - "https://bcr.bazel.build/modules/stardoc/0.5.3/MODULE.bazel": "c7f6948dae6999bf0db32c1858ae345f112cacf98f174c7a8bb707e41b974f1c", - "https://bcr.bazel.build/modules/stardoc/0.5.4/MODULE.bazel": "6569966df04610b8520957cb8e97cf2e9faac2c0309657c537ab51c16c18a2a4", - "https://bcr.bazel.build/modules/stardoc/0.6.2/MODULE.bazel": "7060193196395f5dd668eda046ccbeacebfd98efc77fed418dbe2b82ffaa39fd", - "https://bcr.bazel.build/modules/stardoc/0.7.0/MODULE.bazel": "05e3d6d30c099b6770e97da986c53bd31844d7f13d41412480ea265ac9e8079c", - "https://bcr.bazel.build/modules/stardoc/0.7.2/MODULE.bazel": "fc152419aa2ea0f51c29583fab1e8c99ddefd5b3778421845606ee628629e0e5", - "https://bcr.bazel.build/modules/stardoc/0.7.2/source.json": "58b029e5e901d6802967754adf0a9056747e8176f017cfe3607c0851f4d42216", - "https://bcr.bazel.build/modules/swift_argument_parser/1.3.1.1/MODULE.bazel": "5e463fbfba7b1701d957555ed45097d7f984211330106ccd1352c6e0af0dcf91", - "https://bcr.bazel.build/modules/swift_argument_parser/1.3.1.2/MODULE.bazel": "75aab2373a4bbe2a1260b9bf2a1ebbdbf872d3bd36f80bff058dccd82e89422f", - "https://bcr.bazel.build/modules/swift_argument_parser/1.3.1.2/source.json": "5fba48bbe0ba48761f9e9f75f92876cafb5d07c0ce059cc7a8027416de94a05b", - "https://bcr.bazel.build/modules/tar.bzl/0.2.1/MODULE.bazel": "52d1c00a80a8cc67acbd01649e83d8dd6a9dc426a6c0b754a04fe8c219c76468", - "https://bcr.bazel.build/modules/tar.bzl/0.2.1/source.json": "600ac6ff61744667a439e7b814ae59c1f29632c3984fccf8000c64c9db8d7bb6", - "https://bcr.bazel.build/modules/toml.bzl/0.3.0/MODULE.bazel": "5016e5dd1ad2200e119a4b28b2b3935e276c4b480f2fe3e952bea7eeba88f578", - "https://bcr.bazel.build/modules/toml.bzl/0.3.0/source.json": "0cf7c878c419b37ddb55f3dd93dd7c0c409bd7c4efacb3da504e0748780b2fa9", - "https://bcr.bazel.build/modules/upb/0.0.0-20220923-a547704/MODULE.bazel": "7298990c00040a0e2f121f6c32544bab27d4452f80d9ce51349b1a28f3005c43", - "https://bcr.bazel.build/modules/upb/0.0.0-20230516-61a97ef/MODULE.bazel": "c0df5e35ad55e264160417fd0875932ee3c9dda63d9fccace35ac62f45e1b6f9", - "https://bcr.bazel.build/modules/yq.bzl/0.1.1/MODULE.bazel": "9039681f9bcb8958ee2c87ffc74bdafba9f4369096a2b5634b88abc0eaefa072", - "https://bcr.bazel.build/modules/yq.bzl/0.1.1/source.json": "2d2bad780a9f2b9195a4a370314d2c17ae95eaa745cefc2e12fbc49759b15aa3", - "https://bcr.bazel.build/modules/zlib/1.2.11/MODULE.bazel": "07b389abc85fdbca459b69e2ec656ae5622873af3f845e1c9d80fe179f3effa0", - "https://bcr.bazel.build/modules/zlib/1.2.12/MODULE.bazel": "3b1a8834ada2a883674be8cbd36ede1b6ec481477ada359cd2d3ddc562340b27", - "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.5/MODULE.bazel": "eec517b5bbe5492629466e11dae908d043364302283de25581e3eb944326c4ca", - "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.5/source.json": "22bc55c47af97246cfc093d0acf683a7869377de362b5d1c552c2c2e16b7a806", - "https://bcr.bazel.build/modules/zlib/1.3.1/MODULE.bazel": "751c9940dcfe869f5f7274e1295422a34623555916eb98c174c1e945594bf198" - }, - "selectedYankedVersions": {}, - "moduleExtensions": {}, - "facts": {}, - "factsVersions": {} -} diff --git a/rules/java/README.md b/rules/java/README.md deleted file mode 100644 index 312493bfb..000000000 --- a/rules/java/README.md +++ /dev/null @@ -1,75 +0,0 @@ -# rules/java - -Bazel build rules for NVCF Java services. Load them from `//rules/java:defs.bzl`. - -```starlark -load("//rules/java:defs.bzl", "nvcf_java_library", "nvcf_spring_boot_image") -``` - -## nvcf_spring_boot_image - -Packages a Java application's runtime classpath into a multi-arch OCI image. - -```starlark -nvcf_spring_boot_image( - name = "image", - main_class = "com.nvidia.nvcf.example.ExampleApplication", - deps = [":example_lib"], # java_library targets; transitive runtime jars are packaged - # base = "@temurin_jre", # default JRE base - # registry = "nvcr.io/...",# emits :image_push when set - # jvm_flags = ["-XX:MaxRAMPercentage=75"], -) -``` - -It generates the same target set as the Go image macro (`:image`, -`:image_index`, `:image_load`, `:image.tar`, and `:image_push` when a registry -is given), so a Java service plugs into the existing release machinery unchanged. - -Design note: the app runs from an exploded classpath (`/app/lib/*.jar`), not a -fat jar. Each dependency jar keeps its own `META-INF/spring.factories` and -`META-INF/spring/*.AutoConfiguration.imports`. A fat/singlejar would collapse -those same-path resources to a single file and silently break Spring Boot -auto-configuration. - -Multi-module constraint: jars are packaged flat under `/app/lib` by basename, so -every jar on the transitive runtime classpath must have a unique filename. Maven -jars already are (`artifact-version.jar`); a Bazel `java_library` jar is named -after its target label (`lib<name>.jar`). A multi-module service must give its -library targets distinct names (do not reuse `lib` or `main` across packages) or -the compiled jars overwrite each other in the image layer. The example service -has a single library and is not affected. - -## nvcf_java_library - -Thin wrapper over `java_library`. Use it for NVCF Java code so services load a -single entry point and shared defaults can be added later in one place. - -## Maven dependencies - -Coordinates are resolved by `rules_jvm_external` and pinned in -`//:maven_install.json`. To add a dependency: - -1. Add the coordinate to `maven.install(artifacts = [...])` in the root - `MODULE.bazel`. -2. Re-pin: `bazel run @nv_third_party_deps//:pin` (or `REPIN=1 bazel run @nv_third_party_deps//:pin` when - updating an existing set). -3. Reference it as `@nv_third_party_deps//:group_artifact` in `deps`. List every artifact your - code imports directly, not just the aggregator starter, so the strict-deps - header compiler resolves the symbols. - -### Internal (nv-boot) dependencies - -The foundation resolves from Maven Central only, so it builds anywhere including -the public GitHub mirror. A service that depends on nv-boot or other internal -artifacts adds the internal Artifactory Maven virtual repository to the -`repositories` list in `maven.install` and lists the nv-boot coordinates in -`artifacts`. Point `repositories` at your internal Artifactory virtual repo URL -(kept out of this file to preserve OSS snapshot hygiene) ahead of Central, then -re-pin. Builds that need those artifacts then run only where that repository is -reachable. - -## Java toolchain - -Java builds use a hermetic remotejdk 21 (`--java_language_version=21`, -`--java_runtime_version=remotejdk_21` in `.bazelrc`), independent of the host -JDK, so builds are reproducible on any developer machine and in CI. diff --git a/rules/java/bom_alignment.bzl b/rules/java/bom_alignment.bzl deleted file mode 100644 index 30bc60bae..000000000 --- a/rules/java/bom_alignment.bzl +++ /dev/null @@ -1,55 +0,0 @@ -# SPDX-FileCopyrightText: Copyright (c) NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# 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. - -"""bom_alignment_test: guard that a Java module's inlined BOMs match platform.bzl. - -load() is forbidden in MODULE.bazel, so a module cannot write -`boms = SPRING_BOOT_BOM` and must inline the literal coordinates. This macro -closes that gap: it materializes the canonical SPRING_BOOT_BOM from platform.bzl -into a file and runs a shell test that asserts every canonical coordinate is -present in the consuming module's MODULE.bazel. If someone bumps Spring in -platform.bzl but forgets a module, or edits one module's boms out of step, this -test fails. -""" - -load("@rules_shell//shell:sh_test.bzl", "sh_test") -load("//:platform.bzl", "SPRING_BOOT_BOM") - -def bom_alignment_test(name, module_bazel = "//:MODULE.bazel", boms = SPRING_BOOT_BOM): - """Assert the module's MODULE.bazel inlines exactly the canonical BOM set. - - Args: - name: test target name. - module_bazel: label of the module's MODULE.bazel (default //:MODULE.bazel). - boms: canonical BOM list (default the shared SPRING_BOOT_BOM). - """ - canonical = name + "_canonical" - native.genrule( - name = canonical, - outs = [name + "_canonical.txt"], - cmd = "cat > $@ <<'BOMS'\n" + "\n".join(boms) + "\nBOMS", - ) - sh_test( - name = name, - srcs = ["@nvcf_java_rules//scripts:check_bom_alignment.sh"], - args = [ - "$(location %s)" % module_bazel, - "$(location :%s.txt)" % canonical, - ], - data = [ - module_bazel, - ":%s.txt" % canonical, - ], - ) diff --git a/rules/java/defs.bzl b/rules/java/defs.bzl deleted file mode 100644 index 19d534d25..000000000 --- a/rules/java/defs.bzl +++ /dev/null @@ -1,25 +0,0 @@ -# SPDX-FileCopyrightText: Copyright (c) NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# 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. - -"Public Java build rules for NVCF services." - -load( - "//private:spring_boot.bzl", - _nvcf_java_library = "nvcf_java_library", - _nvcf_spring_boot_image = "nvcf_spring_boot_image", -) - -nvcf_spring_boot_image = _nvcf_spring_boot_image -nvcf_java_library = _nvcf_java_library diff --git a/rules/java/platform.bzl b/rules/java/platform.bzl deleted file mode 100644 index 7ad8d7a27..000000000 --- a/rules/java/platform.bzl +++ /dev/null @@ -1,53 +0,0 @@ -# SPDX-FileCopyrightText: Copyright (c) NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# 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. - -"""Single source of truth for the NVCF Java platform. - -Every Java module resolves its own Maven graph and writes its own -maven_install.json, which is what makes each module independently buildable. The -risk of independent resolution is version drift: two modules pinning different -Spring versions put two copies on a transitive classpath. - -To keep resolutions in agreement, the shared BOM set and version constants live -here, loadable from any BUILD or .bzl file. load() is forbidden in MODULE.bazel, -so a module cannot reference SPRING_BOOT_BOM directly in its maven.install. Each -module instead inlines the same literal BOM list in its MODULE.bazel and guards -it with bom_alignment_test (see //:bom_alignment.bzl), which fails the build if a -module's boms drift from this canonical list. Bumping a shared version is a -one-line change here plus a re-pin of every Java module. -""" - -SPRING_BOOT_VERSION = "4.0.7" -SPRING_CLOUD_VERSION = "2025.1.2" -TESTCONTAINERS_VERSION = "2.0.5" -SHEDLOCK_VERSION = "7.7.0" - -# Canonical shared BOM set. Keep this list, and the literal boms list in every -# Java module's MODULE.bazel, identical. bom_alignment_test enforces it. -SPRING_BOOT_BOM = [ - "org.springframework.boot:spring-boot-dependencies:%s" % SPRING_BOOT_VERSION, - "org.springframework.cloud:spring-cloud-dependencies:%s" % SPRING_CLOUD_VERSION, - "org.testcontainers:testcontainers-bom:%s" % TESTCONTAINERS_VERSION, - "net.javacrumbs.shedlock:shedlock-bom:%s" % SHEDLOCK_VERSION, -] - -# Public Central mirrors only, so the platform resolves anywhere including the -# public GitHub mirror. The Google-hosted mirror is primary (not IP-rate-limited -# like repo1.maven.org); Maven Central is the fallback. Internal builds that need -# NVIDIA artifacts prepend the Artifactory virtual repo in their own overlay. -MAVEN_REPOSITORIES = [ - "https://maven-central.storage-download.googleapis.com/maven2", - "https://repo.maven.apache.org/maven2", -] diff --git a/rules/java/platforms/BUILD.bazel b/rules/java/platforms/BUILD.bazel deleted file mode 100644 index 4cc09b2d0..000000000 --- a/rules/java/platforms/BUILD.bazel +++ /dev/null @@ -1,32 +0,0 @@ -# SPDX-FileCopyrightText: Copyright (c) NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# 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(default_visibility = ["//visibility:public"]) - -platform( - name = "linux_arm64", - constraint_values = [ - "@platforms//os:linux", - "@platforms//cpu:aarch64", - ], -) - -platform( - name = "linux_x86_64", - constraint_values = [ - "@platforms//os:linux", - "@platforms//cpu:x86_64", - ], -) diff --git a/rules/java/private/BUILD.bazel b/rules/java/private/BUILD.bazel deleted file mode 100644 index 908410169..000000000 --- a/rules/java/private/BUILD.bazel +++ /dev/null @@ -1,16 +0,0 @@ -# SPDX-FileCopyrightText: Copyright (c) NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# 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. - -# Private Java rule implementations. diff --git a/rules/java/private/oci.bzl b/rules/java/private/oci.bzl deleted file mode 100644 index 0ac9467d6..000000000 --- a/rules/java/private/oci.bzl +++ /dev/null @@ -1,162 +0,0 @@ -# SPDX-FileCopyrightText: Copyright (c) NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# 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. - -"""Self-contained OCI image helper for the Java rules module. - -Vendored from //rules/oci so nvcf_java_rules is a standalone Bazel module with -no dependency on the root workspace's //rules/oci package. Kept behavior-for- -behavior identical to the shared helper: multi-arch (amd64 + arm64) images with -platform transitions and a registry push target. If the shared helper changes, -re-vendor this copy. -""" - -load("@aspect_bazel_lib//lib:expand_template.bzl", "expand_template") -load("@aspect_bazel_lib//lib:transitions.bzl", "platform_transition_filegroup") -load("@rules_oci//oci:defs.bzl", "oci_image", "oci_image_index", "oci_load", "oci_push") - -DEFAULT_BASE = "@ubuntu_noble" -DEFAULT_PLATFORMS = [ - "//platforms:linux_arm64", - "//platforms:linux_x86_64", -] - -COMMON_LAYERS = [] - -def _multiarch_transition(settings, attr): - return [ - {"//command_line_option:platforms": str(platform)} - for platform in attr.platforms - ] - -multiarch_transition = transition( - implementation = _multiarch_transition, - inputs = [], - outputs = ["//command_line_option:platforms"], -) - -def _multi_arch_impl(ctx): - return DefaultInfo(files = depset(ctx.files.image)) - -multi_arch = rule( - implementation = _multi_arch_impl, - attrs = { - "image": attr.label(cfg = multiarch_transition), - "platforms": attr.label_list(), - "_allowlist_function_transition": attr.label( - default = "@bazel_tools//tools/allowlists/function_transition_allowlist", - ), - }, -) - -def create_oci_image( - name, - tars, - base, - entrypoint, - visibility, - registry = None, - tags = None): - """Creates OCI image targets with platform transitions and tarball output. - - Generates: - - {name}: Platform-transitioned OCI image (for local builds) - - {name}_index: Multi-arch image index (amd64 + arm64) - - {name}_load: Local docker load target - - {name}.tar: Tarball filegroup - - {name}_push: Push to registry (if registry is set) - """ - all_tags = ["manual"] + (tags or []) - - pre_transitioned = name + "_pre_transitioned" - oci_image( - name = pre_transitioned, - base = base, - tars = tars + COMMON_LAYERS, - entrypoint = entrypoint, - visibility = ["//visibility:private"], - tags = all_tags, - ) - - platform_transition_filegroup( - name = name, - srcs = [pre_transitioned], - target_platform = select({ - "@platforms//cpu:arm64": "//platforms:linux_arm64", - "@platforms//cpu:x86_64": "//platforms:linux_x86_64", - }), - visibility = visibility, - tags = all_tags, - ) - - multi_arch_name = name + "_multi_arch" - multi_arch( - name = multi_arch_name, - image = pre_transitioned, - platforms = DEFAULT_PLATFORMS, - visibility = ["//visibility:private"], - tags = all_tags, - ) - - oci_image_index( - name = name + "_index", - images = [multi_arch_name], - visibility = visibility, - tags = all_tags, - ) - - load_name = name + "_load" - oci_load( - name = load_name, - image = name, - repo_tags = [native.package_name() + ":latest"], - visibility = visibility, - tags = all_tags, - ) - - native.filegroup( - name = name + ".tar", - srcs = [load_name], - output_group = "tarball", - visibility = visibility, - tags = all_tags, - ) - - if registry: - stamped_tags = name + "_stamped_tags" - expand_template( - name = stamped_tags, - out = name + "_tags.txt", - stamp_substitutions = { - "{VERSION}": "{{STABLE_VERSION}}", - "{OCI_TAG}": "{{STABLE_OCI_TAG}}", - "{COMMIT}": "{{STABLE_GIT_COMMIT}}", - }, - template = [ - "latest", - "{VERSION}", - "{OCI_TAG}", - "{COMMIT}", - ], - visibility = ["//visibility:private"], - ) - - oci_push( - name = name + "_push", - image = name + "_index", - remote_tags = stamped_tags, - repository = registry, - visibility = visibility, - tags = all_tags, - ) diff --git a/rules/java/private/spring_boot.bzl b/rules/java/private/spring_boot.bzl deleted file mode 100644 index 232d6a07d..000000000 --- a/rules/java/private/spring_boot.bzl +++ /dev/null @@ -1,142 +0,0 @@ -# SPDX-FileCopyrightText: Copyright (c) NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# 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. - -"OCI image + library rules for Java (Spring Boot) services." - -load("@rules_java//java:defs.bzl", "java_library") -load("@rules_java//java/common:java_info.bzl", "JavaInfo") -load("@rules_pkg//pkg:mappings.bzl", "pkg_files", "strip_prefix") -load("@rules_pkg//pkg:tar.bzl", "pkg_tar") -load("//private:oci.bzl", "create_oci_image") - -DEFAULT_JAVA_BASE = "@temurin_jre" - -def _runtime_classpath_impl(ctx): - jars = depset(transitive = [ - dep[JavaInfo].transitive_runtime_jars - for dep in ctx.attr.deps - ]) - return [DefaultInfo(files = jars)] - -# Collects the transitive runtime jars of one or more Java targets so they can -# be packaged as individual files (see _nvcf_spring_boot_image_impl for why the -# jars are kept separate instead of merged into a fat jar). -_runtime_classpath = rule( - implementation = _runtime_classpath_impl, - attrs = { - "deps": attr.label_list( - providers = [JavaInfo], - mandatory = True, - doc = "Java targets whose transitive runtime jars form the classpath.", - ), - }, -) - -def _nvcf_spring_boot_image_impl(name, visibility, deps, main_class, base, registry, tags, jvm_flags): - cp_name = name + "_classpath" - _runtime_classpath( - name = cp_name, - deps = deps, - visibility = ["//visibility:private"], - ) - - files_name = name + "_classpath_files" - pkg_files( - name = files_name, - srcs = [cp_name], - # Flatten every jar to /app/lib/<basename>. Maven artifact jars are - # already uniquely named (artifact-version.jar). Bazel-produced jars are - # named after their target label (lib<name>.jar), so two same-named - # java_library targets in different packages would collide here. See the - # deps attr doc for the single-basename constraint on multi-module apps. - strip_prefix = strip_prefix.files_only(), - prefix = "app/lib", - visibility = ["//visibility:private"], - ) - - layer_name = name + "_layer" - pkg_tar( - name = layer_name, - srcs = [files_name], - visibility = ["//visibility:private"], - ) - - # Run the app off the exploded classpath instead of a fat jar. Keeping each - # dependency jar separate preserves its META-INF/spring.factories and - # META-INF/spring/*.AutoConfiguration.imports; a fat/singlejar collapses - # those same-path resources to a single file and silently breaks Spring - # Boot auto-configuration. - entrypoint = ["java"] + jvm_flags + ["-cp", "/app/lib/*", main_class] - - create_oci_image( - name = name, - tars = [layer_name], - base = base, - entrypoint = entrypoint, - visibility = visibility, - registry = registry, - tags = tags, - ) - -nvcf_spring_boot_image = macro( - doc = "Packages a Java (Spring Boot) app's runtime classpath into a multi-arch OCI image.", - implementation = _nvcf_spring_boot_image_impl, - attrs = { - "deps": attr.label_list( - doc = ( - "Java targets (typically one java_library) providing the app and its runtime " + - "deps. Jars are packaged flat under /app/lib by basename, so every jar on the " + - "transitive runtime classpath must have a unique filename. Maven jars already " + - "are (artifact-version.jar); Bazel jars take their target label (lib<name>.jar). " + - "A multi-module app must therefore give its java_library targets distinct names " + - "(avoid reusing 'lib' or 'main' across packages) or the compiled jars silently " + - "overwrite each other in the image layer." - ), - mandatory = True, - configurable = False, - ), - "main_class": attr.string( - doc = "Fully-qualified main class (the @SpringBootApplication class).", - mandatory = True, - configurable = False, - ), - "base": attr.label( - doc = "Base JRE OCI image.", - default = DEFAULT_JAVA_BASE, - configurable = False, - ), - "registry": attr.string( - doc = "Registry to push to. If unset, no push target is created.", - configurable = False, - ), - "tags": attr.string_list( - doc = "Tags for generated targets. 'manual' is always added.", - configurable = False, - ), - "jvm_flags": attr.string_list( - doc = "Extra JVM flags inserted before -cp in the entrypoint.", - configurable = False, - ), - }, -) - -def nvcf_java_library(name, **kwargs): - """Thin wrapper over java_library for NVCF Java code. - - Exists so services load a single NVCF entry point and so shared defaults - (for example Maven publishing) can be added here later without touching - every service BUILD file. - """ - java_library(name = name, **kwargs) diff --git a/rules/java/scripts/BUILD.bazel b/rules/java/scripts/BUILD.bazel deleted file mode 100644 index c52269c1d..000000000 --- a/rules/java/scripts/BUILD.bazel +++ /dev/null @@ -1,18 +0,0 @@ -# SPDX-FileCopyrightText: Copyright (c) NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# 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(default_visibility = ["//visibility:public"]) - -exports_files(["check_bom_alignment.sh"]) diff --git a/rules/java/scripts/check_bom_alignment.sh b/rules/java/scripts/check_bom_alignment.sh deleted file mode 100755 index a31bee8f7..000000000 --- a/rules/java/scripts/check_bom_alignment.sh +++ /dev/null @@ -1,31 +0,0 @@ -#!/usr/bin/env bash -# SPDX-FileCopyrightText: Copyright (c) NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# Asserts that every canonical Spring BOM coordinate (from platform.bzl, passed -# as a newline-delimited file) appears verbatim in the consuming module's -# MODULE.bazel. Keeps each Java module's inlined boms list aligned with the -# single source of truth, since load() cannot be used in MODULE.bazel. -set -euo pipefail - -module_bazel="$1" -canonical="$2" - -missing=0 -while IFS= read -r coord; do - [ -z "$coord" ] && continue - if ! grep -qF -- "$coord" "$module_bazel"; then - echo "BOM drift: canonical coordinate not found in MODULE.bazel:" >&2 - echo " $coord" >&2 - missing=1 - fi -done < "$canonical" - -if [ "$missing" -ne 0 ]; then - echo >&2 - echo "Every coordinate in @nvcf_java_rules//:platform.bzl SPRING_BOOT_BOM must" >&2 - echo "be inlined in this module's maven.install boms list. Re-align and re-pin." >&2 - exit 1 -fi - -echo "BOM alignment OK: $(grep -c . "$canonical") canonical coordinate(s) present." diff --git a/src/control-plane-services/cloud-tasks/.bazel_downloader_config b/src/control-plane-services/cloud-tasks/.bazel_downloader_config new file mode 100644 index 000000000..df8204c64 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/.bazel_downloader_config @@ -0,0 +1,4 @@ +# Prefer the Google Maven Central mirror for repository-rule downloads that +# hardcode repo1.maven.org. Coursier dependencies still use MODULE.bazel's +# maven.install repositories. +rewrite (repo1.maven.org)/(maven2/.*) https://maven-central.storage-download.googleapis.com/$2 diff --git a/src/control-plane-services/cloud-tasks/.bazelignore b/src/control-plane-services/cloud-tasks/.bazelignore new file mode 100644 index 000000000..e499616c3 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/.bazelignore @@ -0,0 +1,4 @@ +bazel-bin +bazel-cloud-tasks +bazel-out +bazel-testlogs diff --git a/src/control-plane-services/cloud-tasks/.bazelrc b/src/control-plane-services/cloud-tasks/.bazelrc index 3bf18b80d..c5b709b69 100644 --- a/src/control-plane-services/cloud-tasks/.bazelrc +++ b/src/control-plane-services/cloud-tasks/.bazelrc @@ -1,52 +1,14 @@ -# SPDX-FileCopyrightText: Copyright (c) NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# 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. +common --downloader_config=.bazel_downloader_config -# Standalone module .bazelrc. `cd rules/java && bazel build //...` must work with -# no reference to the repo root. The caller supplies any remote cache endpoint; -# no cache config is baked in (parity with the other nested modules). - -common --enable_bzlmod -common --enable_platform_specific_config -build --incompatible_strict_action_env - -# Route public Maven Central through an internal Artifactory mirror on internal -# builds only. The target host lives in an un-mirrored internal bazelrc, so -# public builds go straight to Maven Central (try-import is a no-op when absent). -try-import %workspace%/tools/bazel/internal.bazelrc - -# Java: use the image-provided local JDK 25 (Temurin at JAVA_HOME) instead of a -# hermetic remotejdk download; the bazel-ci image ships Temurin 25 (no download). +build --workspace_status_command=tools/bazel/workspace_status.sh +# rules_spring 2.6.3 still uses bare Java rules/providers in its own BUILD and +# .bzl files. Bazel 9 requires these symbols to be autoloaded for external repos. +common --incompatible_autoload_externally=+@rules_java build --java_language_version=25 -build --java_runtime_version=local_jdk build --tool_java_language_version=25 +build --java_runtime_version=local_jdk build --tool_java_runtime_version=local_jdk -build --java_header_compilation=false - -test --test_output=errors -test --test_env=HOME=/tmp -test --test_env=XDG_CACHE_HOME=/tmp/.cache - -startup --host_jvm_args=-Xmx4g - -build:release --compilation_mode=opt -build:release --strip=always - -try-import %workspace%/user.bazelrc -try-import %user.home%/.bazelrc.user -# gRPC/proto: register the prebuilt protoc toolchain instead of compiling the -# C++ protobuf compiler; allow the 33.0-vs-33.4 protoc skew (wire-compatible). -common --incompatible_enable_proto_toolchain_resolution -common --@com_google_protobuf//bazel/toolchains:allow_nonstandard_protoc +# Lombok onConstructor_ usage in nvct-core is not compatible with Bazel's +# Java header compiler (Turbine). Maven uses full javac, so keep Bazel aligned. +build --nojava_header_compilation diff --git a/src/control-plane-services/cloud-tasks/.bazelversion b/src/control-plane-services/cloud-tasks/.bazelversion new file mode 100644 index 000000000..44931da26 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/.bazelversion @@ -0,0 +1 @@ +9.1.1 diff --git a/src/control-plane-services/cloud-tasks/.gitignore b/src/control-plane-services/cloud-tasks/.gitignore index a6ef824c1..988853feb 100644 --- a/src/control-plane-services/cloud-tasks/.gitignore +++ b/src/control-plane-services/cloud-tasks/.gitignore @@ -1 +1,45 @@ -/bazel-* +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +# +# 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. +**/target +**/.settings/ +**/.metadata/ +**/.recommenders/ +*/.classpath +*/.project +*/bin +/nvidia.log +**/*.iml +*.idea +*.project +*.jtl +*.tern-project +*.log +*.pyc +*.txt +# OSS-prep file that must remain tracked despite the *.txt rule above. +!.allowed-licenses.txt +deploy.sh +*.swp +node_modules +**/results +.DS_Store +**/logs +**/tmp +/bazel-bin +/bazel-cloud-tasks +/bazel-out +/bazel-testlogs +.editorconfig +.sdkmanrc diff --git a/src/control-plane-services/cloud-tasks/AGENTS.md b/src/control-plane-services/cloud-tasks/AGENTS.md index 6977ca467..d73f49e14 100644 --- a/src/control-plane-services/cloud-tasks/AGENTS.md +++ b/src/control-plane-services/cloud-tasks/AGENTS.md @@ -1,39 +1,45 @@ -# AGENTS.md - nvct_cloud_tasks +# AGENTS.md - cloud_tasks The NVCF cloud-tasks Java (Spring Boot) service, as a standalone Bazel module -(`module(name = "nvct_cloud_tasks")`). Depends on `nvcf_java_rules` (shared -macros + multi-arch image helper) and `nv_boot_parent` (the Spring platform -starters), both via `bazel_dep` + `local_path_override`. +(`module(name = "cloud_tasks")`). Depends on `nv_boot_parent` (the Spring +platform starters) via `bazel_dep` plus `local_path_override`. Maven and Bazel +coexist; Maven stays the default build during coexistence. ## Build and test (from this directory) ``` cd src/control-plane-services/cloud-tasks -bazel build //... -bazel test //... --test_tag_filters=-requires-docker +export BAZEL_OUTPUT_USER_ROOT="${TMPDIR:-/tmp}/cloud-tasks-bazel-cache" +bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" build //... +bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" test //... --test_tag_filters=-requires-docker ``` -The module builds on its own with no reference to the repo root. The Spring + -Testcontainers integration tests are tagged `requires-docker` (and `exclusive`) -and run in the dedicated Docker integration lane, not the default fast matrix. +The module builds on its own with no reference to the repo root. The Spring plus +Testcontainers integration tests are tagged `requires-docker` and run in the +dedicated Docker integration lane, not the default fast matrix. -## Maven dependencies +## Dependency hub -Own `@maven` hub and own committed `maven_install.json`. After editing -`maven.install` in `MODULE.bazel`, re-pin and commit: +Third-party dependencies resolve through one shared hub named +`nv_third_party_deps` (never `@maven`). `maven.install` lists `nv_boot_parent` +in `known_contributing_modules`, so this service and the nv-boot starters +resolve a single merged third-party graph. This root owns and re-pins the merged +`maven_install.json`: ``` -REPIN=1 bazel run @maven//:pin +REPIN=1 bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" run @nv_third_party_deps//:pin ``` -The `boms` list must stay identical to `SPRING_BOOT_BOM` in -`@nvcf_java_rules//:platform.bzl`; `//:bom_alignment_test` enforces it. +Both `maven_install.json` and `MODULE.bazel.lock` are committed. Lombok needs +`build --java_header_compilation=false` (via `--nojava_header_compilation` in +this module's `.bazelrc`). ## Layout -- `nvct-core/` - service library plus the gRPC `nvct.proto` codegen - (`nvct_java_grpc_compile` in `tools/bazel/proto.bzl`, driven by the - `protoc-gen-grpc-java` native plugins declared in `MODULE.bazel`). -- `nvct-service/` - the `@SpringBootApplication` entry point and the - `nvcf_spring_boot_image` multi-arch OCI image target (`:image_index`). -- `tools/bazel/` - Lombok wiring, the gRPC plugin `proto_plugin`, JaCoCo runner. +- `nvct-core/` - service library plus the gRPC `nvct.proto` codegen (driven by + the `protoc-gen-grpc-java` native plugins declared in `MODULE.bazel` and the + macros in `tools/bazel/proto.bzl`). +- `nvct-service/` - the `@SpringBootApplication` entry point and the Spring Boot + executable app jar (`tools/bazel/spring_boot.bzl`). +- `tools/bazel/` - the `nv_boot_library` macros (`java.bzl`), Lombok wiring, the + gRPC plugin, the JaCoCo runner, and the NOTICE generator. diff --git a/src/control-plane-services/cloud-tasks/BAZEL.md b/src/control-plane-services/cloud-tasks/BAZEL.md new file mode 100644 index 000000000..b3992a08a --- /dev/null +++ b/src/control-plane-services/cloud-tasks/BAZEL.md @@ -0,0 +1,781 @@ +# Bazel + +This project is migrating from Maven to Bazel while both build systems coexist. +Maven remains available during the migration. + +For the Bazel path, consume `nv-boot-parent` directly as Bazel source targets +instead of consuming Bazel-produced Maven-shaped `com.nvidia.boot:*` artifacts +from URM. + +Hard rule for this migration: do not publish Maven-shaped jars from the Bazel +toolchain. Maven consumers should continue to use the Maven build/publish path +during coexistence. Bazel consumers should depend on Bazel targets. We initially +took a wrong turn by treating Maven artifact publication as required for Bazel +coexistence; after clarifying that Bazel apps can consume source targets +directly, we are correcting that path. + +Set one OS-neutral Bazel output root when opening a shell in this repository: + +```bash +export BAZEL_OUTPUT_USER_ROOT="${TMPDIR:-/tmp}/cloud-tasks-bazel-cache" +``` + +The commands below reuse this variable. It resolves under the operating +system's temporary directory instead of assuming the macOS-specific +`/private/tmp` path. + +## Understanding the Dependency Files + +Bazel uses three top-level files for dependency declarations and locking. A +simple way to remember their responsibilities is: + +```text +MODULE.bazel = what this repository wants +maven_install.json = exact third-party Java artifacts that were resolved +MODULE.bazel.lock = exact Bazel modules and module extensions that were resolved +``` + +### `MODULE.bazel` + +Developers edit this file. It declares the repository as a Bazel module and +contains inputs such as: + +- `bazel_dep` entries for Bazel rules and tooling; +- the pinned `git_override` for the nv-boot-parent source module; +- Maven-compatible BOMs and third-party Java dependency roots supplied to + `rules_jvm_external`; +- the shared `nv_third_party_deps` hub configuration. +- checksum-pinned repositories for native build tools that are not Java + dependencies. + +For someone familiar with Maven, this file serves some of the roles of the +root `pom.xml`, dependency management, and build-plugin configuration, but it +is not a POM and does not use Maven parent inheritance. + +### `maven_install.json` + +Do not edit this file manually. `rules_jvm_external` generates it when the +shared third-party hub is pinned. It records the resolved Java artifacts, +transitive dependency relationships, repository locations, checksums, and an +input signature. + +Its name contains `maven` because the external Java artifacts use Maven +coordinates and come from Maven-compatible repositories. It does not run a +Maven build, publish Cloud Tasks artifacts, or make the Bazel outputs +Maven-shaped. Maven does not normally have a direct checked-in equivalent to +this dependency lockfile. + +The `__INPUT_ARTIFACTS_HASH` and `__RESOLVED_ARTIFACTS_HASH` sections contain +signed 32-bit Java hash values used to detect dependency-input and resolution +drift. Negative numbers there are normal. They are not artifact checksums; +artifact integrity is recorded separately as hexadecimal SHA-256 values under +each artifact's `shasums` entry. + +After changing BOMs, third-party roots, or versions in `MODULE.bazel`, +regenerate it with: + +```bash +REPIN=1 bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ + run @nv_third_party_deps//:pin +``` + +### `MODULE.bazel.lock` + +Do not edit this file manually. Bazel generates and updates it for Bzlmod. It +locks the Bazel module graph and module-extension evaluation used to create +external repositories. For example, it records resolution associated with +rules such as `rules_java`, `rules_spring`, and `rules_jvm_external`; it is not +the lockfile for the Spring, Jackson, or other Java jars listed in +`maven_install.json`. + +Normal Bazel commands update this file when Bzlmod inputs change. + +### Commit Rules + +Commit all three files. When a dependency change updates more than one of +them, commit those changes together. The normal workflow is: + +1. Edit `MODULE.bazel`. +2. Repin `maven_install.json` when the third-party Java graph changes. +3. Run the build and tests, allowing Bazel to update `MODULE.bazel.lock`. +4. Review and commit every changed dependency file; never hand-edit either + lockfile. + +## Prerequisites + +- Bazel 9.1.1, preferably through Bazelisk honoring `.bazelversion`. +- Java 25. `.bazelrc` pins Bazel Java compilation and runtime to Java 25. +- Docker is required for the current `nvct-core` and `nvct-service` + integration tests. + +In `.bazelrc`, an option beginning with `common` applies to commands such as +`query`, `cquery`, `build`, and `test`; an option beginning with `build` applies +only to build and commands that inherit build options. The `rules_spring` +external Java-rule compatibility option is therefore under `common`, while the +Lombok header-compilation setting remains under `build`. + +Current Bazel-path nv-boot source dependency: + +```text +nv_boot_parent git_override commit bfd1db74fa6588cda53df364bfbbb14457221099 +``` + +The Bazel path consumes `nv-boot-parent` source targets directly and does not +list `com.nvidia.boot:nv-boot-bom` or `com.nvidia.boot:*` artifacts in +`MODULE.bazel`. + +## Dependency Updates + +### The Single Dependency Hub + +A third-party dependency hub is the external Bazel repository created by +`rules_jvm_external`. It contains targets for external jars such as Spring, +Jackson, gRPC, and Guava. `rules_jvm_external` currently obtains those jars +from Maven-compatible repositories, but that is an implementation detail of +dependency resolution, not the meaning of the hub name. + +Both `nv-boot-parent` and Cloud Tasks intentionally use: + +```python +maven.install( + name = "nv_third_party_deps", + ... +) +use_repo(maven, "nv_third_party_deps") +``` + +The same name is deliberate. In simple terms: + +1. `nv-boot-parent` contributes the third-party dependencies needed by its + libraries. +2. Cloud Tasks contributes the additional dependencies needed by the app. +3. Bzlmod and `rules_jvm_external` merge those contributions into one + `@nv_third_party_deps` repository. +4. The merged hub resolves one selected version of each third-party artifact + for the complete application. + +The name `nv_third_party_deps` is intentionally agnostic about build tool, +resolver, and runtime. The hub contains only third-party dependency targets. +It does not contain `nv-boot-parent`, `nvct-core`, or `nvct-service`; those are +consumed and built as first-party Bazel source targets. It also does not imply +that Bazel creates or publishes Maven-shaped project artifacts. + +`maven.install.name` names the generated hub. `use_repo` makes that generated +repository visible to BUILD files as `@nv_third_party_deps`. Cloud Tasks also +lists `nv_boot_parent` in `known_contributing_modules` to state that the +upstream module is expected to contribute third-party dependencies to this +hub. + +Using different names would create two independent dependency graphs. A final +Spring Boot app could then contain two versions of the same library or an +incompatible mixture from one dependency family. We observed exactly that: +the two-hub app was 218 MB, while the merged-hub app was 142 MB and closely +matched Maven's 142 MB app. The split graph also mixed gRPC 1.63 and 1.74, +causing missing-class failures at runtime. + +Therefore, do not add a second `maven.install` or rename the Cloud Tasks hub to +something project-specific. Add required roots to the existing +`nv_third_party_deps` install and repin it. + +### Local nv-boot-parent Override + +The shared hub itself is not locally overridden. The command-line override +replaces the first-party `nv_boot_parent` module, and that local module then +contributes its third-party dependency roots to `nv_third_party_deps`. + +A local override is appropriate only while developing unpushed +`nv-boot-parent` changes and validating them in Cloud Tasks. Supply an absolute +path to the local checkout: + +```bash +bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ + build \ + --override_module=nv_boot_parent=/absolute/path/to/nv-boot-parent \ + //... + +bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ + test \ + --override_module=nv_boot_parent=/absolute/path/to/nv-boot-parent \ + //... \ + --cache_test_results=no \ + --test_output=errors +``` + +If the local nv-boot-parent change modifies third-party dependency roots or +versions, repin against that same local checkout: + +```bash +REPIN=1 bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ + run \ + --override_module=nv_boot_parent=/absolute/path/to/nv-boot-parent \ + @nv_third_party_deps//:pin +``` + +Do not put a workstation path in `MODULE.bazel`, CI configuration, or shared +scripts. CI and final validation must omit `--override_module` and use the +committed `git_override` hash. + +An accidental or stale local override causes Bazel to ignore the committed +nv-boot-parent Git hash for that invocation. The build may then use dirty, +unpushed, or outdated source and a different contribution to the shared hub. +It can fail with a pin-signature error, or it can pass locally while producing +a result that CI cannot reproduce. Removing `--override_module` restores the +committed Git dependency. Before committing Cloud Tasks, always repin, build, +and test once without the override. + +### Updating Dependencies + +After changing third-party roots or versions in `MODULE.bazel`, repin with: + +```bash +REPIN=1 bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ + run @nv_third_party_deps//:pin +``` + +Then run the normal build and tests. Commit `MODULE.bazel` and +`maven_install.json` together. Commit `MODULE.bazel.lock` too if Bzlmod changes +it. + +The project intentionally pins gRPC runtime and code generation to 1.63.0. +`rules_proto_grpc_java` 5.8.0 bundles a newer 1.74 generator, so +`tools/bazel/proto.bzl` keeps the upstream compile implementation but selects +the matching 1.63 executable fetched by checksum-pinned `http_file` +repositories. These native executables intentionally stay outside +`nv_third_party_deps`, which has `fetch_sources = True` for Java +dependencies. `rules_jvm_external` 7.0 cannot repin that setting when an +executable-classifier artifact advertises a missing source jar. When upgrading +gRPC, change the single `GRPC_VERSION`, update all platform checksums, repin, +and rerun the full test suite. + +Use the same output root for local commands so Bazel cache/output data stays +outside the checkout: + +```bash +--output_user_root="${BAZEL_OUTPUT_USER_ROOT}" +``` + +## Build Everything + +Build all current Bazel targets: + +```bash +bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ + build //... \ + --verbose_failures +``` + +Bazel builds dependencies automatically. You do not need to run a separate +build before `bazel test` unless you want compile-only feedback. + +## Build `nvct-core` + +Build the main `nvct-core` library: + +```bash +bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ + build //nvct-core:nvct_core \ + --verbose_failures +``` + +The current Bazel library jar is: + +```text +bazel-bin/nvct-core/libnvct_core.jar +``` + +Build the `nvct-core` test-fixtures target consumed by `nvct-service` tests: + +```bash +bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ + build //nvct-core:nvct_core_test_fixtures \ + --verbose_failures +``` + +The current Bazel test-fixtures jar is: + +```text +bazel-bin/nvct-core/libnvct_core_test_fixtures.jar +``` + +This is a Bazel-native library target, not a Maven `tests` classifier artifact. +Maven consumers keep using the Maven build during coexistence. + +## Build `nvct-service` + +Build the private `nvct-service` application classes target for compile-only +feedback: + +```bash +bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ + build //nvct-service:app_classes \ + --verbose_failures +``` + +That target exists only to compile the Spring Boot application classes/resources +and to feed tests and packaging. It is not a product artifact. + +Build the Bazel-native Spring Boot executable jar: + +```bash +bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ + build //nvct-service:app \ + --verbose_failures +``` + +The app jar is: + +```text +bazel-bin/nvct-service/app.jar +``` + +The jar is produced by `tools/bazel/spring_boot.bzl`, which delegates Spring +Boot executable packaging to `rules_spring` and then injects the small set of +metadata files that Maven plugins used to contribute: + +```text +BOOT-INF/classes/git.properties +BOOT-INF/classes/maven.properties +META-INF/maven/com.nvidia.nvct/nvct-service-oss/pom.properties +``` + +The metadata merge uses the platform-specific `singlejar` executable supplied +by `rules_java`. It must not invoke a host `jar` command or depend on +`JAVA_HOME`: CI images can provide Bazel and Java 25 while omitting JDK utility +commands from `PATH`. + +It keeps Spring Boot loader classes at the jar root and places runtime jars +under `BOOT-INF/lib`. It is intentionally separate from Maven's +`nvct-service/target/app.jar` while Maven and Bazel coexist. + +`git.properties` is generated from Bazel workspace status, replacing the app +jar portion of `git-commit-id-maven-plugin` behavior for the Bazel path. The +current generated keys match the keys used by nv-boot startup code: + +```text +git.closest.tag.name +git.commit.id.abbrev +git.commit.id.full +git.tags +``` + +Quick local launch smoke: + +```bash +java -jar bazel-bin/nvct-service/app.jar \ + --spring.main.web-application-type=none \ + --spring.main.banner-mode=off \ + --logging.level.root=OFF \ + --spring.main.lazy-initialization=true +``` + +Without `spring.profiles.active`, this is expected to fail during nv-boot +environment validation. That failure still proves the app jar can load the +Spring Boot launcher, app classes, and runtime dependencies. + +## Build and Run the Docker Image + +Run these commands from the cloud-tasks repository root. + +First, build the Spring Boot executable jar: + +```bash +bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ + build //nvct-service:app \ + --verbose_failures +``` + +Resolve the real Bazel output directory and use the `nvct-service` output +directory as the Docker build context: + +```bash +BAZEL_BIN_DIR="$( + bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" info bazel-bin +)" + +docker build \ + -f nvct-service/Dockerfile \ + --build-arg APP_JAR=app.jar \ + -t nvct-service:bazel \ + "${BAZEL_BIN_DIR}/nvct-service" +``` + +Using the resolved output directory is necessary because the workspace +`bazel-bin` path is a symlink to Bazel's output tree outside the repository. +Docker cannot follow that symlink through a repository-root build context. + +Start the local Cassandra dependency: + +```bash +docker compose -f local_env/docker-compose.yml up -d +``` + +Run the application container with the `local` Spring profile: + +```bash +docker run --rm \ + --name nvct-service \ + --mount "type=bind,source=$(pwd),target=/home/app,readonly" \ + -e SPRING_PROFILES_ACTIVE=local \ + -e SPRING_CASSANDRA_CONTACT_POINTS=host.docker.internal \ + -p 8080:8080 \ + -p 9090:9090 \ + -p 8181:8181 \ + nvct-service:bazel +``` + +The repository bind mount makes `local_env/vault/secrets.json` available at +`/home/app/local_env/vault/secrets.json`. The Cassandra contact point uses +Docker Desktop's host address because `127.0.0.1` inside the application +container refers to the application container itself. + +After stopping the application, stop the local Cassandra dependency: + +```bash +docker compose -f local_env/docker-compose.yml down +``` + +Omitting the Docker build argument keeps the Dockerfile's Maven-build default, +`nvct-service/target/app.jar`, during coexistence. + +## Test Everything + +Run all current Bazel test targets without using cached test results: + +```bash +bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ + test //... \ + --cache_test_results=no \ + --test_output=errors \ + --test_env=DOCKER_HOST \ + --test_env=DOCKER_TLS_VERIFY \ + --test_env=DOCKER_TLS_CERTDIR \ + --test_env=DOCKER_CERT_PATH \ + --verbose_failures +``` + +Current Bazel test targets are: + +```text +//nvct-core:tests +//nvct-service:tests +``` + +Both are tagged `exclusive` because they use the same fixed-port local +integration environment. Without that, `bazel test //...` can run them in +parallel and collide on ports such as WireMock `9092`. + +## Test `nvct-core` + +Run the full `nvct-core` test target: + +```bash +bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ + test //nvct-core:tests \ + --cache_test_results=no \ + --test_output=errors \ + --test_env=DOCKER_HOST \ + --test_env=DOCKER_TLS_VERIFY \ + --test_env=DOCKER_TLS_CERTDIR \ + --test_env=DOCKER_CERT_PATH \ + --verbose_failures +``` + +The full `nvct-core` test target currently runs JUnit through +`org.junit.platform.console.ConsoleLauncher`. + +## Test `nvct-service` + +Run the `nvct-service` Spring Boot smoke/integration test target: + +```bash +bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ + test //nvct-service:tests \ + --cache_test_results=no \ + --test_output=errors \ + --test_env=DOCKER_HOST \ + --test_env=DOCKER_TLS_VERIFY \ + --test_env=DOCKER_TLS_CERTDIR \ + --test_env=DOCKER_CERT_PATH \ + --verbose_failures +``` + +The test target starts the `App` context with the `nvct-core` test fixture +configuration and validates `/health` plus `/actuator/health`. + +## Test One Test File + +Convert the test source path to its fully qualified class name. + +Example: + +```text +nvct-core/src/test/java/com/nvidia/nvct/service/apikeys/ApiKeyValidationResultTest.java +``` + +becomes: + +```text +com.nvidia.nvct.service.apikeys.ApiKeyValidationResultTest +``` + +Run only that test class: + +```bash +bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ + test //nvct-core:tests \ + --cache_test_results=no \ + --test_output=errors \ + --test_env=DOCKER_HOST \ + --test_env=DOCKER_TLS_VERIFY \ + --test_env=DOCKER_TLS_CERTDIR \ + --test_env=DOCKER_CERT_PATH \ + --test_arg=--exclude-classname='^(?!com\.nvidia\.nvct\.service\.apikeys\.ApiKeyValidationResultTest$).*$' \ + --verbose_failures +``` + +Replace the class name in the regular expression for other test files. Keep +dots escaped as `\.`. + +## Test One Method + +Run one test method by combining a class filter with a method-name filter: + +```bash +bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ + test //nvct-core:tests \ + --cache_test_results=no \ + --test_output=errors \ + --test_env=DOCKER_HOST \ + --test_env=DOCKER_TLS_VERIFY \ + --test_env=DOCKER_TLS_CERTDIR \ + --test_env=DOCKER_CERT_PATH \ + --test_arg=--exclude-classname='^(?!com\.nvidia\.nvct\.service\.apikeys\.ApiKeyValidationResultTest$).*$' \ + --test_arg=--include-methodname='.*#allAllowedTasksAccount$' \ + --verbose_failures +``` + +For parameterized tests, use the Java method name; JUnit will run the matching +invocations for that method. + +Example: + +```bash +bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ + test //nvct-core:tests \ + --cache_test_results=no \ + --test_output=errors \ + --test_arg=--exclude-classname='^(?!com\.nvidia\.nvct\.service\.apikeys\.ApiKeyValidationResultTest$).*$' \ + --test_arg=--include-methodname='.*#allAllowedTasks$' \ + --verbose_failures +``` + +## Test Logs + +Bazel writes test logs under: + +```text +bazel-testlogs/<module>/tests/ +``` + +Useful files: + +```text +bazel-testlogs/nvct-core/tests/test.log +bazel-testlogs/nvct-core/tests/test.outputs/junit/TEST-junit-jupiter.xml +bazel-testlogs/nvct-service/tests/test.log +bazel-testlogs/nvct-service/tests/test.outputs/junit/TEST-junit-jupiter.xml +``` + +The Jupiter XML files contain the real Java testcases and are the reports +published by GitLab. The nearby `tests/test.xml` files describe Bazel's single +outer `sh_test` wrapper and must not be used as JUnit reports. + +Use `--cache_test_results=no` when you want to force the tests to run again. + +Use `--test_output=streamed` instead of `--test_output=errors` when you want to +watch test output live: + +```bash +bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ + test //nvct-core:tests \ + --cache_test_results=no \ + --test_output=streamed \ + --test_env=DOCKER_HOST \ + --test_env=DOCKER_TLS_VERIFY \ + --test_env=DOCKER_TLS_CERTDIR \ + --test_env=DOCKER_CERT_PATH +``` + +## Coverage And Sonar XML + +Coverage generation is part of `//nvct-core:tests` and +`//nvct-service:tests`; no separate coverage command is required. Running a +test with `--cache_test_results=no` refreshes these outputs: + +```text +bazel-testlogs/nvct-core/tests/test.outputs/index.html +bazel-testlogs/nvct-core/tests/test.outputs/jacoco.xml +bazel-testlogs/nvct-core/tests/test.outputs/jacoco.exec +bazel-testlogs/nvct-service/tests/test.outputs/index.html +bazel-testlogs/nvct-service/tests/test.outputs/jacoco.xml +bazel-testlogs/nvct-service/tests/test.outputs/jacoco.exec +``` + +The test JVM runs the JaCoCo agent with `dumponexit=true`. After JUnit exits, +the Bazel shell test preserves the JUnit status and invokes the Bazel-declared +JaCoCo CLI to generate XML and HTML. This uses no custom Java coverage launcher +and no JaCoCo internal runtime API. + +Open `index.html` for the JaCoCo HTML report. Sonar consumes the corresponding +`jacoco.xml`, for example: + +```text +-Dsonar.coverage.jacoco.xmlReportPaths=bazel-testlogs/nvct-core/tests/test.outputs/jacoco.xml,bazel-testlogs/nvct-service/tests/test.outputs/jacoco.xml +``` + +Class and method filters also produce reports, but those reports describe only +the selected test execution. + +## License/NOTICE Generation + +This is the Bazel-native replacement for the aggregate third-party inventory +previously produced through `license-maven-plugin`. It covers third-party +runtime dependency names, versions, declared licenses, and project URLs. It is +separate from source-file license-header enforcement. + +The canonical root `NOTICE` is derived from the third-party jars actually +nested in `//nvct-service:app`. This makes the executable application, rather +than a manually maintained dependency list, the source of truth. The generator +does not read project POM files and does not invoke Maven. + +License metadata is checked into +`tools/bazel/notice_metadata.json`. Keeping this metadata in the repository +makes normal NOTICE checks deterministic and allows CI to fail when the runtime +graph changes without a corresponding NOTICE update. + +### Regenerate NOTICE + +Regenerate `NOTICE` and fetch metadata for newly encountered runtime +coordinates: + +```bash +bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ + run //:generate_notice -- --update-metadata --write +``` + +This command builds `//nvct-service:app` automatically, inspects its +`BOOT-INF/lib` jars, refreshes missing license metadata, and writes: + +```text +NOTICE +tools/bazel/notice_metadata.json +``` + +Run it whenever `MODULE.bazel`, `maven_install.json`, or an application runtime +dependency changes. Commit both generated files when both change. + +### Check Committed NOTICE + +Check that the committed NOTICE and metadata match the current app runtime: + +```bash +bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ + test //tools/bazel:notice_check_test \ + --cache_test_results=no \ + --test_output=errors +``` + +For an interactive check through the generator entrypoint: + +```bash +bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ + run //:generate_notice -- --check +``` + +`//tools/bazel:notice_check_test` is also part of `bazel test //...` and the +opt-in Bazel CI job. + +### Build A NOTICE Artifact + +Build a generated NOTICE artifact without modifying the checkout: + +```bash +bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ + build //:third_party_notice +``` + +The output is `bazel-bin/THIRD_PARTY_NOTICE`. It is useful for packaging or +inspection; the checked-in root `NOTICE` remains the reviewable canonical copy. + +## Opt-In CI + +Maven remains the default CI path. To add the Bazel build/test job to a +pipeline, set this GitLab CI/CD variable when starting the pipeline or in an MR +pipeline configuration: + +```yaml +ENABLE_BAZEL_BUILD: "true" +``` + +The `bazel-build-test` job uses Bazelisk with `.bazelversion`, Java 25, and a +Docker-in-Docker service. It runs all Bazel tests without cached test results, +builds all targets, checks NOTICE, and retains `app.jar`, JUnit XML, JaCoCo +HTML/XML, and other Bazel outputs for seven days. It also writes +`bazel-sonar.properties` with the discovered JaCoCo XML paths. + +CI intentionally sets `BAZEL_OUTPUT_USER_ROOT` under `/builds`, outside +`CI_PROJECT_DIR`. With the Kubernetes executor, `/builds` is shared by the job +container and Docker-in-Docker service, while each container has its own +`/tmp`. Testcontainers Compose bind mounts originate inside Bazel's test +sandbox, so a `/tmp` output root makes those files invisible to the Docker +daemon and causes file-versus-directory mount errors. + +There is intentionally no Bazel publish/deploy job. During coexistence, Maven +continues to own Maven artifact publication; the Bazel application consumes +`nv-boot-parent` source targets and produces the container input app jar. + +### Opt-In Bazel Docker Publication + +To prove container publication from the Bazel-built application, set: + +```yaml +ENABLE_BAZEL_DOCKER_PUBLISH: "true" +``` + +This flag also enables `bazel-build-test`, so `ENABLE_BAZEL_BUILD` does not +need to be set separately. It does not replace or disable the default Maven +jobs. The isolated proof path is: + +1. `compute-next-release-version` supplies `NEXT_VERSION`. +2. `bazel-build-test` embeds that value in `maven.properties` and + `pom.properties`, archives `app.jar`, and records its SHA-256. +3. `bazel-docker-build` downloads that artifact, builds and pushes + `nvct-service-oss-bazel-validation` to the GitLab registry, pulls it back, + extracts `/usr/share/app.jar`, and compares its checksum and metadata with + the archived Bazel jar. +4. `bazel-pulse-scan` scans the isolated validation image. +5. `bazel-docker-push-ngc` is a manual job that reuses the existing NGC + publication path. + +An MR image tag remains `mr.<iid>-<commit-short-sha>`; a non-MR image uses +`NEXT_VERSION`. The separate validation image name prevents this proof from +overwriting the Maven-produced `nvct-service-oss` image. Verification evidence +is retained under the `bazel-docker-build` job artifacts. + +This publishes a container application product, not Maven-shaped jars or POMs. +There remains no Bazel Maven artifact publication path. + +## Clean + +Clean Bazel outputs for this workspace: + +```bash +bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" clean +``` + +Use `expunge` sparingly because it removes the whole output base and forces +dependency/tool re-fetching: + +```bash +bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" clean --expunge +``` diff --git a/src/control-plane-services/cloud-tasks/BUILD.bazel b/src/control-plane-services/cloud-tasks/BUILD.bazel index a7dffab12..e3e5e9619 100644 --- a/src/control-plane-services/cloud-tasks/BUILD.bazel +++ b/src/control-plane-services/cloud-tasks/BUILD.bazel @@ -1,19 +1,13 @@ -load("@nvcf_java_rules//:bom_alignment.bzl", "bom_alignment_test") -load("//tools/bazel:runfiles.bzl", "nvct_workspace_runfiles") +load("@rules_shell//shell:sh_binary.bzl", "sh_binary") +load("//tools/bazel:java.bzl", "nvct_workspace_runfiles") package(default_visibility = ["//visibility:public"]) exports_files([ - "MODULE.bazel", "NOTICE", + "maven_install.json", ]) -# Fails the build if this module's inlined maven.install boms drift from the -# canonical SPRING_BOOT_BOM in @nvcf_java_rules//:platform.bzl. -bom_alignment_test( - name = "bom_alignment_test", -) - filegroup( name = "integration_local_env_files", srcs = [ @@ -27,17 +21,33 @@ filegroup( nvct_workspace_runfiles( name = "integration_local_env", srcs = [":integration_local_env_files"], - # After the umbrella relocation the runfiles short_path carries the subtree - # prefix; strip it so integration tests still resolve local_env/... relative - # to the runfiles root (test config references local_env/vault/secrets.json). - strip_prefix = "", ) -# NOTE: THIRD_PARTY_NOTICE generation (the former notice genrule, generate -# binary, and tools/bazel notice check) read the Spring fat jar -# (nvct-service app jar, BOOT-INF/lib/external/... layout). Converging onto -# @nvcf_java_rules's exploded-classpath image removes that fat jar, so the fat-jar -# NOTICE mechanism no longer has an input. Reworking NOTICE generation for the -# exploded classpath is tracked as follow-up; it needs a change to the shared -# nv-boot generate_notice.py, which is out of scope for this build-wiring -# convergence. +genrule( + name = "third_party_notice", + srcs = [ + ":maven_install.json", + "//nvct-service:app", + "//tools/bazel:notice_metadata.json", + "@nv_boot_parent//tools/bazel:generate_notice.py", + ], + outs = ["THIRD_PARTY_NOTICE"], + cmd = """ +python3 "$(location @nv_boot_parent//tools/bazel:generate_notice.py)" \ + --maven-install "$(location :maven_install.json)" \ + --metadata "$(location //tools/bazel:notice_metadata.json)" \ + --runtime-jar "$(location //nvct-service:app)" \ + --first-party-group com.nvidia.nvct \ + --output "$@" \ + --write +""", +) + +sh_binary( + name = "generate_notice", + srcs = ["//tools/bazel:generate_notice.sh"], + data = [ + "//nvct-service:app", + "@nv_boot_parent//tools/bazel:generate_notice.py", + ], +) diff --git a/src/control-plane-services/cloud-tasks/MODULE.bazel b/src/control-plane-services/cloud-tasks/MODULE.bazel index 3bb5eb33b..f29c501cb 100644 --- a/src/control-plane-services/cloud-tasks/MODULE.bazel +++ b/src/control-plane-services/cloud-tasks/MODULE.bazel @@ -1,73 +1,28 @@ -# SPDX-FileCopyrightText: Copyright (c) NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# 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. +module(name = "cloud_tasks") -"""nvct_cloud_tasks: the NVCF cloud-tasks Java service, as a standalone module. - -Depends on nvcf_java_rules (shared macros + image helper) and nv_boot_parent -(the Spring platform starters), both via bazel_dep + local_path_override in-tree. -Resolves its own @maven graph into its own committed maven_install.json and -builds on its own: `cd src/control-plane-services/cloud-tasks && bazel build //...`. - -The boms list in maven.install is inlined (load() is forbidden in MODULE.bazel) -and must stay identical to SPRING_BOOT_BOM in @nvcf_java_rules//:platform.bzl; -//:bom_alignment_test enforces that. -""" - -module( - name = "nvct_cloud_tasks", - version = "1.0.0", -) - -bazel_dep(name = "nvcf_java_rules", version = "0.1.0") -local_path_override( - module_name = "nvcf_java_rules", - path = "../../../rules/java", -) - -bazel_dep(name = "nv_boot_parent", version = "4.0.7") -local_path_override( - module_name = "nv_boot_parent", - path = "../../libraries/java/nv-boot-parent", -) +GRPC_VERSION = "1.63.0" bazel_dep(name = "rules_java", version = "9.3.0") bazel_dep(name = "rules_jvm_external", version = "7.0") -bazel_dep(name = "contrib_rules_jvm", version = "0.33.0") - -# gRPC-Java codegen: rules_proto_grpc_java drives protoc-gen-grpc-java (fetched -# as native binaries below) to generate the nvct.proto stubs. protobuf provides -# the well-known types; toolchains_protoc registers a prebuilt protoc so the -# proto_library does not compile the C++ protobuf compiler from source. -bazel_dep(name = "protobuf", version = "33.4", repo_name = "com_google_protobuf") -bazel_dep(name = "toolchains_protoc", version = "0.6.1") bazel_dep(name = "rules_proto_grpc", version = "5.8.0") bazel_dep(name = "rules_proto_grpc_java", version = "5.8.0") +bazel_dep(name = "rules_shell", version = "0.8.0") +bazel_dep(name = "rules_spring", version = "2.6.3") +bazel_dep(name = "protobuf", version = "33.4") +bazel_dep(name = "nv_boot_parent", version = "0.0.0") -protoc = use_extension("@toolchains_protoc//protoc:extensions.bzl", "protoc") -protoc.toolchain( - google_protobuf = "com_google_protobuf", - version = "v33.0", +local_path_override( + module_name = "nv_boot_parent", + path = "../../libraries/java/nv-boot-parent", ) -GRPC_VERSION = "1.63.0" - http_file = use_repo_rule( "@bazel_tools//tools/build_defs/repo:http.bzl", "http_file", ) +# The gRPC generator is a native executable, not a Java dependency. Keep it +# outside the shared Maven hub so fetch_sources applies only to Java artifacts. http_file( name = "grpc_java_plugin_linux_aarch_64", downloaded_file_path = "protoc-gen-grpc-java.exe", @@ -125,105 +80,75 @@ http_file( maven = use_extension("@rules_jvm_external//:extensions.bzl", "maven") maven.install( - name = "maven", + name = "nv_third_party_deps", + # Phase 1 keeps this list to root coordinates needed to compile nvct-core. + # Versions are omitted when inherited from the imported Maven BOMs/parents. + # Project-local Maven property pins stay explicit here. artifacts = [ - # nv-boot-parent third-party closure (Spring Boot 4 / Spring Cloud / - # OTel / Cassandra / Testcontainers). Root coordinates only: BOM-managed - # starters/modules, parent-owned explicit pins, and build/test tools. - "at.yawk.lz4:lz4-java:1.10.3", - "com.github.ben-manes.caffeine:guava", - "com.github.java-json-tools:json-patch:1.13", - "commons-codec:commons-codec", - "io.cloudevents:cloudevents-core:4.1.1", - "io.cloudevents:cloudevents-json-jackson:4.1.1", - "io.micrometer:micrometer-tracing-bridge-otel", - "io.nats:jnats:2.23.0", - "io.opentelemetry:opentelemetry-exporter-otlp", - "io.opentelemetry:opentelemetry-sdk-testing", - "jakarta.servlet:jakarta.servlet-api", - "org.apache.cassandra:java-driver-metrics-micrometer", - "org.apache.commons:commons-lang3:3.20.0", - "org.bouncycastle:bcprov-jdk18on:1.84", - "org.jacoco:org.jacoco.agent:jar:runtime:0.8.14", - "org.jacoco:org.jacoco.cli:0.8.14", - "org.junit.platform:junit-platform-console-standalone:6.0.3", - "org.ow2.asm:asm-analysis:9.9", - "org.ow2.asm:asm-util:9.9", - "org.projectlombok:lombok", - "org.springdoc:springdoc-openapi-starter-webflux-api:3.0.3", - "org.springdoc:springdoc-openapi-starter-webmvc-api:3.0.3", - "org.springframework.boot:spring-boot-micrometer-tracing-opentelemetry", - "org.springframework.boot:spring-boot-restclient", - "org.springframework.boot:spring-boot-starter", - "org.springframework.boot:spring-boot-starter-actuator", - "org.springframework.boot:spring-boot-starter-actuator-test", - "org.springframework.boot:spring-boot-starter-data-cassandra", - "org.springframework.boot:spring-boot-starter-data-cassandra-test", - "org.springframework.boot:spring-boot-starter-jackson", - "org.springframework.boot:spring-boot-starter-security-oauth2-client", - "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server", - "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server-test", - "org.springframework.boot:spring-boot-starter-test", - "org.springframework.boot:spring-boot-starter-validation", - "org.springframework.boot:spring-boot-starter-webflux", - "org.springframework.boot:spring-boot-starter-webflux-test", - "org.springframework.boot:spring-boot-starter-webmvc-test", - "org.springframework.boot:spring-boot-webclient", - "org.springframework.cloud:spring-cloud-commons", - "org.springframework.cloud:spring-cloud-context", - "org.springframework.cloud:spring-cloud-starter-bootstrap", - "org.springframework.security:spring-security-test", - "org.testcontainers:testcontainers-cassandra", - "org.testcontainers:testcontainers-junit-jupiter", - "org.wiremock:wiremock-standalone:3.13.2", - "software.amazon.awssdk:regions:2.40.1", - "tools.jackson.module:jackson-module-blackbird", - # examples/java-spring-boot-service (versions from the Spring Boot BOM). - "org.springframework.boot:spring-boot-starter-web", - "org.junit.jupiter:junit-jupiter-api", - "org.junit.jupiter:junit-jupiter-engine", - "org.junit.platform:junit-platform-launcher", - "org.junit.platform:junit-platform-reporting", - # cloud-tasks service closure. Version-less coordinates are managed by - # the BOMs above (spring-boot 4.0.7 / spring-cloud 2025.1.2 / - # testcontainers 2.0.5 / shedlock 7.7.0). Explicit versions match the - # cloud-tasks standalone module; io.grpc pins track GRPC_VERSION. "com.bucket4j:bucket4j_jdk17-core:8.19.0", "com.github.ben-manes.caffeine:caffeine", + "com.github.ben-manes.caffeine:guava", + # Keep Java protobuf runtime aligned with the Bazel protobuf generator. "com.google.protobuf:protobuf-java:4.33.4", "com.google.protobuf:protobuf-java-util:4.33.4", "io.grpc:grpc-api:%s" % GRPC_VERSION, "io.grpc:grpc-protobuf:%s" % GRPC_VERSION, "io.grpc:grpc-stub:%s" % GRPC_VERSION, "io.micrometer:micrometer-registry-prometheus", + "io.opentelemetry:opentelemetry-sdk-testing", "io.projectreactor.netty:reactor-netty-core", "io.projectreactor.netty:reactor-netty-http", + "jakarta.servlet:jakarta.servlet-api", "javax.annotation:javax.annotation-api:1.3.2", "net.devh:grpc-server-spring-boot-starter:3.1.0.RELEASE", "net.javacrumbs.shedlock:shedlock-provider-cassandra", "net.javacrumbs.shedlock:shedlock-spring", + "org.apache.cassandra:java-driver-metrics-micrometer", "org.assertj:assertj-core", "org.awaitility:awaitility", + "org.junit.jupiter:junit-jupiter-api", "org.junit.jupiter:junit-jupiter-params", + "org.junit.platform:junit-platform-console-standalone:6.0.3", + # Direct Bazel test-tool dependency; Spring Boot's BOM does not manage it. + "org.jacoco:org.jacoco.agent:jar:runtime:0.8.14", + "org.jacoco:org.jacoco.cli:0.8.14", "org.mockito:mockito-core", "org.mockito:mockito-junit-jupiter", + # JaCoCo report generation needs a Java 25-capable ASM family. Legacy + # jnr/accessors-smart edges otherwise select ASM 5.0.3 at runtime. "org.ow2.asm:asm:9.9", + "org.ow2.asm:asm-analysis:9.9", "org.ow2.asm:asm-commons:9.9", "org.ow2.asm:asm-tree:9.9", - "org.springframework:spring-context-support", - "org.springframework:spring-webflux", + "org.ow2.asm:asm-util:9.9", + "org.projectlombok:lombok", + "org.springdoc:springdoc-openapi-starter-webmvc-api:3.0.3", "org.springframework.boot:spring-boot-actuator", - "org.springframework.boot:spring-boot-loader", "org.springframework.boot:spring-boot-micrometer-metrics", "org.springframework.boot:spring-boot-micrometer-tracing", + "org.springframework.boot:spring-boot-micrometer-tracing-opentelemetry", "org.springframework.boot:spring-boot-opentelemetry", + "org.springframework.boot:spring-boot-loader", + "org.springframework.boot:spring-boot-restclient", + "org.springframework.boot:spring-boot-starter-data-cassandra-test", "org.springframework.boot:spring-boot-starter-aspectj", + "org.springframework.boot:spring-boot-starter-jackson", "org.springframework.boot:spring-boot-starter-security", + "org.springframework.boot:spring-boot-starter-security-oauth2-client", + "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server", + "org.springframework.boot:spring-boot-starter-validation", + "org.springframework.boot:spring-boot-starter-webmvc-test", "org.springframework.boot:spring-boot-starter-webmvc", + "org.springframework.boot:spring-boot-webclient", "org.springframework.cloud:spring-cloud-starter-kubernetes-client-config", "org.springframework.retry:spring-retry", + "org.springframework:spring-context-support", + "org.springframework:spring-webflux", "org.testcontainers:testcontainers", + "org.testcontainers:testcontainers-cassandra", "org.testcontainers:testcontainers-localstack", + "org.wiremock:wiremock-standalone:3.13.2", + "tools.jackson.module:jackson-module-blackbird", ], boms = [ "net.javacrumbs.shedlock:shedlock-bom:7.7.0", @@ -234,20 +159,15 @@ maven.install( fail_on_missing_checksum = True, fetch_sources = True, known_contributing_modules = [ + "nv_boot_parent", "protobuf", "rules_proto_grpc_java", ], lock_file = "//:maven_install.json", repositories = [ - # Public Central mirrors only. This is the public GitHub mirror; its - # hosted runners cannot resolve the internal Artifactory host, so the - # pinned closure must fetch from public repositories. The Google-hosted - # Central mirror is primary (not IP-rate-limited like repo1.maven.org); - # Maven Central is the fallback. Internal builds that need NVIDIA - # artifacts add the Artifactory virtual repo in their own overlay. "https://maven-central.storage-download.googleapis.com/maven2", "https://repo.maven.apache.org/maven2", ], resolver = "maven", ) -use_repo(maven, "maven") +use_repo(maven, "nv_third_party_deps") diff --git a/src/control-plane-services/cloud-tasks/MODULE.bazel.lock b/src/control-plane-services/cloud-tasks/MODULE.bazel.lock index 2683917c6..3c94c79ec 100644 --- a/src/control-plane-services/cloud-tasks/MODULE.bazel.lock +++ b/src/control-plane-services/cloud-tasks/MODULE.bazel.lock @@ -1,5 +1,5 @@ { - "lockFileVersion": 28, + "lockFileVersion": 26, "registryFileHashes": { "https://bcr.bazel.build/bazel_registry.json": "8a28e4aff06ee60aed2a8c281907fb8bcbf3b753c91fb5a5c57da3215d5b3497", "https://bcr.bazel.build/modules/abseil-cpp/20210324.2/MODULE.bazel": "7cd0312e064fde87c8d1cd79ba06c876bd23630c83466e9500321be55c96ace2", @@ -17,8 +17,6 @@ "https://bcr.bazel.build/modules/abseil-cpp/20250814.1/source.json": "cea3901d7e299da7320700abbaafe57a65d039f10d0d7ea601c4a66938ea4b0c", "https://bcr.bazel.build/modules/abseil-py/2.1.0/MODULE.bazel": "5ebe5bf853769c65707e5c28f216798f7a4b1042015e6a36e6d03094d94bec8a", "https://bcr.bazel.build/modules/abseil-py/2.1.0/source.json": "0e8fc4f088ce07099c1cd6594c20c7ddbb48b4b3c0849b7d94ba94be88ff042b", - "https://bcr.bazel.build/modules/apple_rules_lint/0.4.0/MODULE.bazel": "c59831c3a5389430516203777816527f257329a5da363994e1d62b9ae6729f71", - "https://bcr.bazel.build/modules/apple_rules_lint/0.4.0/source.json": "105883202602181f43f109372e1b9ea19e89bbe3bce4bc1fe9bb0baa51eb61ae", "https://bcr.bazel.build/modules/apple_support/1.11.1/MODULE.bazel": "1843d7cd8a58369a444fc6000e7304425fba600ff641592161d9f15b179fb896", "https://bcr.bazel.build/modules/apple_support/1.15.1/MODULE.bazel": "a0556fefca0b1bb2de8567b8827518f94db6a6e7e7d632b4c48dc5f865bc7c85", "https://bcr.bazel.build/modules/apple_support/1.21.0/MODULE.bazel": "ac1824ed5edf17dee2fdd4927ada30c9f8c3b520be1b5fd02a5da15bc10bff3e", @@ -30,7 +28,6 @@ "https://bcr.bazel.build/modules/aspect_bazel_lib/2.19.3/MODULE.bazel": "253d739ba126f62a5767d832765b12b59e9f8d2bc88cc1572f4a73e46eb298ca", "https://bcr.bazel.build/modules/aspect_bazel_lib/2.21.2/MODULE.bazel": "276347663a25b0d5bd6cad869252bea3e160c4d980e764b15f3bae7f80b30624", "https://bcr.bazel.build/modules/aspect_bazel_lib/2.21.2/source.json": "f42051fa42629f0e59b7ac2adf0a55749144b11f1efcd8c697f0ee247181e526", - "https://bcr.bazel.build/modules/aspect_bazel_lib/2.7.2/MODULE.bazel": "780d1a6522b28f5edb7ea09630748720721dfe27690d65a2d33aa7509de77e07", "https://bcr.bazel.build/modules/aspect_bazel_lib/2.8.1/MODULE.bazel": "812d2dd42f65dca362152101fbec418029cc8fd34cbad1a2fde905383d705838", "https://bcr.bazel.build/modules/bazel_features/1.1.0/MODULE.bazel": "cfd42ff3b815a5f39554d97182657f8c4b9719568eb7fded2b9135f084bf760b", "https://bcr.bazel.build/modules/bazel_features/1.1.1/MODULE.bazel": "27b8c79ef57efe08efccbd9dd6ef70d61b4798320b8d3c134fd571f78963dbcd", @@ -80,8 +77,6 @@ "https://bcr.bazel.build/modules/bazel_worker_java/0.0.8/source.json": "9395c4679444bc47bf7e51a710366a4480aa371c6f6bed01868e2fabcf11acec", "https://bcr.bazel.build/modules/buildozer/8.5.1/MODULE.bazel": "a35d9561b3fc5b18797c330793e99e3b834a473d5fbd3d7d7634aafc9bdb6f8f", "https://bcr.bazel.build/modules/buildozer/8.5.1/source.json": "e3386e6ff4529f2442800dee47ad28d3e6487f36a1f75ae39ae56c70f0cd2fbd", - "https://bcr.bazel.build/modules/contrib_rules_jvm/0.33.0/MODULE.bazel": "1aba514585748372ee392484b2645f0bbcb13ad4271d5b7cace018280f15bae1", - "https://bcr.bazel.build/modules/contrib_rules_jvm/0.33.0/source.json": "e52d62ce2a2b8a513d6afe9178acc06a4349c9b0b4c0934d59085ed9df4b4de0", "https://bcr.bazel.build/modules/gawk/5.3.2.bcr.1/MODULE.bazel": "cdf8cbe5ee750db04b78878c9633cc76e80dcf4416cbe982ac3a9222f80713c8", "https://bcr.bazel.build/modules/gawk/5.3.2.bcr.1/source.json": "fa7b512dfcb5eafd90ce3959cf42a2a6fe96144ebbb4b3b3928054895f2afac2", "https://bcr.bazel.build/modules/gazelle/0.32.0/MODULE.bazel": "b499f58a5d0d3537f3cf5b76d8ada18242f64ec474d8391247438bf04f58c7b8", @@ -89,7 +84,6 @@ "https://bcr.bazel.build/modules/gazelle/0.34.0/MODULE.bazel": "abdd8ce4d70978933209db92e436deb3a8b737859e9354fb5fd11fb5c2004c8a", "https://bcr.bazel.build/modules/gazelle/0.36.0/MODULE.bazel": "e375d5d6e9a6ca59b0cb38b0540bc9a05b6aa926d322f2de268ad267a2ee74c0", "https://bcr.bazel.build/modules/gazelle/0.40.0/MODULE.bazel": "42ba5378ebe845fca43989a53186ab436d956db498acde790685fe0e8f9c6146", - "https://bcr.bazel.build/modules/gazelle/0.42.0/MODULE.bazel": "fa140a7c019f3a22779ba7c6132ffff9d2d10a51dba2f3304dee61523d11fef4", "https://bcr.bazel.build/modules/gazelle/0.47.0/MODULE.bazel": "b61bb007c4efad134aa30ee7f4a8e2a39b22aa5685f005edaa022fbd1de43ebc", "https://bcr.bazel.build/modules/gazelle/0.47.0/source.json": "aeb2e5df14b7fb298625d75d08b9c65bdb0b56014c5eb89da9e5dd0572280ae6", "https://bcr.bazel.build/modules/google_benchmark/1.8.2/MODULE.bazel": "a70cf1bba851000ba93b58ae2f6d76490a9feb74192e57ab8e8ff13c34ec50cb", @@ -150,7 +144,6 @@ "https://bcr.bazel.build/modules/re2/2024-07-02/MODULE.bazel": "0eadc4395959969297cbcf31a249ff457f2f1d456228c67719480205aa306daa", "https://bcr.bazel.build/modules/rules_android/0.1.1/MODULE.bazel": "48809ab0091b07ad0182defb787c4c5328bd3a278938415c00a7b69b50c4d3a8", "https://bcr.bazel.build/modules/rules_android/0.6.4/MODULE.bazel": "b4cde12d506dd65d82b2be39761f49f5797303343a3d5b4ee191c0cdf9ef387c", - "https://bcr.bazel.build/modules/rules_android/0.6.6/MODULE.bazel": "b0fb569752aab65ab1a9db0a8f6cfaf5aa1754965e17e95dcf0e4d88e192a68d", "https://bcr.bazel.build/modules/rules_android/0.7.1/MODULE.bazel": "a806fc382a774252f228a40e3b11b9fcc6276f8778c7fb33e9f72937c6258363", "https://bcr.bazel.build/modules/rules_android/0.7.1/source.json": "151440aed3f0f73a00d4ed5cec5d31f63a6fef9b95d8fab1eb1810150fa525f2", "https://bcr.bazel.build/modules/rules_apple/3.16.0/MODULE.bazel": "0d1caf0b8375942ce98ea944be754a18874041e4e0459401d925577624d3a54a", @@ -159,6 +152,7 @@ "https://bcr.bazel.build/modules/rules_cc/0.0.1/MODULE.bazel": "cb2aa0747f84c6c3a78dad4e2049c154f08ab9d166b1273835a8174940365647", "https://bcr.bazel.build/modules/rules_cc/0.0.10/MODULE.bazel": "ec1705118f7eaedd6e118508d3d26deba2a4e76476ada7e0e3965211be012002", "https://bcr.bazel.build/modules/rules_cc/0.0.13/MODULE.bazel": "0e8529ed7b323dad0775ff924d2ae5af7640b23553dfcd4d34344c7e7a867191", + "https://bcr.bazel.build/modules/rules_cc/0.0.14/MODULE.bazel": "5e343a3aac88b8d7af3b1b6d2093b55c347b8eefc2e7d1442f7a02dc8fea48ac", "https://bcr.bazel.build/modules/rules_cc/0.0.15/MODULE.bazel": "6704c35f7b4a72502ee81f61bf88706b54f06b3cbe5558ac17e2e14666cd5dcc", "https://bcr.bazel.build/modules/rules_cc/0.0.16/MODULE.bazel": "7661303b8fc1b4d7f532e54e9d6565771fea666fbdf839e0a86affcd02defe87", "https://bcr.bazel.build/modules/rules_cc/0.0.17/MODULE.bazel": "2ae1d8f4238ec67d7185d8861cb0a2cdf4bc608697c331b95bf990e69b62e64a", @@ -183,7 +177,6 @@ "https://bcr.bazel.build/modules/rules_go/0.46.0/MODULE.bazel": "3477df8bdcc49e698b9d25f734c4f3a9f5931ff34ee48a2c662be168f5f2d3fd", "https://bcr.bazel.build/modules/rules_go/0.50.1/MODULE.bazel": "b91a308dc5782bb0a8021ad4330c81fea5bda77f96b9e4c117b9b9c8f6665ee0", "https://bcr.bazel.build/modules/rules_go/0.51.0-rc2/MODULE.bazel": "edfc3a9cea7bedb0eaaff37b0d7817c1a4bf72b3c615580b0ffcee6c52690fd4", - "https://bcr.bazel.build/modules/rules_go/0.52.0/MODULE.bazel": "0cf080a2706aa8fc9abf64286cee60fdf0238db37b7f1793b0f7d550d59ea3ae", "https://bcr.bazel.build/modules/rules_go/0.53.0/MODULE.bazel": "a4ed760d3ac0dbc0d7b967631a9a3fd9100d28f7d9fcf214b4df87d4bfff5f9a", "https://bcr.bazel.build/modules/rules_go/0.59.0/MODULE.bazel": "b7e43e7414a3139a7547d1b4909b29085fbe5182b6c58cbe1ed4c6272815aeae", "https://bcr.bazel.build/modules/rules_go/0.59.0/source.json": "1df17bb7865cfc029492c30163cee891d0dd8658ea0d5bfdf252c4b6db5c1ef6", @@ -200,7 +193,6 @@ "https://bcr.bazel.build/modules/rules_java/7.3.2/MODULE.bazel": "50dece891cfdf1741ea230d001aa9c14398062f2b7c066470accace78e412bc2", "https://bcr.bazel.build/modules/rules_java/7.4.0/MODULE.bazel": "a592852f8a3dd539e82ee6542013bf2cadfc4c6946be8941e189d224500a8934", "https://bcr.bazel.build/modules/rules_java/7.6.1/MODULE.bazel": "2f14b7e8a1aa2f67ae92bc69d1ec0fa8d9f827c4e17ff5e5f02e91caa3b2d0fe", - "https://bcr.bazel.build/modules/rules_java/8.13.0/MODULE.bazel": "0444ebf737d144cf2bb2ccb368e7f1cce735264285f2a3711785827c1686625e", "https://bcr.bazel.build/modules/rules_java/8.15.2/MODULE.bazel": "5cc6698c822b2f9ef90ca5558599851bed8c3b13f1f8eb140d9bfec638d2acb4", "https://bcr.bazel.build/modules/rules_java/8.3.2/MODULE.bazel": "7336d5511ad5af0b8615fdc7477535a2e4e723a357b6713af439fe8cf0195017", "https://bcr.bazel.build/modules/rules_java/8.5.1/MODULE.bazel": "d8a9e38cc5228881f7055a6079f6f7821a073df3744d441978e7a43e20226939", @@ -216,7 +208,6 @@ "https://bcr.bazel.build/modules/rules_jvm_external/5.2/MODULE.bazel": "d9351ba35217ad0de03816ef3ed63f89d411349353077348a45348b096615036", "https://bcr.bazel.build/modules/rules_jvm_external/5.3/MODULE.bazel": "bf93870767689637164657731849fb887ad086739bd5d360d90007a581d5527d", "https://bcr.bazel.build/modules/rules_jvm_external/6.1/MODULE.bazel": "75b5fec090dbd46cf9b7d8ea08cf84a0472d92ba3585b476f44c326eda8059c4", - "https://bcr.bazel.build/modules/rules_jvm_external/6.10/MODULE.bazel": "33e636ca6bc9ee0fa090a38aa33c631ded2d8cf6fead4124181d1b35dc474f7c", "https://bcr.bazel.build/modules/rules_jvm_external/6.2/MODULE.bazel": "36a6e52487a855f33cb960724eb56547fa87e2c98a0474c3acad94339d7f8e99", "https://bcr.bazel.build/modules/rules_jvm_external/6.3/MODULE.bazel": "c998e060b85f71e00de5ec552019347c8bca255062c990ac02d051bb80a38df0", "https://bcr.bazel.build/modules/rules_jvm_external/6.6/MODULE.bazel": "153042249c7060536dc95b6bb9f9bb8063b8a0b0cb7acdb381bddbc2374aed55", @@ -228,19 +219,15 @@ "https://bcr.bazel.build/modules/rules_kotlin/1.9.0/MODULE.bazel": "ef85697305025e5a61f395d4eaede272a5393cee479ace6686dba707de804d59", "https://bcr.bazel.build/modules/rules_kotlin/1.9.5/MODULE.bazel": "043a16a572f610558ec2030db3ff0c9938574e7dd9f58bded1bb07c0192ef025", "https://bcr.bazel.build/modules/rules_kotlin/1.9.6/MODULE.bazel": "d269a01a18ee74d0335450b10f62c9ed81f2321d7958a2934e44272fe82dcef3", - "https://bcr.bazel.build/modules/rules_kotlin/2.1.3/MODULE.bazel": "ce7def6d576aa8d3a9c6d10e13b4d157296229674371f67dbf788dae0afae3d5", "https://bcr.bazel.build/modules/rules_kotlin/2.2.2/MODULE.bazel": "00d39c5e0fa78cd86193946265bb849e7878c24e44260f9525108428852b315c", "https://bcr.bazel.build/modules/rules_kotlin/2.2.2/source.json": "7a32c2259c79ae0c9a036121f120de825e3ba5f0f3a209ffbbdccf4dc62489b9", "https://bcr.bazel.build/modules/rules_license/0.0.3/MODULE.bazel": "627e9ab0247f7d1e05736b59dbb1b6871373de5ad31c3011880b4133cafd4bd0", "https://bcr.bazel.build/modules/rules_license/0.0.7/MODULE.bazel": "088fbeb0b6a419005b89cf93fe62d9517c0a2b8bb56af3244af65ecfe37e7d5d", "https://bcr.bazel.build/modules/rules_license/1.0.0/MODULE.bazel": "a7fda60eefdf3d8c827262ba499957e4df06f659330bbe6cdbdb975b768bb65c", "https://bcr.bazel.build/modules/rules_license/1.0.0/source.json": "a52c89e54cc311196e478f8382df91c15f7a2bfdf4c6cd0e2675cc2ff0b56efb", - "https://bcr.bazel.build/modules/rules_oci/2.2.7/MODULE.bazel": "f6150e4b224d459f7f6523ef65967464ca4efdd266c7fbf2f5a2a51011957e0c", - "https://bcr.bazel.build/modules/rules_oci/2.2.7/source.json": "b099f02af330f47f19dc67fc9300ef6e1937a8c86882690db0e7a2fcea8c7f6b", "https://bcr.bazel.build/modules/rules_pkg/0.7.0/MODULE.bazel": "df99f03fc7934a4737122518bb87e667e62d780b610910f0447665a7e2be62dc", "https://bcr.bazel.build/modules/rules_pkg/1.0.1/MODULE.bazel": "5b1df97dbc29623bccdf2b0dcd0f5cb08e2f2c9050aab1092fd39a41e82686ff", - "https://bcr.bazel.build/modules/rules_pkg/1.2.0/MODULE.bazel": "c7db3c2b407e673c7a39e3625dc05dc9f12d6682cbd82a3a5924a13b491eda7e", - "https://bcr.bazel.build/modules/rules_pkg/1.2.0/source.json": "9062e00845bf91a4247465d371baa837adf9b6ff44c542f73ba084f07667e1dc", + "https://bcr.bazel.build/modules/rules_pkg/1.0.1/source.json": "bd82e5d7b9ce2d31e380dd9f50c111d678c3bdaca190cb76b0e1c71b05e1ba8a", "https://bcr.bazel.build/modules/rules_proto/4.0.0/MODULE.bazel": "a7a7b6ce9bee418c1a760b3d84f83a299ad6952f9903c67f19e4edd964894e06", "https://bcr.bazel.build/modules/rules_proto/5.3.0-21.7/MODULE.bazel": "e8dff86b0971688790ae75528fe1813f71809b5afd57facb44dad9e8eca631b7", "https://bcr.bazel.build/modules/rules_proto/6.0.0-rc1/MODULE.bazel": "1e5b502e2e1a9e825eef74476a5a1ee524a92297085015a052510b09a1a09483", @@ -262,6 +249,7 @@ "https://bcr.bazel.build/modules/rules_python/0.37.1/MODULE.bazel": "3faeb2d9fa0a81f8980643ee33f212308f4d93eea4b9ce6f36d0b742e71e9500", "https://bcr.bazel.build/modules/rules_python/0.37.2/MODULE.bazel": "b5ffde91410745750b6c13be1c5dc4555ef5bc50562af4a89fd77807fdde626a", "https://bcr.bazel.build/modules/rules_python/0.4.0/MODULE.bazel": "9208ee05fd48bf09ac60ed269791cf17fb343db56c8226a720fbb1cdf467166c", + "https://bcr.bazel.build/modules/rules_python/0.40.0/MODULE.bazel": "9d1a3cd88ed7d8e39583d9ffe56ae8a244f67783ae89b60caafc9f5cf318ada7", "https://bcr.bazel.build/modules/rules_python/1.0.0/MODULE.bazel": "898a3d999c22caa585eb062b600f88654bf92efb204fa346fb55f6f8edffca43", "https://bcr.bazel.build/modules/rules_python/1.3.0/MODULE.bazel": "8361d57eafb67c09b75bf4bbe6be360e1b8f4f18118ab48037f2bd50aa2ccb13", "https://bcr.bazel.build/modules/rules_python/1.4.1/MODULE.bazel": "8991ad45bdc25018301d6b7e1d3626afc3c8af8aaf4bc04f23d0b99c938b73a6", @@ -280,6 +268,8 @@ "https://bcr.bazel.build/modules/rules_shell/0.6.1/MODULE.bazel": "72e76b0eea4e81611ef5452aa82b3da34caca0c8b7b5c0c9584338aa93bae26b", "https://bcr.bazel.build/modules/rules_shell/0.8.0/MODULE.bazel": "f6a89f1d6a669a26f28fe814503857055d76306b79cfc11d12399af08d0b80ae", "https://bcr.bazel.build/modules/rules_shell/0.8.0/source.json": "eb53cc815bc503c6683c5fe12d943f98883f81fc22f51403ec8a95610cba4195", + "https://bcr.bazel.build/modules/rules_spring/2.6.3/MODULE.bazel": "c2f719ea89af7bd3957a322c32430ee59f03fa467a4b1e208eba95a61ddcaa40", + "https://bcr.bazel.build/modules/rules_spring/2.6.3/source.json": "ac68bba4571d93871193ac0e85e3a20e6149221f12dc7f04fa8b042485cd2042", "https://bcr.bazel.build/modules/rules_swift/1.16.0/MODULE.bazel": "4a09f199545a60d09895e8281362b1ff3bb08bbde69c6fc87aff5b92fcc916ca", "https://bcr.bazel.build/modules/rules_swift/2.1.1/MODULE.bazel": "494900a80f944fc7aa61500c2073d9729dff0b764f0e89b824eb746959bc1046", "https://bcr.bazel.build/modules/rules_swift/2.4.0/MODULE.bazel": "1639617eb1ede28d774d967a738b4a68b0accb40650beadb57c21846beab5efd", @@ -287,7 +277,6 @@ "https://bcr.bazel.build/modules/rules_swift/3.1.2/source.json": "e85761f3098a6faf40b8187695e3de6d97944e98abd0d8ce579cb2daf6319a66", "https://bcr.bazel.build/modules/stardoc/0.5.1/MODULE.bazel": "1a05d92974d0c122f5ccf09291442580317cdd859f07a8655f1db9a60374f9f8", "https://bcr.bazel.build/modules/stardoc/0.5.3/MODULE.bazel": "c7f6948dae6999bf0db32c1858ae345f112cacf98f174c7a8bb707e41b974f1c", - "https://bcr.bazel.build/modules/stardoc/0.5.4/MODULE.bazel": "6569966df04610b8520957cb8e97cf2e9faac2c0309657c537ab51c16c18a2a4", "https://bcr.bazel.build/modules/stardoc/0.5.6/MODULE.bazel": "c43dabc564990eeab55e25ed61c07a1aadafe9ece96a4efabb3f8bf9063b71ef", "https://bcr.bazel.build/modules/stardoc/0.6.2/MODULE.bazel": "7060193196395f5dd668eda046ccbeacebfd98efc77fed418dbe2b82ffaa39fd", "https://bcr.bazel.build/modules/stardoc/0.7.0/MODULE.bazel": "05e3d6d30c099b6770e97da986c53bd31844d7f13d41412480ea265ac9e8079c", @@ -303,8 +292,7 @@ "https://bcr.bazel.build/modules/toml.bzl/0.3.0/MODULE.bazel": "5016e5dd1ad2200e119a4b28b2b3935e276c4b480f2fe3e952bea7eeba88f578", "https://bcr.bazel.build/modules/toml.bzl/0.3.0/source.json": "0cf7c878c419b37ddb55f3dd93dd7c0c409bd7c4efacb3da504e0748780b2fa9", "https://bcr.bazel.build/modules/toolchains_protoc/0.5.0/MODULE.bazel": "e649dcd74790d8b186517588c827a777dfa67acfc4cbd733721c4be143ea107f", - "https://bcr.bazel.build/modules/toolchains_protoc/0.6.1/MODULE.bazel": "377cbb438118f413c3361a1dd363da8a42077018473fcdc71a19c203aaf94b17", - "https://bcr.bazel.build/modules/toolchains_protoc/0.6.1/source.json": "b14b0b38c8309691bee7a0ab46113678b8675e04e8999294c58e68b036b8dbff", + "https://bcr.bazel.build/modules/toolchains_protoc/0.5.0/source.json": "9152bf33827a44f796f94f486252fc0128d9efc2413246ebb09a234bb628a846", "https://bcr.bazel.build/modules/upb/0.0.0-20220923-a547704/MODULE.bazel": "7298990c00040a0e2f121f6c32544bab27d4452f80d9ce51349b1a28f3005c43", "https://bcr.bazel.build/modules/upb/0.0.0-20230516-61a97ef/MODULE.bazel": "c0df5e35ad55e264160417fd0875932ee3c9dda63d9fccace35ac62f45e1b6f9", "https://bcr.bazel.build/modules/yq.bzl/0.1.1/MODULE.bazel": "9039681f9bcb8958ee2c87ffc74bdafba9f4369096a2b5634b88abc0eaefa072", @@ -317,21 +305,6 @@ }, "selectedYankedVersions": {}, "moduleExtensions": { - "@@apple_rules_lint+//lint:extensions.bzl%linter": { - "general": { - "bzlTransitiveDigest": "g7izj5kLCmsajh8IospHh4ZQ35dyM0FIrA8D4HapAsM=", - "usagesDigest": "4RWlIKR/sSQ9MqPQRCROVLeGPbvTKmkbEpxkI3mbaCI=", - "recordedInputs": [], - "generatedRepoSpecs": { - "apple_linters": { - "repoRuleId": "@@apple_rules_lint+//lint/private:register_linters.bzl%register_linters", - "attributes": { - "linters": {} - } - } - } - } - }, "@@rules_android+//rules/android_sdk_repository:rule.bzl%android_sdk_repository_extension": { "general": { "bzlTransitiveDigest": "+rMrzIrv7sImYmkbXJYv+gFpTJQ79X3MpwwMLI2A+oA=", @@ -345,229 +318,64 @@ } } }, - "@@rules_oci+//oci:extensions.bzl%oci": { + "@@rules_proto_grpc_java+//:module_extensions.bzl%download_plugins": { "general": { - "bzlTransitiveDigest": "x9tW7bULjt2O48GRYAc+uOtpAZMGSBvKch9MgZbvG/w=", - "usagesDigest": "YV/my4HWfeIYZH762GR/gbfyrtmoU6x5X9/fNcX4Ioo=", + "bzlTransitiveDigest": "IE3yt9aIrDy0PwVS/eJ5bVU9q4C0yoq+KLdHBxYlLjs=", + "usagesDigest": "QLMlNNEIKA7pTDNTyvjS58dkCcrTTmUgPwGYxofkFyk=", "recordedInputs": [ - "REPO_MAPPING:aspect_bazel_lib+,bazel_tools bazel_tools", - "REPO_MAPPING:bazel_features+,bazel_tools bazel_tools", - "REPO_MAPPING:rules_oci+,aspect_bazel_lib aspect_bazel_lib+", - "REPO_MAPPING:rules_oci+,bazel_features bazel_features+", - "REPO_MAPPING:rules_oci+,bazel_skylib bazel_skylib+" + "REPO_MAPPING:rules_proto_grpc_java+,bazel_tools bazel_tools" ], "generatedRepoSpecs": { - "temurin_jre_linux_arm64_v8": { - "repoRuleId": "@@rules_oci+//oci/private:pull.bzl%oci_pull", - "attributes": { - "www_authenticate_challenges": {}, - "scheme": "https", - "registry": "public.ecr.aws", - "repository": "docker/library/eclipse-temurin", - "identifier": "21-jre", - "platform": "linux/arm64/v8", - "target_name": "temurin_jre_linux_arm64_v8", - "bazel_tags": [] - } - }, - "temurin_jre_linux_amd64": { - "repoRuleId": "@@rules_oci+//oci/private:pull.bzl%oci_pull", - "attributes": { - "www_authenticate_challenges": {}, - "scheme": "https", - "registry": "public.ecr.aws", - "repository": "docker/library/eclipse-temurin", - "identifier": "21-jre", - "platform": "linux/amd64", - "target_name": "temurin_jre_linux_amd64", - "bazel_tags": [] - } - }, - "temurin_jre": { - "repoRuleId": "@@rules_oci+//oci/private:pull.bzl%oci_alias", + "grpc_java_plugin_darwin_arm64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_file", "attributes": { - "target_name": "temurin_jre", - "www_authenticate_challenges": {}, - "scheme": "https", - "registry": "public.ecr.aws", - "repository": "docker/library/eclipse-temurin", - "identifier": "21-jre", - "platforms": { - "@@platforms//cpu:arm64": "@temurin_jre_linux_arm64_v8", - "@@platforms//cpu:x86_64": "@temurin_jre_linux_amd64" - }, - "bzlmod_repository": "temurin_jre", - "reproducible": true + "executable": true, + "sha256": "7f286de20e82ea674a5cdf59b6012f056a6d0ee57eb2a85eda0cec4bc3db4761", + "url": "https://repo1.maven.org/maven2/io/grpc/protoc-gen-grpc-java/1.74.0/protoc-gen-grpc-java-1.74.0-osx-aarch_64.exe" } }, - "ubuntu_noble_linux_arm64_v8": { - "repoRuleId": "@@rules_oci+//oci/private:pull.bzl%oci_pull", + "grpc_java_plugin_darwin_x86_64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_file", "attributes": { - "www_authenticate_challenges": {}, - "scheme": "https", - "registry": "public.ecr.aws", - "repository": "ubuntu/ubuntu", - "identifier": "sha256:ef59d9e82939bbce08973bdffb8761b025f75369fb7d2882cdc4938b5a9e992e", - "platform": "linux/arm64/v8", - "target_name": "ubuntu_noble_linux_arm64_v8", - "bazel_tags": [] + "executable": true, + "sha256": "7f286de20e82ea674a5cdf59b6012f056a6d0ee57eb2a85eda0cec4bc3db4761", + "url": "https://repo1.maven.org/maven2/io/grpc/protoc-gen-grpc-java/1.74.0/protoc-gen-grpc-java-1.74.0-osx-x86_64.exe" } }, - "ubuntu_noble_linux_amd64": { - "repoRuleId": "@@rules_oci+//oci/private:pull.bzl%oci_pull", + "grpc_java_plugin_linux_arm64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_file", "attributes": { - "www_authenticate_challenges": {}, - "scheme": "https", - "registry": "public.ecr.aws", - "repository": "ubuntu/ubuntu", - "identifier": "sha256:ef59d9e82939bbce08973bdffb8761b025f75369fb7d2882cdc4938b5a9e992e", - "platform": "linux/amd64", - "target_name": "ubuntu_noble_linux_amd64", - "bazel_tags": [] - } - }, - "ubuntu_noble": { - "repoRuleId": "@@rules_oci+//oci/private:pull.bzl%oci_alias", - "attributes": { - "target_name": "ubuntu_noble", - "www_authenticate_challenges": {}, - "scheme": "https", - "registry": "public.ecr.aws", - "repository": "ubuntu/ubuntu", - "identifier": "sha256:ef59d9e82939bbce08973bdffb8761b025f75369fb7d2882cdc4938b5a9e992e", - "platforms": { - "@@platforms//cpu:arm64": "@ubuntu_noble_linux_arm64_v8", - "@@platforms//cpu:x86_64": "@ubuntu_noble_linux_amd64" - }, - "bzlmod_repository": "ubuntu_noble", - "reproducible": true + "executable": true, + "sha256": "b4d0525c624e38efbec104d027a555e7a256a96eaf3e409972777d659a4b1eb6", + "url": "https://repo1.maven.org/maven2/io/grpc/protoc-gen-grpc-java/1.74.0/protoc-gen-grpc-java-1.74.0-linux-aarch_64.exe" } }, - "oci_crane_darwin_amd64": { - "repoRuleId": "@@rules_oci+//oci:repositories.bzl%crane_repositories", + "grpc_java_plugin_linux_x86_64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_file", "attributes": { - "platform": "darwin_amd64", - "crane_version": "v0.18.0" + "executable": true, + "sha256": "bb6f37cbacea579cba9916d07b05b15beaaf9abdea271323fabdea4b6568f18c", + "url": "https://repo1.maven.org/maven2/io/grpc/protoc-gen-grpc-java/1.74.0/protoc-gen-grpc-java-1.74.0-linux-x86_64.exe" } }, - "oci_crane_darwin_arm64": { - "repoRuleId": "@@rules_oci+//oci:repositories.bzl%crane_repositories", + "grpc_java_plugin_windows_x86_64": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_file", "attributes": { - "platform": "darwin_arm64", - "crane_version": "v0.18.0" - } - }, - "oci_crane_linux_arm64": { - "repoRuleId": "@@rules_oci+//oci:repositories.bzl%crane_repositories", - "attributes": { - "platform": "linux_arm64", - "crane_version": "v0.18.0" - } - }, - "oci_crane_linux_armv6": { - "repoRuleId": "@@rules_oci+//oci:repositories.bzl%crane_repositories", - "attributes": { - "platform": "linux_armv6", - "crane_version": "v0.18.0" - } - }, - "oci_crane_linux_i386": { - "repoRuleId": "@@rules_oci+//oci:repositories.bzl%crane_repositories", - "attributes": { - "platform": "linux_i386", - "crane_version": "v0.18.0" - } - }, - "oci_crane_linux_s390x": { - "repoRuleId": "@@rules_oci+//oci:repositories.bzl%crane_repositories", - "attributes": { - "platform": "linux_s390x", - "crane_version": "v0.18.0" - } - }, - "oci_crane_linux_amd64": { - "repoRuleId": "@@rules_oci+//oci:repositories.bzl%crane_repositories", - "attributes": { - "platform": "linux_amd64", - "crane_version": "v0.18.0" - } - }, - "oci_crane_windows_armv6": { - "repoRuleId": "@@rules_oci+//oci:repositories.bzl%crane_repositories", - "attributes": { - "platform": "windows_armv6", - "crane_version": "v0.18.0" - } - }, - "oci_crane_windows_amd64": { - "repoRuleId": "@@rules_oci+//oci:repositories.bzl%crane_repositories", - "attributes": { - "platform": "windows_amd64", - "crane_version": "v0.18.0" - } - }, - "oci_crane_toolchains": { - "repoRuleId": "@@rules_oci+//oci/private:toolchains_repo.bzl%toolchains_repo", - "attributes": { - "toolchain_type": "@rules_oci//oci:crane_toolchain_type", - "toolchain": "@oci_crane_{platform}//:crane_toolchain" - } - }, - "oci_regctl_darwin_amd64": { - "repoRuleId": "@@rules_oci+//oci:repositories.bzl%regctl_repositories", - "attributes": { - "platform": "darwin_amd64" - } - }, - "oci_regctl_darwin_arm64": { - "repoRuleId": "@@rules_oci+//oci:repositories.bzl%regctl_repositories", - "attributes": { - "platform": "darwin_arm64" - } - }, - "oci_regctl_linux_arm64": { - "repoRuleId": "@@rules_oci+//oci:repositories.bzl%regctl_repositories", - "attributes": { - "platform": "linux_arm64" - } - }, - "oci_regctl_linux_s390x": { - "repoRuleId": "@@rules_oci+//oci:repositories.bzl%regctl_repositories", - "attributes": { - "platform": "linux_s390x" - } - }, - "oci_regctl_linux_amd64": { - "repoRuleId": "@@rules_oci+//oci:repositories.bzl%regctl_repositories", - "attributes": { - "platform": "linux_amd64" - } - }, - "oci_regctl_windows_amd64": { - "repoRuleId": "@@rules_oci+//oci:repositories.bzl%regctl_repositories", - "attributes": { - "platform": "windows_amd64" - } - }, - "oci_regctl_toolchains": { - "repoRuleId": "@@rules_oci+//oci/private:toolchains_repo.bzl%toolchains_repo", - "attributes": { - "toolchain_type": "@rules_oci//oci:regctl_toolchain_type", - "toolchain": "@oci_regctl_{platform}//:regctl_toolchain" + "executable": true, + "sha256": "6c265e8cefbb2158b044807af1188ad303d35e973f562209f337f93a8198fa37", + "url": "https://repo1.maven.org/maven2/io/grpc/protoc-gen-grpc-java/1.74.0/protoc-gen-grpc-java-1.74.0-windows-x86_64.exe" } } }, "moduleExtensionMetadata": { - "explicitRootModuleDirectDeps": [], - "explicitRootModuleDirectDevDeps": [], - "useAllRepos": "NO", + "useAllRepos": "REGULAR", "reproducible": false } } }, "@@rules_python+//python/extensions:config.bzl%config": { "general": { - "bzlTransitiveDigest": "dzD8Q2YmrP3fz8saWLHPmlwPLO91ImtTmP/c9JKTStM=", + "bzlTransitiveDigest": "iibnRYgg8LpcfmH7EAnVwYePC3jsVaJ6Id8XxUjSZps=", "usagesDigest": "ZVSXMAGpD+xzVNPuvF1IoLBkty7TROO0+akMapt1pAg=", "recordedInputs": [ "REPO_MAPPING:rules_python+,bazel_tools bazel_tools", @@ -979,172 +787,6 @@ "5fcd0671a49cecf39b41021621ee1b6e7aa1370f37122b72e80d4fd4185833b6" ] }, - "1.23.6": { - "aix_ppc64": [ - "go1.23.6.aix-ppc64.tar.gz", - "adec10f4ba56591f523aa04851f7f6900b1c61508dfa6b80e62717a8e6684a5c" - ], - "darwin_amd64": [ - "go1.23.6.darwin-amd64.tar.gz", - "782da50ce8ec5e98fac2cd3cdc6a1d7130d093294fc310038f651444232a3fb0" - ], - "darwin_arm64": [ - "go1.23.6.darwin-arm64.tar.gz", - "5cae2450a1708aeb0333237a155640d5562abaf195defebc4306054565536221" - ], - "dragonfly_amd64": [ - "go1.23.6.dragonfly-amd64.tar.gz", - "d52efb3020d9332477ade98163c03d2f2fe3e051b0e7e01f0e167412c66de0cb" - ], - "freebsd_386": [ - "go1.23.6.freebsd-386.tar.gz", - "d3287706b5823712ac6cf7dff684a556cff98163ef60e7b275abe3388c17aac7" - ], - "freebsd_amd64": [ - "go1.23.6.freebsd-amd64.tar.gz", - "ebb4c6a9b0673dbdabc439877779ed6add16575e21bd0a7955c33f692789aef6" - ], - "freebsd_arm": [ - "go1.23.6.freebsd-arm.tar.gz", - "b7241584afb0b161c09148f8fde16171bb743e47b99d451fbc5f5217ec7a88b6" - ], - "freebsd_arm64": [ - "go1.23.6.freebsd-arm64.tar.gz", - "004718b53cedd7955d1b1dc4053539fcd1053c031f5f3374334a22befd1f8310" - ], - "freebsd_riscv64": [ - "go1.23.6.freebsd-riscv64.tar.gz", - "ca026ec8a30dd0c18164f40e1ce21bd725e2445f11699177d05815189a38de7a" - ], - "illumos_amd64": [ - "go1.23.6.illumos-amd64.tar.gz", - "7db973efa3fb2e48e45059b855721550fce8e90803e7373d3efd37b88dd821e8" - ], - "linux_386": [ - "go1.23.6.linux-386.tar.gz", - "e61f87693169c0bbcc43363128f1e929b9dff0b7f448573f1bdd4e4a0b9687ba" - ], - "linux_amd64": [ - "go1.23.6.linux-amd64.tar.gz", - "9379441ea310de000f33a4dc767bd966e72ab2826270e038e78b2c53c2e7802d" - ], - "linux_arm64": [ - "go1.23.6.linux-arm64.tar.gz", - "561c780e8f4a8955d32bf72e46af0b5ee5e0debe1e4633df9a03781878219202" - ], - "linux_armv6l": [ - "go1.23.6.linux-armv6l.tar.gz", - "27a4611010c16b8c4f37ade3aada55bd5781998f02f348b164302fd5eea4eb74" - ], - "linux_loong64": [ - "go1.23.6.linux-loong64.tar.gz", - "c459226424372abc2b35957cc8955dad348330714f7605093325dbb73e33c750" - ], - "linux_mips": [ - "go1.23.6.linux-mips.tar.gz", - "e2a0aff70b958a3463a7d47132a2d0238369f64578d4f7f95e679e3a5af05622" - ], - "linux_mips64": [ - "go1.23.6.linux-mips64.tar.gz", - "7d30ec7db056311d420bf930c16abcae13c0f41c26a202868f279721ec3c2f2f" - ], - "linux_mips64le": [ - "go1.23.6.linux-mips64le.tar.gz", - "74ca7bc475bcc084c6718b74df024d7de9612932cea8a6dc75e29d3a5315a23a" - ], - "linux_mipsle": [ - "go1.23.6.linux-mipsle.tar.gz", - "09bf935a14e9f59a20499989438b1655453480016bdbcb10406acf4df2678ccb" - ], - "linux_ppc64": [ - "go1.23.6.linux-ppc64.tar.gz", - "5cb2f6a5090276c72c5eda8a55896f5a3d6ea0f28d10fa1a50e8318640f02d6c" - ], - "linux_ppc64le": [ - "go1.23.6.linux-ppc64le.tar.gz", - "0f817201e83d78ddbfa27f5f78d9b72450b92cc21d5e045145efacd0d3244a99" - ], - "linux_riscv64": [ - "go1.23.6.linux-riscv64.tar.gz", - "f95f7f817ab22ecab4503d0704d6449ea1aa26a595f57bf9b9f94ddf2aa7c1f3" - ], - "linux_s390x": [ - "go1.23.6.linux-s390x.tar.gz", - "321e7ed0d5416f731479c52fa7610b52b8079a8061967bd48cec6d66f671a60e" - ], - "netbsd_386": [ - "go1.23.6.netbsd-386.tar.gz", - "92d678fb8e1eeeb8c6af6f22e4e5494652dcbb4a320113fc08325cb9956a2d4c" - ], - "netbsd_amd64": [ - "go1.23.6.netbsd-amd64.tar.gz", - "86ba51e7bb26b30ea6a8d88ddb79d8e8c83b4116200040ecb7a5a44cf90a8c5c" - ], - "netbsd_arm": [ - "go1.23.6.netbsd-arm.tar.gz", - "4b974c35345100f0be6ea66afab2781de91ee9882117314126eaf0ae90fd3816" - ], - "netbsd_arm64": [ - "go1.23.6.netbsd-arm64.tar.gz", - "53e3589fc38e787a493ea038961f8e40803714dbb42754c1713b00099c12e9b9" - ], - "openbsd_386": [ - "go1.23.6.openbsd-386.tar.gz", - "6d2317b3a8505ccebff8f72d943f2ac9b82c115632e54a53a786eff24ced56d9" - ], - "openbsd_amd64": [ - "go1.23.6.openbsd-amd64.tar.gz", - "f699e707d95a984fcc00361d91aecdb413d3c75e18235156ffba7a89edf68aae" - ], - "openbsd_arm": [ - "go1.23.6.openbsd-arm.tar.gz", - "3c1cf6ab893657d0bf1942e40ce115acfd27cbce1ccb9bc88fd9cd21ca3d489f" - ], - "openbsd_arm64": [ - "go1.23.6.openbsd-arm64.tar.gz", - "cc0875535d14001f2da23ae9af89025b28c466e8f4f4c63f991ebb6f4b02f66c" - ], - "openbsd_ppc64": [ - "go1.23.6.openbsd-ppc64.tar.gz", - "64de80e29ca66cb566cbf8be030bf8599953af4e48402eab724cbe0a08b40602" - ], - "openbsd_riscv64": [ - "go1.23.6.openbsd-riscv64.tar.gz", - "c398a6b43c569f34bb4a2d16b52f8010eaac9a2a82ecac0602b4338e35cef377" - ], - "plan9_386": [ - "go1.23.6.plan9-386.tar.gz", - "10998b6b130bb7b542b407f0db42b86a913b111f8fa86d44394beaace4d45f01" - ], - "plan9_amd64": [ - "go1.23.6.plan9-amd64.tar.gz", - "9fbe8065436d8d12c02f19f64f51c9107da3a7a4ac46ab5777e182e9fe88c32f" - ], - "plan9_arm": [ - "go1.23.6.plan9-arm.tar.gz", - "8e3c826b884daee2de37e3b070d7eac4cea5d68edab8db09910e22201c75db83" - ], - "solaris_amd64": [ - "go1.23.6.solaris-amd64.tar.gz", - "b619eff63fec86daaea92ca170559e448a58b8ba0b92eef1971bc14e92ea86a7" - ], - "windows_386": [ - "go1.23.6.windows-386.zip", - "96820c0f5d464dd694543329e9b4d413b17c821c03a055717a29e6735b44c2d8" - ], - "windows_amd64": [ - "go1.23.6.windows-amd64.zip", - "53fec1586850b2cf5ad6438341ff7adc5f6700dd3ec1cfa3f5e8b141df190243" - ], - "windows_arm": [ - "go1.23.6.windows-arm.zip", - "22c2518c45c20018afa20d5376dc9fd7a7e74367240ed7b5209e79a30b5c4218" - ], - "windows_arm64": [ - "go1.23.6.windows-arm64.zip", - "a2d2ec1b3759552bdd9cdf58858f91dfbfd6ab3a472f00b5255acbed30b1aa41" - ] - }, "1.25.0": { "aix_ppc64": [ "go1.25.0.aix-ppc64.tar.gz", @@ -1308,6 +950,5 @@ ] } } - }, - "factsVersions": {} + } } diff --git a/src/control-plane-services/cloud-tasks/maven_install.json b/src/control-plane-services/cloud-tasks/maven_install.json old mode 100755 new mode 100644 index ed26396a1..544b5385b --- a/src/control-plane-services/cloud-tasks/maven_install.json +++ b/src/control-plane-services/cloud-tasks/maven_install.json @@ -6,20 +6,14 @@ "com.github.ben-manes.caffeine:caffeine": 1100418982, "com.github.ben-manes.caffeine:guava": 1054685015, "com.github.java-json-tools:json-patch": -1031005245, - "com.google.code.findbugs:jsr305": 495355163, - "com.google.code.gson:gson": 597770368, - "com.google.errorprone:error_prone_annotations": -1035138750, - "com.google.guava:guava": 1943808618, - "com.google.j2objc:j2objc-annotations": 2003271689, "com.google.protobuf:protobuf-java": 1906581597, "com.google.protobuf:protobuf-java-util": -1626074784, "commons-codec:commons-codec": -1269462382, "io.cloudevents:cloudevents-core": -2103567774, "io.cloudevents:cloudevents-json-jackson": -1197487309, - "io.grpc:grpc-api": 1424099231, - "io.grpc:grpc-netty": -904974271, - "io.grpc:grpc-protobuf": 1036850648, - "io.grpc:grpc-stub": -26097747, + "io.grpc:grpc-api": 811923177, + "io.grpc:grpc-protobuf": 1083049616, + "io.grpc:grpc-stub": 1416868173, "io.micrometer:micrometer-registry-prometheus": 1865600799, "io.micrometer:micrometer-tracing-bridge-otel": -754588172, "io.nats:jnats": 572014237, @@ -41,11 +35,8 @@ "org.jacoco:org.jacoco.agent": -2069397525, "org.jacoco:org.jacoco.cli": -1856875155, "org.junit.jupiter:junit-jupiter-api": 194920406, - "org.junit.jupiter:junit-jupiter-engine": -1886863302, "org.junit.jupiter:junit-jupiter-params": 1082310006, "org.junit.platform:junit-platform-console-standalone": -1481831078, - "org.junit.platform:junit-platform-launcher": -354104948, - "org.junit.platform:junit-platform-reporting": 1896713402, "org.mockito:mockito-core": -554630660, "org.mockito:mockito-junit-jupiter": -1104541639, "org.ow2.asm:asm": -221905796, @@ -77,7 +68,6 @@ "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server-test": -1173625786, "org.springframework.boot:spring-boot-starter-test": -1561809354, "org.springframework.boot:spring-boot-starter-validation": 113118493, - "org.springframework.boot:spring-boot-starter-web": -1905796688, "org.springframework.boot:spring-boot-starter-webflux": 1788530073, "org.springframework.boot:spring-boot-starter-webflux-test": 5326534, "org.springframework.boot:spring-boot-starter-webmvc": 338400426, @@ -103,8 +93,6 @@ "tools.jackson.module:jackson-module-blackbird": -423541381 }, "__RESOLVED_ARTIFACTS_HASH": { - "aopalliance:aopalliance": -1763688673, - "aopalliance:aopalliance:jar:sources": 758113234, "args4j:args4j": -572028113, "args4j:args4j:jar:sources": 74047526, "at.yawk.lz4:lz4-java": -1985362494, @@ -117,7 +105,7 @@ "com.bucket4j:bucket4j-core:jar:sources": -559201191, "com.bucket4j:bucket4j_jdk17-core": -1244833112, "com.bucket4j:bucket4j_jdk17-core:jar:sources": -2075602285, - "com.datastax.cassandra:cassandra-driver-core": 197829386, + "com.datastax.cassandra:cassandra-driver-core": -1043458548, "com.datastax.cassandra:cassandra-driver-core:jar:sources": -2045236197, "com.datastax.oss:native-protocol": 447263174, "com.datastax.oss:native-protocol:jar:sources": 396473389, @@ -133,9 +121,9 @@ "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:jar:sources": 1241536710, "com.fasterxml:classmate": -1468141616, "com.fasterxml:classmate:jar:sources": -179492269, - "com.github.ben-manes.caffeine:caffeine": 1925806502, + "com.github.ben-manes.caffeine:caffeine": 96455941, "com.github.ben-manes.caffeine:caffeine:jar:sources": -967473790, - "com.github.ben-manes.caffeine:guava": 2074933175, + "com.github.ben-manes.caffeine:guava": 1187631417, "com.github.ben-manes.caffeine:guava:jar:sources": 1956210603, "com.github.docker-java:docker-java-api": 1857041788, "com.github.docker-java:docker-java-api:jar:sources": 300128277, @@ -170,19 +158,19 @@ "com.google.api.grpc:proto-google-common-protos:jar:sources": 944916609, "com.google.code.findbugs:jsr305": -1038659426, "com.google.code.findbugs:jsr305:jar:sources": -1300148931, - "com.google.code.gson:gson": 1618556651, - "com.google.code.gson:gson:jar:sources": 389178860, - "com.google.errorprone:error_prone_annotations": 492382488, - "com.google.errorprone:error_prone_annotations:jar:sources": 456515251, - "com.google.guava:failureaccess": -268223546, - "com.google.guava:failureaccess:jar:sources": 2053502918, - "com.google.guava:guava": 1240305771, - "com.google.guava:guava:jar:sources": 1591586943, + "com.google.code.gson:gson": 328405842, + "com.google.code.gson:gson:jar:sources": -329485452, + "com.google.errorprone:error_prone_annotations": -1266099896, + "com.google.errorprone:error_prone_annotations:jar:sources": 936701586, + "com.google.guava:failureaccess": -56291903, + "com.google.guava:failureaccess:jar:sources": -820168004, + "com.google.guava:guava": -1132194940, + "com.google.guava:guava:jar:sources": -1505508770, "com.google.guava:listenablefuture": 1588902908, - "com.google.j2objc:j2objc-annotations": -596695707, - "com.google.j2objc:j2objc-annotations:jar:sources": 900785715, + "com.google.j2objc:j2objc-annotations": -2074422376, + "com.google.j2objc:j2objc-annotations:jar:sources": -597974451, "com.google.protobuf:protobuf-java": 1139989641, - "com.google.protobuf:protobuf-java-util": -1990628174, + "com.google.protobuf:protobuf-java-util": 404866093, "com.google.protobuf:protobuf-java-util:jar:sources": 1216176261, "com.google.protobuf:protobuf-java:jar:sources": -718827633, "com.jayway.jsonpath:json-path": 626712679, @@ -221,38 +209,36 @@ "io.cloudevents:cloudevents-core:jar:sources": 223693387, "io.cloudevents:cloudevents-json-jackson": -807987873, "io.cloudevents:cloudevents-json-jackson:jar:sources": -166751855, - "io.dropwizard.metrics:metrics-core": 1029463962, - "io.dropwizard.metrics:metrics-core:jar:sources": 1607397396, - "io.grpc:grpc-api": 1731222191, + "io.dropwizard.metrics:metrics-core": -1658658454, + "io.dropwizard.metrics:metrics-core:jar:sources": 1726519463, + "io.grpc:grpc-api": 716151037, "io.grpc:grpc-api:jar:sources": 234601049, - "io.grpc:grpc-context": 1511740056, - "io.grpc:grpc-context:jar:sources": -1094751930, - "io.grpc:grpc-core": 831039331, - "io.grpc:grpc-core:jar:sources": 691468151, - "io.grpc:grpc-inprocess": -1501508632, + "io.grpc:grpc-context": 721938541, + "io.grpc:grpc-context:jar:sources": 1478851124, + "io.grpc:grpc-core": -1513972768, + "io.grpc:grpc-core:jar:sources": -232667389, + "io.grpc:grpc-inprocess": 353730710, "io.grpc:grpc-inprocess:jar:sources": -676994554, - "io.grpc:grpc-netty": 1825797901, - "io.grpc:grpc-netty-shaded": -345312471, + "io.grpc:grpc-netty-shaded": 1759851352, "io.grpc:grpc-netty-shaded:jar:sources": 1478851124, - "io.grpc:grpc-netty:jar:sources": -231652768, - "io.grpc:grpc-protobuf": 45290816, - "io.grpc:grpc-protobuf-lite": 63739651, + "io.grpc:grpc-protobuf": -549393834, + "io.grpc:grpc-protobuf-lite": -1967256086, "io.grpc:grpc-protobuf-lite:jar:sources": -1659538303, "io.grpc:grpc-protobuf:jar:sources": -1849103116, - "io.grpc:grpc-services": -1598479097, + "io.grpc:grpc-services": 1483710115, "io.grpc:grpc-services:jar:sources": 2062893709, - "io.grpc:grpc-stub": 1646600797, + "io.grpc:grpc-stub": -1391817309, "io.grpc:grpc-stub:jar:sources": -1596678046, - "io.grpc:grpc-util": 1123291627, - "io.grpc:grpc-util:jar:sources": 661341860, - "io.gsonfire:gson-fire": -839915556, + "io.grpc:grpc-util": 188637273, + "io.grpc:grpc-util:jar:sources": -2003766127, + "io.gsonfire:gson-fire": -1955577022, "io.gsonfire:gson-fire:jar:sources": -237239617, - "io.kubernetes:client-java": -1707157006, - "io.kubernetes:client-java-api": -2039476626, - "io.kubernetes:client-java-api-fluent": 178640861, + "io.kubernetes:client-java": -1721476940, + "io.kubernetes:client-java-api": 1944060710, + "io.kubernetes:client-java-api-fluent": 889139695, "io.kubernetes:client-java-api-fluent:jar:sources": -1413457658, "io.kubernetes:client-java-api:jar:sources": -1450077171, - "io.kubernetes:client-java-extended": 1201157788, + "io.kubernetes:client-java-extended": 693015729, "io.kubernetes:client-java-extended:jar:sources": -483537505, "io.kubernetes:client-java-proto": -533144525, "io.kubernetes:client-java-proto:jar:sources": 396874650, @@ -271,8 +257,8 @@ "io.micrometer:micrometer-observation:jar:sources": 1279306785, "io.micrometer:micrometer-registry-prometheus": -104964751, "io.micrometer:micrometer-registry-prometheus:jar:sources": 769452823, - "io.micrometer:micrometer-tracing": -109714346, - "io.micrometer:micrometer-tracing-bridge-otel": 975863312, + "io.micrometer:micrometer-tracing": -1023327334, + "io.micrometer:micrometer-tracing-bridge-otel": 1199970811, "io.micrometer:micrometer-tracing-bridge-otel:jar:sources": 1300289348, "io.micrometer:micrometer-tracing:jar:sources": 266031561, "io.nats:jnats": 1273546329, @@ -355,8 +341,8 @@ "io.opentelemetry:opentelemetry-sdk-trace": 2083919234, "io.opentelemetry:opentelemetry-sdk-trace:jar:sources": 818630467, "io.opentelemetry:opentelemetry-sdk:jar:sources": -1478160490, - "io.perfmark:perfmark-api": -752483303, - "io.perfmark:perfmark-api:jar:sources": 1421329924, + "io.perfmark:perfmark-api": 2140534246, + "io.perfmark:perfmark-api:jar:sources": 1660808382, "io.projectreactor.netty:reactor-netty-core": -1310988391, "io.projectreactor.netty:reactor-netty-core:jar:sources": 160926198, "io.projectreactor.netty:reactor-netty-http": -1289714469, @@ -401,15 +387,15 @@ "net.bytebuddy:byte-buddy-agent": -1380713096, "net.bytebuddy:byte-buddy-agent:jar:sources": 564051985, "net.bytebuddy:byte-buddy:jar:sources": -1360611642, - "net.devh:grpc-common-spring-boot": -552555366, + "net.devh:grpc-common-spring-boot": 868090547, "net.devh:grpc-common-spring-boot:jar:sources": 1655513026, - "net.devh:grpc-server-spring-boot-starter": 265787149, + "net.devh:grpc-server-spring-boot-starter": 1078456931, "net.devh:grpc-server-spring-boot-starter:jar:sources": 1954333860, "net.java.dev.jna:jna": -1951542637, "net.java.dev.jna:jna:jar:sources": -545183654, "net.javacrumbs.shedlock:shedlock-core": 672475327, "net.javacrumbs.shedlock:shedlock-core:jar:sources": 69227555, - "net.javacrumbs.shedlock:shedlock-provider-cassandra": -460637299, + "net.javacrumbs.shedlock:shedlock-provider-cassandra": 1266553971, "net.javacrumbs.shedlock:shedlock-provider-cassandra:jar:sources": 1860167, "net.javacrumbs.shedlock:shedlock-spring": 2008414309, "net.javacrumbs.shedlock:shedlock-spring:jar:sources": 875349683, @@ -417,13 +403,13 @@ "net.minidev:accessors-smart:jar:sources": -124254155, "net.minidev:json-smart": 1673421716, "net.minidev:json-smart:jar:sources": -1084786431, - "org.apache.cassandra:java-driver-core": 42196324, + "org.apache.cassandra:java-driver-core": -474731455, "org.apache.cassandra:java-driver-core:jar:sources": -1508814165, "org.apache.cassandra:java-driver-guava-shaded": 568990261, "org.apache.cassandra:java-driver-guava-shaded:jar:sources": 1291502230, - "org.apache.cassandra:java-driver-metrics-micrometer": -93817708, + "org.apache.cassandra:java-driver-metrics-micrometer": 813209106, "org.apache.cassandra:java-driver-metrics-micrometer:jar:sources": -2019023443, - "org.apache.cassandra:java-driver-query-builder": 303143232, + "org.apache.cassandra:java-driver-query-builder": 572260414, "org.apache.cassandra:java-driver-query-builder:jar:sources": -1665027563, "org.apache.commons:commons-collections4": -321403372, "org.apache.commons:commons-collections4:jar:sources": -620214302, @@ -459,10 +445,8 @@ "org.bouncycastle:bcprov-lts8on:jar:sources": -196135755, "org.bouncycastle:bcutil-jdk18on": 686883151, "org.bouncycastle:bcutil-jdk18on:jar:sources": 1665148152, - "org.checkerframework:checker-qual": -2018582244, - "org.checkerframework:checker-qual:jar:sources": 2110417205, - "org.codehaus.mojo:animal-sniffer-annotations": -284157962, - "org.codehaus.mojo:animal-sniffer-annotations:jar:sources": 1440193403, + "org.codehaus.mojo:animal-sniffer-annotations": -1054702037, + "org.codehaus.mojo:animal-sniffer-annotations:jar:sources": -248345982, "org.hamcrest:hamcrest": 1116842741, "org.hamcrest:hamcrest:jar:sources": -996443755, "org.hdrhistogram:HdrHistogram": 1379183334, @@ -503,10 +487,6 @@ "org.junit.platform:junit-platform-console-standalone:jar:sources": -103511349, "org.junit.platform:junit-platform-engine": -748595950, "org.junit.platform:junit-platform-engine:jar:sources": -191078126, - "org.junit.platform:junit-platform-launcher": 1722101087, - "org.junit.platform:junit-platform-launcher:jar:sources": -717285440, - "org.junit.platform:junit-platform-reporting": 1847654060, - "org.junit.platform:junit-platform-reporting:jar:sources": -1771745730, "org.latencyutils:LatencyUtils": 1082471286, "org.latencyutils:LatencyUtils:jar:sources": 1894864087, "org.mockito:mockito-core": 734095861, @@ -515,8 +495,6 @@ "org.mockito:mockito-junit-jupiter:jar:sources": -1281757309, "org.objenesis:objenesis": 1083875484, "org.objenesis:objenesis:jar:sources": 703772823, - "org.opentest4j.reporting:open-test-reporting-tooling-spi": -1639379357, - "org.opentest4j.reporting:open-test-reporting-tooling-spi:jar:sources": 1632689314, "org.opentest4j:opentest4j": 793813175, "org.opentest4j:opentest4j:jar:sources": 1210936723, "org.ow2.asm:asm": 716467505, @@ -554,10 +532,10 @@ "org.springframework.boot:spring-boot-actuator:jar:sources": 1545596535, "org.springframework.boot:spring-boot-autoconfigure": -491644458, "org.springframework.boot:spring-boot-autoconfigure:jar:sources": 562322138, - "org.springframework.boot:spring-boot-cassandra": 1880514148, + "org.springframework.boot:spring-boot-cassandra": -1547665178, "org.springframework.boot:spring-boot-cassandra:jar:sources": -285158244, - "org.springframework.boot:spring-boot-data-cassandra": -1136414714, - "org.springframework.boot:spring-boot-data-cassandra-test": 1687171774, + "org.springframework.boot:spring-boot-data-cassandra": 317643841, + "org.springframework.boot:spring-boot-data-cassandra-test": 1607977176, "org.springframework.boot:spring-boot-data-cassandra-test:jar:sources": -601584645, "org.springframework.boot:spring-boot-data-cassandra:jar:sources": 73983427, "org.springframework.boot:spring-boot-data-commons": 1096447250, @@ -580,8 +558,8 @@ "org.springframework.boot:spring-boot-micrometer-metrics:jar:sources": -1326033951, "org.springframework.boot:spring-boot-micrometer-observation": -515345138, "org.springframework.boot:spring-boot-micrometer-observation:jar:sources": -1374159176, - "org.springframework.boot:spring-boot-micrometer-tracing": -1769177987, - "org.springframework.boot:spring-boot-micrometer-tracing-opentelemetry": 686601187, + "org.springframework.boot:spring-boot-micrometer-tracing": 1633930466, + "org.springframework.boot:spring-boot-micrometer-tracing-opentelemetry": 1193263452, "org.springframework.boot:spring-boot-micrometer-tracing-opentelemetry:jar:sources": 2058843242, "org.springframework.boot:spring-boot-micrometer-tracing:jar:sources": -531678236, "org.springframework.boot:spring-boot-netty": -1868279944, @@ -615,8 +593,8 @@ "org.springframework.boot:spring-boot-starter-actuator:jar:sources": -2079433447, "org.springframework.boot:spring-boot-starter-aspectj": 740892542, "org.springframework.boot:spring-boot-starter-aspectj:jar:sources": 1957689077, - "org.springframework.boot:spring-boot-starter-data-cassandra": -1305411192, - "org.springframework.boot:spring-boot-starter-data-cassandra-test": 1049224325, + "org.springframework.boot:spring-boot-starter-data-cassandra": -705283811, + "org.springframework.boot:spring-boot-starter-data-cassandra-test": -1214165647, "org.springframework.boot:spring-boot-starter-data-cassandra-test:jar:sources": 464889083, "org.springframework.boot:spring-boot-starter-data-cassandra:jar:sources": 62860247, "org.springframework.boot:spring-boot-starter-jackson": 211326145, @@ -649,8 +627,6 @@ "org.springframework.boot:spring-boot-starter-tomcat:jar:sources": 1319064174, "org.springframework.boot:spring-boot-starter-validation": -321633530, "org.springframework.boot:spring-boot-starter-validation:jar:sources": -1002865328, - "org.springframework.boot:spring-boot-starter-web": 1122240419, - "org.springframework.boot:spring-boot-starter-web:jar:sources": -768709610, "org.springframework.boot:spring-boot-starter-webflux": -818164168, "org.springframework.boot:spring-boot-starter-webflux-test": -415179163, "org.springframework.boot:spring-boot-starter-webflux-test:jar:sources": -1654084055, @@ -687,17 +663,17 @@ "org.springframework.cloud:spring-cloud-commons:jar:sources": 1320616004, "org.springframework.cloud:spring-cloud-context": 1118197933, "org.springframework.cloud:spring-cloud-context:jar:sources": -1413797918, - "org.springframework.cloud:spring-cloud-kubernetes-client-autoconfig": -1665956951, + "org.springframework.cloud:spring-cloud-kubernetes-client-autoconfig": -256822388, "org.springframework.cloud:spring-cloud-kubernetes-client-autoconfig:jar:sources": 758022911, - "org.springframework.cloud:spring-cloud-kubernetes-client-config": -325837469, + "org.springframework.cloud:spring-cloud-kubernetes-client-config": 954066893, "org.springframework.cloud:spring-cloud-kubernetes-client-config:jar:sources": -251471561, "org.springframework.cloud:spring-cloud-kubernetes-commons": -500725348, "org.springframework.cloud:spring-cloud-kubernetes-commons:jar:sources": -325491963, "org.springframework.cloud:spring-cloud-starter": -1812063683, "org.springframework.cloud:spring-cloud-starter-bootstrap": -1263482746, "org.springframework.cloud:spring-cloud-starter-bootstrap:jar:sources": 1965832056, - "org.springframework.cloud:spring-cloud-starter-kubernetes-client-config": -710796001, - "org.springframework.data:spring-data-cassandra": -1548120966, + "org.springframework.cloud:spring-cloud-starter-kubernetes-client-config": -251169345, + "org.springframework.data:spring-data-cassandra": -546629484, "org.springframework.data:spring-data-cassandra:jar:sources": -1628107854, "org.springframework.data:spring-data-commons": 1312199320, "org.springframework.data:spring-data-commons:jar:sources": 544548950, @@ -744,7 +720,7 @@ "org.springframework:spring-webmvc": 56813816, "org.springframework:spring-webmvc:jar:sources": -837106767, "org.testcontainers:testcontainers": 450183679, - "org.testcontainers:testcontainers-cassandra": 584880112, + "org.testcontainers:testcontainers-cassandra": 888108804, "org.testcontainers:testcontainers-cassandra:jar:sources": 2024290088, "org.testcontainers:testcontainers-database-commons": -1213526598, "org.testcontainers:testcontainers-database-commons:jar:sources": 315333060, @@ -801,13 +777,6 @@ "tools.jackson.module:jackson-module-blackbird:jar:sources": -9825245 }, "artifacts": { - "aopalliance:aopalliance": { - "shasums": { - "jar": "0addec670fedcd3f113c5c8091d783280d23f75e3acb841b61a9cdb079376a08", - "sources": "e6ef91d439ada9045f419c77543ebe0416c3cdfc5b063448343417a3e4a72123" - }, - "version": "1.0" - }, "args4j:args4j": { "shasums": { "jar": "11b029a602e787e2bc08eb3b77eda1a4f5e8b263d22e3c5d6220cd5c51f30b18", @@ -1035,31 +1004,31 @@ }, "com.google.code.gson:gson": { "shasums": { - "jar": "d3999291855de495c94c743761b8ab5176cfeabe281a5ab0d8e8d45326fd703e", - "sources": "ba5bddb1a89eb721fcca39f3b34294532060f851e2407a82d82134a41eec4719" + "jar": "dd0ce1b55a3ed2080cb70f9c655850cda86c206862310009dcb5e5c95265a5e0", + "sources": "058974b69cb7b0a04712278e11870e84ee8cd8fb5f551bd8401e72ba6638bfef" }, - "version": "2.8.9" + "version": "2.13.2" }, "com.google.errorprone:error_prone_annotations": { "shasums": { - "jar": "ff80626baaf12a09342befd4e84cba9d50662f5fcd7f7a9b3490a6b7cf87e66c", - "sources": "bf08616e340f5e2ef50aaa84aea8baa086fd7bb2ad310501ff4e88ec77f8f31a" + "jar": "3b1003e51b8ae56fdbd7c71073e81d1683b97e6c4dff5a9151164d59b769d13c", + "sources": "69d2de7f69033ff914ba06f0858adb96ac7b1436959f04fca7de5805c834b281" }, - "version": "2.5.1" + "version": "2.49.0" }, "com.google.guava:failureaccess": { "shasums": { - "jar": "a171ee4c734dd2da837e4b16be9df4661afab72a41adaf31eb84dfdaf936ca26", - "sources": "092346eebbb1657b51aa7485a246bf602bb464cc0b0e2e1c7e7201fadce1e98f" + "jar": "cbfc3906b19b8f55dd7cfd6dfe0aa4532e834250d7f080bd8d211a3e246b59cb", + "sources": "6fef4dfd2eb9f961655f2a3c4ea87c023618d9fcbfb6b104c17862e5afe66b97" }, - "version": "1.0.1" + "version": "1.0.3" }, "com.google.guava:guava": { "shasums": { - "jar": "bd7fa227591fb8509677d0d1122cf95158f3b8a9f45653f58281d879f6dc48c5", - "sources": "9105dfc522fb440b39ff8da07cc56aacf65a9f765044c7803a9f32e36e05a22b" + "jar": "dc573e1fca4fd5454f4a5fd3d7da2df03002876a4175bafc14a95980dd7713b3", + "sources": "eff31867dd63a92d63ca856127a424a6836418d8bfa044162cac20430abd3500" }, - "version": "32.0.1-jre" + "version": "33.6.0-jre" }, "com.google.guava:listenablefuture": { "shasums": { @@ -1069,10 +1038,10 @@ }, "com.google.j2objc:j2objc-annotations": { "shasums": { - "jar": "f02a95fa1a5e95edb3ed859fd0fb7df709d121a35290eff8b74dce2ab7f4d6ed", - "sources": "7413eed41f111453a08837f5ac680edded7faed466cbd35745e402e13f4cc3f5" + "jar": "84d3a150518485f8140ea99b8a985656749629f6433c92b80c75b36aba3b099b", + "sources": "295938307f4016b3f128f7347101b236ada1394808104519c9e93cd61b64602b" }, - "version": "2.8" + "version": "3.1" }, "com.google.protobuf:protobuf-java": { "shasums": { @@ -1216,10 +1185,10 @@ }, "io.dropwizard.metrics:metrics-core": { "shasums": { - "jar": "5c6f685e41664d10c70c65837cba9e58d39ff3896811e3b5707a934b11c85ad0", - "sources": "773164a026ea78df51d14608def3a746a2270f630e9a2f5f6f99d6e155ad5bcf" + "jar": "a735eb5b62f425181efa53aefa5b7edad2b0e48cd0fa91105aa0ec1a45169e0b", + "sources": "da7c32215bb0e94f8e735f7ebd70acd08340ea36d4e0cdf150ae1435e3a25221" }, - "version": "3.2.2" + "version": "4.1.18" }, "io.grpc:grpc-api": { "shasums": { @@ -1230,17 +1199,17 @@ }, "io.grpc:grpc-context": { "shasums": { - "jar": "fec0773020404a1f9b9610168692c8ed47fb77181c2ba37cc842ba7664bfc6b0", - "sources": "0a45ca2dc3452783be72412c0e75e0a57c276e76d29d778a22e331279f08d5c0" + "jar": "d7f50185bb858131d02314de23ea3cc797131ed98b215e845429f45a81dd5fed", + "sources": "a9032f8d2f795247bef60b45ee5fc3eb4693c705c05818cc12e9ed1deba440d4" }, - "version": "1.74.0" + "version": "1.63.0" }, "io.grpc:grpc-core": { "shasums": { - "jar": "5175e6223ee1f0a63cf93049aabe7bd5b675cc739b286fe3b320a88fa90c320e", - "sources": "2c7a8d053a2bfa7c423ca01f1b6462bf402ff710aea8c49a73c2d0d73ba8e358" + "jar": "246e4e583cc11c70ed15cc8f988eff8e76fed5c06426e8310d51c4da6f5cc81b", + "sources": "6d2f37cebce94495593d736e118d6df8ff05b877e2ebc2b5e472c140a5fa5559" }, - "version": "1.74.0" + "version": "1.63.0" }, "io.grpc:grpc-inprocess": { "shasums": { @@ -1249,13 +1218,6 @@ }, "version": "1.63.0" }, - "io.grpc:grpc-netty": { - "shasums": { - "jar": "8ead962173ff44752a1970b6e567225e1e9aeebb5c74af1e33e7786a45c9d620", - "sources": "cc8b33cf89f7ab51c14c8ac5eae47ffccb9836216ecd0bbe311f8e774f3aac86" - }, - "version": "1.74.0" - }, "io.grpc:grpc-netty-shaded": { "shasums": { "jar": "4d170c599e47214f35c8955cda3edd7cdb8171229b45795d4d61eb43dfa76402", @@ -1293,10 +1255,10 @@ }, "io.grpc:grpc-util": { "shasums": { - "jar": "296dc07438c43454afc1a7f2736086550feb1fc783f9547337ad2ae721e24350", - "sources": "ba7b02ef3f3a7ed93881c1c37db8b7372458215c7e2e7d57d1a7fc91725d94e1" + "jar": "b15006f22e76a6631dfb137a6930aaf9e0cb3a797499ec42394d79641fb770ee", + "sources": "969b6a21c1689ad8d71e4f557ccd76c9c3f422c037fe0e5c1e9c9b3f6eeb45d6" }, - "version": "1.74.0" + "version": "1.63.0" }, "io.gsonfire:gson-fire": { "shasums": { @@ -1675,10 +1637,10 @@ }, "io.perfmark:perfmark-api": { "shasums": { - "jar": "c7b478503ec524e55df19b424d46d27c8a68aeb801664fadd4f069b71f52d0f6", - "sources": "311551ab29cf51e5a8abee6a019e88dee47d1ea71deb9fcd3649db9c51b237bc" + "jar": "b7d23e93a34537ce332708269a0d1404788a5b5e1949e82f5535fce51b3ea95b", + "sources": "7379e0fef0c32d69f3ebae8f271f426fc808613f1cfbc29e680757f348ba8aa4" }, - "version": "0.27.0" + "version": "0.26.0" }, "io.projectreactor.netty:reactor-netty-core": { "shasums": { @@ -2037,19 +1999,12 @@ }, "version": "1.80.2" }, - "org.checkerframework:checker-qual": { - "shasums": { - "jar": "e316255bbfcd9fe50d165314b85abb2b33cb2a66a93c491db648e498a82c2de1", - "sources": "443fa6151982bb4c6ce62e2938f53660085b13a7dceb517202777b87d0dea2c7" - }, - "version": "3.33.0" - }, "org.codehaus.mojo:animal-sniffer-annotations": { "shasums": { - "jar": "c720e6e5bcbe6b2f48ded75a47bccdb763eede79d14330102e0d352e3d89ed92", - "sources": "4270ce5531ed0f12e4234e08f240ef3b45ee3ceeb16e28d44abc61c12cf522ca" + "jar": "9ffe526bf43a6348e9d8b33b9cd6f580a7f5eed0cf055913007eda263de974d0", + "sources": "4878fcc6808dbc88085a4622db670e703867754bc4bc40312c52bf3a3510d019" }, - "version": "1.24" + "version": "1.23" }, "org.hamcrest:hamcrest": { "shasums": { @@ -2191,20 +2146,6 @@ }, "version": "6.0.3" }, - "org.junit.platform:junit-platform-launcher": { - "shasums": { - "jar": "315608372e4dc44bca0ccb3ae8a07ecc206b3367033fa05748a03ccd563f1301", - "sources": "4fcbdb81cc882c0c3e73f742878db5884d3d2f86facc08369ca953e32796d144" - }, - "version": "6.0.3" - }, - "org.junit.platform:junit-platform-reporting": { - "shasums": { - "jar": "f19c5be871c37ebed493f3152b67a909f89a44dff67c2db8016dfe34167d5730", - "sources": "bbdda2b9c002dbd1b05cfec144bab91e8cca46ed8d58525f51b547f3a0a84a7d" - }, - "version": "6.0.3" - }, "org.latencyutils:LatencyUtils": { "shasums": { "jar": "a32a9ffa06b2f4e01c5360f8f9df7bc5d9454a5d373cd8f361347fa5a57165ec", @@ -2233,13 +2174,6 @@ }, "version": "3.3" }, - "org.opentest4j.reporting:open-test-reporting-tooling-spi": { - "shasums": { - "jar": "04ac4ecfcaf60abe0e6d5b18e8306320aec7cd9cbf15e59eeac54fa9faa16902", - "sources": "efe9672e74111726c0ff85a2508a0bc78be611a7cbe460560dc7cd429ee0a4ce" - }, - "version": "0.2.4" - }, "org.opentest4j:opentest4j": { "shasums": { "jar": "48e2df636cab6563ced64dcdff8abb2355627cb236ef0bf37598682ddf742f1b", @@ -2709,13 +2643,6 @@ }, "version": "4.0.7" }, - "org.springframework.boot:spring-boot-starter-web": { - "shasums": { - "jar": "1ac009b240450c089df7ef1e5cc9b63df292bea22393ed5c7deca42c85944e3c", - "sources": "1ac009b240450c089df7ef1e5cc9b63df292bea22393ed5c7deca42c85944e3c" - }, - "version": "4.0.7" - }, "org.springframework.boot:spring-boot-starter-webflux": { "shasums": { "jar": "dd99ab79bd18c6358183b146c3eb35730652dd36d2225d5795405efa7137b1a0", @@ -3236,12 +3163,20 @@ "conflict_resolution": { "com.github.jnr:jnr-ffi:2.2.11": "com.github.jnr:jnr-ffi:2.1.7", "com.github.jnr:jnr-posix:3.0.44": "com.github.jnr:jnr-posix:3.1.15", + "com.google.code.findbugs:jsr305:2.0.1": "com.google.code.findbugs:jsr305:3.0.2", + "com.google.errorprone:error_prone_annotations:2.18.0": "com.google.errorprone:error_prone_annotations:2.49.0", + "com.google.errorprone:error_prone_annotations:2.23.0": "com.google.errorprone:error_prone_annotations:2.49.0", + "com.google.errorprone:error_prone_annotations:2.41.0": "com.google.errorprone:error_prone_annotations:2.49.0", + "com.google.errorprone:error_prone_annotations:2.47.0": "com.google.errorprone:error_prone_annotations:2.49.0", + "com.google.guava:guava:19.0": "com.google.guava:guava:33.6.0-jre", + "com.google.guava:guava:32.1.3-android": "com.google.guava:guava:33.6.0-jre", + "com.google.guava:guava:32.1.3-jre": "com.google.guava:guava:33.6.0-jre", + "com.google.j2objc:j2objc-annotations:2.8": "com.google.j2objc:j2objc-annotations:3.1", "com.squareup.okio:okio-jvm:3.6.0": "com.squareup.okio:okio-jvm:3.16.1", "commons-io:commons-io:2.19.0": "commons-io:commons-io:2.20.0", - "io.grpc:grpc-core:1.63.0": "io.grpc:grpc-core:1.74.0", - "io.grpc:grpc-util:1.63.0": "io.grpc:grpc-util:1.74.0", - "io.perfmark:perfmark-api:0.26.0": "io.perfmark:perfmark-api:0.27.0", + "io.dropwizard.metrics:metrics-core:3.2.2": "io.dropwizard.metrics:metrics-core:4.1.18", "org.apache.commons:commons-compress:1.27.1": "org.apache.commons:commons-compress:1.28.0", + "org.hdrhistogram:HdrHistogram:2.1.12": "org.hdrhistogram:HdrHistogram:2.2.2", "org.jetbrains:annotations:13.0": "org.jetbrains:annotations:17.0.0" }, "dependencies": { @@ -3323,13 +3258,15 @@ "com.google.api.grpc:proto-google-common-protos": [ "com.google.protobuf:protobuf-java" ], + "com.google.code.gson:gson": [ + "com.google.errorprone:error_prone_annotations" + ], "com.google.guava:guava": [ - "com.google.code.findbugs:jsr305", "com.google.errorprone:error_prone_annotations", "com.google.guava:failureaccess", "com.google.guava:listenablefuture", "com.google.j2objc:j2objc-annotations", - "org.checkerframework:checker-qual" + "org.jspecify:jspecify" ], "com.google.protobuf:protobuf-java-util": [ "com.google.code.findbugs:jsr305", @@ -3400,18 +3337,6 @@ "io.grpc:grpc-api", "io.grpc:grpc-core" ], - "io.grpc:grpc-netty": [ - "com.google.errorprone:error_prone_annotations", - "com.google.guava:guava", - "io.grpc:grpc-api", - "io.grpc:grpc-core", - "io.grpc:grpc-util", - "io.netty:netty-codec-http2", - "io.netty:netty-handler-proxy", - "io.netty:netty-transport-native-unix-common", - "io.perfmark:perfmark-api", - "org.codehaus.mojo:animal-sniffer-annotations" - ], "io.grpc:grpc-netty-shaded": [ "com.google.errorprone:error_prone_annotations", "com.google.guava:guava", @@ -3537,7 +3462,6 @@ "org.jspecify:jspecify" ], "io.micrometer:micrometer-tracing": [ - "aopalliance:aopalliance", "io.micrometer:context-propagation", "io.micrometer:micrometer-observation", "org.jspecify:jspecify" @@ -3849,8 +3773,10 @@ "com.fasterxml.jackson.core:jackson-databind", "com.github.jnr:jnr-posix", "com.typesafe:config", + "io.dropwizard.metrics:metrics-core", "io.netty:netty-handler", "org.apache.cassandra:java-driver-guava-shaded", + "org.hdrhistogram:HdrHistogram", "org.reactivestreams:reactive-streams", "org.slf4j:slf4j-api" ], @@ -3949,17 +3875,6 @@ "org.junit.platform:junit-platform-commons", "org.opentest4j:opentest4j" ], - "org.junit.platform:junit-platform-launcher": [ - "org.apiguardian:apiguardian-api", - "org.jspecify:jspecify", - "org.junit.platform:junit-platform-engine" - ], - "org.junit.platform:junit-platform-reporting": [ - "org.apiguardian:apiguardian-api", - "org.jspecify:jspecify", - "org.junit.platform:junit-platform-launcher", - "org.opentest4j.reporting:open-test-reporting-tooling-spi" - ], "org.mockito:mockito-core": [ "net.bytebuddy:byte-buddy", "net.bytebuddy:byte-buddy-agent", @@ -3969,9 +3884,6 @@ "org.junit.jupiter:junit-jupiter-api", "org.mockito:mockito-core" ], - "org.opentest4j.reporting:open-test-reporting-tooling-spi": [ - "org.apiguardian:apiguardian-api" - ], "org.ow2.asm:asm-analysis": [ "org.ow2.asm:asm-tree" ], @@ -4271,12 +4183,6 @@ "org.springframework.boot:spring-boot-starter", "org.springframework.boot:spring-boot-validation" ], - "org.springframework.boot:spring-boot-starter-web": [ - "org.springframework.boot:spring-boot-http-converter", - "org.springframework.boot:spring-boot-starter-jackson", - "org.springframework.boot:spring-boot-starter-tomcat", - "org.springframework.boot:spring-boot-webmvc" - ], "org.springframework.boot:spring-boot-starter-webflux": [ "org.springframework.boot:spring-boot-reactor", "org.springframework.boot:spring-boot-starter", @@ -4645,10 +4551,6 @@ ] }, "packages": { - "aopalliance:aopalliance": [ - "org.aopalliance.aop", - "org.aopalliance.intercept" - ], "args4j:args4j": [ "org.kohsuke.args4j", "org.kohsuke.args4j.spi" @@ -5346,9 +5248,6 @@ "io.grpc:grpc-inprocess": [ "io.grpc.inprocess" ], - "io.grpc:grpc-netty": [ - "io.grpc.netty" - ], "io.grpc:grpc-netty-shaded": [ "io.grpc.netty.shaded.io.grpc.netty", "io.grpc.netty.shaded.io.netty.bootstrap", @@ -7013,38 +6912,6 @@ "org.bouncycastle.oer.its.template.ieee1609dot2.basetypes", "org.bouncycastle.oer.its.template.ieee1609dot2dot1" ], - "org.checkerframework:checker-qual": [ - "org.checkerframework.checker.builder.qual", - "org.checkerframework.checker.calledmethods.qual", - "org.checkerframework.checker.compilermsgs.qual", - "org.checkerframework.checker.fenum.qual", - "org.checkerframework.checker.formatter.qual", - "org.checkerframework.checker.guieffect.qual", - "org.checkerframework.checker.i18n.qual", - "org.checkerframework.checker.i18nformatter.qual", - "org.checkerframework.checker.index.qual", - "org.checkerframework.checker.initialization.qual", - "org.checkerframework.checker.interning.qual", - "org.checkerframework.checker.lock.qual", - "org.checkerframework.checker.mustcall.qual", - "org.checkerframework.checker.nullness.qual", - "org.checkerframework.checker.optional.qual", - "org.checkerframework.checker.propkey.qual", - "org.checkerframework.checker.regex.qual", - "org.checkerframework.checker.signature.qual", - "org.checkerframework.checker.signedness.qual", - "org.checkerframework.checker.tainting.qual", - "org.checkerframework.checker.units.qual", - "org.checkerframework.common.aliasing.qual", - "org.checkerframework.common.initializedfields.qual", - "org.checkerframework.common.reflection.qual", - "org.checkerframework.common.returnsreceiver.qual", - "org.checkerframework.common.subtyping.qual", - "org.checkerframework.common.util.report.qual", - "org.checkerframework.common.value.qual", - "org.checkerframework.dataflow.qual", - "org.checkerframework.framework.qual" - ], "org.codehaus.mojo:animal-sniffer-annotations": [ "org.codehaus.mojo.animal_sniffer" ], @@ -7428,27 +7295,6 @@ "org.junit.platform.engine.support.hierarchical", "org.junit.platform.engine.support.store" ], - "org.junit.platform:junit-platform-launcher": [ - "org.junit.platform.launcher", - "org.junit.platform.launcher.core", - "org.junit.platform.launcher.jfr", - "org.junit.platform.launcher.listeners", - "org.junit.platform.launcher.listeners.discovery", - "org.junit.platform.launcher.listeners.session", - "org.junit.platform.launcher.tagexpression" - ], - "org.junit.platform:junit-platform-reporting": [ - "org.junit.platform.reporting", - "org.junit.platform.reporting.legacy", - "org.junit.platform.reporting.legacy.xml", - "org.junit.platform.reporting.open.xml", - "org.junit.platform.reporting.shadow.org.opentest4j.reporting.events.api", - "org.junit.platform.reporting.shadow.org.opentest4j.reporting.events.core", - "org.junit.platform.reporting.shadow.org.opentest4j.reporting.events.git", - "org.junit.platform.reporting.shadow.org.opentest4j.reporting.events.java", - "org.junit.platform.reporting.shadow.org.opentest4j.reporting.events.root", - "org.junit.platform.reporting.shadow.org.opentest4j.reporting.schema" - ], "org.latencyutils:LatencyUtils": [ "org.LatencyUtils" ], @@ -7535,9 +7381,6 @@ "org.objenesis.instantiator.util", "org.objenesis.strategy" ], - "org.opentest4j.reporting:open-test-reporting-tooling-spi": [ - "org.opentest4j.reporting.tooling.spi.htmlreport" - ], "org.opentest4j:opentest4j": [ "org.opentest4j" ], @@ -9952,8 +9795,6 @@ }, "repositories": { "https://maven-central.storage-download.googleapis.com/maven2/": [ - "aopalliance:aopalliance", - "aopalliance:aopalliance:jar:sources", "args4j:args4j", "args4j:args4j:jar:sources", "at.yawk.lz4:lz4-java", @@ -10080,10 +9921,8 @@ "io.grpc:grpc-core:jar:sources", "io.grpc:grpc-inprocess", "io.grpc:grpc-inprocess:jar:sources", - "io.grpc:grpc-netty", "io.grpc:grpc-netty-shaded", "io.grpc:grpc-netty-shaded:jar:sources", - "io.grpc:grpc-netty:jar:sources", "io.grpc:grpc-protobuf", "io.grpc:grpc-protobuf-lite", "io.grpc:grpc-protobuf-lite:jar:sources", @@ -10308,8 +10147,6 @@ "org.bouncycastle:bcprov-lts8on:jar:sources", "org.bouncycastle:bcutil-jdk18on", "org.bouncycastle:bcutil-jdk18on:jar:sources", - "org.checkerframework:checker-qual", - "org.checkerframework:checker-qual:jar:sources", "org.codehaus.mojo:animal-sniffer-annotations", "org.codehaus.mojo:animal-sniffer-annotations:jar:sources", "org.hamcrest:hamcrest", @@ -10352,10 +10189,6 @@ "org.junit.platform:junit-platform-console-standalone:jar:sources", "org.junit.platform:junit-platform-engine", "org.junit.platform:junit-platform-engine:jar:sources", - "org.junit.platform:junit-platform-launcher", - "org.junit.platform:junit-platform-launcher:jar:sources", - "org.junit.platform:junit-platform-reporting", - "org.junit.platform:junit-platform-reporting:jar:sources", "org.latencyutils:LatencyUtils", "org.latencyutils:LatencyUtils:jar:sources", "org.mockito:mockito-core", @@ -10364,8 +10197,6 @@ "org.mockito:mockito-junit-jupiter:jar:sources", "org.objenesis:objenesis", "org.objenesis:objenesis:jar:sources", - "org.opentest4j.reporting:open-test-reporting-tooling-spi", - "org.opentest4j.reporting:open-test-reporting-tooling-spi:jar:sources", "org.opentest4j:opentest4j", "org.opentest4j:opentest4j:jar:sources", "org.ow2.asm:asm", @@ -10498,8 +10329,6 @@ "org.springframework.boot:spring-boot-starter-tomcat:jar:sources", "org.springframework.boot:spring-boot-starter-validation", "org.springframework.boot:spring-boot-starter-validation:jar:sources", - "org.springframework.boot:spring-boot-starter-web", - "org.springframework.boot:spring-boot-starter-web:jar:sources", "org.springframework.boot:spring-boot-starter-webflux", "org.springframework.boot:spring-boot-starter-webflux-test", "org.springframework.boot:spring-boot-starter-webflux-test:jar:sources", @@ -10650,8 +10479,6 @@ "tools.jackson.module:jackson-module-blackbird:jar:sources" ], "https://repo.maven.apache.org/maven2/": [ - "aopalliance:aopalliance", - "aopalliance:aopalliance:jar:sources", "args4j:args4j", "args4j:args4j:jar:sources", "at.yawk.lz4:lz4-java", @@ -10778,10 +10605,8 @@ "io.grpc:grpc-core:jar:sources", "io.grpc:grpc-inprocess", "io.grpc:grpc-inprocess:jar:sources", - "io.grpc:grpc-netty", "io.grpc:grpc-netty-shaded", "io.grpc:grpc-netty-shaded:jar:sources", - "io.grpc:grpc-netty:jar:sources", "io.grpc:grpc-protobuf", "io.grpc:grpc-protobuf-lite", "io.grpc:grpc-protobuf-lite:jar:sources", @@ -11006,8 +10831,6 @@ "org.bouncycastle:bcprov-lts8on:jar:sources", "org.bouncycastle:bcutil-jdk18on", "org.bouncycastle:bcutil-jdk18on:jar:sources", - "org.checkerframework:checker-qual", - "org.checkerframework:checker-qual:jar:sources", "org.codehaus.mojo:animal-sniffer-annotations", "org.codehaus.mojo:animal-sniffer-annotations:jar:sources", "org.hamcrest:hamcrest", @@ -11050,10 +10873,6 @@ "org.junit.platform:junit-platform-console-standalone:jar:sources", "org.junit.platform:junit-platform-engine", "org.junit.platform:junit-platform-engine:jar:sources", - "org.junit.platform:junit-platform-launcher", - "org.junit.platform:junit-platform-launcher:jar:sources", - "org.junit.platform:junit-platform-reporting", - "org.junit.platform:junit-platform-reporting:jar:sources", "org.latencyutils:LatencyUtils", "org.latencyutils:LatencyUtils:jar:sources", "org.mockito:mockito-core", @@ -11062,8 +10881,6 @@ "org.mockito:mockito-junit-jupiter:jar:sources", "org.objenesis:objenesis", "org.objenesis:objenesis:jar:sources", - "org.opentest4j.reporting:open-test-reporting-tooling-spi", - "org.opentest4j.reporting:open-test-reporting-tooling-spi:jar:sources", "org.opentest4j:opentest4j", "org.opentest4j:opentest4j:jar:sources", "org.ow2.asm:asm", @@ -11196,8 +11013,6 @@ "org.springframework.boot:spring-boot-starter-tomcat:jar:sources", "org.springframework.boot:spring-boot-starter-validation", "org.springframework.boot:spring-boot-starter-validation:jar:sources", - "org.springframework.boot:spring-boot-starter-web", - "org.springframework.boot:spring-boot-starter-web:jar:sources", "org.springframework.boot:spring-boot-starter-webflux", "org.springframework.boot:spring-boot-starter-webflux-test", "org.springframework.boot:spring-boot-starter-webflux-test:jar:sources", @@ -11393,18 +11208,6 @@ "io.grpc.internal.DnsNameResolverProvider" ] }, - "io.grpc:grpc-netty": { - "io.grpc.ManagedChannelProvider": [ - "io.grpc.netty.NettyChannelProvider", - "io.grpc.netty.UdsNettyChannelProvider" - ], - "io.grpc.NameResolverProvider": [ - "io.grpc.netty.UdsNameResolverProvider" - ], - "io.grpc.ServerProvider": [ - "io.grpc.netty.NettyServerProvider" - ] - }, "io.grpc:grpc-netty-shaded": { "io.grpc.ManagedChannelProvider": [ "io.grpc.netty.shaded.io.grpc.netty.NettyChannelProvider", @@ -11603,19 +11406,6 @@ "org.junit.platform.engine.discovery.UriSelector$IdentifierParser" ] }, - "org.junit.platform:junit-platform-launcher": { - "org.junit.platform.launcher.TestExecutionListener": [ - "org.junit.platform.launcher.listeners.UniqueIdTrackingListener" - ] - }, - "org.junit.platform:junit-platform-reporting": { - "org.junit.platform.launcher.TestExecutionListener": [ - "org.junit.platform.reporting.open.xml.OpenTestReportGeneratingListener" - ], - "org.opentest4j.reporting.tooling.spi.htmlreport.Contributor": [ - "org.junit.platform.reporting.open.xml.JUnitContributor" - ] - }, "org.projectlombok:lombok": { "javax.annotation.processing.Processor": [ "lombok.launch.AnnotationProcessorHider$AnnotationProcessor", diff --git a/src/control-plane-services/cloud-tasks/nvct-core/BUILD.bazel b/src/control-plane-services/cloud-tasks/nvct-core/BUILD.bazel index cca9b3952..7a9fa8c7a 100644 --- a/src/control-plane-services/cloud-tasks/nvct-core/BUILD.bazel +++ b/src/control-plane-services/cloud-tasks/nvct-core/BUILD.bazel @@ -1,35 +1,11 @@ -load("@com_google_protobuf//bazel:proto_library.bzl", "proto_library") -load("@contrib_rules_jvm//java:defs.bzl", "java_junit5_test") +load("@protobuf//bazel:proto_library.bzl", "proto_library") load("@rules_java//java:defs.bzl", "java_library") -load("@nvcf_java_rules//:defs.bzl", "nvcf_java_library") +load("//tools/bazel:java.bzl", "nvct_library", "nvct_library_test") load("//tools/bazel:proto.bzl", "nvct_java_grpc_compile") package(default_visibility = ["//visibility:public"]) -# Error Prone runs in the default Bazel Java toolchain; keep the checks the -# service opts out of and enable deprecation lints. --release matches the -# hermetic remotejdk toolchain language level. -NVCT_JAVACOPTS = [ - "--release", - "25", - "-Xep:CheckReturnValue:OFF", - "-Xep:ImpossibleNullComparison:OFF", - "-Xep:OptionalOfRedundantMethod:OFF", - "-Xlint:deprecation", -] - -# nvcf_java_library does not wire Lombok; add the annotation processor plugin -# plus the neverlink annotations jar to every library that compiles Lombok -# sources. Both targets already exist in tools/bazel. -LOMBOK_PLUGINS = ["//tools/bazel:lombok_plugin"] - -LOMBOK_DEPS = ["//tools/bazel:lombok_annotations"] - -JUNIT5_RUNTIME_DEPS = [ - "@maven//:org_junit_jupiter_junit_jupiter_engine", - "@maven//:org_junit_platform_junit_platform_launcher", - "@maven//:org_junit_platform_junit_platform_reporting", -] +NVCT_CORE_SRCS = glob(["src/main/java/**/*.java"]) NVCT_CORE_TEST_SRCS = glob(["src/test/java/**/*.java"]) @@ -40,7 +16,7 @@ NVCT_CORE_TEST_RESOURCES = glob(["src/test/resources/**"]) + [ proto_library( name = "nvct_proto", srcs = ["src/main/proto/nvct.proto"], - deps = ["@com_google_protobuf//:timestamp_proto"], + deps = ["@protobuf//:timestamp_proto"], ) nvct_java_grpc_compile( @@ -50,45 +26,43 @@ nvct_java_grpc_compile( # rules_proto_grpc_java's convenience java_grpc_library macro hardcodes its # private @maven runtime hub. Owning this small wrapper keeps all application -# runtime jars in this module's own @maven hub. +# runtime jars in the merged @nv_third_party_deps hub shared with nv-boot-parent. java_library( name = "nvct_proto_java_grpc", srcs = [":nvct_proto_java_grpc_srcs"], deps = [ - "@maven//:com_google_guava_guava", - "@maven//:com_google_protobuf_protobuf_java", - "@maven//:com_google_protobuf_protobuf_java_util", - "@maven//:io_grpc_grpc_api", - "@maven//:io_grpc_grpc_protobuf", - "@maven//:io_grpc_grpc_stub", - "@maven//:javax_annotation_javax_annotation_api", + "@nv_third_party_deps//:com_google_guava_guava", + "@nv_third_party_deps//:com_google_protobuf_protobuf_java", + "@nv_third_party_deps//:com_google_protobuf_protobuf_java_util", + "@nv_third_party_deps//:io_grpc_grpc_api", + "@nv_third_party_deps//:io_grpc_grpc_protobuf", + "@nv_third_party_deps//:io_grpc_grpc_stub", + "@nv_third_party_deps//:javax_annotation_javax_annotation_api", ], exports = [ - "@maven//:com_google_guava_guava", - "@maven//:com_google_protobuf_protobuf_java", - "@maven//:com_google_protobuf_protobuf_java_util", - "@maven//:io_grpc_grpc_api", - "@maven//:io_grpc_grpc_protobuf", - "@maven//:io_grpc_grpc_stub", - "@maven//:javax_annotation_javax_annotation_api", + "@nv_third_party_deps//:com_google_guava_guava", + "@nv_third_party_deps//:com_google_protobuf_protobuf_java", + "@nv_third_party_deps//:com_google_protobuf_protobuf_java_util", + "@nv_third_party_deps//:io_grpc_grpc_api", + "@nv_third_party_deps//:io_grpc_grpc_protobuf", + "@nv_third_party_deps//:io_grpc_grpc_stub", + "@nv_third_party_deps//:javax_annotation_javax_annotation_api", ], ) -nvcf_java_library( +nvct_library( name = "nvct_core", - srcs = glob(["src/main/java/**/*.java"]), - javacopts = NVCT_JAVACOPTS, - plugins = LOMBOK_PLUGINS, + srcs = NVCT_CORE_SRCS, deps = [ ":nvct_proto_java_grpc", - "@maven//:com_bucket4j_bucket4j_jdk17_core", - "@maven//:commons_codec_commons_codec", - "@maven//:com_fasterxml_jackson_core_jackson_annotations", - "@maven//:com_github_ben_manes_caffeine_caffeine", - "@maven//:com_github_ben_manes_caffeine_guava", - "@maven//:com_google_guava_guava", - "@maven//:com_google_protobuf_protobuf_java", - "@maven//:com_nimbusds_oauth2_oidc_sdk", + "@nv_third_party_deps//:com_bucket4j_bucket4j_jdk17_core", + "@nv_third_party_deps//:commons_codec_commons_codec", + "@nv_third_party_deps//:com_fasterxml_jackson_core_jackson_annotations", + "@nv_third_party_deps//:com_github_ben_manes_caffeine_caffeine", + "@nv_third_party_deps//:com_github_ben_manes_caffeine_guava", + "@nv_third_party_deps//:com_google_guava_guava", + "@nv_third_party_deps//:com_google_protobuf_protobuf_java", + "@nv_third_party_deps//:com_nimbusds_oauth2_oidc_sdk", "@nv_boot_parent//nv-boot-starter-audit:nv_boot_starter_audit", "@nv_boot_parent//nv-boot-starter-cassandra:nv_boot_starter_cassandra", "@nv_boot_parent//nv-boot-starter-core:nv_boot_starter_core", @@ -96,84 +70,84 @@ nvcf_java_library( "@nv_boot_parent//nv-boot-starter-observability:nv_boot_starter_observability", "@nv_boot_parent//nv-boot-starter-registries:nv_boot_starter_registries", "@nv_boot_parent//nv-boot-starter-reloadable-properties:nv_boot_starter_reloadable_properties", - "@maven//:io_grpc_grpc_api", - "@maven//:io_grpc_grpc_netty_shaded", - "@maven//:io_grpc_grpc_stub", - "@maven//:io_micrometer_micrometer_core", - "@maven//:io_micrometer_micrometer_observation", - "@maven//:io_micrometer_micrometer_registry_prometheus", - "@maven//:io_micrometer_micrometer_tracing", - "@maven//:io_swagger_core_v3_swagger_annotations_jakarta", - "@maven//:io_swagger_core_v3_swagger_models_jakarta", - "@maven//:io_netty_netty_transport", - "@maven//:io_netty_netty_handler", - "@maven//:jakarta_annotation_jakarta_annotation_api", - "@maven//:jakarta_servlet_jakarta_servlet_api", - "@maven//:jakarta_validation_jakarta_validation_api", - "@maven//:net_devh_grpc_server_spring_boot_starter", - "@maven//:net_javacrumbs_shedlock_shedlock_core", - "@maven//:net_javacrumbs_shedlock_shedlock_provider_cassandra", - "@maven//:net_javacrumbs_shedlock_shedlock_spring", - "@maven//:org_apache_cassandra_java_driver_metrics_micrometer", - "@maven//:org_apache_cassandra_java_driver_core", - "@maven//:org_apache_cassandra_java_driver_query_builder", - "@maven//:org_apache_commons_commons_lang3", - "@maven//:org_apache_logging_log4j_log4j_api", - "@maven//:org_hibernate_validator_hibernate_validator", - "@maven//:org_jspecify_jspecify", - "@maven//:org_slf4j_slf4j_api", - "@maven//:org_springdoc_springdoc_openapi_starter_common", - "@maven//:org_springdoc_springdoc_openapi_starter_webmvc_api", - "@maven//:org_springframework_boot_spring_boot", - "@maven//:org_springframework_boot_spring_boot_actuator", - "@maven//:org_springframework_boot_spring_boot_autoconfigure", - "@maven//:org_springframework_boot_spring_boot_micrometer_metrics", - "@maven//:org_springframework_boot_spring_boot_starter_aspectj", - "@maven//:org_springframework_boot_spring_boot_starter_jackson", - "@maven//:org_springframework_boot_spring_boot_starter_security", - "@maven//:org_springframework_boot_spring_boot_starter_security_oauth2_client", - "@maven//:org_springframework_boot_spring_boot_starter_security_oauth2_resource_server", - "@maven//:org_springframework_boot_spring_boot_starter_validation", - "@maven//:org_springframework_boot_spring_boot_starter_webmvc", - "@maven//:org_springframework_cloud_spring_cloud_context", - "@maven//:org_springframework_cloud_spring_cloud_starter_kubernetes_client_config", - "@maven//:org_springframework_data_spring_data_cassandra", - "@maven//:org_springframework_data_spring_data_commons", - "@maven//:org_springframework_spring_aop", - "@maven//:org_springframework_spring_beans", - "@maven//:org_springframework_spring_context", - "@maven//:org_springframework_spring_context_support", - "@maven//:org_springframework_spring_core", - "@maven//:org_springframework_spring_expression", - "@maven//:org_springframework_spring_tx", - "@maven//:org_springframework_spring_web", - "@maven//:org_springframework_spring_webflux", - "@maven//:org_springframework_spring_webmvc", - "@maven//:org_springframework_retry_spring_retry", - "@maven//:org_springframework_security_spring_security_config", - "@maven//:org_springframework_security_spring_security_core", - "@maven//:org_springframework_security_spring_security_oauth2_client", - "@maven//:org_springframework_security_spring_security_oauth2_core", - "@maven//:org_springframework_security_spring_security_oauth2_jose", - "@maven//:org_springframework_security_spring_security_oauth2_resource_server", - "@maven//:org_springframework_security_spring_security_web", - "@maven//:io_projectreactor_reactor_core", - "@maven//:io_projectreactor_netty_reactor_netty_core", - "@maven//:io_projectreactor_netty_reactor_netty_http", - "@maven//:tools_jackson_core_jackson_core", - "@maven//:tools_jackson_core_jackson_databind", - "@maven//:tools_jackson_module_jackson_module_blackbird", - ] + LOMBOK_DEPS, + "@nv_third_party_deps//:io_grpc_grpc_api", + "@nv_third_party_deps//:io_grpc_grpc_netty_shaded", + "@nv_third_party_deps//:io_grpc_grpc_stub", + "@nv_third_party_deps//:io_micrometer_micrometer_core", + "@nv_third_party_deps//:io_micrometer_micrometer_observation", + "@nv_third_party_deps//:io_micrometer_micrometer_registry_prometheus", + "@nv_third_party_deps//:io_micrometer_micrometer_tracing", + "@nv_third_party_deps//:io_swagger_core_v3_swagger_annotations_jakarta", + "@nv_third_party_deps//:io_swagger_core_v3_swagger_models_jakarta", + "@nv_third_party_deps//:io_netty_netty_transport", + "@nv_third_party_deps//:io_netty_netty_handler", + "@nv_third_party_deps//:jakarta_annotation_jakarta_annotation_api", + "@nv_third_party_deps//:jakarta_servlet_jakarta_servlet_api", + "@nv_third_party_deps//:jakarta_validation_jakarta_validation_api", + "@nv_third_party_deps//:net_devh_grpc_server_spring_boot_starter", + "@nv_third_party_deps//:net_javacrumbs_shedlock_shedlock_core", + "@nv_third_party_deps//:net_javacrumbs_shedlock_shedlock_provider_cassandra", + "@nv_third_party_deps//:net_javacrumbs_shedlock_shedlock_spring", + "@nv_third_party_deps//:org_apache_cassandra_java_driver_metrics_micrometer", + "@nv_third_party_deps//:org_apache_cassandra_java_driver_core", + "@nv_third_party_deps//:org_apache_cassandra_java_driver_query_builder", + "@nv_third_party_deps//:org_apache_commons_commons_lang3", + "@nv_third_party_deps//:org_apache_logging_log4j_log4j_api", + "@nv_third_party_deps//:org_hibernate_validator_hibernate_validator", + "@nv_third_party_deps//:org_jspecify_jspecify", + "@nv_third_party_deps//:org_slf4j_slf4j_api", + "@nv_third_party_deps//:org_springdoc_springdoc_openapi_starter_common", + "@nv_third_party_deps//:org_springdoc_springdoc_openapi_starter_webmvc_api", + "@nv_third_party_deps//:org_springframework_boot_spring_boot", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_actuator", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_autoconfigure", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_micrometer_metrics", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_aspectj", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_jackson", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_security", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_security_oauth2_client", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_security_oauth2_resource_server", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_validation", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_webmvc", + "@nv_third_party_deps//:org_springframework_cloud_spring_cloud_context", + "@nv_third_party_deps//:org_springframework_cloud_spring_cloud_starter_kubernetes_client_config", + "@nv_third_party_deps//:org_springframework_data_spring_data_cassandra", + "@nv_third_party_deps//:org_springframework_data_spring_data_commons", + "@nv_third_party_deps//:org_springframework_spring_aop", + "@nv_third_party_deps//:org_springframework_spring_beans", + "@nv_third_party_deps//:org_springframework_spring_context", + "@nv_third_party_deps//:org_springframework_spring_context_support", + "@nv_third_party_deps//:org_springframework_spring_core", + "@nv_third_party_deps//:org_springframework_spring_expression", + "@nv_third_party_deps//:org_springframework_spring_tx", + "@nv_third_party_deps//:org_springframework_spring_web", + "@nv_third_party_deps//:org_springframework_spring_webflux", + "@nv_third_party_deps//:org_springframework_spring_webmvc", + "@nv_third_party_deps//:org_springframework_retry_spring_retry", + "@nv_third_party_deps//:org_springframework_security_spring_security_config", + "@nv_third_party_deps//:org_springframework_security_spring_security_core", + "@nv_third_party_deps//:org_springframework_security_spring_security_oauth2_client", + "@nv_third_party_deps//:org_springframework_security_spring_security_oauth2_core", + "@nv_third_party_deps//:org_springframework_security_spring_security_oauth2_jose", + "@nv_third_party_deps//:org_springframework_security_spring_security_oauth2_resource_server", + "@nv_third_party_deps//:org_springframework_security_spring_security_web", + "@nv_third_party_deps//:io_projectreactor_reactor_core", + "@nv_third_party_deps//:io_projectreactor_netty_reactor_netty_core", + "@nv_third_party_deps//:io_projectreactor_netty_reactor_netty_http", + "@nv_third_party_deps//:tools_jackson_core_jackson_core", + "@nv_third_party_deps//:tools_jackson_core_jackson_databind", + "@nv_third_party_deps//:tools_jackson_module_jackson_module_blackbird", + ], ) NVCT_CORE_TEST_DEPS = [ ":nvct_core", ":nvct_proto_java_grpc", - "@maven//:org_apache_cassandra_java_driver_core", - "@maven//:org_apache_cassandra_java_driver_guava_shaded", - "@maven//:com_google_guava_guava", - "@maven//:com_google_protobuf_protobuf_java", - "@maven//:com_nimbusds_nimbus_jose_jwt", + "@nv_third_party_deps//:org_apache_cassandra_java_driver_core", + "@nv_third_party_deps//:org_apache_cassandra_java_driver_guava_shaded", + "@nv_third_party_deps//:com_google_guava_guava", + "@nv_third_party_deps//:com_google_protobuf_protobuf_java", + "@nv_third_party_deps//:com_nimbusds_nimbus_jose_jwt", "@nv_boot_parent//nv-boot-mock-servers-test:nv_boot_mock_servers_test", "@nv_boot_parent//nv-boot-starter-audit:nv_boot_starter_audit", "@nv_boot_parent//nv-boot-starter-core:nv_boot_starter_core", @@ -181,82 +155,74 @@ NVCT_CORE_TEST_DEPS = [ "@nv_boot_parent//nv-boot-starter-observability:nv_boot_starter_observability", "@nv_boot_parent//nv-boot-starter-registries:nv_boot_starter_registries", "@nv_boot_parent//nv-boot-starter-reloadable-properties:nv_boot_starter_reloadable_properties", - "@maven//:io_grpc_grpc_api", - "@maven//:io_grpc_grpc_stub", - "@maven//:io_micrometer_micrometer_core", - "@maven//:io_opentelemetry_opentelemetry_api", - "@maven//:io_opentelemetry_opentelemetry_sdk_testing", - "@maven//:io_opentelemetry_opentelemetry_sdk_trace", - "@maven//:io_projectreactor_reactor_core", - "@maven//:io_projectreactor_netty_reactor_netty_core", - "@maven//:jakarta_annotation_jakarta_annotation_api", - "@maven//:jakarta_validation_jakarta_validation_api", - "@maven//:net_minidev_json_smart", - "@maven//:org_apache_commons_commons_lang3", - "@maven//:org_apache_logging_log4j_log4j_api", - "@maven//:org_assertj_assertj_core", - "@maven//:org_awaitility_awaitility", - "@maven//:org_junit_jupiter_junit_jupiter_api", - "@maven//:org_junit_jupiter_junit_jupiter_params", - "@maven//:org_mockito_mockito_core", - "@maven//:org_mockito_mockito_junit_jupiter", - "@maven//:org_springframework_boot_spring_boot", - "@maven//:org_springframework_boot_spring_boot_autoconfigure", - "@maven//:org_springframework_boot_spring_boot_micrometer_tracing", - "@maven//:org_springframework_boot_spring_boot_restclient", - "@maven//:org_springframework_boot_spring_boot_resttestclient", - "@maven//:org_springframework_boot_spring_boot_security", - "@maven//:org_springframework_boot_spring_boot_starter_data_cassandra_test", - "@maven//:org_springframework_boot_spring_boot_starter_webmvc_test", - "@maven//:org_springframework_boot_spring_boot_test", - "@maven//:org_springframework_boot_spring_boot_test_autoconfigure", - "@maven//:org_slf4j_slf4j_api", - "@maven//:org_springframework_data_spring_data_cassandra", - "@maven//:org_springframework_spring_beans", - "@maven//:org_springframework_spring_context", - "@maven//:org_springframework_spring_core", - "@maven//:org_springframework_spring_test", - "@maven//:org_springframework_spring_web", - "@maven//:org_springframework_spring_webflux", - "@maven//:org_springframework_spring_webmvc", - "@maven//:org_testcontainers_testcontainers", - "@maven//:org_testcontainers_testcontainers_cassandra", - "@maven//:tools_jackson_core_jackson_core", - "@maven//:tools_jackson_core_jackson_databind", - "@maven//:org_wiremock_wiremock_standalone", -] + LOMBOK_DEPS + "@nv_third_party_deps//:io_grpc_grpc_api", + "@nv_third_party_deps//:io_grpc_grpc_stub", + "@nv_third_party_deps//:io_micrometer_micrometer_core", + "@nv_third_party_deps//:io_opentelemetry_opentelemetry_api", + "@nv_third_party_deps//:io_opentelemetry_opentelemetry_sdk_testing", + "@nv_third_party_deps//:io_opentelemetry_opentelemetry_sdk_trace", + "@nv_third_party_deps//:io_projectreactor_reactor_core", + "@nv_third_party_deps//:io_projectreactor_netty_reactor_netty_core", + "@nv_third_party_deps//:jakarta_annotation_jakarta_annotation_api", + "@nv_third_party_deps//:jakarta_validation_jakarta_validation_api", + "@nv_third_party_deps//:net_minidev_json_smart", + "@nv_third_party_deps//:org_apache_commons_commons_lang3", + "@nv_third_party_deps//:org_apache_logging_log4j_log4j_api", + "@nv_third_party_deps//:org_assertj_assertj_core", + "@nv_third_party_deps//:org_awaitility_awaitility", + "@nv_third_party_deps//:org_junit_jupiter_junit_jupiter_api", + "@nv_third_party_deps//:org_junit_jupiter_junit_jupiter_params", + "@nv_third_party_deps//:org_mockito_mockito_core", + "@nv_third_party_deps//:org_mockito_mockito_junit_jupiter", + "@nv_third_party_deps//:org_springframework_boot_spring_boot", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_autoconfigure", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_micrometer_tracing", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_restclient", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_resttestclient", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_security", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_data_cassandra_test", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_webmvc_test", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_test", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_test_autoconfigure", + "@nv_third_party_deps//:org_slf4j_slf4j_api", + "@nv_third_party_deps//:org_springframework_data_spring_data_cassandra", + "@nv_third_party_deps//:org_springframework_spring_beans", + "@nv_third_party_deps//:org_springframework_spring_context", + "@nv_third_party_deps//:org_springframework_spring_core", + "@nv_third_party_deps//:org_springframework_spring_test", + "@nv_third_party_deps//:org_springframework_spring_web", + "@nv_third_party_deps//:org_springframework_spring_webflux", + "@nv_third_party_deps//:org_springframework_spring_webmvc", + "@nv_third_party_deps//:org_testcontainers_testcontainers", + "@nv_third_party_deps//:org_testcontainers_testcontainers_cassandra", + "@nv_third_party_deps//:tools_jackson_core_jackson_core", + "@nv_third_party_deps//:tools_jackson_core_jackson_databind", + "@nv_third_party_deps//:org_wiremock_wiremock_standalone", +] -# Compiled test classes, reused by the nvct-service integration test module. -nvcf_java_library( +nvct_library( name = "nvct_core_test_fixtures", - testonly = True, srcs = NVCT_CORE_TEST_SRCS, - javacopts = NVCT_JAVACOPTS, - plugins = LOMBOK_PLUGINS, - resources = NVCT_CORE_TEST_RESOURCES, deps = NVCT_CORE_TEST_DEPS, + resources = NVCT_CORE_TEST_RESOURCES, ) -java_junit5_test( +nvct_library_test( name = "tests", - size = "large", - test_class = "com.nvidia.nvct.rest.task.TaskManagementControllerTest", + coverage_library = ":nvct_core", + srcs = NVCT_CORE_TEST_SRCS, + deps = NVCT_CORE_TEST_DEPS, + data = [ + "//:integration_local_env", + ], # Spring Framework 7 pauses cached contexts when switching configurations. # The embedded gRPC server cannot reliably rebind its random port during # that pause/restart cycle on Linux, so retain the pre-Spring-7 lifecycle. jvm_flags = ["-Dspring.test.context.cache.pause=never"], - data = [ - "//:integration_local_env", - ], + resources = NVCT_CORE_TEST_RESOURCES, tags = [ - # Testcontainers/Cassandra integration test. Runs in the dedicated - # Docker (DinD) integration lane, which selects targets by the - # "requires-docker" tag; the fast matrix excludes it via - # --test_tag_filters=-requires-docker. The test sources still compile in - # the build step via :nvct_core_test_fixtures. "exclusive", "requires-docker", ], timeout = "long", - runtime_deps = [":nvct_core_test_fixtures"] + JUNIT5_RUNTIME_DEPS, ) diff --git a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/HelmChartBasedTaskCreationTest.java b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/HelmChartBasedTaskCreationTest.java index 4879cf64c..73556073c 100644 --- a/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/HelmChartBasedTaskCreationTest.java +++ b/src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/rest/task/HelmChartBasedTaskCreationTest.java @@ -329,7 +329,7 @@ Stream<Arguments> invalidHelmChartUriArgs() { Arguments.of(URI.create("ftp://registry.example.com/chart.tgz")), Arguments.of(URI.create("file:///path/to/chart.tgz")), Arguments.of(URI.create("ldap://registry.example.com/chart")), - Arguments.of(URI.create("ssh://registry.example.com/chart.tgz")), + Arguments.of(URI.create("git://registry.example.com/chart.tgz")), Arguments.of(URI.create( "helm.stg.ngc.nvidia.com/test-org/charts/test-chart-1.0.0.tgz")), Arguments.of(URI.create( diff --git a/src/control-plane-services/cloud-tasks/nvct-service/BUILD.bazel b/src/control-plane-services/cloud-tasks/nvct-service/BUILD.bazel index 70b7a0e8d..d27aab763 100644 --- a/src/control-plane-services/cloud-tasks/nvct-service/BUILD.bazel +++ b/src/control-plane-services/cloud-tasks/nvct-service/BUILD.bazel @@ -1,105 +1,76 @@ -load("@contrib_rules_jvm//java:defs.bzl", "java_junit5_test") -load("@nvcf_java_rules//:defs.bzl", "nvcf_java_library", "nvcf_spring_boot_image") +load("//tools/bazel:java.bzl", "nvct_library", "nvct_library_test") +load("//tools/bazel:spring_boot.bzl", "spring_boot_app") package(default_visibility = ["//visibility:public"]) -# Error Prone runs in the default Bazel Java toolchain; keep the checks the -# service opts out of and enable deprecation lints. --release matches the -# hermetic remotejdk toolchain language level. -NVCT_JAVACOPTS = [ - "--release", - "25", - "-Xep:CheckReturnValue:OFF", - "-Xep:ImpossibleNullComparison:OFF", - "-Xep:OptionalOfRedundantMethod:OFF", - "-Xlint:deprecation", -] +NVCT_SERVICE_SRCS = glob(["src/main/java/**/*.java"]) + +NVCT_SERVICE_RESOURCES = glob(["src/main/resources/**"]) -# nvcf_java_library does not wire Lombok; add the annotation processor plugin -# plus the neverlink annotations jar to every library that compiles Lombok -# sources. Both targets already exist in tools/bazel. -LOMBOK_PLUGINS = ["//tools/bazel:lombok_plugin"] +NVCT_SERVICE_TEST_SRCS = glob(["src/test/java/**/*.java"]) -LOMBOK_DEPS = ["//tools/bazel:lombok_annotations"] +NVCT_SERVICE_TEST_RESOURCES = glob(["src/test/resources/**"]) + [ + "//:integration_local_env_files", +] -JUNIT5_RUNTIME_DEPS = [ - "@maven//:org_junit_jupiter_junit_jupiter_engine", - "@maven//:org_junit_platform_junit_platform_launcher", - "@maven//:org_junit_platform_junit_platform_reporting", +NVCT_SERVICE_DEPS = [ + "//nvct-core:nvct_core", + "@nv_third_party_deps//:org_slf4j_slf4j_api", + "@nv_third_party_deps//:org_springframework_boot_spring_boot", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_autoconfigure", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_loader", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_micrometer_tracing", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_security", ] -nvcf_java_library( +nvct_library( name = "app_classes", - srcs = glob(["src/main/java/**/*.java"]), - javacopts = NVCT_JAVACOPTS, - plugins = LOMBOK_PLUGINS, + srcs = NVCT_SERVICE_SRCS, + deps = NVCT_SERVICE_DEPS, resource_strip_prefix = "nvct-service/src/main/resources", - resources = glob(["src/main/resources/**"]), - deps = [ - "//nvct-core:nvct_core", - "@maven//:org_slf4j_slf4j_api", - "@maven//:org_springframework_boot_spring_boot", - "@maven//:org_springframework_boot_spring_boot_autoconfigure", - "@maven//:org_springframework_boot_spring_boot_loader", - "@maven//:org_springframework_boot_spring_boot_micrometer_tracing", - "@maven//:org_springframework_boot_spring_boot_security", - ] + LOMBOK_DEPS, + resources = NVCT_SERVICE_RESOURCES, + visibility = ["//visibility:private"], ) -# Multi-arch OCI image (exploded classpath under /app/lib). Build-only for now: -# no registry = ... is set, so no :image_push target is emitted. :image_index -# carries the amd64 + arm64 manifest. -nvcf_spring_boot_image( - name = "image", +spring_boot_app( + name = "app", + application = ":app_classes", + artifact_id = "nvct-service-oss", + artifact_name = "NVCT Service OSS", + artifact_version = "0.0.1-SNAPSHOT", + description = "NVIDIA Cloud Tasks OSS executable", + group_id = "com.nvidia.nvct", main_class = "com.nvidia.nvct.App", - deps = [":app_classes"], ) -java_junit5_test( +nvct_library_test( name = "tests", - size = "large", - srcs = glob(["src/test/java/**/*.java"]), - test_class = "com.nvidia.nvct.NvctServiceIntegrationTest", - javacopts = NVCT_JAVACOPTS, - plugins = LOMBOK_PLUGINS, - resources = glob(["src/test/resources/**"]) + [ - "//:integration_local_env_files", + coverage_library = ":app_classes", + srcs = NVCT_SERVICE_TEST_SRCS, + deps = [ + ":app_classes", + "//nvct-core:nvct_core", + "//nvct-core:nvct_core_test_fixtures", + "@nv_boot_parent//nv-boot-mock-servers-test:nv_boot_mock_servers_test", + "@nv_third_party_deps//:io_opentelemetry_opentelemetry_sdk_testing", + "@nv_third_party_deps//:org_springframework_boot_spring_boot", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_restclient", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_resttestclient", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_webmvc_test", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_web_server", + "@nv_third_party_deps//:org_springframework_spring_beans", + "@nv_third_party_deps//:org_springframework_spring_web", + "@nv_third_party_deps//:org_springframework_spring_webmvc", + "@nv_third_party_deps//:org_testcontainers_testcontainers", + "@nv_third_party_deps//:org_testcontainers_testcontainers_cassandra", ], data = [ "//:integration_local_env", ], + resources = NVCT_SERVICE_TEST_RESOURCES, tags = [ - # Full Spring context + Testcontainers integration test. Runs in the - # dedicated Docker (DinD) integration lane (selected by "requires-docker"); - # the fast matrix excludes it via --test_tag_filters=-requires-docker. "exclusive", "requires-docker", ], timeout = "long", - deps = [ - ":app_classes", - "//nvct-core:nvct_core", - "//nvct-core:nvct_core_test_fixtures", - "@nv_boot_parent//nv-boot-mock-servers-test:nv_boot_mock_servers_test", - "@maven//:io_opentelemetry_opentelemetry_sdk_testing", - "@maven//:org_assertj_assertj_core", - "@maven//:org_junit_jupiter_junit_jupiter_api", - "@maven//:org_junit_jupiter_junit_jupiter_params", - "@maven//:org_mockito_mockito_core", - "@maven//:org_mockito_mockito_junit_jupiter", - "@maven//:org_springframework_boot_spring_boot_test", - "@maven//:org_springframework_boot_spring_boot_test_autoconfigure", - "@maven//:org_springframework_spring_test", - "@maven//:org_springframework_boot_spring_boot", - "@maven//:org_springframework_boot_spring_boot_restclient", - "@maven//:org_springframework_boot_spring_boot_resttestclient", - "@maven//:org_springframework_boot_spring_boot_starter_webmvc_test", - "@maven//:org_springframework_boot_spring_boot_web_server", - "@maven//:org_springframework_spring_beans", - "@maven//:org_springframework_spring_web", - "@maven//:org_springframework_spring_webmvc", - "@maven//:org_testcontainers_testcontainers", - "@maven//:org_testcontainers_testcontainers_cassandra", - ] + LOMBOK_DEPS, - runtime_deps = JUNIT5_RUNTIME_DEPS, ) diff --git a/src/control-plane-services/cloud-tasks/nvct-service/src/main/resources/application-ncp.yaml b/src/control-plane-services/cloud-tasks/nvct-service/src/main/resources/application-ncp.yaml index 36aa4c350..0c31d5bda 100644 --- a/src/control-plane-services/cloud-tasks/nvct-service/src/main/resources/application-ncp.yaml +++ b/src/control-plane-services/cloud-tasks/nvct-service/src/main/resources/application-ncp.yaml @@ -81,8 +81,8 @@ nvct: tracing-key: unused hostname: nvcr.io repository: nv-cf/nvcf-core - # Sidecar container images are configured in configData in nvct-api-colocated-deploy/nvct-api/values.yaml: - # https://gitlab-master.nvidia.com/ncp/nvcf/application-services/nvct-api-colocated-deploy/-/blob/main/nvct-api/values.yaml + # Sidecar container images are configured in configData in the colocated + # deploy values (nvct-api/values.yaml). init-container: dummy utils-container: dummy otel-container: dummy diff --git a/src/control-plane-services/cloud-tasks/tools/bazel/BUILD.bazel b/src/control-plane-services/cloud-tasks/tools/bazel/BUILD.bazel index cd72e556c..1f2e00f6f 100644 --- a/src/control-plane-services/cloud-tasks/tools/bazel/BUILD.bazel +++ b/src/control-plane-services/cloud-tasks/tools/bazel/BUILD.bazel @@ -1,9 +1,11 @@ load("@rules_java//java:defs.bzl", "java_binary", "java_library", "java_plugin") load("@rules_proto_grpc//:defs.bzl", "proto_plugin") +load("@rules_shell//shell:sh_test.bzl", "sh_test") package(default_visibility = ["//visibility:public"]) exports_files([ + "generate_notice.sh", "jacoco_test_runner.sh", "notice_metadata.json", ]) @@ -20,21 +22,33 @@ proto_plugin( }), ) +sh_test( + name = "notice_check_test", + srcs = ["notice_check_test.sh"], + data = [ + ":notice_metadata.json", + "//:NOTICE", + "//:maven_install.json", + "//nvct-service:app", + "@nv_boot_parent//tools/bazel:generate_notice.py", + ], +) + java_plugin( name = "lombok_plugin", generates_api = True, processor_class = "lombok.launch.AnnotationProcessorHider$AnnotationProcessor", - deps = ["@maven//:org_projectlombok_lombok"], + deps = ["@nv_third_party_deps//:org_projectlombok_lombok"], ) java_binary( name = "jacoco_cli", main_class = "org.jacoco.cli.internal.Main", - runtime_deps = ["@maven//:org_jacoco_org_jacoco_cli"], + runtime_deps = ["@nv_third_party_deps//:org_jacoco_org_jacoco_cli"], ) java_library( name = "lombok_annotations", - exports = ["@maven//:org_projectlombok_lombok"], + exports = ["@nv_third_party_deps//:org_projectlombok_lombok"], neverlink = True, ) diff --git a/src/control-plane-services/cloud-tasks/tools/bazel/generate_notice.sh b/src/control-plane-services/cloud-tasks/tools/bazel/generate_notice.sh new file mode 100755 index 000000000..1d27aeadc --- /dev/null +++ b/src/control-plane-services/cloud-tasks/tools/bazel/generate_notice.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash +set -euo pipefail + +workspace="${BUILD_WORKSPACE_DIRECTORY:?Run this command through bazel run}" +runfiles_root="${RUNFILES_DIR:-${0}.runfiles}" + +generator="$(find "${runfiles_root}" -path '*/tools/bazel/generate_notice.py' -print -quit)" +runtime_jar="$(find "${runfiles_root}" -path '*/nvct-service/app.jar' -print -quit)" + +if [[ -z "${generator}" || -z "${runtime_jar}" ]]; then + printf 'Could not locate NOTICE generator or app.jar in runfiles\n' >&2 + exit 1 +fi + +exec python3 "${generator}" \ + --maven-install "${workspace}/maven_install.json" \ + --metadata "${workspace}/tools/bazel/notice_metadata.json" \ + --notice "${workspace}/NOTICE" \ + --runtime-jar "${runtime_jar}" \ + --first-party-group com.nvidia.nvct \ + "$@" diff --git a/src/control-plane-services/cloud-tasks/tools/bazel/java.bzl b/src/control-plane-services/cloud-tasks/tools/bazel/java.bzl new file mode 100644 index 000000000..dc0f99500 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/tools/bazel/java.bzl @@ -0,0 +1,177 @@ +load("@rules_java//java:defs.bzl", _java_binary = "java_binary", _java_library = "java_library") +load("@rules_shell//shell:sh_test.bzl", _sh_test = "sh_test") + +NVCT_JAVACOPTS = [ + "--release", + "25", + "-Xep:CheckReturnValue:OFF", + "-Xep:ImpossibleNullComparison:OFF", + "-Xep:OptionalOfRedundantMethod:OFF", + "-Xlint:deprecation", +] + +NVCT_LOMBOK_COMPILE_DEPS = [ + "//tools/bazel:lombok_annotations", +] + +NVCT_LOMBOK_PLUGINS = [ + "//tools/bazel:lombok_plugin", +] + +NVCT_JUNIT_ARGS = [ + "execute", + "--details=flat", + "--disable-ansi-colors", + "--details-theme=ascii", + "--include-classname=.*(Test|IntegrationTest)", + "--fail-if-no-tests", +] + +NVCT_JUNIT_COMPILE_DEPS = [ + "@nv_third_party_deps//:org_assertj_assertj_core", + "@nv_third_party_deps//:org_junit_jupiter_junit_jupiter_api", + "@nv_third_party_deps//:org_junit_jupiter_junit_jupiter_params", + "@nv_third_party_deps//:org_mockito_mockito_core", + "@nv_third_party_deps//:org_mockito_mockito_junit_jupiter", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_test", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_test_autoconfigure", + "@nv_third_party_deps//:org_springframework_spring_test", +] + +NVCT_JUNIT_RUNTIME_DEPS = [ + "@nv_third_party_deps//:org_junit_platform_junit_platform_console_standalone", +] + +NVCT_MOCKITO_CORE = "@nv_third_party_deps//:org_mockito_mockito_core" + +NVCT_JACOCO_AGENT = "@nv_third_party_deps//:org_jacoco_org_jacoco_agent_runtime" + +NVCT_JACOCO_JVM_FLAGS = [ + ( + "-javaagent:$(location %s)=destfile=jacoco.exec,append=false," + + "dumponexit=true,includes=com.nvidia.*" + ) % NVCT_JACOCO_AGENT, +] + +def _unique(values): + seen = {} + result = [] + for value in values: + if value not in seen: + seen[value] = True + result.append(value) + return result + +def _nvct_workspace_runfiles_impl(ctx): + symlinks = {} + strip_prefix = ctx.attr.strip_prefix + + for src in ctx.files.srcs: + runfiles_path = src.short_path + if strip_prefix: + if not runfiles_path.startswith(strip_prefix): + fail("Expected %s to start with strip_prefix %s" % (runfiles_path, strip_prefix)) + runfiles_path = runfiles_path[len(strip_prefix):] + + if runfiles_path in symlinks: + fail("Duplicate runfiles path: %s" % runfiles_path) + symlinks[runfiles_path] = src + + return [DefaultInfo(runfiles = ctx.runfiles(symlinks = symlinks))] + +nvct_workspace_runfiles = rule( + implementation = _nvct_workspace_runfiles_impl, + attrs = { + "srcs": attr.label_list(allow_files = True), + "strip_prefix": attr.string(), + }, +) + +def nvct_library( + name, + srcs, + deps = [], + resources = [], + runtime_deps = [], + visibility = None, + resource_strip_prefix = ""): + _java_library( + name = name, + srcs = srcs, + deps = deps + NVCT_LOMBOK_COMPILE_DEPS, + javacopts = NVCT_JAVACOPTS, + plugins = NVCT_LOMBOK_PLUGINS, + resources = resources, + resource_strip_prefix = resource_strip_prefix, + runtime_deps = runtime_deps, + visibility = visibility, + ) + +def nvct_library_test( + name, + deps, + coverage_library, + data = [], + jvm_flags = [], + resources = [], + runtime_deps = [], + size = "large", + srcs = [], + tags = [], + timeout = "long", + visibility = None): + if type(coverage_library) != "string" or not coverage_library.startswith(":"): + fail( + "coverage_library must be the module library target as a local " + + "label starting with ':'", + ) + + coverage_sourcefiles = native.glob(["src/main/java/**/*.java"]) + coverage_source_root = native.package_name() + "/src/main/java" + junit_runner = name + "_junit_runner" + + _java_binary( + name = junit_runner, + srcs = srcs, + data = _unique(data + [ + NVCT_JACOCO_AGENT, + NVCT_MOCKITO_CORE, + ]), + deps = _unique(deps + NVCT_LOMBOK_COMPILE_DEPS + NVCT_JUNIT_COMPILE_DEPS), + javacopts = NVCT_JAVACOPTS, + jvm_flags = NVCT_JACOCO_JVM_FLAGS + [ + "-javaagent:$(location %s)" % NVCT_MOCKITO_CORE, + ] + jvm_flags, + main_class = "org.junit.platform.console.ConsoleLauncher", + plugins = NVCT_LOMBOK_PLUGINS, + resources = resources, + runtime_deps = runtime_deps + NVCT_JUNIT_RUNTIME_DEPS, + tags = ["manual"], + testonly = True, + visibility = ["//visibility:private"], + ) + + _sh_test( + name = name, + srcs = ["//tools/bazel:jacoco_test_runner.sh"], + args = [ + "$(location :%s)" % junit_runner, + "$(location %s)" % coverage_library, + coverage_source_root if coverage_sourcefiles else "", + native.package_name(), + "$(location //tools/bazel:jacoco_cli)", + ] + NVCT_JUNIT_ARGS + [ + "--class-path=$(location :%s.jar)" % junit_runner, + "--scan-classpath=$(location :%s.jar)" % junit_runner, + ], + data = _unique([ + ":" + junit_runner, + ":%s.jar" % junit_runner, + coverage_library, + "//tools/bazel:jacoco_cli", + ] + coverage_sourcefiles), + size = size, + tags = tags, + timeout = timeout, + visibility = visibility, + ) diff --git a/src/control-plane-services/cloud-tasks/tools/bazel/notice_check_test.sh b/src/control-plane-services/cloud-tasks/tools/bazel/notice_check_test.sh new file mode 100755 index 000000000..49256c3ef --- /dev/null +++ b/src/control-plane-services/cloud-tasks/tools/bazel/notice_check_test.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash +set -euo pipefail + +runfiles_root="${TEST_SRCDIR:?TEST_SRCDIR is not set}" +workspace="${runfiles_root}/_main" + +generator="$(find "${runfiles_root}" -path '*/tools/bazel/generate_notice.py' -print -quit)" +runtime_jar="$(find "${runfiles_root}" -path '*/nvct-service/app.jar' -print -quit)" + +if [[ -z "${generator}" || -z "${runtime_jar}" ]]; then + printf 'Could not locate NOTICE generator or app.jar in test runfiles\n' >&2 + exit 1 +fi + +exec python3 "${generator}" \ + --maven-install "${workspace}/maven_install.json" \ + --metadata "${workspace}/tools/bazel/notice_metadata.json" \ + --notice "${workspace}/NOTICE" \ + --runtime-jar "${runtime_jar}" \ + --first-party-group com.nvidia.nvct \ + --check diff --git a/src/control-plane-services/cloud-tasks/tools/bazel/runfiles.bzl b/src/control-plane-services/cloud-tasks/tools/bazel/runfiles.bzl deleted file mode 100644 index 71499bc16..000000000 --- a/src/control-plane-services/cloud-tasks/tools/bazel/runfiles.bzl +++ /dev/null @@ -1,26 +0,0 @@ -"""Workspace-relative runfiles helper for cloud-tasks integration tests.""" - -def _nvct_workspace_runfiles_impl(ctx): - symlinks = {} - strip_prefix = ctx.attr.strip_prefix - - for src in ctx.files.srcs: - runfiles_path = src.short_path - if strip_prefix: - if not runfiles_path.startswith(strip_prefix): - fail("Expected %s to start with strip_prefix %s" % (runfiles_path, strip_prefix)) - runfiles_path = runfiles_path[len(strip_prefix):] - - if runfiles_path in symlinks: - fail("Duplicate runfiles path: %s" % runfiles_path) - symlinks[runfiles_path] = src - - return [DefaultInfo(runfiles = ctx.runfiles(symlinks = symlinks))] - -nvct_workspace_runfiles = rule( - implementation = _nvct_workspace_runfiles_impl, - attrs = { - "srcs": attr.label_list(allow_files = True), - "strip_prefix": attr.string(), - }, -) diff --git a/src/control-plane-services/cloud-tasks/tools/bazel/spring_boot.bzl b/src/control-plane-services/cloud-tasks/tools/bazel/spring_boot.bzl new file mode 100644 index 000000000..b3e7538e3 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/tools/bazel/spring_boot.bzl @@ -0,0 +1,178 @@ +load("@rules_spring//springboot:springboot.bzl", "springboot") + +def _spring_boot_metadata_impl(ctx): + app_jar = ctx.file.app_jar + output = ctx.actions.declare_file("%s.jar" % ctx.attr.name) + git_properties = ctx.actions.declare_file( + "%s_metadata/BOOT-INF/classes/git.properties" % ctx.attr.name, + ) + maven_properties = ctx.actions.declare_file( + "%s_metadata/BOOT-INF/classes/maven.properties" % ctx.attr.name, + ) + pom_properties = ctx.actions.declare_file( + "%s_metadata/META-INF/maven/%s/%s/pom.properties" % ( + ctx.attr.name, + ctx.attr.group_id, + ctx.attr.artifact_id, + ), + ) + + args = ctx.actions.args() + args.add(ctx.info_file) + args.add(git_properties) + args.add(maven_properties) + args.add(pom_properties) + args.add(ctx.attr.group_id) + args.add(ctx.attr.artifact_id) + args.add(ctx.attr.artifact_version) + args.add(ctx.attr.java_version) + + ctx.actions.run_shell( + inputs = [ctx.info_file], + outputs = [git_properties, maven_properties, pom_properties], + arguments = [args], + mnemonic = "SpringBootMetadataFiles", + progress_message = "Generating Spring Boot app metadata for %s" % output.short_path, + command = """ +set -eu + +status_file="$1" +git_properties="$2" +maven_properties="$3" +pom_properties="$4" +group_id="$5" +artifact_id="$6" +artifact_version="$7" +java_version="$8" + +status_value() { + key="$1" + awk -v key="${key}" '$1 == key { sub("^[^ ]+ ?", ""); print; found=1 } END { if (!found) exit 0 }' "${status_file}" +} + +git_full="$(status_value STABLE_GIT_COMMIT_ID_FULL)" +git_abbrev="$(status_value STABLE_GIT_COMMIT_ID_ABBREV)" +git_tags="$(status_value STABLE_GIT_TAGS)" +git_closest_tag="$(status_value STABLE_GIT_CLOSEST_TAG_NAME)" +build_version="$(status_value STABLE_BUILD_VERSION)" +if [ -n "${build_version}" ]; then + artifact_version="${build_version}" +fi + +mkdir -p \ + "$(dirname "${git_properties}")" \ + "$(dirname "${maven_properties}")" \ + "$(dirname "${pom_properties}")" + +cat > "${git_properties}" <<EOF +#Generated by Bazel workspace status +git.closest.tag.name=${git_closest_tag} +git.commit.id.abbrev=${git_abbrev} +git.commit.id.full=${git_full} +git.tags=${git_tags} +EOF + +cat > "${maven_properties}" <<EOF +#Properties +artifactId=${artifact_id} +groupId=${group_id} +java.version=${java_version} +version=${artifact_version} +EOF + +cat > "${pom_properties}" <<EOF +artifactId=${artifact_id} +groupId=${group_id} +version=${artifact_version} +EOF +""", + ) + + singlejar_args = ctx.actions.args() + singlejar_args.add("--output", output) + singlejar_args.add("--dont_change_compression") + singlejar_args.add("--sources", app_jar) + singlejar_args.add_all("--deploy_manifest_lines", [ + "Main-Class: org.springframework.boot.loader.launch.JarLauncher", + "Start-Class: %s" % ctx.attr.main_class, + ]) + singlejar_args.add_all("--resources", [ + "%s:BOOT-INF/classes/git.properties" % git_properties.path, + "%s:BOOT-INF/classes/maven.properties" % maven_properties.path, + "%s:META-INF/maven/%s/%s/pom.properties" % ( + pom_properties.path, + ctx.attr.group_id, + ctx.attr.artifact_id, + ), + ]) + + ctx.actions.run( + inputs = [app_jar, git_properties, maven_properties, pom_properties], + outputs = [output], + arguments = [singlejar_args], + executable = ctx.executable._singlejar, + mnemonic = "SpringBootAppMetadata", + progress_message = "Adding Spring Boot app metadata %s" % output.short_path, + ) + + return [DefaultInfo(files = depset([output]))] + +_spring_boot_metadata = rule( + implementation = _spring_boot_metadata_impl, + attrs = { + "app_jar": attr.label( + allow_single_file = [".jar"], + mandatory = True, + ), + "group_id": attr.string(mandatory = True), + "artifact_id": attr.string(mandatory = True), + "artifact_version": attr.string(mandatory = True), + "artifact_name": attr.string(mandatory = True), + "description": attr.string(mandatory = True), + "java_version": attr.string(default = "25"), + "main_class": attr.string(mandatory = True), + "_singlejar": attr.label( + allow_single_file = True, + cfg = "exec", + default = Label("@rules_java//toolchains:singlejar"), + executable = True, + ), + }, +) + +def spring_boot_app( + name, + application, + main_class, + group_id, + artifact_id, + artifact_version, + artifact_name, + description, + java_version = "25", + visibility = None): + springboot_name = name + "_springboot" + springboot_genjar = "%s_%s_genjar" % (native.package_name(), springboot_name) + + springboot( + name = springboot_name, + boot_app_class = main_class, + boot_launcher_class = "org.springframework.boot.loader.launch.JarLauncher", + include_git_properties_file = False, + java_library = application, + tags = ["manual"], + visibility = ["//visibility:private"], + ) + + _spring_boot_metadata( + name = name, + app_jar = ":" + springboot_genjar, + artifact_id = artifact_id, + artifact_name = artifact_name, + artifact_version = artifact_version, + description = description, + group_id = group_id, + java_version = java_version, + main_class = main_class, + visibility = visibility, + ) diff --git a/src/libraries/java/nv-boot-parent/.bazelrc b/src/libraries/java/nv-boot-parent/.bazelrc index 38ab37cda..d63d1b9a9 100644 --- a/src/libraries/java/nv-boot-parent/.bazelrc +++ b/src/libraries/java/nv-boot-parent/.bazelrc @@ -1,47 +1,9 @@ -# SPDX-FileCopyrightText: Copyright (c) NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# 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. - -# Standalone module .bazelrc. `cd rules/java && bazel build //...` must work with -# no reference to the repo root. The caller supplies any remote cache endpoint; -# no cache config is baked in (parity with the other nested modules). - -common --enable_bzlmod -common --enable_platform_specific_config -build --incompatible_strict_action_env - -# Route public Maven Central through an internal Artifactory mirror on internal -# builds only. The target host lives in an un-mirrored internal bazelrc, so -# public builds go straight to Maven Central (try-import is a no-op when absent). -try-import %workspace%/tools/bazel/internal.bazelrc - -# Java: use the image-provided local JDK 25 (Temurin at JAVA_HOME) instead of a -# hermetic remotejdk download; the bazel-ci image ships Temurin 25 (no download). +build --enable_bzlmod build --java_language_version=25 -build --java_runtime_version=local_jdk build --tool_java_language_version=25 +build --java_runtime_version=local_jdk build --tool_java_runtime_version=local_jdk build --java_header_compilation=false +build --javacopt=-Xlint:deprecation test --test_output=errors -test --test_env=HOME=/tmp -test --test_env=XDG_CACHE_HOME=/tmp/.cache - -startup --host_jvm_args=-Xmx4g - -build:release --compilation_mode=opt -build:release --strip=always - -try-import %workspace%/user.bazelrc -try-import %user.home%/.bazelrc.user diff --git a/src/libraries/java/nv-boot-parent/.bazelversion b/src/libraries/java/nv-boot-parent/.bazelversion new file mode 100644 index 000000000..44931da26 --- /dev/null +++ b/src/libraries/java/nv-boot-parent/.bazelversion @@ -0,0 +1 @@ +9.1.1 diff --git a/src/libraries/java/nv-boot-parent/AGENTS.md b/src/libraries/java/nv-boot-parent/AGENTS.md index 9188494c9..2d6e77416 100644 --- a/src/libraries/java/nv-boot-parent/AGENTS.md +++ b/src/libraries/java/nv-boot-parent/AGENTS.md @@ -3,34 +3,38 @@ The NVCF Spring Boot platform library, as a standalone Bazel module (`module(name = "nv_boot_parent")`). Owns the shared Spring BOM set and the `nv-boot-*` starter `java_library` targets that every NVCF Java service depends -on. +on. Maven and Bazel coexist here; Maven stays authoritative for Maven consumers. ## Build and test (from this directory) ``` cd src/libraries/java/nv-boot-parent -bazel build //... -bazel test //... +export BAZEL_OUTPUT_USER_ROOT="${TMPDIR:-/tmp}/nv-boot-parent-bazel-cache" +bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" build //... +bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" test //... ``` The module builds on its own with no reference to the repo root. Docker integration tests are tagged `requires-docker` and run in the dedicated integration lane, not the default `bazel test //...`. -## Maven dependencies +## Dependency hub -This module has its own `@maven` hub and its own committed `maven_install.json`. -After editing `maven.install` in `MODULE.bazel`, re-pin and commit the lockfile: +Third-party dependencies resolve through one shared hub named +`nv_third_party_deps` (never `@maven`). Downstream services contribute to the +same hub and list this module in `known_contributing_modules`, so the final +application resolves a single third-party graph. Public BUILD labels look like +`@nv_third_party_deps//:org_springframework_boot_spring_boot`. + +`MODULE.bazel` is the edited source of truth for BOM-managed roots and explicit +pins. After editing `maven.install`, re-pin and commit the lockfile: ``` -REPIN=1 bazel run @maven//:pin +REPIN=1 bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" run @nv_third_party_deps//:pin ``` -The `boms` list in `MODULE.bazel` must stay identical to `SPRING_BOOT_BOM` in -`@nvcf_java_rules//:platform.bzl`. `//:bom_alignment_test` fails the build if it -drifts. Bumping a shared version (Spring, Spring Cloud, Testcontainers, -ShedLock) is a one-line edit in that `platform.bzl`, the matching edit here, then -a re-pin. +Both `maven_install.json` and `MODULE.bazel.lock` are committed and never +hand-edited. ## Layout @@ -40,8 +44,12 @@ a re-pin. generator (`generate_notice.py`). - `NOTICE` - generated from this module's own `maven_install.json`. +Lombok needs `build --java_header_compilation=false`; that flag lives in this +module's `.bazelrc` and must also be set in every downstream consuming root, +because `.bazelrc` is not transitive through Bzlmod. + ## Consuming this module -In-tree, a service module uses `bazel_dep` + `local_path_override`. Out-of-tree, -`git_override` with `strip_prefix = "src/libraries/java/nv-boot-parent"`, which -works because `MODULE.bazel` is rooted here. +In-tree, a service module uses `bazel_dep(name = "nv_boot_parent", version = +"0.0.0")` plus `local_path_override`. See +`src/control-plane-services/cloud-tasks/MODULE.bazel` for the reference wiring. diff --git a/src/libraries/java/nv-boot-parent/BUILD.bazel b/src/libraries/java/nv-boot-parent/BUILD.bazel index 7b8da684b..bc2af9c2a 100644 --- a/src/libraries/java/nv-boot-parent/BUILD.bazel +++ b/src/libraries/java/nv-boot-parent/BUILD.bazel @@ -1,20 +1,15 @@ -load("@nvcf_java_rules//:bom_alignment.bzl", "bom_alignment_test") - package(default_visibility = ["//visibility:public"]) -exports_files(["NOTICE", "MODULE.bazel"]) - -# Fails the build if this module's inlined maven.install boms drift from the -# canonical SPRING_BOOT_BOM in @nvcf_java_rules//:platform.bzl. load() cannot be -# used in MODULE.bazel, so the boms list is inlined and guarded here instead. -bom_alignment_test( - name = "bom_alignment_test", -) +exports_files([ + "maven_install.json", + "MODULE.bazel", + "NOTICE", +]) genrule( name = "third_party_notice", srcs = [ - "//:maven_install.json", + ":maven_install.json", "//tools/bazel:notice_metadata.json", "//tools/bazel:notice_roots.json", ], @@ -23,7 +18,7 @@ genrule( cmd = """ set -eu "$(execpath //tools/bazel:generate_notice_tool)" \ - --maven-install "$(location //:maven_install.json)" \ + --maven-install "$(location :maven_install.json)" \ --metadata "$(location //tools/bazel:notice_metadata.json)" \ --root-manifest "$(location //tools/bazel:notice_roots.json)" \ --output "$@" \ @@ -34,7 +29,7 @@ set -eu genrule( name = "generate_notice", srcs = [ - "//:maven_install.json", + ":maven_install.json", "//tools/bazel:notice_metadata.json", "//tools/bazel:notice_roots.json", ], @@ -47,7 +42,7 @@ set -euo pipefail workspace="$${BUILD_WORKSPACE_DIRECTORY:-$$(pwd)}" exec "$(execpath //tools/bazel:generate_notice_tool)" \ - --maven-install "$(location //:maven_install.json)" \ + --maven-install "$(location :maven_install.json)" \ --metadata "$${workspace}/tools/bazel/notice_metadata.json" \ --notice "$${workspace}/NOTICE" \ --root-manifest "$(location //tools/bazel:notice_roots.json)" \ diff --git a/src/libraries/java/nv-boot-parent/MODULE.bazel b/src/libraries/java/nv-boot-parent/MODULE.bazel index 34493bc45..3bbbf6245 100644 --- a/src/libraries/java/nv-boot-parent/MODULE.bazel +++ b/src/libraries/java/nv-boot-parent/MODULE.bazel @@ -1,61 +1,38 @@ -# SPDX-FileCopyrightText: Copyright (c) NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# -# 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. +module(name = "nv_boot_parent") -"""nv_boot_parent: the NVCF Spring Boot platform library, as a standalone module. - -Owns the shared Spring BOM set and the nv-boot-* starter java_library targets. -Every Java service module depends on this module (bazel_dep + local_path_override -in-tree, git_override with strip_prefix out-of-tree) plus nvcf_java_rules, and -builds on its own: `cd src/libraries/java/nv-boot-parent && bazel build //...`. - -Maven: this module resolves its own graph into its own @maven hub and commits -its own maven_install.json. The boms list below is inlined (load() is forbidden -in MODULE.bazel) and must stay identical to SPRING_BOOT_BOM in -@nvcf_java_rules//:platform.bzl; //:bom_alignment_test enforces that. -""" - -module( - name = "nv_boot_parent", - version = "4.0.7", -) - -bazel_dep(name = "nvcf_java_rules", version = "0.1.0") -local_path_override( - module_name = "nvcf_java_rules", - path = "../../../../rules/java", -) - -bazel_dep(name = "rules_java", version = "9.3.0") bazel_dep(name = "rules_jvm_external", version = "7.0") -bazel_dep(name = "rules_python", version = "1.4.1") +bazel_dep(name = "rules_java", version = "9.3.0") +bazel_dep(name = "rules_python", version = "1.7.0") bazel_dep(name = "rules_shell", version = "0.8.0") -python = use_extension("@rules_python//python/extensions:python.bzl", "python") -python.toolchain( - ignore_root_user_error = True, - python_version = "3.11", -) - maven = use_extension("@rules_jvm_external//:extensions.bzl", "maven") maven.install( - name = "maven", + name = "nv_third_party_deps", + # Keep this list to root coordinates: BOM-managed starters/modules, parent-owned + # explicit pins, and build/test tools. This file is the source of truth for + # Bazel/Coursier dependency resolution and explicit version pins. Generated + # publication metadata reads versions from here rather than owning a separate + # version map. + # BUILD files may still reference transitive labels when source code imports + # those classes. artifacts = [ - # nv-boot-parent third-party closure (Spring Boot 4 / Spring Cloud / - # OTel / Cassandra / Testcontainers). Root coordinates only: BOM-managed - # starters/modules, parent-owned explicit pins, and build/test tools. - # Version-less coordinates are managed by the boms below. + # Security override example: + # Maven property overrides from spring-boot-dependencies, such as + # tomcat.version, become explicit artifact pins in Bazel. If a Tomcat + # CVE fix is available before Spring Boot imports it, temporarily add + # the concrete Tomcat artifacts with the fixed version: + # + # "org.apache.tomcat.embed:tomcat-embed-core:<fixed-version>", + # "org.apache.tomcat.embed:tomcat-embed-el:<fixed-version>", + # "org.apache.tomcat.embed:tomcat-embed-websocket:<fixed-version>", + # + # Then repin and test: + # export BAZEL_OUTPUT_USER_ROOT="${TMPDIR:-/tmp}/nv-boot-parent-bazel-cache" + # REPIN=1 bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" run @nv_third_party_deps//:pin + # bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" test //... + # + # Remove the explicit pins once the imported Spring Boot BOM manages + # the fixed version. "at.yawk.lz4:lz4-java:1.10.3", "com.github.ben-manes.caffeine:guava", "com.github.java-json-tools:json-patch:1.13", @@ -73,6 +50,10 @@ maven.install( "org.jacoco:org.jacoco.agent:jar:runtime:0.8.14", "org.jacoco:org.jacoco.cli:0.8.14", "org.junit.platform:junit-platform-console-standalone:6.0.3", + # JaCoCo resolves asm, asm-commons, and asm-tree to 9.9 in the shared + # hub, while jnr-ffi otherwise leaves these two modules at 5.0.3. + # Keep the ASM family aligned so production and test tooling do not + # share a partially upgraded runtime graph. "org.ow2.asm:asm-analysis:9.9", "org.ow2.asm:asm-util:9.9", "org.projectlombok:lombok", @@ -104,40 +85,21 @@ maven.install( "org.wiremock:wiremock-standalone:3.13.2", "software.amazon.awssdk:regions:2.40.1", "tools.jackson.module:jackson-module-blackbird", - # Test tooling the nv-boot starters compile and run against directly - # (JUnit 5 console launcher, AssertJ, Awaitility, Mockito). Versions are - # managed by the Spring Boot BOM. - "org.assertj:assertj-core", - "org.awaitility:awaitility", - "org.junit.jupiter:junit-jupiter-api", - "org.junit.jupiter:junit-jupiter-engine", - "org.junit.jupiter:junit-jupiter-params", - "org.junit.platform:junit-platform-launcher", - "org.junit.platform:junit-platform-reporting", - "org.mockito:mockito-core", - "org.mockito:mockito-junit-jupiter", ], boms = [ - # Keep identical to SPRING_BOOT_BOM in @nvcf_java_rules//:platform.bzl. - # //:bom_alignment_test fails the build if these drift. + "net.javacrumbs.shedlock:shedlock-bom:7.7.0", "org.springframework.boot:spring-boot-dependencies:4.0.7", "org.springframework.cloud:spring-cloud-dependencies:2025.1.2", "org.testcontainers:testcontainers-bom:2.0.5", - "net.javacrumbs.shedlock:shedlock-bom:7.7.0", ], fail_on_missing_checksum = True, fetch_sources = True, - # contrib_rules_jvm (via nvcf_java_rules) contributes protobuf-java into this - # hub; acknowledged so resolution is shared cleanly rather than warned. known_contributing_modules = ["protobuf"], lock_file = "//:maven_install.json", repositories = [ - # Public Central mirrors only; keep aligned with MAVEN_REPOSITORIES in - # @nvcf_java_rules//:platform.bzl. Internal builds add the Artifactory - # virtual repo in their own overlay. "https://maven-central.storage-download.googleapis.com/maven2", "https://repo.maven.apache.org/maven2", ], resolver = "maven", ) -use_repo(maven, "maven") +use_repo(maven, "nv_third_party_deps") diff --git a/src/libraries/java/nv-boot-parent/MODULE.bazel.lock b/src/libraries/java/nv-boot-parent/MODULE.bazel.lock index 1d8059294..480155120 100644 --- a/src/libraries/java/nv-boot-parent/MODULE.bazel.lock +++ b/src/libraries/java/nv-boot-parent/MODULE.bazel.lock @@ -1,5 +1,5 @@ { - "lockFileVersion": 28, + "lockFileVersion": 26, "registryFileHashes": { "https://bcr.bazel.build/bazel_registry.json": "8a28e4aff06ee60aed2a8c281907fb8bcbf3b753c91fb5a5c57da3215d5b3497", "https://bcr.bazel.build/modules/abseil-cpp/20210324.2/MODULE.bazel": "7cd0312e064fde87c8d1cd79ba06c876bd23630c83466e9500321be55c96ace2", @@ -17,19 +17,12 @@ "https://bcr.bazel.build/modules/abseil-cpp/20250814.1/source.json": "cea3901d7e299da7320700abbaafe57a65d039f10d0d7ea601c4a66938ea4b0c", "https://bcr.bazel.build/modules/abseil-py/2.1.0/MODULE.bazel": "5ebe5bf853769c65707e5c28f216798f7a4b1042015e6a36e6d03094d94bec8a", "https://bcr.bazel.build/modules/abseil-py/2.1.0/source.json": "0e8fc4f088ce07099c1cd6594c20c7ddbb48b4b3c0849b7d94ba94be88ff042b", - "https://bcr.bazel.build/modules/apple_rules_lint/0.4.0/MODULE.bazel": "c59831c3a5389430516203777816527f257329a5da363994e1d62b9ae6729f71", - "https://bcr.bazel.build/modules/apple_rules_lint/0.4.0/source.json": "105883202602181f43f109372e1b9ea19e89bbe3bce4bc1fe9bb0baa51eb61ae", "https://bcr.bazel.build/modules/apple_support/1.11.1/MODULE.bazel": "1843d7cd8a58369a444fc6000e7304425fba600ff641592161d9f15b179fb896", "https://bcr.bazel.build/modules/apple_support/1.15.1/MODULE.bazel": "a0556fefca0b1bb2de8567b8827518f94db6a6e7e7d632b4c48dc5f865bc7c85", "https://bcr.bazel.build/modules/apple_support/1.21.0/MODULE.bazel": "ac1824ed5edf17dee2fdd4927ada30c9f8c3b520be1b5fd02a5da15bc10bff3e", "https://bcr.bazel.build/modules/apple_support/1.21.1/MODULE.bazel": "5809fa3efab15d1f3c3c635af6974044bac8a4919c62238cce06acee8a8c11f1", "https://bcr.bazel.build/modules/apple_support/1.24.2/MODULE.bazel": "0e62471818affb9f0b26f128831d5c40b074d32e6dda5a0d3852847215a41ca4", "https://bcr.bazel.build/modules/apple_support/1.24.2/source.json": "2c22c9827093250406c5568da6c54e6fdf0ef06238def3d99c71b12feb057a8d", - "https://bcr.bazel.build/modules/aspect_bazel_lib/2.14.0/MODULE.bazel": "2b31ffcc9bdc8295b2167e07a757dbbc9ac8906e7028e5170a3708cecaac119f", - "https://bcr.bazel.build/modules/aspect_bazel_lib/2.19.3/MODULE.bazel": "253d739ba126f62a5767d832765b12b59e9f8d2bc88cc1572f4a73e46eb298ca", - "https://bcr.bazel.build/modules/aspect_bazel_lib/2.19.3/source.json": "ffab9254c65ba945f8369297ad97ca0dec213d3adc6e07877e23a48624a8b456", - "https://bcr.bazel.build/modules/aspect_bazel_lib/2.7.2/MODULE.bazel": "780d1a6522b28f5edb7ea09630748720721dfe27690d65a2d33aa7509de77e07", - "https://bcr.bazel.build/modules/aspect_bazel_lib/2.8.1/MODULE.bazel": "812d2dd42f65dca362152101fbec418029cc8fd34cbad1a2fde905383d705838", "https://bcr.bazel.build/modules/bazel_features/1.1.0/MODULE.bazel": "cfd42ff3b815a5f39554d97182657f8c4b9719568eb7fded2b9135f084bf760b", "https://bcr.bazel.build/modules/bazel_features/1.1.1/MODULE.bazel": "27b8c79ef57efe08efccbd9dd6ef70d61b4798320b8d3c134fd571f78963dbcd", "https://bcr.bazel.build/modules/bazel_features/1.10.0/MODULE.bazel": "f75e8807570484a99be90abcd52b5e1f390362c258bcb73106f4544957a48101", @@ -77,14 +70,11 @@ "https://bcr.bazel.build/modules/bazel_worker_java/0.0.8/source.json": "9395c4679444bc47bf7e51a710366a4480aa371c6f6bed01868e2fabcf11acec", "https://bcr.bazel.build/modules/buildozer/8.5.1/MODULE.bazel": "a35d9561b3fc5b18797c330793e99e3b834a473d5fbd3d7d7634aafc9bdb6f8f", "https://bcr.bazel.build/modules/buildozer/8.5.1/source.json": "e3386e6ff4529f2442800dee47ad28d3e6487f36a1f75ae39ae56c70f0cd2fbd", - "https://bcr.bazel.build/modules/contrib_rules_jvm/0.33.0/MODULE.bazel": "1aba514585748372ee392484b2645f0bbcb13ad4271d5b7cace018280f15bae1", - "https://bcr.bazel.build/modules/contrib_rules_jvm/0.33.0/source.json": "e52d62ce2a2b8a513d6afe9178acc06a4349c9b0b4c0934d59085ed9df4b4de0", "https://bcr.bazel.build/modules/gazelle/0.32.0/MODULE.bazel": "b499f58a5d0d3537f3cf5b76d8ada18242f64ec474d8391247438bf04f58c7b8", "https://bcr.bazel.build/modules/gazelle/0.33.0/MODULE.bazel": "a13a0f279b462b784fb8dd52a4074526c4a2afe70e114c7d09066097a46b3350", "https://bcr.bazel.build/modules/gazelle/0.34.0/MODULE.bazel": "abdd8ce4d70978933209db92e436deb3a8b737859e9354fb5fd11fb5c2004c8a", "https://bcr.bazel.build/modules/gazelle/0.36.0/MODULE.bazel": "e375d5d6e9a6ca59b0cb38b0540bc9a05b6aa926d322f2de268ad267a2ee74c0", "https://bcr.bazel.build/modules/gazelle/0.40.0/MODULE.bazel": "42ba5378ebe845fca43989a53186ab436d956db498acde790685fe0e8f9c6146", - "https://bcr.bazel.build/modules/gazelle/0.42.0/MODULE.bazel": "fa140a7c019f3a22779ba7c6132ffff9d2d10a51dba2f3304dee61523d11fef4", "https://bcr.bazel.build/modules/gazelle/0.47.0/MODULE.bazel": "b61bb007c4efad134aa30ee7f4a8e2a39b22aa5685f005edaa022fbd1de43ebc", "https://bcr.bazel.build/modules/gazelle/0.47.0/source.json": "aeb2e5df14b7fb298625d75d08b9c65bdb0b56014c5eb89da9e5dd0572280ae6", "https://bcr.bazel.build/modules/google_benchmark/1.8.2/MODULE.bazel": "a70cf1bba851000ba93b58ae2f6d76490a9feb74192e57ab8e8ff13c34ec50cb", @@ -94,8 +84,6 @@ "https://bcr.bazel.build/modules/googletest/1.15.2/MODULE.bazel": "6de1edc1d26cafb0ea1a6ab3f4d4192d91a312fd2d360b63adaa213cd00b2108", "https://bcr.bazel.build/modules/googletest/1.17.0/MODULE.bazel": "dbec758171594a705933a29fcf69293d2468c49ec1f2ebca65c36f504d72df46", "https://bcr.bazel.build/modules/googletest/1.17.0/source.json": "38e4454b25fc30f15439c0378e57909ab1fd0a443158aa35aec685da727cd713", - "https://bcr.bazel.build/modules/jq.bzl/0.1.0/MODULE.bazel": "2ce69b1af49952cd4121a9c3055faa679e748ce774c7f1fda9657f936cae902f", - "https://bcr.bazel.build/modules/jq.bzl/0.1.0/source.json": "746bf13cac0860f091df5e4911d0c593971cd8796b5ad4e809b2f8e133eee3d5", "https://bcr.bazel.build/modules/jsoncpp/1.9.5/MODULE.bazel": "31271aedc59e815656f5736f282bb7509a97c7ecb43e927ac1a37966e0578075", "https://bcr.bazel.build/modules/jsoncpp/1.9.6/MODULE.bazel": "2f8d20d3b7d54143213c4dfc3d98225c42de7d666011528dc8fe91591e2e17b0", "https://bcr.bazel.build/modules/jsoncpp/1.9.6/source.json": "a04756d367a2126c3541682864ecec52f92cdee80a35735a3cb249ce015ca000", @@ -145,7 +133,6 @@ "https://bcr.bazel.build/modules/re2/2024-07-02/MODULE.bazel": "0eadc4395959969297cbcf31a249ff457f2f1d456228c67719480205aa306daa", "https://bcr.bazel.build/modules/rules_android/0.1.1/MODULE.bazel": "48809ab0091b07ad0182defb787c4c5328bd3a278938415c00a7b69b50c4d3a8", "https://bcr.bazel.build/modules/rules_android/0.6.4/MODULE.bazel": "b4cde12d506dd65d82b2be39761f49f5797303343a3d5b4ee191c0cdf9ef387c", - "https://bcr.bazel.build/modules/rules_android/0.6.6/MODULE.bazel": "b0fb569752aab65ab1a9db0a8f6cfaf5aa1754965e17e95dcf0e4d88e192a68d", "https://bcr.bazel.build/modules/rules_android/0.7.1/MODULE.bazel": "a806fc382a774252f228a40e3b11b9fcc6276f8778c7fb33e9f72937c6258363", "https://bcr.bazel.build/modules/rules_android/0.7.1/source.json": "151440aed3f0f73a00d4ed5cec5d31f63a6fef9b95d8fab1eb1810150fa525f2", "https://bcr.bazel.build/modules/rules_apple/3.16.0/MODULE.bazel": "0d1caf0b8375942ce98ea944be754a18874041e4e0459401d925577624d3a54a", @@ -177,7 +164,6 @@ "https://bcr.bazel.build/modules/rules_go/0.46.0/MODULE.bazel": "3477df8bdcc49e698b9d25f734c4f3a9f5931ff34ee48a2c662be168f5f2d3fd", "https://bcr.bazel.build/modules/rules_go/0.50.1/MODULE.bazel": "b91a308dc5782bb0a8021ad4330c81fea5bda77f96b9e4c117b9b9c8f6665ee0", "https://bcr.bazel.build/modules/rules_go/0.51.0-rc2/MODULE.bazel": "edfc3a9cea7bedb0eaaff37b0d7817c1a4bf72b3c615580b0ffcee6c52690fd4", - "https://bcr.bazel.build/modules/rules_go/0.52.0/MODULE.bazel": "0cf080a2706aa8fc9abf64286cee60fdf0238db37b7f1793b0f7d550d59ea3ae", "https://bcr.bazel.build/modules/rules_go/0.53.0/MODULE.bazel": "a4ed760d3ac0dbc0d7b967631a9a3fd9100d28f7d9fcf214b4df87d4bfff5f9a", "https://bcr.bazel.build/modules/rules_go/0.59.0/MODULE.bazel": "b7e43e7414a3139a7547d1b4909b29085fbe5182b6c58cbe1ed4c6272815aeae", "https://bcr.bazel.build/modules/rules_go/0.59.0/source.json": "1df17bb7865cfc029492c30163cee891d0dd8658ea0d5bfdf252c4b6db5c1ef6", @@ -191,8 +177,6 @@ "https://bcr.bazel.build/modules/rules_java/7.2.0/MODULE.bazel": "06c0334c9be61e6cef2c8c84a7800cef502063269a5af25ceb100b192453d4ab", "https://bcr.bazel.build/modules/rules_java/7.4.0/MODULE.bazel": "a592852f8a3dd539e82ee6542013bf2cadfc4c6946be8941e189d224500a8934", "https://bcr.bazel.build/modules/rules_java/7.6.1/MODULE.bazel": "2f14b7e8a1aa2f67ae92bc69d1ec0fa8d9f827c4e17ff5e5f02e91caa3b2d0fe", - "https://bcr.bazel.build/modules/rules_java/8.13.0/MODULE.bazel": "0444ebf737d144cf2bb2ccb368e7f1cce735264285f2a3711785827c1686625e", - "https://bcr.bazel.build/modules/rules_java/8.15.2/MODULE.bazel": "5cc6698c822b2f9ef90ca5558599851bed8c3b13f1f8eb140d9bfec638d2acb4", "https://bcr.bazel.build/modules/rules_java/8.3.2/MODULE.bazel": "7336d5511ad5af0b8615fdc7477535a2e4e723a357b6713af439fe8cf0195017", "https://bcr.bazel.build/modules/rules_java/8.5.1/MODULE.bazel": "d8a9e38cc5228881f7055a6079f6f7821a073df3744d441978e7a43e20226939", "https://bcr.bazel.build/modules/rules_java/8.6.0/MODULE.bazel": "9c064c434606d75a086f15ade5edb514308cccd1544c2b2a89bbac4310e41c71", @@ -205,7 +189,6 @@ "https://bcr.bazel.build/modules/rules_jvm_external/4.4.2/MODULE.bazel": "a56b85e418c83eb1839819f0b515c431010160383306d13ec21959ac412d2fe7", "https://bcr.bazel.build/modules/rules_jvm_external/5.1/MODULE.bazel": "33f6f999e03183f7d088c9be518a63467dfd0be94a11d0055fe2d210f89aa909", "https://bcr.bazel.build/modules/rules_jvm_external/5.2/MODULE.bazel": "d9351ba35217ad0de03816ef3ed63f89d411349353077348a45348b096615036", - "https://bcr.bazel.build/modules/rules_jvm_external/6.10/MODULE.bazel": "33e636ca6bc9ee0fa090a38aa33c631ded2d8cf6fead4124181d1b35dc474f7c", "https://bcr.bazel.build/modules/rules_jvm_external/6.2/MODULE.bazel": "36a6e52487a855f33cb960724eb56547fa87e2c98a0474c3acad94339d7f8e99", "https://bcr.bazel.build/modules/rules_jvm_external/6.3/MODULE.bazel": "c998e060b85f71e00de5ec552019347c8bca255062c990ac02d051bb80a38df0", "https://bcr.bazel.build/modules/rules_jvm_external/6.6/MODULE.bazel": "153042249c7060536dc95b6bb9f9bb8063b8a0b0cb7acdb381bddbc2374aed55", @@ -215,19 +198,15 @@ "https://bcr.bazel.build/modules/rules_jvm_external/7.0/source.json": "714cd003eadf5be5c83268311fe8e951db39f802babeaddc536b3560dc8f6faf", "https://bcr.bazel.build/modules/rules_kotlin/1.9.5/MODULE.bazel": "043a16a572f610558ec2030db3ff0c9938574e7dd9f58bded1bb07c0192ef025", "https://bcr.bazel.build/modules/rules_kotlin/1.9.6/MODULE.bazel": "d269a01a18ee74d0335450b10f62c9ed81f2321d7958a2934e44272fe82dcef3", - "https://bcr.bazel.build/modules/rules_kotlin/2.1.3/MODULE.bazel": "ce7def6d576aa8d3a9c6d10e13b4d157296229674371f67dbf788dae0afae3d5", "https://bcr.bazel.build/modules/rules_kotlin/2.2.2/MODULE.bazel": "00d39c5e0fa78cd86193946265bb849e7878c24e44260f9525108428852b315c", "https://bcr.bazel.build/modules/rules_kotlin/2.2.2/source.json": "7a32c2259c79ae0c9a036121f120de825e3ba5f0f3a209ffbbdccf4dc62489b9", "https://bcr.bazel.build/modules/rules_license/0.0.3/MODULE.bazel": "627e9ab0247f7d1e05736b59dbb1b6871373de5ad31c3011880b4133cafd4bd0", "https://bcr.bazel.build/modules/rules_license/0.0.7/MODULE.bazel": "088fbeb0b6a419005b89cf93fe62d9517c0a2b8bb56af3244af65ecfe37e7d5d", "https://bcr.bazel.build/modules/rules_license/1.0.0/MODULE.bazel": "a7fda60eefdf3d8c827262ba499957e4df06f659330bbe6cdbdb975b768bb65c", "https://bcr.bazel.build/modules/rules_license/1.0.0/source.json": "a52c89e54cc311196e478f8382df91c15f7a2bfdf4c6cd0e2675cc2ff0b56efb", - "https://bcr.bazel.build/modules/rules_oci/2.2.7/MODULE.bazel": "f6150e4b224d459f7f6523ef65967464ca4efdd266c7fbf2f5a2a51011957e0c", - "https://bcr.bazel.build/modules/rules_oci/2.2.7/source.json": "b099f02af330f47f19dc67fc9300ef6e1937a8c86882690db0e7a2fcea8c7f6b", "https://bcr.bazel.build/modules/rules_pkg/0.7.0/MODULE.bazel": "df99f03fc7934a4737122518bb87e667e62d780b610910f0447665a7e2be62dc", "https://bcr.bazel.build/modules/rules_pkg/1.0.1/MODULE.bazel": "5b1df97dbc29623bccdf2b0dcd0f5cb08e2f2c9050aab1092fd39a41e82686ff", - "https://bcr.bazel.build/modules/rules_pkg/1.2.0/MODULE.bazel": "c7db3c2b407e673c7a39e3625dc05dc9f12d6682cbd82a3a5924a13b491eda7e", - "https://bcr.bazel.build/modules/rules_pkg/1.2.0/source.json": "9062e00845bf91a4247465d371baa837adf9b6ff44c542f73ba084f07667e1dc", + "https://bcr.bazel.build/modules/rules_pkg/1.0.1/source.json": "bd82e5d7b9ce2d31e380dd9f50c111d678c3bdaca190cb76b0e1c71b05e1ba8a", "https://bcr.bazel.build/modules/rules_proto/4.0.0/MODULE.bazel": "a7a7b6ce9bee418c1a760b3d84f83a299ad6952f9903c67f19e4edd964894e06", "https://bcr.bazel.build/modules/rules_proto/5.3.0-21.7/MODULE.bazel": "e8dff86b0971688790ae75528fe1813f71809b5afd57facb44dad9e8eca631b7", "https://bcr.bazel.build/modules/rules_proto/6.0.0-rc1/MODULE.bazel": "1e5b502e2e1a9e825eef74476a5a1ee524a92297085015a052510b09a1a09483", @@ -267,7 +246,6 @@ "https://bcr.bazel.build/modules/rules_swift/3.1.2/source.json": "e85761f3098a6faf40b8187695e3de6d97944e98abd0d8ce579cb2daf6319a66", "https://bcr.bazel.build/modules/stardoc/0.5.1/MODULE.bazel": "1a05d92974d0c122f5ccf09291442580317cdd859f07a8655f1db9a60374f9f8", "https://bcr.bazel.build/modules/stardoc/0.5.3/MODULE.bazel": "c7f6948dae6999bf0db32c1858ae345f112cacf98f174c7a8bb707e41b974f1c", - "https://bcr.bazel.build/modules/stardoc/0.5.4/MODULE.bazel": "6569966df04610b8520957cb8e97cf2e9faac2c0309657c537ab51c16c18a2a4", "https://bcr.bazel.build/modules/stardoc/0.6.2/MODULE.bazel": "7060193196395f5dd668eda046ccbeacebfd98efc77fed418dbe2b82ffaa39fd", "https://bcr.bazel.build/modules/stardoc/0.7.0/MODULE.bazel": "05e3d6d30c099b6770e97da986c53bd31844d7f13d41412480ea265ac9e8079c", "https://bcr.bazel.build/modules/stardoc/0.7.2/MODULE.bazel": "fc152419aa2ea0f51c29583fab1e8c99ddefd5b3778421845606ee628629e0e5", @@ -275,14 +253,10 @@ "https://bcr.bazel.build/modules/swift_argument_parser/1.3.1.1/MODULE.bazel": "5e463fbfba7b1701d957555ed45097d7f984211330106ccd1352c6e0af0dcf91", "https://bcr.bazel.build/modules/swift_argument_parser/1.3.1.2/MODULE.bazel": "75aab2373a4bbe2a1260b9bf2a1ebbdbf872d3bd36f80bff058dccd82e89422f", "https://bcr.bazel.build/modules/swift_argument_parser/1.3.1.2/source.json": "5fba48bbe0ba48761f9e9f75f92876cafb5d07c0ce059cc7a8027416de94a05b", - "https://bcr.bazel.build/modules/tar.bzl/0.2.1/MODULE.bazel": "52d1c00a80a8cc67acbd01649e83d8dd6a9dc426a6c0b754a04fe8c219c76468", - "https://bcr.bazel.build/modules/tar.bzl/0.2.1/source.json": "600ac6ff61744667a439e7b814ae59c1f29632c3984fccf8000c64c9db8d7bb6", "https://bcr.bazel.build/modules/toml.bzl/0.3.0/MODULE.bazel": "5016e5dd1ad2200e119a4b28b2b3935e276c4b480f2fe3e952bea7eeba88f578", "https://bcr.bazel.build/modules/toml.bzl/0.3.0/source.json": "0cf7c878c419b37ddb55f3dd93dd7c0c409bd7c4efacb3da504e0748780b2fa9", "https://bcr.bazel.build/modules/upb/0.0.0-20220923-a547704/MODULE.bazel": "7298990c00040a0e2f121f6c32544bab27d4452f80d9ce51349b1a28f3005c43", "https://bcr.bazel.build/modules/upb/0.0.0-20230516-61a97ef/MODULE.bazel": "c0df5e35ad55e264160417fd0875932ee3c9dda63d9fccace35ac62f45e1b6f9", - "https://bcr.bazel.build/modules/yq.bzl/0.1.1/MODULE.bazel": "9039681f9bcb8958ee2c87ffc74bdafba9f4369096a2b5634b88abc0eaefa072", - "https://bcr.bazel.build/modules/yq.bzl/0.1.1/source.json": "2d2bad780a9f2b9195a4a370314d2c17ae95eaa745cefc2e12fbc49759b15aa3", "https://bcr.bazel.build/modules/zlib/1.2.11/MODULE.bazel": "07b389abc85fdbca459b69e2ec656ae5622873af3f845e1c9d80fe179f3effa0", "https://bcr.bazel.build/modules/zlib/1.2.12/MODULE.bazel": "3b1a8834ada2a883674be8cbd36ede1b6ec481477ada359cd2d3ddc562340b27", "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.5/MODULE.bazel": "eec517b5bbe5492629466e11dae908d043364302283de25581e3eb944326c4ca", @@ -304,229 +278,9 @@ } } }, - "@@rules_oci+//oci:extensions.bzl%oci": { - "general": { - "bzlTransitiveDigest": "pt4oC5w4SZXivjOVNAFM5W2NyEaU5cCGwrSOmM0x9wQ=", - "usagesDigest": "YV/my4HWfeIYZH762GR/gbfyrtmoU6x5X9/fNcX4Ioo=", - "recordedInputs": [ - "REPO_MAPPING:aspect_bazel_lib+,bazel_tools bazel_tools", - "REPO_MAPPING:bazel_features+,bazel_tools bazel_tools", - "REPO_MAPPING:rules_oci+,aspect_bazel_lib aspect_bazel_lib+", - "REPO_MAPPING:rules_oci+,bazel_features bazel_features+", - "REPO_MAPPING:rules_oci+,bazel_skylib bazel_skylib+" - ], - "generatedRepoSpecs": { - "temurin_jre_linux_arm64_v8": { - "repoRuleId": "@@rules_oci+//oci/private:pull.bzl%oci_pull", - "attributes": { - "www_authenticate_challenges": {}, - "scheme": "https", - "registry": "public.ecr.aws", - "repository": "docker/library/eclipse-temurin", - "identifier": "21-jre", - "platform": "linux/arm64/v8", - "target_name": "temurin_jre_linux_arm64_v8", - "bazel_tags": [] - } - }, - "temurin_jre_linux_amd64": { - "repoRuleId": "@@rules_oci+//oci/private:pull.bzl%oci_pull", - "attributes": { - "www_authenticate_challenges": {}, - "scheme": "https", - "registry": "public.ecr.aws", - "repository": "docker/library/eclipse-temurin", - "identifier": "21-jre", - "platform": "linux/amd64", - "target_name": "temurin_jre_linux_amd64", - "bazel_tags": [] - } - }, - "temurin_jre": { - "repoRuleId": "@@rules_oci+//oci/private:pull.bzl%oci_alias", - "attributes": { - "target_name": "temurin_jre", - "www_authenticate_challenges": {}, - "scheme": "https", - "registry": "public.ecr.aws", - "repository": "docker/library/eclipse-temurin", - "identifier": "21-jre", - "platforms": { - "@@platforms//cpu:arm64": "@temurin_jre_linux_arm64_v8", - "@@platforms//cpu:x86_64": "@temurin_jre_linux_amd64" - }, - "bzlmod_repository": "temurin_jre", - "reproducible": true - } - }, - "ubuntu_noble_linux_arm64_v8": { - "repoRuleId": "@@rules_oci+//oci/private:pull.bzl%oci_pull", - "attributes": { - "www_authenticate_challenges": {}, - "scheme": "https", - "registry": "public.ecr.aws", - "repository": "ubuntu/ubuntu", - "identifier": "sha256:ef59d9e82939bbce08973bdffb8761b025f75369fb7d2882cdc4938b5a9e992e", - "platform": "linux/arm64/v8", - "target_name": "ubuntu_noble_linux_arm64_v8", - "bazel_tags": [] - } - }, - "ubuntu_noble_linux_amd64": { - "repoRuleId": "@@rules_oci+//oci/private:pull.bzl%oci_pull", - "attributes": { - "www_authenticate_challenges": {}, - "scheme": "https", - "registry": "public.ecr.aws", - "repository": "ubuntu/ubuntu", - "identifier": "sha256:ef59d9e82939bbce08973bdffb8761b025f75369fb7d2882cdc4938b5a9e992e", - "platform": "linux/amd64", - "target_name": "ubuntu_noble_linux_amd64", - "bazel_tags": [] - } - }, - "ubuntu_noble": { - "repoRuleId": "@@rules_oci+//oci/private:pull.bzl%oci_alias", - "attributes": { - "target_name": "ubuntu_noble", - "www_authenticate_challenges": {}, - "scheme": "https", - "registry": "public.ecr.aws", - "repository": "ubuntu/ubuntu", - "identifier": "sha256:ef59d9e82939bbce08973bdffb8761b025f75369fb7d2882cdc4938b5a9e992e", - "platforms": { - "@@platforms//cpu:arm64": "@ubuntu_noble_linux_arm64_v8", - "@@platforms//cpu:x86_64": "@ubuntu_noble_linux_amd64" - }, - "bzlmod_repository": "ubuntu_noble", - "reproducible": true - } - }, - "oci_crane_darwin_amd64": { - "repoRuleId": "@@rules_oci+//oci:repositories.bzl%crane_repositories", - "attributes": { - "platform": "darwin_amd64", - "crane_version": "v0.18.0" - } - }, - "oci_crane_darwin_arm64": { - "repoRuleId": "@@rules_oci+//oci:repositories.bzl%crane_repositories", - "attributes": { - "platform": "darwin_arm64", - "crane_version": "v0.18.0" - } - }, - "oci_crane_linux_arm64": { - "repoRuleId": "@@rules_oci+//oci:repositories.bzl%crane_repositories", - "attributes": { - "platform": "linux_arm64", - "crane_version": "v0.18.0" - } - }, - "oci_crane_linux_armv6": { - "repoRuleId": "@@rules_oci+//oci:repositories.bzl%crane_repositories", - "attributes": { - "platform": "linux_armv6", - "crane_version": "v0.18.0" - } - }, - "oci_crane_linux_i386": { - "repoRuleId": "@@rules_oci+//oci:repositories.bzl%crane_repositories", - "attributes": { - "platform": "linux_i386", - "crane_version": "v0.18.0" - } - }, - "oci_crane_linux_s390x": { - "repoRuleId": "@@rules_oci+//oci:repositories.bzl%crane_repositories", - "attributes": { - "platform": "linux_s390x", - "crane_version": "v0.18.0" - } - }, - "oci_crane_linux_amd64": { - "repoRuleId": "@@rules_oci+//oci:repositories.bzl%crane_repositories", - "attributes": { - "platform": "linux_amd64", - "crane_version": "v0.18.0" - } - }, - "oci_crane_windows_armv6": { - "repoRuleId": "@@rules_oci+//oci:repositories.bzl%crane_repositories", - "attributes": { - "platform": "windows_armv6", - "crane_version": "v0.18.0" - } - }, - "oci_crane_windows_amd64": { - "repoRuleId": "@@rules_oci+//oci:repositories.bzl%crane_repositories", - "attributes": { - "platform": "windows_amd64", - "crane_version": "v0.18.0" - } - }, - "oci_crane_toolchains": { - "repoRuleId": "@@rules_oci+//oci/private:toolchains_repo.bzl%toolchains_repo", - "attributes": { - "toolchain_type": "@rules_oci//oci:crane_toolchain_type", - "toolchain": "@oci_crane_{platform}//:crane_toolchain" - } - }, - "oci_regctl_darwin_amd64": { - "repoRuleId": "@@rules_oci+//oci:repositories.bzl%regctl_repositories", - "attributes": { - "platform": "darwin_amd64" - } - }, - "oci_regctl_darwin_arm64": { - "repoRuleId": "@@rules_oci+//oci:repositories.bzl%regctl_repositories", - "attributes": { - "platform": "darwin_arm64" - } - }, - "oci_regctl_linux_arm64": { - "repoRuleId": "@@rules_oci+//oci:repositories.bzl%regctl_repositories", - "attributes": { - "platform": "linux_arm64" - } - }, - "oci_regctl_linux_s390x": { - "repoRuleId": "@@rules_oci+//oci:repositories.bzl%regctl_repositories", - "attributes": { - "platform": "linux_s390x" - } - }, - "oci_regctl_linux_amd64": { - "repoRuleId": "@@rules_oci+//oci:repositories.bzl%regctl_repositories", - "attributes": { - "platform": "linux_amd64" - } - }, - "oci_regctl_windows_amd64": { - "repoRuleId": "@@rules_oci+//oci:repositories.bzl%regctl_repositories", - "attributes": { - "platform": "windows_amd64" - } - }, - "oci_regctl_toolchains": { - "repoRuleId": "@@rules_oci+//oci/private:toolchains_repo.bzl%toolchains_repo", - "attributes": { - "toolchain_type": "@rules_oci//oci:regctl_toolchain_type", - "toolchain": "@oci_regctl_{platform}//:regctl_toolchain" - } - } - }, - "moduleExtensionMetadata": { - "explicitRootModuleDirectDeps": [], - "explicitRootModuleDirectDevDeps": [], - "useAllRepos": "NO", - "reproducible": false - } - } - }, "@@rules_python+//python/extensions:config.bzl%config": { "general": { - "bzlTransitiveDigest": "dzD8Q2YmrP3fz8saWLHPmlwPLO91ImtTmP/c9JKTStM=", + "bzlTransitiveDigest": "iibnRYgg8LpcfmH7EAnVwYePC3jsVaJ6Id8XxUjSZps=", "usagesDigest": "ZVSXMAGpD+xzVNPuvF1IoLBkty7TROO0+akMapt1pAg=", "recordedInputs": [ "REPO_MAPPING:rules_python+,bazel_tools bazel_tools", @@ -887,172 +641,6 @@ "5fcd0671a49cecf39b41021621ee1b6e7aa1370f37122b72e80d4fd4185833b6" ] }, - "1.23.6": { - "aix_ppc64": [ - "go1.23.6.aix-ppc64.tar.gz", - "adec10f4ba56591f523aa04851f7f6900b1c61508dfa6b80e62717a8e6684a5c" - ], - "darwin_amd64": [ - "go1.23.6.darwin-amd64.tar.gz", - "782da50ce8ec5e98fac2cd3cdc6a1d7130d093294fc310038f651444232a3fb0" - ], - "darwin_arm64": [ - "go1.23.6.darwin-arm64.tar.gz", - "5cae2450a1708aeb0333237a155640d5562abaf195defebc4306054565536221" - ], - "dragonfly_amd64": [ - "go1.23.6.dragonfly-amd64.tar.gz", - "d52efb3020d9332477ade98163c03d2f2fe3e051b0e7e01f0e167412c66de0cb" - ], - "freebsd_386": [ - "go1.23.6.freebsd-386.tar.gz", - "d3287706b5823712ac6cf7dff684a556cff98163ef60e7b275abe3388c17aac7" - ], - "freebsd_amd64": [ - "go1.23.6.freebsd-amd64.tar.gz", - "ebb4c6a9b0673dbdabc439877779ed6add16575e21bd0a7955c33f692789aef6" - ], - "freebsd_arm": [ - "go1.23.6.freebsd-arm.tar.gz", - "b7241584afb0b161c09148f8fde16171bb743e47b99d451fbc5f5217ec7a88b6" - ], - "freebsd_arm64": [ - "go1.23.6.freebsd-arm64.tar.gz", - "004718b53cedd7955d1b1dc4053539fcd1053c031f5f3374334a22befd1f8310" - ], - "freebsd_riscv64": [ - "go1.23.6.freebsd-riscv64.tar.gz", - "ca026ec8a30dd0c18164f40e1ce21bd725e2445f11699177d05815189a38de7a" - ], - "illumos_amd64": [ - "go1.23.6.illumos-amd64.tar.gz", - "7db973efa3fb2e48e45059b855721550fce8e90803e7373d3efd37b88dd821e8" - ], - "linux_386": [ - "go1.23.6.linux-386.tar.gz", - "e61f87693169c0bbcc43363128f1e929b9dff0b7f448573f1bdd4e4a0b9687ba" - ], - "linux_amd64": [ - "go1.23.6.linux-amd64.tar.gz", - "9379441ea310de000f33a4dc767bd966e72ab2826270e038e78b2c53c2e7802d" - ], - "linux_arm64": [ - "go1.23.6.linux-arm64.tar.gz", - "561c780e8f4a8955d32bf72e46af0b5ee5e0debe1e4633df9a03781878219202" - ], - "linux_armv6l": [ - "go1.23.6.linux-armv6l.tar.gz", - "27a4611010c16b8c4f37ade3aada55bd5781998f02f348b164302fd5eea4eb74" - ], - "linux_loong64": [ - "go1.23.6.linux-loong64.tar.gz", - "c459226424372abc2b35957cc8955dad348330714f7605093325dbb73e33c750" - ], - "linux_mips": [ - "go1.23.6.linux-mips.tar.gz", - "e2a0aff70b958a3463a7d47132a2d0238369f64578d4f7f95e679e3a5af05622" - ], - "linux_mips64": [ - "go1.23.6.linux-mips64.tar.gz", - "7d30ec7db056311d420bf930c16abcae13c0f41c26a202868f279721ec3c2f2f" - ], - "linux_mips64le": [ - "go1.23.6.linux-mips64le.tar.gz", - "74ca7bc475bcc084c6718b74df024d7de9612932cea8a6dc75e29d3a5315a23a" - ], - "linux_mipsle": [ - "go1.23.6.linux-mipsle.tar.gz", - "09bf935a14e9f59a20499989438b1655453480016bdbcb10406acf4df2678ccb" - ], - "linux_ppc64": [ - "go1.23.6.linux-ppc64.tar.gz", - "5cb2f6a5090276c72c5eda8a55896f5a3d6ea0f28d10fa1a50e8318640f02d6c" - ], - "linux_ppc64le": [ - "go1.23.6.linux-ppc64le.tar.gz", - "0f817201e83d78ddbfa27f5f78d9b72450b92cc21d5e045145efacd0d3244a99" - ], - "linux_riscv64": [ - "go1.23.6.linux-riscv64.tar.gz", - "f95f7f817ab22ecab4503d0704d6449ea1aa26a595f57bf9b9f94ddf2aa7c1f3" - ], - "linux_s390x": [ - "go1.23.6.linux-s390x.tar.gz", - "321e7ed0d5416f731479c52fa7610b52b8079a8061967bd48cec6d66f671a60e" - ], - "netbsd_386": [ - "go1.23.6.netbsd-386.tar.gz", - "92d678fb8e1eeeb8c6af6f22e4e5494652dcbb4a320113fc08325cb9956a2d4c" - ], - "netbsd_amd64": [ - "go1.23.6.netbsd-amd64.tar.gz", - "86ba51e7bb26b30ea6a8d88ddb79d8e8c83b4116200040ecb7a5a44cf90a8c5c" - ], - "netbsd_arm": [ - "go1.23.6.netbsd-arm.tar.gz", - "4b974c35345100f0be6ea66afab2781de91ee9882117314126eaf0ae90fd3816" - ], - "netbsd_arm64": [ - "go1.23.6.netbsd-arm64.tar.gz", - "53e3589fc38e787a493ea038961f8e40803714dbb42754c1713b00099c12e9b9" - ], - "openbsd_386": [ - "go1.23.6.openbsd-386.tar.gz", - "6d2317b3a8505ccebff8f72d943f2ac9b82c115632e54a53a786eff24ced56d9" - ], - "openbsd_amd64": [ - "go1.23.6.openbsd-amd64.tar.gz", - "f699e707d95a984fcc00361d91aecdb413d3c75e18235156ffba7a89edf68aae" - ], - "openbsd_arm": [ - "go1.23.6.openbsd-arm.tar.gz", - "3c1cf6ab893657d0bf1942e40ce115acfd27cbce1ccb9bc88fd9cd21ca3d489f" - ], - "openbsd_arm64": [ - "go1.23.6.openbsd-arm64.tar.gz", - "cc0875535d14001f2da23ae9af89025b28c466e8f4f4c63f991ebb6f4b02f66c" - ], - "openbsd_ppc64": [ - "go1.23.6.openbsd-ppc64.tar.gz", - "64de80e29ca66cb566cbf8be030bf8599953af4e48402eab724cbe0a08b40602" - ], - "openbsd_riscv64": [ - "go1.23.6.openbsd-riscv64.tar.gz", - "c398a6b43c569f34bb4a2d16b52f8010eaac9a2a82ecac0602b4338e35cef377" - ], - "plan9_386": [ - "go1.23.6.plan9-386.tar.gz", - "10998b6b130bb7b542b407f0db42b86a913b111f8fa86d44394beaace4d45f01" - ], - "plan9_amd64": [ - "go1.23.6.plan9-amd64.tar.gz", - "9fbe8065436d8d12c02f19f64f51c9107da3a7a4ac46ab5777e182e9fe88c32f" - ], - "plan9_arm": [ - "go1.23.6.plan9-arm.tar.gz", - "8e3c826b884daee2de37e3b070d7eac4cea5d68edab8db09910e22201c75db83" - ], - "solaris_amd64": [ - "go1.23.6.solaris-amd64.tar.gz", - "b619eff63fec86daaea92ca170559e448a58b8ba0b92eef1971bc14e92ea86a7" - ], - "windows_386": [ - "go1.23.6.windows-386.zip", - "96820c0f5d464dd694543329e9b4d413b17c821c03a055717a29e6735b44c2d8" - ], - "windows_amd64": [ - "go1.23.6.windows-amd64.zip", - "53fec1586850b2cf5ad6438341ff7adc5f6700dd3ec1cfa3f5e8b141df190243" - ], - "windows_arm": [ - "go1.23.6.windows-arm.zip", - "22c2518c45c20018afa20d5376dc9fd7a7e74367240ed7b5209e79a30b5c4218" - ], - "windows_arm64": [ - "go1.23.6.windows-arm64.zip", - "a2d2ec1b3759552bdd9cdf58858f91dfbfd6ab3a472f00b5255acbed30b1aa41" - ] - }, "1.25.0": { "aix_ppc64": [ "go1.25.0.aix-ppc64.tar.gz", @@ -1216,6 +804,5 @@ ] } } - }, - "factsVersions": {} + } } diff --git a/src/libraries/java/nv-boot-parent/NOTICE b/src/libraries/java/nv-boot-parent/NOTICE index e56935131..ca15f90d3 100644 --- a/src/libraries/java/nv-boot-parent/NOTICE +++ b/src/libraries/java/nv-boot-parent/NOTICE @@ -1,5 +1,5 @@ -Lists of 209 third-party dependencies. +Lists of 208 third-party dependencies. (Public Domain) AOP alliance (aopalliance:aopalliance:1.0 - http://aopalliance.sourceforge.net) (Apache License, Version 2.0) LZ4 Java Compression (at.yawk.lz4:lz4-java:1.10.3 - https://github.com/yawkat/lz4-java) (EPL-2.0) (LGPL-2.1-only) Logback Classic Module (ch.qos.logback:logback-classic:1.5.34 - http://logback.qos.ch) @@ -23,12 +23,12 @@ Lists of 209 third-party dependencies. (Eclipse Public License - v 2.0) (GNU General Public License Version 2) (GNU Lesser General Public License Version 2.1) jnr-posix (com.github.jnr:jnr-posix:3.1.15 - http://nexus.sonatype.org/oss-repository-hosting.html) (MIT License) jnr-x86asm (com.github.jnr:jnr-x86asm:1.0.2 - http://github.com/jnr/jnr-x86asm) (Apache License, Version 2.0) JCIP Annotations under Apache License (com.github.stephenc.jcip:jcip-annotations:1.0-1 - http://stephenc.github.com/jcip-annotations) - (The Apache Software License, Version 2.0) FindBugs-jsr305 (com.google.code.findbugs:jsr305:3.0.2 - http://findbugs.sourceforge.net/) - (Apache 2.0) error-prone annotations (com.google.errorprone:error_prone_annotations:2.5.1 - http://nexus.sonatype.org/oss-repository-hosting.html) - (The Apache Software License, Version 2.0) Guava InternalFutureFailureAccess and InternalFutures (com.google.guava:failureaccess:1.0.1 - https://github.com/google/guava) - (Apache License, Version 2.0) Guava: Google Core Libraries for Java (com.google.guava:guava:32.0.1-jre - https://github.com/google/guava) + (The Apache Software License, Version 2.0) FindBugs-jsr305 (com.google.code.findbugs:jsr305:2.0.1 - http://findbugs.sourceforge.net/) + (Apache 2.0) error-prone annotations (com.google.errorprone:error_prone_annotations:2.49.0 - https://errorprone.info) + (Apache License, Version 2.0) Guava InternalFutureFailureAccess and InternalFutures (com.google.guava:failureaccess:1.0.3 - https://github.com/google/guava) + (Apache License, Version 2.0) Guava: Google Core Libraries for Java (com.google.guava:guava:33.6.0-jre - https://github.com/google/guava) (The Apache Software License, Version 2.0) Guava ListenableFuture only (com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava - https://github.com/google/guava) - (Apache License, Version 2.0) J2ObjC Annotations (com.google.j2objc:j2objc-annotations:2.8 - https://github.com/google/j2objc/) + (Apache License, Version 2.0) J2ObjC Annotations (com.google.j2objc:j2objc-annotations:3.1 - https://github.com/google/j2objc/) (The Apache Software License, Version 2.0) Nimbus Content Type (com.nimbusds:content-type:2.3 - https://bitbucket.org/connect2id/nimbus-content-type) (The Apache Software License, Version 2.0) Nimbus LangTag (com.nimbusds:lang-tag:1.7 - https://bitbucket.org/connect2id/nimbus-language-tags) (The Apache Software License, Version 2.0) Nimbus JOSE+JWT (com.nimbusds:nimbus-jose-jwt:10.4 - https://bitbucket.org/connect2id/nimbus-jose-jwt) @@ -102,7 +102,6 @@ Lists of 209 third-party dependencies. (Apache License, Version 2.0) tomcat-embed-el (org.apache.tomcat.embed:tomcat-embed-el:11.0.22 - https://tomcat.apache.org/) (Bouncy Castle Licence) Bouncy Castle Provider (org.bouncycastle:bcprov-jdk18on:1.84 - https://www.bouncycastle.org/download/bouncy-castle-java/) (Bouncy Castle Licence) Bouncy Castle Provider (LTS Distribution) (org.bouncycastle:bcprov-lts8on:2.73.8 - https://www.bouncycastle.org/lts-java) - (The MIT License) Checker Qual (org.checkerframework:checker-qual:3.33.0 - https://checkerframework.org/) (Public Domain, per Creative Commons CC0) (BSD-2-Clause) HdrHistogram (org.hdrhistogram:HdrHistogram:2.2.2 - http://hdrhistogram.github.io/HdrHistogram/) (Apache License 2.0) Hibernate Validator Engine (org.hibernate.validator:hibernate-validator:9.0.1.Final - https://hibernate.org/validator) (Apache License 2.0) JBoss Logging 3 (org.jboss.logging:jboss-logging:3.6.3.Final - https://www.jboss.org) diff --git a/src/libraries/java/nv-boot-parent/maven_install.json b/src/libraries/java/nv-boot-parent/maven_install.json index 182e542e3..dbdfb4db2 100644 --- a/src/libraries/java/nv-boot-parent/maven_install.json +++ b/src/libraries/java/nv-boot-parent/maven_install.json @@ -4,11 +4,6 @@ "at.yawk.lz4:lz4-java": 1725015399, "com.github.ben-manes.caffeine:guava": 1054685015, "com.github.java-json-tools:json-patch": -1031005245, - "com.google.code.findbugs:jsr305": 495355163, - "com.google.code.gson:gson": 597770368, - "com.google.errorprone:error_prone_annotations": -1035138750, - "com.google.guava:guava": 1943808618, - "com.google.j2objc:j2objc-annotations": 2003271689, "commons-codec:commons-codec": -1269462382, "io.cloudevents:cloudevents-core": -2103567774, "io.cloudevents:cloudevents-json-jackson": -1197487309, @@ -20,19 +15,10 @@ "net.javacrumbs.shedlock:shedlock-bom": -1406345450, "org.apache.cassandra:java-driver-metrics-micrometer": -465267397, "org.apache.commons:commons-lang3": -278168457, - "org.assertj:assertj-core": 1863574844, - "org.awaitility:awaitility": -1630939750, "org.bouncycastle:bcprov-jdk18on": -1405390253, "org.jacoco:org.jacoco.agent": -2069397525, "org.jacoco:org.jacoco.cli": -1856875155, - "org.junit.jupiter:junit-jupiter-api": 194920406, - "org.junit.jupiter:junit-jupiter-engine": -1886863302, - "org.junit.jupiter:junit-jupiter-params": 1082310006, "org.junit.platform:junit-platform-console-standalone": -1481831078, - "org.junit.platform:junit-platform-launcher": -354104948, - "org.junit.platform:junit-platform-reporting": 1896713402, - "org.mockito:mockito-core": -554630660, - "org.mockito:mockito-junit-jupiter": -1104541639, "org.ow2.asm:asm-analysis": -1027574299, "org.ow2.asm:asm-util": -307204853, "org.projectlombok:lombok": -2073039513, @@ -80,7 +66,7 @@ "ch.qos.logback:logback-classic:jar:sources": -390128445, "ch.qos.logback:logback-core": -1554021729, "ch.qos.logback:logback-core:jar:sources": 77538609, - "com.datastax.cassandra:cassandra-driver-core": 197829386, + "com.datastax.cassandra:cassandra-driver-core": -681774303, "com.datastax.cassandra:cassandra-driver-core:jar:sources": -2045236197, "com.datastax.oss:native-protocol": 447263174, "com.datastax.oss:native-protocol:jar:sources": 396473389, @@ -96,9 +82,9 @@ "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:jar:sources": 1241536710, "com.fasterxml:classmate": -1468141616, "com.fasterxml:classmate:jar:sources": -179492269, - "com.github.ben-manes.caffeine:caffeine": 1925806502, + "com.github.ben-manes.caffeine:caffeine": 96455941, "com.github.ben-manes.caffeine:caffeine:jar:sources": -967473790, - "com.github.ben-manes.caffeine:guava": 2074933175, + "com.github.ben-manes.caffeine:guava": 1187631417, "com.github.ben-manes.caffeine:guava:jar:sources": 1956210603, "com.github.docker-java:docker-java-api": 1857041788, "com.github.docker-java:docker-java-api:jar:sources": 300128277, @@ -106,13 +92,13 @@ "com.github.docker-java:docker-java-transport-zerodep": -1848983763, "com.github.docker-java:docker-java-transport-zerodep:jar:sources": 1882881505, "com.github.docker-java:docker-java-transport:jar:sources": 864522470, - "com.github.java-json-tools:btf": 204024567, + "com.github.java-json-tools:btf": -1747700664, "com.github.java-json-tools:btf:jar:sources": 1539011915, - "com.github.java-json-tools:jackson-coreutils": 1585779168, + "com.github.java-json-tools:jackson-coreutils": 2047023685, "com.github.java-json-tools:jackson-coreutils:jar:sources": 323093438, - "com.github.java-json-tools:json-patch": 388171991, + "com.github.java-json-tools:json-patch": -399792119, "com.github.java-json-tools:json-patch:jar:sources": -1320375757, - "com.github.java-json-tools:msg-simple": -285204120, + "com.github.java-json-tools:msg-simple": 986302814, "com.github.java-json-tools:msg-simple:jar:sources": 1013495835, "com.github.jnr:jffi": 1952487985, "com.github.jnr:jffi:jar:native": 1426144838, @@ -127,19 +113,16 @@ "com.github.jnr:jnr-x86asm:jar:sources": -1784079536, "com.github.stephenc.jcip:jcip-annotations": -121928928, "com.github.stephenc.jcip:jcip-annotations:jar:sources": -2051941468, - "com.google.code.findbugs:jsr305": -1038659426, - "com.google.code.findbugs:jsr305:jar:sources": -1300148931, - "com.google.code.gson:gson": 1618556651, - "com.google.code.gson:gson:jar:sources": 389178860, - "com.google.errorprone:error_prone_annotations": 492382488, - "com.google.errorprone:error_prone_annotations:jar:sources": 456515251, - "com.google.guava:failureaccess": -268223546, - "com.google.guava:failureaccess:jar:sources": 2053502918, - "com.google.guava:guava": 1240305771, - "com.google.guava:guava:jar:sources": 1591586943, + "com.google.code.findbugs:jsr305": 1838181273, + "com.google.errorprone:error_prone_annotations": -1266099896, + "com.google.errorprone:error_prone_annotations:jar:sources": 936701586, + "com.google.guava:failureaccess": -56291903, + "com.google.guava:failureaccess:jar:sources": -820168004, + "com.google.guava:guava": -1132194940, + "com.google.guava:guava:jar:sources": -1505508770, "com.google.guava:listenablefuture": 1588902908, - "com.google.j2objc:j2objc-annotations": -596695707, - "com.google.j2objc:j2objc-annotations:jar:sources": 900785715, + "com.google.j2objc:j2objc-annotations": -2074422376, + "com.google.j2objc:j2objc-annotations:jar:sources": -597974451, "com.jayway.jsonpath:json-path": 626712679, "com.jayway.jsonpath:json-path:jar:sources": -343427302, "com.nimbusds:content-type": -444977683, @@ -334,8 +317,6 @@ "org.bouncycastle:bcprov-jdk18on:jar:sources": 106463766, "org.bouncycastle:bcprov-lts8on": 973431866, "org.bouncycastle:bcprov-lts8on:jar:sources": -196135755, - "org.checkerframework:checker-qual": -2018582244, - "org.checkerframework:checker-qual:jar:sources": 2110417205, "org.hamcrest:hamcrest": 1116842741, "org.hamcrest:hamcrest:jar:sources": -996443755, "org.hdrhistogram:HdrHistogram": 1379183334, @@ -372,10 +353,6 @@ "org.junit.platform:junit-platform-console-standalone:jar:sources": -103511349, "org.junit.platform:junit-platform-engine": -748595950, "org.junit.platform:junit-platform-engine:jar:sources": -191078126, - "org.junit.platform:junit-platform-launcher": 1722101087, - "org.junit.platform:junit-platform-launcher:jar:sources": -717285440, - "org.junit.platform:junit-platform-reporting": 1847654060, - "org.junit.platform:junit-platform-reporting:jar:sources": -1771745730, "org.latencyutils:LatencyUtils": 1082471286, "org.latencyutils:LatencyUtils:jar:sources": 1894864087, "org.mockito:mockito-core": 734095861, @@ -384,8 +361,6 @@ "org.mockito:mockito-junit-jupiter:jar:sources": -1281757309, "org.objenesis:objenesis": 1083875484, "org.objenesis:objenesis:jar:sources": 703772823, - "org.opentest4j.reporting:open-test-reporting-tooling-spi": -1639379357, - "org.opentest4j.reporting:open-test-reporting-tooling-spi:jar:sources": 1632689314, "org.opentest4j:opentest4j": 793813175, "org.opentest4j:opentest4j:jar:sources": 1210936723, "org.ow2.asm:asm": 716467505, @@ -596,7 +571,7 @@ "org.springframework:spring-webmvc": 56813816, "org.springframework:spring-webmvc:jar:sources": -837106767, "org.testcontainers:testcontainers": 450183679, - "org.testcontainers:testcontainers-cassandra": 584880112, + "org.testcontainers:testcontainers-cassandra": -1886187917, "org.testcontainers:testcontainers-cassandra:jar:sources": 2024290088, "org.testcontainers:testcontainers-database-commons": -1213526598, "org.testcontainers:testcontainers-database-commons:jar:sources": 315333060, @@ -850,38 +825,30 @@ }, "com.google.code.findbugs:jsr305": { "shasums": { - "jar": "766ad2a0783f2687962c8ad74ceecc38a28b9f72a2d085ee438b7813e928d0c7", - "sources": "1c9e85e272d0708c6a591dc74828c71603053b48cc75ae83cce56912a2aa063b" + "jar": "1e7f53fa5b8b5c807e986ba335665da03f18d660802d8bf061823089d1bee468" }, - "version": "3.0.2" - }, - "com.google.code.gson:gson": { - "shasums": { - "jar": "d3999291855de495c94c743761b8ab5176cfeabe281a5ab0d8e8d45326fd703e", - "sources": "ba5bddb1a89eb721fcca39f3b34294532060f851e2407a82d82134a41eec4719" - }, - "version": "2.8.9" + "version": "2.0.1" }, "com.google.errorprone:error_prone_annotations": { "shasums": { - "jar": "ff80626baaf12a09342befd4e84cba9d50662f5fcd7f7a9b3490a6b7cf87e66c", - "sources": "bf08616e340f5e2ef50aaa84aea8baa086fd7bb2ad310501ff4e88ec77f8f31a" + "jar": "3b1003e51b8ae56fdbd7c71073e81d1683b97e6c4dff5a9151164d59b769d13c", + "sources": "69d2de7f69033ff914ba06f0858adb96ac7b1436959f04fca7de5805c834b281" }, - "version": "2.5.1" + "version": "2.49.0" }, "com.google.guava:failureaccess": { "shasums": { - "jar": "a171ee4c734dd2da837e4b16be9df4661afab72a41adaf31eb84dfdaf936ca26", - "sources": "092346eebbb1657b51aa7485a246bf602bb464cc0b0e2e1c7e7201fadce1e98f" + "jar": "cbfc3906b19b8f55dd7cfd6dfe0aa4532e834250d7f080bd8d211a3e246b59cb", + "sources": "6fef4dfd2eb9f961655f2a3c4ea87c023618d9fcbfb6b104c17862e5afe66b97" }, - "version": "1.0.1" + "version": "1.0.3" }, "com.google.guava:guava": { "shasums": { - "jar": "bd7fa227591fb8509677d0d1122cf95158f3b8a9f45653f58281d879f6dc48c5", - "sources": "9105dfc522fb440b39ff8da07cc56aacf65a9f765044c7803a9f32e36e05a22b" + "jar": "dc573e1fca4fd5454f4a5fd3d7da2df03002876a4175bafc14a95980dd7713b3", + "sources": "eff31867dd63a92d63ca856127a424a6836418d8bfa044162cac20430abd3500" }, - "version": "32.0.1-jre" + "version": "33.6.0-jre" }, "com.google.guava:listenablefuture": { "shasums": { @@ -891,10 +858,10 @@ }, "com.google.j2objc:j2objc-annotations": { "shasums": { - "jar": "f02a95fa1a5e95edb3ed859fd0fb7df709d121a35290eff8b74dce2ab7f4d6ed", - "sources": "7413eed41f111453a08837f5ac680edded7faed466cbd35745e402e13f4cc3f5" + "jar": "84d3a150518485f8140ea99b8a985656749629f6433c92b80c75b36aba3b099b", + "sources": "295938307f4016b3f128f7347101b236ada1394808104519c9e93cd61b64602b" }, - "version": "2.8" + "version": "3.1" }, "com.jayway.jsonpath:json-path": { "shasums": { @@ -1565,13 +1532,6 @@ }, "version": "2.73.8" }, - "org.checkerframework:checker-qual": { - "shasums": { - "jar": "e316255bbfcd9fe50d165314b85abb2b33cb2a66a93c491db648e498a82c2de1", - "sources": "443fa6151982bb4c6ce62e2938f53660085b13a7dceb517202777b87d0dea2c7" - }, - "version": "3.33.0" - }, "org.hamcrest:hamcrest": { "shasums": { "jar": "5d66b6a4a680755cb6ed7cb104fa7835ef644667586ff0737adeb977c39ecdbc", @@ -1698,20 +1658,6 @@ }, "version": "6.0.3" }, - "org.junit.platform:junit-platform-launcher": { - "shasums": { - "jar": "315608372e4dc44bca0ccb3ae8a07ecc206b3367033fa05748a03ccd563f1301", - "sources": "4fcbdb81cc882c0c3e73f742878db5884d3d2f86facc08369ca953e32796d144" - }, - "version": "6.0.3" - }, - "org.junit.platform:junit-platform-reporting": { - "shasums": { - "jar": "f19c5be871c37ebed493f3152b67a909f89a44dff67c2db8016dfe34167d5730", - "sources": "bbdda2b9c002dbd1b05cfec144bab91e8cca46ed8d58525f51b547f3a0a84a7d" - }, - "version": "6.0.3" - }, "org.latencyutils:LatencyUtils": { "shasums": { "jar": "a32a9ffa06b2f4e01c5360f8f9df7bc5d9454a5d373cd8f361347fa5a57165ec", @@ -1740,13 +1686,6 @@ }, "version": "3.3" }, - "org.opentest4j.reporting:open-test-reporting-tooling-spi": { - "shasums": { - "jar": "04ac4ecfcaf60abe0e6d5b18e8306320aec7cd9cbf15e59eeac54fa9faa16902", - "sources": "efe9672e74111726c0ff85a2508a0bc78be611a7cbe460560dc7cd429ee0a4ce" - }, - "version": "0.2.4" - }, "org.opentest4j:opentest4j": { "shasums": { "jar": "48e2df636cab6563ced64dcdff8abb2355627cb236ef0bf37598682ddf742f1b", @@ -2674,6 +2613,9 @@ "conflict_resolution": { "com.github.jnr:jnr-ffi:2.2.11": "com.github.jnr:jnr-ffi:2.1.7", "com.github.jnr:jnr-posix:3.0.44": "com.github.jnr:jnr-posix:3.1.15", + "com.google.code.findbugs:jsr305:3.0.2": "com.google.code.findbugs:jsr305:2.0.1", + "com.google.errorprone:error_prone_annotations:2.47.0": "com.google.errorprone:error_prone_annotations:2.49.0", + "com.google.guava:guava:19.0": "com.google.guava:guava:33.6.0-jre", "org.jetbrains:annotations:13.0": "org.jetbrains:annotations:17.0.0", "org.ow2.asm:asm-commons:5.0.3": "org.ow2.asm:asm-commons:9.9", "org.ow2.asm:asm-tree:5.0.3": "org.ow2.asm:asm-tree:9.9", @@ -2757,12 +2699,11 @@ "com.github.jnr:jnr-ffi" ], "com.google.guava:guava": [ - "com.google.code.findbugs:jsr305", "com.google.errorprone:error_prone_annotations", "com.google.guava:failureaccess", "com.google.guava:listenablefuture", "com.google.j2objc:j2objc-annotations", - "org.checkerframework:checker-qual" + "org.jspecify:jspecify" ], "com.jayway.jsonpath:json-path": [ "net.minidev:json-smart", @@ -3180,17 +3121,6 @@ "org.junit.platform:junit-platform-commons", "org.opentest4j:opentest4j" ], - "org.junit.platform:junit-platform-launcher": [ - "org.apiguardian:apiguardian-api", - "org.jspecify:jspecify", - "org.junit.platform:junit-platform-engine" - ], - "org.junit.platform:junit-platform-reporting": [ - "org.apiguardian:apiguardian-api", - "org.jspecify:jspecify", - "org.junit.platform:junit-platform-launcher", - "org.opentest4j.reporting:open-test-reporting-tooling-spi" - ], "org.mockito:mockito-core": [ "net.bytebuddy:byte-buddy", "net.bytebuddy:byte-buddy-agent", @@ -3200,9 +3130,6 @@ "org.junit.jupiter:junit-jupiter-api", "org.mockito:mockito-core" ], - "org.opentest4j.reporting:open-test-reporting-tooling-spi": [ - "org.apiguardian:apiguardian-api" - ], "org.ow2.asm:asm-analysis": [ "org.ow2.asm:asm-tree" ], @@ -4197,17 +4124,6 @@ "javax.annotation.concurrent", "javax.annotation.meta" ], - "com.google.code.gson:gson": [ - "com.google.gson", - "com.google.gson.annotations", - "com.google.gson.internal", - "com.google.gson.internal.bind", - "com.google.gson.internal.bind.util", - "com.google.gson.internal.reflect", - "com.google.gson.internal.sql", - "com.google.gson.reflect", - "com.google.gson.stream" - ], "com.google.errorprone:error_prone_annotations": [ "com.google.errorprone.annotations", "com.google.errorprone.annotations.concurrent" @@ -5680,38 +5596,6 @@ "org.bouncycastle.util.io.pem", "org.bouncycastle.util.test" ], - "org.checkerframework:checker-qual": [ - "org.checkerframework.checker.builder.qual", - "org.checkerframework.checker.calledmethods.qual", - "org.checkerframework.checker.compilermsgs.qual", - "org.checkerframework.checker.fenum.qual", - "org.checkerframework.checker.formatter.qual", - "org.checkerframework.checker.guieffect.qual", - "org.checkerframework.checker.i18n.qual", - "org.checkerframework.checker.i18nformatter.qual", - "org.checkerframework.checker.index.qual", - "org.checkerframework.checker.initialization.qual", - "org.checkerframework.checker.interning.qual", - "org.checkerframework.checker.lock.qual", - "org.checkerframework.checker.mustcall.qual", - "org.checkerframework.checker.nullness.qual", - "org.checkerframework.checker.optional.qual", - "org.checkerframework.checker.propkey.qual", - "org.checkerframework.checker.regex.qual", - "org.checkerframework.checker.signature.qual", - "org.checkerframework.checker.signedness.qual", - "org.checkerframework.checker.tainting.qual", - "org.checkerframework.checker.units.qual", - "org.checkerframework.common.aliasing.qual", - "org.checkerframework.common.initializedfields.qual", - "org.checkerframework.common.reflection.qual", - "org.checkerframework.common.returnsreceiver.qual", - "org.checkerframework.common.subtyping.qual", - "org.checkerframework.common.util.report.qual", - "org.checkerframework.common.value.qual", - "org.checkerframework.dataflow.qual", - "org.checkerframework.framework.qual" - ], "org.hamcrest:hamcrest": [ "org.hamcrest", "org.hamcrest.beans", @@ -6092,27 +5976,6 @@ "org.junit.platform.engine.support.hierarchical", "org.junit.platform.engine.support.store" ], - "org.junit.platform:junit-platform-launcher": [ - "org.junit.platform.launcher", - "org.junit.platform.launcher.core", - "org.junit.platform.launcher.jfr", - "org.junit.platform.launcher.listeners", - "org.junit.platform.launcher.listeners.discovery", - "org.junit.platform.launcher.listeners.session", - "org.junit.platform.launcher.tagexpression" - ], - "org.junit.platform:junit-platform-reporting": [ - "org.junit.platform.reporting", - "org.junit.platform.reporting.legacy", - "org.junit.platform.reporting.legacy.xml", - "org.junit.platform.reporting.open.xml", - "org.junit.platform.reporting.shadow.org.opentest4j.reporting.events.api", - "org.junit.platform.reporting.shadow.org.opentest4j.reporting.events.core", - "org.junit.platform.reporting.shadow.org.opentest4j.reporting.events.git", - "org.junit.platform.reporting.shadow.org.opentest4j.reporting.events.java", - "org.junit.platform.reporting.shadow.org.opentest4j.reporting.events.root", - "org.junit.platform.reporting.shadow.org.opentest4j.reporting.schema" - ], "org.latencyutils:LatencyUtils": [ "org.LatencyUtils" ], @@ -6199,9 +6062,6 @@ "org.objenesis.instantiator.util", "org.objenesis.strategy" ], - "org.opentest4j.reporting:open-test-reporting-tooling-spi": [ - "org.opentest4j.reporting.tooling.spi.htmlreport" - ], "org.opentest4j:opentest4j": [ "org.opentest4j" ], @@ -8610,9 +8470,6 @@ "com.github.stephenc.jcip:jcip-annotations", "com.github.stephenc.jcip:jcip-annotations:jar:sources", "com.google.code.findbugs:jsr305", - "com.google.code.findbugs:jsr305:jar:sources", - "com.google.code.gson:gson", - "com.google.code.gson:gson:jar:sources", "com.google.errorprone:error_prone_annotations", "com.google.errorprone:error_prone_annotations:jar:sources", "com.google.guava:failureaccess", @@ -8816,8 +8673,6 @@ "org.bouncycastle:bcprov-jdk18on:jar:sources", "org.bouncycastle:bcprov-lts8on", "org.bouncycastle:bcprov-lts8on:jar:sources", - "org.checkerframework:checker-qual", - "org.checkerframework:checker-qual:jar:sources", "org.hamcrest:hamcrest", "org.hamcrest:hamcrest:jar:sources", "org.hdrhistogram:HdrHistogram", @@ -8854,10 +8709,6 @@ "org.junit.platform:junit-platform-console-standalone:jar:sources", "org.junit.platform:junit-platform-engine", "org.junit.platform:junit-platform-engine:jar:sources", - "org.junit.platform:junit-platform-launcher", - "org.junit.platform:junit-platform-launcher:jar:sources", - "org.junit.platform:junit-platform-reporting", - "org.junit.platform:junit-platform-reporting:jar:sources", "org.latencyutils:LatencyUtils", "org.latencyutils:LatencyUtils:jar:sources", "org.mockito:mockito-core", @@ -8866,8 +8717,6 @@ "org.mockito:mockito-junit-jupiter:jar:sources", "org.objenesis:objenesis", "org.objenesis:objenesis:jar:sources", - "org.opentest4j.reporting:open-test-reporting-tooling-spi", - "org.opentest4j.reporting:open-test-reporting-tooling-spi:jar:sources", "org.opentest4j:opentest4j", "org.opentest4j:opentest4j:jar:sources", "org.ow2.asm:asm", @@ -9191,9 +9040,6 @@ "com.github.stephenc.jcip:jcip-annotations", "com.github.stephenc.jcip:jcip-annotations:jar:sources", "com.google.code.findbugs:jsr305", - "com.google.code.findbugs:jsr305:jar:sources", - "com.google.code.gson:gson", - "com.google.code.gson:gson:jar:sources", "com.google.errorprone:error_prone_annotations", "com.google.errorprone:error_prone_annotations:jar:sources", "com.google.guava:failureaccess", @@ -9397,8 +9243,6 @@ "org.bouncycastle:bcprov-jdk18on:jar:sources", "org.bouncycastle:bcprov-lts8on", "org.bouncycastle:bcprov-lts8on:jar:sources", - "org.checkerframework:checker-qual", - "org.checkerframework:checker-qual:jar:sources", "org.hamcrest:hamcrest", "org.hamcrest:hamcrest:jar:sources", "org.hdrhistogram:HdrHistogram", @@ -9435,10 +9279,6 @@ "org.junit.platform:junit-platform-console-standalone:jar:sources", "org.junit.platform:junit-platform-engine", "org.junit.platform:junit-platform-engine:jar:sources", - "org.junit.platform:junit-platform-launcher", - "org.junit.platform:junit-platform-launcher:jar:sources", - "org.junit.platform:junit-platform-reporting", - "org.junit.platform:junit-platform-reporting:jar:sources", "org.latencyutils:LatencyUtils", "org.latencyutils:LatencyUtils:jar:sources", "org.mockito:mockito-core", @@ -9447,8 +9287,6 @@ "org.mockito:mockito-junit-jupiter:jar:sources", "org.objenesis:objenesis", "org.objenesis:objenesis:jar:sources", - "org.opentest4j.reporting:open-test-reporting-tooling-spi", - "org.opentest4j.reporting:open-test-reporting-tooling-spi:jar:sources", "org.opentest4j:opentest4j", "org.opentest4j:opentest4j:jar:sources", "org.ow2.asm:asm", @@ -9923,19 +9761,6 @@ "org.junit.platform.engine.discovery.UriSelector$IdentifierParser" ] }, - "org.junit.platform:junit-platform-launcher": { - "org.junit.platform.launcher.TestExecutionListener": [ - "org.junit.platform.launcher.listeners.UniqueIdTrackingListener" - ] - }, - "org.junit.platform:junit-platform-reporting": { - "org.junit.platform.launcher.TestExecutionListener": [ - "org.junit.platform.reporting.open.xml.OpenTestReportGeneratingListener" - ], - "org.opentest4j.reporting.tooling.spi.htmlreport.Contributor": [ - "org.junit.platform.reporting.open.xml.JUnitContributor" - ] - }, "org.projectlombok:lombok": { "javax.annotation.processing.Processor": [ "lombok.launch.AnnotationProcessorHider$AnnotationProcessor", diff --git a/src/libraries/java/nv-boot-parent/nv-boot-mock-servers-test/BUILD.bazel b/src/libraries/java/nv-boot-parent/nv-boot-mock-servers-test/BUILD.bazel index a89ecf6bd..acb3366a0 100644 --- a/src/libraries/java/nv-boot-parent/nv-boot-mock-servers-test/BUILD.bazel +++ b/src/libraries/java/nv-boot-parent/nv-boot-mock-servers-test/BUILD.bazel @@ -1,22 +1,22 @@ load("//tools/bazel:java.bzl", "nv_boot_library", "nv_boot_library_test") MOCK_SERVERS_COMPILE_DEPS = [ - "@maven//:com_fasterxml_jackson_core_jackson_annotations", - "@maven//:com_nimbusds_nimbus_jose_jwt", - "@maven//:jakarta_annotation_jakarta_annotation_api", - "@maven//:jakarta_validation_jakarta_validation_api", - "@maven//:org_apache_commons_commons_lang3", - "@maven//:org_apache_logging_log4j_log4j_api", - "@maven//:org_slf4j_slf4j_api", - "@maven//:org_springframework_boot_spring_boot_autoconfigure", - "@maven//:org_springframework_boot_spring_boot_starter_jackson", - "@maven//:org_springframework_cloud_spring_cloud_context", - "@maven//:org_springframework_security_spring_security_oauth2_core", - "@maven//:org_springframework_security_spring_security_oauth2_jose", - "@maven//:org_springframework_spring_context", - "@maven//:org_springframework_spring_web", - "@maven//:org_wiremock_wiremock_standalone", - "@maven//:tools_jackson_core_jackson_databind", + "@nv_third_party_deps//:com_fasterxml_jackson_core_jackson_annotations", + "@nv_third_party_deps//:com_nimbusds_nimbus_jose_jwt", + "@nv_third_party_deps//:jakarta_annotation_jakarta_annotation_api", + "@nv_third_party_deps//:jakarta_validation_jakarta_validation_api", + "@nv_third_party_deps//:org_apache_commons_commons_lang3", + "@nv_third_party_deps//:org_apache_logging_log4j_log4j_api", + "@nv_third_party_deps//:org_slf4j_slf4j_api", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_autoconfigure", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_jackson", + "@nv_third_party_deps//:org_springframework_cloud_spring_cloud_context", + "@nv_third_party_deps//:org_springframework_security_spring_security_oauth2_core", + "@nv_third_party_deps//:org_springframework_security_spring_security_oauth2_jose", + "@nv_third_party_deps//:org_springframework_spring_context", + "@nv_third_party_deps//:org_springframework_spring_web", + "@nv_third_party_deps//:org_wiremock_wiremock_standalone", + "@nv_third_party_deps//:tools_jackson_core_jackson_databind", ] nv_boot_library( diff --git a/src/libraries/java/nv-boot-parent/nv-boot-starter-audit/BUILD.bazel b/src/libraries/java/nv-boot-parent/nv-boot-starter-audit/BUILD.bazel index 2adccbeb8..fe0b483ff 100644 --- a/src/libraries/java/nv-boot-parent/nv-boot-starter-audit/BUILD.bazel +++ b/src/libraries/java/nv-boot-parent/nv-boot-starter-audit/BUILD.bazel @@ -2,32 +2,32 @@ load("@rules_java//java:defs.bzl", "java_library") load("//tools/bazel:java.bzl", "nv_boot_library", "nv_boot_library_test", "nv_boot_runtime_classpath_test") AUDIT_REQUIRED_DEPS = [ - "@maven//:com_fasterxml_jackson_core_jackson_annotations", - "@maven//:com_fasterxml_jackson_core_jackson_databind", - "@maven//:com_github_java_json_tools_json_patch", - "@maven//:org_apache_commons_commons_lang3", - "@maven//:org_bouncycastle_bcprov_jdk18on", - "@maven//:org_slf4j_slf4j_api", - "@maven//:org_springframework_boot_spring_boot", - "@maven//:org_springframework_boot_spring_boot_autoconfigure", - "@maven//:org_springframework_boot_spring_boot_jackson", - "@maven//:org_springframework_boot_spring_boot_starter", - "@maven//:org_springframework_boot_spring_boot_starter_jackson", - "@maven//:org_springframework_security_spring_security_core", - "@maven//:org_springframework_spring_beans", - "@maven//:org_springframework_spring_context", - "@maven//:org_springframework_spring_core", - "@maven//:tools_jackson_core_jackson_core", - "@maven//:tools_jackson_core_jackson_databind", + "@nv_third_party_deps//:com_fasterxml_jackson_core_jackson_annotations", + "@nv_third_party_deps//:com_fasterxml_jackson_core_jackson_databind", + "@nv_third_party_deps//:com_github_java_json_tools_json_patch", + "@nv_third_party_deps//:org_apache_commons_commons_lang3", + "@nv_third_party_deps//:org_bouncycastle_bcprov_jdk18on", + "@nv_third_party_deps//:org_slf4j_slf4j_api", + "@nv_third_party_deps//:org_springframework_boot_spring_boot", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_autoconfigure", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_jackson", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_jackson", + "@nv_third_party_deps//:org_springframework_security_spring_security_core", + "@nv_third_party_deps//:org_springframework_spring_beans", + "@nv_third_party_deps//:org_springframework_spring_context", + "@nv_third_party_deps//:org_springframework_spring_core", + "@nv_third_party_deps//:tools_jackson_core_jackson_core", + "@nv_third_party_deps//:tools_jackson_core_jackson_databind", ] # The OAuth2 resource-server starter is optional in Maven. Keep its APIs on # this module's compile/test classpaths without exporting them at runtime. AUDIT_OPTIONAL_COMPILE_DEPS = [ - "@maven//:org_springframework_boot_spring_boot_starter_security_oauth2_resource_server", - "@maven//:org_springframework_security_spring_security_oauth2_core", - "@maven//:org_springframework_security_spring_security_oauth2_jose", - "@maven//:org_springframework_security_spring_security_oauth2_resource_server", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_security_oauth2_resource_server", + "@nv_third_party_deps//:org_springframework_security_spring_security_oauth2_core", + "@nv_third_party_deps//:org_springframework_security_spring_security_oauth2_jose", + "@nv_third_party_deps//:org_springframework_security_spring_security_oauth2_resource_server", ] java_library( @@ -62,9 +62,9 @@ nv_boot_library_test( coverage_library = ":nv_boot_starter_audit", deps = [ ":nv_boot_starter_audit", - "@maven//:ch_qos_logback_logback_classic", - "@maven//:org_springframework_boot_spring_boot_starter_security_oauth2_resource_server_test", - "@maven//:org_springframework_boot_spring_boot_starter_test", - "@maven//:org_springframework_security_spring_security_test", + "@nv_third_party_deps//:ch_qos_logback_logback_classic", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_security_oauth2_resource_server_test", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_test", + "@nv_third_party_deps//:org_springframework_security_spring_security_test", ] + AUDIT_REQUIRED_DEPS + AUDIT_OPTIONAL_COMPILE_DEPS, ) diff --git a/src/libraries/java/nv-boot-parent/nv-boot-starter-cassandra/BUILD.bazel b/src/libraries/java/nv-boot-parent/nv-boot-starter-cassandra/BUILD.bazel index 014ae1837..ea64f0995 100644 --- a/src/libraries/java/nv-boot-parent/nv-boot-starter-cassandra/BUILD.bazel +++ b/src/libraries/java/nv-boot-parent/nv-boot-starter-cassandra/BUILD.bazel @@ -1,47 +1,47 @@ load("//tools/bazel:java.bzl", "nv_boot_library", "nv_boot_library_test") CASSANDRA_COMPILE_DEPS = [ - "@maven//:at_yawk_lz4_lz4_java", - "@maven//:com_github_ben_manes_caffeine_guava", - "@maven//:com_google_guava_guava", - "@maven//:io_micrometer_micrometer_commons", - "@maven//:io_micrometer_micrometer_core", - "@maven//:io_micrometer_micrometer_observation", - "@maven//:jakarta_annotation_jakarta_annotation_api", - "@maven//:jakarta_validation_jakarta_validation_api", - "@maven//:org_apache_cassandra_java_driver_core", - "@maven//:org_apache_cassandra_java_driver_metrics_micrometer", - "@maven//:org_apache_commons_commons_lang3", - "@maven//:org_jspecify_jspecify", - "@maven//:org_slf4j_slf4j_api", - "@maven//:org_springframework_boot_spring_boot", - "@maven//:org_springframework_boot_spring_boot_actuator", - "@maven//:org_springframework_boot_spring_boot_actuator_autoconfigure", - "@maven//:org_springframework_boot_spring_boot_autoconfigure", - "@maven//:org_springframework_boot_spring_boot_cassandra", - "@maven//:org_springframework_boot_spring_boot_data_cassandra", - "@maven//:org_springframework_boot_spring_boot_health", - "@maven//:org_springframework_boot_spring_boot_starter_actuator", - "@maven//:org_springframework_boot_spring_boot_starter_data_cassandra", - "@maven//:org_springframework_cloud_spring_cloud_context", - "@maven//:org_springframework_data_spring_data_cassandra", - "@maven//:org_springframework_data_spring_data_commons", - "@maven//:org_springframework_spring_beans", - "@maven//:org_springframework_spring_context", - "@maven//:org_springframework_spring_core", + "@nv_third_party_deps//:at_yawk_lz4_lz4_java", + "@nv_third_party_deps//:com_github_ben_manes_caffeine_guava", + "@nv_third_party_deps//:com_google_guava_guava", + "@nv_third_party_deps//:io_micrometer_micrometer_commons", + "@nv_third_party_deps//:io_micrometer_micrometer_core", + "@nv_third_party_deps//:io_micrometer_micrometer_observation", + "@nv_third_party_deps//:jakarta_annotation_jakarta_annotation_api", + "@nv_third_party_deps//:jakarta_validation_jakarta_validation_api", + "@nv_third_party_deps//:org_apache_cassandra_java_driver_core", + "@nv_third_party_deps//:org_apache_cassandra_java_driver_metrics_micrometer", + "@nv_third_party_deps//:org_apache_commons_commons_lang3", + "@nv_third_party_deps//:org_jspecify_jspecify", + "@nv_third_party_deps//:org_slf4j_slf4j_api", + "@nv_third_party_deps//:org_springframework_boot_spring_boot", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_actuator", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_actuator_autoconfigure", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_autoconfigure", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_cassandra", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_data_cassandra", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_health", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_actuator", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_data_cassandra", + "@nv_third_party_deps//:org_springframework_cloud_spring_cloud_context", + "@nv_third_party_deps//:org_springframework_data_spring_data_cassandra", + "@nv_third_party_deps//:org_springframework_data_spring_data_commons", + "@nv_third_party_deps//:org_springframework_spring_beans", + "@nv_third_party_deps//:org_springframework_spring_context", + "@nv_third_party_deps//:org_springframework_spring_core", ] CASSANDRA_TEST_DEPS = [ ":nv_boot_starter_cassandra", - "@maven//:org_springframework_boot_spring_boot_starter_actuator_test", - "@maven//:org_springframework_boot_spring_boot_starter_data_cassandra_test", - "@maven//:org_springframework_boot_spring_boot_starter_webmvc_test", - "@maven//:org_springframework_boot_spring_boot_webmvc_test", - "@maven//:org_springframework_spring_aop", - "@maven//:org_springframework_spring_web", - "@maven//:org_testcontainers_testcontainers", - "@maven//:org_testcontainers_testcontainers_cassandra", - "@maven//:org_testcontainers_testcontainers_junit_jupiter", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_actuator_test", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_data_cassandra_test", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_webmvc_test", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_webmvc_test", + "@nv_third_party_deps//:org_springframework_spring_aop", + "@nv_third_party_deps//:org_springframework_spring_web", + "@nv_third_party_deps//:org_testcontainers_testcontainers", + "@nv_third_party_deps//:org_testcontainers_testcontainers_cassandra", + "@nv_third_party_deps//:org_testcontainers_testcontainers_junit_jupiter", ] + CASSANDRA_COMPILE_DEPS nv_boot_library( diff --git a/src/libraries/java/nv-boot-parent/nv-boot-starter-core/BUILD.bazel b/src/libraries/java/nv-boot-parent/nv-boot-starter-core/BUILD.bazel index fe628e591..2ca8c9ab4 100644 --- a/src/libraries/java/nv-boot-parent/nv-boot-starter-core/BUILD.bazel +++ b/src/libraries/java/nv-boot-parent/nv-boot-starter-core/BUILD.bazel @@ -2,33 +2,33 @@ load("@rules_java//java:defs.bzl", "java_library") load("//tools/bazel:java.bzl", "nv_boot_library", "nv_boot_library_test", "nv_boot_runtime_classpath_test") CORE_REQUIRED_DEPS = [ - "@maven//:com_github_ben_manes_caffeine_guava", - "@maven//:com_google_guava_guava", - "@maven//:jakarta_annotation_jakarta_annotation_api", - "@maven//:org_apache_commons_commons_lang3", - "@maven//:org_slf4j_slf4j_api", - "@maven//:org_springframework_boot_spring_boot", - "@maven//:org_springframework_boot_spring_boot_actuator_autoconfigure", - "@maven//:org_springframework_boot_spring_boot_autoconfigure", - "@maven//:org_springframework_boot_spring_boot_health", - "@maven//:org_springframework_boot_spring_boot_starter", - "@maven//:org_springframework_boot_spring_boot_starter_actuator", - "@maven//:org_springframework_cloud_spring_cloud_context", - "@maven//:org_springframework_spring_beans", - "@maven//:org_springframework_spring_context", - "@maven//:org_springframework_spring_core", + "@nv_third_party_deps//:com_github_ben_manes_caffeine_guava", + "@nv_third_party_deps//:com_google_guava_guava", + "@nv_third_party_deps//:jakarta_annotation_jakarta_annotation_api", + "@nv_third_party_deps//:org_apache_commons_commons_lang3", + "@nv_third_party_deps//:org_slf4j_slf4j_api", + "@nv_third_party_deps//:org_springframework_boot_spring_boot", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_actuator_autoconfigure", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_autoconfigure", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_health", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_actuator", + "@nv_third_party_deps//:org_springframework_cloud_spring_cloud_context", + "@nv_third_party_deps//:org_springframework_spring_beans", + "@nv_third_party_deps//:org_springframework_spring_context", + "@nv_third_party_deps//:org_springframework_spring_core", ] # Maven optional/provided integrations must compile with the starter, but they # must not become runtime dependencies of every downstream Bazel application. CORE_OPTIONAL_COMPILE_DEPS = [ - "@maven//:io_swagger_core_v3_swagger_models_jakarta", - "@maven//:jakarta_servlet_jakarta_servlet_api", - "@maven//:org_springdoc_springdoc_openapi_starter_webflux_api", - "@maven//:org_springdoc_springdoc_openapi_starter_webmvc_api", - "@maven//:org_springframework_spring_web", - "@maven//:org_springframework_spring_webflux", - "@maven//:org_springframework_spring_webmvc", + "@nv_third_party_deps//:io_swagger_core_v3_swagger_models_jakarta", + "@nv_third_party_deps//:jakarta_servlet_jakarta_servlet_api", + "@nv_third_party_deps//:org_springdoc_springdoc_openapi_starter_webflux_api", + "@nv_third_party_deps//:org_springdoc_springdoc_openapi_starter_webmvc_api", + "@nv_third_party_deps//:org_springframework_spring_web", + "@nv_third_party_deps//:org_springframework_spring_webflux", + "@nv_third_party_deps//:org_springframework_spring_webmvc", ] java_library( @@ -69,10 +69,10 @@ nv_boot_library_test( resources = glob(["src/test/resources/**"]), deps = [ ":nv_boot_starter_core", - "@maven//:org_springframework_boot_spring_boot_starter_actuator_test", - "@maven//:org_springframework_boot_spring_boot_starter_webflux_test", - "@maven//:org_springframework_boot_spring_boot_starter_webmvc_test", - "@maven//:org_springframework_boot_spring_boot_webmvc_test", - "@maven//:org_springframework_boot_spring_boot_webtestclient", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_actuator_test", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_webflux_test", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_webmvc_test", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_webmvc_test", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_webtestclient", ] + CORE_REQUIRED_DEPS + CORE_OPTIONAL_COMPILE_DEPS, ) diff --git a/src/libraries/java/nv-boot-parent/nv-boot-starter-data-migration-notification/BUILD.bazel b/src/libraries/java/nv-boot-parent/nv-boot-starter-data-migration-notification/BUILD.bazel index c02b707e1..0d0d3bee7 100644 --- a/src/libraries/java/nv-boot-parent/nv-boot-starter-data-migration-notification/BUILD.bazel +++ b/src/libraries/java/nv-boot-parent/nv-boot-starter-data-migration-notification/BUILD.bazel @@ -1,24 +1,24 @@ load("//tools/bazel:java.bzl", "nv_boot_library", "nv_boot_library_test") DATA_MIGRATION_NOTIFICATION_COMPILE_DEPS = [ - "@maven//:io_cloudevents_cloudevents_api", - "@maven//:io_cloudevents_cloudevents_core", - "@maven//:io_cloudevents_cloudevents_json_jackson", - "@maven//:io_nats_jnats", - "@maven//:jakarta_annotation_jakarta_annotation_api", - "@maven//:jakarta_validation_jakarta_validation_api", - "@maven//:org_apache_commons_commons_lang3", - "@maven//:org_slf4j_slf4j_api", - "@maven//:org_springframework_boot_spring_boot", - "@maven//:org_springframework_boot_spring_boot_autoconfigure", - "@maven//:org_springframework_boot_spring_boot_jackson", - "@maven//:org_springframework_boot_spring_boot_starter", - "@maven//:org_springframework_boot_spring_boot_starter_jackson", - "@maven//:org_springframework_boot_spring_boot_starter_validation", - "@maven//:org_springframework_spring_beans", - "@maven//:org_springframework_spring_context", - "@maven//:org_springframework_spring_core", - "@maven//:tools_jackson_core_jackson_databind", + "@nv_third_party_deps//:io_cloudevents_cloudevents_api", + "@nv_third_party_deps//:io_cloudevents_cloudevents_core", + "@nv_third_party_deps//:io_cloudevents_cloudevents_json_jackson", + "@nv_third_party_deps//:io_nats_jnats", + "@nv_third_party_deps//:jakarta_annotation_jakarta_annotation_api", + "@nv_third_party_deps//:jakarta_validation_jakarta_validation_api", + "@nv_third_party_deps//:org_apache_commons_commons_lang3", + "@nv_third_party_deps//:org_slf4j_slf4j_api", + "@nv_third_party_deps//:org_springframework_boot_spring_boot", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_autoconfigure", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_jackson", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_jackson", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_validation", + "@nv_third_party_deps//:org_springframework_spring_beans", + "@nv_third_party_deps//:org_springframework_spring_context", + "@nv_third_party_deps//:org_springframework_spring_core", + "@nv_third_party_deps//:tools_jackson_core_jackson_databind", ] nv_boot_library( @@ -36,6 +36,6 @@ nv_boot_library_test( coverage_library = ":nv_boot_starter_data_migration_notification", deps = [ ":nv_boot_starter_data_migration_notification", - "@maven//:org_springframework_boot_spring_boot_starter_test", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_test", ] + DATA_MIGRATION_NOTIFICATION_COMPILE_DEPS, ) diff --git a/src/libraries/java/nv-boot-parent/nv-boot-starter-exceptions/BUILD.bazel b/src/libraries/java/nv-boot-parent/nv-boot-starter-exceptions/BUILD.bazel index a3cc5ef8f..3171512e5 100644 --- a/src/libraries/java/nv-boot-parent/nv-boot-starter-exceptions/BUILD.bazel +++ b/src/libraries/java/nv-boot-parent/nv-boot-starter-exceptions/BUILD.bazel @@ -2,24 +2,24 @@ load("@rules_java//java:defs.bzl", "java_library") load("//tools/bazel:java.bzl", "nv_boot_library", "nv_boot_library_test", "nv_boot_runtime_classpath_test") EXCEPTIONS_REQUIRED_DEPS = [ - "@maven//:jakarta_annotation_jakarta_annotation_api", - "@maven//:org_slf4j_slf4j_api", + "@nv_third_party_deps//:jakarta_annotation_jakarta_annotation_api", + "@nv_third_party_deps//:org_slf4j_slf4j_api", ] # Maven marks the Spring MVC, WebFlux, Security, and autoconfiguration APIs as # optional/provided. They compile conditional handlers but must not select a # downstream application's web stack or security runtime. EXCEPTIONS_OPTIONAL_COMPILE_DEPS = [ - "@maven//:io_projectreactor_reactor_core", - "@maven//:org_jspecify_jspecify", - "@maven//:org_springframework_boot_spring_boot", - "@maven//:org_springframework_boot_spring_boot_autoconfigure", - "@maven//:org_springframework_security_spring_security_core", - "@maven//:org_springframework_spring_context", - "@maven//:org_springframework_spring_core", - "@maven//:org_springframework_spring_web", - "@maven//:org_springframework_spring_webflux", - "@maven//:org_springframework_spring_webmvc", + "@nv_third_party_deps//:io_projectreactor_reactor_core", + "@nv_third_party_deps//:org_jspecify_jspecify", + "@nv_third_party_deps//:org_springframework_boot_spring_boot", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_autoconfigure", + "@nv_third_party_deps//:org_springframework_security_spring_security_core", + "@nv_third_party_deps//:org_springframework_spring_context", + "@nv_third_party_deps//:org_springframework_spring_core", + "@nv_third_party_deps//:org_springframework_spring_web", + "@nv_third_party_deps//:org_springframework_spring_webflux", + "@nv_third_party_deps//:org_springframework_spring_webmvc", ] java_library( @@ -59,7 +59,7 @@ nv_boot_library_test( resources = glob(["src/test/resources/**"]), deps = [ ":nv_boot_starter_exceptions", - "@maven//:org_springframework_boot_spring_boot_starter_webflux_test", - "@maven//:org_springframework_boot_spring_boot_starter_webmvc_test", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_webflux_test", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_webmvc_test", ] + EXCEPTIONS_REQUIRED_DEPS + EXCEPTIONS_OPTIONAL_COMPILE_DEPS, ) diff --git a/src/libraries/java/nv-boot-parent/nv-boot-starter-jwt/BUILD.bazel b/src/libraries/java/nv-boot-parent/nv-boot-starter-jwt/BUILD.bazel index 622f23af8..dda0b65df 100644 --- a/src/libraries/java/nv-boot-parent/nv-boot-starter-jwt/BUILD.bazel +++ b/src/libraries/java/nv-boot-parent/nv-boot-starter-jwt/BUILD.bazel @@ -1,29 +1,29 @@ load("//tools/bazel:java.bzl", "nv_boot_library", "nv_boot_library_test") JWT_COMPILE_DEPS = [ - "@maven//:com_fasterxml_jackson_core_jackson_annotations", - "@maven//:com_github_ben_manes_caffeine_guava", - "@maven//:com_google_guava_guava", - "@maven//:com_nimbusds_nimbus_jose_jwt", - "@maven//:io_opentelemetry_opentelemetry_api", - "@maven//:org_apache_commons_commons_lang3", - "@maven//:org_bouncycastle_bcprov_jdk18on", - "@maven//:org_slf4j_slf4j_api", - "@maven//:org_springframework_boot_spring_boot", - "@maven//:org_springframework_boot_spring_boot_autoconfigure", - "@maven//:org_springframework_boot_spring_boot_jackson", - "@maven//:org_springframework_boot_spring_boot_starter", - "@maven//:org_springframework_boot_spring_boot_starter_jackson", - "@maven//:org_springframework_cloud_spring_cloud_context", - "@maven//:org_springframework_security_spring_security_oauth2_core", - "@maven//:org_springframework_security_spring_security_oauth2_jose", - "@maven//:org_springframework_spring_beans", - "@maven//:org_springframework_spring_context", - "@maven//:org_springframework_spring_core", - "@maven//:org_springframework_spring_web", - "@maven//:tools_jackson_core_jackson_core", - "@maven//:tools_jackson_core_jackson_databind", - "@maven//:tools_jackson_module_jackson_module_blackbird", + "@nv_third_party_deps//:com_fasterxml_jackson_core_jackson_annotations", + "@nv_third_party_deps//:com_github_ben_manes_caffeine_guava", + "@nv_third_party_deps//:com_google_guava_guava", + "@nv_third_party_deps//:com_nimbusds_nimbus_jose_jwt", + "@nv_third_party_deps//:io_opentelemetry_opentelemetry_api", + "@nv_third_party_deps//:org_apache_commons_commons_lang3", + "@nv_third_party_deps//:org_bouncycastle_bcprov_jdk18on", + "@nv_third_party_deps//:org_slf4j_slf4j_api", + "@nv_third_party_deps//:org_springframework_boot_spring_boot", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_autoconfigure", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_jackson", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_jackson", + "@nv_third_party_deps//:org_springframework_cloud_spring_cloud_context", + "@nv_third_party_deps//:org_springframework_security_spring_security_oauth2_core", + "@nv_third_party_deps//:org_springframework_security_spring_security_oauth2_jose", + "@nv_third_party_deps//:org_springframework_spring_beans", + "@nv_third_party_deps//:org_springframework_spring_context", + "@nv_third_party_deps//:org_springframework_spring_core", + "@nv_third_party_deps//:org_springframework_spring_web", + "@nv_third_party_deps//:tools_jackson_core_jackson_core", + "@nv_third_party_deps//:tools_jackson_core_jackson_databind", + "@nv_third_party_deps//:tools_jackson_module_jackson_module_blackbird", ] nv_boot_library( @@ -43,6 +43,6 @@ nv_boot_library_test( resources = glob(["src/test/resources/**"]), deps = [ ":nv_boot_starter_jwt", - "@maven//:org_springframework_boot_spring_boot_starter_webmvc_test", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_webmvc_test", ] + JWT_COMPILE_DEPS, ) diff --git a/src/libraries/java/nv-boot-parent/nv-boot-starter-observability/BUILD.bazel b/src/libraries/java/nv-boot-parent/nv-boot-starter-observability/BUILD.bazel index 0fcc1585a..fd238f454 100644 --- a/src/libraries/java/nv-boot-parent/nv-boot-starter-observability/BUILD.bazel +++ b/src/libraries/java/nv-boot-parent/nv-boot-starter-observability/BUILD.bazel @@ -2,51 +2,51 @@ load("@rules_java//java:defs.bzl", "java_library") load("//tools/bazel:java.bzl", "nv_boot_library", "nv_boot_library_test", "nv_boot_runtime_classpath_test") OBSERVABILITY_REQUIRED_DEPS = [ - "@maven//:ch_qos_logback_logback_classic", - "@maven//:ch_qos_logback_logback_core", - "@maven//:io_micrometer_micrometer_commons", - "@maven//:io_micrometer_micrometer_core", - "@maven//:io_micrometer_micrometer_observation", - "@maven//:io_micrometer_micrometer_tracing", - "@maven//:io_micrometer_micrometer_tracing_bridge_otel", - "@maven//:io_opentelemetry_opentelemetry_api", - "@maven//:io_opentelemetry_opentelemetry_sdk_common", - "@maven//:io_opentelemetry_opentelemetry_sdk_trace", - "@maven//:io_opentelemetry_semconv_opentelemetry_semconv", - "@maven//:org_apache_commons_commons_lang3", - "@maven//:org_slf4j_slf4j_api", - "@maven//:org_springframework_boot_spring_boot", - "@maven//:org_springframework_boot_spring_boot_actuator", - "@maven//:org_springframework_boot_spring_boot_actuator_autoconfigure", - "@maven//:org_springframework_boot_spring_boot_autoconfigure", - "@maven//:org_springframework_boot_spring_boot_health", - "@maven//:org_springframework_boot_spring_boot_micrometer_metrics", - "@maven//:org_springframework_boot_spring_boot_micrometer_observation", - "@maven//:org_springframework_boot_spring_boot_micrometer_tracing", - "@maven//:org_springframework_boot_spring_boot_micrometer_tracing_opentelemetry", - "@maven//:org_springframework_boot_spring_boot_opentelemetry", - "@maven//:org_springframework_boot_spring_boot_starter_actuator", - "@maven//:org_springframework_spring_beans", - "@maven//:org_springframework_spring_context", - "@maven//:org_springframework_spring_core", + "@nv_third_party_deps//:ch_qos_logback_logback_classic", + "@nv_third_party_deps//:ch_qos_logback_logback_core", + "@nv_third_party_deps//:io_micrometer_micrometer_commons", + "@nv_third_party_deps//:io_micrometer_micrometer_core", + "@nv_third_party_deps//:io_micrometer_micrometer_observation", + "@nv_third_party_deps//:io_micrometer_micrometer_tracing", + "@nv_third_party_deps//:io_micrometer_micrometer_tracing_bridge_otel", + "@nv_third_party_deps//:io_opentelemetry_opentelemetry_api", + "@nv_third_party_deps//:io_opentelemetry_opentelemetry_sdk_common", + "@nv_third_party_deps//:io_opentelemetry_opentelemetry_sdk_trace", + "@nv_third_party_deps//:io_opentelemetry_semconv_opentelemetry_semconv", + "@nv_third_party_deps//:org_apache_commons_commons_lang3", + "@nv_third_party_deps//:org_slf4j_slf4j_api", + "@nv_third_party_deps//:org_springframework_boot_spring_boot", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_actuator", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_actuator_autoconfigure", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_autoconfigure", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_health", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_micrometer_metrics", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_micrometer_observation", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_micrometer_tracing", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_micrometer_tracing_opentelemetry", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_opentelemetry", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_actuator", + "@nv_third_party_deps//:org_springframework_spring_beans", + "@nv_third_party_deps//:org_springframework_spring_context", + "@nv_third_party_deps//:org_springframework_spring_core", ] # Cassandra, Spring Cloud, servlet, MVC, and WebFlux support is optional in the # Maven POM. Keep those APIs available to compile/test conditional integration # code without adding those frameworks to every downstream runtime classpath. OBSERVABILITY_OPTIONAL_COMPILE_DEPS = [ - "@maven//:jakarta_servlet_jakarta_servlet_api", - "@maven//:org_apache_cassandra_java_driver_core", - "@maven//:org_apache_cassandra_java_driver_guava_shaded", - "@maven//:org_springframework_boot_spring_boot_cassandra", - "@maven//:org_springframework_boot_spring_boot_data_cassandra", - "@maven//:org_springframework_boot_spring_boot_starter_data_cassandra", - "@maven//:org_springframework_boot_spring_boot_web_server", - "@maven//:org_springframework_cloud_spring_cloud_commons", - "@maven//:org_springframework_data_spring_data_cassandra", - "@maven//:org_springframework_spring_web", - "@maven//:org_springframework_spring_webflux", - "@maven//:org_springframework_spring_webmvc", + "@nv_third_party_deps//:jakarta_servlet_jakarta_servlet_api", + "@nv_third_party_deps//:org_apache_cassandra_java_driver_core", + "@nv_third_party_deps//:org_apache_cassandra_java_driver_guava_shaded", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_cassandra", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_data_cassandra", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_data_cassandra", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_web_server", + "@nv_third_party_deps//:org_springframework_cloud_spring_cloud_commons", + "@nv_third_party_deps//:org_springframework_data_spring_data_cassandra", + "@nv_third_party_deps//:org_springframework_spring_web", + "@nv_third_party_deps//:org_springframework_spring_webflux", + "@nv_third_party_deps//:org_springframework_spring_webmvc", ] java_library( @@ -88,14 +88,14 @@ nv_boot_library_test( resources = glob(["src/test/resources/**"]), deps = [ ":nv_boot_starter_observability", - "@maven//:io_opentelemetry_opentelemetry_sdk_testing", - "@maven//:org_awaitility_awaitility", - "@maven//:org_springframework_boot_spring_boot_restclient", - "@maven//:org_springframework_boot_spring_boot_resttestclient", - "@maven//:org_springframework_boot_spring_boot_starter_actuator_test", - "@maven//:org_springframework_boot_spring_boot_starter_webflux_test", - "@maven//:org_springframework_boot_spring_boot_starter_webmvc_test", - "@maven//:org_springframework_boot_spring_boot_webmvc_test", + "@nv_third_party_deps//:io_opentelemetry_opentelemetry_sdk_testing", + "@nv_third_party_deps//:org_awaitility_awaitility", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_restclient", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_resttestclient", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_actuator_test", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_webflux_test", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_webmvc_test", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_webmvc_test", ] + OBSERVABILITY_REQUIRED_DEPS + OBSERVABILITY_OPTIONAL_COMPILE_DEPS, size = "medium", timeout = "moderate", diff --git a/src/libraries/java/nv-boot-parent/nv-boot-starter-registries/BUILD.bazel b/src/libraries/java/nv-boot-parent/nv-boot-starter-registries/BUILD.bazel index 8fe4515cb..2fcfb9745 100644 --- a/src/libraries/java/nv-boot-parent/nv-boot-starter-registries/BUILD.bazel +++ b/src/libraries/java/nv-boot-parent/nv-boot-starter-registries/BUILD.bazel @@ -2,47 +2,47 @@ load("//tools/bazel:java.bzl", "nv_boot_library", "nv_boot_library_test") REGISTRIES_COMPILE_DEPS = [ "//nv-boot-starter-exceptions:nv_boot_starter_exceptions", - "@maven//:com_fasterxml_jackson_core_jackson_annotations", - "@maven//:com_github_ben_manes_caffeine_caffeine", - "@maven//:com_github_ben_manes_caffeine_guava", - "@maven//:com_google_guava_guava", - "@maven//:com_nimbusds_nimbus_jose_jwt", - "@maven//:commons_codec_commons_codec", - "@maven//:io_micrometer_micrometer_commons", - "@maven//:io_netty_netty_common", - "@maven//:io_netty_netty_handler", - "@maven//:io_netty_netty_transport", - "@maven//:io_projectreactor_netty_reactor_netty_core", - "@maven//:io_projectreactor_netty_reactor_netty_http", - "@maven//:io_projectreactor_reactor_core", - "@maven//:jakarta_annotation_jakarta_annotation_api", - "@maven//:jakarta_validation_jakarta_validation_api", - "@maven//:org_apache_commons_commons_lang3", - "@maven//:org_apache_logging_log4j_log4j_api", - "@maven//:org_jspecify_jspecify", - "@maven//:org_slf4j_slf4j_api", - "@maven//:org_springframework_boot_spring_boot", - "@maven//:org_springframework_boot_spring_boot_autoconfigure", - "@maven//:org_springframework_boot_spring_boot_jackson", - "@maven//:org_springframework_boot_spring_boot_starter_jackson", - "@maven//:org_springframework_boot_spring_boot_starter_security_oauth2_client", - "@maven//:org_springframework_boot_spring_boot_starter_validation", - "@maven//:org_springframework_boot_spring_boot_webclient", - "@maven//:org_springframework_cloud_spring_cloud_context", - "@maven//:org_springframework_security_spring_security_config", - "@maven//:org_springframework_security_spring_security_core", - "@maven//:org_springframework_security_spring_security_oauth2_client", - "@maven//:org_springframework_security_spring_security_oauth2_core", - "@maven//:org_springframework_security_spring_security_oauth2_jose", - "@maven//:org_springframework_security_spring_security_web", - "@maven//:org_springframework_spring_beans", - "@maven//:org_springframework_spring_context", - "@maven//:org_springframework_spring_core", - "@maven//:org_springframework_spring_web", - "@maven//:org_springframework_spring_webflux", - "@maven//:software_amazon_awssdk_regions", - "@maven//:tools_jackson_core_jackson_core", - "@maven//:tools_jackson_core_jackson_databind", + "@nv_third_party_deps//:com_fasterxml_jackson_core_jackson_annotations", + "@nv_third_party_deps//:com_github_ben_manes_caffeine_caffeine", + "@nv_third_party_deps//:com_github_ben_manes_caffeine_guava", + "@nv_third_party_deps//:com_google_guava_guava", + "@nv_third_party_deps//:com_nimbusds_nimbus_jose_jwt", + "@nv_third_party_deps//:commons_codec_commons_codec", + "@nv_third_party_deps//:io_micrometer_micrometer_commons", + "@nv_third_party_deps//:io_netty_netty_common", + "@nv_third_party_deps//:io_netty_netty_handler", + "@nv_third_party_deps//:io_netty_netty_transport", + "@nv_third_party_deps//:io_projectreactor_netty_reactor_netty_core", + "@nv_third_party_deps//:io_projectreactor_netty_reactor_netty_http", + "@nv_third_party_deps//:io_projectreactor_reactor_core", + "@nv_third_party_deps//:jakarta_annotation_jakarta_annotation_api", + "@nv_third_party_deps//:jakarta_validation_jakarta_validation_api", + "@nv_third_party_deps//:org_apache_commons_commons_lang3", + "@nv_third_party_deps//:org_apache_logging_log4j_log4j_api", + "@nv_third_party_deps//:org_jspecify_jspecify", + "@nv_third_party_deps//:org_slf4j_slf4j_api", + "@nv_third_party_deps//:org_springframework_boot_spring_boot", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_autoconfigure", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_jackson", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_jackson", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_security_oauth2_client", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_validation", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_webclient", + "@nv_third_party_deps//:org_springframework_cloud_spring_cloud_context", + "@nv_third_party_deps//:org_springframework_security_spring_security_config", + "@nv_third_party_deps//:org_springframework_security_spring_security_core", + "@nv_third_party_deps//:org_springframework_security_spring_security_oauth2_client", + "@nv_third_party_deps//:org_springframework_security_spring_security_oauth2_core", + "@nv_third_party_deps//:org_springframework_security_spring_security_oauth2_jose", + "@nv_third_party_deps//:org_springframework_security_spring_security_web", + "@nv_third_party_deps//:org_springframework_spring_beans", + "@nv_third_party_deps//:org_springframework_spring_context", + "@nv_third_party_deps//:org_springframework_spring_core", + "@nv_third_party_deps//:org_springframework_spring_web", + "@nv_third_party_deps//:org_springframework_spring_webflux", + "@nv_third_party_deps//:software_amazon_awssdk_regions", + "@nv_third_party_deps//:tools_jackson_core_jackson_core", + "@nv_third_party_deps//:tools_jackson_core_jackson_databind", ] nv_boot_library( @@ -63,8 +63,8 @@ nv_boot_library_test( deps = [ ":nv_boot_starter_registries", "//nv-boot-mock-servers-test:nv_boot_mock_servers_test", - "@maven//:org_springframework_boot_spring_boot_starter_webflux_test", - "@maven//:org_wiremock_wiremock_standalone", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_webflux_test", + "@nv_third_party_deps//:org_wiremock_wiremock_standalone", ] + REGISTRIES_COMPILE_DEPS, size = "medium", tags = ["exclusive"], diff --git a/src/libraries/java/nv-boot-parent/nv-boot-starter-registries/src/main/java/com/nvidia/boot/registries/service/registry/client/ngc/NgcArtifactRegistryClient.java b/src/libraries/java/nv-boot-parent/nv-boot-starter-registries/src/main/java/com/nvidia/boot/registries/service/registry/client/ngc/NgcArtifactRegistryClient.java index bcb02575d..af689f3f9 100644 --- a/src/libraries/java/nv-boot-parent/nv-boot-starter-registries/src/main/java/com/nvidia/boot/registries/service/registry/client/ngc/NgcArtifactRegistryClient.java +++ b/src/libraries/java/nv-boot-parent/nv-boot-starter-registries/src/main/java/com/nvidia/boot/registries/service/registry/client/ngc/NgcArtifactRegistryClient.java @@ -64,8 +64,7 @@ public class NgcArtifactRegistryClient { "Null response from getting token from registry %s"; private static final int PAGE_SIZE = 100; private static final long OAUTH_TTL_IN_SECONDS = 900; // 15 minutes - // The Regex is inspired from NGC helm service implementation - // https://gitlab-master.nvidia.com/ngc/cloud/helmchart-registry/-/blob/main/internal/proxy/helm_registry_proxy.go?ref_type=heads#L75 + // The Regex is inspired from the NGC helm service implementation. private static final String NGC_HELM_CHART_VERSION_URL_REGEX = "^(?:/api)?/(?<namespace>[^/]+(?:/[^/]+)?)/charts/(?<chartName>[a-zA-Z0-9-_]+)-(?<version>v?\\d+(\\.\\d+){0,2}([-+][\\w.+-]+)?)\\.tgz(?:\\.prov)?$"; private static final Pattern HELM_CHART_VERSION_URL_REGEX_PATTERN = diff --git a/src/libraries/java/nv-boot-parent/nv-boot-starter-reloadable-properties/BUILD.bazel b/src/libraries/java/nv-boot-parent/nv-boot-starter-reloadable-properties/BUILD.bazel index 072c9e01d..2bb6601b2 100644 --- a/src/libraries/java/nv-boot-parent/nv-boot-starter-reloadable-properties/BUILD.bazel +++ b/src/libraries/java/nv-boot-parent/nv-boot-starter-reloadable-properties/BUILD.bazel @@ -1,18 +1,18 @@ load("//tools/bazel:java.bzl", "nv_boot_library", "nv_boot_library_test", "nv_boot_workspace_runfiles") RELOADABLE_PROPERTIES_COMPILE_DEPS = [ - "@maven//:com_github_ben_manes_caffeine_guava", - "@maven//:com_google_guava_guava", - "@maven//:jakarta_annotation_jakarta_annotation_api", - "@maven//:org_apache_commons_commons_lang3", - "@maven//:org_slf4j_slf4j_api", - "@maven//:org_springframework_boot_spring_boot", - "@maven//:org_springframework_boot_spring_boot_autoconfigure", - "@maven//:org_springframework_cloud_spring_cloud_context", - "@maven//:org_springframework_cloud_spring_cloud_starter_bootstrap", - "@maven//:org_springframework_spring_beans", - "@maven//:org_springframework_spring_context", - "@maven//:org_springframework_spring_core", + "@nv_third_party_deps//:com_github_ben_manes_caffeine_guava", + "@nv_third_party_deps//:com_google_guava_guava", + "@nv_third_party_deps//:jakarta_annotation_jakarta_annotation_api", + "@nv_third_party_deps//:org_apache_commons_commons_lang3", + "@nv_third_party_deps//:org_slf4j_slf4j_api", + "@nv_third_party_deps//:org_springframework_boot_spring_boot", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_autoconfigure", + "@nv_third_party_deps//:org_springframework_cloud_spring_cloud_context", + "@nv_third_party_deps//:org_springframework_cloud_spring_cloud_starter_bootstrap", + "@nv_third_party_deps//:org_springframework_spring_beans", + "@nv_third_party_deps//:org_springframework_spring_context", + "@nv_third_party_deps//:org_springframework_spring_core", ] filegroup( @@ -45,9 +45,9 @@ nv_boot_library_test( resources = glob(["src/test/resources/**"]), deps = [ ":nv_boot_starter_reloadable_properties", - "@maven//:org_springframework_boot_spring_boot_jackson", - "@maven//:org_springframework_boot_spring_boot_starter_jackson", - "@maven//:org_springframework_boot_spring_boot_starter_webmvc_test", - "@maven//:tools_jackson_core_jackson_databind", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_jackson", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_jackson", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_webmvc_test", + "@nv_third_party_deps//:tools_jackson_core_jackson_databind", ] + RELOADABLE_PROPERTIES_COMPILE_DEPS, ) diff --git a/src/libraries/java/nv-boot-parent/nv-boot-starter-telemetry/BUILD.bazel b/src/libraries/java/nv-boot-parent/nv-boot-starter-telemetry/BUILD.bazel index 42d454c30..ef45217e6 100644 --- a/src/libraries/java/nv-boot-parent/nv-boot-starter-telemetry/BUILD.bazel +++ b/src/libraries/java/nv-boot-parent/nv-boot-starter-telemetry/BUILD.bazel @@ -1,30 +1,30 @@ load("//tools/bazel:java.bzl", "nv_boot_library", "nv_boot_library_test") TELEMETRY_COMPILE_DEPS = [ - "@maven//:io_cloudevents_cloudevents_api", - "@maven//:io_cloudevents_cloudevents_core", - "@maven//:io_cloudevents_cloudevents_json_jackson", - "@maven//:io_netty_netty_common", - "@maven//:io_netty_netty_transport", - "@maven//:io_projectreactor_netty_reactor_netty_http", - "@maven//:io_projectreactor_reactor_core", - "@maven//:jakarta_validation_jakarta_validation_api", - "@maven//:org_apache_commons_commons_lang3", - "@maven//:org_slf4j_slf4j_api", - "@maven//:org_springframework_boot_spring_boot", - "@maven//:org_springframework_boot_spring_boot_autoconfigure", - "@maven//:org_springframework_boot_spring_boot_jackson", - "@maven//:org_springframework_boot_spring_boot_starter", - "@maven//:org_springframework_boot_spring_boot_starter_jackson", - "@maven//:org_springframework_boot_spring_boot_starter_validation", - "@maven//:org_springframework_boot_spring_boot_starter_webflux", - "@maven//:org_springframework_security_spring_security_core", - "@maven//:org_springframework_spring_beans", - "@maven//:org_springframework_spring_context", - "@maven//:org_springframework_spring_core", - "@maven//:org_springframework_spring_web", - "@maven//:org_springframework_spring_webflux", - "@maven//:tools_jackson_core_jackson_databind", + "@nv_third_party_deps//:io_cloudevents_cloudevents_api", + "@nv_third_party_deps//:io_cloudevents_cloudevents_core", + "@nv_third_party_deps//:io_cloudevents_cloudevents_json_jackson", + "@nv_third_party_deps//:io_netty_netty_common", + "@nv_third_party_deps//:io_netty_netty_transport", + "@nv_third_party_deps//:io_projectreactor_netty_reactor_netty_http", + "@nv_third_party_deps//:io_projectreactor_reactor_core", + "@nv_third_party_deps//:jakarta_validation_jakarta_validation_api", + "@nv_third_party_deps//:org_apache_commons_commons_lang3", + "@nv_third_party_deps//:org_slf4j_slf4j_api", + "@nv_third_party_deps//:org_springframework_boot_spring_boot", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_autoconfigure", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_jackson", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_jackson", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_validation", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_webflux", + "@nv_third_party_deps//:org_springframework_security_spring_security_core", + "@nv_third_party_deps//:org_springframework_spring_beans", + "@nv_third_party_deps//:org_springframework_spring_context", + "@nv_third_party_deps//:org_springframework_spring_core", + "@nv_third_party_deps//:org_springframework_spring_web", + "@nv_third_party_deps//:org_springframework_spring_webflux", + "@nv_third_party_deps//:tools_jackson_core_jackson_databind", ] nv_boot_library( @@ -42,10 +42,10 @@ nv_boot_library_test( coverage_library = ":nv_boot_starter_telemetry", deps = [ ":nv_boot_starter_telemetry", - "@maven//:org_hibernate_validator_hibernate_validator", - "@maven//:org_springframework_boot_spring_boot_starter_webflux_test", - "@maven//:org_springframework_security_spring_security_test", - "@maven//:org_wiremock_wiremock_standalone", + "@nv_third_party_deps//:org_hibernate_validator_hibernate_validator", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_webflux_test", + "@nv_third_party_deps//:org_springframework_security_spring_security_test", + "@nv_third_party_deps//:org_wiremock_wiremock_standalone", ] + TELEMETRY_COMPILE_DEPS, size = "medium", timeout = "moderate", diff --git a/src/libraries/java/nv-boot-parent/pom.xml b/src/libraries/java/nv-boot-parent/pom.xml index 96500c265..d7d223ac4 100644 --- a/src/libraries/java/nv-boot-parent/pom.xml +++ b/src/libraries/java/nv-boot-parent/pom.xml @@ -62,23 +62,23 @@ </properties> <scm> - <url>https://gitlab-master.nvidia.com/nvcf/nvcf-libraries/java/nv-boot-parent</url> + <url>https://github.com/NVIDIA/nvcf</url> </scm> <repositories> - <!-- Internal Maven2 Mirror --> + <!-- GCS Maven Central mirror --> <repository> - <id>nv-central</id> - <url>https://urm.nvidia.com/artifactory/maven</url> + <id>google-maven-central</id> + <name>GCS Maven Central mirror</name> + <url>https://maven-central.storage-download.googleapis.com/maven2</url> <snapshots> <enabled>false</enabled> </snapshots> </repository> - <!-- GCS Maven2 Mirror as our URM mirror is causing 429s --> + <!-- Maven Central --> <repository> - <id>google-maven-central</id> - <name>GCS Maven Central mirror</name> - <url>https://maven-central.storage-download.googleapis.com/maven2</url> + <id>maven-central</id> + <url>https://repo.maven.apache.org/maven2</url> <snapshots> <enabled>false</enabled> </snapshots> @@ -86,37 +86,25 @@ </repositories> <pluginRepositories> - <!-- Internal Maven2 Mirror --> + <!-- GCS Maven Central mirror --> <pluginRepository> - <id>nv-central</id> - <url>https://urm.nvidia.com/artifactory/maven</url> + <id>google-maven-central</id> + <name>GCS Maven Central mirror</name> + <url>https://maven-central.storage-download.googleapis.com/maven2</url> <snapshots> <enabled>false</enabled> </snapshots> </pluginRepository> - <!-- GCS Maven2 Mirror as our URM mirror is causing 429s --> + <!-- Maven Central --> <pluginRepository> - <id>google-maven-central</id> - <name>GCS Maven Central mirror</name> - <url>https://maven-central.storage-download.googleapis.com/maven2</url> + <id>maven-central</id> + <url>https://repo.maven.apache.org/maven2</url> <snapshots> <enabled>false</enabled> </snapshots> </pluginRepository> </pluginRepositories> - <distributionManagement> - <!-- Publish jars to URM for time being. --> - <repository> - <id>nvcf</id> - <url>https://urm.nvidia.com/artifactory/sw-nvcf-maven</url> - </repository> - <snapshotRepository> - <id>nvcf</id> - <url>https://urm.nvidia.com/artifactory/sw-nvcf-maven</url> - </snapshotRepository> - </distributionManagement> - <modules> <module>nv-boot-bom</module> <module>nv-boot-mock-servers-test</module> diff --git a/src/libraries/java/nv-boot-parent/tools/bazel/BUILD.bazel b/src/libraries/java/nv-boot-parent/tools/bazel/BUILD.bazel index 114bc1153..b8494a40f 100644 --- a/src/libraries/java/nv-boot-parent/tools/bazel/BUILD.bazel +++ b/src/libraries/java/nv-boot-parent/tools/bazel/BUILD.bazel @@ -32,9 +32,6 @@ sh_test( ":generate_notice.py", ":notice_metadata.json", "//:MODULE.bazel", - # nv-boot-parent's own NOTICE (its Java closure), not the aggregate root - # NOTICE which also covers the Go/Rust subtrees and can never match a - # Java-only regeneration. "//:NOTICE", "//:maven_install.json", ":notice_roots.json", @@ -45,17 +42,17 @@ java_plugin( name = "lombok_plugin", generates_api = True, processor_class = "lombok.launch.AnnotationProcessorHider$AnnotationProcessor", - deps = ["@maven//:org_projectlombok_lombok"], + deps = ["@nv_third_party_deps//:org_projectlombok_lombok"], ) java_binary( name = "jacoco_cli", main_class = "org.jacoco.cli.internal.Main", - runtime_deps = ["@maven//:org_jacoco_org_jacoco_cli"], + runtime_deps = ["@nv_third_party_deps//:org_jacoco_org_jacoco_cli"], ) java_library( name = "lombok_annotations", - exports = ["@maven//:org_projectlombok_lombok"], + exports = ["@nv_third_party_deps//:org_projectlombok_lombok"], neverlink = True, ) diff --git a/src/libraries/java/nv-boot-parent/tools/bazel/java.bzl b/src/libraries/java/nv-boot-parent/tools/bazel/java.bzl index 733097dd0..80ff0cd80 100644 --- a/src/libraries/java/nv-boot-parent/tools/bazel/java.bzl +++ b/src/libraries/java/nv-boot-parent/tools/bazel/java.bzl @@ -24,21 +24,21 @@ NV_JUNIT5_ARGS = [ ] NV_JUNIT5_RUNTIME_DEPS = [ - "@maven//:org_junit_platform_junit_platform_console_standalone", + "@nv_third_party_deps//:org_junit_platform_junit_platform_console_standalone", ] NV_JUNIT5_COMPILE_DEPS = [ - "@maven//:org_assertj_assertj_core", - "@maven//:org_junit_jupiter_junit_jupiter_api", - "@maven//:org_junit_jupiter_junit_jupiter_params", - "@maven//:org_mockito_mockito_core", - "@maven//:org_mockito_mockito_junit_jupiter", - "@maven//:org_springframework_boot_spring_boot_test", - "@maven//:org_springframework_boot_spring_boot_test_autoconfigure", - "@maven//:org_springframework_spring_test", + "@nv_third_party_deps//:org_assertj_assertj_core", + "@nv_third_party_deps//:org_junit_jupiter_junit_jupiter_api", + "@nv_third_party_deps//:org_junit_jupiter_junit_jupiter_params", + "@nv_third_party_deps//:org_mockito_mockito_core", + "@nv_third_party_deps//:org_mockito_mockito_junit_jupiter", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_test", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_test_autoconfigure", + "@nv_third_party_deps//:org_springframework_spring_test", ] -NV_MOCKITO_CORE = "@maven//:org_mockito_mockito_core" +NV_MOCKITO_CORE = "@nv_third_party_deps//:org_mockito_mockito_core" NV_MOCKITO_AGENT_DATA = [ NV_MOCKITO_CORE, @@ -48,7 +48,7 @@ NV_MOCKITO_AGENT_JVM_FLAGS = [ "-javaagent:$(location %s)" % NV_MOCKITO_CORE, ] -NV_JACOCO_AGENT = "@maven//:org_jacoco_org_jacoco_agent_runtime" +NV_JACOCO_AGENT = "@nv_third_party_deps//:org_jacoco_org_jacoco_agent_runtime" NV_JACOCO_AGENT_DATA = [ NV_JACOCO_AGENT, diff --git a/src/libraries/java/nv-boot-parent/tools/bazel/notice_check_test.sh b/src/libraries/java/nv-boot-parent/tools/bazel/notice_check_test.sh index 527fffd71..13033e0b0 100755 --- a/src/libraries/java/nv-boot-parent/tools/bazel/notice_check_test.sh +++ b/src/libraries/java/nv-boot-parent/tools/bazel/notice_check_test.sh @@ -46,12 +46,8 @@ find_workspace() { } workspace="$(find_workspace)" -# nv-boot-parent is its own standalone Bazel module: its module root is the -# nv-boot-parent directory, so the notice tooling, its NOTICE, and its -# maven_install.json all live at the workspace root. -nvboot="${workspace}" -PYTHONPATH="${nvboot}/tools/bazel" python3 - <<'PY' +PYTHONPATH="${workspace}/tools/bazel" python3 - <<'PY' import pathlib import tempfile import zipfile @@ -100,9 +96,9 @@ with tempfile.TemporaryDirectory() as directory: raise AssertionError("Runtime NOTICE accepted a stale lockfile version") PY -exec python3 "${nvboot}/tools/bazel/generate_notice.py" \ +exec python3 "${workspace}/tools/bazel/generate_notice.py" \ --maven-install "${workspace}/maven_install.json" \ - --metadata "${nvboot}/tools/bazel/notice_metadata.json" \ - --notice "${nvboot}/NOTICE" \ - --root-manifest "${nvboot}/tools/bazel/notice_roots.json" \ + --metadata "${workspace}/tools/bazel/notice_metadata.json" \ + --notice "${workspace}/NOTICE" \ + --root-manifest "${workspace}/tools/bazel/notice_roots.json" \ --check From 5c7cfc8b8174d2b9b609d00918065c1048f46565 Mon Sep 17 00:00:00 2001 From: Balaji Ganesan <bganesan@nvidia.com> Date: Thu, 23 Jul 2026 11:34:38 -0700 Subject: [PATCH 15/29] refactor(java): fold nv-boot-parent + cloud-tasks into the single root Bazel module per monorepo architecture Re-architects the Java Bazel integration to match the canonical monorepo design in nv-boot-parent's bazel-enablement/github-monorepo-architecture.md. Previously nv-boot-parent and cloud-tasks were nested independent Bazel modules (each with its own MODULE.bazel, maven_install.json, .bazelrc, and nv_third_party_deps hub), which splits those directories out of the root module. This folds them into plain source directories of the single root "nvcf" module. - Delete the nested boundary files (MODULE.bazel, MODULE.bazel.lock, maven_install.json, .bazelrc, .bazelversion, .bazelignore, .bazel_downloader_config) from both service directories. - The root MODULE.bazel owns the single nv_third_party_deps hub with the merged artifact + BOM union and the single root maven_install.json. All BOMs (spring-boot-dependencies 4.0.7, spring-cloud-dependencies 2025.1.2, testcontainers-bom 2.0.5, shedlock-bom 7.7.0) and explicit version pins are declared exactly once at the root; service coordinates stay versionless. Add rules_spring as a root bazel_dep. - Move reusable Starlark macros to root //rules/java (defs.bzl, spring.bzl, proto.bzl) and executable helpers + shared build targets to //tools/bazel/java. Rewrite every service BUILD.bazel to load from //rules/java, reference @nv_third_party_deps//:... and direct //src/... first-party labels. Remove all @maven, @nv_boot_parent, bazel_dep(nv_boot), and local_path_override references. - Root .bazelrc: Java 25 language + local_jdk runtimes, --java_header_compilation=false, --incompatible_autoload_externally=+@rules_java, and one root .bazel_downloader_config. Un-ignore the two Java trees and tools/ in .bazelignore so the folded packages are loadable. Co-authored-by: Balaji Ganesan <bganesan@nvidia.com> --- ...nloader_config => .bazel_downloader_config | 0 .bazelignore | 17 +- .bazelrc | 24 +- BUILD.bazel | 9 +- MODULE.bazel | 4 + MODULE.bazel.lock | 4 + rules/java/BUILD.bazel | 2 + rules/java/defs.bzl | 332 + .../tools/bazel => rules/java}/proto.bzl | 2 +- .../spring_boot.bzl => rules/java/spring.bzl | 0 .../cloud-tasks/.bazelignore | 4 - .../cloud-tasks/.bazelrc | 14 - .../cloud-tasks/.bazelversion | 1 - .../cloud-tasks/BUILD.bazel | 37 +- .../cloud-tasks/MODULE.bazel | 173 - .../cloud-tasks/MODULE.bazel.lock | 954 -- .../{tools/bazel => }/generate_notice.sh | 4 +- .../cloud-tasks/maven_install.json | 11690 ---------------- .../{tools/bazel => }/notice_metadata.json | 0 .../cloud-tasks/nvct-core/BUILD.bazel | 40 +- .../cloud-tasks/nvct-service/BUILD.bazel | 18 +- .../cloud-tasks/tools/bazel/java.bzl | 177 - .../tools/bazel/notice_check_test.sh | 21 - .../tools/bazel/workspace_status.sh | 20 - src/libraries/java/nv-boot-parent/.bazelrc | 9 - .../java/nv-boot-parent/.bazelversion | 1 - src/libraries/java/nv-boot-parent/BUILD.bazel | 42 +- .../java/nv-boot-parent/MODULE.bazel | 105 - .../java/nv-boot-parent/MODULE.bazel.lock | 808 -- .../java/nv-boot-parent/maven_install.json | 10040 ------------- .../{tools/bazel => }/notice_metadata.json | 0 .../{tools/bazel => }/notice_roots.json | 0 .../nv-boot-mock-servers-test/BUILD.bazel | 2 +- .../nv-boot-starter-audit/BUILD.bazel | 4 +- .../nv-boot-starter-cassandra/BUILD.bazel | 6 +- .../nv-boot-starter-core/BUILD.bazel | 6 +- .../BUILD.bazel | 4 +- .../nv-boot-starter-exceptions/BUILD.bazel | 6 +- .../nv-boot-starter-jwt/BUILD.bazel | 6 +- .../nv-boot-starter-observability/BUILD.bazel | 6 +- .../nv-boot-starter-registries/BUILD.bazel | 10 +- .../BUILD.bazel | 8 +- .../nv-boot-starter-telemetry/BUILD.bazel | 4 +- .../nv-boot-parent/tools/bazel/BUILD.bazel | 58 - .../tools/bazel/jacoco_test_runner.sh | 77 - .../java/nv-boot-parent/tools/bazel/java.bzl | 210 - .../tools/bazel/notice_check_test.sh | 104 - .../bazel => tools/bazel/java}/BUILD.bazel | 70 +- .../bazel/java}/generate_notice.py | 0 .../bazel/java}/jacoco_test_runner.sh | 0 .../bazel/java}/lcov_to_sonar_generic.py | 0 .../bazel/java}/lcov_to_sonar_generic_test.sh | 0 tools/workspace_status.sh | 12 + 53 files changed, 538 insertions(+), 24607 deletions(-) rename src/control-plane-services/cloud-tasks/.bazel_downloader_config => .bazel_downloader_config (100%) create mode 100644 rules/java/BUILD.bazel create mode 100644 rules/java/defs.bzl rename {src/control-plane-services/cloud-tasks/tools/bazel => rules/java}/proto.bzl (92%) rename src/control-plane-services/cloud-tasks/tools/bazel/spring_boot.bzl => rules/java/spring.bzl (100%) delete mode 100644 src/control-plane-services/cloud-tasks/.bazelignore delete mode 100644 src/control-plane-services/cloud-tasks/.bazelrc delete mode 100644 src/control-plane-services/cloud-tasks/.bazelversion delete mode 100644 src/control-plane-services/cloud-tasks/MODULE.bazel delete mode 100644 src/control-plane-services/cloud-tasks/MODULE.bazel.lock rename src/control-plane-services/cloud-tasks/{tools/bazel => }/generate_notice.sh (79%) delete mode 100644 src/control-plane-services/cloud-tasks/maven_install.json rename src/control-plane-services/cloud-tasks/{tools/bazel => }/notice_metadata.json (100%) delete mode 100644 src/control-plane-services/cloud-tasks/tools/bazel/java.bzl delete mode 100755 src/control-plane-services/cloud-tasks/tools/bazel/notice_check_test.sh delete mode 100755 src/control-plane-services/cloud-tasks/tools/bazel/workspace_status.sh delete mode 100644 src/libraries/java/nv-boot-parent/.bazelrc delete mode 100644 src/libraries/java/nv-boot-parent/.bazelversion delete mode 100644 src/libraries/java/nv-boot-parent/MODULE.bazel delete mode 100644 src/libraries/java/nv-boot-parent/MODULE.bazel.lock delete mode 100644 src/libraries/java/nv-boot-parent/maven_install.json rename src/libraries/java/nv-boot-parent/{tools/bazel => }/notice_metadata.json (100%) rename src/libraries/java/nv-boot-parent/{tools/bazel => }/notice_roots.json (100%) delete mode 100644 src/libraries/java/nv-boot-parent/tools/bazel/BUILD.bazel delete mode 100755 src/libraries/java/nv-boot-parent/tools/bazel/jacoco_test_runner.sh delete mode 100644 src/libraries/java/nv-boot-parent/tools/bazel/java.bzl delete mode 100755 src/libraries/java/nv-boot-parent/tools/bazel/notice_check_test.sh rename {src/control-plane-services/cloud-tasks/tools/bazel => tools/bazel/java}/BUILD.bazel (61%) rename {src/libraries/java/nv-boot-parent/tools/bazel => tools/bazel/java}/generate_notice.py (100%) rename {src/control-plane-services/cloud-tasks/tools/bazel => tools/bazel/java}/jacoco_test_runner.sh (100%) rename {src/libraries/java/nv-boot-parent/tools/bazel => tools/bazel/java}/lcov_to_sonar_generic.py (100%) rename {src/libraries/java/nv-boot-parent/tools/bazel => tools/bazel/java}/lcov_to_sonar_generic_test.sh (100%) diff --git a/src/control-plane-services/cloud-tasks/.bazel_downloader_config b/.bazel_downloader_config similarity index 100% rename from src/control-plane-services/cloud-tasks/.bazel_downloader_config rename to .bazel_downloader_config diff --git a/.bazelignore b/.bazelignore index bb26af335..f50748fbc 100644 --- a/.bazelignore +++ b/.bazelignore @@ -50,15 +50,16 @@ docs fern infra migrations -tools -# Standalone Java modules. Each has its own MODULE.bazel, its own -# nv_third_party_deps hub, and a CI matrix row in .github/workflows/bazel.yml; -# their BUILD files reference module-local repos (@nv_third_party_deps, -# @nv_boot_parent) that the root module does not define, so the root build must -# not recurse into them. -src/libraries/java/nv-boot-parent -src/control-plane-services/cloud-tasks +# Note: tools/ is not ignored here so //tools/bazel/java (the root-owned Java +# build helpers) is loadable. Gazelle is still kept out of tools/ via the +# gazelle:exclude directive in the root BUILD.bazel. + +# The Java subtrees (src/libraries/java/nv-boot-parent and +# src/control-plane-services/cloud-tasks) are part of the single root module: +# plain source dirs with BUILD.bazel only, no nested MODULE.bazel. They are +# intentionally loadable so root labels traverse them. Gazelle is kept out via +# the root BUILD.bazel gazelle:exclude directives. # Vendored dependencies inside the two Phase 1 subtrees. Bazel resolves these # from MODULE.bazel via Gazelle's go_deps extension, not from on-disk vendor. diff --git a/.bazelrc b/.bazelrc index 863882f9d..d5842697c 100644 --- a/.bazelrc +++ b/.bazelrc @@ -68,15 +68,29 @@ common --incompatible_enable_proto_toolchain_resolution build --workspace_status_command=./tools/workspace_status.sh build --nostamp -# Java: build and run against a hermetic remotejdk 21 regardless of the host -# JDK, so Java service builds are reproducible on any developer machine and in -# CI. Language version 21 is the current Spring Boot 3.x baseline. +# Java baseline: Java 25 for the whole monorepo (nv-boot-parent and the Java +# control-plane services). local_jdk is the approved runtime here: the folded +# Java subtrees were validated against a locally provisioned JDK 25, so both the +# build and tool runtimes resolve to local_jdk rather than a hermetic remotejdk. +# Full javac (header compilation off) is required because Lombok-generated APIs +# in the imported projects are not compatible with Bazel's Turbine header +# compiler. build --java_language_version=25 -build --java_runtime_version=remotejdk_25 build --tool_java_language_version=25 -build --tool_java_runtime_version=remotejdk_25 +build --java_runtime_version=local_jdk +build --tool_java_runtime_version=local_jdk build --java_header_compilation=false +# rules_spring 2.6.3 (cloud-tasks Spring Boot packaging) still uses bare Java +# rules/providers in its own BUILD and .bzl files; Bazel 9 requires these +# symbols to be autoloaded for that external repo. +common --incompatible_autoload_externally=+@rules_java + +# Downloader rewrites for repository-rule downloads (e.g. rules that hardcode +# repo1.maven.org). Coursier maven.install still uses the repositories declared +# in MODULE.bazel. Public, credentials-free mappings only. +common --downloader_config=.bazel_downloader_config + test --test_output=errors # Bazel's sandbox strips HOME, but a lot of Go code (cobra/viper config, # user state files, git cache lookups) blows up without it. Point HOME at diff --git a/BUILD.bazel b/BUILD.bazel index ce3c98a73..3f8365df4 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -21,15 +21,18 @@ exports_files( ) # Root module identity + third-party lock + NOTICE index, consumed by the -# nv-boot-parent NOTICE generation/verification tooling now that its Maven -# closure is owned by the root module. +# Java subtrees' NOTICE generation/verification tooling now that their Maven +# closure is owned by the single root module. exports_files( [ "MODULE.bazel", "NOTICE", "maven_install.json", ], - visibility = ["//src/libraries/java/nv-boot-parent:__subpackages__"], + visibility = [ + "//src/control-plane-services/cloud-tasks:__subpackages__", + "//src/libraries/java/nv-boot-parent:__subpackages__", + ], ) # Phase 1 scope: only the native Go subtrees listed in go.work.bazel are diff --git a/MODULE.bazel b/MODULE.bazel index 03a069e92..f89e90136 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -164,6 +164,10 @@ bazel_dep(name = "rules_java", version = "9.3.0") bazel_dep(name = "rules_jvm_external", version = "7.0") bazel_dep(name = "contrib_rules_jvm", version = "0.33.0") +# Spring Boot executable-jar packaging for the Java control-plane services +# (consumed by //rules/java:spring.bzl). Folded in from the cloud-tasks import. +bazel_dep(name = "rules_spring", version = "2.6.3") + # gRPC-Java codegen. rules_proto_grpc_java drives the protoc-gen-grpc-java # plugin (fetched as native binaries below) to generate Java gRPC stubs for # Java services that expose or consume gRPC. protobuf/com_google_protobuf and diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index 25d1aea46..dc12c256c 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -163,6 +163,7 @@ "https://bcr.bazel.build/modules/rules_cc/0.0.1/MODULE.bazel": "cb2aa0747f84c6c3a78dad4e2049c154f08ab9d166b1273835a8174940365647", "https://bcr.bazel.build/modules/rules_cc/0.0.10/MODULE.bazel": "ec1705118f7eaedd6e118508d3d26deba2a4e76476ada7e0e3965211be012002", "https://bcr.bazel.build/modules/rules_cc/0.0.13/MODULE.bazel": "0e8529ed7b323dad0775ff924d2ae5af7640b23553dfcd4d34344c7e7a867191", + "https://bcr.bazel.build/modules/rules_cc/0.0.14/MODULE.bazel": "5e343a3aac88b8d7af3b1b6d2093b55c347b8eefc2e7d1442f7a02dc8fea48ac", "https://bcr.bazel.build/modules/rules_cc/0.0.15/MODULE.bazel": "6704c35f7b4a72502ee81f61bf88706b54f06b3cbe5558ac17e2e14666cd5dcc", "https://bcr.bazel.build/modules/rules_cc/0.0.16/MODULE.bazel": "7661303b8fc1b4d7f532e54e9d6565771fea666fbdf839e0a86affcd02defe87", "https://bcr.bazel.build/modules/rules_cc/0.0.17/MODULE.bazel": "2ae1d8f4238ec67d7185d8861cb0a2cdf4bc608697c331b95bf990e69b62e64a", @@ -267,6 +268,7 @@ "https://bcr.bazel.build/modules/rules_python/0.37.1/MODULE.bazel": "3faeb2d9fa0a81f8980643ee33f212308f4d93eea4b9ce6f36d0b742e71e9500", "https://bcr.bazel.build/modules/rules_python/0.37.2/MODULE.bazel": "b5ffde91410745750b6c13be1c5dc4555ef5bc50562af4a89fd77807fdde626a", "https://bcr.bazel.build/modules/rules_python/0.4.0/MODULE.bazel": "9208ee05fd48bf09ac60ed269791cf17fb343db56c8226a720fbb1cdf467166c", + "https://bcr.bazel.build/modules/rules_python/0.40.0/MODULE.bazel": "9d1a3cd88ed7d8e39583d9ffe56ae8a244f67783ae89b60caafc9f5cf318ada7", "https://bcr.bazel.build/modules/rules_python/1.0.0/MODULE.bazel": "898a3d999c22caa585eb062b600f88654bf92efb204fa346fb55f6f8edffca43", "https://bcr.bazel.build/modules/rules_python/1.3.0/MODULE.bazel": "8361d57eafb67c09b75bf4bbe6be360e1b8f4f18118ab48037f2bd50aa2ccb13", "https://bcr.bazel.build/modules/rules_python/1.4.1/MODULE.bazel": "8991ad45bdc25018301d6b7e1d3626afc3c8af8aaf4bc04f23d0b99c938b73a6", @@ -285,6 +287,8 @@ "https://bcr.bazel.build/modules/rules_shell/0.6.1/MODULE.bazel": "72e76b0eea4e81611ef5452aa82b3da34caca0c8b7b5c0c9584338aa93bae26b", "https://bcr.bazel.build/modules/rules_shell/0.8.0/MODULE.bazel": "f6a89f1d6a669a26f28fe814503857055d76306b79cfc11d12399af08d0b80ae", "https://bcr.bazel.build/modules/rules_shell/0.8.0/source.json": "eb53cc815bc503c6683c5fe12d943f98883f81fc22f51403ec8a95610cba4195", + "https://bcr.bazel.build/modules/rules_spring/2.6.3/MODULE.bazel": "c2f719ea89af7bd3957a322c32430ee59f03fa467a4b1e208eba95a61ddcaa40", + "https://bcr.bazel.build/modules/rules_spring/2.6.3/source.json": "ac68bba4571d93871193ac0e85e3a20e6149221f12dc7f04fa8b042485cd2042", "https://bcr.bazel.build/modules/rules_swift/1.16.0/MODULE.bazel": "4a09f199545a60d09895e8281362b1ff3bb08bbde69c6fc87aff5b92fcc916ca", "https://bcr.bazel.build/modules/rules_swift/2.1.1/MODULE.bazel": "494900a80f944fc7aa61500c2073d9729dff0b764f0e89b824eb746959bc1046", "https://bcr.bazel.build/modules/rules_swift/2.4.0/MODULE.bazel": "1639617eb1ede28d774d967a738b4a68b0accb40650beadb57c21846beab5efd", diff --git a/rules/java/BUILD.bazel b/rules/java/BUILD.bazel new file mode 100644 index 000000000..65778e0d4 --- /dev/null +++ b/rules/java/BUILD.bazel @@ -0,0 +1,2 @@ +# Root-owned reusable Java Starlark APIs. See defs.bzl, spring.bzl, proto.bzl. +package(default_visibility = ["//visibility:public"]) diff --git a/rules/java/defs.bzl b/rules/java/defs.bzl new file mode 100644 index 000000000..c1d1e3854 --- /dev/null +++ b/rules/java/defs.bzl @@ -0,0 +1,332 @@ +"""Shared Java build macros for the NVCF monorepo. + +Reusable Starlark APIs for Java libraries and their JUnit 5 + JaCoCo tests. +These macros are owned by the root module and consumed by every native Java +subtree through direct `//rules/java:defs.bzl` loads. Third-party artifacts +resolve from the single root `@nv_third_party_deps` hub; executable helpers +and shared build targets (Lombok, JaCoCo CLI, JUnit runner) live under +`//tools/bazel/java`. + +Two profiles coexist while services keep distinct compile settings: +- nv_boot_* : nv-boot-parent library profile (`-Xlint:deprecation`). +- nvct_* : cloud-tasks service profile (`--release 25` + Error Prone opts). +Generalize into one profile only after multiple services demonstrate the same +need, per the monorepo Java architecture. +""" + +load("@rules_java//java:defs.bzl", _java_binary = "java_binary", _java_library = "java_library") +load("@rules_java//java/common:java_info.bzl", "JavaInfo") +load("@rules_shell//shell:sh_test.bzl", _sh_test = "sh_test") + +# ============================================================================ +# Shared helper targets (root-owned). +# ============================================================================ +_LOMBOK_COMPILE_DEPS = ["//tools/bazel/java:lombok_annotations"] +_LOMBOK_PLUGINS = ["//tools/bazel/java:lombok_plugin"] +_JACOCO_TEST_RUNNER = "//tools/bazel/java:jacoco_test_runner.sh" +_JACOCO_CLI = "//tools/bazel/java:jacoco_cli" + +_JUNIT5_ARGS = [ + "execute", + "--details=flat", + "--disable-ansi-colors", + "--details-theme=ascii", + "--include-classname=.*(Test|IntegrationTest)", + "--fail-if-no-tests", +] + +_JUNIT5_RUNTIME_DEPS = [ + "@nv_third_party_deps//:org_junit_platform_junit_platform_console_standalone", +] + +_JUNIT5_COMPILE_DEPS = [ + "@nv_third_party_deps//:org_assertj_assertj_core", + "@nv_third_party_deps//:org_junit_jupiter_junit_jupiter_api", + "@nv_third_party_deps//:org_junit_jupiter_junit_jupiter_params", + "@nv_third_party_deps//:org_mockito_mockito_core", + "@nv_third_party_deps//:org_mockito_mockito_junit_jupiter", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_test", + "@nv_third_party_deps//:org_springframework_boot_spring_boot_test_autoconfigure", + "@nv_third_party_deps//:org_springframework_spring_test", +] + +_MOCKITO_CORE = "@nv_third_party_deps//:org_mockito_mockito_core" +_JACOCO_AGENT = "@nv_third_party_deps//:org_jacoco_org_jacoco_agent_runtime" + +_JACOCO_AGENT_JVM_FLAGS = [ + ( + "-javaagent:$(location %s)=destfile=jacoco.exec,append=false," + + "dumponexit=true,includes=com.nvidia.*" + ) % _JACOCO_AGENT, +] + +def _unique(values): + seen = {} + result = [] + for value in values: + if value not in seen: + seen[value] = True + result.append(value) + return result + +# ============================================================================ +# Shared rules. +# ============================================================================ +def _nv_boot_runtime_classpath_test_impl(ctx): + runtime_jars = ctx.attr.target[JavaInfo].transitive_runtime_jars.to_list() + leaked = [] + + for jar in runtime_jars: + for artifact in ctx.attr.forbidden_artifacts: + if artifact in jar.basename: + leaked.append(jar.short_path) + break + + if leaked: + fail( + "%s exports Maven-optional/provided runtime jars:\n%s" % ( + ctx.attr.target.label, + "\n".join(sorted(leaked)), + ), + ) + + executable = ctx.actions.declare_file(ctx.label.name + ".sh") + ctx.actions.write( + output = executable, + content = "#!/bin/sh\nexit 0\n", + is_executable = True, + ) + return [DefaultInfo(executable = executable)] + +nv_boot_runtime_classpath_test = rule( + implementation = _nv_boot_runtime_classpath_test_impl, + attrs = { + "forbidden_artifacts": attr.string_list(mandatory = True), + "target": attr.label(mandatory = True, providers = [JavaInfo]), + }, + test = True, +) + +def _workspace_runfiles_impl(ctx): + symlinks = {} + strip_prefix = ctx.attr.strip_prefix + + for src in ctx.files.srcs: + runfiles_path = src.short_path + if strip_prefix: + if not runfiles_path.startswith(strip_prefix): + fail("Expected %s to start with strip_prefix %s" % (runfiles_path, strip_prefix)) + runfiles_path = runfiles_path[len(strip_prefix):] + + if runfiles_path in symlinks: + fail("Duplicate runfiles path: %s" % runfiles_path) + symlinks[runfiles_path] = src + + return [DefaultInfo(runfiles = ctx.runfiles(symlinks = symlinks))] + +_workspace_runfiles = rule( + implementation = _workspace_runfiles_impl, + attrs = { + "srcs": attr.label_list(allow_files = True), + "strip_prefix": attr.string(), + }, +) + +# Both profiles expose the same runfiles rule under their historical names. +nv_boot_workspace_runfiles = _workspace_runfiles +nvct_workspace_runfiles = _workspace_runfiles + +# ============================================================================ +# nv-boot-parent library profile. +# ============================================================================ +NV_JAVA_JAVACOPTS = [ + "-Xlint:deprecation", +] + +def nv_boot_library( + name, + srcs, + deps = [], + resources = [], + runtime_deps = [], + visibility = None, + resource_strip_prefix = ""): + _java_library( + name = name, + srcs = srcs, + deps = deps + _LOMBOK_COMPILE_DEPS, + javacopts = NV_JAVA_JAVACOPTS, + plugins = _LOMBOK_PLUGINS, + resources = resources, + resource_strip_prefix = resource_strip_prefix, + runtime_deps = runtime_deps, + visibility = visibility, + ) + +def nv_boot_library_test( + name, + srcs, + deps, + coverage_library, + data = [], + junit_classpath = [], + jvm_flags = [], + resources = [], + runtime_deps = [], + size = "small", + tags = [], + timeout = "short", + resource_strip_prefix = ""): + if type(coverage_library) != "string" or not coverage_library.startswith(":"): + fail( + "coverage_library must be the module library target as a local " + + "label starting with ':'", + ) + + coverage_sourcefiles = native.glob(["src/main/java/**/*.java"]) + coverage_source_root = native.package_name() + "/src/main/java" + junit_runner = name + "_junit_runner" + + _java_binary( + name = junit_runner, + srcs = srcs, + data = data + [_JACOCO_AGENT, _MOCKITO_CORE], + deps = deps + _LOMBOK_COMPILE_DEPS + _JUNIT5_COMPILE_DEPS, + javacopts = NV_JAVA_JAVACOPTS, + jvm_flags = _JACOCO_AGENT_JVM_FLAGS + [ + "-javaagent:$(location %s)" % _MOCKITO_CORE, + ] + jvm_flags, + main_class = "org.junit.platform.console.ConsoleLauncher", + plugins = _LOMBOK_PLUGINS, + resources = resources, + resource_strip_prefix = resource_strip_prefix, + runtime_deps = runtime_deps + _JUNIT5_RUNTIME_DEPS, + tags = ["manual"], + testonly = True, + visibility = ["//visibility:private"], + ) + + _sh_test( + name = name, + srcs = [_JACOCO_TEST_RUNNER], + args = [ + "$(location :%s)" % junit_runner, + "$(location %s)" % coverage_library, + coverage_source_root if coverage_sourcefiles else "", + native.package_name(), + "$(location %s)" % _JACOCO_CLI, + ] + _JUNIT5_ARGS + [ + "--class-path=$(location :%s.jar)" % junit_runner, + "--scan-classpath=$(location :%s.jar)" % junit_runner, + ] + [ + "--class-path=%s" % path + for path in junit_classpath + ], + data = [ + ":" + junit_runner, + ":%s.jar" % junit_runner, + coverage_library, + _JACOCO_CLI, + ] + coverage_sourcefiles, + size = size, + tags = tags, + timeout = timeout, + ) + +# ============================================================================ +# cloud-tasks service profile. +# ============================================================================ +NVCT_JAVACOPTS = [ + "--release", + "25", + "-Xep:CheckReturnValue:OFF", + "-Xep:ImpossibleNullComparison:OFF", + "-Xep:OptionalOfRedundantMethod:OFF", + "-Xlint:deprecation", +] + +def nvct_library( + name, + srcs, + deps = [], + resources = [], + runtime_deps = [], + visibility = None, + resource_strip_prefix = ""): + _java_library( + name = name, + srcs = srcs, + deps = deps + _LOMBOK_COMPILE_DEPS, + javacopts = NVCT_JAVACOPTS, + plugins = _LOMBOK_PLUGINS, + resources = resources, + resource_strip_prefix = resource_strip_prefix, + runtime_deps = runtime_deps, + visibility = visibility, + ) + +def nvct_library_test( + name, + deps, + coverage_library, + data = [], + jvm_flags = [], + resources = [], + runtime_deps = [], + size = "large", + srcs = [], + tags = [], + timeout = "long", + visibility = None): + if type(coverage_library) != "string" or not coverage_library.startswith(":"): + fail( + "coverage_library must be the module library target as a local " + + "label starting with ':'", + ) + + coverage_sourcefiles = native.glob(["src/main/java/**/*.java"]) + coverage_source_root = native.package_name() + "/src/main/java" + junit_runner = name + "_junit_runner" + + _java_binary( + name = junit_runner, + srcs = srcs, + data = _unique(data + [_JACOCO_AGENT, _MOCKITO_CORE]), + deps = _unique(deps + _LOMBOK_COMPILE_DEPS + _JUNIT5_COMPILE_DEPS), + javacopts = NVCT_JAVACOPTS, + jvm_flags = _JACOCO_AGENT_JVM_FLAGS + [ + "-javaagent:$(location %s)" % _MOCKITO_CORE, + ] + jvm_flags, + main_class = "org.junit.platform.console.ConsoleLauncher", + plugins = _LOMBOK_PLUGINS, + resources = resources, + runtime_deps = runtime_deps + _JUNIT5_RUNTIME_DEPS, + tags = ["manual"], + testonly = True, + visibility = ["//visibility:private"], + ) + + _sh_test( + name = name, + srcs = [_JACOCO_TEST_RUNNER], + args = [ + "$(location :%s)" % junit_runner, + "$(location %s)" % coverage_library, + coverage_source_root if coverage_sourcefiles else "", + native.package_name(), + "$(location %s)" % _JACOCO_CLI, + ] + _JUNIT5_ARGS + [ + "--class-path=$(location :%s.jar)" % junit_runner, + "--scan-classpath=$(location :%s.jar)" % junit_runner, + ], + data = _unique([ + ":" + junit_runner, + ":%s.jar" % junit_runner, + coverage_library, + _JACOCO_CLI, + ] + coverage_sourcefiles), + size = size, + tags = tags, + timeout = timeout, + visibility = visibility, + ) diff --git a/src/control-plane-services/cloud-tasks/tools/bazel/proto.bzl b/rules/java/proto.bzl similarity index 92% rename from src/control-plane-services/cloud-tasks/tools/bazel/proto.bzl rename to rules/java/proto.bzl index ef77df006..02016b421 100644 --- a/src/control-plane-services/cloud-tasks/tools/bazel/proto.bzl +++ b/rules/java/proto.bzl @@ -18,7 +18,7 @@ nvct_java_grpc_compile = rule( providers = [ProtoPluginInfo], default = [ Label("@rules_proto_grpc_java//:proto_plugin"), - Label("//tools/bazel:grpc_java_1_63_plugin"), + Label("//tools/bazel/java:grpc_java_1_63_plugin"), ], cfg = "exec", ), diff --git a/src/control-plane-services/cloud-tasks/tools/bazel/spring_boot.bzl b/rules/java/spring.bzl similarity index 100% rename from src/control-plane-services/cloud-tasks/tools/bazel/spring_boot.bzl rename to rules/java/spring.bzl diff --git a/src/control-plane-services/cloud-tasks/.bazelignore b/src/control-plane-services/cloud-tasks/.bazelignore deleted file mode 100644 index e499616c3..000000000 --- a/src/control-plane-services/cloud-tasks/.bazelignore +++ /dev/null @@ -1,4 +0,0 @@ -bazel-bin -bazel-cloud-tasks -bazel-out -bazel-testlogs diff --git a/src/control-plane-services/cloud-tasks/.bazelrc b/src/control-plane-services/cloud-tasks/.bazelrc deleted file mode 100644 index c5b709b69..000000000 --- a/src/control-plane-services/cloud-tasks/.bazelrc +++ /dev/null @@ -1,14 +0,0 @@ -common --downloader_config=.bazel_downloader_config - -build --workspace_status_command=tools/bazel/workspace_status.sh -# rules_spring 2.6.3 still uses bare Java rules/providers in its own BUILD and -# .bzl files. Bazel 9 requires these symbols to be autoloaded for external repos. -common --incompatible_autoload_externally=+@rules_java -build --java_language_version=25 -build --tool_java_language_version=25 -build --java_runtime_version=local_jdk -build --tool_java_runtime_version=local_jdk - -# Lombok onConstructor_ usage in nvct-core is not compatible with Bazel's -# Java header compiler (Turbine). Maven uses full javac, so keep Bazel aligned. -build --nojava_header_compilation diff --git a/src/control-plane-services/cloud-tasks/.bazelversion b/src/control-plane-services/cloud-tasks/.bazelversion deleted file mode 100644 index 44931da26..000000000 --- a/src/control-plane-services/cloud-tasks/.bazelversion +++ /dev/null @@ -1 +0,0 @@ -9.1.1 diff --git a/src/control-plane-services/cloud-tasks/BUILD.bazel b/src/control-plane-services/cloud-tasks/BUILD.bazel index e3e5e9619..d9ade0221 100644 --- a/src/control-plane-services/cloud-tasks/BUILD.bazel +++ b/src/control-plane-services/cloud-tasks/BUILD.bazel @@ -1,11 +1,15 @@ load("@rules_shell//shell:sh_binary.bzl", "sh_binary") -load("//tools/bazel:java.bzl", "nvct_workspace_runfiles") +load("//rules/java:defs.bzl", "nvct_workspace_runfiles") package(default_visibility = ["//visibility:public"]) +# NOTICE and its service-local metadata are owned by this subtree. The +# third-party artifact lock is the single root //:maven_install.json; the +# generation algorithm is root-owned under //tools/bazel/java. exports_files([ "NOTICE", - "maven_install.json", + "notice_metadata.json", + "generate_notice.sh", ]) filegroup( @@ -26,17 +30,24 @@ nvct_workspace_runfiles( genrule( name = "third_party_notice", srcs = [ - ":maven_install.json", - "//nvct-service:app", - "//tools/bazel:notice_metadata.json", - "@nv_boot_parent//tools/bazel:generate_notice.py", + "//:maven_install.json", + "//src/control-plane-services/cloud-tasks/nvct-service:app", + ":notice_metadata.json", + "//tools/bazel/java:generate_notice.py", ], outs = ["THIRD_PARTY_NOTICE"], + # Excluded from wildcard builds: the service NOTICE metadata does not yet + # cover every transitive resolved through the single merged root hub (for + # example aopalliance:aopalliance:1.0). Reconciling service NOTICE metadata + # against the merged root closure is the layered-NOTICE work deferred to the + # shared-tooling pilot in the monorepo Java architecture. Run explicitly + # with `bazel build //src/control-plane-services/cloud-tasks:third_party_notice`. + tags = ["manual"], cmd = """ -python3 "$(location @nv_boot_parent//tools/bazel:generate_notice.py)" \ - --maven-install "$(location :maven_install.json)" \ - --metadata "$(location //tools/bazel:notice_metadata.json)" \ - --runtime-jar "$(location //nvct-service:app)" \ +python3 "$(location //tools/bazel/java:generate_notice.py)" \ + --maven-install "$(location //:maven_install.json)" \ + --metadata "$(location :notice_metadata.json)" \ + --runtime-jar "$(location //src/control-plane-services/cloud-tasks/nvct-service:app)" \ --first-party-group com.nvidia.nvct \ --output "$@" \ --write @@ -45,9 +56,9 @@ python3 "$(location @nv_boot_parent//tools/bazel:generate_notice.py)" \ sh_binary( name = "generate_notice", - srcs = ["//tools/bazel:generate_notice.sh"], + srcs = [":generate_notice.sh"], data = [ - "//nvct-service:app", - "@nv_boot_parent//tools/bazel:generate_notice.py", + "//src/control-plane-services/cloud-tasks/nvct-service:app", + "//tools/bazel/java:generate_notice.py", ], ) diff --git a/src/control-plane-services/cloud-tasks/MODULE.bazel b/src/control-plane-services/cloud-tasks/MODULE.bazel deleted file mode 100644 index f29c501cb..000000000 --- a/src/control-plane-services/cloud-tasks/MODULE.bazel +++ /dev/null @@ -1,173 +0,0 @@ -module(name = "cloud_tasks") - -GRPC_VERSION = "1.63.0" - -bazel_dep(name = "rules_java", version = "9.3.0") -bazel_dep(name = "rules_jvm_external", version = "7.0") -bazel_dep(name = "rules_proto_grpc", version = "5.8.0") -bazel_dep(name = "rules_proto_grpc_java", version = "5.8.0") -bazel_dep(name = "rules_shell", version = "0.8.0") -bazel_dep(name = "rules_spring", version = "2.6.3") -bazel_dep(name = "protobuf", version = "33.4") -bazel_dep(name = "nv_boot_parent", version = "0.0.0") - -local_path_override( - module_name = "nv_boot_parent", - path = "../../libraries/java/nv-boot-parent", -) - -http_file = use_repo_rule( - "@bazel_tools//tools/build_defs/repo:http.bzl", - "http_file", -) - -# The gRPC generator is a native executable, not a Java dependency. Keep it -# outside the shared Maven hub so fetch_sources applies only to Java artifacts. -http_file( - name = "grpc_java_plugin_linux_aarch_64", - downloaded_file_path = "protoc-gen-grpc-java.exe", - executable = True, - sha256 = "471427565ad82b3caac5e19dba2d15fb75b81042503ea32357630312d1f074b4", - urls = [ - "https://maven-central.storage-download.googleapis.com/maven2/io/grpc/protoc-gen-grpc-java/%s/protoc-gen-grpc-java-%s-linux-aarch_64.exe" % (GRPC_VERSION, GRPC_VERSION), - "https://repo.maven.apache.org/maven2/io/grpc/protoc-gen-grpc-java/%s/protoc-gen-grpc-java-%s-linux-aarch_64.exe" % (GRPC_VERSION, GRPC_VERSION), - ], -) - -http_file( - name = "grpc_java_plugin_linux_x86_64", - downloaded_file_path = "protoc-gen-grpc-java.exe", - executable = True, - sha256 = "0e3e8db80ba1fbddeed97ea3220b52cfaa95764ff8bf00716df7322883ce47e8", - urls = [ - "https://maven-central.storage-download.googleapis.com/maven2/io/grpc/protoc-gen-grpc-java/%s/protoc-gen-grpc-java-%s-linux-x86_64.exe" % (GRPC_VERSION, GRPC_VERSION), - "https://repo.maven.apache.org/maven2/io/grpc/protoc-gen-grpc-java/%s/protoc-gen-grpc-java-%s-linux-x86_64.exe" % (GRPC_VERSION, GRPC_VERSION), - ], -) - -http_file( - name = "grpc_java_plugin_osx_aarch_64", - downloaded_file_path = "protoc-gen-grpc-java.exe", - executable = True, - sha256 = "28290117a2ee9ea60f50f94273ab139dc2b3be4b8f2a557bef7e6efefee5b363", - urls = [ - "https://maven-central.storage-download.googleapis.com/maven2/io/grpc/protoc-gen-grpc-java/%s/protoc-gen-grpc-java-%s-osx-aarch_64.exe" % (GRPC_VERSION, GRPC_VERSION), - "https://repo.maven.apache.org/maven2/io/grpc/protoc-gen-grpc-java/%s/protoc-gen-grpc-java-%s-osx-aarch_64.exe" % (GRPC_VERSION, GRPC_VERSION), - ], -) - -http_file( - name = "grpc_java_plugin_osx_x86_64", - downloaded_file_path = "protoc-gen-grpc-java.exe", - executable = True, - sha256 = "28290117a2ee9ea60f50f94273ab139dc2b3be4b8f2a557bef7e6efefee5b363", - urls = [ - "https://maven-central.storage-download.googleapis.com/maven2/io/grpc/protoc-gen-grpc-java/%s/protoc-gen-grpc-java-%s-osx-x86_64.exe" % (GRPC_VERSION, GRPC_VERSION), - "https://repo.maven.apache.org/maven2/io/grpc/protoc-gen-grpc-java/%s/protoc-gen-grpc-java-%s-osx-x86_64.exe" % (GRPC_VERSION, GRPC_VERSION), - ], -) - -http_file( - name = "grpc_java_plugin_windows_x86_64", - downloaded_file_path = "protoc-gen-grpc-java.exe", - executable = True, - sha256 = "c3e9aaefd825a6ea9a252e153e0998d7ef36a7b27c2156867a98c71edf9c18a1", - urls = [ - "https://maven-central.storage-download.googleapis.com/maven2/io/grpc/protoc-gen-grpc-java/%s/protoc-gen-grpc-java-%s-windows-x86_64.exe" % (GRPC_VERSION, GRPC_VERSION), - "https://repo.maven.apache.org/maven2/io/grpc/protoc-gen-grpc-java/%s/protoc-gen-grpc-java-%s-windows-x86_64.exe" % (GRPC_VERSION, GRPC_VERSION), - ], -) - -maven = use_extension("@rules_jvm_external//:extensions.bzl", "maven") -maven.install( - name = "nv_third_party_deps", - # Phase 1 keeps this list to root coordinates needed to compile nvct-core. - # Versions are omitted when inherited from the imported Maven BOMs/parents. - # Project-local Maven property pins stay explicit here. - artifacts = [ - "com.bucket4j:bucket4j_jdk17-core:8.19.0", - "com.github.ben-manes.caffeine:caffeine", - "com.github.ben-manes.caffeine:guava", - # Keep Java protobuf runtime aligned with the Bazel protobuf generator. - "com.google.protobuf:protobuf-java:4.33.4", - "com.google.protobuf:protobuf-java-util:4.33.4", - "io.grpc:grpc-api:%s" % GRPC_VERSION, - "io.grpc:grpc-protobuf:%s" % GRPC_VERSION, - "io.grpc:grpc-stub:%s" % GRPC_VERSION, - "io.micrometer:micrometer-registry-prometheus", - "io.opentelemetry:opentelemetry-sdk-testing", - "io.projectreactor.netty:reactor-netty-core", - "io.projectreactor.netty:reactor-netty-http", - "jakarta.servlet:jakarta.servlet-api", - "javax.annotation:javax.annotation-api:1.3.2", - "net.devh:grpc-server-spring-boot-starter:3.1.0.RELEASE", - "net.javacrumbs.shedlock:shedlock-provider-cassandra", - "net.javacrumbs.shedlock:shedlock-spring", - "org.apache.cassandra:java-driver-metrics-micrometer", - "org.assertj:assertj-core", - "org.awaitility:awaitility", - "org.junit.jupiter:junit-jupiter-api", - "org.junit.jupiter:junit-jupiter-params", - "org.junit.platform:junit-platform-console-standalone:6.0.3", - # Direct Bazel test-tool dependency; Spring Boot's BOM does not manage it. - "org.jacoco:org.jacoco.agent:jar:runtime:0.8.14", - "org.jacoco:org.jacoco.cli:0.8.14", - "org.mockito:mockito-core", - "org.mockito:mockito-junit-jupiter", - # JaCoCo report generation needs a Java 25-capable ASM family. Legacy - # jnr/accessors-smart edges otherwise select ASM 5.0.3 at runtime. - "org.ow2.asm:asm:9.9", - "org.ow2.asm:asm-analysis:9.9", - "org.ow2.asm:asm-commons:9.9", - "org.ow2.asm:asm-tree:9.9", - "org.ow2.asm:asm-util:9.9", - "org.projectlombok:lombok", - "org.springdoc:springdoc-openapi-starter-webmvc-api:3.0.3", - "org.springframework.boot:spring-boot-actuator", - "org.springframework.boot:spring-boot-micrometer-metrics", - "org.springframework.boot:spring-boot-micrometer-tracing", - "org.springframework.boot:spring-boot-micrometer-tracing-opentelemetry", - "org.springframework.boot:spring-boot-opentelemetry", - "org.springframework.boot:spring-boot-loader", - "org.springframework.boot:spring-boot-restclient", - "org.springframework.boot:spring-boot-starter-data-cassandra-test", - "org.springframework.boot:spring-boot-starter-aspectj", - "org.springframework.boot:spring-boot-starter-jackson", - "org.springframework.boot:spring-boot-starter-security", - "org.springframework.boot:spring-boot-starter-security-oauth2-client", - "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server", - "org.springframework.boot:spring-boot-starter-validation", - "org.springframework.boot:spring-boot-starter-webmvc-test", - "org.springframework.boot:spring-boot-starter-webmvc", - "org.springframework.boot:spring-boot-webclient", - "org.springframework.cloud:spring-cloud-starter-kubernetes-client-config", - "org.springframework.retry:spring-retry", - "org.springframework:spring-context-support", - "org.springframework:spring-webflux", - "org.testcontainers:testcontainers", - "org.testcontainers:testcontainers-cassandra", - "org.testcontainers:testcontainers-localstack", - "org.wiremock:wiremock-standalone:3.13.2", - "tools.jackson.module:jackson-module-blackbird", - ], - boms = [ - "net.javacrumbs.shedlock:shedlock-bom:7.7.0", - "org.springframework.boot:spring-boot-dependencies:4.0.7", - "org.springframework.cloud:spring-cloud-dependencies:2025.1.2", - "org.testcontainers:testcontainers-bom:2.0.5", - ], - fail_on_missing_checksum = True, - fetch_sources = True, - known_contributing_modules = [ - "nv_boot_parent", - "protobuf", - "rules_proto_grpc_java", - ], - lock_file = "//:maven_install.json", - repositories = [ - "https://maven-central.storage-download.googleapis.com/maven2", - "https://repo.maven.apache.org/maven2", - ], - resolver = "maven", -) -use_repo(maven, "nv_third_party_deps") diff --git a/src/control-plane-services/cloud-tasks/MODULE.bazel.lock b/src/control-plane-services/cloud-tasks/MODULE.bazel.lock deleted file mode 100644 index 3c94c79ec..000000000 --- a/src/control-plane-services/cloud-tasks/MODULE.bazel.lock +++ /dev/null @@ -1,954 +0,0 @@ -{ - "lockFileVersion": 26, - "registryFileHashes": { - "https://bcr.bazel.build/bazel_registry.json": "8a28e4aff06ee60aed2a8c281907fb8bcbf3b753c91fb5a5c57da3215d5b3497", - "https://bcr.bazel.build/modules/abseil-cpp/20210324.2/MODULE.bazel": "7cd0312e064fde87c8d1cd79ba06c876bd23630c83466e9500321be55c96ace2", - "https://bcr.bazel.build/modules/abseil-cpp/20211102.0/MODULE.bazel": "70390338f7a5106231d20620712f7cccb659cd0e9d073d1991c038eb9fc57589", - "https://bcr.bazel.build/modules/abseil-cpp/20230125.1/MODULE.bazel": "89047429cb0207707b2dface14ba7f8df85273d484c2572755be4bab7ce9c3a0", - "https://bcr.bazel.build/modules/abseil-cpp/20230802.0.bcr.1/MODULE.bazel": "1c8cec495288dccd14fdae6e3f95f772c1c91857047a098fad772034264cc8cb", - "https://bcr.bazel.build/modules/abseil-cpp/20230802.0/MODULE.bazel": "d253ae36a8bd9ee3c5955384096ccb6baf16a1b1e93e858370da0a3b94f77c16", - "https://bcr.bazel.build/modules/abseil-cpp/20230802.1/MODULE.bazel": "fa92e2eb41a04df73cdabeec37107316f7e5272650f81d6cc096418fe647b915", - "https://bcr.bazel.build/modules/abseil-cpp/20240116.1/MODULE.bazel": "37bcdb4440fbb61df6a1c296ae01b327f19e9bb521f9b8e26ec854b6f97309ed", - "https://bcr.bazel.build/modules/abseil-cpp/20240116.2/MODULE.bazel": "73939767a4686cd9a520d16af5ab440071ed75cec1a876bf2fcfaf1f71987a16", - "https://bcr.bazel.build/modules/abseil-cpp/20250127.0/MODULE.bazel": "d1086e248cda6576862b4b3fe9ad76a214e08c189af5b42557a6e1888812c5d5", - "https://bcr.bazel.build/modules/abseil-cpp/20250127.1/MODULE.bazel": "c4a89e7ceb9bf1e25cf84a9f830ff6b817b72874088bf5141b314726e46a57c1", - "https://bcr.bazel.build/modules/abseil-cpp/20250512.1/MODULE.bazel": "d209fdb6f36ffaf61c509fcc81b19e81b411a999a934a032e10cd009a0226215", - "https://bcr.bazel.build/modules/abseil-cpp/20250814.1/MODULE.bazel": "51f2312901470cdab0dbdf3b88c40cd21c62a7ed58a3de45b365ddc5b11bcab2", - "https://bcr.bazel.build/modules/abseil-cpp/20250814.1/source.json": "cea3901d7e299da7320700abbaafe57a65d039f10d0d7ea601c4a66938ea4b0c", - "https://bcr.bazel.build/modules/abseil-py/2.1.0/MODULE.bazel": "5ebe5bf853769c65707e5c28f216798f7a4b1042015e6a36e6d03094d94bec8a", - "https://bcr.bazel.build/modules/abseil-py/2.1.0/source.json": "0e8fc4f088ce07099c1cd6594c20c7ddbb48b4b3c0849b7d94ba94be88ff042b", - "https://bcr.bazel.build/modules/apple_support/1.11.1/MODULE.bazel": "1843d7cd8a58369a444fc6000e7304425fba600ff641592161d9f15b179fb896", - "https://bcr.bazel.build/modules/apple_support/1.15.1/MODULE.bazel": "a0556fefca0b1bb2de8567b8827518f94db6a6e7e7d632b4c48dc5f865bc7c85", - "https://bcr.bazel.build/modules/apple_support/1.21.0/MODULE.bazel": "ac1824ed5edf17dee2fdd4927ada30c9f8c3b520be1b5fd02a5da15bc10bff3e", - "https://bcr.bazel.build/modules/apple_support/1.21.1/MODULE.bazel": "5809fa3efab15d1f3c3c635af6974044bac8a4919c62238cce06acee8a8c11f1", - "https://bcr.bazel.build/modules/apple_support/1.23.0/MODULE.bazel": "317d47e3f65b580e7fb4221c160797fda48e32f07d2dfff63d754ef2316dcd25", - "https://bcr.bazel.build/modules/apple_support/1.24.2/MODULE.bazel": "0e62471818affb9f0b26f128831d5c40b074d32e6dda5a0d3852847215a41ca4", - "https://bcr.bazel.build/modules/apple_support/1.24.2/source.json": "2c22c9827093250406c5568da6c54e6fdf0ef06238def3d99c71b12feb057a8d", - "https://bcr.bazel.build/modules/aspect_bazel_lib/2.14.0/MODULE.bazel": "2b31ffcc9bdc8295b2167e07a757dbbc9ac8906e7028e5170a3708cecaac119f", - "https://bcr.bazel.build/modules/aspect_bazel_lib/2.19.3/MODULE.bazel": "253d739ba126f62a5767d832765b12b59e9f8d2bc88cc1572f4a73e46eb298ca", - "https://bcr.bazel.build/modules/aspect_bazel_lib/2.21.2/MODULE.bazel": "276347663a25b0d5bd6cad869252bea3e160c4d980e764b15f3bae7f80b30624", - "https://bcr.bazel.build/modules/aspect_bazel_lib/2.21.2/source.json": "f42051fa42629f0e59b7ac2adf0a55749144b11f1efcd8c697f0ee247181e526", - "https://bcr.bazel.build/modules/aspect_bazel_lib/2.8.1/MODULE.bazel": "812d2dd42f65dca362152101fbec418029cc8fd34cbad1a2fde905383d705838", - "https://bcr.bazel.build/modules/bazel_features/1.1.0/MODULE.bazel": "cfd42ff3b815a5f39554d97182657f8c4b9719568eb7fded2b9135f084bf760b", - "https://bcr.bazel.build/modules/bazel_features/1.1.1/MODULE.bazel": "27b8c79ef57efe08efccbd9dd6ef70d61b4798320b8d3c134fd571f78963dbcd", - "https://bcr.bazel.build/modules/bazel_features/1.10.0/MODULE.bazel": "f75e8807570484a99be90abcd52b5e1f390362c258bcb73106f4544957a48101", - "https://bcr.bazel.build/modules/bazel_features/1.11.0/MODULE.bazel": "f9382337dd5a474c3b7d334c2f83e50b6eaedc284253334cf823044a26de03e8", - "https://bcr.bazel.build/modules/bazel_features/1.13.0/MODULE.bazel": "c14c33c7c3c730612bdbe14ebbb5e61936b6f11322ea95a6e91cd1ba962f94df", - "https://bcr.bazel.build/modules/bazel_features/1.15.0/MODULE.bazel": "d38ff6e517149dc509406aca0db3ad1efdd890a85e049585b7234d04238e2a4d", - "https://bcr.bazel.build/modules/bazel_features/1.17.0/MODULE.bazel": "039de32d21b816b47bd42c778e0454217e9c9caac4a3cf8e15c7231ee3ddee4d", - "https://bcr.bazel.build/modules/bazel_features/1.18.0/MODULE.bazel": "1be0ae2557ab3a72a57aeb31b29be347bcdc5d2b1eb1e70f39e3851a7e97041a", - "https://bcr.bazel.build/modules/bazel_features/1.19.0/MODULE.bazel": "59adcdf28230d220f0067b1f435b8537dd033bfff8db21335ef9217919c7fb58", - "https://bcr.bazel.build/modules/bazel_features/1.21.0/MODULE.bazel": "675642261665d8eea09989aa3b8afb5c37627f1be178382c320d1b46afba5e3b", - "https://bcr.bazel.build/modules/bazel_features/1.23.0/MODULE.bazel": "fd1ac84bc4e97a5a0816b7fd7d4d4f6d837b0047cf4cbd81652d616af3a6591a", - "https://bcr.bazel.build/modules/bazel_features/1.25.0/MODULE.bazel": "e2e60a10a6da64bbf533f15ca652bf61a033e41c2ed734d79a9a08ba87f68c1a", - "https://bcr.bazel.build/modules/bazel_features/1.27.0/MODULE.bazel": "621eeee06c4458a9121d1f104efb80f39d34deff4984e778359c60eaf1a8cb65", - "https://bcr.bazel.build/modules/bazel_features/1.28.0/MODULE.bazel": "4b4200e6cbf8fa335b2c3f43e1d6ef3e240319c33d43d60cc0fbd4b87ece299d", - "https://bcr.bazel.build/modules/bazel_features/1.3.0/MODULE.bazel": "cdcafe83ec318cda34e02948e81d790aab8df7a929cec6f6969f13a489ccecd9", - "https://bcr.bazel.build/modules/bazel_features/1.30.0/MODULE.bazel": "a14b62d05969a293b80257e72e597c2da7f717e1e69fa8b339703ed6731bec87", - "https://bcr.bazel.build/modules/bazel_features/1.32.0/MODULE.bazel": "095d67022a58cb20f7e20e1aefecfa65257a222c18a938e2914fd257b5f1ccdc", - "https://bcr.bazel.build/modules/bazel_features/1.33.0/MODULE.bazel": "8b8dc9d2a4c88609409c3191165bccec0e4cb044cd7a72ccbe826583303459f6", - "https://bcr.bazel.build/modules/bazel_features/1.4.1/MODULE.bazel": "e45b6bb2350aff3e442ae1111c555e27eac1d915e77775f6fdc4b351b758b5d7", - "https://bcr.bazel.build/modules/bazel_features/1.42.1/MODULE.bazel": "275a59b5406ff18c01739860aa70ad7ccb3cfb474579411decca11c93b951080", - "https://bcr.bazel.build/modules/bazel_features/1.42.1/source.json": "fcd4396b2df85f64f2b3bb436ad870793ecf39180f1d796f913cc9276d355309", - "https://bcr.bazel.build/modules/bazel_features/1.9.0/MODULE.bazel": "885151d58d90d8d9c811eb75e3288c11f850e1d6b481a8c9f766adee4712358b", - "https://bcr.bazel.build/modules/bazel_features/1.9.1/MODULE.bazel": "8f679097876a9b609ad1f60249c49d68bfab783dd9be012faf9d82547b14815a", - "https://bcr.bazel.build/modules/bazel_lib/3.0.0/MODULE.bazel": "22b70b80ac89ad3f3772526cd9feee2fa412c2b01933fea7ed13238a448d370d", - "https://bcr.bazel.build/modules/bazel_lib/3.0.0/source.json": "895f21909c6fba01d7c17914bb6c8e135982275a1b18cdaa4e62272217ef1751", - "https://bcr.bazel.build/modules/bazel_skylib/1.0.3/MODULE.bazel": "bcb0fd896384802d1ad283b4e4eb4d718eebd8cb820b0a2c3a347fb971afd9d8", - "https://bcr.bazel.build/modules/bazel_skylib/1.1.1/MODULE.bazel": "1add3e7d93ff2e6998f9e118022c84d163917d912f5afafb3058e3d2f1545b5e", - "https://bcr.bazel.build/modules/bazel_skylib/1.2.0/MODULE.bazel": "44fe84260e454ed94ad326352a698422dbe372b21a1ac9f3eab76eb531223686", - "https://bcr.bazel.build/modules/bazel_skylib/1.2.1/MODULE.bazel": "f35baf9da0efe45fa3da1696ae906eea3d615ad41e2e3def4aeb4e8bc0ef9a7a", - "https://bcr.bazel.build/modules/bazel_skylib/1.3.0/MODULE.bazel": "20228b92868bf5cfc41bda7afc8a8ba2a543201851de39d990ec957b513579c5", - "https://bcr.bazel.build/modules/bazel_skylib/1.4.1/MODULE.bazel": "a0dcb779424be33100dcae821e9e27e4f2901d9dfd5333efe5ac6a8d7ab75e1d", - "https://bcr.bazel.build/modules/bazel_skylib/1.4.2/MODULE.bazel": "3bd40978e7a1fac911d5989e6b09d8f64921865a45822d8b09e815eaa726a651", - "https://bcr.bazel.build/modules/bazel_skylib/1.5.0/MODULE.bazel": "32880f5e2945ce6a03d1fbd588e9198c0a959bb42297b2cfaf1685b7bc32e138", - "https://bcr.bazel.build/modules/bazel_skylib/1.6.1/MODULE.bazel": "8fdee2dbaace6c252131c00e1de4b165dc65af02ea278476187765e1a617b917", - "https://bcr.bazel.build/modules/bazel_skylib/1.7.0/MODULE.bazel": "0db596f4563de7938de764cc8deeabec291f55e8ec15299718b93c4423e9796d", - "https://bcr.bazel.build/modules/bazel_skylib/1.7.1/MODULE.bazel": "3120d80c5861aa616222ec015332e5f8d3171e062e3e804a2a0253e1be26e59b", - "https://bcr.bazel.build/modules/bazel_skylib/1.8.1/MODULE.bazel": "88ade7293becda963e0e3ea33e7d54d3425127e0a326e0d17da085a5f1f03ff6", - "https://bcr.bazel.build/modules/bazel_skylib/1.8.2/MODULE.bazel": "69ad6927098316848b34a9142bcc975e018ba27f08c4ff403f50c1b6e646ca67", - "https://bcr.bazel.build/modules/bazel_skylib/1.8.2/source.json": "34a3c8bcf233b835eb74be9d628899bb32999d3e0eadef1947a0a562a2b16ffb", - "https://bcr.bazel.build/modules/bazel_worker_api/0.0.1/MODULE.bazel": "02a13b77321773b2042e70ee5e4c5e099c8ddee4cf2da9cd420442c36938d4bd", - "https://bcr.bazel.build/modules/bazel_worker_api/0.0.4/MODULE.bazel": "460aa12d01231a80cce03c548287b433b321d205b0028ae596728c35e5ee442e", - "https://bcr.bazel.build/modules/bazel_worker_api/0.0.8/MODULE.bazel": "396c1ef53835aafe3d42ce6619080531ee770648303731f16cfaa33fa056bf0c", - "https://bcr.bazel.build/modules/bazel_worker_api/0.0.8/source.json": "abaf8ac9d2ab2f47bda9af4c0c080ff7907378888e1f4bc62a0539dd13ba61e8", - "https://bcr.bazel.build/modules/bazel_worker_java/0.0.4/MODULE.bazel": "82494a01018bb7ef06d4a17ec4cd7a758721f10eb8b6c820a818e70d669500db", - "https://bcr.bazel.build/modules/bazel_worker_java/0.0.8/MODULE.bazel": "e76479eae70bd4e8f5f4c2dfc5d03ab971cfb18750246c7b3f3454c5c2ee6629", - "https://bcr.bazel.build/modules/bazel_worker_java/0.0.8/source.json": "9395c4679444bc47bf7e51a710366a4480aa371c6f6bed01868e2fabcf11acec", - "https://bcr.bazel.build/modules/buildozer/8.5.1/MODULE.bazel": "a35d9561b3fc5b18797c330793e99e3b834a473d5fbd3d7d7634aafc9bdb6f8f", - "https://bcr.bazel.build/modules/buildozer/8.5.1/source.json": "e3386e6ff4529f2442800dee47ad28d3e6487f36a1f75ae39ae56c70f0cd2fbd", - "https://bcr.bazel.build/modules/gawk/5.3.2.bcr.1/MODULE.bazel": "cdf8cbe5ee750db04b78878c9633cc76e80dcf4416cbe982ac3a9222f80713c8", - "https://bcr.bazel.build/modules/gawk/5.3.2.bcr.1/source.json": "fa7b512dfcb5eafd90ce3959cf42a2a6fe96144ebbb4b3b3928054895f2afac2", - "https://bcr.bazel.build/modules/gazelle/0.32.0/MODULE.bazel": "b499f58a5d0d3537f3cf5b76d8ada18242f64ec474d8391247438bf04f58c7b8", - "https://bcr.bazel.build/modules/gazelle/0.33.0/MODULE.bazel": "a13a0f279b462b784fb8dd52a4074526c4a2afe70e114c7d09066097a46b3350", - "https://bcr.bazel.build/modules/gazelle/0.34.0/MODULE.bazel": "abdd8ce4d70978933209db92e436deb3a8b737859e9354fb5fd11fb5c2004c8a", - "https://bcr.bazel.build/modules/gazelle/0.36.0/MODULE.bazel": "e375d5d6e9a6ca59b0cb38b0540bc9a05b6aa926d322f2de268ad267a2ee74c0", - "https://bcr.bazel.build/modules/gazelle/0.40.0/MODULE.bazel": "42ba5378ebe845fca43989a53186ab436d956db498acde790685fe0e8f9c6146", - "https://bcr.bazel.build/modules/gazelle/0.47.0/MODULE.bazel": "b61bb007c4efad134aa30ee7f4a8e2a39b22aa5685f005edaa022fbd1de43ebc", - "https://bcr.bazel.build/modules/gazelle/0.47.0/source.json": "aeb2e5df14b7fb298625d75d08b9c65bdb0b56014c5eb89da9e5dd0572280ae6", - "https://bcr.bazel.build/modules/google_benchmark/1.8.2/MODULE.bazel": "a70cf1bba851000ba93b58ae2f6d76490a9feb74192e57ab8e8ff13c34ec50cb", - "https://bcr.bazel.build/modules/googletest/1.11.0/MODULE.bazel": "3a83f095183f66345ca86aa13c58b59f9f94a2f81999c093d4eeaa2d262d12f4", - "https://bcr.bazel.build/modules/googletest/1.14.0.bcr.1/MODULE.bazel": "22c31a561553727960057361aa33bf20fb2e98584bc4fec007906e27053f80c6", - "https://bcr.bazel.build/modules/googletest/1.14.0/MODULE.bazel": "cfbcbf3e6eac06ef9d85900f64424708cc08687d1b527f0ef65aa7517af8118f", - "https://bcr.bazel.build/modules/googletest/1.15.2/MODULE.bazel": "6de1edc1d26cafb0ea1a6ab3f4d4192d91a312fd2d360b63adaa213cd00b2108", - "https://bcr.bazel.build/modules/googletest/1.17.0/MODULE.bazel": "dbec758171594a705933a29fcf69293d2468c49ec1f2ebca65c36f504d72df46", - "https://bcr.bazel.build/modules/googletest/1.17.0/source.json": "38e4454b25fc30f15439c0378e57909ab1fd0a443158aa35aec685da727cd713", - "https://bcr.bazel.build/modules/jq.bzl/0.1.0/MODULE.bazel": "2ce69b1af49952cd4121a9c3055faa679e748ce774c7f1fda9657f936cae902f", - "https://bcr.bazel.build/modules/jq.bzl/0.1.0/source.json": "746bf13cac0860f091df5e4911d0c593971cd8796b5ad4e809b2f8e133eee3d5", - "https://bcr.bazel.build/modules/jsoncpp/1.9.5/MODULE.bazel": "31271aedc59e815656f5736f282bb7509a97c7ecb43e927ac1a37966e0578075", - "https://bcr.bazel.build/modules/jsoncpp/1.9.6/MODULE.bazel": "2f8d20d3b7d54143213c4dfc3d98225c42de7d666011528dc8fe91591e2e17b0", - "https://bcr.bazel.build/modules/jsoncpp/1.9.6/source.json": "a04756d367a2126c3541682864ecec52f92cdee80a35735a3cb249ce015ca000", - "https://bcr.bazel.build/modules/libpfm/4.11.0/MODULE.bazel": "45061ff025b301940f1e30d2c16bea596c25b176c8b6b3087e92615adbd52902", - "https://bcr.bazel.build/modules/nlohmann_json/3.6.1/MODULE.bazel": "6f7b417dcc794d9add9e556673ad25cb3ba835224290f4f848f8e2db1e1fca74", - "https://bcr.bazel.build/modules/nlohmann_json/3.6.1/source.json": "f448c6e8963fdfa7eb831457df83ad63d3d6355018f6574fb017e8169deb43a9", - "https://bcr.bazel.build/modules/package_metadata/0.0.2/MODULE.bazel": "fb8d25550742674d63d7b250063d4580ca530499f045d70748b1b142081ebb92", - "https://bcr.bazel.build/modules/package_metadata/0.0.3/MODULE.bazel": "77890552ecea9e284b5424c9de827a58099348763a4359e975c359a83d4faa83", - "https://bcr.bazel.build/modules/package_metadata/0.0.5/MODULE.bazel": "ef4f9439e3270fdd6b9fd4dbc3d2f29d13888e44c529a1b243f7a31dfbc2e8e4", - "https://bcr.bazel.build/modules/package_metadata/0.0.7/MODULE.bazel": "7adb03933fc8401f495800cf4eafcff0edc6da0ff55c7db223ef69d19f689486", - "https://bcr.bazel.build/modules/package_metadata/0.0.7/source.json": "50639625e937b56115012674c797cca7a05a96b4878c87d803c13dc2b31de8a0", - "https://bcr.bazel.build/modules/platforms/0.0.10/MODULE.bazel": "8cb8efaf200bdeb2150d93e162c40f388529a25852b332cec879373771e48ed5", - "https://bcr.bazel.build/modules/platforms/0.0.11/MODULE.bazel": "0daefc49732e227caa8bfa834d65dc52e8cc18a2faf80df25e8caea151a9413f", - "https://bcr.bazel.build/modules/platforms/0.0.4/MODULE.bazel": "9b328e31ee156f53f3c416a64f8491f7eb731742655a47c9eec4703a71644aee", - "https://bcr.bazel.build/modules/platforms/0.0.5/MODULE.bazel": "5733b54ea419d5eaf7997054bb55f6a1d0b5ff8aedf0176fef9eea44f3acda37", - "https://bcr.bazel.build/modules/platforms/0.0.6/MODULE.bazel": "ad6eeef431dc52aefd2d77ed20a4b353f8ebf0f4ecdd26a807d2da5aa8cd0615", - "https://bcr.bazel.build/modules/platforms/0.0.7/MODULE.bazel": "72fd4a0ede9ee5c021f6a8dd92b503e089f46c227ba2813ff183b71616034814", - "https://bcr.bazel.build/modules/platforms/0.0.8/MODULE.bazel": "9f142c03e348f6d263719f5074b21ef3adf0b139ee4c5133e2aa35664da9eb2d", - "https://bcr.bazel.build/modules/platforms/0.0.9/MODULE.bazel": "4a87a60c927b56ddd67db50c89acaa62f4ce2a1d2149ccb63ffd871d5ce29ebc", - "https://bcr.bazel.build/modules/platforms/1.0.0/MODULE.bazel": "f05feb42b48f1b3c225e4ccf351f367be0371411a803198ec34a389fb22aa580", - "https://bcr.bazel.build/modules/platforms/1.0.0/source.json": "f4ff1fd412e0246fd38c82328eb209130ead81d62dcd5a9e40910f867f733d96", - "https://bcr.bazel.build/modules/protobuf/21.7/MODULE.bazel": "a5a29bb89544f9b97edce05642fac225a808b5b7be74038ea3640fae2f8e66a7", - "https://bcr.bazel.build/modules/protobuf/23.1/MODULE.bazel": "88b393b3eb4101d18129e5db51847cd40a5517a53e81216144a8c32dfeeca52a", - "https://bcr.bazel.build/modules/protobuf/24.4/MODULE.bazel": "7bc7ce5f2abf36b3b7b7c8218d3acdebb9426aeb35c2257c96445756f970eb12", - "https://bcr.bazel.build/modules/protobuf/27.0/MODULE.bazel": "7873b60be88844a0a1d8f80b9d5d20cfbd8495a689b8763e76c6372998d3f64c", - "https://bcr.bazel.build/modules/protobuf/27.1/MODULE.bazel": "703a7b614728bb06647f965264967a8ef1c39e09e8f167b3ca0bb1fd80449c0d", - "https://bcr.bazel.build/modules/protobuf/27.2/MODULE.bazel": "32450b50673882e4c8c3d10a83f3bc82161b213ed2f80d17e38bece8f165c295", - "https://bcr.bazel.build/modules/protobuf/29.0-rc2.bcr.1/MODULE.bazel": "52f4126f63a2f0bbf36b99c2a87648f08467a4eaf92ba726bc7d6a500bbf770c", - "https://bcr.bazel.build/modules/protobuf/29.0-rc2/MODULE.bazel": "6241d35983510143049943fc0d57937937122baf1b287862f9dc8590fc4c37df", - "https://bcr.bazel.build/modules/protobuf/29.0-rc3/MODULE.bazel": "33c2dfa286578573afc55a7acaea3cada4122b9631007c594bf0729f41c8de92", - "https://bcr.bazel.build/modules/protobuf/29.0/MODULE.bazel": "319dc8bf4c679ff87e71b1ccfb5a6e90a6dbc4693501d471f48662ac46d04e4e", - "https://bcr.bazel.build/modules/protobuf/29.1/MODULE.bazel": "557c3457560ff49e122ed76c0bc3397a64af9574691cb8201b4e46d4ab2ecb95", - "https://bcr.bazel.build/modules/protobuf/29.3/MODULE.bazel": "77480eea5fb5541903e49683f24dc3e09f4a79e0eea247414887bb9fc0066e94", - "https://bcr.bazel.build/modules/protobuf/3.19.0/MODULE.bazel": "6b5fbb433f760a99a22b18b6850ed5784ef0e9928a72668b66e4d7ccd47db9b0", - "https://bcr.bazel.build/modules/protobuf/3.19.2/MODULE.bazel": "532ffe5f2186b69fdde039efe6df13ba726ff338c6bc82275ad433013fa10573", - "https://bcr.bazel.build/modules/protobuf/3.19.6/MODULE.bazel": "9233edc5e1f2ee276a60de3eaa47ac4132302ef9643238f23128fea53ea12858", - "https://bcr.bazel.build/modules/protobuf/31.1/MODULE.bazel": "379a389bb330b7b8c1cdf331cc90bf3e13de5614799b3b52cdb7c6f389f6b38e", - "https://bcr.bazel.build/modules/protobuf/32.1/MODULE.bazel": "89cd2866a9cb07fee9ff74c41ceace11554f32e0d849de4e23ac55515cfada4d", - "https://bcr.bazel.build/modules/protobuf/33.4/MODULE.bazel": "114775b816b38b6d0ca620450d6b02550c60ceedfdc8d9a229833b34a223dc42", - "https://bcr.bazel.build/modules/protobuf/33.4/source.json": "555f8686b4c7d6b5ba731fbea13bf656b4bfd9a7ff629c1d9d3f6e1d6155de79", - "https://bcr.bazel.build/modules/pybind11_bazel/2.11.1/MODULE.bazel": "88af1c246226d87e65be78ed49ecd1e6f5e98648558c14ce99176da041dc378e", - "https://bcr.bazel.build/modules/pybind11_bazel/2.12.0/MODULE.bazel": "e6f4c20442eaa7c90d7190d8dc539d0ab422f95c65a57cc59562170c58ae3d34", - "https://bcr.bazel.build/modules/pybind11_bazel/2.12.0/source.json": "6900fdc8a9e95866b8c0d4ad4aba4d4236317b5c1cd04c502df3f0d33afed680", - "https://bcr.bazel.build/modules/re2/2023-09-01/MODULE.bazel": "cb3d511531b16cfc78a225a9e2136007a48cf8a677e4264baeab57fe78a80206", - "https://bcr.bazel.build/modules/re2/2024-07-02.bcr.1/MODULE.bazel": "b4963dda9b31080be1905ef085ecd7dd6cd47c05c79b9cdf83ade83ab2ab271a", - "https://bcr.bazel.build/modules/re2/2024-07-02.bcr.1/source.json": "2ff292be6ef3340325ce8a045ecc326e92cbfab47c7cbab4bd85d28971b97ac4", - "https://bcr.bazel.build/modules/re2/2024-07-02/MODULE.bazel": "0eadc4395959969297cbcf31a249ff457f2f1d456228c67719480205aa306daa", - "https://bcr.bazel.build/modules/rules_android/0.1.1/MODULE.bazel": "48809ab0091b07ad0182defb787c4c5328bd3a278938415c00a7b69b50c4d3a8", - "https://bcr.bazel.build/modules/rules_android/0.6.4/MODULE.bazel": "b4cde12d506dd65d82b2be39761f49f5797303343a3d5b4ee191c0cdf9ef387c", - "https://bcr.bazel.build/modules/rules_android/0.7.1/MODULE.bazel": "a806fc382a774252f228a40e3b11b9fcc6276f8778c7fb33e9f72937c6258363", - "https://bcr.bazel.build/modules/rules_android/0.7.1/source.json": "151440aed3f0f73a00d4ed5cec5d31f63a6fef9b95d8fab1eb1810150fa525f2", - "https://bcr.bazel.build/modules/rules_apple/3.16.0/MODULE.bazel": "0d1caf0b8375942ce98ea944be754a18874041e4e0459401d925577624d3a54a", - "https://bcr.bazel.build/modules/rules_apple/4.1.0/MODULE.bazel": "76e10fd4a48038d3fc7c5dc6e63b7063bbf5304a2e3bd42edda6ec660eebea68", - "https://bcr.bazel.build/modules/rules_apple/4.1.0/source.json": "8ee81e1708756f81b343a5eb2b2f0b953f1d25c4ab3d4a68dc02754872e80715", - "https://bcr.bazel.build/modules/rules_cc/0.0.1/MODULE.bazel": "cb2aa0747f84c6c3a78dad4e2049c154f08ab9d166b1273835a8174940365647", - "https://bcr.bazel.build/modules/rules_cc/0.0.10/MODULE.bazel": "ec1705118f7eaedd6e118508d3d26deba2a4e76476ada7e0e3965211be012002", - "https://bcr.bazel.build/modules/rules_cc/0.0.13/MODULE.bazel": "0e8529ed7b323dad0775ff924d2ae5af7640b23553dfcd4d34344c7e7a867191", - "https://bcr.bazel.build/modules/rules_cc/0.0.14/MODULE.bazel": "5e343a3aac88b8d7af3b1b6d2093b55c347b8eefc2e7d1442f7a02dc8fea48ac", - "https://bcr.bazel.build/modules/rules_cc/0.0.15/MODULE.bazel": "6704c35f7b4a72502ee81f61bf88706b54f06b3cbe5558ac17e2e14666cd5dcc", - "https://bcr.bazel.build/modules/rules_cc/0.0.16/MODULE.bazel": "7661303b8fc1b4d7f532e54e9d6565771fea666fbdf839e0a86affcd02defe87", - "https://bcr.bazel.build/modules/rules_cc/0.0.17/MODULE.bazel": "2ae1d8f4238ec67d7185d8861cb0a2cdf4bc608697c331b95bf990e69b62e64a", - "https://bcr.bazel.build/modules/rules_cc/0.0.2/MODULE.bazel": "6915987c90970493ab97393024c156ea8fb9f3bea953b2f3ec05c34f19b5695c", - "https://bcr.bazel.build/modules/rules_cc/0.0.6/MODULE.bazel": "abf360251023dfe3efcef65ab9d56beefa8394d4176dd29529750e1c57eaa33f", - "https://bcr.bazel.build/modules/rules_cc/0.0.8/MODULE.bazel": "964c85c82cfeb6f3855e6a07054fdb159aced38e99a5eecf7bce9d53990afa3e", - "https://bcr.bazel.build/modules/rules_cc/0.0.9/MODULE.bazel": "836e76439f354b89afe6a911a7adf59a6b2518fafb174483ad78a2a2fde7b1c5", - "https://bcr.bazel.build/modules/rules_cc/0.1.1/MODULE.bazel": "2f0222a6f229f0bf44cd711dc13c858dad98c62d52bd51d8fc3a764a83125513", - "https://bcr.bazel.build/modules/rules_cc/0.1.2/MODULE.bazel": "557ddc3a96858ec0d465a87c0a931054d7dcfd6583af2c7ed3baf494407fd8d0", - "https://bcr.bazel.build/modules/rules_cc/0.1.5/MODULE.bazel": "88dfc9361e8b5ae1008ac38f7cdfd45ad738e4fa676a3ad67d19204f045a1fd8", - "https://bcr.bazel.build/modules/rules_cc/0.2.0/MODULE.bazel": "b5c17f90458caae90d2ccd114c81970062946f49f355610ed89bebf954f5783c", - "https://bcr.bazel.build/modules/rules_cc/0.2.13/MODULE.bazel": "eecdd666eda6be16a8d9dc15e44b5c75133405e820f620a234acc4b1fdc5aa37", - "https://bcr.bazel.build/modules/rules_cc/0.2.14/MODULE.bazel": "353c99ed148887ee89c54a17d4100ae7e7e436593d104b668476019023b58df8", - "https://bcr.bazel.build/modules/rules_cc/0.2.17/MODULE.bazel": "1849602c86cb60da8613d2de887f9566a6d354a6df6d7009f9d04a14402f9a84", - "https://bcr.bazel.build/modules/rules_cc/0.2.17/source.json": "3832f45d145354049137c0090df04629d9c2b5493dc5c2bf46f1834040133a07", - "https://bcr.bazel.build/modules/rules_cc/0.2.4/MODULE.bazel": "1ff1223dfd24f3ecf8f028446d4a27608aa43c3f41e346d22838a4223980b8cc", - "https://bcr.bazel.build/modules/rules_cc/0.2.8/MODULE.bazel": "f1df20f0bf22c28192a794f29b501ee2018fa37a3862a1a2132ae2940a23a642", - "https://bcr.bazel.build/modules/rules_foreign_cc/0.9.0/MODULE.bazel": "c9e8c682bf75b0e7c704166d79b599f93b72cfca5ad7477df596947891feeef6", - "https://bcr.bazel.build/modules/rules_fuzzing/0.5.2/MODULE.bazel": "40c97d1144356f52905566c55811f13b299453a14ac7769dfba2ac38192337a8", - "https://bcr.bazel.build/modules/rules_go/0.41.0/MODULE.bazel": "55861d8e8bb0e62cbd2896f60ff303f62ffcb0eddb74ecb0e5c0cbe36fc292c8", - "https://bcr.bazel.build/modules/rules_go/0.42.0/MODULE.bazel": "8cfa875b9aa8c6fce2b2e5925e73c1388173ea3c32a0db4d2b4804b453c14270", - "https://bcr.bazel.build/modules/rules_go/0.46.0/MODULE.bazel": "3477df8bdcc49e698b9d25f734c4f3a9f5931ff34ee48a2c662be168f5f2d3fd", - "https://bcr.bazel.build/modules/rules_go/0.50.1/MODULE.bazel": "b91a308dc5782bb0a8021ad4330c81fea5bda77f96b9e4c117b9b9c8f6665ee0", - "https://bcr.bazel.build/modules/rules_go/0.51.0-rc2/MODULE.bazel": "edfc3a9cea7bedb0eaaff37b0d7817c1a4bf72b3c615580b0ffcee6c52690fd4", - "https://bcr.bazel.build/modules/rules_go/0.53.0/MODULE.bazel": "a4ed760d3ac0dbc0d7b967631a9a3fd9100d28f7d9fcf214b4df87d4bfff5f9a", - "https://bcr.bazel.build/modules/rules_go/0.59.0/MODULE.bazel": "b7e43e7414a3139a7547d1b4909b29085fbe5182b6c58cbe1ed4c6272815aeae", - "https://bcr.bazel.build/modules/rules_go/0.59.0/source.json": "1df17bb7865cfc029492c30163cee891d0dd8658ea0d5bfdf252c4b6db5c1ef6", - "https://bcr.bazel.build/modules/rules_java/4.0.0/MODULE.bazel": "5a78a7ae82cd1a33cef56dc578c7d2a46ed0dca12643ee45edbb8417899e6f74", - "https://bcr.bazel.build/modules/rules_java/5.3.5/MODULE.bazel": "a4ec4f2db570171e3e5eb753276ee4b389bae16b96207e9d3230895c99644b86", - "https://bcr.bazel.build/modules/rules_java/6.0.0/MODULE.bazel": "8a43b7df601a7ec1af61d79345c17b31ea1fedc6711fd4abfd013ea612978e39", - "https://bcr.bazel.build/modules/rules_java/6.3.0/MODULE.bazel": "a97c7678c19f236a956ad260d59c86e10a463badb7eb2eda787490f4c969b963", - "https://bcr.bazel.build/modules/rules_java/6.4.0/MODULE.bazel": "e986a9fe25aeaa84ac17ca093ef13a4637f6107375f64667a15999f77db6c8f6", - "https://bcr.bazel.build/modules/rules_java/6.5.2/MODULE.bazel": "1d440d262d0e08453fa0c4d8f699ba81609ed0e9a9a0f02cd10b3e7942e61e31", - "https://bcr.bazel.build/modules/rules_java/7.1.0/MODULE.bazel": "30d9135a2b6561c761bd67bd4990da591e6bdc128790ce3e7afd6a3558b2fb64", - "https://bcr.bazel.build/modules/rules_java/7.10.0/MODULE.bazel": "530c3beb3067e870561739f1144329a21c851ff771cd752a49e06e3dc9c2e71a", - "https://bcr.bazel.build/modules/rules_java/7.12.2/MODULE.bazel": "579c505165ee757a4280ef83cda0150eea193eed3bef50b1004ba88b99da6de6", - "https://bcr.bazel.build/modules/rules_java/7.2.0/MODULE.bazel": "06c0334c9be61e6cef2c8c84a7800cef502063269a5af25ceb100b192453d4ab", - "https://bcr.bazel.build/modules/rules_java/7.3.2/MODULE.bazel": "50dece891cfdf1741ea230d001aa9c14398062f2b7c066470accace78e412bc2", - "https://bcr.bazel.build/modules/rules_java/7.4.0/MODULE.bazel": "a592852f8a3dd539e82ee6542013bf2cadfc4c6946be8941e189d224500a8934", - "https://bcr.bazel.build/modules/rules_java/7.6.1/MODULE.bazel": "2f14b7e8a1aa2f67ae92bc69d1ec0fa8d9f827c4e17ff5e5f02e91caa3b2d0fe", - "https://bcr.bazel.build/modules/rules_java/8.15.2/MODULE.bazel": "5cc6698c822b2f9ef90ca5558599851bed8c3b13f1f8eb140d9bfec638d2acb4", - "https://bcr.bazel.build/modules/rules_java/8.3.2/MODULE.bazel": "7336d5511ad5af0b8615fdc7477535a2e4e723a357b6713af439fe8cf0195017", - "https://bcr.bazel.build/modules/rules_java/8.5.1/MODULE.bazel": "d8a9e38cc5228881f7055a6079f6f7821a073df3744d441978e7a43e20226939", - "https://bcr.bazel.build/modules/rules_java/8.6.0/MODULE.bazel": "9c064c434606d75a086f15ade5edb514308cccd1544c2b2a89bbac4310e41c71", - "https://bcr.bazel.build/modules/rules_java/8.6.1/MODULE.bazel": "f4808e2ab5b0197f094cabce9f4b006a27766beb6a9975931da07099560ca9c2", - "https://bcr.bazel.build/modules/rules_java/8.6.3/MODULE.bazel": "e90505b7a931d194245ffcfb6ff4ca8ef9d46b4e830d12e64817752e0198e2ed", - "https://bcr.bazel.build/modules/rules_java/8.9.0/MODULE.bazel": "e17c876cb53dcd817b7b7f0d2985b710610169729e8c371b2221cacdcd3dce4a", - "https://bcr.bazel.build/modules/rules_java/9.1.0/MODULE.bazel": "ee63f27e36a3fada80342869361182f120a9819c74320e8e65b1e04ba0cd7a9d", - "https://bcr.bazel.build/modules/rules_java/9.3.0/MODULE.bazel": "f657c72d65ac449caae9abf2e68e66c0d36f9416848c4c4903d0b3234229e7f2", - "https://bcr.bazel.build/modules/rules_java/9.3.0/source.json": "59ae7e662c3c7042b88bbb42ad12483523e234c65ebe4c51611baa43e85cb248", - "https://bcr.bazel.build/modules/rules_jvm_external/4.4.2/MODULE.bazel": "a56b85e418c83eb1839819f0b515c431010160383306d13ec21959ac412d2fe7", - "https://bcr.bazel.build/modules/rules_jvm_external/5.1/MODULE.bazel": "33f6f999e03183f7d088c9be518a63467dfd0be94a11d0055fe2d210f89aa909", - "https://bcr.bazel.build/modules/rules_jvm_external/5.2/MODULE.bazel": "d9351ba35217ad0de03816ef3ed63f89d411349353077348a45348b096615036", - "https://bcr.bazel.build/modules/rules_jvm_external/5.3/MODULE.bazel": "bf93870767689637164657731849fb887ad086739bd5d360d90007a581d5527d", - "https://bcr.bazel.build/modules/rules_jvm_external/6.1/MODULE.bazel": "75b5fec090dbd46cf9b7d8ea08cf84a0472d92ba3585b476f44c326eda8059c4", - "https://bcr.bazel.build/modules/rules_jvm_external/6.2/MODULE.bazel": "36a6e52487a855f33cb960724eb56547fa87e2c98a0474c3acad94339d7f8e99", - "https://bcr.bazel.build/modules/rules_jvm_external/6.3/MODULE.bazel": "c998e060b85f71e00de5ec552019347c8bca255062c990ac02d051bb80a38df0", - "https://bcr.bazel.build/modules/rules_jvm_external/6.6/MODULE.bazel": "153042249c7060536dc95b6bb9f9bb8063b8a0b0cb7acdb381bddbc2374aed55", - "https://bcr.bazel.build/modules/rules_jvm_external/6.7/MODULE.bazel": "e717beabc4d091ecb2c803c2d341b88590e9116b8bf7947915eeb33aab4f96dd", - "https://bcr.bazel.build/modules/rules_jvm_external/6.8/MODULE.bazel": "b5afe861e867e4c8e5b88e401cb7955bd35924258f97b1862cc966cbcf4f1a62", - "https://bcr.bazel.build/modules/rules_jvm_external/6.9/MODULE.bazel": "07c5db05527db7744a54fcffd653e1550d40e0540207a7f7e6d0a4de5bef8274", - "https://bcr.bazel.build/modules/rules_jvm_external/7.0/MODULE.bazel": "421482bdbcf05709f933c96b867a599deb517f2804ceb3e74511880610cfbf71", - "https://bcr.bazel.build/modules/rules_jvm_external/7.0/source.json": "714cd003eadf5be5c83268311fe8e951db39f802babeaddc536b3560dc8f6faf", - "https://bcr.bazel.build/modules/rules_kotlin/1.9.0/MODULE.bazel": "ef85697305025e5a61f395d4eaede272a5393cee479ace6686dba707de804d59", - "https://bcr.bazel.build/modules/rules_kotlin/1.9.5/MODULE.bazel": "043a16a572f610558ec2030db3ff0c9938574e7dd9f58bded1bb07c0192ef025", - "https://bcr.bazel.build/modules/rules_kotlin/1.9.6/MODULE.bazel": "d269a01a18ee74d0335450b10f62c9ed81f2321d7958a2934e44272fe82dcef3", - "https://bcr.bazel.build/modules/rules_kotlin/2.2.2/MODULE.bazel": "00d39c5e0fa78cd86193946265bb849e7878c24e44260f9525108428852b315c", - "https://bcr.bazel.build/modules/rules_kotlin/2.2.2/source.json": "7a32c2259c79ae0c9a036121f120de825e3ba5f0f3a209ffbbdccf4dc62489b9", - "https://bcr.bazel.build/modules/rules_license/0.0.3/MODULE.bazel": "627e9ab0247f7d1e05736b59dbb1b6871373de5ad31c3011880b4133cafd4bd0", - "https://bcr.bazel.build/modules/rules_license/0.0.7/MODULE.bazel": "088fbeb0b6a419005b89cf93fe62d9517c0a2b8bb56af3244af65ecfe37e7d5d", - "https://bcr.bazel.build/modules/rules_license/1.0.0/MODULE.bazel": "a7fda60eefdf3d8c827262ba499957e4df06f659330bbe6cdbdb975b768bb65c", - "https://bcr.bazel.build/modules/rules_license/1.0.0/source.json": "a52c89e54cc311196e478f8382df91c15f7a2bfdf4c6cd0e2675cc2ff0b56efb", - "https://bcr.bazel.build/modules/rules_pkg/0.7.0/MODULE.bazel": "df99f03fc7934a4737122518bb87e667e62d780b610910f0447665a7e2be62dc", - "https://bcr.bazel.build/modules/rules_pkg/1.0.1/MODULE.bazel": "5b1df97dbc29623bccdf2b0dcd0f5cb08e2f2c9050aab1092fd39a41e82686ff", - "https://bcr.bazel.build/modules/rules_pkg/1.0.1/source.json": "bd82e5d7b9ce2d31e380dd9f50c111d678c3bdaca190cb76b0e1c71b05e1ba8a", - "https://bcr.bazel.build/modules/rules_proto/4.0.0/MODULE.bazel": "a7a7b6ce9bee418c1a760b3d84f83a299ad6952f9903c67f19e4edd964894e06", - "https://bcr.bazel.build/modules/rules_proto/5.3.0-21.7/MODULE.bazel": "e8dff86b0971688790ae75528fe1813f71809b5afd57facb44dad9e8eca631b7", - "https://bcr.bazel.build/modules/rules_proto/6.0.0-rc1/MODULE.bazel": "1e5b502e2e1a9e825eef74476a5a1ee524a92297085015a052510b09a1a09483", - "https://bcr.bazel.build/modules/rules_proto/6.0.0/MODULE.bazel": "b531d7f09f58dce456cd61b4579ce8c86b38544da75184eadaf0a7cb7966453f", - "https://bcr.bazel.build/modules/rules_proto/6.0.2/MODULE.bazel": "ce916b775a62b90b61888052a416ccdda405212b6aaeb39522f7dc53431a5e73", - "https://bcr.bazel.build/modules/rules_proto/7.0.2/MODULE.bazel": "bf81793bd6d2ad89a37a40693e56c61b0ee30f7a7fdbaf3eabbf5f39de47dea2", - "https://bcr.bazel.build/modules/rules_proto/7.1.0/MODULE.bazel": "002d62d9108f75bb807cd56245d45648f38275cb3a99dcd45dfb864c5d74cb96", - "https://bcr.bazel.build/modules/rules_proto/7.1.0/source.json": "39f89066c12c24097854e8f57ab8558929f9c8d474d34b2c00ac04630ad8940e", - "https://bcr.bazel.build/modules/rules_proto_grpc/5.8.0/MODULE.bazel": "38e2acb9aa480a04c780fa4b11bfaae0fa16e05f85f6d8fc32e044bad683ed86", - "https://bcr.bazel.build/modules/rules_proto_grpc/5.8.0/source.json": "142d5c5dd650d0f817936835738daa7df2256dfb33c247163b600ab28cba31d1", - "https://bcr.bazel.build/modules/rules_proto_grpc_java/5.8.0/MODULE.bazel": "0e24d1d4716b017afa6c85649bee47144066310057fbce7bdb5661aecd525571", - "https://bcr.bazel.build/modules/rules_proto_grpc_java/5.8.0/source.json": "965a546920ecf67e8cbb9e060f35d7f87a6fcd4319db0cf47cbc66c30327b1ee", - "https://bcr.bazel.build/modules/rules_python/0.10.2/MODULE.bazel": "cc82bc96f2997baa545ab3ce73f196d040ffb8756fd2d66125a530031cd90e5f", - "https://bcr.bazel.build/modules/rules_python/0.23.1/MODULE.bazel": "49ffccf0511cb8414de28321f5fcf2a31312b47c40cc21577144b7447f2bf300", - "https://bcr.bazel.build/modules/rules_python/0.25.0/MODULE.bazel": "72f1506841c920a1afec76975b35312410eea3aa7b63267436bfb1dd91d2d382", - "https://bcr.bazel.build/modules/rules_python/0.28.0/MODULE.bazel": "cba2573d870babc976664a912539b320cbaa7114cd3e8f053c720171cde331ed", - "https://bcr.bazel.build/modules/rules_python/0.31.0/MODULE.bazel": "93a43dc47ee570e6ec9f5779b2e64c1476a6ce921c48cc9a1678a91dd5f8fd58", - "https://bcr.bazel.build/modules/rules_python/0.33.2/MODULE.bazel": "3e036c4ad8d804a4dad897d333d8dce200d943df4827cb849840055be8d2e937", - "https://bcr.bazel.build/modules/rules_python/0.37.1/MODULE.bazel": "3faeb2d9fa0a81f8980643ee33f212308f4d93eea4b9ce6f36d0b742e71e9500", - "https://bcr.bazel.build/modules/rules_python/0.37.2/MODULE.bazel": "b5ffde91410745750b6c13be1c5dc4555ef5bc50562af4a89fd77807fdde626a", - "https://bcr.bazel.build/modules/rules_python/0.4.0/MODULE.bazel": "9208ee05fd48bf09ac60ed269791cf17fb343db56c8226a720fbb1cdf467166c", - "https://bcr.bazel.build/modules/rules_python/0.40.0/MODULE.bazel": "9d1a3cd88ed7d8e39583d9ffe56ae8a244f67783ae89b60caafc9f5cf318ada7", - "https://bcr.bazel.build/modules/rules_python/1.0.0/MODULE.bazel": "898a3d999c22caa585eb062b600f88654bf92efb204fa346fb55f6f8edffca43", - "https://bcr.bazel.build/modules/rules_python/1.3.0/MODULE.bazel": "8361d57eafb67c09b75bf4bbe6be360e1b8f4f18118ab48037f2bd50aa2ccb13", - "https://bcr.bazel.build/modules/rules_python/1.4.1/MODULE.bazel": "8991ad45bdc25018301d6b7e1d3626afc3c8af8aaf4bc04f23d0b99c938b73a6", - "https://bcr.bazel.build/modules/rules_python/1.6.0/MODULE.bazel": "7e04ad8f8d5bea40451cf80b1bd8262552aa73f841415d20db96b7241bd027d8", - "https://bcr.bazel.build/modules/rules_python/1.7.0/MODULE.bazel": "d01f995ecd137abf30238ad9ce97f8fc3ac57289c8b24bd0bf53324d937a14f8", - "https://bcr.bazel.build/modules/rules_python/1.7.0/source.json": "028a084b65dcf8f4dc4f82f8778dbe65df133f234b316828a82e060d81bdce32", - "https://bcr.bazel.build/modules/rules_robolectric/4.14.1.2/MODULE.bazel": "d44fec647d0aeb67b9f3b980cf68ba634976f3ae7ccd6c07d790b59b87a4f251", - "https://bcr.bazel.build/modules/rules_robolectric/4.14.1.2/source.json": "37c10335f2361c337c5c1f34ed36d2da70534c23088062b33a8bdaab68aa9dea", - "https://bcr.bazel.build/modules/rules_rust/0.66.0/MODULE.bazel": "86ef763a582f4739a27029bdcc6c562258ed0ea6f8d58294b049e215ceb251b3", - "https://bcr.bazel.build/modules/rules_rust/0.66.0/source.json": "5c2252a61ccc19b4e420c7c06429c8f51d8edd7b743dcb4b60571e7d40b5aa57", - "https://bcr.bazel.build/modules/rules_shell/0.1.2/MODULE.bazel": "66e4ca3ce084b04af0b9ff05ff14cab4e5df7503973818bb91cbc6cda08d32fc", - "https://bcr.bazel.build/modules/rules_shell/0.2.0/MODULE.bazel": "fda8a652ab3c7d8fee214de05e7a9916d8b28082234e8d2c0094505c5268ed3c", - "https://bcr.bazel.build/modules/rules_shell/0.3.0/MODULE.bazel": "de4402cd12f4cc8fda2354fce179fdb068c0b9ca1ec2d2b17b3e21b24c1a937b", - "https://bcr.bazel.build/modules/rules_shell/0.4.0/MODULE.bazel": "0f8f11bb3cd11755f0b48c1de0bbcf62b4b34421023aa41a2fc74ef68d9584f0", - "https://bcr.bazel.build/modules/rules_shell/0.4.1/MODULE.bazel": "00e501db01bbf4e3e1dd1595959092c2fadf2087b2852d3f553b5370f5633592", - "https://bcr.bazel.build/modules/rules_shell/0.6.1/MODULE.bazel": "72e76b0eea4e81611ef5452aa82b3da34caca0c8b7b5c0c9584338aa93bae26b", - "https://bcr.bazel.build/modules/rules_shell/0.8.0/MODULE.bazel": "f6a89f1d6a669a26f28fe814503857055d76306b79cfc11d12399af08d0b80ae", - "https://bcr.bazel.build/modules/rules_shell/0.8.0/source.json": "eb53cc815bc503c6683c5fe12d943f98883f81fc22f51403ec8a95610cba4195", - "https://bcr.bazel.build/modules/rules_spring/2.6.3/MODULE.bazel": "c2f719ea89af7bd3957a322c32430ee59f03fa467a4b1e208eba95a61ddcaa40", - "https://bcr.bazel.build/modules/rules_spring/2.6.3/source.json": "ac68bba4571d93871193ac0e85e3a20e6149221f12dc7f04fa8b042485cd2042", - "https://bcr.bazel.build/modules/rules_swift/1.16.0/MODULE.bazel": "4a09f199545a60d09895e8281362b1ff3bb08bbde69c6fc87aff5b92fcc916ca", - "https://bcr.bazel.build/modules/rules_swift/2.1.1/MODULE.bazel": "494900a80f944fc7aa61500c2073d9729dff0b764f0e89b824eb746959bc1046", - "https://bcr.bazel.build/modules/rules_swift/2.4.0/MODULE.bazel": "1639617eb1ede28d774d967a738b4a68b0accb40650beadb57c21846beab5efd", - "https://bcr.bazel.build/modules/rules_swift/3.1.2/MODULE.bazel": "72c8f5cf9d26427cee6c76c8e3853eb46ce6b0412a081b2b6db6e8ad56267400", - "https://bcr.bazel.build/modules/rules_swift/3.1.2/source.json": "e85761f3098a6faf40b8187695e3de6d97944e98abd0d8ce579cb2daf6319a66", - "https://bcr.bazel.build/modules/stardoc/0.5.1/MODULE.bazel": "1a05d92974d0c122f5ccf09291442580317cdd859f07a8655f1db9a60374f9f8", - "https://bcr.bazel.build/modules/stardoc/0.5.3/MODULE.bazel": "c7f6948dae6999bf0db32c1858ae345f112cacf98f174c7a8bb707e41b974f1c", - "https://bcr.bazel.build/modules/stardoc/0.5.6/MODULE.bazel": "c43dabc564990eeab55e25ed61c07a1aadafe9ece96a4efabb3f8bf9063b71ef", - "https://bcr.bazel.build/modules/stardoc/0.6.2/MODULE.bazel": "7060193196395f5dd668eda046ccbeacebfd98efc77fed418dbe2b82ffaa39fd", - "https://bcr.bazel.build/modules/stardoc/0.7.0/MODULE.bazel": "05e3d6d30c099b6770e97da986c53bd31844d7f13d41412480ea265ac9e8079c", - "https://bcr.bazel.build/modules/stardoc/0.7.1/MODULE.bazel": "3548faea4ee5dda5580f9af150e79d0f6aea934fc60c1cc50f4efdd9420759e7", - "https://bcr.bazel.build/modules/stardoc/0.7.2/MODULE.bazel": "fc152419aa2ea0f51c29583fab1e8c99ddefd5b3778421845606ee628629e0e5", - "https://bcr.bazel.build/modules/stardoc/0.7.2/source.json": "58b029e5e901d6802967754adf0a9056747e8176f017cfe3607c0851f4d42216", - "https://bcr.bazel.build/modules/swift_argument_parser/1.3.1.1/MODULE.bazel": "5e463fbfba7b1701d957555ed45097d7f984211330106ccd1352c6e0af0dcf91", - "https://bcr.bazel.build/modules/swift_argument_parser/1.3.1.2/MODULE.bazel": "75aab2373a4bbe2a1260b9bf2a1ebbdbf872d3bd36f80bff058dccd82e89422f", - "https://bcr.bazel.build/modules/swift_argument_parser/1.3.1.2/source.json": "5fba48bbe0ba48761f9e9f75f92876cafb5d07c0ce059cc7a8027416de94a05b", - "https://bcr.bazel.build/modules/tar.bzl/0.2.1/MODULE.bazel": "52d1c00a80a8cc67acbd01649e83d8dd6a9dc426a6c0b754a04fe8c219c76468", - "https://bcr.bazel.build/modules/tar.bzl/0.5.1/MODULE.bazel": "7c2eb3dcfc53b0f3d6f9acdfd911ca803eaf92aadf54f8ca6e4c1f3aee288351", - "https://bcr.bazel.build/modules/tar.bzl/0.5.1/source.json": "deed3094f7cc779ed1d37a68403847b0e38d9dd9d931e03cb90825f3368b515f", - "https://bcr.bazel.build/modules/toml.bzl/0.3.0/MODULE.bazel": "5016e5dd1ad2200e119a4b28b2b3935e276c4b480f2fe3e952bea7eeba88f578", - "https://bcr.bazel.build/modules/toml.bzl/0.3.0/source.json": "0cf7c878c419b37ddb55f3dd93dd7c0c409bd7c4efacb3da504e0748780b2fa9", - "https://bcr.bazel.build/modules/toolchains_protoc/0.5.0/MODULE.bazel": "e649dcd74790d8b186517588c827a777dfa67acfc4cbd733721c4be143ea107f", - "https://bcr.bazel.build/modules/toolchains_protoc/0.5.0/source.json": "9152bf33827a44f796f94f486252fc0128d9efc2413246ebb09a234bb628a846", - "https://bcr.bazel.build/modules/upb/0.0.0-20220923-a547704/MODULE.bazel": "7298990c00040a0e2f121f6c32544bab27d4452f80d9ce51349b1a28f3005c43", - "https://bcr.bazel.build/modules/upb/0.0.0-20230516-61a97ef/MODULE.bazel": "c0df5e35ad55e264160417fd0875932ee3c9dda63d9fccace35ac62f45e1b6f9", - "https://bcr.bazel.build/modules/yq.bzl/0.1.1/MODULE.bazel": "9039681f9bcb8958ee2c87ffc74bdafba9f4369096a2b5634b88abc0eaefa072", - "https://bcr.bazel.build/modules/yq.bzl/0.1.1/source.json": "2d2bad780a9f2b9195a4a370314d2c17ae95eaa745cefc2e12fbc49759b15aa3", - "https://bcr.bazel.build/modules/zlib/1.2.11/MODULE.bazel": "07b389abc85fdbca459b69e2ec656ae5622873af3f845e1c9d80fe179f3effa0", - "https://bcr.bazel.build/modules/zlib/1.2.12/MODULE.bazel": "3b1a8834ada2a883674be8cbd36ede1b6ec481477ada359cd2d3ddc562340b27", - "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.5/MODULE.bazel": "eec517b5bbe5492629466e11dae908d043364302283de25581e3eb944326c4ca", - "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.5/source.json": "22bc55c47af97246cfc093d0acf683a7869377de362b5d1c552c2c2e16b7a806", - "https://bcr.bazel.build/modules/zlib/1.3.1/MODULE.bazel": "751c9940dcfe869f5f7274e1295422a34623555916eb98c174c1e945594bf198" - }, - "selectedYankedVersions": {}, - "moduleExtensions": { - "@@rules_android+//rules/android_sdk_repository:rule.bzl%android_sdk_repository_extension": { - "general": { - "bzlTransitiveDigest": "+rMrzIrv7sImYmkbXJYv+gFpTJQ79X3MpwwMLI2A+oA=", - "usagesDigest": "iEGI2aNDMkHt9LXCdViLNUUOslpiVj2DrevWWXZEFnU=", - "recordedInputs": [], - "generatedRepoSpecs": { - "androidsdk": { - "repoRuleId": "@@rules_android+//rules/android_sdk_repository:rule.bzl%_android_sdk_repository", - "attributes": {} - } - } - } - }, - "@@rules_proto_grpc_java+//:module_extensions.bzl%download_plugins": { - "general": { - "bzlTransitiveDigest": "IE3yt9aIrDy0PwVS/eJ5bVU9q4C0yoq+KLdHBxYlLjs=", - "usagesDigest": "QLMlNNEIKA7pTDNTyvjS58dkCcrTTmUgPwGYxofkFyk=", - "recordedInputs": [ - "REPO_MAPPING:rules_proto_grpc_java+,bazel_tools bazel_tools" - ], - "generatedRepoSpecs": { - "grpc_java_plugin_darwin_arm64": { - "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_file", - "attributes": { - "executable": true, - "sha256": "7f286de20e82ea674a5cdf59b6012f056a6d0ee57eb2a85eda0cec4bc3db4761", - "url": "https://repo1.maven.org/maven2/io/grpc/protoc-gen-grpc-java/1.74.0/protoc-gen-grpc-java-1.74.0-osx-aarch_64.exe" - } - }, - "grpc_java_plugin_darwin_x86_64": { - "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_file", - "attributes": { - "executable": true, - "sha256": "7f286de20e82ea674a5cdf59b6012f056a6d0ee57eb2a85eda0cec4bc3db4761", - "url": "https://repo1.maven.org/maven2/io/grpc/protoc-gen-grpc-java/1.74.0/protoc-gen-grpc-java-1.74.0-osx-x86_64.exe" - } - }, - "grpc_java_plugin_linux_arm64": { - "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_file", - "attributes": { - "executable": true, - "sha256": "b4d0525c624e38efbec104d027a555e7a256a96eaf3e409972777d659a4b1eb6", - "url": "https://repo1.maven.org/maven2/io/grpc/protoc-gen-grpc-java/1.74.0/protoc-gen-grpc-java-1.74.0-linux-aarch_64.exe" - } - }, - "grpc_java_plugin_linux_x86_64": { - "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_file", - "attributes": { - "executable": true, - "sha256": "bb6f37cbacea579cba9916d07b05b15beaaf9abdea271323fabdea4b6568f18c", - "url": "https://repo1.maven.org/maven2/io/grpc/protoc-gen-grpc-java/1.74.0/protoc-gen-grpc-java-1.74.0-linux-x86_64.exe" - } - }, - "grpc_java_plugin_windows_x86_64": { - "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_file", - "attributes": { - "executable": true, - "sha256": "6c265e8cefbb2158b044807af1188ad303d35e973f562209f337f93a8198fa37", - "url": "https://repo1.maven.org/maven2/io/grpc/protoc-gen-grpc-java/1.74.0/protoc-gen-grpc-java-1.74.0-windows-x86_64.exe" - } - } - }, - "moduleExtensionMetadata": { - "useAllRepos": "REGULAR", - "reproducible": false - } - } - }, - "@@rules_python+//python/extensions:config.bzl%config": { - "general": { - "bzlTransitiveDigest": "iibnRYgg8LpcfmH7EAnVwYePC3jsVaJ6Id8XxUjSZps=", - "usagesDigest": "ZVSXMAGpD+xzVNPuvF1IoLBkty7TROO0+akMapt1pAg=", - "recordedInputs": [ - "REPO_MAPPING:rules_python+,bazel_tools bazel_tools", - "REPO_MAPPING:rules_python+,pypi__build rules_python++config+pypi__build", - "REPO_MAPPING:rules_python+,pypi__click rules_python++config+pypi__click", - "REPO_MAPPING:rules_python+,pypi__colorama rules_python++config+pypi__colorama", - "REPO_MAPPING:rules_python+,pypi__importlib_metadata rules_python++config+pypi__importlib_metadata", - "REPO_MAPPING:rules_python+,pypi__installer rules_python++config+pypi__installer", - "REPO_MAPPING:rules_python+,pypi__more_itertools rules_python++config+pypi__more_itertools", - "REPO_MAPPING:rules_python+,pypi__packaging rules_python++config+pypi__packaging", - "REPO_MAPPING:rules_python+,pypi__pep517 rules_python++config+pypi__pep517", - "REPO_MAPPING:rules_python+,pypi__pip rules_python++config+pypi__pip", - "REPO_MAPPING:rules_python+,pypi__pip_tools rules_python++config+pypi__pip_tools", - "REPO_MAPPING:rules_python+,pypi__pyproject_hooks rules_python++config+pypi__pyproject_hooks", - "REPO_MAPPING:rules_python+,pypi__setuptools rules_python++config+pypi__setuptools", - "REPO_MAPPING:rules_python+,pypi__tomli rules_python++config+pypi__tomli", - "REPO_MAPPING:rules_python+,pypi__wheel rules_python++config+pypi__wheel", - "REPO_MAPPING:rules_python+,pypi__zipp rules_python++config+pypi__zipp" - ], - "generatedRepoSpecs": { - "rules_python_internal": { - "repoRuleId": "@@rules_python+//python/private:internal_config_repo.bzl%internal_config_repo", - "attributes": { - "transition_setting_generators": {}, - "transition_settings": [] - } - }, - "pypi__build": { - "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", - "attributes": { - "url": "https://files.pythonhosted.org/packages/e2/03/f3c8ba0a6b6e30d7d18c40faab90807c9bb5e9a1e3b2fe2008af624a9c97/build-1.2.1-py3-none-any.whl", - "sha256": "75e10f767a433d9a86e50d83f418e83efc18ede923ee5ff7df93b6cb0306c5d4", - "type": "zip", - "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" - } - }, - "pypi__click": { - "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", - "attributes": { - "url": "https://files.pythonhosted.org/packages/00/2e/d53fa4befbf2cfa713304affc7ca780ce4fc1fd8710527771b58311a3229/click-8.1.7-py3-none-any.whl", - "sha256": "ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", - "type": "zip", - "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" - } - }, - "pypi__colorama": { - "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", - "attributes": { - "url": "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", - "sha256": "4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", - "type": "zip", - "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" - } - }, - "pypi__importlib_metadata": { - "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", - "attributes": { - "url": "https://files.pythonhosted.org/packages/2d/0a/679461c511447ffaf176567d5c496d1de27cbe34a87df6677d7171b2fbd4/importlib_metadata-7.1.0-py3-none-any.whl", - "sha256": "30962b96c0c223483ed6cc7280e7f0199feb01a0e40cfae4d4450fc6fab1f570", - "type": "zip", - "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" - } - }, - "pypi__installer": { - "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", - "attributes": { - "url": "https://files.pythonhosted.org/packages/e5/ca/1172b6638d52f2d6caa2dd262ec4c811ba59eee96d54a7701930726bce18/installer-0.7.0-py3-none-any.whl", - "sha256": "05d1933f0a5ba7d8d6296bb6d5018e7c94fa473ceb10cf198a92ccea19c27b53", - "type": "zip", - "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" - } - }, - "pypi__more_itertools": { - "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", - "attributes": { - "url": "https://files.pythonhosted.org/packages/50/e2/8e10e465ee3987bb7c9ab69efb91d867d93959095f4807db102d07995d94/more_itertools-10.2.0-py3-none-any.whl", - "sha256": "686b06abe565edfab151cb8fd385a05651e1fdf8f0a14191e4439283421f8684", - "type": "zip", - "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" - } - }, - "pypi__packaging": { - "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", - "attributes": { - "url": "https://files.pythonhosted.org/packages/49/df/1fceb2f8900f8639e278b056416d49134fb8d84c5942ffaa01ad34782422/packaging-24.0-py3-none-any.whl", - "sha256": "2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5", - "type": "zip", - "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" - } - }, - "pypi__pep517": { - "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", - "attributes": { - "url": "https://files.pythonhosted.org/packages/25/6e/ca4a5434eb0e502210f591b97537d322546e4833dcb4d470a48c375c5540/pep517-0.13.1-py3-none-any.whl", - "sha256": "31b206f67165b3536dd577c5c3f1518e8fbaf38cbc57efff8369a392feff1721", - "type": "zip", - "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" - } - }, - "pypi__pip": { - "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", - "attributes": { - "url": "https://files.pythonhosted.org/packages/8a/6a/19e9fe04fca059ccf770861c7d5721ab4c2aebc539889e97c7977528a53b/pip-24.0-py3-none-any.whl", - "sha256": "ba0d021a166865d2265246961bec0152ff124de910c5cc39f1156ce3fa7c69dc", - "type": "zip", - "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" - } - }, - "pypi__pip_tools": { - "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", - "attributes": { - "url": "https://files.pythonhosted.org/packages/0d/dc/38f4ce065e92c66f058ea7a368a9c5de4e702272b479c0992059f7693941/pip_tools-7.4.1-py3-none-any.whl", - "sha256": "4c690e5fbae2f21e87843e89c26191f0d9454f362d8acdbd695716493ec8b3a9", - "type": "zip", - "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" - } - }, - "pypi__pyproject_hooks": { - "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", - "attributes": { - "url": "https://files.pythonhosted.org/packages/ae/f3/431b9d5fe7d14af7a32340792ef43b8a714e7726f1d7b69cc4e8e7a3f1d7/pyproject_hooks-1.1.0-py3-none-any.whl", - "sha256": "7ceeefe9aec63a1064c18d939bdc3adf2d8aa1988a510afec15151578b232aa2", - "type": "zip", - "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" - } - }, - "pypi__setuptools": { - "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", - "attributes": { - "url": "https://files.pythonhosted.org/packages/90/99/158ad0609729111163fc1f674a5a42f2605371a4cf036d0441070e2f7455/setuptools-78.1.1-py3-none-any.whl", - "sha256": "c3a9c4211ff4c309edb8b8c4f1cbfa7ae324c4ba9f91ff254e3d305b9fd54561", - "type": "zip", - "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" - } - }, - "pypi__tomli": { - "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", - "attributes": { - "url": "https://files.pythonhosted.org/packages/97/75/10a9ebee3fd790d20926a90a2547f0bf78f371b2f13aa822c759680ca7b9/tomli-2.0.1-py3-none-any.whl", - "sha256": "939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc", - "type": "zip", - "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" - } - }, - "pypi__wheel": { - "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", - "attributes": { - "url": "https://files.pythonhosted.org/packages/7d/cd/d7460c9a869b16c3dd4e1e403cce337df165368c71d6af229a74699622ce/wheel-0.43.0-py3-none-any.whl", - "sha256": "55c570405f142630c6b9f72fe09d9b67cf1477fcf543ae5b8dcb1f5b7377da81", - "type": "zip", - "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" - } - }, - "pypi__zipp": { - "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", - "attributes": { - "url": "https://files.pythonhosted.org/packages/da/55/a03fd7240714916507e1fcf7ae355bd9d9ed2e6db492595f1a67f61681be/zipp-3.18.2-py3-none-any.whl", - "sha256": "dce197b859eb796242b0622af1b8beb0a722d52aa2f57133ead08edd5bf5374e", - "type": "zip", - "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" - } - } - } - } - }, - "@@rules_python+//python/uv:uv.bzl%uv": { - "general": { - "bzlTransitiveDigest": "ijW9KS7qsIY+yBVvJ+Nr1mzwQox09j13DnE3iIwaeTM=", - "usagesDigest": "H8dQoNZcoqP+Mu0tHZTi4KHATzvNkM5ePuEqoQdklIU=", - "recordedInputs": [ - "REPO_MAPPING:rules_python+,bazel_tools bazel_tools", - "REPO_MAPPING:rules_python+,platforms platforms" - ], - "generatedRepoSpecs": { - "uv": { - "repoRuleId": "@@rules_python+//python/uv/private:uv_toolchains_repo.bzl%uv_toolchains_repo", - "attributes": { - "toolchain_type": "'@@rules_python+//python/uv:uv_toolchain_type'", - "toolchain_names": [ - "none" - ], - "toolchain_implementations": { - "none": "'@@rules_python+//python:none'" - }, - "toolchain_compatible_with": { - "none": [ - "@platforms//:incompatible" - ] - }, - "toolchain_target_settings": {} - } - } - } - } - }, - "@@tar.bzl+//tar:extensions.bzl%toolchains": { - "general": { - "bzlTransitiveDigest": "/2afh6fPjq/rcyE/jztQDK3ierehmFFngfvmqyRv72M=", - "usagesDigest": "maF8qsAIqeH1ey8pxP0gNZbvJt34kLZvTFeQ0ntrJVA=", - "recordedInputs": [], - "generatedRepoSpecs": { - "bsd_tar_toolchains": { - "repoRuleId": "@@tar.bzl+//tar/toolchain:toolchain.bzl%tar_toolchains_repo", - "attributes": { - "user_repository_name": "bsd_tar_toolchains" - } - }, - "bsd_tar_toolchains_darwin_amd64": { - "repoRuleId": "@@tar.bzl+//tar/toolchain:platforms.bzl%bsdtar_binary_repo", - "attributes": { - "platform": "darwin_amd64" - } - }, - "bsd_tar_toolchains_darwin_arm64": { - "repoRuleId": "@@tar.bzl+//tar/toolchain:platforms.bzl%bsdtar_binary_repo", - "attributes": { - "platform": "darwin_arm64" - } - }, - "bsd_tar_toolchains_linux_amd64": { - "repoRuleId": "@@tar.bzl+//tar/toolchain:platforms.bzl%bsdtar_binary_repo", - "attributes": { - "platform": "linux_amd64" - } - }, - "bsd_tar_toolchains_linux_arm64": { - "repoRuleId": "@@tar.bzl+//tar/toolchain:platforms.bzl%bsdtar_binary_repo", - "attributes": { - "platform": "linux_arm64" - } - }, - "bsd_tar_toolchains_windows_amd64": { - "repoRuleId": "@@tar.bzl+//tar/toolchain:platforms.bzl%bsdtar_binary_repo", - "attributes": { - "platform": "windows_amd64" - } - }, - "bsd_tar_toolchains_windows_arm64": { - "repoRuleId": "@@tar.bzl+//tar/toolchain:platforms.bzl%bsdtar_binary_repo", - "attributes": { - "platform": "windows_arm64" - } - } - } - } - } - }, - "facts": { - "@@rules_go+//go:extensions.bzl%go_sdk": { - "1.22.4": { - "aix_ppc64": [ - "go1.22.4.aix-ppc64.tar.gz", - "b9647fa9fc83a0cc5d4f092a19eaeaecf45f063a5aa7d4962fde65aeb7ae6ce1" - ], - "darwin_amd64": [ - "go1.22.4.darwin-amd64.tar.gz", - "c95967f50aa4ace34af0c236cbdb49a9a3e80ee2ad09d85775cb4462a5c19ed3" - ], - "darwin_arm64": [ - "go1.22.4.darwin-arm64.tar.gz", - "242b78dc4c8f3d5435d28a0d2cec9b4c1aa999b601fb8aa59fb4e5a1364bf827" - ], - "dragonfly_amd64": [ - "go1.22.4.dragonfly-amd64.tar.gz", - "f2fbb51af4719d3616efb482d6ed2b96579b474156f85a7ddc6f126764feec4b" - ], - "freebsd_386": [ - "go1.22.4.freebsd-386.tar.gz", - "7c54884bb9f274884651d41e61d1bc12738863ad1497e97ea19ad0e9aa6bf7b5" - ], - "freebsd_amd64": [ - "go1.22.4.freebsd-amd64.tar.gz", - "88d44500e1701dd35797619774d6dd51bf60f45a8338b0a82ddc018e4e63fb78" - ], - "freebsd_arm64": [ - "go1.22.4.freebsd-arm64.tar.gz", - "726dc093cf020277be45debf03c3b02b43c2efb3e2a5d4fba8f52579d65327dc" - ], - "freebsd_armv6l": [ - "go1.22.4.freebsd-arm.tar.gz", - "3d9efe47db142a22679aba46b1772e3900b0d87ae13bd2b3bc80dbf2ac0b2cd6" - ], - "freebsd_riscv64": [ - "go1.22.4.freebsd-riscv64.tar.gz", - "5f6b67e5e32f1d6ccb2d4dcb44934a5e2e870a877ba7443d86ec43cfc28afa71" - ], - "illumos_amd64": [ - "go1.22.4.illumos-amd64.tar.gz", - "d56ecc2f85b6418a21ef83879594d0c42ab4f65391a676bb12254870e6690d63" - ], - "linux_386": [ - "go1.22.4.linux-386.tar.gz", - "47a2a8d249a91eb8605c33bceec63aedda0441a43eac47b4721e3975ff916cec" - ], - "linux_amd64": [ - "go1.22.4.linux-amd64.tar.gz", - "ba79d4526102575196273416239cca418a651e049c2b099f3159db85e7bade7d" - ], - "linux_arm64": [ - "go1.22.4.linux-arm64.tar.gz", - "a8e177c354d2e4a1b61020aca3562e27ea3e8f8247eca3170e3fa1e0c2f9e771" - ], - "linux_armv6l": [ - "go1.22.4.linux-armv6l.tar.gz", - "e2b143fbacbc9cbd448e9ef41ac3981f0488ce849af1cf37e2341d09670661de" - ], - "linux_loong64": [ - "go1.22.4.linux-loong64.tar.gz", - "e2ff9436e4b34bf6926b06d97916e26d67a909a2effec17967245900f0816f1d" - ], - "linux_mips": [ - "go1.22.4.linux-mips.tar.gz", - "73f0dcc60458c4770593b05a7bc01cc0d31fc98f948c0c2334812c7a1f2fc3f1" - ], - "linux_mips64": [ - "go1.22.4.linux-mips64.tar.gz", - "417af97fc2630a647052375768be4c38adcc5af946352ea5b28613ea81ca5d45" - ], - "linux_mips64le": [ - "go1.22.4.linux-mips64le.tar.gz", - "7486e2d7dd8c98eb44df815ace35a7fe7f30b7c02326e3741bd934077508139b" - ], - "linux_mipsle": [ - "go1.22.4.linux-mipsle.tar.gz", - "69479c8aad301e459a8365b40cad1074a0dbba5defb9291669f94809c4c4be6e" - ], - "linux_ppc64": [ - "go1.22.4.linux-ppc64.tar.gz", - "dd238847e65bc3e2745caca475a5db6522a2fcf85cf6c38fc36a06642b19efd7" - ], - "linux_ppc64le": [ - "go1.22.4.linux-ppc64le.tar.gz", - "a3e5834657ef92523f570f798fed42f1f87bc18222a16815ec76b84169649ec4" - ], - "linux_riscv64": [ - "go1.22.4.linux-riscv64.tar.gz", - "56a827ff7dc6245bcd7a1e9288dffaa1d8b0fd7468562264c1523daf3b4f1b4a" - ], - "linux_s390x": [ - "go1.22.4.linux-s390x.tar.gz", - "7590c3e278e2dc6040aae0a39da3ca1eb2e3921673a7304cc34d588c45889eec" - ], - "netbsd_386": [ - "go1.22.4.netbsd-386.tar.gz", - "ddd2eebe34471a2502de6c5dad04ab27c9fc80cbde7a9ad5b3c66ecec4504e1d" - ], - "netbsd_amd64": [ - "go1.22.4.netbsd-amd64.tar.gz", - "33af79f6f935f6fbacc5d23876450b3567b79348fc065beef8e64081127dd234" - ], - "netbsd_arm64": [ - "go1.22.4.netbsd-arm64.tar.gz", - "c9a2971dec9f6d320c6f2b049b2353c6d0a2d35e87b8a4b2d78a2f0d62545f8e" - ], - "netbsd_armv6l": [ - "go1.22.4.netbsd-arm.tar.gz", - "fa3550ebd5375a70b3bcd342b5a71f4bd271dcbbfaf4eabefa2144ab5d8924b6" - ], - "openbsd_386": [ - "go1.22.4.openbsd-386.tar.gz", - "d21af022331bfdc2b5b161d616c3a1a4573d33cf7a30416ee509a8f3641deb47" - ], - "openbsd_amd64": [ - "go1.22.4.openbsd-amd64.tar.gz", - "72c0094c43f7e5722ec49c2a3e9dfa7a1123ac43a5f3a63eecf3e3795d3ff0ae" - ], - "openbsd_arm64": [ - "go1.22.4.openbsd-arm64.tar.gz", - "a7ab8d4e0b02bf06ed144ba42c61c0e93ee00f2b433415dfd4ad4b6e79f31650" - ], - "openbsd_armv6l": [ - "go1.22.4.openbsd-arm.tar.gz", - "1096831ea3c5ea3ca57d14251d9eda3786889531eb40d7d6775dcaa324d4b065" - ], - "openbsd_ppc64": [ - "go1.22.4.openbsd-ppc64.tar.gz", - "9716327c8a628358798898dc5148c49dbbeb5196bf2cbf088e550721a6e4f60b" - ], - "plan9_386": [ - "go1.22.4.plan9-386.tar.gz", - "a8dd4503c95c32a502a616ab78870a19889c9325fe9bd31eb16dd69346e4bfa8" - ], - "plan9_amd64": [ - "go1.22.4.plan9-amd64.tar.gz", - "5423a25808d76fe5aca8607a2e5ac5673abf45446b168cb5e9d8519ee9fe39a1" - ], - "plan9_armv6l": [ - "go1.22.4.plan9-arm.tar.gz", - "6af939ad583f5c85c09c53728ab7d38c3cc2b39167562d6c18a07c5c6608b370" - ], - "solaris_amd64": [ - "go1.22.4.solaris-amd64.tar.gz", - "e8cabe69c03085725afdb32a6f9998191a3e55a747b270d835fd05000d56abba" - ], - "windows_386": [ - "go1.22.4.windows-386.zip", - "aca4e2c37278a10f1c70dd0df142f7d66b50334fcee48978d409202d308d6d25" - ], - "windows_amd64": [ - "go1.22.4.windows-amd64.zip", - "26321c4d945a0035d8a5bc4a1965b0df401ff8ceac66ce2daadabf9030419a98" - ], - "windows_arm64": [ - "go1.22.4.windows-arm64.zip", - "8a2daa9ea28cbdafddc6171aefed384f4e5b6e714fb52116fe9ed25a132f37ed" - ], - "windows_armv6l": [ - "go1.22.4.windows-arm.zip", - "5fcd0671a49cecf39b41021621ee1b6e7aa1370f37122b72e80d4fd4185833b6" - ] - }, - "1.25.0": { - "aix_ppc64": [ - "go1.25.0.aix-ppc64.tar.gz", - "e5234a7dac67bc86c528fe9752fc9d63557918627707a733ab4cac1a6faed2d4" - ], - "darwin_amd64": [ - "go1.25.0.darwin-amd64.tar.gz", - "5bd60e823037062c2307c71e8111809865116714d6f6b410597cf5075dfd80ef" - ], - "darwin_arm64": [ - "go1.25.0.darwin-arm64.tar.gz", - "544932844156d8172f7a28f77f2ac9c15a23046698b6243f633b0a0b00c0749c" - ], - "dragonfly_amd64": [ - "go1.25.0.dragonfly-amd64.tar.gz", - "5ed3cf9a810a1483822538674f1336c06b51aa1b94d6d545a1a0319a48177120" - ], - "freebsd_386": [ - "go1.25.0.freebsd-386.tar.gz", - "abea5d5c6697e6b5c224731f2158fe87c602996a2a233ac0c4730cd57bf8374e" - ], - "freebsd_amd64": [ - "go1.25.0.freebsd-amd64.tar.gz", - "86e6fe0a29698d7601c4442052dac48bd58d532c51cccb8f1917df648138730b" - ], - "freebsd_arm": [ - "go1.25.0.freebsd-arm.tar.gz", - "d90b78e41921f72f30e8bbc81d9dec2cff7ff384a33d8d8debb24053e4336bfe" - ], - "freebsd_arm64": [ - "go1.25.0.freebsd-arm64.tar.gz", - "451d0da1affd886bfb291b7c63a6018527b269505db21ce6e14724f22ab0662e" - ], - "freebsd_riscv64": [ - "go1.25.0.freebsd-riscv64.tar.gz", - "7b565f76bd8bda46549eeaaefe0e53b251e644c230577290c0f66b1ecdb3cdbe" - ], - "illumos_amd64": [ - "go1.25.0.illumos-amd64.tar.gz", - "b1e1fdaab1ad25aa1c08d7a36c97d45d74b98b89c3f78c6d2145f77face54a2c" - ], - "linux_386": [ - "go1.25.0.linux-386.tar.gz", - "8c602dd9d99bc9453b3995d20ce4baf382cc50855900a0ece5de9929df4a993a" - ], - "linux_amd64": [ - "go1.25.0.linux-amd64.tar.gz", - "2852af0cb20a13139b3448992e69b868e50ed0f8a1e5940ee1de9e19a123b613" - ], - "linux_arm64": [ - "go1.25.0.linux-arm64.tar.gz", - "05de75d6994a2783699815ee553bd5a9327d8b79991de36e38b66862782f54ae" - ], - "linux_armv6l": [ - "go1.25.0.linux-armv6l.tar.gz", - "a5a8f8198fcf00e1e485b8ecef9ee020778bf32a408a4e8873371bfce458cd09" - ], - "linux_loong64": [ - "go1.25.0.linux-loong64.tar.gz", - "cab86b1cf761b1cb3bac86a8877cfc92e7b036fc0d3084123d77013d61432afc" - ], - "linux_mips": [ - "go1.25.0.linux-mips.tar.gz", - "d66b6fb74c3d91b9829dc95ec10ca1f047ef5e89332152f92e136cf0e2da5be1" - ], - "linux_mips64": [ - "go1.25.0.linux-mips64.tar.gz", - "4082e4381a8661bc2a839ff94ba3daf4f6cde20f8fb771b5b3d4762dc84198a2" - ], - "linux_mips64le": [ - "go1.25.0.linux-mips64le.tar.gz", - "70002c299ec7f7175ac2ef673b1b347eecfa54ae11f34416a6053c17f855afcc" - ], - "linux_mipsle": [ - "go1.25.0.linux-mipsle.tar.gz", - "b00a3a39eff099f6df9f1c7355bf28e4589d0586f42d7d4a394efb763d145a73" - ], - "linux_ppc64": [ - "go1.25.0.linux-ppc64.tar.gz", - "df166f33bd98160662560a72ff0b4ba731f969a80f088922bddcf566a88c1ec1" - ], - "linux_ppc64le": [ - "go1.25.0.linux-ppc64le.tar.gz", - "0f18a89e7576cf2c5fa0b487a1635d9bcbf843df5f110e9982c64df52a983ad0" - ], - "linux_riscv64": [ - "go1.25.0.linux-riscv64.tar.gz", - "c018ff74a2c48d55c8ca9b07c8e24163558ffec8bea08b326d6336905d956b67" - ], - "linux_s390x": [ - "go1.25.0.linux-s390x.tar.gz", - "34e5a2e19f2292fbaf8783e3a241e6e49689276aef6510a8060ea5ef54eee408" - ], - "netbsd_386": [ - "go1.25.0.netbsd-386.tar.gz", - "f8586cdb7aa855657609a5c5f6dbf523efa00c2bbd7c76d3936bec80aa6c0aba" - ], - "netbsd_amd64": [ - "go1.25.0.netbsd-amd64.tar.gz", - "ae8dc1469385b86a157a423bb56304ba45730de8a897615874f57dd096db2c2a" - ], - "netbsd_arm": [ - "go1.25.0.netbsd-arm.tar.gz", - "1ff7e4cc764425fc9dd6825eaee79d02b3c7cafffbb3691687c8d672ade76cb7" - ], - "netbsd_arm64": [ - "go1.25.0.netbsd-arm64.tar.gz", - "e1b310739f26724216aa6d7d7208c4031f9ff54c9b5b9a796ddc8bebcb4a5f16" - ], - "openbsd_386": [ - "go1.25.0.openbsd-386.tar.gz", - "4802a9b20e533da91adb84aab42e94aa56cfe3e5475d0550bed3385b182e69d8" - ], - "openbsd_amd64": [ - "go1.25.0.openbsd-amd64.tar.gz", - "c016cd984bebe317b19a4f297c4f50def120dc9788490540c89f28e42f1dabe1" - ], - "openbsd_arm": [ - "go1.25.0.openbsd-arm.tar.gz", - "a1e31d0bf22172ddde42edf5ec811ef81be43433df0948ece52fecb247ccfd8d" - ], - "openbsd_arm64": [ - "go1.25.0.openbsd-arm64.tar.gz", - "343ea8edd8c218196e15a859c6072d0dd3246fbbb168481ab665eb4c4140458d" - ], - "openbsd_ppc64": [ - "go1.25.0.openbsd-ppc64.tar.gz", - "694c14da1bcaeb5e3332d49bdc2b6d155067648f8fe1540c5de8f3cf8e157154" - ], - "openbsd_riscv64": [ - "go1.25.0.openbsd-riscv64.tar.gz", - "aa510ad25cf54c06cd9c70b6d80ded69cb20188ac6e1735655eef29ff7e7885f" - ], - "plan9_386": [ - "go1.25.0.plan9-386.tar.gz", - "46f8cef02086cf04bf186c5912776b56535178d4cb319cd19c9fdbdd29231986" - ], - "plan9_amd64": [ - "go1.25.0.plan9-amd64.tar.gz", - "29b34391d84095e44608a228f63f2f88113a37b74a79781353ec043dfbcb427b" - ], - "plan9_arm": [ - "go1.25.0.plan9-arm.tar.gz", - "0a047107d13ebe7943aaa6d54b1d7bbd2e45e68ce449b52915a818da715799c2" - ], - "solaris_amd64": [ - "go1.25.0.solaris-amd64.tar.gz", - "9977f9e4351984364a3b2b78f8b88bfd1d339812356d5237678514594b7d3611" - ], - "windows_386": [ - "go1.25.0.windows-386.zip", - "df9f39db82a803af0db639e3613a36681ab7a42866b1384b3f3a1045663961a7" - ], - "windows_amd64": [ - "go1.25.0.windows-amd64.zip", - "89efb4f9b30812eee083cc1770fdd2913c14d301064f6454851428f9707d190b" - ], - "windows_arm64": [ - "go1.25.0.windows-arm64.zip", - "27bab004c72b3d7bd05a69b6ec0fc54a309b4b78cc569dd963d8b3ec28bfdb8c" - ] - } - } - } -} diff --git a/src/control-plane-services/cloud-tasks/tools/bazel/generate_notice.sh b/src/control-plane-services/cloud-tasks/generate_notice.sh similarity index 79% rename from src/control-plane-services/cloud-tasks/tools/bazel/generate_notice.sh rename to src/control-plane-services/cloud-tasks/generate_notice.sh index 1d27aeadc..d8a90dd43 100755 --- a/src/control-plane-services/cloud-tasks/tools/bazel/generate_notice.sh +++ b/src/control-plane-services/cloud-tasks/generate_notice.sh @@ -14,8 +14,8 @@ fi exec python3 "${generator}" \ --maven-install "${workspace}/maven_install.json" \ - --metadata "${workspace}/tools/bazel/notice_metadata.json" \ - --notice "${workspace}/NOTICE" \ + --metadata "${workspace}/src/control-plane-services/cloud-tasks/notice_metadata.json" \ + --notice "${workspace}/src/control-plane-services/cloud-tasks/NOTICE" \ --runtime-jar "${runtime_jar}" \ --first-party-group com.nvidia.nvct \ "$@" diff --git a/src/control-plane-services/cloud-tasks/maven_install.json b/src/control-plane-services/cloud-tasks/maven_install.json deleted file mode 100644 index 544b5385b..000000000 --- a/src/control-plane-services/cloud-tasks/maven_install.json +++ /dev/null @@ -1,11690 +0,0 @@ -{ - "__AUTOGENERATED_FILE_DO_NOT_MODIFY_THIS_FILE_MANUALLY": "THERE_IS_NO_DATA_ONLY_ZUUL", - "__INPUT_ARTIFACTS_HASH": { - "at.yawk.lz4:lz4-java": 1725015399, - "com.bucket4j:bucket4j_jdk17-core": -1409600715, - "com.github.ben-manes.caffeine:caffeine": 1100418982, - "com.github.ben-manes.caffeine:guava": 1054685015, - "com.github.java-json-tools:json-patch": -1031005245, - "com.google.protobuf:protobuf-java": 1906581597, - "com.google.protobuf:protobuf-java-util": -1626074784, - "commons-codec:commons-codec": -1269462382, - "io.cloudevents:cloudevents-core": -2103567774, - "io.cloudevents:cloudevents-json-jackson": -1197487309, - "io.grpc:grpc-api": 811923177, - "io.grpc:grpc-protobuf": 1083049616, - "io.grpc:grpc-stub": 1416868173, - "io.micrometer:micrometer-registry-prometheus": 1865600799, - "io.micrometer:micrometer-tracing-bridge-otel": -754588172, - "io.nats:jnats": 572014237, - "io.opentelemetry:opentelemetry-exporter-otlp": -12806658, - "io.opentelemetry:opentelemetry-sdk-testing": -32635354, - "io.projectreactor.netty:reactor-netty-core": -2096527644, - "io.projectreactor.netty:reactor-netty-http": 131695323, - "jakarta.servlet:jakarta.servlet-api": 2120044853, - "javax.annotation:javax.annotation-api": 1286517389, - "net.devh:grpc-server-spring-boot-starter": -1304967214, - "net.javacrumbs.shedlock:shedlock-bom": -1406345450, - "net.javacrumbs.shedlock:shedlock-provider-cassandra": -1200872, - "net.javacrumbs.shedlock:shedlock-spring": -326290089, - "org.apache.cassandra:java-driver-metrics-micrometer": -465267397, - "org.apache.commons:commons-lang3": -278168457, - "org.assertj:assertj-core": 1863574844, - "org.awaitility:awaitility": -1630939750, - "org.bouncycastle:bcprov-jdk18on": -1405390253, - "org.jacoco:org.jacoco.agent": -2069397525, - "org.jacoco:org.jacoco.cli": -1856875155, - "org.junit.jupiter:junit-jupiter-api": 194920406, - "org.junit.jupiter:junit-jupiter-params": 1082310006, - "org.junit.platform:junit-platform-console-standalone": -1481831078, - "org.mockito:mockito-core": -554630660, - "org.mockito:mockito-junit-jupiter": -1104541639, - "org.ow2.asm:asm": -221905796, - "org.ow2.asm:asm-analysis": -1027574299, - "org.ow2.asm:asm-commons": 1525995351, - "org.ow2.asm:asm-tree": -242459737, - "org.ow2.asm:asm-util": -307204853, - "org.projectlombok:lombok": -2073039513, - "org.springdoc:springdoc-openapi-starter-webflux-api": 1102747448, - "org.springdoc:springdoc-openapi-starter-webmvc-api": 655186513, - "org.springframework.boot:spring-boot-actuator": 763411999, - "org.springframework.boot:spring-boot-dependencies": 70164638, - "org.springframework.boot:spring-boot-loader": 1745496505, - "org.springframework.boot:spring-boot-micrometer-metrics": -782059807, - "org.springframework.boot:spring-boot-micrometer-tracing": -2099172128, - "org.springframework.boot:spring-boot-micrometer-tracing-opentelemetry": 238152322, - "org.springframework.boot:spring-boot-opentelemetry": -396622647, - "org.springframework.boot:spring-boot-restclient": 525086533, - "org.springframework.boot:spring-boot-starter": 1358725161, - "org.springframework.boot:spring-boot-starter-actuator": -1082017891, - "org.springframework.boot:spring-boot-starter-actuator-test": 536870722, - "org.springframework.boot:spring-boot-starter-aspectj": -1960483986, - "org.springframework.boot:spring-boot-starter-data-cassandra": 699136521, - "org.springframework.boot:spring-boot-starter-data-cassandra-test": -667262890, - "org.springframework.boot:spring-boot-starter-jackson": -1899095121, - "org.springframework.boot:spring-boot-starter-security": 1168390884, - "org.springframework.boot:spring-boot-starter-security-oauth2-client": -1248590284, - "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server": 185843737, - "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server-test": -1173625786, - "org.springframework.boot:spring-boot-starter-test": -1561809354, - "org.springframework.boot:spring-boot-starter-validation": 113118493, - "org.springframework.boot:spring-boot-starter-webflux": 1788530073, - "org.springframework.boot:spring-boot-starter-webflux-test": 5326534, - "org.springframework.boot:spring-boot-starter-webmvc": 338400426, - "org.springframework.boot:spring-boot-starter-webmvc-test": -2111356331, - "org.springframework.boot:spring-boot-webclient": -1835278023, - "org.springframework.cloud:spring-cloud-commons": -673836000, - "org.springframework.cloud:spring-cloud-context": -1724959431, - "org.springframework.cloud:spring-cloud-dependencies": 46341733, - "org.springframework.cloud:spring-cloud-starter-bootstrap": -213001704, - "org.springframework.cloud:spring-cloud-starter-kubernetes-client-config": -2108580045, - "org.springframework.retry:spring-retry": -815156811, - "org.springframework.security:spring-security-test": 1317137564, - "org.springframework:spring-context-support": 43813702, - "org.springframework:spring-webflux": 11421498, - "org.testcontainers:testcontainers": -258185670, - "org.testcontainers:testcontainers-bom": 483223872, - "org.testcontainers:testcontainers-cassandra": -1027104267, - "org.testcontainers:testcontainers-junit-jupiter": -918230293, - "org.testcontainers:testcontainers-localstack": 1146768038, - "org.wiremock:wiremock-standalone": -1242936487, - "repositories": -1624298853, - "software.amazon.awssdk:regions": -1274787064, - "tools.jackson.module:jackson-module-blackbird": -423541381 - }, - "__RESOLVED_ARTIFACTS_HASH": { - "args4j:args4j": -572028113, - "args4j:args4j:jar:sources": 74047526, - "at.yawk.lz4:lz4-java": -1985362494, - "at.yawk.lz4:lz4-java:jar:sources": -2141970549, - "ch.qos.logback:logback-classic": -619930806, - "ch.qos.logback:logback-classic:jar:sources": -390128445, - "ch.qos.logback:logback-core": -1554021729, - "ch.qos.logback:logback-core:jar:sources": 77538609, - "com.bucket4j:bucket4j-core": -332288989, - "com.bucket4j:bucket4j-core:jar:sources": -559201191, - "com.bucket4j:bucket4j_jdk17-core": -1244833112, - "com.bucket4j:bucket4j_jdk17-core:jar:sources": -2075602285, - "com.datastax.cassandra:cassandra-driver-core": -1043458548, - "com.datastax.cassandra:cassandra-driver-core:jar:sources": -2045236197, - "com.datastax.oss:native-protocol": 447263174, - "com.datastax.oss:native-protocol:jar:sources": 396473389, - "com.fasterxml.jackson.core:jackson-annotations": 1407322119, - "com.fasterxml.jackson.core:jackson-annotations:jar:sources": -1408285999, - "com.fasterxml.jackson.core:jackson-core": -1715692416, - "com.fasterxml.jackson.core:jackson-core:jar:sources": 1404881423, - "com.fasterxml.jackson.core:jackson-databind": -1922910990, - "com.fasterxml.jackson.core:jackson-databind:jar:sources": -802304801, - "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml": 2129087476, - "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:jar:sources": -175522790, - "com.fasterxml.jackson.datatype:jackson-datatype-jsr310": 1940996847, - "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:jar:sources": 1241536710, - "com.fasterxml:classmate": -1468141616, - "com.fasterxml:classmate:jar:sources": -179492269, - "com.github.ben-manes.caffeine:caffeine": 96455941, - "com.github.ben-manes.caffeine:caffeine:jar:sources": -967473790, - "com.github.ben-manes.caffeine:guava": 1187631417, - "com.github.ben-manes.caffeine:guava:jar:sources": 1956210603, - "com.github.docker-java:docker-java-api": 1857041788, - "com.github.docker-java:docker-java-api:jar:sources": 300128277, - "com.github.docker-java:docker-java-transport": 689281477, - "com.github.docker-java:docker-java-transport-zerodep": -1848983763, - "com.github.docker-java:docker-java-transport-zerodep:jar:sources": 1882881505, - "com.github.docker-java:docker-java-transport:jar:sources": 864522470, - "com.github.java-json-tools:btf": 204024567, - "com.github.java-json-tools:btf:jar:sources": 1539011915, - "com.github.java-json-tools:jackson-coreutils": 1585779168, - "com.github.java-json-tools:jackson-coreutils:jar:sources": 323093438, - "com.github.java-json-tools:json-patch": 388171991, - "com.github.java-json-tools:json-patch:jar:sources": -1320375757, - "com.github.java-json-tools:msg-simple": -285204120, - "com.github.java-json-tools:msg-simple:jar:sources": 1013495835, - "com.github.jnr:jffi": 1952487985, - "com.github.jnr:jffi:jar:native": 1426144838, - "com.github.jnr:jffi:jar:sources": -252446498, - "com.github.jnr:jnr-constants": 1522135714, - "com.github.jnr:jnr-constants:jar:sources": -1920781516, - "com.github.jnr:jnr-ffi": 1663045836, - "com.github.jnr:jnr-ffi:jar:sources": -150631029, - "com.github.jnr:jnr-posix": 1594911544, - "com.github.jnr:jnr-posix:jar:sources": -992203730, - "com.github.jnr:jnr-x86asm": 1097235222, - "com.github.jnr:jnr-x86asm:jar:sources": -1784079536, - "com.github.stephenc.jcip:jcip-annotations": -121928928, - "com.github.stephenc.jcip:jcip-annotations:jar:sources": -2051941468, - "com.google.android:annotations": 769933135, - "com.google.android:annotations:jar:sources": 215169100, - "com.google.api.grpc:proto-google-common-protos": -1208329413, - "com.google.api.grpc:proto-google-common-protos:jar:sources": 944916609, - "com.google.code.findbugs:jsr305": -1038659426, - "com.google.code.findbugs:jsr305:jar:sources": -1300148931, - "com.google.code.gson:gson": 328405842, - "com.google.code.gson:gson:jar:sources": -329485452, - "com.google.errorprone:error_prone_annotations": -1266099896, - "com.google.errorprone:error_prone_annotations:jar:sources": 936701586, - "com.google.guava:failureaccess": -56291903, - "com.google.guava:failureaccess:jar:sources": -820168004, - "com.google.guava:guava": -1132194940, - "com.google.guava:guava:jar:sources": -1505508770, - "com.google.guava:listenablefuture": 1588902908, - "com.google.j2objc:j2objc-annotations": -2074422376, - "com.google.j2objc:j2objc-annotations:jar:sources": -597974451, - "com.google.protobuf:protobuf-java": 1139989641, - "com.google.protobuf:protobuf-java-util": 404866093, - "com.google.protobuf:protobuf-java-util:jar:sources": 1216176261, - "com.google.protobuf:protobuf-java:jar:sources": -718827633, - "com.jayway.jsonpath:json-path": 626712679, - "com.jayway.jsonpath:json-path:jar:sources": -343427302, - "com.nimbusds:content-type": -444977683, - "com.nimbusds:content-type:jar:sources": -634646164, - "com.nimbusds:lang-tag": -694347345, - "com.nimbusds:lang-tag:jar:sources": 266930896, - "com.nimbusds:nimbus-jose-jwt": -286981492, - "com.nimbusds:nimbus-jose-jwt:jar:sources": 24935039, - "com.nimbusds:oauth2-oidc-sdk": -498816278, - "com.nimbusds:oauth2-oidc-sdk:jar:sources": 1276926642, - "com.squareup.okhttp3:logging-interceptor": -2002563184, - "com.squareup.okhttp3:logging-interceptor:jar:sources": 524942179, - "com.squareup.okhttp3:okhttp": -2047906849, - "com.squareup.okhttp3:okhttp-jvm": -314031254, - "com.squareup.okhttp3:okhttp-jvm:jar:sources": 447067750, - "com.squareup.okhttp3:okhttp:jar:sources": -967779406, - "com.squareup.okio:okio": -11775483, - "com.squareup.okio:okio-jvm": -391120506, - "com.squareup.okio:okio-jvm:jar:sources": 1375453359, - "com.squareup.okio:okio:jar:sources": -1339925226, - "com.typesafe:config": 96906638, - "com.typesafe:config:jar:sources": -892423283, - "com.vaadin.external.google:android-json": -1531950165, - "com.vaadin.external.google:android-json:jar:sources": -116078240, - "commons-codec:commons-codec": -835030550, - "commons-codec:commons-codec:jar:sources": 990790236, - "commons-io:commons-io": -1021273518, - "commons-io:commons-io:jar:sources": 2066085027, - "commons-logging:commons-logging": 1061992981, - "commons-logging:commons-logging:jar:sources": 1867783947, - "io.cloudevents:cloudevents-api": -617548735, - "io.cloudevents:cloudevents-api:jar:sources": 924762007, - "io.cloudevents:cloudevents-core": -688560325, - "io.cloudevents:cloudevents-core:jar:sources": 223693387, - "io.cloudevents:cloudevents-json-jackson": -807987873, - "io.cloudevents:cloudevents-json-jackson:jar:sources": -166751855, - "io.dropwizard.metrics:metrics-core": -1658658454, - "io.dropwizard.metrics:metrics-core:jar:sources": 1726519463, - "io.grpc:grpc-api": 716151037, - "io.grpc:grpc-api:jar:sources": 234601049, - "io.grpc:grpc-context": 721938541, - "io.grpc:grpc-context:jar:sources": 1478851124, - "io.grpc:grpc-core": -1513972768, - "io.grpc:grpc-core:jar:sources": -232667389, - "io.grpc:grpc-inprocess": 353730710, - "io.grpc:grpc-inprocess:jar:sources": -676994554, - "io.grpc:grpc-netty-shaded": 1759851352, - "io.grpc:grpc-netty-shaded:jar:sources": 1478851124, - "io.grpc:grpc-protobuf": -549393834, - "io.grpc:grpc-protobuf-lite": -1967256086, - "io.grpc:grpc-protobuf-lite:jar:sources": -1659538303, - "io.grpc:grpc-protobuf:jar:sources": -1849103116, - "io.grpc:grpc-services": 1483710115, - "io.grpc:grpc-services:jar:sources": 2062893709, - "io.grpc:grpc-stub": -1391817309, - "io.grpc:grpc-stub:jar:sources": -1596678046, - "io.grpc:grpc-util": 188637273, - "io.grpc:grpc-util:jar:sources": -2003766127, - "io.gsonfire:gson-fire": -1955577022, - "io.gsonfire:gson-fire:jar:sources": -237239617, - "io.kubernetes:client-java": -1721476940, - "io.kubernetes:client-java-api": 1944060710, - "io.kubernetes:client-java-api-fluent": 889139695, - "io.kubernetes:client-java-api-fluent:jar:sources": -1413457658, - "io.kubernetes:client-java-api:jar:sources": -1450077171, - "io.kubernetes:client-java-extended": 693015729, - "io.kubernetes:client-java-extended:jar:sources": -483537505, - "io.kubernetes:client-java-proto": -533144525, - "io.kubernetes:client-java-proto:jar:sources": 396874650, - "io.kubernetes:client-java:jar:sources": -1422160339, - "io.micrometer:context-propagation": -1130727419, - "io.micrometer:context-propagation:jar:sources": -1135393170, - "io.micrometer:micrometer-commons": 326693391, - "io.micrometer:micrometer-commons:jar:sources": -57818626, - "io.micrometer:micrometer-core": 829567043, - "io.micrometer:micrometer-core:jar:sources": 265175165, - "io.micrometer:micrometer-jakarta9": -15933884, - "io.micrometer:micrometer-jakarta9:jar:sources": 1275065742, - "io.micrometer:micrometer-observation": -319705914, - "io.micrometer:micrometer-observation-test": -1818068529, - "io.micrometer:micrometer-observation-test:jar:sources": 117373145, - "io.micrometer:micrometer-observation:jar:sources": 1279306785, - "io.micrometer:micrometer-registry-prometheus": -104964751, - "io.micrometer:micrometer-registry-prometheus:jar:sources": 769452823, - "io.micrometer:micrometer-tracing": -1023327334, - "io.micrometer:micrometer-tracing-bridge-otel": 1199970811, - "io.micrometer:micrometer-tracing-bridge-otel:jar:sources": 1300289348, - "io.micrometer:micrometer-tracing:jar:sources": 266031561, - "io.nats:jnats": 1273546329, - "io.nats:jnats:jar:sources": 194791155, - "io.netty:netty-buffer": -1740802869, - "io.netty:netty-buffer:jar:sources": 622468392, - "io.netty:netty-codec-base": -1042304993, - "io.netty:netty-codec-base:jar:sources": -612797714, - "io.netty:netty-codec-classes-quic": -702276906, - "io.netty:netty-codec-classes-quic:jar:sources": 1548159851, - "io.netty:netty-codec-compression": -789209831, - "io.netty:netty-codec-compression:jar:sources": -1402960067, - "io.netty:netty-codec-dns": 81169397, - "io.netty:netty-codec-dns:jar:sources": -1086447458, - "io.netty:netty-codec-http": -95764323, - "io.netty:netty-codec-http2": 544878123, - "io.netty:netty-codec-http2:jar:sources": -83820759, - "io.netty:netty-codec-http3": -194972071, - "io.netty:netty-codec-http3:jar:sources": 1699772273, - "io.netty:netty-codec-http:jar:sources": -116842177, - "io.netty:netty-codec-native-quic:jar:linux-aarch_64": -2075260519, - "io.netty:netty-codec-native-quic:jar:linux-x86_64": -1982796133, - "io.netty:netty-codec-native-quic:jar:osx-aarch_64": -632727283, - "io.netty:netty-codec-native-quic:jar:osx-x86_64": 1253945631, - "io.netty:netty-codec-native-quic:jar:sources": -986328940, - "io.netty:netty-codec-native-quic:jar:windows-x86_64": -115110822, - "io.netty:netty-codec-socks": 336734625, - "io.netty:netty-codec-socks:jar:sources": -1241946572, - "io.netty:netty-common": -1557278455, - "io.netty:netty-common:jar:sources": -467395659, - "io.netty:netty-handler": -1757690436, - "io.netty:netty-handler-proxy": -892232184, - "io.netty:netty-handler-proxy:jar:sources": -216040607, - "io.netty:netty-handler:jar:sources": -1379156289, - "io.netty:netty-resolver": -1571627366, - "io.netty:netty-resolver-dns": 954988644, - "io.netty:netty-resolver-dns-classes-macos": -441663783, - "io.netty:netty-resolver-dns-classes-macos:jar:sources": 776580055, - "io.netty:netty-resolver-dns-native-macos:jar:osx-x86_64": -354533951, - "io.netty:netty-resolver-dns-native-macos:jar:sources": -120739665, - "io.netty:netty-resolver-dns:jar:sources": 1652413066, - "io.netty:netty-resolver:jar:sources": 2084403340, - "io.netty:netty-transport": 44555455, - "io.netty:netty-transport-classes-epoll": -588470325, - "io.netty:netty-transport-classes-epoll:jar:sources": -1697662320, - "io.netty:netty-transport-native-epoll:jar:linux-x86_64": -563523863, - "io.netty:netty-transport-native-epoll:jar:sources": -1040259378, - "io.netty:netty-transport-native-unix-common": -166041147, - "io.netty:netty-transport-native-unix-common:jar:sources": -1674017507, - "io.netty:netty-transport:jar:sources": -820889350, - "io.opentelemetry.semconv:opentelemetry-semconv": 1195624836, - "io.opentelemetry.semconv:opentelemetry-semconv:jar:sources": -893534237, - "io.opentelemetry:opentelemetry-api": 885391408, - "io.opentelemetry:opentelemetry-api:jar:sources": -1404426315, - "io.opentelemetry:opentelemetry-common": 676580228, - "io.opentelemetry:opentelemetry-common:jar:sources": 1797051654, - "io.opentelemetry:opentelemetry-context": 747746024, - "io.opentelemetry:opentelemetry-context:jar:sources": 560193252, - "io.opentelemetry:opentelemetry-exporter-common": 42591217, - "io.opentelemetry:opentelemetry-exporter-common:jar:sources": 2032641450, - "io.opentelemetry:opentelemetry-exporter-otlp": 1346623356, - "io.opentelemetry:opentelemetry-exporter-otlp-common": -2043450521, - "io.opentelemetry:opentelemetry-exporter-otlp-common:jar:sources": -1909225648, - "io.opentelemetry:opentelemetry-exporter-otlp:jar:sources": -1536215787, - "io.opentelemetry:opentelemetry-exporter-sender-okhttp": -2026614746, - "io.opentelemetry:opentelemetry-exporter-sender-okhttp:jar:sources": -1387239258, - "io.opentelemetry:opentelemetry-extension-trace-propagators": -480191373, - "io.opentelemetry:opentelemetry-extension-trace-propagators:jar:sources": 517135536, - "io.opentelemetry:opentelemetry-sdk": -369820209, - "io.opentelemetry:opentelemetry-sdk-common": -1049102876, - "io.opentelemetry:opentelemetry-sdk-common:jar:sources": -1004050981, - "io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi": -928104061, - "io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi:jar:sources": -1626691242, - "io.opentelemetry:opentelemetry-sdk-logs": -1310291573, - "io.opentelemetry:opentelemetry-sdk-logs:jar:sources": 1572252989, - "io.opentelemetry:opentelemetry-sdk-metrics": -2038069517, - "io.opentelemetry:opentelemetry-sdk-metrics:jar:sources": -323022280, - "io.opentelemetry:opentelemetry-sdk-testing": 19519171, - "io.opentelemetry:opentelemetry-sdk-testing:jar:sources": -578292790, - "io.opentelemetry:opentelemetry-sdk-trace": 2083919234, - "io.opentelemetry:opentelemetry-sdk-trace:jar:sources": 818630467, - "io.opentelemetry:opentelemetry-sdk:jar:sources": -1478160490, - "io.perfmark:perfmark-api": 2140534246, - "io.perfmark:perfmark-api:jar:sources": 1660808382, - "io.projectreactor.netty:reactor-netty-core": -1310988391, - "io.projectreactor.netty:reactor-netty-core:jar:sources": 160926198, - "io.projectreactor.netty:reactor-netty-http": -1289714469, - "io.projectreactor.netty:reactor-netty-http:jar:sources": 1066415166, - "io.projectreactor:reactor-core": -745004757, - "io.projectreactor:reactor-core:jar:sources": -717353230, - "io.projectreactor:reactor-test": 947112823, - "io.projectreactor:reactor-test:jar:sources": 383025302, - "io.prometheus:prometheus-metrics-config": 2090275681, - "io.prometheus:prometheus-metrics-config:jar:sources": -594166944, - "io.prometheus:prometheus-metrics-core": 786050810, - "io.prometheus:prometheus-metrics-core:jar:sources": 832360457, - "io.prometheus:prometheus-metrics-exposition-formats": 968068623, - "io.prometheus:prometheus-metrics-exposition-formats:jar:sources": -438412972, - "io.prometheus:prometheus-metrics-exposition-textformats": 620169553, - "io.prometheus:prometheus-metrics-exposition-textformats:jar:sources": 1866131456, - "io.prometheus:prometheus-metrics-model": -1472396605, - "io.prometheus:prometheus-metrics-model:jar:sources": 2095315251, - "io.prometheus:prometheus-metrics-tracer-common": -1148816462, - "io.prometheus:prometheus-metrics-tracer-common:jar:sources": 2121978274, - "io.swagger.core.v3:swagger-annotations-jakarta": -842428034, - "io.swagger.core.v3:swagger-annotations-jakarta:jar:sources": 133934665, - "io.swagger.core.v3:swagger-core-jakarta": -439612282, - "io.swagger.core.v3:swagger-core-jakarta:jar:sources": 449241668, - "io.swagger.core.v3:swagger-models-jakarta": -1439553498, - "io.swagger.core.v3:swagger-models-jakarta:jar:sources": 2092063988, - "io.swagger:swagger-annotations": 1839493157, - "io.swagger:swagger-annotations:jar:sources": 686356574, - "jakarta.activation:jakarta.activation-api": -1560267684, - "jakarta.activation:jakarta.activation-api:jar:sources": 759160467, - "jakarta.annotation:jakarta.annotation-api": -1904975463, - "jakarta.annotation:jakarta.annotation-api:jar:sources": -247204066, - "jakarta.servlet:jakarta.servlet-api": 972614879, - "jakarta.servlet:jakarta.servlet-api:jar:sources": 2070183472, - "jakarta.validation:jakarta.validation-api": 666686261, - "jakarta.validation:jakarta.validation-api:jar:sources": -131796339, - "jakarta.xml.bind:jakarta.xml.bind-api": 1157993223, - "jakarta.xml.bind:jakarta.xml.bind-api:jar:sources": -945798747, - "javax.annotation:javax.annotation-api": 193132517, - "javax.annotation:javax.annotation-api:jar:sources": -1766532873, - "net.bytebuddy:byte-buddy": 383637760, - "net.bytebuddy:byte-buddy-agent": -1380713096, - "net.bytebuddy:byte-buddy-agent:jar:sources": 564051985, - "net.bytebuddy:byte-buddy:jar:sources": -1360611642, - "net.devh:grpc-common-spring-boot": 868090547, - "net.devh:grpc-common-spring-boot:jar:sources": 1655513026, - "net.devh:grpc-server-spring-boot-starter": 1078456931, - "net.devh:grpc-server-spring-boot-starter:jar:sources": 1954333860, - "net.java.dev.jna:jna": -1951542637, - "net.java.dev.jna:jna:jar:sources": -545183654, - "net.javacrumbs.shedlock:shedlock-core": 672475327, - "net.javacrumbs.shedlock:shedlock-core:jar:sources": 69227555, - "net.javacrumbs.shedlock:shedlock-provider-cassandra": 1266553971, - "net.javacrumbs.shedlock:shedlock-provider-cassandra:jar:sources": 1860167, - "net.javacrumbs.shedlock:shedlock-spring": 2008414309, - "net.javacrumbs.shedlock:shedlock-spring:jar:sources": 875349683, - "net.minidev:accessors-smart": -325667575, - "net.minidev:accessors-smart:jar:sources": -124254155, - "net.minidev:json-smart": 1673421716, - "net.minidev:json-smart:jar:sources": -1084786431, - "org.apache.cassandra:java-driver-core": -474731455, - "org.apache.cassandra:java-driver-core:jar:sources": -1508814165, - "org.apache.cassandra:java-driver-guava-shaded": 568990261, - "org.apache.cassandra:java-driver-guava-shaded:jar:sources": 1291502230, - "org.apache.cassandra:java-driver-metrics-micrometer": 813209106, - "org.apache.cassandra:java-driver-metrics-micrometer:jar:sources": -2019023443, - "org.apache.cassandra:java-driver-query-builder": 572260414, - "org.apache.cassandra:java-driver-query-builder:jar:sources": -1665027563, - "org.apache.commons:commons-collections4": -321403372, - "org.apache.commons:commons-collections4:jar:sources": -620214302, - "org.apache.commons:commons-compress": -134181577, - "org.apache.commons:commons-compress:jar:sources": -1845261624, - "org.apache.commons:commons-lang3": 759645435, - "org.apache.commons:commons-lang3:jar:sources": 1890991939, - "org.apache.logging.log4j:log4j-api": 191755139, - "org.apache.logging.log4j:log4j-api:jar:sources": 1226633672, - "org.apache.logging.log4j:log4j-to-slf4j": 357996538, - "org.apache.logging.log4j:log4j-to-slf4j:jar:sources": -1847454236, - "org.apache.tomcat.embed:tomcat-embed-core": -2079786590, - "org.apache.tomcat.embed:tomcat-embed-core:jar:sources": -745705587, - "org.apache.tomcat.embed:tomcat-embed-el": -727131551, - "org.apache.tomcat.embed:tomcat-embed-el:jar:sources": 1938415424, - "org.apache.tomcat.embed:tomcat-embed-websocket": 1876889190, - "org.apache.tomcat.embed:tomcat-embed-websocket:jar:sources": -1809736441, - "org.apiguardian:apiguardian-api": -1579303244, - "org.apiguardian:apiguardian-api:jar:sources": 768152577, - "org.aspectj:aspectjweaver": -278059941, - "org.aspectj:aspectjweaver:jar:sources": 2235676, - "org.assertj:assertj-core": -536770136, - "org.assertj:assertj-core:jar:sources": -1826278818, - "org.awaitility:awaitility": 755971515, - "org.awaitility:awaitility:jar:sources": -1322650242, - "org.bitbucket.b_c:jose4j": 1319068658, - "org.bitbucket.b_c:jose4j:jar:sources": 969109778, - "org.bouncycastle:bcpkix-jdk18on": 755215182, - "org.bouncycastle:bcpkix-jdk18on:jar:sources": -167831728, - "org.bouncycastle:bcprov-jdk18on": -709136978, - "org.bouncycastle:bcprov-jdk18on:jar:sources": 106463766, - "org.bouncycastle:bcprov-lts8on": 973431866, - "org.bouncycastle:bcprov-lts8on:jar:sources": -196135755, - "org.bouncycastle:bcutil-jdk18on": 686883151, - "org.bouncycastle:bcutil-jdk18on:jar:sources": 1665148152, - "org.codehaus.mojo:animal-sniffer-annotations": -1054702037, - "org.codehaus.mojo:animal-sniffer-annotations:jar:sources": -248345982, - "org.hamcrest:hamcrest": 1116842741, - "org.hamcrest:hamcrest:jar:sources": -996443755, - "org.hdrhistogram:HdrHistogram": 1379183334, - "org.hdrhistogram:HdrHistogram:jar:sources": -1235434218, - "org.hibernate.validator:hibernate-validator": 1976561513, - "org.hibernate.validator:hibernate-validator:jar:sources": 367698734, - "org.jacoco:org.jacoco.agent:jar:runtime": -111724801, - "org.jacoco:org.jacoco.agent:jar:sources": 1432778515, - "org.jacoco:org.jacoco.cli": 2021870981, - "org.jacoco:org.jacoco.cli:jar:sources": 47843733, - "org.jacoco:org.jacoco.core": 579589309, - "org.jacoco:org.jacoco.core:jar:sources": -458393909, - "org.jacoco:org.jacoco.report": -1287135579, - "org.jacoco:org.jacoco.report:jar:sources": -2068401168, - "org.jboss.logging:jboss-logging": -2136063667, - "org.jboss.logging:jboss-logging:jar:sources": 2066441551, - "org.jetbrains.kotlin:kotlin-stdlib": -570435334, - "org.jetbrains.kotlin:kotlin-stdlib-jdk7": -1527302391, - "org.jetbrains.kotlin:kotlin-stdlib-jdk7:jar:sources": 197696244, - "org.jetbrains.kotlin:kotlin-stdlib-jdk8": 1920837701, - "org.jetbrains.kotlin:kotlin-stdlib-jdk8:jar:sources": -680289057, - "org.jetbrains.kotlin:kotlin-stdlib:jar:sources": 1404576391, - "org.jetbrains:annotations": 643765179, - "org.jetbrains:annotations:jar:sources": 1009912224, - "org.jspecify:jspecify": -1402924792, - "org.jspecify:jspecify:jar:sources": -841008091, - "org.junit.jupiter:junit-jupiter": -313198921, - "org.junit.jupiter:junit-jupiter-api": 80944698, - "org.junit.jupiter:junit-jupiter-api:jar:sources": -1650654944, - "org.junit.jupiter:junit-jupiter-engine": 730848020, - "org.junit.jupiter:junit-jupiter-engine:jar:sources": 1805473715, - "org.junit.jupiter:junit-jupiter-params": -1923494954, - "org.junit.jupiter:junit-jupiter-params:jar:sources": 1561682205, - "org.junit.jupiter:junit-jupiter:jar:sources": 1809716175, - "org.junit.platform:junit-platform-commons": -1304725543, - "org.junit.platform:junit-platform-commons:jar:sources": -139331649, - "org.junit.platform:junit-platform-console-standalone": -406221538, - "org.junit.platform:junit-platform-console-standalone:jar:sources": -103511349, - "org.junit.platform:junit-platform-engine": -748595950, - "org.junit.platform:junit-platform-engine:jar:sources": -191078126, - "org.latencyutils:LatencyUtils": 1082471286, - "org.latencyutils:LatencyUtils:jar:sources": 1894864087, - "org.mockito:mockito-core": 734095861, - "org.mockito:mockito-core:jar:sources": 1757924088, - "org.mockito:mockito-junit-jupiter": -501680015, - "org.mockito:mockito-junit-jupiter:jar:sources": -1281757309, - "org.objenesis:objenesis": 1083875484, - "org.objenesis:objenesis:jar:sources": 703772823, - "org.opentest4j:opentest4j": 793813175, - "org.opentest4j:opentest4j:jar:sources": 1210936723, - "org.ow2.asm:asm": 716467505, - "org.ow2.asm:asm-analysis": 129370658, - "org.ow2.asm:asm-analysis:jar:sources": -2126326860, - "org.ow2.asm:asm-commons": 530868933, - "org.ow2.asm:asm-commons:jar:sources": 1248498766, - "org.ow2.asm:asm-tree": 369430530, - "org.ow2.asm:asm-tree:jar:sources": -1850601298, - "org.ow2.asm:asm-util": -803635337, - "org.ow2.asm:asm-util:jar:sources": 51483494, - "org.ow2.asm:asm:jar:sources": -947428423, - "org.projectlombok:lombok": -1095750717, - "org.projectlombok:lombok:jar:sources": 1834083797, - "org.reactivestreams:reactive-streams": -1996658890, - "org.reactivestreams:reactive-streams:jar:sources": -258070571, - "org.rnorth.duct-tape:duct-tape": 615461963, - "org.rnorth.duct-tape:duct-tape:jar:sources": 427419407, - "org.skyscreamer:jsonassert": -1571197746, - "org.skyscreamer:jsonassert:jar:sources": -392658057, - "org.slf4j:jul-to-slf4j": -911724984, - "org.slf4j:jul-to-slf4j:jar:sources": -662175280, - "org.slf4j:slf4j-api": -1249720338, - "org.slf4j:slf4j-api:jar:sources": -297247278, - "org.springdoc:springdoc-openapi-starter-common": -50810541, - "org.springdoc:springdoc-openapi-starter-common:jar:sources": 776689800, - "org.springdoc:springdoc-openapi-starter-webflux-api": -2128144311, - "org.springdoc:springdoc-openapi-starter-webflux-api:jar:sources": -1775632648, - "org.springdoc:springdoc-openapi-starter-webmvc-api": 479427887, - "org.springdoc:springdoc-openapi-starter-webmvc-api:jar:sources": -1201450538, - "org.springframework.boot:spring-boot": -1519545366, - "org.springframework.boot:spring-boot-actuator": 1868004981, - "org.springframework.boot:spring-boot-actuator-autoconfigure": 437017470, - "org.springframework.boot:spring-boot-actuator-autoconfigure:jar:sources": 1090885133, - "org.springframework.boot:spring-boot-actuator:jar:sources": 1545596535, - "org.springframework.boot:spring-boot-autoconfigure": -491644458, - "org.springframework.boot:spring-boot-autoconfigure:jar:sources": 562322138, - "org.springframework.boot:spring-boot-cassandra": -1547665178, - "org.springframework.boot:spring-boot-cassandra:jar:sources": -285158244, - "org.springframework.boot:spring-boot-data-cassandra": 317643841, - "org.springframework.boot:spring-boot-data-cassandra-test": 1607977176, - "org.springframework.boot:spring-boot-data-cassandra-test:jar:sources": -601584645, - "org.springframework.boot:spring-boot-data-cassandra:jar:sources": 73983427, - "org.springframework.boot:spring-boot-data-commons": 1096447250, - "org.springframework.boot:spring-boot-data-commons:jar:sources": 867332098, - "org.springframework.boot:spring-boot-health": 988376788, - "org.springframework.boot:spring-boot-health:jar:sources": 1156692002, - "org.springframework.boot:spring-boot-http-client": -294534102, - "org.springframework.boot:spring-boot-http-client:jar:sources": 881974750, - "org.springframework.boot:spring-boot-http-codec": 434302862, - "org.springframework.boot:spring-boot-http-codec:jar:sources": 585983495, - "org.springframework.boot:spring-boot-http-converter": -1456188332, - "org.springframework.boot:spring-boot-http-converter:jar:sources": 678862764, - "org.springframework.boot:spring-boot-jackson": -886310726, - "org.springframework.boot:spring-boot-jackson:jar:sources": -928970153, - "org.springframework.boot:spring-boot-loader": 1516185416, - "org.springframework.boot:spring-boot-loader:jar:sources": 499181734, - "org.springframework.boot:spring-boot-micrometer-metrics": -971815116, - "org.springframework.boot:spring-boot-micrometer-metrics-test": 1059861465, - "org.springframework.boot:spring-boot-micrometer-metrics-test:jar:sources": 539702709, - "org.springframework.boot:spring-boot-micrometer-metrics:jar:sources": -1326033951, - "org.springframework.boot:spring-boot-micrometer-observation": -515345138, - "org.springframework.boot:spring-boot-micrometer-observation:jar:sources": -1374159176, - "org.springframework.boot:spring-boot-micrometer-tracing": 1633930466, - "org.springframework.boot:spring-boot-micrometer-tracing-opentelemetry": 1193263452, - "org.springframework.boot:spring-boot-micrometer-tracing-opentelemetry:jar:sources": 2058843242, - "org.springframework.boot:spring-boot-micrometer-tracing:jar:sources": -531678236, - "org.springframework.boot:spring-boot-netty": -1868279944, - "org.springframework.boot:spring-boot-netty:jar:sources": 2079852054, - "org.springframework.boot:spring-boot-opentelemetry": -1423093456, - "org.springframework.boot:spring-boot-opentelemetry:jar:sources": 1840051882, - "org.springframework.boot:spring-boot-persistence": -1485790991, - "org.springframework.boot:spring-boot-persistence:jar:sources": -1027448649, - "org.springframework.boot:spring-boot-reactor": 1298372962, - "org.springframework.boot:spring-boot-reactor-netty": 1434335970, - "org.springframework.boot:spring-boot-reactor-netty:jar:sources": -732886702, - "org.springframework.boot:spring-boot-reactor:jar:sources": -1373689055, - "org.springframework.boot:spring-boot-restclient": -67067992, - "org.springframework.boot:spring-boot-restclient:jar:sources": -1554622109, - "org.springframework.boot:spring-boot-resttestclient": 1078416021, - "org.springframework.boot:spring-boot-resttestclient:jar:sources": 1128597445, - "org.springframework.boot:spring-boot-security": -528218864, - "org.springframework.boot:spring-boot-security-oauth2-client": 1972725629, - "org.springframework.boot:spring-boot-security-oauth2-client:jar:sources": -1211778370, - "org.springframework.boot:spring-boot-security-oauth2-resource-server": -1021125134, - "org.springframework.boot:spring-boot-security-oauth2-resource-server:jar:sources": 1301519418, - "org.springframework.boot:spring-boot-security-test": -1810341741, - "org.springframework.boot:spring-boot-security-test:jar:sources": -311791400, - "org.springframework.boot:spring-boot-security:jar:sources": -1644906067, - "org.springframework.boot:spring-boot-servlet": -1040246830, - "org.springframework.boot:spring-boot-servlet:jar:sources": 1162002660, - "org.springframework.boot:spring-boot-starter": 191814674, - "org.springframework.boot:spring-boot-starter-actuator": 1761935967, - "org.springframework.boot:spring-boot-starter-actuator-test": 910069034, - "org.springframework.boot:spring-boot-starter-actuator-test:jar:sources": 314973026, - "org.springframework.boot:spring-boot-starter-actuator:jar:sources": -2079433447, - "org.springframework.boot:spring-boot-starter-aspectj": 740892542, - "org.springframework.boot:spring-boot-starter-aspectj:jar:sources": 1957689077, - "org.springframework.boot:spring-boot-starter-data-cassandra": -705283811, - "org.springframework.boot:spring-boot-starter-data-cassandra-test": -1214165647, - "org.springframework.boot:spring-boot-starter-data-cassandra-test:jar:sources": 464889083, - "org.springframework.boot:spring-boot-starter-data-cassandra:jar:sources": 62860247, - "org.springframework.boot:spring-boot-starter-jackson": 211326145, - "org.springframework.boot:spring-boot-starter-jackson-test": 538761659, - "org.springframework.boot:spring-boot-starter-jackson-test:jar:sources": 1211585483, - "org.springframework.boot:spring-boot-starter-jackson:jar:sources": 1689728463, - "org.springframework.boot:spring-boot-starter-logging": 51215582, - "org.springframework.boot:spring-boot-starter-logging:jar:sources": 1271111015, - "org.springframework.boot:spring-boot-starter-micrometer-metrics": 546085162, - "org.springframework.boot:spring-boot-starter-micrometer-metrics-test": -835747019, - "org.springframework.boot:spring-boot-starter-micrometer-metrics-test:jar:sources": 1830581000, - "org.springframework.boot:spring-boot-starter-micrometer-metrics:jar:sources": -1130818080, - "org.springframework.boot:spring-boot-starter-reactor-netty": 812139334, - "org.springframework.boot:spring-boot-starter-reactor-netty:jar:sources": 1164956430, - "org.springframework.boot:spring-boot-starter-security": 1058973423, - "org.springframework.boot:spring-boot-starter-security-oauth2-client": -1355057519, - "org.springframework.boot:spring-boot-starter-security-oauth2-client:jar:sources": 1707609356, - "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server": -265511875, - "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server-test": -17384836, - "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server-test:jar:sources": -746940353, - "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server:jar:sources": 2136275088, - "org.springframework.boot:spring-boot-starter-security-test": 1690721902, - "org.springframework.boot:spring-boot-starter-security-test:jar:sources": 468207576, - "org.springframework.boot:spring-boot-starter-security:jar:sources": -1720617031, - "org.springframework.boot:spring-boot-starter-test": -1087542039, - "org.springframework.boot:spring-boot-starter-test:jar:sources": -480189945, - "org.springframework.boot:spring-boot-starter-tomcat": -521361670, - "org.springframework.boot:spring-boot-starter-tomcat-runtime": -1912812722, - "org.springframework.boot:spring-boot-starter-tomcat-runtime:jar:sources": 1011838045, - "org.springframework.boot:spring-boot-starter-tomcat:jar:sources": 1319064174, - "org.springframework.boot:spring-boot-starter-validation": -321633530, - "org.springframework.boot:spring-boot-starter-validation:jar:sources": -1002865328, - "org.springframework.boot:spring-boot-starter-webflux": -818164168, - "org.springframework.boot:spring-boot-starter-webflux-test": -415179163, - "org.springframework.boot:spring-boot-starter-webflux-test:jar:sources": -1654084055, - "org.springframework.boot:spring-boot-starter-webflux:jar:sources": 1008425882, - "org.springframework.boot:spring-boot-starter-webmvc": 170962824, - "org.springframework.boot:spring-boot-starter-webmvc-test": -1343848488, - "org.springframework.boot:spring-boot-starter-webmvc-test:jar:sources": -1751111514, - "org.springframework.boot:spring-boot-starter-webmvc:jar:sources": -2120956724, - "org.springframework.boot:spring-boot-starter:jar:sources": 1138639700, - "org.springframework.boot:spring-boot-test": -927444958, - "org.springframework.boot:spring-boot-test-autoconfigure": -669950838, - "org.springframework.boot:spring-boot-test-autoconfigure:jar:sources": 392165449, - "org.springframework.boot:spring-boot-test:jar:sources": -1764708648, - "org.springframework.boot:spring-boot-tomcat": -1113349252, - "org.springframework.boot:spring-boot-tomcat:jar:sources": -1529683395, - "org.springframework.boot:spring-boot-validation": 1270368638, - "org.springframework.boot:spring-boot-validation:jar:sources": -1684576067, - "org.springframework.boot:spring-boot-web-server": 285708094, - "org.springframework.boot:spring-boot-web-server:jar:sources": 990724443, - "org.springframework.boot:spring-boot-webclient": -507647, - "org.springframework.boot:spring-boot-webclient:jar:sources": 71538120, - "org.springframework.boot:spring-boot-webflux": -231291542, - "org.springframework.boot:spring-boot-webflux-test": 1600114323, - "org.springframework.boot:spring-boot-webflux-test:jar:sources": 1452173744, - "org.springframework.boot:spring-boot-webflux:jar:sources": -1118813321, - "org.springframework.boot:spring-boot-webmvc": -2104103221, - "org.springframework.boot:spring-boot-webmvc-test": 749235095, - "org.springframework.boot:spring-boot-webmvc-test:jar:sources": 444837917, - "org.springframework.boot:spring-boot-webmvc:jar:sources": -1895028417, - "org.springframework.boot:spring-boot-webtestclient": -705991472, - "org.springframework.boot:spring-boot-webtestclient:jar:sources": -542316343, - "org.springframework.boot:spring-boot:jar:sources": 580880564, - "org.springframework.cloud:spring-cloud-commons": -788453967, - "org.springframework.cloud:spring-cloud-commons:jar:sources": 1320616004, - "org.springframework.cloud:spring-cloud-context": 1118197933, - "org.springframework.cloud:spring-cloud-context:jar:sources": -1413797918, - "org.springframework.cloud:spring-cloud-kubernetes-client-autoconfig": -256822388, - "org.springframework.cloud:spring-cloud-kubernetes-client-autoconfig:jar:sources": 758022911, - "org.springframework.cloud:spring-cloud-kubernetes-client-config": 954066893, - "org.springframework.cloud:spring-cloud-kubernetes-client-config:jar:sources": -251471561, - "org.springframework.cloud:spring-cloud-kubernetes-commons": -500725348, - "org.springframework.cloud:spring-cloud-kubernetes-commons:jar:sources": -325491963, - "org.springframework.cloud:spring-cloud-starter": -1812063683, - "org.springframework.cloud:spring-cloud-starter-bootstrap": -1263482746, - "org.springframework.cloud:spring-cloud-starter-bootstrap:jar:sources": 1965832056, - "org.springframework.cloud:spring-cloud-starter-kubernetes-client-config": -251169345, - "org.springframework.data:spring-data-cassandra": -546629484, - "org.springframework.data:spring-data-cassandra:jar:sources": -1628107854, - "org.springframework.data:spring-data-commons": 1312199320, - "org.springframework.data:spring-data-commons:jar:sources": 544548950, - "org.springframework.retry:spring-retry": -2038056656, - "org.springframework.retry:spring-retry:jar:sources": -870799349, - "org.springframework.security:spring-security-config": 2001744589, - "org.springframework.security:spring-security-config:jar:sources": -756968726, - "org.springframework.security:spring-security-core": -1251894794, - "org.springframework.security:spring-security-core:jar:sources": 1285888871, - "org.springframework.security:spring-security-crypto": 424824057, - "org.springframework.security:spring-security-crypto:jar:sources": 1862561396, - "org.springframework.security:spring-security-oauth2-client": -1975050683, - "org.springframework.security:spring-security-oauth2-client:jar:sources": 1833974239, - "org.springframework.security:spring-security-oauth2-core": -1658804453, - "org.springframework.security:spring-security-oauth2-core:jar:sources": -948845785, - "org.springframework.security:spring-security-oauth2-jose": 502613895, - "org.springframework.security:spring-security-oauth2-jose:jar:sources": 17294361, - "org.springframework.security:spring-security-oauth2-resource-server": -1894007153, - "org.springframework.security:spring-security-oauth2-resource-server:jar:sources": -1508178760, - "org.springframework.security:spring-security-test": 1672796517, - "org.springframework.security:spring-security-test:jar:sources": -1326480212, - "org.springframework.security:spring-security-web": -1696304083, - "org.springframework.security:spring-security-web:jar:sources": 1443816202, - "org.springframework:spring-aop": -819786825, - "org.springframework:spring-aop:jar:sources": 1924976574, - "org.springframework:spring-beans": -698130853, - "org.springframework:spring-beans:jar:sources": -2147408778, - "org.springframework:spring-context": -846077202, - "org.springframework:spring-context-support": 427709038, - "org.springframework:spring-context-support:jar:sources": -410245914, - "org.springframework:spring-context:jar:sources": -1263444176, - "org.springframework:spring-core": -253727183, - "org.springframework:spring-core:jar:sources": -173347576, - "org.springframework:spring-expression": 1724609785, - "org.springframework:spring-expression:jar:sources": 1135225455, - "org.springframework:spring-test": -279979944, - "org.springframework:spring-test:jar:sources": -6017836, - "org.springframework:spring-tx": 1899606770, - "org.springframework:spring-tx:jar:sources": -1007028336, - "org.springframework:spring-web": 2084009704, - "org.springframework:spring-web:jar:sources": 1608360284, - "org.springframework:spring-webflux": 1763806581, - "org.springframework:spring-webflux:jar:sources": -1419709374, - "org.springframework:spring-webmvc": 56813816, - "org.springframework:spring-webmvc:jar:sources": -837106767, - "org.testcontainers:testcontainers": 450183679, - "org.testcontainers:testcontainers-cassandra": 888108804, - "org.testcontainers:testcontainers-cassandra:jar:sources": 2024290088, - "org.testcontainers:testcontainers-database-commons": -1213526598, - "org.testcontainers:testcontainers-database-commons:jar:sources": 315333060, - "org.testcontainers:testcontainers-junit-jupiter": -1827576744, - "org.testcontainers:testcontainers-junit-jupiter:jar:sources": 975697823, - "org.testcontainers:testcontainers-localstack": 744979553, - "org.testcontainers:testcontainers-localstack:jar:sources": 311852137, - "org.testcontainers:testcontainers:jar:sources": 76092129, - "org.wiremock:wiremock-standalone": -1817681233, - "org.wiremock:wiremock-standalone:jar:sources": 695361099, - "org.xmlunit:xmlunit-core": 1938864481, - "org.xmlunit:xmlunit-core:jar:sources": -54376142, - "org.yaml:snakeyaml": -1432706414, - "org.yaml:snakeyaml:jar:sources": 393768628, - "software.amazon.awssdk:annotations": -647669452, - "software.amazon.awssdk:annotations:jar:sources": -277384386, - "software.amazon.awssdk:checksums": 573213413, - "software.amazon.awssdk:checksums-spi": -720493267, - "software.amazon.awssdk:checksums-spi:jar:sources": -650776626, - "software.amazon.awssdk:checksums:jar:sources": -241565759, - "software.amazon.awssdk:endpoints-spi": 1412926322, - "software.amazon.awssdk:endpoints-spi:jar:sources": -1092637607, - "software.amazon.awssdk:http-auth-aws": -589182304, - "software.amazon.awssdk:http-auth-aws:jar:sources": -993506252, - "software.amazon.awssdk:http-auth-spi": -45686548, - "software.amazon.awssdk:http-auth-spi:jar:sources": -1486999869, - "software.amazon.awssdk:http-client-spi": 1386281563, - "software.amazon.awssdk:http-client-spi:jar:sources": 541891925, - "software.amazon.awssdk:identity-spi": -969758372, - "software.amazon.awssdk:identity-spi:jar:sources": -1418587191, - "software.amazon.awssdk:json-utils": -1666742251, - "software.amazon.awssdk:json-utils:jar:sources": 1618084806, - "software.amazon.awssdk:metrics-spi": -500500368, - "software.amazon.awssdk:metrics-spi:jar:sources": -1496041869, - "software.amazon.awssdk:profiles": 1556987661, - "software.amazon.awssdk:profiles:jar:sources": 517790158, - "software.amazon.awssdk:regions": 1394259783, - "software.amazon.awssdk:regions:jar:sources": 927040140, - "software.amazon.awssdk:retries": 1273159411, - "software.amazon.awssdk:retries-spi": 1857446587, - "software.amazon.awssdk:retries-spi:jar:sources": -974151310, - "software.amazon.awssdk:retries:jar:sources": 1826499536, - "software.amazon.awssdk:sdk-core": 1641186658, - "software.amazon.awssdk:sdk-core:jar:sources": -769872481, - "software.amazon.awssdk:third-party-jackson-core": -1062653941, - "software.amazon.awssdk:third-party-jackson-core:jar:sources": -230379012, - "software.amazon.awssdk:utils": 1497168994, - "software.amazon.awssdk:utils:jar:sources": 249477790, - "tools.jackson.core:jackson-core": -1258054011, - "tools.jackson.core:jackson-core:jar:sources": -1689479769, - "tools.jackson.core:jackson-databind": 1443518747, - "tools.jackson.core:jackson-databind:jar:sources": -871567409, - "tools.jackson.module:jackson-module-blackbird": 1038981586, - "tools.jackson.module:jackson-module-blackbird:jar:sources": -9825245 - }, - "artifacts": { - "args4j:args4j": { - "shasums": { - "jar": "11b029a602e787e2bc08eb3b77eda1a4f5e8b263d22e3c5d6220cd5c51f30b18", - "sources": "ec1eb6aa4859b9b4fd9da4d58efb28b2eb629a4c14919e9078054879540243b7" - }, - "version": "2.0.28" - }, - "at.yawk.lz4:lz4-java": { - "shasums": { - "jar": "49753ae8a9b7dc3ce48cb2989cc6605e43eb8269748ad3466251836ec4cd02a8", - "sources": "3b9a0590c53a4f4e45b204695af0e480dbd4f3a589913c6a36f7c2c3d31b0eaa" - }, - "version": "1.10.3" - }, - "ch.qos.logback:logback-classic": { - "shasums": { - "jar": "b65e05076a5c1aadb659b4fe4bc5fee31cb26cd70390292eb03e4a7a24cff10f", - "sources": "c2e39cb4d6d9b8c2343c6da2469e21e1d6aef2dde16c2227762c084d549ad0a0" - }, - "version": "1.5.34" - }, - "ch.qos.logback:logback-core": { - "shasums": { - "jar": "42eda264c0c650c2bec59e66151a88b708a8663dc1b49d788202d53e78b8caae", - "sources": "6a9f217ef206caf2880810c505e057fd2bb90a6024013906815e9513c6e488c5" - }, - "version": "1.5.34" - }, - "com.bucket4j:bucket4j-core": { - "shasums": { - "jar": "c274208e4961855e8e341bcb74434af8771ce98a494aec48997028efeb4909f2", - "sources": "fb9270f4aef9d0688e12f9b83553fe2bc1fa0c15bd98894579c3f19b489ef4dc" - }, - "version": "8.10.1" - }, - "com.bucket4j:bucket4j_jdk17-core": { - "shasums": { - "jar": "603885663799e203f7e17394315fdbdc584fe021643614d8a34b49b53e618c74", - "sources": "e68a40186a9ef6f80e05db48ac76d7beca94b8d5bd635fb22aeab784ad16a520" - }, - "version": "8.19.0" - }, - "com.datastax.cassandra:cassandra-driver-core": { - "shasums": { - "jar": "09c4d54009e942e3afb8755c5fd51abac8ba721e407b61dcb22f435d1a33c1a1", - "sources": "b0e1d20dd052986f1cc1511fee039801ebb1ae3474a14f0708bedf9b6278083d" - }, - "version": "3.10.0" - }, - "com.datastax.oss:native-protocol": { - "shasums": { - "jar": "190dc40f3c63d6d803c48f90d457e06c65e6c5d955e47d4735dc9954a6743655", - "sources": "6029f3fd12ebe066826642d42f0efb63108b051577828458b66a8637847e88c9" - }, - "version": "1.5.2" - }, - "com.fasterxml.jackson.core:jackson-annotations": { - "shasums": { - "jar": "53ca085f4a150f703f49e1aabd935bd03b43e1ea3d55d135438292af22cef56b", - "sources": "71fe6323d91b16d5d1007fd1e1533fa06bb369abde74f68a42a68c0f8f061a8b" - }, - "version": "2.21" - }, - "com.fasterxml.jackson.core:jackson-core": { - "shasums": { - "jar": "4b40a06396f239f8de2da57419adde6e94e5edc18a2171d471ea05eeed4e5c2d", - "sources": "90ccada55626ce4f00a81bde235af0a942ec2bc4c701fcc86a93af1be9b3e08d" - }, - "version": "2.21.4" - }, - "com.fasterxml.jackson.core:jackson-databind": { - "shasums": { - "jar": "3888e9e69ab66fbacaacc9aea0e9ffbf15368288e4aca468b024dba11c09fbf9", - "sources": "23188e78e912c9866367bf038fb7f729e79f1c2724174ca66e0a00915de70e61" - }, - "version": "2.21.4" - }, - "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml": { - "shasums": { - "jar": "055eb4c008ab12f0cb63e93a6454463d032fde0fca85943d69f8dc7469489e4b", - "sources": "164cef68956eb2797e421dd6cf74bfd648581965a8df2389c260bb363d1f3baa" - }, - "version": "2.21.4" - }, - "com.fasterxml.jackson.datatype:jackson-datatype-jsr310": { - "shasums": { - "jar": "d1ac4b98b70304e56448423589fde5e775b100889643ad1ead62cc7811633684", - "sources": "884a8812af289bb56f38f09a4b3b7b73b4a16dbc184ae735fbe6c4aa1089161f" - }, - "version": "2.21.4" - }, - "com.fasterxml:classmate": { - "shasums": { - "jar": "75fbda45456f123fb6e2028a6189442d8d0730b357adce4c0a6d7e789f70669b", - "sources": "b0690a771dc54865c3d0ad9ab6abb319633b6b88849900a28f719e792c15fc68" - }, - "version": "1.7.3" - }, - "com.github.ben-manes.caffeine:caffeine": { - "shasums": { - "jar": "9d9d2cfd681fd9272ded3d27c9930db12f89f732345975aa113ebc223bbf1224", - "sources": "5079e1b327d79e2fc8ae3f5927587e59c968603e63785fb33479acd8b732211d" - }, - "version": "3.2.4" - }, - "com.github.ben-manes.caffeine:guava": { - "shasums": { - "jar": "7819335459a43b3d2d501bd19b6cf880041a1ad47a9a118d018d89c432357358", - "sources": "2de42779d0ee1807262065382a9302715b2d8daa186f9b39aca1043c10681ab5" - }, - "version": "3.2.4" - }, - "com.github.docker-java:docker-java-api": { - "shasums": { - "jar": "dad153d484b1f4ef009e2fdbad27e07aeb3191122da52b8985507ac504300081", - "sources": "57c9b5bc37d48c256a2a0de556095158f363b10eec58052e58f299c542cf9391" - }, - "version": "3.7.1" - }, - "com.github.docker-java:docker-java-transport": { - "shasums": { - "jar": "d15eec8034bf0f92c2a48ca9172691804048115c96dc853272f9486fa2695c3c", - "sources": "131ed62714d94125f89a3c3ad966e517c8ad48fbbc1905b08bcdafc0d6e9de45" - }, - "version": "3.7.1" - }, - "com.github.docker-java:docker-java-transport-zerodep": { - "shasums": { - "jar": "b89bdb1754160323597f9ea32a7fe7a4a3aa8f5b3b43b88e8d71fff3b267ab21", - "sources": "f4d1457f9e2e151d19713e46cf2b49796887d5a9744664a15a4ce07c76660883" - }, - "version": "3.7.1" - }, - "com.github.java-json-tools:btf": { - "shasums": { - "jar": "67c3e462eb50807f4e0a5f4dee304bbf17cd986a42ee5eb0b2f4c9bf64d130d9", - "sources": "97f8bfb9a8876534bf2832a5be4b913b695d72c6ff6f9c8c6719bd38fd4aeb73" - }, - "version": "1.3" - }, - "com.github.java-json-tools:jackson-coreutils": { - "shasums": { - "jar": "16b3aabd3a9eb25655dda433e35f9bd9c7c1aa7991427702f5f11f000813dbb0", - "sources": "6f39b6beed5b000702ade7014be2ca21f895a0b70ab6c199f6ca5bebc1807080" - }, - "version": "2.0" - }, - "com.github.java-json-tools:json-patch": { - "shasums": { - "jar": "1f794d256965b53ef37e70b55505e2ed00ddc0184d44e2e8e1fdce5a3cacc7de", - "sources": "f4ba54ca57611123fe972f05537d44d4b61fd8ed6f71541b3ca37e09a6e3e318" - }, - "version": "1.13" - }, - "com.github.java-json-tools:msg-simple": { - "shasums": { - "jar": "bef4111b993a5b3e6148d8f585621cceac2a1889cdbc34448b11632e0d8a9a8f", - "sources": "eeb0ecd504611cec75f261a6d282bb8b80214e473ef235481c8067b6b121f1cd" - }, - "version": "1.2" - }, - "com.github.jnr:jffi": { - "shasums": { - "jar": "7a616bb7dc6e10531a28a098078f8184df9b008d5231bdc5f1c131839385335f", - "native": "ef78953e3dbf47fab94469190bc2a6d601566a21d4651f73c822bad1c02b64fe", - "sources": "45ad89d2774e9d03de89905cf990d49d5821ce8012a841faddf23dca02538d72" - }, - "version": "1.2.16" - }, - "com.github.jnr:jnr-constants": { - "shasums": { - "jar": "a617b0d8463d3ea36435bd1611113dedb3749157afd2269908ab306c992aefed", - "sources": "9406718df04cd893a94933213b370d99c613d94d80e23119e2cf8dc51394ea12" - }, - "version": "0.10.3" - }, - "com.github.jnr:jnr-ffi": { - "shasums": { - "jar": "2ed1bedf59935cd3cc0964bac5cd91638b2e966a82041fe0a6c85f52279c9b34", - "sources": "61842708c7e617ae2ca3a389931142f506f854104392fa6f7aaac6f51c93cf58" - }, - "version": "2.1.7" - }, - "com.github.jnr:jnr-posix": { - "shasums": { - "jar": "c38ecfccd24e5f21f17a62e45d5bd454842c5db17ed42b01b868f9206d0e99e7", - "sources": "abfff56a7628d223ba86c3ccb3bcb5101aeefdeedbe58c3c52b1917a92d7e332" - }, - "version": "3.1.15" - }, - "com.github.jnr:jnr-x86asm": { - "shasums": { - "jar": "39f3675b910e6e9b93825f8284bec9f4ad3044cd20a6f7c8ff9e2f8695ebf21e", - "sources": "3c983efd496f95ea5382ca014f96613786826136e0ce13d5c1cbc3097ea92ca0" - }, - "version": "1.0.2" - }, - "com.github.stephenc.jcip:jcip-annotations": { - "shasums": { - "jar": "4fccff8382aafc589962c4edb262f6aa595e34f1e11e61057d1c6a96e8fc7323", - "sources": "d60bb3bf4e03a5e405f9b16f4c2625de86089d6ce4f999bcc2548dcac090ae19" - }, - "version": "1.0-1" - }, - "com.google.android:annotations": { - "shasums": { - "jar": "ba734e1e84c09d615af6a09d33034b4f0442f8772dec120efb376d86a565ae15", - "sources": "e9b667aa958df78ea1ad115f7bbac18a5869c3128b1d5043feb360b0cfce9d40" - }, - "version": "4.1.1.4" - }, - "com.google.api.grpc:proto-google-common-protos": { - "shasums": { - "jar": "ee9c751f06b112e92b37f75e4f73a17d03ef2c3302c6e8d986adbcc721b63cb0", - "sources": "fe7831089c20c097ef540b61ff90d12cfe0fbc57c2bbe21a3e8fa96bb0085d99" - }, - "version": "2.29.0" - }, - "com.google.code.findbugs:jsr305": { - "shasums": { - "jar": "766ad2a0783f2687962c8ad74ceecc38a28b9f72a2d085ee438b7813e928d0c7", - "sources": "1c9e85e272d0708c6a591dc74828c71603053b48cc75ae83cce56912a2aa063b" - }, - "version": "3.0.2" - }, - "com.google.code.gson:gson": { - "shasums": { - "jar": "dd0ce1b55a3ed2080cb70f9c655850cda86c206862310009dcb5e5c95265a5e0", - "sources": "058974b69cb7b0a04712278e11870e84ee8cd8fb5f551bd8401e72ba6638bfef" - }, - "version": "2.13.2" - }, - "com.google.errorprone:error_prone_annotations": { - "shasums": { - "jar": "3b1003e51b8ae56fdbd7c71073e81d1683b97e6c4dff5a9151164d59b769d13c", - "sources": "69d2de7f69033ff914ba06f0858adb96ac7b1436959f04fca7de5805c834b281" - }, - "version": "2.49.0" - }, - "com.google.guava:failureaccess": { - "shasums": { - "jar": "cbfc3906b19b8f55dd7cfd6dfe0aa4532e834250d7f080bd8d211a3e246b59cb", - "sources": "6fef4dfd2eb9f961655f2a3c4ea87c023618d9fcbfb6b104c17862e5afe66b97" - }, - "version": "1.0.3" - }, - "com.google.guava:guava": { - "shasums": { - "jar": "dc573e1fca4fd5454f4a5fd3d7da2df03002876a4175bafc14a95980dd7713b3", - "sources": "eff31867dd63a92d63ca856127a424a6836418d8bfa044162cac20430abd3500" - }, - "version": "33.6.0-jre" - }, - "com.google.guava:listenablefuture": { - "shasums": { - "jar": "b372a037d4230aa57fbeffdef30fd6123f9c0c2db85d0aced00c91b974f33f99" - }, - "version": "9999.0-empty-to-avoid-conflict-with-guava" - }, - "com.google.j2objc:j2objc-annotations": { - "shasums": { - "jar": "84d3a150518485f8140ea99b8a985656749629f6433c92b80c75b36aba3b099b", - "sources": "295938307f4016b3f128f7347101b236ada1394808104519c9e93cd61b64602b" - }, - "version": "3.1" - }, - "com.google.protobuf:protobuf-java": { - "shasums": { - "jar": "3ca892fd6ea8b37d01bb6917dbc0bf2637548b756753f65a28d4f1d4d982347f", - "sources": "ed30fe6a51c7c15a6f123448304c97185f2039f2aeca9d5e3b4f53de3a4c813c" - }, - "version": "4.33.4" - }, - "com.google.protobuf:protobuf-java-util": { - "shasums": { - "jar": "6f02f04c5ca088e74b68dbbaf118f1ffa9d587958e637f893e0f8a1899a61342", - "sources": "4bf8ae758fdaae56220796e651cf5fbc3f7ce99bdc42b7048c2604f757592f8a" - }, - "version": "4.33.4" - }, - "com.jayway.jsonpath:json-path": { - "shasums": { - "jar": "890daa95dd3892d34d9fabc27cd5153656e6f369358625c88f4dc7b79cbd6c5a", - "sources": "357f1c52217497c4251fae715ba8ef76ae310b1aae77ea319260bf4c6ad61440" - }, - "version": "2.10.0" - }, - "com.nimbusds:content-type": { - "shasums": { - "jar": "60349793e006fba96b532cb0c21e10e969fe0db8d87f91c3b9eaf82ba2998895", - "sources": "9a154c802659594d8745a0e364bd2e6b418e010268467cd222354445dd77d626" - }, - "version": "2.3" - }, - "com.nimbusds:lang-tag": { - "shasums": { - "jar": "e8c1c594e2425bdbea2d860de55c69b69fc5d59454452449a0f0913c2a5b8a31", - "sources": "8d37da312db366d702bd7254df6bceca0a7814e18da9c32db9cc1d8ca038c468" - }, - "version": "1.7" - }, - "com.nimbusds:nimbus-jose-jwt": { - "shasums": { - "jar": "6f13f3480ddc53d820d276f582f54843cff1daf5c6e35e534947e9de7723b46b", - "sources": "b3fd3b569013246fb9a1ac6b43ff3e3033065bce16de92ecf4c971d14875eb30" - }, - "version": "10.4" - }, - "com.nimbusds:oauth2-oidc-sdk": { - "shasums": { - "jar": "648494b00da090a4df23aa6a05e4dc03f6e8603b29dd807a4491f33d586f7f78", - "sources": "e4de2ef818fbb57aa3731b65e2f5edc1a40dc1e3f6e6541306ca9f45490aed2a" - }, - "version": "11.26.1" - }, - "com.squareup.okhttp3:logging-interceptor": { - "shasums": { - "jar": "f3e8d5f0903c250c2b55d2f47fcfe008e80634385da8385161c7a63aaed0c74c", - "sources": "967335783f8af3fca7819f9f343f753243f2877c5480099e2084fe493af7da82" - }, - "version": "4.12.0" - }, - "com.squareup.okhttp3:okhttp": { - "shasums": { - "jar": "b1050081b14bb7a3a7e55a4d3ef01b5dcfabc453b4573a4fc019767191d5f4e0", - "sources": "d91a769a4140e542cddbac4e67fcf279299614e8bfd53bd23b85e60c2861341c" - }, - "version": "4.12.0" - }, - "com.squareup.okhttp3:okhttp-jvm": { - "shasums": { - "jar": "9632c08567dbb21c569b13d793107834c8580d44e4eea74b2eae0722f0506179", - "sources": "9fa32be62c7a46ffe70cdb1bf7e195f5ee3fc885999379292cb636b5aa311704" - }, - "version": "5.2.1" - }, - "com.squareup.okio:okio": { - "shasums": { - "jar": "8e63292e5c53bb93c4a6b0c213e79f15990fed250c1340f1c343880e1c9c39b5", - "sources": "64d5b6667f064511dd93100173f735b2d5052a1c926858f4b6a05b84e825ef94" - }, - "version": "3.6.0" - }, - "com.squareup.okio:okio-jvm": { - "shasums": { - "jar": "31f48e6463ec587d6d262d042c91da00659c983b6ad20d5982bf31e85222693c", - "sources": "b29b5f4ad1adfd7cbfb3d388f7bf29d1702f0b85be1b6c61b0185ce7e2b2e6dc" - }, - "version": "3.16.1" - }, - "com.typesafe:config": { - "shasums": { - "jar": "4c0aa7e223c75c8840c41fc183d4cd3118140a1ee503e3e08ce66ed2794c948f", - "sources": "89af318a607f7e2b2691ed1ef4b4890bd37ea17d6986b0aec50dd4d5f889520c" - }, - "version": "1.4.1" - }, - "com.vaadin.external.google:android-json": { - "shasums": { - "jar": "dfb7bae2f404cfe0b72b4d23944698cb716b7665171812a0a4d0f5926c0fac79", - "sources": "54c781eea645c450cbbc4a5a1b5a474745465452cec1354cb567b781ea6622c3" - }, - "version": "0.0.20131108.vaadin1" - }, - "commons-codec:commons-codec": { - "shasums": { - "jar": "5c3881e4f556855e9c532927ee0c9dfde94cc66760d5805c031a59887070af5f", - "sources": "b0462142585d45fc15bc8091b7b02f1e3a85c83595068659548c82cac9cdc7a2" - }, - "version": "1.19.0" - }, - "commons-io:commons-io": { - "shasums": { - "jar": "df90bba0fe3cb586b7f164e78fe8f8f4da3f2dd5c27fa645f888100ccc25dd72", - "sources": "7a87277538cce40da6389a7163a4d9458bc7a9c39937a329881b91d144be8e0d" - }, - "version": "2.20.0" - }, - "commons-logging:commons-logging": { - "shasums": { - "jar": "f8ead8943401081dea0aa824b5b1ba40a0e4ed297a572a0f02258150a0b62357", - "sources": "6e821e03cfc64e509cc162d428af84697b6c4188eb14c0b137c75b69649976ef" - }, - "version": "1.3.6" - }, - "io.cloudevents:cloudevents-api": { - "shasums": { - "jar": "95751500be617f0c795ea3cd7c370fa712459da500fbd22bb8b7f69fcba46e97", - "sources": "962306ae4d9c9aaea5958a3e5e837c895bc683098c2da7f2fa8e972dfea82ebd" - }, - "version": "4.1.1" - }, - "io.cloudevents:cloudevents-core": { - "shasums": { - "jar": "25c3756d184eebf20aceadbd2357cd48516938ca458a1b77a3ebdc09f8dfc592", - "sources": "869ae88ca9b7f7e62af3f34ae6269e7c816b58d08ef371040530164e2aaea02a" - }, - "version": "4.1.1" - }, - "io.cloudevents:cloudevents-json-jackson": { - "shasums": { - "jar": "28aa328c61ae1783cecb430f7b51880e365ea8678628eca416e12654eafbb66d", - "sources": "b4ee1b7db2dfa50101a9fa7a3beef610b6931546be1bc5a61ae28cc929473406" - }, - "version": "4.1.1" - }, - "io.dropwizard.metrics:metrics-core": { - "shasums": { - "jar": "a735eb5b62f425181efa53aefa5b7edad2b0e48cd0fa91105aa0ec1a45169e0b", - "sources": "da7c32215bb0e94f8e735f7ebd70acd08340ea36d4e0cdf150ae1435e3a25221" - }, - "version": "4.1.18" - }, - "io.grpc:grpc-api": { - "shasums": { - "jar": "21d747911e1e5931004f1b058417f3c3f72f1fbf8aea16f5fc6af7a3f0caf35a", - "sources": "7ff367383a7e67241d72404f584a73d47d8f0a6b4c0bdf8aca4170f6475e58a3" - }, - "version": "1.63.0" - }, - "io.grpc:grpc-context": { - "shasums": { - "jar": "d7f50185bb858131d02314de23ea3cc797131ed98b215e845429f45a81dd5fed", - "sources": "a9032f8d2f795247bef60b45ee5fc3eb4693c705c05818cc12e9ed1deba440d4" - }, - "version": "1.63.0" - }, - "io.grpc:grpc-core": { - "shasums": { - "jar": "246e4e583cc11c70ed15cc8f988eff8e76fed5c06426e8310d51c4da6f5cc81b", - "sources": "6d2f37cebce94495593d736e118d6df8ff05b877e2ebc2b5e472c140a5fa5559" - }, - "version": "1.63.0" - }, - "io.grpc:grpc-inprocess": { - "shasums": { - "jar": "5386e23de85651bf868c3565bfa4f1af1bb9c888d8de5ae4350e010064041336", - "sources": "55a86f1a031e1c7dfe4bae6b6350ff561003e0395ca2c3af5114a3aab8afaa22" - }, - "version": "1.63.0" - }, - "io.grpc:grpc-netty-shaded": { - "shasums": { - "jar": "4d170c599e47214f35c8955cda3edd7cdb8171229b45795d4d61eb43dfa76402", - "sources": "a9032f8d2f795247bef60b45ee5fc3eb4693c705c05818cc12e9ed1deba440d4" - }, - "version": "1.63.0" - }, - "io.grpc:grpc-protobuf": { - "shasums": { - "jar": "260e0abaf8ac72fc71deec9f88d2beeb163e6d19494bbabe45676a4b4ce87087", - "sources": "e44785571580c4bfc25582a739f66acacf4af030bb6d58d8459532d4570225a6" - }, - "version": "1.63.0" - }, - "io.grpc:grpc-protobuf-lite": { - "shasums": { - "jar": "5e7f36c03600c7cfa8e10d2d0321f0ba8c32d74cd044873f44b026704f355fb7", - "sources": "0464b0b77b4360c0f9916477859abbbf22457a9d18c343743635e7247c2af684" - }, - "version": "1.63.0" - }, - "io.grpc:grpc-services": { - "shasums": { - "jar": "5258358c47d5afb1dc8fd6bc869c93b02bce686c156f5e0a1aab5d39b1d8e0a5", - "sources": "d265c23748ecd5c15142978d38798e8db4a2cd146cf7fe6f8cb535f202219561" - }, - "version": "1.63.0" - }, - "io.grpc:grpc-stub": { - "shasums": { - "jar": "a92fc7c7f1ac9d580c5e3df5825b977c842f442874794663b78db22b27d649e0", - "sources": "77cf1024d4612bf7ec085ff330456eb49cdbaa93e21559396f07b063ea289238" - }, - "version": "1.63.0" - }, - "io.grpc:grpc-util": { - "shasums": { - "jar": "b15006f22e76a6631dfb137a6930aaf9e0cb3a797499ec42394d79641fb770ee", - "sources": "969b6a21c1689ad8d71e4f557ccd76c9c3f422c037fe0e5c1e9c9b3f6eeb45d6" - }, - "version": "1.63.0" - }, - "io.gsonfire:gson-fire": { - "shasums": { - "jar": "73f56642ef43381efda085befb1e6cb51ce906af426d8db19632d396a5bb7a91", - "sources": "40d8500f33c7309515782d5381593a9d6c42699fc3fe38df0055ec4e08055f59" - }, - "version": "1.9.0" - }, - "io.kubernetes:client-java": { - "shasums": { - "jar": "8facf414f052bd39176703f0a5e923e3ed945fa736eb4a00cc685e633eaeb286", - "sources": "f4982edc9570241d940971b6f9a93a60976596584feba462e94c58263b234abe" - }, - "version": "24.0.0" - }, - "io.kubernetes:client-java-api": { - "shasums": { - "jar": "580bf0c6c7ab498cb53d16d975ee6fab8183e90c8993f39a9e739e100bb432d3", - "sources": "0248c50909280447729c9ab996abf41b96bcf54e1d7c9567b49dcddfae78fa67" - }, - "version": "24.0.0" - }, - "io.kubernetes:client-java-api-fluent": { - "shasums": { - "jar": "abd85f46b6a8d81032e25129dcc04a04e3efe414057255b91593e1a08aff0be5", - "sources": "febf43923730c43335aecb9bf8e16618cf9d6d35fef6acbd3b11579cf4e6cf75" - }, - "version": "24.0.0" - }, - "io.kubernetes:client-java-extended": { - "shasums": { - "jar": "5c7089ef93a08714f6b63142579cf7a9f7c2bde62bdf530174351ba390002281", - "sources": "127e271c85091a8a4f563cea1a7a4e16051b3db77b0b824ae1e51a2aada57787" - }, - "version": "24.0.0" - }, - "io.kubernetes:client-java-proto": { - "shasums": { - "jar": "ffe88472b1bac61e08fa19e8a3af53f5a4ee314913f77313f0a1beff7ca228b1", - "sources": "b954e41c5b45105699d1ee179f4e6fb6b0c707a9f3fe52a418989070194232d2" - }, - "version": "24.0.0" - }, - "io.micrometer:context-propagation": { - "shasums": { - "jar": "5b69e2100640879ccf4b20673ced86de560b8e217b55542f85a53d3563b72aaa", - "sources": "719639b819c3ecc76f2b3d4da4b17ca7a8ed6c73b93a770c69aa9d86276f8bf2" - }, - "version": "1.2.1" - }, - "io.micrometer:micrometer-commons": { - "shasums": { - "jar": "45aff76226830db257f4bc39a5bcff83d633e572fee9dc4e45cfa12af9a0a49a", - "sources": "0e4a336c7bca50bfa6cbea274ea681e42d86bfdac1038af3041301c8454f76ff" - }, - "version": "1.16.6" - }, - "io.micrometer:micrometer-core": { - "shasums": { - "jar": "1957ef2deaffbc1fb98cebfd0f5b3109ecf19c994d7e5378598c20747ba8d68b", - "sources": "f85d566a76d98891cdecd54c106b7ad7f8948cddad3b393debe341ecfba18bce" - }, - "version": "1.16.6" - }, - "io.micrometer:micrometer-jakarta9": { - "shasums": { - "jar": "987722add6461c5a4c796be11e7452e8813fba341f2cc067b1d283eef2bd4f40", - "sources": "83fa1c6356611b3381d6309a6159b2739c9c29446c8b52183b2111fb13ce5301" - }, - "version": "1.16.6" - }, - "io.micrometer:micrometer-observation": { - "shasums": { - "jar": "4c0826d5e7c8522a8e111470b4e77f77b0a10f520eb5502ddd143fdbcedb2340", - "sources": "ff5525482df358e7502d4c8680fb654ec700e3b01341149d870bd6cfd8ce04c0" - }, - "version": "1.16.6" - }, - "io.micrometer:micrometer-observation-test": { - "shasums": { - "jar": "e69bf8df81458f4ad6f6027a7310d75c8ca8d11df2e95d44dd4616f8637069ad", - "sources": "1ebcdbf4e14e6a4dcec4ad188bc4227ebd5ce0a3f361f5f0ed6df2bebb10cfb2" - }, - "version": "1.16.6" - }, - "io.micrometer:micrometer-registry-prometheus": { - "shasums": { - "jar": "0e9c7a32dffea3745f2ebff41a4cfeddc5269ca0fd6d98d6e3bafc7b5e35375d", - "sources": "76668b6182ad39e92ddc48ee7815d32cd84ceea4c6751ee13f076a86a37c8136" - }, - "version": "1.16.6" - }, - "io.micrometer:micrometer-tracing": { - "shasums": { - "jar": "b335096393e4d070dfda4fb30808f8488d31d43811b93b2d7496703c5f1315ef", - "sources": "a089a2bcc462d6ced28d7f67b01a9f54baf6c52984cd13f3ed713f2fda0810c6" - }, - "version": "1.6.6" - }, - "io.micrometer:micrometer-tracing-bridge-otel": { - "shasums": { - "jar": "581b6908d46ed2df6b9bb8167df4c44deddc5c2567c430c73bca66326138f661", - "sources": "2aa7115e2f0562e3c50149e77d6fc41340b20d5111b737ea443e0b8bf53a75b3" - }, - "version": "1.6.6" - }, - "io.nats:jnats": { - "shasums": { - "jar": "a5705531ff8fc96657d99d2fc4436178c04463df6a216ba6b5528a5d5228f240", - "sources": "40d6500a369ad57822074fa2a838367e4818ac61eba5c038c95b54772c4ef96f" - }, - "version": "2.23.0" - }, - "io.netty:netty-buffer": { - "shasums": { - "jar": "1361fd9c9ba85b9831cf54a1b2e45ddc3ce34a768931726c099d3f5ef0efe4a3", - "sources": "13259b636c4a91c0f34a8536d621178fba302f9ba61f3e4aaec3a17ca291dc2a" - }, - "version": "4.2.15.Final" - }, - "io.netty:netty-codec-base": { - "shasums": { - "jar": "2c6d39d7270628b8cfc3166fbd7a93d595958e59c461bc32ddb383c8c91bf811", - "sources": "029bea433dfc710c640338954c7403cc7ac31cc5bf4c192904c837b0ebda5fb2" - }, - "version": "4.2.15.Final" - }, - "io.netty:netty-codec-classes-quic": { - "shasums": { - "jar": "ec1d5da906ea0139741cd8c570907c399df5995e48a2b07fe3155272e0be21a6", - "sources": "edfbbece45f21e8f214c0f08f33666ef09ae4580322ffa27020633b5fdee6250" - }, - "version": "4.2.15.Final" - }, - "io.netty:netty-codec-compression": { - "shasums": { - "jar": "4adaa5cdd4d2e9b50b23e4c3eff42e73de6eb40848718b3aa84cd5b454da6ce8", - "sources": "58d61aa4f781657f955a196f17e28fcd9b02e21658b996571e4604a2dadbd8af" - }, - "version": "4.2.15.Final" - }, - "io.netty:netty-codec-dns": { - "shasums": { - "jar": "c5e2c05b4faeba3cf374cc6af29d6f4a7e969d7ca222be958e0800c79a02ee4e", - "sources": "f10017539ab2816efee10b70b47b262c04b881fca685327769d576dd8b222b47" - }, - "version": "4.2.15.Final" - }, - "io.netty:netty-codec-http": { - "shasums": { - "jar": "76ae57e87af37b3c4107140f50b9244b1456163a6a225510838f7c5a4458ec22", - "sources": "76b25b4884e7bec78cd310415b068204e67da5a87162774abfad9a0e6c7a0e78" - }, - "version": "4.2.15.Final" - }, - "io.netty:netty-codec-http2": { - "shasums": { - "jar": "4a9b052bd815c765d9c05e27b32abbd32a2c7c3e3364ccb992ce71da1a26bc0d", - "sources": "01f8ad714e5abb989b0e782da9ec467068821299cd17d80c2db833a6472507f6" - }, - "version": "4.2.15.Final" - }, - "io.netty:netty-codec-http3": { - "shasums": { - "jar": "f2f96b7557317c1378dd8d84b4d9b1865db285c5e665b1220ea519e9f868929d", - "sources": "3a35802b80f536b5693d53d6dfbf4102e94edd0e7b26b3b8d8ab400a12d0f9e0" - }, - "version": "4.2.15.Final" - }, - "io.netty:netty-codec-native-quic": { - "shasums": { - "linux-aarch_64": "59a8e59aa9d3a886cd7fae30fb3d3a18ebee40fa9dc08b83eb88bee58cf46774", - "linux-x86_64": "850ed59fac6679b5e205bf53187b45dbaf2d105ee5f669440645d2acd89524ec", - "osx-aarch_64": "ce18ffeccef21adb3caca5534061c921ef750662f29028fdde62d65196d63a9d", - "osx-x86_64": "10999923bf08ff5e3a75106bd8dbc5b5e4d06b5e614f8c135981ecb4377c944a", - "sources": "d9772d6d7d0eb6fdf82ccaeb9558f88b5600c6f0696a724f5e067b67bdc049f3", - "windows-x86_64": "40adba6df605302bf98a4a462bb002c4697f60958cea7cfec38f0fab6331eb7a" - }, - "version": "4.2.15.Final" - }, - "io.netty:netty-codec-socks": { - "shasums": { - "jar": "4230d43481241e49382a83da2fa9d5980c5702668fc5aa5a980346ce03d30828", - "sources": "f126a6f94589b56b1c056a5dbbda4e76e4e749cec1591a3e878e4d6854144a43" - }, - "version": "4.2.15.Final" - }, - "io.netty:netty-common": { - "shasums": { - "jar": "78206aa7f6d197caa926291408c01889b6b910ca0f74017d3fcbdaccf9562959", - "sources": "de720a128534ba1072b354c863d671ab1999900a8fddaadc4a68ee74c2e33fd6" - }, - "version": "4.2.15.Final" - }, - "io.netty:netty-handler": { - "shasums": { - "jar": "99b59e4bea72220d2aed52df8baf37d97431b06ade0b135226cdf73168975eab", - "sources": "68306697d15d870e7bb29ab9ce725d121ac3170428e8a5d7a33767c5fb0ffa0e" - }, - "version": "4.2.15.Final" - }, - "io.netty:netty-handler-proxy": { - "shasums": { - "jar": "a06aaaaa1a2e6eb26824e53566bfd020ba930a9390d57a1f0bbf57316e357373", - "sources": "91fa7fc64aaa39982b30cc19974f80021090c91023d1d5f6a8e4179aa3a5056b" - }, - "version": "4.2.15.Final" - }, - "io.netty:netty-resolver": { - "shasums": { - "jar": "24318497f2a3a645964fed418f48879ba11365cab8e1f8d66c47fa7da15ef19a", - "sources": "c87b295c43265b34c749331e12ee667f7d43329338618bee2a08027b839220d2" - }, - "version": "4.2.15.Final" - }, - "io.netty:netty-resolver-dns": { - "shasums": { - "jar": "2e8dd2d861775483d689329ab2546045647c8f8bf5ae3ed2dd48eefbb748952d", - "sources": "4db838a89ec84479476e71956d59c67a957779dc5f9781f1a9964f9a6b607c29" - }, - "version": "4.2.15.Final" - }, - "io.netty:netty-resolver-dns-classes-macos": { - "shasums": { - "jar": "dc91d81e0f6c8987ed34f6ca005b4b97cc6032f933a49f7500940e846ade7c43", - "sources": "00067617cc0927d804091590f9ea5041e39c4f907357e3c969c45078fe10be3d" - }, - "version": "4.2.15.Final" - }, - "io.netty:netty-resolver-dns-native-macos": { - "shasums": { - "osx-x86_64": "a1115fb0fd88fe50209fbd645cbfe09e41fe2d264bb1854dc545f44a1bd020cf", - "sources": "87a85f239a73c9a4e7dde8ca31e0a8dea711b3b5e3cff9df18b8c07f31f5dc50" - }, - "version": "4.2.15.Final" - }, - "io.netty:netty-transport": { - "shasums": { - "jar": "9fb671e96651066cf1a28dad3f1382c7c99df5b8326d4a214d9a375b311f8dc1", - "sources": "e17c0a4c7324a93fa01f00bc6ddd2bf2f6eb94702ad8de7af777dec87f89eaf8" - }, - "version": "4.2.15.Final" - }, - "io.netty:netty-transport-classes-epoll": { - "shasums": { - "jar": "be509407fd71a4b83378567c613420db544d659bb522df7b253a1dbe8ca297fe", - "sources": "bb095191a070714f769bff1dd0e5d2496305d10bd566bdc16dbca5773df48b4e" - }, - "version": "4.2.15.Final" - }, - "io.netty:netty-transport-native-epoll": { - "shasums": { - "linux-x86_64": "5440e38f5ca2858fee8d7898e65291e05b665736c9e8a14c832e707511f5dba6", - "sources": "d48e8de50b0994842bec4e65725a7f8e9734144dd4f08b78ffe5396a70ab06b6" - }, - "version": "4.2.15.Final" - }, - "io.netty:netty-transport-native-unix-common": { - "shasums": { - "jar": "b9ea9fc5ad5eba04e99afdff75b2eb97b5ddfb2ad772e2f2ef5d8f277f3cbd76", - "sources": "2b82c54d1b2b9908ec0104664edf58ded4848ae5b34266ee1cf90707efc420ab" - }, - "version": "4.2.15.Final" - }, - "io.opentelemetry.semconv:opentelemetry-semconv": { - "shasums": { - "jar": "693ad6f04f29b4b593a04adef5f575d28b3a91ea3449ab5b1e1e2e5c6efc6cdc", - "sources": "186f9e009d914ebe31f5994d42ff67c5dba8e0893569a4f0f0eeb7958b956d4f" - }, - "version": "1.37.0" - }, - "io.opentelemetry:opentelemetry-api": { - "shasums": { - "jar": "387b4bf98631fc2ede9470879a8ff28dd8c5cb2d3dcf5b6ef77f5ee2bdb7b4f1", - "sources": "3abc57abcaaff4521a5fb2b89593031da5feca24aa54816ec58a8d08ab71fd4a" - }, - "version": "1.55.0" - }, - "io.opentelemetry:opentelemetry-common": { - "shasums": { - "jar": "fca14bb87309d1193347d179b91c63045fa05a856f1fbeec6ef61c4a7f81b227", - "sources": "4219708637e60172c347e48b677b71f5ad97ab8e4850cfda2f85ed59da74e250" - }, - "version": "1.55.0" - }, - "io.opentelemetry:opentelemetry-context": { - "shasums": { - "jar": "f34a4718b70446ec462703ced5cc2c9ad4c9b7c69dcb41d0f032ba51c625a3dd", - "sources": "e0b63b17ccb407f6208a89a180ad48c6add5cca05d29047e858a6ebe8442b3fb" - }, - "version": "1.55.0" - }, - "io.opentelemetry:opentelemetry-exporter-common": { - "shasums": { - "jar": "3b4faaae49dd87bdefae13528d069a271f8476e2a64420e32f4e959a8d09c132", - "sources": "b795169dce773a549f6f3ce2202886ad93622306f2991bd5771547e3c649a2dc" - }, - "version": "1.55.0" - }, - "io.opentelemetry:opentelemetry-exporter-otlp": { - "shasums": { - "jar": "cf42ce6e7cc6755182149f269447f6677f69c0a31e101464594dbcf62fe874c3", - "sources": "a94ebfb492577503d49d43423328f5d0042206f309a18407386a4ab5375bcc82" - }, - "version": "1.55.0" - }, - "io.opentelemetry:opentelemetry-exporter-otlp-common": { - "shasums": { - "jar": "7ddfa417d88a5ff8626dad9ebe0c8c59776491478ab1f72aedfacd75b984931f", - "sources": "7b36e1080bbb2c4dbc7ce009393c568e3d968328f0e5891beb1e45ebd894337a" - }, - "version": "1.55.0" - }, - "io.opentelemetry:opentelemetry-exporter-sender-okhttp": { - "shasums": { - "jar": "e9cd97f59b18a89772ececbebccd773740eec2cd3ff67a4542eff73738acd60f", - "sources": "55f2f24814971e7b476db3713ec82f29285b679fbcaa434c481863f503e2a6e2" - }, - "version": "1.55.0" - }, - "io.opentelemetry:opentelemetry-extension-trace-propagators": { - "shasums": { - "jar": "27861a2b49b3acf3166f489426808032c3addd9c082999f74a110eb7ac6985ce", - "sources": "784afdd2a2a6fca26f8bf237b8aae7f6bfcb44c65d141901a110b4ff769bee0c" - }, - "version": "1.55.0" - }, - "io.opentelemetry:opentelemetry-sdk": { - "shasums": { - "jar": "d63231ea6fd33e0457c776a9aa8ae7ba778379b03119228ec56a5c8c16f9480e", - "sources": "3685819f7d9efb6761d35ecf5b6053dfc1d0161835da744b0fdb2c4d89c87a42" - }, - "version": "1.55.0" - }, - "io.opentelemetry:opentelemetry-sdk-common": { - "shasums": { - "jar": "e28bb83d0ae5a760ba95952daf820180ee7defb0c5783c9d21f9c00ada80020e", - "sources": "cb9423298f9c42ac2c568af5271d335e468d7730b21d7ca6c246c16c6eca25f7" - }, - "version": "1.55.0" - }, - "io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi": { - "shasums": { - "jar": "3ee1f647238bb77df7b7bde47bc87a35a7807b3c5bb389ca81b0ba16c77824ff", - "sources": "71760407f00ba82b762335ff2c3470daf3d5ff1c6a798eb9ae52a24c7772f418" - }, - "version": "1.55.0" - }, - "io.opentelemetry:opentelemetry-sdk-logs": { - "shasums": { - "jar": "d917bb833899057c7cbdbcc30290e816071b90e52c965693aaad4cc1b32ecc11", - "sources": "edb0008c29edf69671865945a1c47d1944c1f498ef7e895f7b21b916fea2f14c" - }, - "version": "1.55.0" - }, - "io.opentelemetry:opentelemetry-sdk-metrics": { - "shasums": { - "jar": "6219d69c3abdd6113bee35df94826f48e84b742041f5124b5857a2b801f74573", - "sources": "5f9c8dab78339e402caa7f7aa4616b6b5c8e2d50201335c73e23bd21aba147fd" - }, - "version": "1.55.0" - }, - "io.opentelemetry:opentelemetry-sdk-testing": { - "shasums": { - "jar": "9e257ac45834e5d184abdc238b5ee146a74a259d940c57722999ef400cdc2232", - "sources": "b40c580007e26d721d406e0b85385e87f6e2e8c36bea55adfd8837d77f57ccee" - }, - "version": "1.55.0" - }, - "io.opentelemetry:opentelemetry-sdk-trace": { - "shasums": { - "jar": "e593660b9fad8bfdb5e981ccd392aa030f788d577c55f8bac3b6c4c6dae509bb", - "sources": "2f374e9b5f2e7e33157bd6fc97eb5c629d0dac0f22a975075b52714916dfc6c5" - }, - "version": "1.55.0" - }, - "io.perfmark:perfmark-api": { - "shasums": { - "jar": "b7d23e93a34537ce332708269a0d1404788a5b5e1949e82f5535fce51b3ea95b", - "sources": "7379e0fef0c32d69f3ebae8f271f426fc808613f1cfbc29e680757f348ba8aa4" - }, - "version": "0.26.0" - }, - "io.projectreactor.netty:reactor-netty-core": { - "shasums": { - "jar": "b8aaddd6025af42c2d810a76dc5b9a7717f0fde84beb93d6d4a778dac25fc287", - "sources": "061136ccc1bc3bed6938cea77a7343dc47de275aad4851b3407fb7ac15854121" - }, - "version": "1.3.6" - }, - "io.projectreactor.netty:reactor-netty-http": { - "shasums": { - "jar": "0ffdcaafe718327ca4687dd41c21318a267e93cea7b43f42db6f3fb3175256a5", - "sources": "712c12723e57d68e909ce9221cb12e04be105435ca518d13f63075af81cbaa44" - }, - "version": "1.3.6" - }, - "io.projectreactor:reactor-core": { - "shasums": { - "jar": "ffc646b225465efce55d3ea350f1bcd1d27d4a56e912323e316dd8e6d04bff11", - "sources": "d6180835f642a1f6d8b330fac98876488994187a89c3df48b369f37344ea6845" - }, - "version": "3.8.6" - }, - "io.projectreactor:reactor-test": { - "shasums": { - "jar": "27acda356a59c19bc3db033f1ed4cff9a6469da6caf424a4004ffaabbfe24d2a", - "sources": "882b7654b056b77f721a03a804e4830030f072a2f4afb92638d6925568d6d930" - }, - "version": "3.8.6" - }, - "io.prometheus:prometheus-metrics-config": { - "shasums": { - "jar": "3da2d5f0123af9e313bcf26f04c1248afeacd1b0d5c3a35f220034604ac0ec47", - "sources": "b926a8a6802d8f1ea9800f9e88cb4b2ff8511b6fb63786ad51d778a5f22bd059" - }, - "version": "1.4.3" - }, - "io.prometheus:prometheus-metrics-core": { - "shasums": { - "jar": "7ecd546d5238e3d3f5f312f580eaaab10cb05d147597978ab90b78080cc58255", - "sources": "48721aa5dd183e912fe82f2c19ebd980a11ed56c9a8296d23fd4011051ec8d96" - }, - "version": "1.4.3" - }, - "io.prometheus:prometheus-metrics-exposition-formats": { - "shasums": { - "jar": "502ad6b37c44b1a6311f6070a18fc921ffa2e26abb43eaaaf7626aa1b97984b6", - "sources": "4bc087c844d7dd22799e5466bcd47c7e0feda0a6fbc084c26aaa843af5cee6e9" - }, - "version": "1.4.3" - }, - "io.prometheus:prometheus-metrics-exposition-textformats": { - "shasums": { - "jar": "4aeee30d937ae5baf34ca9daced0f84400ec0f034e7beaa8331d9c519d84e3d7", - "sources": "a4b5c7b615f221b4fd6dc46a877c9c5b5151a86f03789c21f2d708407d1a9bc3" - }, - "version": "1.4.3" - }, - "io.prometheus:prometheus-metrics-model": { - "shasums": { - "jar": "bc3f1825014a14006626086ea779b62893e647e71d1eab075c0bb65057c245f8", - "sources": "61abe1dd37b1f8caea95ba193e5d85dc4b37861017731524ca155bfb57936cfe" - }, - "version": "1.4.3" - }, - "io.prometheus:prometheus-metrics-tracer-common": { - "shasums": { - "jar": "b816aaf84e45d591e5f66c5b94c7a789dedf2d705e5bf3eec2ae8730f76c68cd", - "sources": "797e6e276ccf7d874248b4d779b705ce0a400fe02b54443a04758b393de3f66e" - }, - "version": "1.4.3" - }, - "io.swagger.core.v3:swagger-annotations-jakarta": { - "shasums": { - "jar": "9b30b319f1c31993e6128d22e12652be9a688589e30c67819ed84e95b96e7f88", - "sources": "b9324b72ab6c498fad2d766f5074b1b24be0cf2c1e55f6c937b4b8345ca90bf9" - }, - "version": "2.2.47" - }, - "io.swagger.core.v3:swagger-core-jakarta": { - "shasums": { - "jar": "e63b78c1e5b049e6670ca9bb43c3f35cf362ecc08ac59a783994a6a732a7d7eb", - "sources": "55b6e465caf14b019ebe4ab9d886915afd1a4796c6c790ffdd4789b36997f556" - }, - "version": "2.2.47" - }, - "io.swagger.core.v3:swagger-models-jakarta": { - "shasums": { - "jar": "15d10f4f7eac1e02a8ff940b430c634fc9dfe08368a54dffa3216cc2dc811aa2", - "sources": "4770b07fcb362a2c1b289fd255d5bf9ec11619bc0cbfcfc07e49599f24fef753" - }, - "version": "2.2.47" - }, - "io.swagger:swagger-annotations": { - "shasums": { - "jar": "c832295d639aa54139404b7406fb2f8fbf1da8c57219df3395de475503464297", - "sources": "7b2de9dc92520bd12e30987ee491191131e719d30e3bbe8a536f18e80ca14df3" - }, - "version": "1.6.16" - }, - "jakarta.activation:jakarta.activation-api": { - "shasums": { - "jar": "c9db52100ce6c8aac95cc39075f95720d2e561b11f8051b81c121ad4effd7004", - "sources": "2aa5a3ba55059b778a3b467269404d7ac3b9485ed4a23ad26d2e63aa769ec35f" - }, - "version": "2.1.4" - }, - "jakarta.annotation:jakarta.annotation-api": { - "shasums": { - "jar": "b01f55552284cfb149411e64eabca75e942d26d2e1786b32914250e4330afaa2", - "sources": "142dfd2343429df2aac3e1cfacfacc21c8393112c0e0280d3628648d9b612470" - }, - "version": "3.0.0" - }, - "jakarta.servlet:jakarta.servlet-api": { - "shasums": { - "jar": "8a31f465f3593bf2351531a5c952014eb839da96a605b5825b93dd54714c48c4", - "sources": "6eb958543e0548bb93d2519e40224d13c8003b10cc615b5652bfd9899350bfb4" - }, - "version": "6.1.0" - }, - "jakarta.validation:jakarta.validation-api": { - "shasums": { - "jar": "63ce00156388c365f3ac1be71fcfaf114682fc0c452020b5df6e7ec236e142ab", - "sources": "941cc2028fe8f5e6b912954bca360ed347ace453aca4f8e2fd58dc3845a0c792" - }, - "version": "3.1.1" - }, - "jakarta.xml.bind:jakarta.xml.bind-api": { - "shasums": { - "jar": "5e489b6c874c4119e003ff1403db523ee3a8959ec499f3de29e77245efccf216", - "sources": "5bcf811e6719582ab2be21c84bc48f963ba377dfe1dae5ecb2673c1efa00e422" - }, - "version": "4.0.5" - }, - "javax.annotation:javax.annotation-api": { - "shasums": { - "jar": "e04ba5195bcd555dc95650f7cc614d151e4bcd52d29a10b8aa2197f3ab89ab9b", - "sources": "128971e52e0d84a66e3b6e049dab8ad7b2c58b7e1ad37fa2debd3d40c2947b95" - }, - "version": "1.3.2" - }, - "net.bytebuddy:byte-buddy": { - "shasums": { - "jar": "2b5ddc8c1f4234bdb7cb45338a8e10a13e0e3ca473e91d5d821d681127ea8ba1", - "sources": "5211140f46c380a5e9630a86b2c07b396a9c374128fa603ca1d321b3c7da7449" - }, - "version": "1.17.8" - }, - "net.bytebuddy:byte-buddy-agent": { - "shasums": { - "jar": "5b17113e66e77ca6f8af07ff367c216df964a980f0e9f11e3b1aa793253aa64f", - "sources": "a205437d772e3edaf4a7a1a709e9d59c666e8a05218d0e000deb5651c52de2d2" - }, - "version": "1.17.8" - }, - "net.devh:grpc-common-spring-boot": { - "shasums": { - "jar": "951fd28aa9dce0cfc5be8ff9eba6d7dc616b2998e920a7b6acc05e11f4064f94", - "sources": "157991de7c495e40c1b18f8ef274e5ff1e2c0393b75642e7308457b866b3096a" - }, - "version": "3.1.0.RELEASE" - }, - "net.devh:grpc-server-spring-boot-starter": { - "shasums": { - "jar": "289b7b45fe511d14f54801745ac3de7602bf7d7eef0fb75890bef7fbedb94ec4", - "sources": "e0ddd0872ffbbc48c322ba617035bafd0f5bc656e91eec0bda876d3f07d9f3f1" - }, - "version": "3.1.0.RELEASE" - }, - "net.java.dev.jna:jna": { - "shasums": { - "jar": "260c4b1e22b1db9e110ee441c4f13ce115f841fa48c41d78750986214b395557", - "sources": "0b9224e215b3c6a464959e3f994ddd64c14d46fb4014facd6afa1cc18e469466" - }, - "version": "5.18.1" - }, - "net.javacrumbs.shedlock:shedlock-core": { - "shasums": { - "jar": "b2ca6f358b5dcbadc641a7c5ef6217b8c5f91bc2b49e89d715fdd5443cc48166", - "sources": "81a2914ff05c94d86b54d78fa59f79216df1db8e980d5d5a910559f6da3bb9e1" - }, - "version": "7.7.0" - }, - "net.javacrumbs.shedlock:shedlock-provider-cassandra": { - "shasums": { - "jar": "e8a5db022350461384618f4ebaf978dbc2894becb208d7c053ae0125dd31a7eb", - "sources": "2e6e6fdcbc77faffaa22b16850ae4b50f7693439b59fc146c0ec9f510c012eb5" - }, - "version": "7.7.0" - }, - "net.javacrumbs.shedlock:shedlock-spring": { - "shasums": { - "jar": "a71fa9d539b10140b5aaea5a4a0e58f219b396195b6bc7148c8adf65425cbce1", - "sources": "bb61469b2f50396b4ab6ccb2a30ecb3d394ca0d0c986f43086de2beaafeac67e" - }, - "version": "7.7.0" - }, - "net.minidev:accessors-smart": { - "shasums": { - "jar": "222c9f547bb20a99fc486403a398352d1306fb671b38abd7ecab6401df170e61", - "sources": "10880e44ed732de27ae424a9698a041c398102098b5b1bae3cc597ec62dac43e" - }, - "version": "2.6.0" - }, - "net.minidev:json-smart": { - "shasums": { - "jar": "1ae4b561458afb540be8ec5c6dbb4f2e715a319a7ae64854998aaf924770d61b", - "sources": "a4af3f3773286fe3f76f94d38d977611fd2493685f589466b76dd25cf70b400c" - }, - "version": "2.6.0" - }, - "org.apache.cassandra:java-driver-core": { - "shasums": { - "jar": "6276a8e25c8821eeaa5d2d67c50b81615d551dd7ec943302689996f6bdb2add1", - "sources": "80a95f2d4d61091a8f54bf76f2d26269ee7b8ac82e261314108d7ad83c083838" - }, - "version": "4.19.3" - }, - "org.apache.cassandra:java-driver-guava-shaded": { - "shasums": { - "jar": "fa5e6dfb61a987e69cd8559464145b6ceb6610d28760b0d8cff17eba052c8264", - "sources": "9415d1dd6132671cefc43eb5ac560f34d5e4a1b73ac25310fbfc4584a8033ec3" - }, - "version": "4.19.3" - }, - "org.apache.cassandra:java-driver-metrics-micrometer": { - "shasums": { - "jar": "4f61ed8dabc978f7c9bfdae578915480b6242468feea1c73571be7d832ee3d0a", - "sources": "6214d824dc8e72fd6221165b1497f4c46099027b7ad220ce17f44a8f3f58807f" - }, - "version": "4.19.3" - }, - "org.apache.cassandra:java-driver-query-builder": { - "shasums": { - "jar": "b6e4c84dff2448aaa67f5e3e867b1bf284ca6ad0c15701a4d4d7283384d8df12", - "sources": "dd63fa1af436d1b01155fdca72563338007e265fd8c05c3a8b2e80e76b2d4aa8" - }, - "version": "4.19.3" - }, - "org.apache.commons:commons-collections4": { - "shasums": { - "jar": "00f93263c267be201b8ae521b44a7137271b16688435340bf629db1bac0a5845", - "sources": "75f1bef9447cce189743f7d52f63a669bd796ae19ca863e1f22db1d5b6b504a6" - }, - "version": "4.5.0" - }, - "org.apache.commons:commons-compress": { - "shasums": { - "jar": "e1522945218456f3649a39bc4afd70ce4bd466221519dba7d378f2141a4642ca", - "sources": "6de9de4559f12bba6d41789c72f6a2a424514f2d2a3f7f49e2a3c52414db9632" - }, - "version": "1.28.0" - }, - "org.apache.commons:commons-lang3": { - "shasums": { - "jar": "69e5c9fa35da7a51a5fd2099dfe56a2d8d32cf233e2f6d770e796146440263f4", - "sources": "eec245e820ec2800a1780cf756aefb427c1c6170e06902e67ac15b6910ce6335" - }, - "version": "3.20.0" - }, - "org.apache.logging.log4j:log4j-api": { - "shasums": { - "jar": "c4b642a7f047275215de117e0e3847eb2c7711d84a0aa7433e7b3c096daf341d", - "sources": "b86680bcf8ffa25897b6114cae508bb8e6ecac8081a0fc8985e0c00e27d4f4ec" - }, - "version": "2.25.4" - }, - "org.apache.logging.log4j:log4j-to-slf4j": { - "shasums": { - "jar": "d7b78fc0aaaa5e8ada388b29d718b0ab187e512965bed0b259bb4ab299f13db2", - "sources": "ca9159da173bf88fb621adf745fe1d313ba4074f4c66576ae70f5dd99eab89c9" - }, - "version": "2.25.4" - }, - "org.apache.tomcat.embed:tomcat-embed-core": { - "shasums": { - "jar": "78cd7cd7c104b6b87142c1b0bd902e1ce005b0245c3cefa8a06759148947200b", - "sources": "0bfbdc27e60d4db5b83e0f51193bae5f4bd02ac270fd78b06945e219fc473359" - }, - "version": "11.0.22" - }, - "org.apache.tomcat.embed:tomcat-embed-el": { - "shasums": { - "jar": "1b34c33b858c141df36c501b4d809e68036c406bca3671a86facae297917c7de", - "sources": "da3724004575f5c8fa7e45649f2900ec53e7ecfb502b6ce227ca9cf86b36a156" - }, - "version": "11.0.22" - }, - "org.apache.tomcat.embed:tomcat-embed-websocket": { - "shasums": { - "jar": "210e0c7ab194a76cc7283df0be365276091b042369dae125fb477828ba67e922", - "sources": "711f09af528ac5af172c664244bcba4748eac00811ef7c6b52ddd6836b5a4a28" - }, - "version": "11.0.22" - }, - "org.apiguardian:apiguardian-api": { - "shasums": { - "jar": "b509448ac506d607319f182537f0b35d71007582ec741832a1f111e5b5b70b38", - "sources": "277a7a4315412817beb6655b324dc7276621e95ebff00b8bf65e17a27b685e2d" - }, - "version": "1.1.2" - }, - "org.aspectj:aspectjweaver": { - "shasums": { - "jar": "4fe86fdc18faea571f29129c70eaad5d121363504a06d7907be88f6c60ba3116", - "sources": "06fbde6ef3a83791e70965432b5f1891e493e21cdbc37307c54575ee86752595" - }, - "version": "1.9.25.1" - }, - "org.assertj:assertj-core": { - "shasums": { - "jar": "c4a445426c3c2861666863b842cc4ec7bbb1c4226fefd370b6d2fe83d6c4ff0f", - "sources": "5ba6de05730cf76021001f8437f35db4cb5b513465d4ace8c3a6fcd68d9a19ee" - }, - "version": "3.27.7" - }, - "org.awaitility:awaitility": { - "shasums": { - "jar": "ee58568ea5945dcf988551501655183dc184e23e45a8e013fdfd9036194e6f7b", - "sources": "92d209bd0135b04ca6bb7689c6b921819896ec2d517a5357760f598faafee46c" - }, - "version": "4.3.0" - }, - "org.bitbucket.b_c:jose4j": { - "shasums": { - "jar": "7314af50cde9c99e8eaf43eee617a23edcc6bb43036221064355094999d837ef", - "sources": "958be1837b507d3a1f1187257072b4c1e1d031c3a0c610d3c02ac69aabfac6a5" - }, - "version": "0.9.6" - }, - "org.bouncycastle:bcpkix-jdk18on": { - "shasums": { - "jar": "4f4ba6a92617ea19dc183f0fa5db492eee426fdde2a0a2d6c94777ffd1af6413", - "sources": "601ec2beb4749f0be65e296811b6e63de567f90d124f26887875bb722fd87e71" - }, - "version": "1.80" - }, - "org.bouncycastle:bcprov-jdk18on": { - "shasums": { - "jar": "64d6c5a6121fcd927152dd182cbed39afe0fda641a970d9bcc0c9cb1858b2731", - "sources": "e5f04550f7740e588edcbd1654c59277cd7ee8725d8b674e44f7f8f4b9c5674a" - }, - "version": "1.84" - }, - "org.bouncycastle:bcprov-lts8on": { - "shasums": { - "jar": "492049b928f8baab535af0185bbab8734d14e1c7648ae2a2037d58486cafb676", - "sources": "d4447a4f412b328f3e43595ab99603dd38b08ee1db9f1ea341e6158eeb86a70d" - }, - "version": "2.73.8" - }, - "org.bouncycastle:bcutil-jdk18on": { - "shasums": { - "jar": "bc78d32d7ffb141ee27e4fb77df04259d842c899e7e8eaf912f990d7253bd3b4", - "sources": "f1e43055e8287cde556a7741bf16b7fd7896b8f572ab91e0cadb337e710b015f" - }, - "version": "1.80.2" - }, - "org.codehaus.mojo:animal-sniffer-annotations": { - "shasums": { - "jar": "9ffe526bf43a6348e9d8b33b9cd6f580a7f5eed0cf055913007eda263de974d0", - "sources": "4878fcc6808dbc88085a4622db670e703867754bc4bc40312c52bf3a3510d019" - }, - "version": "1.23" - }, - "org.hamcrest:hamcrest": { - "shasums": { - "jar": "5d66b6a4a680755cb6ed7cb104fa7835ef644667586ff0737adeb977c39ecdbc", - "sources": "7a4050b1898f7e1aa395cf2be78fb6683f9e2766fcb8e1507926b204fa24d1bf" - }, - "version": "3.0" - }, - "org.hdrhistogram:HdrHistogram": { - "shasums": { - "jar": "22d1d4316c4ec13a68b559e98c8256d69071593731da96136640f864fa14fad8", - "sources": "d3933c83a764994930f4477d4199539eaf413b42e32127ec2b68c61d711ac1a9" - }, - "version": "2.2.2" - }, - "org.hibernate.validator:hibernate-validator": { - "shasums": { - "jar": "25f40118fa4c50f8522d090d25d52d5a38953b0ccd1250835f052e7bd3164ce0", - "sources": "db6a3d49eceaae0a880de8749cd7f7e8928c18458b44fac84633c3ee8db7ac0d" - }, - "version": "9.0.1.Final" - }, - "org.jacoco:org.jacoco.agent": { - "shasums": { - "runtime": "3fb76eea65f81bd9415202bab34b6571728841dff1ab8e6bbe81adc2e299face", - "sources": "8a643b749deb255d7a42c445c3053c9ec263e27103becdaaf88cedda44357255" - }, - "version": "0.8.14" - }, - "org.jacoco:org.jacoco.cli": { - "shasums": { - "jar": "12d5d78351c638efeea71ac840f6a5cf7bcff89001ddb05eb89f956d1079a2c6", - "sources": "52f715f15b890960f70f4ae8fbdd4bca70eba59c0283b37af2d79ad9215d2e37" - }, - "version": "0.8.14" - }, - "org.jacoco:org.jacoco.core": { - "shasums": { - "jar": "28abbf0eea5a08e4f24097f2fbac663ca17c341c25c3a04d90d6cd325943c995", - "sources": "1550fd5081ecd2c2ad053994c23d91a4cef6dcbed4c4dac95130e7d75fa9cd3c" - }, - "version": "0.8.14" - }, - "org.jacoco:org.jacoco.report": { - "shasums": { - "jar": "a3e2026060ab8b8d5c650706406234bb4c033dfd5376afeb8b1666e8ed27c453", - "sources": "80ac2fac212d6a4583b7f025dc7b602f384a9dfcdbccd0e9cb78c415e9f5ffc6" - }, - "version": "0.8.14" - }, - "org.jboss.logging:jboss-logging": { - "shasums": { - "jar": "7c12ee575508f81e22b1db9334b969d0ec54ef0fd1dcba24eeab1a44235fc366", - "sources": "e8a2b9aaac82b0082aa040e6bdf6cd7f225cdbc75d2bd1a79fa7b17007ec1b15" - }, - "version": "3.6.3.Final" - }, - "org.jetbrains.kotlin:kotlin-stdlib": { - "shasums": { - "jar": "6558a3d233da56a20934b32159f9db5f86ed5816ef098f78a2c223dc6abb79dd", - "sources": "664f515359444a92267a13266101431a630f99d6b8d04407a92b1a0e558d33ee" - }, - "version": "2.2.21" - }, - "org.jetbrains.kotlin:kotlin-stdlib-jdk7": { - "shasums": { - "jar": "b785922f11e6d91a6dd1d75cb0aef1ce37b83f8de0e3a2139139dfb823bb8a2c", - "sources": "2534c8908432e06de73177509903d405b55f423dd4c2f747e16b92a2162611e6" - }, - "version": "2.2.21" - }, - "org.jetbrains.kotlin:kotlin-stdlib-jdk8": { - "shasums": { - "jar": "c62275c50ee591ca2f82c7ba42696b791600c25844f47e84bd9460302a0d5238", - "sources": "3cb6895054a0985bba591c165503fe4dd63a215af53263b67a071ccdc242bf6e" - }, - "version": "2.2.21" - }, - "org.jetbrains:annotations": { - "shasums": { - "jar": "195fb0da046d55bb042e91543484cf1da68b02bb7afbfe031f229e45ac84b3f2", - "sources": "b2c0d02e0a32c56d359e99634e7d769f9b1a8cd6e25061995abad1c1baf86f56" - }, - "version": "17.0.0" - }, - "org.jspecify:jspecify": { - "shasums": { - "jar": "1fad6e6be7557781e4d33729d49ae1cdc8fdda6fe477bb0cc68ce351eafdfbab", - "sources": "adf0898191d55937fb3192ba971826f4f294292c4a960740f3c27310e7b70296" - }, - "version": "1.0.0" - }, - "org.junit.jupiter:junit-jupiter": { - "shasums": { - "jar": "784b65815f479a0c99a9d3a573b142e2a525efb6025d97f751b19e72f90aeda3", - "sources": "402f86a4fdce930bb68b592f2ed5a9d57dc4d1b2747aa2d66c0b3cb7a2adceeb" - }, - "version": "6.0.3" - }, - "org.junit.jupiter:junit-jupiter-api": { - "shasums": { - "jar": "d655d7e6f0c7ae07f10a2f3bbaaebb6d30e9b26204a068ad9e9b3950aa28792c", - "sources": "8266d8da51d0c7d6a2ed4895a3cb76e0ec22194907f24364f2a4f3efd05f00a5" - }, - "version": "6.0.3" - }, - "org.junit.jupiter:junit-jupiter-engine": { - "shasums": { - "jar": "1e2fab61ad27ea08fc7c70dd9677cf8c6d1ae5434d42dcfdd633b12c7e7c04d0", - "sources": "35706a9edf1b580bf22d6eca9d6a9165f478f75b0108840ad6f31481cd662d6c" - }, - "version": "6.0.3" - }, - "org.junit.jupiter:junit-jupiter-params": { - "shasums": { - "jar": "cf2947e2302b9f8c8a059259a277881c1cadae8fbc2514c16a925cfeb7beb2e5", - "sources": "f0dcf217100b06b98cd36c2e74fb919c74e3024faad868bac9eba6ff00c7c263" - }, - "version": "6.0.3" - }, - "org.junit.platform:junit-platform-commons": { - "shasums": { - "jar": "39f262d09c3d52719fe0b77f080e90a3695e285d779a41b232e17963ae5da200", - "sources": "06cbe4a4bbd79339c3817983510cf3adc3d6a88a8a556c80c5b84eeb1ebd13dc" - }, - "version": "6.0.3" - }, - "org.junit.platform:junit-platform-console-standalone": { - "shasums": { - "jar": "3ba0d6150af79214a1411f9ea2fbef864eef68b68c89a17f672c0b89bff9d3a2", - "sources": "c4e79459727c6fe6afbddcc04daa67767fb73d7044d29846dd4ab90de1d0fa0c" - }, - "version": "6.0.3" - }, - "org.junit.platform:junit-platform-engine": { - "shasums": { - "jar": "491e9e4f745f161b8a8e4186a1a7c6a450ea12c70930c9aedae427215301d947", - "sources": "89a893566a97557dbbcb0706d9b5565c4e7a402050841753dc527f3e9139c9ac" - }, - "version": "6.0.3" - }, - "org.latencyutils:LatencyUtils": { - "shasums": { - "jar": "a32a9ffa06b2f4e01c5360f8f9df7bc5d9454a5d373cd8f361347fa5a57165ec", - "sources": "717e271b5d67c190afba092795d79bba496434256aca7151cf6a02f83564e724" - }, - "version": "2.0.3" - }, - "org.mockito:mockito-core": { - "shasums": { - "jar": "d1a96d252128d3a4247cfd8a2e76412efa3cc103977be17933c942117a24f374", - "sources": "dcde489c1db6449c162f05105ace4c172850d3dc7f6633bb4f54d47a16a0fd1b" - }, - "version": "5.20.0" - }, - "org.mockito:mockito-junit-jupiter": { - "shasums": { - "jar": "fd6c703c2b00b914f3adbc27b18077a708f3d6992f19242c444e737c6cce024e", - "sources": "3c199479a2319db4395fd9fd209946ecc4530f48fe5cdeed7677c285bf70fbb5" - }, - "version": "5.20.0" - }, - "org.objenesis:objenesis": { - "shasums": { - "jar": "02dfd0b0439a5591e35b708ed2f5474eb0948f53abf74637e959b8e4ef69bfeb", - "sources": "d06164f8ca002c8ef193cef2d682822014dd330505616af93a3fb64226fc131d" - }, - "version": "3.3" - }, - "org.opentest4j:opentest4j": { - "shasums": { - "jar": "48e2df636cab6563ced64dcdff8abb2355627cb236ef0bf37598682ddf742f1b", - "sources": "724a24e3a68267d5ebac9411389a15638a71e50c62448ffa58f59c34d5c1ebb2" - }, - "version": "1.3.0" - }, - "org.ow2.asm:asm": { - "shasums": { - "jar": "03d99a74ad1ee5c71334ef67437f4ef4fe3488caa7c96d8645abc73c8e2017d4", - "sources": "e37000a2a0bc9f0bef373714ad7dde4082212351847b74618d483057a4ae186c" - }, - "version": "9.9" - }, - "org.ow2.asm:asm-analysis": { - "shasums": { - "jar": "6a15d28e8bd29ba4fd5bca4baf9b50e8fba2d7b51fbf78cfa0c875a7214c678b", - "sources": "ff731d401ea2407759ea19b4b025800d32495a51a912f2553d987cddda424773" - }, - "version": "9.9" - }, - "org.ow2.asm:asm-commons": { - "shasums": { - "jar": "db2f6f26150bbe7c126606b4a1151836bcc22a1e05a423b3585698bece995ff8", - "sources": "218bbb648e24578a385cb6b6a21ceff222a2a8f8b2d5f6a256a8099dd336dc76" - }, - "version": "9.9" - }, - "org.ow2.asm:asm-tree": { - "shasums": { - "jar": "42178f3775c9c63f9e5e1446747d29b4eca4d91bd6e75e5c43cfa372a47d38c6", - "sources": "9d1fe261fa1d29904ca9dbc76878396e76bc225191676a8c16ad2669a205321a" - }, - "version": "9.9" - }, - "org.ow2.asm:asm-util": { - "shasums": { - "jar": "3842e13cfe324ee9ab7cdc4914be9943541ead397c17e26daf0b8a755bede717", - "sources": "e518a00b1d004832e72c6448351c4865971ac95a7cfe78fb0315d76acb393a46" - }, - "version": "9.9" - }, - "org.projectlombok:lombok": { - "shasums": { - "jar": "01f7b1a015e33e2b62d5f5f37053306357ab1415fd181fcba7794f5d198c1126", - "sources": "5b78c305a65fbe257d57878bff6530e2b79e1a2cd660f45dcb7d7f8f5e56a483" - }, - "version": "1.18.46" - }, - "org.reactivestreams:reactive-streams": { - "shasums": { - "jar": "f75ca597789b3dac58f61857b9ac2e1034a68fa672db35055a8fb4509e325f28", - "sources": "5a7a36ae9536698c434ebe119feb374d721210fee68eb821a37ef3859b64b708" - }, - "version": "1.0.4" - }, - "org.rnorth.duct-tape:duct-tape": { - "shasums": { - "jar": "31cef12ddec979d1f86d7cf708c41a17da523d05c685fd6642e9d0b2addb7240", - "sources": "b385fd2c2b435c313b3f02988d351503230c9631bfb432261cbd8ce9765d2a26" - }, - "version": "1.0.8" - }, - "org.skyscreamer:jsonassert": { - "shasums": { - "jar": "719095c07d4203961320da593441d8b3b643c18eb1d81aa98ea933bb7eb351ba", - "sources": "a825c29f8cc40f85ea4e7a431a55d4278a785c34acdeef4cd1be7367f70ea6bb" - }, - "version": "1.5.3" - }, - "org.slf4j:jul-to-slf4j": { - "shasums": { - "jar": "cbb7d1aaaa9e871eb1a06594abd911bf97027152976edf1edc315be75239204e", - "sources": "b6dd2138f3e83d876bf07206d09f2b48ca655bc36a8e80b0c2a32ad19ab8f1d5" - }, - "version": "2.0.18" - }, - "org.slf4j:slf4j-api": { - "shasums": { - "jar": "44508fd1576500688c790b190acdd16fec4f8c79a3e0b900afd70503cf055f55", - "sources": "192e007cf7f2be41d40574e44521fc0b7ce55e01f13dbe0fa8707c8ae3329075" - }, - "version": "2.0.18" - }, - "org.springdoc:springdoc-openapi-starter-common": { - "shasums": { - "jar": "a0b5a6a5384b4a36718fd7a69efbd48311fd5f404c96ce286a6c285c5d0038e6", - "sources": "19a2612f56ea7d867c70cdae5e8fdf9d2b7a3cbdcba257c1d9ddfe88e48a74b0" - }, - "version": "3.0.3" - }, - "org.springdoc:springdoc-openapi-starter-webflux-api": { - "shasums": { - "jar": "a58f130aa60c47001e0d7b6b5e611edbbf187f58aa7d697dd720ac220f57b384", - "sources": "90968a39c963a144ee30248146dff38eb568edf57109ccddb843d6a92c1ef756" - }, - "version": "3.0.3" - }, - "org.springdoc:springdoc-openapi-starter-webmvc-api": { - "shasums": { - "jar": "c7e0221797240037eaf20c834f2d03fabec3f26051bd7052be8bf169f2c02876", - "sources": "e0fad37b01fefa5b52aec1cc09101017a397ae93f7ba8dace72ed29d1f2a3106" - }, - "version": "3.0.3" - }, - "org.springframework.boot:spring-boot": { - "shasums": { - "jar": "edb984d0bc80d209bed271e6d334fbfbfcf11cc4c1ef5059adc31c5bde7b1d7c", - "sources": "850ec7c91b0ff92c46797e0adcf1f47369d64a0cf4a8427d01b4834df129d0d4" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-actuator": { - "shasums": { - "jar": "edfedbcc5d33c8b0a8d0156dcc8cbf6234a33dc861001c7ec8ef63af19197b7e", - "sources": "d74a19a07e1eaf70bfe00b33332c3d61d82621e887b1a8af3b4dbb05051ca197" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-actuator-autoconfigure": { - "shasums": { - "jar": "59b188a313fda88bbe6cba613dd13aa00d1cc49135b11120ae5d451f72d49c00", - "sources": "c4aa275f1a4c97020d56d96cdb5f1b9a0b8157da06b62313c55e2d861e683c59" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-autoconfigure": { - "shasums": { - "jar": "1e8a953294fe76727965970de31e3bb08fba2b65e3ca0ee9b8bca492d0818d10", - "sources": "477e9834d7982b080b485c7baeb27ea399fca324d0442dc2f694a473b6a394fd" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-cassandra": { - "shasums": { - "jar": "8a69a41383b36eed9b58b462c698cf7ec825ea0ac3b131ce7c2f92419dbc3bc7", - "sources": "e580260c129670d80a96c84c2241d5cbad3d9f9a183d3af201b2b5acab96e3cd" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-data-cassandra": { - "shasums": { - "jar": "f17d6ed4fe4825abb68ec4743a3248d9e456c94e099e2653c392ee75cef4b8a6", - "sources": "d2fcf562626d79bc13f71284c2a9b820975ce0bd35e9e9daeef8deb05fb14e53" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-data-cassandra-test": { - "shasums": { - "jar": "5ad17d2ffcd040eae3f425e7588e2b2604461b47ac7801c5ccfb5179e6725832", - "sources": "73ca527b7a6d67b0e8a20865d91f0bb15092ef3415c7ebefe475bc14894440da" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-data-commons": { - "shasums": { - "jar": "991f28c95c3b5687d41429ec1da258d6ebdf33c1778dab2057361df9983dc6c7", - "sources": "bbfa0f3571ee162c21597e7fc7a925a5919e1267ebb55eb5b3698c2832de9ec0" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-health": { - "shasums": { - "jar": "e1c81e0e8d89ba7d25a3522d52159a4bcfa9bf7ee4e0d53cef61244e75a244bb", - "sources": "0d664e89d03dffde004f79e9aa5a7482128d0358c284edb0b5c2895eb25a43b7" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-http-client": { - "shasums": { - "jar": "7881d09b33f278b39fd1018d0cb7d91b73b72406d2350351166511b1c3a76c6b", - "sources": "17ee08d609a1d4d1d64198b9cf0cf79920974400460022b4b97117d22b7ea73a" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-http-codec": { - "shasums": { - "jar": "dd3e79f5bf872e34eca182f3a6f050278263562da042a1a0bc338f5d70d4ab60", - "sources": "4f2231f549e7353f3095b58995520bcb073d4c155aadc839f3f66d1b6543059e" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-http-converter": { - "shasums": { - "jar": "9f620c36cb98103ef664a9fccad4173ae20120d1abc790b795130be4e02dbb90", - "sources": "9f4378bcb3caa6696d8fe340c519bd673287f2c046098607cbe079ba9aa98874" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-jackson": { - "shasums": { - "jar": "0cdbadd10bcc3b23d32dffd419caceda4a4ed6b3da0262617f543732e9105ece", - "sources": "efe6e9f38861e94fbf36045bb23d23076407d26fed5752efb852ad2accaea3bb" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-loader": { - "shasums": { - "jar": "bb1cd5fee23e03eec3fb5fdaff59c56d1db3829afe5f59381904764df76fb1a8", - "sources": "539b6b3e0fde31a126ee1bc885840874aae9275f28c8c7d4c30e1c15ed85b221" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-micrometer-metrics": { - "shasums": { - "jar": "1cd20b112104d244fdc96b44b3a8193e0916686a819a6be93127c1c7eefc1c9d", - "sources": "b61f894a893ef3f3e0b978e7430f08c6b3580c19ac963bbbf8901a28b2d18f6b" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-micrometer-metrics-test": { - "shasums": { - "jar": "124e88e2d8ef0331653bb9d2c849143e210e97d3ded4e8cbdb0bd68c05ea2e65", - "sources": "b17d0251cee5454db0d3e573a8c23d6b0055de534fa49b75c18bc0af6ea9f100" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-micrometer-observation": { - "shasums": { - "jar": "aced85ab6f7a2a8b15d8bd52c2b75dfe47c9890dc08d39e24b2e7b78f79b6ac2", - "sources": "8e159976cbcf123f3333793f47e88c71932ff6f2f785db8c69831bfbcf75bc3b" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-micrometer-tracing": { - "shasums": { - "jar": "dfb60c9422c80957a020e8751317bc3515f3ed56d5d92da685bfece6c0ba780a", - "sources": "c0d8f28ffbd343b00586195ee8fd34d2441562c67f01cc100578f62145e51846" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-micrometer-tracing-opentelemetry": { - "shasums": { - "jar": "3463de0849ee471c99726b8c9a334cde69a96c78c496aa452db9d9f34b53603e", - "sources": "01b024f9530bce7dabf3592a3f50fe8063c1f9f5ae6d982edf73ba85410b3cd6" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-netty": { - "shasums": { - "jar": "d5526be25b050ad5e4dd7a56095b78357bf73bbe447d900588fe7f895873ff3f", - "sources": "34b0173a82c5b35275a773b213b20591c4047b87e3f0b6dc9c1d0736b5084591" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-opentelemetry": { - "shasums": { - "jar": "42ce3e301fb94f6d15efbed5bae1c3ea9f8fe8da93afa1ac4aacf1819c1d2cd4", - "sources": "f07c50fd5e2dc2b27fbcf08f2d7ad1b8663b8611788b6bf1f4b66fe5c5dbee5b" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-persistence": { - "shasums": { - "jar": "201cd088c5fddbcff7ece343f42eee0cabbab64083d339f35e5eb4edbcdbd4bb", - "sources": "863fc339ae51cc5b5287cac067ff5527cdff2ec8da85358d8bf61fa9a460568c" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-reactor": { - "shasums": { - "jar": "abb8ac783f1a3e2de68f2ececfb22ef4ba47c74089ce377a1476f3ccf5c35539", - "sources": "0753ac2c9596f010acdac06e9bc69d3d5a35dd9abec4e44c1de600dbb7577c13" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-reactor-netty": { - "shasums": { - "jar": "5679a1518fece25f608b6abdb165bae59c4ba1aa76833700fb6cf35d528575a1", - "sources": "35281bbd1465a0a22c1f6a2188c64e2efc8535f2e30807687c77ec15197b58ca" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-restclient": { - "shasums": { - "jar": "4438e7cbe09fe2d1aa40da4112cbc2a7f0067046dbfd153e79122be6e143c82a", - "sources": "87f4a654821800a30f5d41ac5320877cd96cf436a60ac2dd541369b159a4eff2" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-resttestclient": { - "shasums": { - "jar": "976fada4921b1817e1ced3c0da93a709d85638b519a9e63c3075e76c1e3c0593", - "sources": "ad2de8d55af3be0eba0e59259eb6427fd83eca7fdd134454a0c9cde2cde4c9bc" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-security": { - "shasums": { - "jar": "fef4d4952d7c4f86112d4a27cb98cf1d71001373f9d8f88fbf0af9d908fdaa3c", - "sources": "edc45113d48d5b3f7e3ef6f722ffb905a2b0bd5791e79879b591cfe74972178e" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-security-oauth2-client": { - "shasums": { - "jar": "37a6474b11b65f39b444971572e66553512992f4434280365cedcb396b8afbec", - "sources": "dcf7f976f5e8216498d3415508598fa6e8da7248a9ae3056f94fc3abfb76c65f" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-security-oauth2-resource-server": { - "shasums": { - "jar": "d33c17f53bab6054589d94bbc36f8ed017fb0c1cd353c9b8a85359b72d4d25e8", - "sources": "2d598d95730fca23bc1ab8d08af3cad04c6cd69e5d4f728d7ce25f3f5e410953" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-security-test": { - "shasums": { - "jar": "7e34b14edd632dc3cd911931d3e3d74de40d863aa1a1849be4b217a293b14004", - "sources": "ad5a8312d621e12e659b198ded8b8c1b1a2066b34940443856e6302bd8e885b1" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-servlet": { - "shasums": { - "jar": "fb1af769617daa2808a82921d98ca94efde8cb20fcefc55e71b2e0bf93de1423", - "sources": "172a6736933d75bdeeee725078769e27d8142a826e811940c595aea815913512" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-starter": { - "shasums": { - "jar": "d70f5f300c9e7af18813799bffce38974398f6429c578c825822a32560c4b202", - "sources": "d70f5f300c9e7af18813799bffce38974398f6429c578c825822a32560c4b202" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-starter-actuator": { - "shasums": { - "jar": "576d445c6d0b7920f098822f45d74c2239f363d06508f8acf2a181f0b69c2cb9", - "sources": "576d445c6d0b7920f098822f45d74c2239f363d06508f8acf2a181f0b69c2cb9" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-starter-actuator-test": { - "shasums": { - "jar": "9f87aeefd9049094dd1fd64d96632bee353f871e0999c7c0531d69a2dcf7a945", - "sources": "9f87aeefd9049094dd1fd64d96632bee353f871e0999c7c0531d69a2dcf7a945" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-starter-aspectj": { - "shasums": { - "jar": "5521390213e6f2a0a3ef0d78eed35094868f840888823f9508e175dab10e7306", - "sources": "5521390213e6f2a0a3ef0d78eed35094868f840888823f9508e175dab10e7306" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-starter-data-cassandra": { - "shasums": { - "jar": "32abc561b414e781bc1998e1a6cd1167f3eff2247e6bb2b1b08a347bb3054acb", - "sources": "32abc561b414e781bc1998e1a6cd1167f3eff2247e6bb2b1b08a347bb3054acb" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-starter-data-cassandra-test": { - "shasums": { - "jar": "aacd60f7f5cab180a23dbd87fd5b53d524c2c89ce42635d5eaa4331075dec548", - "sources": "aacd60f7f5cab180a23dbd87fd5b53d524c2c89ce42635d5eaa4331075dec548" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-starter-jackson": { - "shasums": { - "jar": "bd042218bf291c4ee821d7ec3e86f7f747223d32cd87066aa5e3730a2dd5c3b6", - "sources": "bd042218bf291c4ee821d7ec3e86f7f747223d32cd87066aa5e3730a2dd5c3b6" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-starter-jackson-test": { - "shasums": { - "jar": "72ad611e32e370446bb2de890da4f084def1d354f4526522f0ae1182265b545a", - "sources": "72ad611e32e370446bb2de890da4f084def1d354f4526522f0ae1182265b545a" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-starter-logging": { - "shasums": { - "jar": "b5f1d01cd179ffc24b125a6ce971854b7b141c4e19e9c050a0b82d514983b1f6", - "sources": "b5f1d01cd179ffc24b125a6ce971854b7b141c4e19e9c050a0b82d514983b1f6" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-starter-micrometer-metrics": { - "shasums": { - "jar": "a5d302b2d6e9a8e1989455888aad2f69349f4c0b43b7ef41c8063c4bb92dec32", - "sources": "a5d302b2d6e9a8e1989455888aad2f69349f4c0b43b7ef41c8063c4bb92dec32" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-starter-micrometer-metrics-test": { - "shasums": { - "jar": "dd6d8969ce0e7736d29c5ce1dbdf9d9d89ac0c7ecbae41485abeb5b3efe87546", - "sources": "dd6d8969ce0e7736d29c5ce1dbdf9d9d89ac0c7ecbae41485abeb5b3efe87546" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-starter-reactor-netty": { - "shasums": { - "jar": "ceebf772bae1c9492fce1c766fdc18a7a17388f02f639a6ba20824b8a3dd848c", - "sources": "ceebf772bae1c9492fce1c766fdc18a7a17388f02f639a6ba20824b8a3dd848c" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-starter-security": { - "shasums": { - "jar": "04e806b5737be0d399c85d356b060599684df6fc4f56cc08b85a563ae1a066dd", - "sources": "04e806b5737be0d399c85d356b060599684df6fc4f56cc08b85a563ae1a066dd" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-starter-security-oauth2-client": { - "shasums": { - "jar": "1afd7f96736afc19451ad2a4f001e54af93d9d9d788802df9f4e536860560aca", - "sources": "1afd7f96736afc19451ad2a4f001e54af93d9d9d788802df9f4e536860560aca" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server": { - "shasums": { - "jar": "72dbb14dc0b21f43cee18ae6caa6bf7b0c4efe4bac11702e34529280865ecd83", - "sources": "72dbb14dc0b21f43cee18ae6caa6bf7b0c4efe4bac11702e34529280865ecd83" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server-test": { - "shasums": { - "jar": "8e13abf7c7754171c83c8236b796ef3d6e8d841a3ddafd84dfec0e5615b77e75", - "sources": "8e13abf7c7754171c83c8236b796ef3d6e8d841a3ddafd84dfec0e5615b77e75" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-starter-security-test": { - "shasums": { - "jar": "a7320624975022865468e255b8e0c414f76d380eef7793faeca87f98496998ad", - "sources": "a7320624975022865468e255b8e0c414f76d380eef7793faeca87f98496998ad" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-starter-test": { - "shasums": { - "jar": "e4844ae2375d569711af218763620993ea434b4836d3463cf26d9f6b6e589340", - "sources": "e4844ae2375d569711af218763620993ea434b4836d3463cf26d9f6b6e589340" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-starter-tomcat": { - "shasums": { - "jar": "f4a81ce616baa9c715be0dc0735210d770aa67301f92d3b11942f780056fc7ad", - "sources": "f4a81ce616baa9c715be0dc0735210d770aa67301f92d3b11942f780056fc7ad" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-starter-tomcat-runtime": { - "shasums": { - "jar": "8d0c7cbd6bd43d47e664a9127f70ceddab952828797f20e2b0b93848796d82f2", - "sources": "8d0c7cbd6bd43d47e664a9127f70ceddab952828797f20e2b0b93848796d82f2" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-starter-validation": { - "shasums": { - "jar": "bc449f60bb483374e7358afcda3fccb6e01906e158c7e1e00d9035277a6545b7", - "sources": "bc449f60bb483374e7358afcda3fccb6e01906e158c7e1e00d9035277a6545b7" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-starter-webflux": { - "shasums": { - "jar": "dd99ab79bd18c6358183b146c3eb35730652dd36d2225d5795405efa7137b1a0", - "sources": "dd99ab79bd18c6358183b146c3eb35730652dd36d2225d5795405efa7137b1a0" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-starter-webflux-test": { - "shasums": { - "jar": "78c866953b611065c85b8f069b18d330c1f2051db932fc3a3e8213b852b7f8eb", - "sources": "78c866953b611065c85b8f069b18d330c1f2051db932fc3a3e8213b852b7f8eb" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-starter-webmvc": { - "shasums": { - "jar": "b70e0d9e1bc667a3a9ad509f98a6e9ac443af8eab5143f8c77a38aec0a014a2c", - "sources": "b70e0d9e1bc667a3a9ad509f98a6e9ac443af8eab5143f8c77a38aec0a014a2c" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-starter-webmvc-test": { - "shasums": { - "jar": "d11fd7bbd613040f88ddba503c486970dd282abb92f12158bc9655ee533e9f31", - "sources": "d11fd7bbd613040f88ddba503c486970dd282abb92f12158bc9655ee533e9f31" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-test": { - "shasums": { - "jar": "8879b4a336972eb498ca6606266e6ecdae911964c0a480d3f4bf37a6c2455b33", - "sources": "4dc67a1a332d75fa3dcf517f4b6dc66ed146793307aa9d23c0ebb5f4b399850a" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-test-autoconfigure": { - "shasums": { - "jar": "99ca7ab8be0dde10fa6c03e1026969619e826fcc914b6bc0d09090e75ba17cb4", - "sources": "f94cf34c24539cc3752fae1a0bf182282086452e9c83cfae5241574f20951eb3" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-tomcat": { - "shasums": { - "jar": "ad7c6527319f5cac0b5638a28820847f64d21282147fb98daaaa1f515ee17323", - "sources": "2388d2eaeb9d413d3d7525983fe14030d3b48bc0cca1530c8c7e9dc73e05e8b5" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-validation": { - "shasums": { - "jar": "15161d6eda4589a24ea30d1fd466bfe3843861c3b55963d49a26bfc0bf2ebbb2", - "sources": "52beb1b2b90adb6cec5bf8523e534e56fed771a7f0fe3d42191a4d3b8a5d3873" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-web-server": { - "shasums": { - "jar": "26a13c73ee85e7a851b73eb2d683ed4d3b7a4ca581b608dfd627bd4551997cf2", - "sources": "41e1dddf6e1be5fc35c4849f51639c097e7a8eb9c6627a780791a1d9e430c311" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-webclient": { - "shasums": { - "jar": "119d82faa651b35964eab73ea3d962b1c7434792647cbf82c9dde44785749671", - "sources": "bf3dd5bf566482bc32c0c75548eb9c6a598b4d26c66677cfb84fca4cd21ccf81" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-webflux": { - "shasums": { - "jar": "7eca957fe0ad8ee60642d58e6a8e652ebaf64198b72f9ccfa959bea056fb7091", - "sources": "fc7dcb5570215a40c78fdab85c60876b740be714cb479d03b3bd39b2c7b26e5f" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-webflux-test": { - "shasums": { - "jar": "3ed73416ab316d0247d9c2efbb922db1247f03d114fada897f70f9d59408c839", - "sources": "5164cd1c633380d2f2616855a2773f099f15aebc2ad70c04a942e673be12be6b" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-webmvc": { - "shasums": { - "jar": "95250948bda9a0a1e1f2ad3f413bd23e36dfedefb89fe59d309d447c6c4c5010", - "sources": "26a04367e170092463c619c886f4f8b688644eecc4a6c91c18d17c242a8f4211" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-webmvc-test": { - "shasums": { - "jar": "06180d3ee7f9019880b0528cc93164f8f038e35007bd99a40fbe52892d96a955", - "sources": "4c5b614a96d50a44fce7c3269b82f26fed6d3d04933140ecf52db5e4d32e2480" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-webtestclient": { - "shasums": { - "jar": "7015636f7e41b69d80fd903acdcb1554f2b062551c1ce353e625ea4a11f52903", - "sources": "b1175e4937c93d493bbae0a2c7e2cee13cd60a6b7dd859fb6e662091f986e28f" - }, - "version": "4.0.7" - }, - "org.springframework.cloud:spring-cloud-commons": { - "shasums": { - "jar": "6973e75b09d7ccb98566e4e980f600cd98ffcdc76d19fd822e93c7c2166ffa49", - "sources": "fd39f42ebda40c120a450256bbca653d250ff105ea640a530680c1251ced5ca3" - }, - "version": "5.0.2" - }, - "org.springframework.cloud:spring-cloud-context": { - "shasums": { - "jar": "8972e4677e511dc518280d13a16d1a3e6e3ed4ee91e643d3f0c66676f6078f75", - "sources": "3765a79f4a43fe01a1298b09cd8ee51f0e9692971555478fd157bdf456a70c7b" - }, - "version": "5.0.2" - }, - "org.springframework.cloud:spring-cloud-kubernetes-client-autoconfig": { - "shasums": { - "jar": "3ccfe0d3f130c7e2ddede783c416a331e935c5818df7ad6a0369c646641cd596", - "sources": "15ba3dfaf88146e82232510b8a02bdb1c0e6982efe5a0e00a5bbaacd40f7321f" - }, - "version": "5.0.2" - }, - "org.springframework.cloud:spring-cloud-kubernetes-client-config": { - "shasums": { - "jar": "3891c4930a4c214e316a6f1624a596c4007f759b3465cc1fa3cb1fc7edba2614", - "sources": "abf13b94b56188d1df40c9f080c3771c77c1252350a4d6b674887fa1466076e5" - }, - "version": "5.0.2" - }, - "org.springframework.cloud:spring-cloud-kubernetes-commons": { - "shasums": { - "jar": "34a0c7e9a1036e03faa0d75655f7e82eade86f6fc3b4ae2273e434b5798bd8f5", - "sources": "bec63622fa749d090a711f9a24b0c0561f70a8ee5853db7c1bf727990c373817" - }, - "version": "5.0.2" - }, - "org.springframework.cloud:spring-cloud-starter": { - "shasums": { - "jar": "7568b8ced4069bc055af52b5455b206092401a44dcbd4f89d6fa00f89df1cc18" - }, - "version": "5.0.2" - }, - "org.springframework.cloud:spring-cloud-starter-bootstrap": { - "shasums": { - "jar": "366aa9da9bd1e8222bed83fa698649b16ba4b2a976a028d565b95afe610735df", - "sources": "46bb02036834b9db0cfe086ca2b4e9581319029e9dff2b420ddf3eb8094f3d62" - }, - "version": "5.0.2" - }, - "org.springframework.cloud:spring-cloud-starter-kubernetes-client-config": { - "shasums": { - "jar": "f0b4f8adf2dbac198147d18e1890e5ebd5f41d8de4db68ae5eca930e946c1efe" - }, - "version": "5.0.2" - }, - "org.springframework.data:spring-data-cassandra": { - "shasums": { - "jar": "d9e4f2656df238d5561d02d0521036f52518b91d0ef840fd8f25d113b4325610", - "sources": "35340468867c3c37447606312f1d2e2ab18b5123885967a364743f77f196bdb7" - }, - "version": "5.0.6" - }, - "org.springframework.data:spring-data-commons": { - "shasums": { - "jar": "626151b9c33ab98ebec7f1a2e9746cfe1aa428b0de513f9bb90383533ab8ba6d", - "sources": "8d08a88e7b6761bfb84a79fadde38bafaeeed90ddf4595ba9cbf71c25ed7e2dd" - }, - "version": "4.0.6" - }, - "org.springframework.retry:spring-retry": { - "shasums": { - "jar": "213785750007f90b067ba43036cbffdad2890f6bb98917e199f6b049cf810040", - "sources": "672447ec8df39cf31fcd8b9fdd209ae65776fb06c17e1e6fd13e30943963947b" - }, - "version": "2.0.13" - }, - "org.springframework.security:spring-security-config": { - "shasums": { - "jar": "7aeafd876d48d8b5660356953ed7a607d2d09e8f2b9844acba3fcbc32beb63cc", - "sources": "aeb9131e5cd38ea7ebeb0d348c90da837c807f8b68ae3c0fc3152a46682f16ee" - }, - "version": "7.0.6" - }, - "org.springframework.security:spring-security-core": { - "shasums": { - "jar": "f9e1aebb39e051f6f92be029a6fca31e2977a06d417aa51504bfb298bc2a7c69", - "sources": "73d208a0dd021cad8cbbb85a71c8efc66df0161f49e91cd9d877a55def6bc9d0" - }, - "version": "7.0.6" - }, - "org.springframework.security:spring-security-crypto": { - "shasums": { - "jar": "baf9f76bc5b15d090a82841fd5713fa11b75f91fc86de27029d972ce85d3d2e2", - "sources": "bb183230f96711625bdc1d0fc45398917062c2b6b605f94f8dbf0de6a7a1f862" - }, - "version": "7.0.6" - }, - "org.springframework.security:spring-security-oauth2-client": { - "shasums": { - "jar": "2c50bff8f60f08a46bef837dca50d1270f0dba64a60f551c0b96b33a1f608487", - "sources": "47549b16e028266bf4836b4bf00e9111a46143ae486aaed1ff0370c56ddbe82a" - }, - "version": "7.0.6" - }, - "org.springframework.security:spring-security-oauth2-core": { - "shasums": { - "jar": "01cc03b6f30e5b526e85fc276b32af25f34b119f601bc17ba3cbe023f45b0271", - "sources": "68bc19e0b85c108766d92bc4a9e9948a641d65d23d1d93cca7f724998665f88f" - }, - "version": "7.0.6" - }, - "org.springframework.security:spring-security-oauth2-jose": { - "shasums": { - "jar": "c8cd9a8aefc42a02e34166ff02f3f7def2f6028f555932f04f163dea729bdff9", - "sources": "1a33db514d2ce33222aae9bb3ba41227112de08986aac4e58be857417e7332ea" - }, - "version": "7.0.6" - }, - "org.springframework.security:spring-security-oauth2-resource-server": { - "shasums": { - "jar": "4c53ad5b6a06b9f6272212b5a0a71d003b4ba01dd16de691fd63ddf37554f098", - "sources": "97d33151cd02afcded341ab7ad65f1bcca4798789f5626a5d948809ba529373a" - }, - "version": "7.0.6" - }, - "org.springframework.security:spring-security-test": { - "shasums": { - "jar": "4b65c38c7fcf372793cdf6e57651be1332ec241fff9481b15ed8f3ea2207382c", - "sources": "61886c39c6853ebafa91718c1bc44ebaad6f834dcb8d0524e509135033c9498c" - }, - "version": "7.0.6" - }, - "org.springframework.security:spring-security-web": { - "shasums": { - "jar": "6ef060f97271218c0bff56273dc2edb8e2e001a253a0291278d5fdafa5d70573", - "sources": "33298fd169429984bb6cebf9f4a6176ae9eee047e8b5a3ab6b3d752526db03d9" - }, - "version": "7.0.6" - }, - "org.springframework:spring-aop": { - "shasums": { - "jar": "1178f039e087884174e2affc46e484f4a8bd7f2a4e011d33dd9137709f740f80", - "sources": "580610d9e5e2418ea48f64850673ed1d1fdc2d9c8e5cf6e9cfaece1e61b70522" - }, - "version": "7.0.8" - }, - "org.springframework:spring-beans": { - "shasums": { - "jar": "6ec2e361a8872a71d8b1ff66f1bcb8cfa29fcc437931998919da7cecfb59b45b", - "sources": "d75bdcfe142b1576f72356748292cad5c21872a52be2c7f2920a9795bb3c52a5" - }, - "version": "7.0.8" - }, - "org.springframework:spring-context": { - "shasums": { - "jar": "1eb7d552414ebac00e30ab3e809138d810785f6d2c4271db77cdf0181f308f19", - "sources": "a28b30679b51bcf8aac7f06cb564a379cc2d6c4891b2e2dfc738ddd750c6278e" - }, - "version": "7.0.8" - }, - "org.springframework:spring-context-support": { - "shasums": { - "jar": "9ab80715682c47ad66a1a2c0e9ab2be9ec3d828276f281597f12c5208147b92e", - "sources": "22d3e1ee4d52ede6b31cd6fd27d65d4bdd0b2709fcc14af92ec287286ae8abf3" - }, - "version": "7.0.8" - }, - "org.springframework:spring-core": { - "shasums": { - "jar": "726ba2a5130833644bdf267a55ff26e1f52e8dcc9aa1ffa06904ca9c14619f25", - "sources": "3cbdaed9f2b1eea10d8ac27148ac5e6407d2861fa2d373253a09a1220a232919" - }, - "version": "7.0.8" - }, - "org.springframework:spring-expression": { - "shasums": { - "jar": "3c97c38ab59c77ee886e08ccf8096f6bb58a1245f68dfed7a40e93f41c435f9a", - "sources": "35517249c504d1d4550186808665587c8bb5be953cb6cbbb3856804194e790e9" - }, - "version": "7.0.8" - }, - "org.springframework:spring-test": { - "shasums": { - "jar": "6ffb7796075a204915edc4bb9e54dc420183cecb520d753004f660f153763c8e", - "sources": "7bc670e2e1c9cc902da5557a857dde0a4d8089c267ccfcc1bb554cbf2a8c5a05" - }, - "version": "7.0.8" - }, - "org.springframework:spring-tx": { - "shasums": { - "jar": "57e8fdb6de949e7ec2617683fec03af0253bdbdf4bf3d2651a926a94413df283", - "sources": "7887541d74a7221ca92e21d1a2ecc13e8f98767b1603b3b6bb81d7bbd5aede48" - }, - "version": "7.0.8" - }, - "org.springframework:spring-web": { - "shasums": { - "jar": "4d4ed7ecb0453d25d735ea27d025ea36b003c3d29cb7d006bedd6d5188a2f5c0", - "sources": "281cbbd965844cdf2e08396924eacd8a369cd38f56fdfb9519c7492217d8b411" - }, - "version": "7.0.8" - }, - "org.springframework:spring-webflux": { - "shasums": { - "jar": "3e48db9c30d3768ac14898cfad4bad21f4cfc6a8979a12071b75e725143e5eb9", - "sources": "9b00f6ad4a63f3c636e455f3e733d0f75cf5dcdd8225820a1498469b707652ba" - }, - "version": "7.0.8" - }, - "org.springframework:spring-webmvc": { - "shasums": { - "jar": "48f7e1e2d0d46e98ed3fa30d5a64cb1f7ed2aa339a82edcd87289ed8ff216f04", - "sources": "6dcbc3dc4d5222121f83d1eb0d30807e389771b8d233be38b8e413b92b88a106" - }, - "version": "7.0.8" - }, - "org.testcontainers:testcontainers": { - "shasums": { - "jar": "0466f481343d5f350a91274cd7bf984308cbaf90d706247fd1cf4b1a8010c2e1", - "sources": "b4dfdb7d0f8dadc6bfa6d817df703b5c6881b83b6d0452148fd9a00434387e24" - }, - "version": "2.0.5" - }, - "org.testcontainers:testcontainers-cassandra": { - "shasums": { - "jar": "c6ce343636e40330da6ffa317ca4a56bf09affd3e272445d0176498497218cbe", - "sources": "4b2324b4336a0e6d928467abef387ded2b9014ab1353f85cf715f87d1dbb5be3" - }, - "version": "2.0.5" - }, - "org.testcontainers:testcontainers-database-commons": { - "shasums": { - "jar": "0ebbc62bdcfb315cb840a63fbaa148b455927666d9034b5e5c00009d84c755b0", - "sources": "017efc160847bf209b3fdfa3561fa6eb1a5b5b5b82d2214f965caabe9c2cf9ab" - }, - "version": "2.0.5" - }, - "org.testcontainers:testcontainers-junit-jupiter": { - "shasums": { - "jar": "d66eb7f257a85833a8cc973e3814d740967d40a7db1a0de0040653c6ed236748", - "sources": "0dd4463ca900cbce90894cdaafb18fd146ea50b92ee0ee72a9c3e1e48b53a8e6" - }, - "version": "2.0.5" - }, - "org.testcontainers:testcontainers-localstack": { - "shasums": { - "jar": "2fa0f4271a69112ece3841bb26b251962280e39f2e6b2daa7a4aa9128a54485d", - "sources": "b37477b207c29a395c8d0428a6131954aa3495ba2cf5a8db40c9f57c1e8cfa8d" - }, - "version": "2.0.5" - }, - "org.wiremock:wiremock-standalone": { - "shasums": { - "jar": "d097b19bd483c5038479b13a5c71e9faf8f2f5106584f0c120a7770ab0bdb367", - "sources": "76cda98377991ed09088773fe7127f9787e14f8bd41bcd285f94cbd7cd95546f" - }, - "version": "3.13.2" - }, - "org.xmlunit:xmlunit-core": { - "shasums": { - "jar": "208e0cee82aedd9183937e4b9ae44b83884179f724a706bef5795477acfcca91", - "sources": "bb8dba65e8bc1ade346e4bfd98d7f620f51ae8b9034e9758cd6f3031838e79fd" - }, - "version": "2.10.4" - }, - "org.yaml:snakeyaml": { - "shasums": { - "jar": "e6682acf1ace77508ef13649cbf4f8d09d2cf5457bdb61d25ffb6ac0233d78dd", - "sources": "7a7d307ca9fe1663219a60045a8e5a113a69331566f9ebbe1d3b12c6781909ac" - }, - "version": "2.5" - }, - "software.amazon.awssdk:annotations": { - "shasums": { - "jar": "fa3ba3b1b635dfc4d0b20f3910b325f8b70419d1fdb56b487d2e1c423c85e041", - "sources": "2c15cad3cec83ce99c86b9f135d24f42429c5c9a4d032351adfc42330cde8b97" - }, - "version": "2.40.1" - }, - "software.amazon.awssdk:checksums": { - "shasums": { - "jar": "6770fdd0d970c1869cd869d784cc20963a4a6b2bee09f125da0504ba2c9e818d", - "sources": "3a5de1a7994ab25bef0eda898645ba6f02ab584bd3d904f21014bfd9d7cb98b5" - }, - "version": "2.40.1" - }, - "software.amazon.awssdk:checksums-spi": { - "shasums": { - "jar": "1f9d68cd2f5ec133757e37b794ab06de015d1b35f4c1452b43ab8b612318a8c3", - "sources": "d17d8d92268f9c6773aa6b72564774dc394ae2fb2149bed26152385a9b6751ff" - }, - "version": "2.40.1" - }, - "software.amazon.awssdk:endpoints-spi": { - "shasums": { - "jar": "05a48200f243664fa9ca8f05cf29725cbd059a9a6f3cdd55bac44a8fc12903de", - "sources": "24644eb6a36a38df7a31e81fb9fcd106298f188215b6e2ec178732711fc4b0ba" - }, - "version": "2.40.1" - }, - "software.amazon.awssdk:http-auth-aws": { - "shasums": { - "jar": "9b182f3697acc111b213524126f857f844fed5fdf95f734470d16b96097fcd3a", - "sources": "6de3c527d996a46a4e14e268fc13a32b314383a3b2976e7820720c9ddff483a5" - }, - "version": "2.40.1" - }, - "software.amazon.awssdk:http-auth-spi": { - "shasums": { - "jar": "d0cd6f8dd1ef77a990c4b0ae45132707490f886307d9ee446ae1eae93a80ae5a", - "sources": "6bd36a3bfbce87b5550d73ad7ff6d0950dc6aec1baf071b0c47bd02cd98daa3d" - }, - "version": "2.40.1" - }, - "software.amazon.awssdk:http-client-spi": { - "shasums": { - "jar": "87c6fc3ec6c79e088ebfcc818963715bc0a5e103f5612bd4b6d5c49720bb06e3", - "sources": "d6667c353cc231efee460dae061be2b654d3319ffb66d16804da30f5a8475d84" - }, - "version": "2.40.1" - }, - "software.amazon.awssdk:identity-spi": { - "shasums": { - "jar": "b4693f3832b3669850a11f29608a2a3d6e0150ab1528d01cad2a7a32848db591", - "sources": "56ab003dea16ded5f70c1a3af840433c6f5f8fd33435500535e7b888cdf8c923" - }, - "version": "2.40.1" - }, - "software.amazon.awssdk:json-utils": { - "shasums": { - "jar": "f565187ae223ab13a4b959f213933540475652269c414b0c82f33cab45977a74", - "sources": "3fbd4a882a672587b93b9cdd2ee7c2c1faa0f5a848509d3d3d7931ef714d6d95" - }, - "version": "2.40.1" - }, - "software.amazon.awssdk:metrics-spi": { - "shasums": { - "jar": "033b5d20384c9b4ac98a17eba0656711738da94a9d33a292b414aa0905177471", - "sources": "373fbebacc328596dda847d8183f22b9e6abef85f7c6287d7c71615cab3d4939" - }, - "version": "2.40.1" - }, - "software.amazon.awssdk:profiles": { - "shasums": { - "jar": "602cac04531cf13d4c06d8d70d7b5b0e109517c73a4c91473058886fbe574cc1", - "sources": "e498cf7ef147b8fc789a448554561b5706daae1062a5e23bc4870149b42d8002" - }, - "version": "2.40.1" - }, - "software.amazon.awssdk:regions": { - "shasums": { - "jar": "6b1c788306fd7a4fac6bc788a8f5d2300be13049197adacfca072d1b69eb9ddb", - "sources": "1bae6ad3cb124a6850fbede87c9dcd72f7c7eab1f570c9ae71a98f3597c4b59f" - }, - "version": "2.40.1" - }, - "software.amazon.awssdk:retries": { - "shasums": { - "jar": "198f5f0202fe8e861f3ad2fa8ecb70d0a8180dd568f4d136c898f824b3cd0dd3", - "sources": "2305b334eceb894749d281a3f48be9198e9305f09cb3b40b948a5c661c20c41a" - }, - "version": "2.40.1" - }, - "software.amazon.awssdk:retries-spi": { - "shasums": { - "jar": "af1c67e4212fffe7d215b41fb74e6994c36a0499234e325954c38db6b14e0e28", - "sources": "c8e5f28924cc8e0cb017a2a25c370a0d0ed9223cfb0051c6a1b0c769a5a46e0b" - }, - "version": "2.40.1" - }, - "software.amazon.awssdk:sdk-core": { - "shasums": { - "jar": "6c6b1a49b18538060d1f9a797998ca8d589910b274b345bbf0a61c4540e41f27", - "sources": "560156fe956a48cd171077edc2ccb1bcfe2f93c09e3ce62667018228b6144450" - }, - "version": "2.40.1" - }, - "software.amazon.awssdk:third-party-jackson-core": { - "shasums": { - "jar": "9939a77038dd0d53675a44fc06afb9b34805cef8fc7b3641d2e861740c1655fc", - "sources": "92ce15d5817f97d935c595b780135666d4674eaf3aeb94ae13b1e4e553f93e42" - }, - "version": "2.40.1" - }, - "software.amazon.awssdk:utils": { - "shasums": { - "jar": "40f19e6ce26acc6a78204aa493833f578e2245cc0bc9749cc9ba431bb8f855e1", - "sources": "2ddd7c56fbc36d7c4e0c84739d68388faff130f51855ce2b80466c8784cf1b25" - }, - "version": "2.40.1" - }, - "tools.jackson.core:jackson-core": { - "shasums": { - "jar": "3bda1cd6eff0a8d47bdfcaeae7c2bd5311d6c8ed494ef5f3e51029bb44aa9bdf", - "sources": "5aa481c1c120505fc1d204510ec201a40c2bb0bb6bdea24560e0b5fb66484e60" - }, - "version": "3.1.4" - }, - "tools.jackson.core:jackson-databind": { - "shasums": { - "jar": "14034bfdf392b6ebec1b4bb6c1de29d604f0aa97251259a19d5f19af8719bb20", - "sources": "109baa39968ff6fdcc4389dd4249f04d2edcab7387421ea17bfb51bf18e24189" - }, - "version": "3.1.4" - }, - "tools.jackson.module:jackson-module-blackbird": { - "shasums": { - "jar": "d93aef324acdbffeb4e943e75ed0772f43101930b70fe37219147e5d3b84b3cd", - "sources": "5c7f6900e8b888c6c3edad9b13cd4df0d11f5bd8307064bb79881cb4edd389ef" - }, - "version": "3.1.4" - } - }, - "conflict_resolution": { - "com.github.jnr:jnr-ffi:2.2.11": "com.github.jnr:jnr-ffi:2.1.7", - "com.github.jnr:jnr-posix:3.0.44": "com.github.jnr:jnr-posix:3.1.15", - "com.google.code.findbugs:jsr305:2.0.1": "com.google.code.findbugs:jsr305:3.0.2", - "com.google.errorprone:error_prone_annotations:2.18.0": "com.google.errorprone:error_prone_annotations:2.49.0", - "com.google.errorprone:error_prone_annotations:2.23.0": "com.google.errorprone:error_prone_annotations:2.49.0", - "com.google.errorprone:error_prone_annotations:2.41.0": "com.google.errorprone:error_prone_annotations:2.49.0", - "com.google.errorprone:error_prone_annotations:2.47.0": "com.google.errorprone:error_prone_annotations:2.49.0", - "com.google.guava:guava:19.0": "com.google.guava:guava:33.6.0-jre", - "com.google.guava:guava:32.1.3-android": "com.google.guava:guava:33.6.0-jre", - "com.google.guava:guava:32.1.3-jre": "com.google.guava:guava:33.6.0-jre", - "com.google.j2objc:j2objc-annotations:2.8": "com.google.j2objc:j2objc-annotations:3.1", - "com.squareup.okio:okio-jvm:3.6.0": "com.squareup.okio:okio-jvm:3.16.1", - "commons-io:commons-io:2.19.0": "commons-io:commons-io:2.20.0", - "io.dropwizard.metrics:metrics-core:3.2.2": "io.dropwizard.metrics:metrics-core:4.1.18", - "org.apache.commons:commons-compress:1.27.1": "org.apache.commons:commons-compress:1.28.0", - "org.hdrhistogram:HdrHistogram:2.1.12": "org.hdrhistogram:HdrHistogram:2.2.2", - "org.jetbrains:annotations:13.0": "org.jetbrains:annotations:17.0.0" - }, - "dependencies": { - "ch.qos.logback:logback-classic": [ - "ch.qos.logback:logback-core", - "org.slf4j:slf4j-api" - ], - "com.datastax.cassandra:cassandra-driver-core": [ - "com.fasterxml.jackson.core:jackson-databind", - "com.github.jnr:jnr-ffi", - "com.github.jnr:jnr-posix", - "com.google.guava:guava", - "io.dropwizard.metrics:metrics-core", - "io.netty:netty-handler", - "org.slf4j:slf4j-api" - ], - "com.fasterxml.jackson.core:jackson-databind": [ - "com.fasterxml.jackson.core:jackson-annotations", - "com.fasterxml.jackson.core:jackson-core" - ], - "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml": [ - "com.fasterxml.jackson.core:jackson-core", - "com.fasterxml.jackson.core:jackson-databind", - "org.yaml:snakeyaml" - ], - "com.fasterxml.jackson.datatype:jackson-datatype-jsr310": [ - "com.fasterxml.jackson.core:jackson-annotations", - "com.fasterxml.jackson.core:jackson-core", - "com.fasterxml.jackson.core:jackson-databind" - ], - "com.github.ben-manes.caffeine:caffeine": [ - "com.google.errorprone:error_prone_annotations", - "org.jspecify:jspecify" - ], - "com.github.ben-manes.caffeine:guava": [ - "com.github.ben-manes.caffeine:caffeine", - "com.google.guava:guava" - ], - "com.github.docker-java:docker-java-api": [ - "com.fasterxml.jackson.core:jackson-annotations", - "org.slf4j:slf4j-api" - ], - "com.github.docker-java:docker-java-transport-zerodep": [ - "com.github.docker-java:docker-java-transport", - "net.java.dev.jna:jna", - "org.slf4j:slf4j-api" - ], - "com.github.java-json-tools:btf": [ - "com.google.code.findbugs:jsr305" - ], - "com.github.java-json-tools:jackson-coreutils": [ - "com.fasterxml.jackson.core:jackson-databind", - "com.github.java-json-tools:msg-simple", - "com.google.code.findbugs:jsr305" - ], - "com.github.java-json-tools:json-patch": [ - "com.fasterxml.jackson.core:jackson-databind", - "com.github.java-json-tools:jackson-coreutils", - "com.github.java-json-tools:msg-simple" - ], - "com.github.java-json-tools:msg-simple": [ - "com.github.java-json-tools:btf", - "com.google.code.findbugs:jsr305" - ], - "com.github.jnr:jnr-ffi": [ - "com.github.jnr:jffi", - "com.github.jnr:jffi:jar:native", - "com.github.jnr:jnr-x86asm", - "org.ow2.asm:asm", - "org.ow2.asm:asm-analysis", - "org.ow2.asm:asm-commons", - "org.ow2.asm:asm-tree", - "org.ow2.asm:asm-util" - ], - "com.github.jnr:jnr-posix": [ - "com.github.jnr:jnr-constants", - "com.github.jnr:jnr-ffi" - ], - "com.google.api.grpc:proto-google-common-protos": [ - "com.google.protobuf:protobuf-java" - ], - "com.google.code.gson:gson": [ - "com.google.errorprone:error_prone_annotations" - ], - "com.google.guava:guava": [ - "com.google.errorprone:error_prone_annotations", - "com.google.guava:failureaccess", - "com.google.guava:listenablefuture", - "com.google.j2objc:j2objc-annotations", - "org.jspecify:jspecify" - ], - "com.google.protobuf:protobuf-java-util": [ - "com.google.code.findbugs:jsr305", - "com.google.code.gson:gson", - "com.google.errorprone:error_prone_annotations", - "com.google.protobuf:protobuf-java" - ], - "com.jayway.jsonpath:json-path": [ - "net.minidev:json-smart", - "org.slf4j:slf4j-api" - ], - "com.nimbusds:oauth2-oidc-sdk": [ - "com.github.stephenc.jcip:jcip-annotations", - "com.nimbusds:content-type", - "com.nimbusds:lang-tag", - "com.nimbusds:nimbus-jose-jwt", - "net.minidev:json-smart" - ], - "com.squareup.okhttp3:logging-interceptor": [ - "com.squareup.okhttp3:okhttp", - "org.jetbrains.kotlin:kotlin-stdlib-jdk8" - ], - "com.squareup.okhttp3:okhttp": [ - "com.squareup.okio:okio", - "org.jetbrains.kotlin:kotlin-stdlib-jdk8" - ], - "com.squareup.okhttp3:okhttp-jvm": [ - "com.squareup.okio:okio-jvm", - "org.jetbrains.kotlin:kotlin-stdlib" - ], - "com.squareup.okio:okio": [ - "com.squareup.okio:okio-jvm" - ], - "com.squareup.okio:okio-jvm": [ - "org.jetbrains.kotlin:kotlin-stdlib" - ], - "io.cloudevents:cloudevents-core": [ - "io.cloudevents:cloudevents-api" - ], - "io.cloudevents:cloudevents-json-jackson": [ - "com.fasterxml.jackson.core:jackson-core", - "com.fasterxml.jackson.core:jackson-databind", - "io.cloudevents:cloudevents-core" - ], - "io.dropwizard.metrics:metrics-core": [ - "org.slf4j:slf4j-api" - ], - "io.grpc:grpc-api": [ - "com.google.code.findbugs:jsr305", - "com.google.errorprone:error_prone_annotations", - "com.google.guava:guava" - ], - "io.grpc:grpc-context": [ - "io.grpc:grpc-api" - ], - "io.grpc:grpc-core": [ - "com.google.android:annotations", - "com.google.code.gson:gson", - "com.google.errorprone:error_prone_annotations", - "com.google.guava:guava", - "io.grpc:grpc-api", - "io.grpc:grpc-context", - "io.perfmark:perfmark-api", - "org.codehaus.mojo:animal-sniffer-annotations" - ], - "io.grpc:grpc-inprocess": [ - "com.google.guava:guava", - "io.grpc:grpc-api", - "io.grpc:grpc-core" - ], - "io.grpc:grpc-netty-shaded": [ - "com.google.errorprone:error_prone_annotations", - "com.google.guava:guava", - "io.grpc:grpc-api", - "io.grpc:grpc-core", - "io.grpc:grpc-util", - "io.perfmark:perfmark-api" - ], - "io.grpc:grpc-protobuf": [ - "com.google.api.grpc:proto-google-common-protos", - "com.google.code.findbugs:jsr305", - "com.google.guava:guava", - "com.google.protobuf:protobuf-java", - "io.grpc:grpc-api", - "io.grpc:grpc-protobuf-lite" - ], - "io.grpc:grpc-protobuf-lite": [ - "com.google.code.findbugs:jsr305", - "com.google.guava:guava", - "io.grpc:grpc-api" - ], - "io.grpc:grpc-services": [ - "com.google.code.gson:gson", - "com.google.errorprone:error_prone_annotations", - "com.google.guava:guava", - "com.google.j2objc:j2objc-annotations", - "com.google.protobuf:protobuf-java-util", - "io.grpc:grpc-core", - "io.grpc:grpc-protobuf", - "io.grpc:grpc-stub", - "io.grpc:grpc-util" - ], - "io.grpc:grpc-stub": [ - "com.google.errorprone:error_prone_annotations", - "com.google.guava:guava", - "io.grpc:grpc-api" - ], - "io.grpc:grpc-util": [ - "com.google.guava:guava", - "io.grpc:grpc-api", - "io.grpc:grpc-core", - "org.codehaus.mojo:animal-sniffer-annotations" - ], - "io.gsonfire:gson-fire": [ - "com.google.code.gson:gson" - ], - "io.kubernetes:client-java": [ - "com.google.protobuf:protobuf-java", - "commons-codec:commons-codec", - "commons-io:commons-io", - "io.kubernetes:client-java-api", - "io.kubernetes:client-java-proto", - "org.apache.commons:commons-collections4", - "org.apache.commons:commons-compress", - "org.apache.commons:commons-lang3", - "org.bitbucket.b_c:jose4j", - "org.bouncycastle:bcpkix-jdk18on", - "org.slf4j:slf4j-api", - "org.yaml:snakeyaml" - ], - "io.kubernetes:client-java-api": [ - "com.fasterxml.jackson.core:jackson-databind", - "com.google.code.findbugs:jsr305", - "com.google.code.gson:gson", - "com.squareup.okhttp3:logging-interceptor", - "com.squareup.okhttp3:okhttp", - "io.gsonfire:gson-fire", - "io.swagger:swagger-annotations", - "jakarta.annotation:jakarta.annotation-api", - "javax.annotation:javax.annotation-api", - "org.apache.commons:commons-lang3" - ], - "io.kubernetes:client-java-api-fluent": [ - "io.kubernetes:client-java-api" - ], - "io.kubernetes:client-java-extended": [ - "com.bucket4j:bucket4j-core", - "com.github.ben-manes.caffeine:caffeine", - "io.kubernetes:client-java", - "io.kubernetes:client-java-api", - "io.kubernetes:client-java-api-fluent", - "io.kubernetes:client-java-proto", - "org.apache.commons:commons-lang3" - ], - "io.kubernetes:client-java-proto": [ - "com.google.protobuf:protobuf-java" - ], - "io.micrometer:context-propagation": [ - "org.jspecify:jspecify" - ], - "io.micrometer:micrometer-commons": [ - "org.jspecify:jspecify" - ], - "io.micrometer:micrometer-core": [ - "io.micrometer:micrometer-commons", - "io.micrometer:micrometer-observation", - "org.hdrhistogram:HdrHistogram", - "org.jspecify:jspecify", - "org.latencyutils:LatencyUtils" - ], - "io.micrometer:micrometer-jakarta9": [ - "io.micrometer:micrometer-commons", - "io.micrometer:micrometer-core", - "io.micrometer:micrometer-observation", - "org.jspecify:jspecify" - ], - "io.micrometer:micrometer-observation": [ - "io.micrometer:micrometer-commons", - "org.jspecify:jspecify" - ], - "io.micrometer:micrometer-observation-test": [ - "io.micrometer:micrometer-observation", - "org.assertj:assertj-core", - "org.jspecify:jspecify", - "org.junit.jupiter:junit-jupiter", - "org.mockito:mockito-core" - ], - "io.micrometer:micrometer-registry-prometheus": [ - "io.micrometer:micrometer-core", - "io.prometheus:prometheus-metrics-core", - "io.prometheus:prometheus-metrics-exposition-formats", - "io.prometheus:prometheus-metrics-tracer-common", - "org.jspecify:jspecify" - ], - "io.micrometer:micrometer-tracing": [ - "io.micrometer:context-propagation", - "io.micrometer:micrometer-observation", - "org.jspecify:jspecify" - ], - "io.micrometer:micrometer-tracing-bridge-otel": [ - "io.micrometer:micrometer-observation", - "io.micrometer:micrometer-tracing", - "io.opentelemetry.semconv:opentelemetry-semconv", - "io.opentelemetry:opentelemetry-api", - "io.opentelemetry:opentelemetry-extension-trace-propagators", - "io.opentelemetry:opentelemetry-sdk", - "io.opentelemetry:opentelemetry-sdk-common", - "io.opentelemetry:opentelemetry-sdk-trace", - "org.jspecify:jspecify", - "org.slf4j:slf4j-api" - ], - "io.nats:jnats": [ - "org.bouncycastle:bcprov-lts8on", - "org.jspecify:jspecify" - ], - "io.netty:netty-buffer": [ - "io.netty:netty-common" - ], - "io.netty:netty-codec-base": [ - "io.netty:netty-buffer", - "io.netty:netty-common", - "io.netty:netty-transport" - ], - "io.netty:netty-codec-compression": [ - "io.netty:netty-buffer", - "io.netty:netty-codec-base", - "io.netty:netty-common", - "io.netty:netty-transport" - ], - "io.netty:netty-codec-dns": [ - "io.netty:netty-buffer", - "io.netty:netty-codec-base", - "io.netty:netty-common", - "io.netty:netty-transport" - ], - "io.netty:netty-codec-http": [ - "io.netty:netty-buffer", - "io.netty:netty-codec-base", - "io.netty:netty-codec-compression", - "io.netty:netty-common", - "io.netty:netty-handler", - "io.netty:netty-transport" - ], - "io.netty:netty-codec-http2": [ - "io.netty:netty-buffer", - "io.netty:netty-codec-base", - "io.netty:netty-codec-http", - "io.netty:netty-common", - "io.netty:netty-handler", - "io.netty:netty-transport" - ], - "io.netty:netty-codec-http3": [ - "io.netty:netty-buffer", - "io.netty:netty-codec-base", - "io.netty:netty-codec-classes-quic", - "io.netty:netty-codec-compression", - "io.netty:netty-codec-http", - "io.netty:netty-codec-native-quic:jar:linux-aarch_64", - "io.netty:netty-codec-native-quic:jar:linux-x86_64", - "io.netty:netty-codec-native-quic:jar:osx-aarch_64", - "io.netty:netty-codec-native-quic:jar:osx-x86_64", - "io.netty:netty-codec-native-quic:jar:windows-x86_64", - "io.netty:netty-common", - "io.netty:netty-handler", - "io.netty:netty-resolver", - "io.netty:netty-transport", - "io.netty:netty-transport-native-unix-common" - ], - "io.netty:netty-codec-native-quic:jar:linux-aarch_64": [ - "io.netty:netty-codec-classes-quic" - ], - "io.netty:netty-codec-native-quic:jar:linux-x86_64": [ - "io.netty:netty-codec-classes-quic" - ], - "io.netty:netty-codec-native-quic:jar:osx-aarch_64": [ - "io.netty:netty-codec-classes-quic" - ], - "io.netty:netty-codec-native-quic:jar:osx-x86_64": [ - "io.netty:netty-codec-classes-quic" - ], - "io.netty:netty-codec-native-quic:jar:windows-x86_64": [ - "io.netty:netty-codec-classes-quic" - ], - "io.netty:netty-codec-socks": [ - "io.netty:netty-buffer", - "io.netty:netty-codec-base", - "io.netty:netty-common", - "io.netty:netty-transport" - ], - "io.netty:netty-handler": [ - "io.netty:netty-buffer", - "io.netty:netty-codec-base", - "io.netty:netty-common", - "io.netty:netty-resolver", - "io.netty:netty-transport", - "io.netty:netty-transport-native-unix-common" - ], - "io.netty:netty-handler-proxy": [ - "io.netty:netty-buffer", - "io.netty:netty-codec-base", - "io.netty:netty-codec-http", - "io.netty:netty-codec-socks", - "io.netty:netty-common", - "io.netty:netty-handler", - "io.netty:netty-transport" - ], - "io.netty:netty-resolver": [ - "io.netty:netty-common" - ], - "io.netty:netty-resolver-dns": [ - "io.netty:netty-buffer", - "io.netty:netty-codec-base", - "io.netty:netty-codec-dns", - "io.netty:netty-common", - "io.netty:netty-handler", - "io.netty:netty-resolver", - "io.netty:netty-transport" - ], - "io.netty:netty-resolver-dns-classes-macos": [ - "io.netty:netty-common", - "io.netty:netty-resolver-dns", - "io.netty:netty-transport-native-unix-common" - ], - "io.netty:netty-resolver-dns-native-macos:jar:osx-x86_64": [ - "io.netty:netty-resolver-dns-classes-macos" - ], - "io.netty:netty-transport": [ - "io.netty:netty-buffer", - "io.netty:netty-common", - "io.netty:netty-resolver" - ], - "io.netty:netty-transport-classes-epoll": [ - "io.netty:netty-buffer", - "io.netty:netty-common", - "io.netty:netty-transport", - "io.netty:netty-transport-native-unix-common" - ], - "io.netty:netty-transport-native-epoll:jar:linux-x86_64": [ - "io.netty:netty-buffer", - "io.netty:netty-common", - "io.netty:netty-transport", - "io.netty:netty-transport-classes-epoll", - "io.netty:netty-transport-native-unix-common" - ], - "io.netty:netty-transport-native-unix-common": [ - "io.netty:netty-buffer", - "io.netty:netty-common", - "io.netty:netty-transport" - ], - "io.opentelemetry:opentelemetry-api": [ - "io.opentelemetry:opentelemetry-context" - ], - "io.opentelemetry:opentelemetry-context": [ - "io.opentelemetry:opentelemetry-common" - ], - "io.opentelemetry:opentelemetry-exporter-common": [ - "io.opentelemetry:opentelemetry-api", - "io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi" - ], - "io.opentelemetry:opentelemetry-exporter-otlp": [ - "io.opentelemetry:opentelemetry-exporter-otlp-common", - "io.opentelemetry:opentelemetry-exporter-sender-okhttp", - "io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi", - "io.opentelemetry:opentelemetry-sdk-logs", - "io.opentelemetry:opentelemetry-sdk-metrics", - "io.opentelemetry:opentelemetry-sdk-trace" - ], - "io.opentelemetry:opentelemetry-exporter-otlp-common": [ - "io.opentelemetry:opentelemetry-exporter-common" - ], - "io.opentelemetry:opentelemetry-exporter-sender-okhttp": [ - "com.squareup.okhttp3:okhttp-jvm", - "io.opentelemetry:opentelemetry-exporter-common", - "io.opentelemetry:opentelemetry-sdk-common" - ], - "io.opentelemetry:opentelemetry-extension-trace-propagators": [ - "io.opentelemetry:opentelemetry-api" - ], - "io.opentelemetry:opentelemetry-sdk": [ - "io.opentelemetry:opentelemetry-api", - "io.opentelemetry:opentelemetry-sdk-common", - "io.opentelemetry:opentelemetry-sdk-logs", - "io.opentelemetry:opentelemetry-sdk-metrics", - "io.opentelemetry:opentelemetry-sdk-trace" - ], - "io.opentelemetry:opentelemetry-sdk-common": [ - "io.opentelemetry:opentelemetry-api" - ], - "io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi": [ - "io.opentelemetry:opentelemetry-sdk" - ], - "io.opentelemetry:opentelemetry-sdk-logs": [ - "io.opentelemetry:opentelemetry-api", - "io.opentelemetry:opentelemetry-sdk-common" - ], - "io.opentelemetry:opentelemetry-sdk-metrics": [ - "io.opentelemetry:opentelemetry-api", - "io.opentelemetry:opentelemetry-sdk-common" - ], - "io.opentelemetry:opentelemetry-sdk-testing": [ - "io.opentelemetry:opentelemetry-api", - "io.opentelemetry:opentelemetry-sdk" - ], - "io.opentelemetry:opentelemetry-sdk-trace": [ - "io.opentelemetry:opentelemetry-api", - "io.opentelemetry:opentelemetry-sdk-common" - ], - "io.projectreactor.netty:reactor-netty-core": [ - "io.netty:netty-handler", - "io.netty:netty-handler-proxy", - "io.netty:netty-resolver-dns", - "io.netty:netty-resolver-dns-native-macos:jar:osx-x86_64", - "io.netty:netty-transport-native-epoll:jar:linux-x86_64", - "io.projectreactor:reactor-core", - "org.jspecify:jspecify" - ], - "io.projectreactor.netty:reactor-netty-http": [ - "io.netty:netty-codec-http", - "io.netty:netty-codec-http2", - "io.netty:netty-codec-http3", - "io.netty:netty-resolver-dns", - "io.netty:netty-resolver-dns-native-macos:jar:osx-x86_64", - "io.netty:netty-transport-native-epoll:jar:linux-x86_64", - "io.projectreactor.netty:reactor-netty-core", - "io.projectreactor:reactor-core", - "org.jspecify:jspecify" - ], - "io.projectreactor:reactor-core": [ - "org.jspecify:jspecify", - "org.reactivestreams:reactive-streams" - ], - "io.projectreactor:reactor-test": [ - "io.projectreactor:reactor-core", - "org.jspecify:jspecify" - ], - "io.prometheus:prometheus-metrics-core": [ - "io.prometheus:prometheus-metrics-config", - "io.prometheus:prometheus-metrics-model" - ], - "io.prometheus:prometheus-metrics-exposition-formats": [ - "io.prometheus:prometheus-metrics-exposition-textformats" - ], - "io.prometheus:prometheus-metrics-exposition-textformats": [ - "io.prometheus:prometheus-metrics-config", - "io.prometheus:prometheus-metrics-model" - ], - "io.prometheus:prometheus-metrics-model": [ - "io.prometheus:prometheus-metrics-config" - ], - "io.swagger.core.v3:swagger-core-jakarta": [ - "com.fasterxml.jackson.core:jackson-annotations", - "com.fasterxml.jackson.core:jackson-databind", - "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml", - "com.fasterxml.jackson.datatype:jackson-datatype-jsr310", - "io.swagger.core.v3:swagger-annotations-jakarta", - "io.swagger.core.v3:swagger-models-jakarta", - "jakarta.validation:jakarta.validation-api", - "jakarta.xml.bind:jakarta.xml.bind-api", - "org.apache.commons:commons-lang3", - "org.slf4j:slf4j-api", - "org.yaml:snakeyaml" - ], - "io.swagger.core.v3:swagger-models-jakarta": [ - "com.fasterxml.jackson.core:jackson-annotations" - ], - "jakarta.xml.bind:jakarta.xml.bind-api": [ - "jakarta.activation:jakarta.activation-api" - ], - "net.devh:grpc-common-spring-boot": [ - "io.grpc:grpc-core", - "org.springframework.boot:spring-boot-starter" - ], - "net.devh:grpc-server-spring-boot-starter": [ - "io.grpc:grpc-api", - "io.grpc:grpc-inprocess", - "io.grpc:grpc-netty-shaded", - "io.grpc:grpc-protobuf", - "io.grpc:grpc-services", - "io.grpc:grpc-stub", - "net.devh:grpc-common-spring-boot", - "org.springframework.boot:spring-boot-starter" - ], - "net.javacrumbs.shedlock:shedlock-core": [ - "org.slf4j:slf4j-api" - ], - "net.javacrumbs.shedlock:shedlock-provider-cassandra": [ - "net.javacrumbs.shedlock:shedlock-core", - "org.apache.cassandra:java-driver-core", - "org.apache.cassandra:java-driver-query-builder" - ], - "net.javacrumbs.shedlock:shedlock-spring": [ - "net.javacrumbs.shedlock:shedlock-core", - "org.springframework:spring-context" - ], - "net.minidev:accessors-smart": [ - "org.ow2.asm:asm" - ], - "net.minidev:json-smart": [ - "net.minidev:accessors-smart" - ], - "org.apache.cassandra:java-driver-core": [ - "com.datastax.oss:native-protocol", - "com.fasterxml.jackson.core:jackson-core", - "com.fasterxml.jackson.core:jackson-databind", - "com.github.jnr:jnr-posix", - "com.typesafe:config", - "io.dropwizard.metrics:metrics-core", - "io.netty:netty-handler", - "org.apache.cassandra:java-driver-guava-shaded", - "org.hdrhistogram:HdrHistogram", - "org.reactivestreams:reactive-streams", - "org.slf4j:slf4j-api" - ], - "org.apache.cassandra:java-driver-metrics-micrometer": [ - "io.micrometer:micrometer-core", - "org.apache.cassandra:java-driver-core" - ], - "org.apache.cassandra:java-driver-query-builder": [ - "org.apache.cassandra:java-driver-core", - "org.apache.cassandra:java-driver-guava-shaded" - ], - "org.apache.commons:commons-compress": [ - "commons-codec:commons-codec", - "commons-io:commons-io", - "org.apache.commons:commons-lang3" - ], - "org.apache.logging.log4j:log4j-to-slf4j": [ - "org.apache.logging.log4j:log4j-api", - "org.slf4j:slf4j-api" - ], - "org.apache.tomcat.embed:tomcat-embed-websocket": [ - "org.apache.tomcat.embed:tomcat-embed-core" - ], - "org.assertj:assertj-core": [ - "net.bytebuddy:byte-buddy" - ], - "org.awaitility:awaitility": [ - "org.hamcrest:hamcrest" - ], - "org.bitbucket.b_c:jose4j": [ - "org.slf4j:slf4j-api" - ], - "org.bouncycastle:bcpkix-jdk18on": [ - "org.bouncycastle:bcutil-jdk18on" - ], - "org.bouncycastle:bcutil-jdk18on": [ - "org.bouncycastle:bcprov-jdk18on" - ], - "org.hibernate.validator:hibernate-validator": [ - "com.fasterxml:classmate", - "jakarta.validation:jakarta.validation-api", - "org.jboss.logging:jboss-logging" - ], - "org.jacoco:org.jacoco.cli": [ - "args4j:args4j", - "org.jacoco:org.jacoco.core", - "org.jacoco:org.jacoco.report" - ], - "org.jacoco:org.jacoco.core": [ - "org.ow2.asm:asm", - "org.ow2.asm:asm-commons", - "org.ow2.asm:asm-tree" - ], - "org.jacoco:org.jacoco.report": [ - "org.jacoco:org.jacoco.core" - ], - "org.jetbrains.kotlin:kotlin-stdlib": [ - "org.jetbrains:annotations" - ], - "org.jetbrains.kotlin:kotlin-stdlib-jdk7": [ - "org.jetbrains.kotlin:kotlin-stdlib" - ], - "org.jetbrains.kotlin:kotlin-stdlib-jdk8": [ - "org.jetbrains.kotlin:kotlin-stdlib", - "org.jetbrains.kotlin:kotlin-stdlib-jdk7" - ], - "org.junit.jupiter:junit-jupiter": [ - "org.junit.jupiter:junit-jupiter-api", - "org.junit.jupiter:junit-jupiter-engine", - "org.junit.jupiter:junit-jupiter-params" - ], - "org.junit.jupiter:junit-jupiter-api": [ - "org.apiguardian:apiguardian-api", - "org.jspecify:jspecify", - "org.junit.platform:junit-platform-commons", - "org.opentest4j:opentest4j" - ], - "org.junit.jupiter:junit-jupiter-engine": [ - "org.apiguardian:apiguardian-api", - "org.jspecify:jspecify", - "org.junit.jupiter:junit-jupiter-api", - "org.junit.platform:junit-platform-engine" - ], - "org.junit.jupiter:junit-jupiter-params": [ - "org.apiguardian:apiguardian-api", - "org.jspecify:jspecify", - "org.junit.jupiter:junit-jupiter-api" - ], - "org.junit.platform:junit-platform-commons": [ - "org.apiguardian:apiguardian-api", - "org.jspecify:jspecify" - ], - "org.junit.platform:junit-platform-engine": [ - "org.apiguardian:apiguardian-api", - "org.jspecify:jspecify", - "org.junit.platform:junit-platform-commons", - "org.opentest4j:opentest4j" - ], - "org.mockito:mockito-core": [ - "net.bytebuddy:byte-buddy", - "net.bytebuddy:byte-buddy-agent", - "org.objenesis:objenesis" - ], - "org.mockito:mockito-junit-jupiter": [ - "org.junit.jupiter:junit-jupiter-api", - "org.mockito:mockito-core" - ], - "org.ow2.asm:asm-analysis": [ - "org.ow2.asm:asm-tree" - ], - "org.ow2.asm:asm-commons": [ - "org.ow2.asm:asm", - "org.ow2.asm:asm-tree" - ], - "org.ow2.asm:asm-tree": [ - "org.ow2.asm:asm" - ], - "org.ow2.asm:asm-util": [ - "org.ow2.asm:asm", - "org.ow2.asm:asm-analysis", - "org.ow2.asm:asm-tree" - ], - "org.rnorth.duct-tape:duct-tape": [ - "org.jetbrains:annotations" - ], - "org.skyscreamer:jsonassert": [ - "com.vaadin.external.google:android-json" - ], - "org.slf4j:jul-to-slf4j": [ - "org.slf4j:slf4j-api" - ], - "org.springdoc:springdoc-openapi-starter-common": [ - "io.swagger.core.v3:swagger-core-jakarta", - "org.springframework.boot:spring-boot-autoconfigure", - "org.springframework.boot:spring-boot-jackson", - "org.springframework.boot:spring-boot-starter", - "org.springframework.boot:spring-boot-validation" - ], - "org.springdoc:springdoc-openapi-starter-webflux-api": [ - "org.springdoc:springdoc-openapi-starter-common", - "org.springframework.boot:spring-boot-web-server", - "org.springframework.boot:spring-boot-webflux" - ], - "org.springdoc:springdoc-openapi-starter-webmvc-api": [ - "org.springdoc:springdoc-openapi-starter-common", - "org.springframework.boot:spring-boot-web-server", - "org.springframework.boot:spring-boot-webmvc" - ], - "org.springframework.boot:spring-boot": [ - "org.springframework:spring-context", - "org.springframework:spring-core" - ], - "org.springframework.boot:spring-boot-actuator": [ - "org.springframework.boot:spring-boot" - ], - "org.springframework.boot:spring-boot-actuator-autoconfigure": [ - "org.springframework.boot:spring-boot-actuator", - "org.springframework.boot:spring-boot-autoconfigure" - ], - "org.springframework.boot:spring-boot-autoconfigure": [ - "org.springframework.boot:spring-boot" - ], - "org.springframework.boot:spring-boot-cassandra": [ - "org.apache.cassandra:java-driver-core", - "org.springframework.boot:spring-boot" - ], - "org.springframework.boot:spring-boot-data-cassandra": [ - "org.springframework.boot:spring-boot-cassandra", - "org.springframework.boot:spring-boot-data-commons", - "org.springframework.data:spring-data-cassandra" - ], - "org.springframework.boot:spring-boot-data-cassandra-test": [ - "org.springframework.boot:spring-boot-data-cassandra", - "org.springframework.boot:spring-boot-test-autoconfigure" - ], - "org.springframework.boot:spring-boot-data-commons": [ - "org.springframework.boot:spring-boot", - "org.springframework.boot:spring-boot-persistence", - "org.springframework.data:spring-data-commons" - ], - "org.springframework.boot:spring-boot-health": [ - "org.springframework.boot:spring-boot" - ], - "org.springframework.boot:spring-boot-http-client": [ - "org.springframework.boot:spring-boot", - "org.springframework.boot:spring-boot-http-converter", - "org.springframework:spring-web" - ], - "org.springframework.boot:spring-boot-http-codec": [ - "org.springframework.boot:spring-boot", - "org.springframework:spring-web" - ], - "org.springframework.boot:spring-boot-http-converter": [ - "org.springframework.boot:spring-boot", - "org.springframework:spring-web" - ], - "org.springframework.boot:spring-boot-jackson": [ - "org.springframework.boot:spring-boot", - "tools.jackson.core:jackson-databind" - ], - "org.springframework.boot:spring-boot-micrometer-metrics": [ - "io.micrometer:micrometer-core", - "org.springframework.boot:spring-boot", - "org.springframework.boot:spring-boot-micrometer-observation" - ], - "org.springframework.boot:spring-boot-micrometer-metrics-test": [ - "io.micrometer:micrometer-observation-test", - "org.springframework.boot:spring-boot-micrometer-metrics", - "org.springframework.boot:spring-boot-test-autoconfigure" - ], - "org.springframework.boot:spring-boot-micrometer-observation": [ - "io.micrometer:micrometer-observation", - "org.springframework.boot:spring-boot" - ], - "org.springframework.boot:spring-boot-micrometer-tracing": [ - "io.micrometer:micrometer-tracing", - "org.springframework.boot:spring-boot", - "org.springframework.boot:spring-boot-micrometer-observation" - ], - "org.springframework.boot:spring-boot-micrometer-tracing-opentelemetry": [ - "io.micrometer:micrometer-tracing", - "org.springframework.boot:spring-boot", - "org.springframework.boot:spring-boot-micrometer-observation", - "org.springframework.boot:spring-boot-micrometer-tracing", - "org.springframework.boot:spring-boot-opentelemetry" - ], - "org.springframework.boot:spring-boot-netty": [ - "io.netty:netty-common", - "org.springframework.boot:spring-boot" - ], - "org.springframework.boot:spring-boot-opentelemetry": [ - "io.opentelemetry:opentelemetry-api", - "io.opentelemetry:opentelemetry-sdk", - "org.springframework.boot:spring-boot" - ], - "org.springframework.boot:spring-boot-persistence": [ - "org.springframework.boot:spring-boot", - "org.springframework:spring-tx" - ], - "org.springframework.boot:spring-boot-reactor": [ - "io.projectreactor:reactor-core", - "org.springframework.boot:spring-boot" - ], - "org.springframework.boot:spring-boot-reactor-netty": [ - "io.projectreactor.netty:reactor-netty-http", - "org.springframework.boot:spring-boot-netty", - "org.springframework.boot:spring-boot-web-server", - "org.springframework:spring-web" - ], - "org.springframework.boot:spring-boot-restclient": [ - "org.springframework.boot:spring-boot", - "org.springframework.boot:spring-boot-http-client", - "org.springframework.boot:spring-boot-http-converter" - ], - "org.springframework.boot:spring-boot-resttestclient": [ - "org.springframework.boot:spring-boot-http-converter", - "org.springframework.boot:spring-boot-test", - "org.springframework:spring-web" - ], - "org.springframework.boot:spring-boot-security": [ - "org.springframework.boot:spring-boot", - "org.springframework.security:spring-security-config", - "org.springframework.security:spring-security-web" - ], - "org.springframework.boot:spring-boot-security-oauth2-client": [ - "org.springframework.boot:spring-boot", - "org.springframework.boot:spring-boot-security", - "org.springframework.security:spring-security-oauth2-client" - ], - "org.springframework.boot:spring-boot-security-oauth2-resource-server": [ - "org.springframework.boot:spring-boot", - "org.springframework.boot:spring-boot-security", - "org.springframework.security:spring-security-oauth2-jose", - "org.springframework.security:spring-security-oauth2-resource-server" - ], - "org.springframework.boot:spring-boot-security-test": [ - "org.springframework.boot:spring-boot-security", - "org.springframework.boot:spring-boot-test-autoconfigure", - "org.springframework.security:spring-security-test" - ], - "org.springframework.boot:spring-boot-servlet": [ - "org.springframework.boot:spring-boot", - "org.springframework:spring-web" - ], - "org.springframework.boot:spring-boot-starter": [ - "jakarta.annotation:jakarta.annotation-api", - "org.springframework.boot:spring-boot-autoconfigure", - "org.springframework.boot:spring-boot-starter-logging", - "org.yaml:snakeyaml" - ], - "org.springframework.boot:spring-boot-starter-actuator": [ - "io.micrometer:micrometer-jakarta9", - "io.micrometer:micrometer-observation", - "org.springframework.boot:spring-boot-actuator-autoconfigure", - "org.springframework.boot:spring-boot-health", - "org.springframework.boot:spring-boot-starter", - "org.springframework.boot:spring-boot-starter-micrometer-metrics" - ], - "org.springframework.boot:spring-boot-starter-actuator-test": [ - "org.springframework.boot:spring-boot-starter-actuator", - "org.springframework.boot:spring-boot-starter-micrometer-metrics-test", - "org.springframework.boot:spring-boot-starter-test" - ], - "org.springframework.boot:spring-boot-starter-aspectj": [ - "org.aspectj:aspectjweaver", - "org.springframework.boot:spring-boot-starter", - "org.springframework:spring-aop" - ], - "org.springframework.boot:spring-boot-starter-data-cassandra": [ - "org.springframework.boot:spring-boot-cassandra", - "org.springframework.boot:spring-boot-data-cassandra", - "org.springframework.boot:spring-boot-starter" - ], - "org.springframework.boot:spring-boot-starter-data-cassandra-test": [ - "org.springframework.boot:spring-boot-data-cassandra-test", - "org.springframework.boot:spring-boot-starter-data-cassandra", - "org.springframework.boot:spring-boot-starter-test" - ], - "org.springframework.boot:spring-boot-starter-jackson": [ - "org.springframework.boot:spring-boot-jackson", - "org.springframework.boot:spring-boot-starter" - ], - "org.springframework.boot:spring-boot-starter-jackson-test": [ - "org.springframework.boot:spring-boot-starter-jackson", - "org.springframework.boot:spring-boot-starter-test" - ], - "org.springframework.boot:spring-boot-starter-logging": [ - "ch.qos.logback:logback-classic", - "org.apache.logging.log4j:log4j-to-slf4j", - "org.slf4j:jul-to-slf4j" - ], - "org.springframework.boot:spring-boot-starter-micrometer-metrics": [ - "org.springframework.boot:spring-boot-micrometer-metrics", - "org.springframework.boot:spring-boot-starter" - ], - "org.springframework.boot:spring-boot-starter-micrometer-metrics-test": [ - "org.springframework.boot:spring-boot-micrometer-metrics-test", - "org.springframework.boot:spring-boot-starter-micrometer-metrics", - "org.springframework.boot:spring-boot-starter-test" - ], - "org.springframework.boot:spring-boot-starter-reactor-netty": [ - "org.springframework.boot:spring-boot-reactor", - "org.springframework.boot:spring-boot-reactor-netty", - "org.springframework.boot:spring-boot-starter" - ], - "org.springframework.boot:spring-boot-starter-security": [ - "org.springframework.boot:spring-boot-security", - "org.springframework.boot:spring-boot-starter", - "org.springframework:spring-aop" - ], - "org.springframework.boot:spring-boot-starter-security-oauth2-client": [ - "org.springframework.boot:spring-boot-security-oauth2-client", - "org.springframework.boot:spring-boot-starter", - "org.springframework.boot:spring-boot-starter-security", - "org.springframework.security:spring-security-oauth2-jose" - ], - "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server": [ - "org.springframework.boot:spring-boot-security-oauth2-resource-server", - "org.springframework.boot:spring-boot-starter", - "org.springframework.boot:spring-boot-starter-security" - ], - "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server-test": [ - "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server", - "org.springframework.boot:spring-boot-starter-security-test", - "org.springframework.boot:spring-boot-starter-test" - ], - "org.springframework.boot:spring-boot-starter-security-test": [ - "org.springframework.boot:spring-boot-security-test", - "org.springframework.boot:spring-boot-starter-security", - "org.springframework.boot:spring-boot-starter-test" - ], - "org.springframework.boot:spring-boot-starter-test": [ - "com.jayway.jsonpath:json-path", - "jakarta.xml.bind:jakarta.xml.bind-api", - "net.minidev:json-smart", - "org.assertj:assertj-core", - "org.awaitility:awaitility", - "org.hamcrest:hamcrest", - "org.junit.jupiter:junit-jupiter", - "org.mockito:mockito-core", - "org.mockito:mockito-junit-jupiter", - "org.skyscreamer:jsonassert", - "org.springframework.boot:spring-boot-starter", - "org.springframework.boot:spring-boot-test", - "org.springframework.boot:spring-boot-test-autoconfigure", - "org.springframework:spring-core", - "org.springframework:spring-test", - "org.xmlunit:xmlunit-core" - ], - "org.springframework.boot:spring-boot-starter-tomcat": [ - "org.springframework.boot:spring-boot-starter", - "org.springframework.boot:spring-boot-starter-tomcat-runtime", - "org.springframework.boot:spring-boot-tomcat" - ], - "org.springframework.boot:spring-boot-starter-tomcat-runtime": [ - "jakarta.annotation:jakarta.annotation-api", - "org.apache.tomcat.embed:tomcat-embed-core", - "org.apache.tomcat.embed:tomcat-embed-el", - "org.apache.tomcat.embed:tomcat-embed-websocket", - "org.springframework.boot:spring-boot-tomcat", - "org.springframework.boot:spring-boot-web-server" - ], - "org.springframework.boot:spring-boot-starter-validation": [ - "org.springframework.boot:spring-boot-starter", - "org.springframework.boot:spring-boot-validation" - ], - "org.springframework.boot:spring-boot-starter-webflux": [ - "org.springframework.boot:spring-boot-reactor", - "org.springframework.boot:spring-boot-starter", - "org.springframework.boot:spring-boot-starter-jackson", - "org.springframework.boot:spring-boot-starter-reactor-netty", - "org.springframework.boot:spring-boot-webflux" - ], - "org.springframework.boot:spring-boot-starter-webflux-test": [ - "io.projectreactor:reactor-test", - "org.springframework.boot:spring-boot-starter-jackson-test", - "org.springframework.boot:spring-boot-starter-test", - "org.springframework.boot:spring-boot-starter-webflux", - "org.springframework.boot:spring-boot-webflux-test", - "org.springframework.boot:spring-boot-webtestclient" - ], - "org.springframework.boot:spring-boot-starter-webmvc": [ - "org.springframework.boot:spring-boot-http-converter", - "org.springframework.boot:spring-boot-starter", - "org.springframework.boot:spring-boot-starter-jackson", - "org.springframework.boot:spring-boot-starter-tomcat", - "org.springframework.boot:spring-boot-webmvc" - ], - "org.springframework.boot:spring-boot-starter-webmvc-test": [ - "org.springframework.boot:spring-boot-resttestclient", - "org.springframework.boot:spring-boot-starter-jackson-test", - "org.springframework.boot:spring-boot-starter-test", - "org.springframework.boot:spring-boot-starter-webmvc", - "org.springframework.boot:spring-boot-webmvc-test" - ], - "org.springframework.boot:spring-boot-test": [ - "org.springframework.boot:spring-boot", - "org.springframework:spring-test" - ], - "org.springframework.boot:spring-boot-test-autoconfigure": [ - "org.springframework.boot:spring-boot-test" - ], - "org.springframework.boot:spring-boot-tomcat": [ - "jakarta.annotation:jakarta.annotation-api", - "org.apache.tomcat.embed:tomcat-embed-core", - "org.springframework.boot:spring-boot-web-server" - ], - "org.springframework.boot:spring-boot-validation": [ - "org.apache.tomcat.embed:tomcat-embed-el", - "org.hibernate.validator:hibernate-validator", - "org.springframework.boot:spring-boot" - ], - "org.springframework.boot:spring-boot-web-server": [ - "org.springframework.boot:spring-boot", - "org.springframework:spring-web" - ], - "org.springframework.boot:spring-boot-webclient": [ - "org.springframework.boot:spring-boot", - "org.springframework.boot:spring-boot-http-client", - "org.springframework.boot:spring-boot-http-codec", - "org.springframework:spring-webflux" - ], - "org.springframework.boot:spring-boot-webflux": [ - "org.springframework.boot:spring-boot", - "org.springframework.boot:spring-boot-http-codec", - "org.springframework.boot:spring-boot-web-server", - "org.springframework:spring-webflux" - ], - "org.springframework.boot:spring-boot-webflux-test": [ - "org.springframework.boot:spring-boot-test-autoconfigure", - "org.springframework.boot:spring-boot-webflux", - "org.springframework.boot:spring-boot-webtestclient" - ], - "org.springframework.boot:spring-boot-webmvc": [ - "org.springframework.boot:spring-boot-http-converter", - "org.springframework.boot:spring-boot-servlet", - "org.springframework:spring-web", - "org.springframework:spring-webmvc" - ], - "org.springframework.boot:spring-boot-webmvc-test": [ - "org.springframework.boot:spring-boot-http-converter", - "org.springframework.boot:spring-boot-test-autoconfigure", - "org.springframework.boot:spring-boot-web-server", - "org.springframework.boot:spring-boot-webmvc" - ], - "org.springframework.boot:spring-boot-webtestclient": [ - "org.springframework.boot:spring-boot-http-codec", - "org.springframework.boot:spring-boot-test", - "org.springframework:spring-webflux" - ], - "org.springframework.cloud:spring-cloud-commons": [ - "org.springframework.security:spring-security-crypto" - ], - "org.springframework.cloud:spring-cloud-context": [ - "org.springframework.security:spring-security-crypto" - ], - "org.springframework.cloud:spring-cloud-kubernetes-client-autoconfig": [ - "io.kubernetes:client-java", - "io.kubernetes:client-java-extended", - "org.springframework.boot:spring-boot-autoconfigure", - "org.springframework.cloud:spring-cloud-kubernetes-commons" - ], - "org.springframework.cloud:spring-cloud-kubernetes-client-config": [ - "io.kubernetes:client-java", - "io.kubernetes:client-java-extended", - "org.springframework.boot:spring-boot-autoconfigure", - "org.springframework.cloud:spring-cloud-kubernetes-client-autoconfig", - "org.springframework.cloud:spring-cloud-kubernetes-commons", - "org.springframework.cloud:spring-cloud-starter" - ], - "org.springframework.cloud:spring-cloud-kubernetes-commons": [ - "jakarta.annotation:jakarta.annotation-api", - "org.springframework.boot:spring-boot-autoconfigure", - "org.springframework.cloud:spring-cloud-commons", - "org.springframework.cloud:spring-cloud-context" - ], - "org.springframework.cloud:spring-cloud-starter": [ - "org.bouncycastle:bcprov-jdk18on", - "org.springframework.boot:spring-boot-starter", - "org.springframework.cloud:spring-cloud-commons", - "org.springframework.cloud:spring-cloud-context" - ], - "org.springframework.cloud:spring-cloud-starter-bootstrap": [ - "org.springframework.cloud:spring-cloud-starter" - ], - "org.springframework.cloud:spring-cloud-starter-kubernetes-client-config": [ - "org.springframework.cloud:spring-cloud-kubernetes-client-config" - ], - "org.springframework.data:spring-data-cassandra": [ - "org.apache.cassandra:java-driver-core", - "org.apache.cassandra:java-driver-query-builder", - "org.slf4j:slf4j-api", - "org.springframework.data:spring-data-commons", - "org.springframework:spring-beans", - "org.springframework:spring-context", - "org.springframework:spring-core", - "org.springframework:spring-expression", - "org.springframework:spring-tx" - ], - "org.springframework.data:spring-data-commons": [ - "org.slf4j:slf4j-api", - "org.springframework:spring-beans", - "org.springframework:spring-core" - ], - "org.springframework.security:spring-security-config": [ - "org.springframework.security:spring-security-core", - "org.springframework:spring-aop", - "org.springframework:spring-beans", - "org.springframework:spring-context", - "org.springframework:spring-core" - ], - "org.springframework.security:spring-security-core": [ - "io.micrometer:micrometer-observation", - "org.springframework.security:spring-security-crypto", - "org.springframework:spring-aop", - "org.springframework:spring-beans", - "org.springframework:spring-context", - "org.springframework:spring-core", - "org.springframework:spring-expression" - ], - "org.springframework.security:spring-security-oauth2-client": [ - "com.nimbusds:oauth2-oidc-sdk", - "org.springframework.security:spring-security-core", - "org.springframework.security:spring-security-oauth2-core", - "org.springframework.security:spring-security-web", - "org.springframework:spring-core" - ], - "org.springframework.security:spring-security-oauth2-core": [ - "org.springframework.security:spring-security-core", - "org.springframework:spring-core", - "org.springframework:spring-web" - ], - "org.springframework.security:spring-security-oauth2-jose": [ - "com.nimbusds:nimbus-jose-jwt", - "org.springframework.security:spring-security-core", - "org.springframework.security:spring-security-oauth2-core", - "org.springframework:spring-core" - ], - "org.springframework.security:spring-security-oauth2-resource-server": [ - "org.springframework.security:spring-security-core", - "org.springframework.security:spring-security-oauth2-core", - "org.springframework.security:spring-security-web", - "org.springframework:spring-core" - ], - "org.springframework.security:spring-security-test": [ - "org.springframework.security:spring-security-core", - "org.springframework.security:spring-security-web", - "org.springframework:spring-core", - "org.springframework:spring-test" - ], - "org.springframework.security:spring-security-web": [ - "org.springframework.security:spring-security-core", - "org.springframework:spring-aop", - "org.springframework:spring-beans", - "org.springframework:spring-context", - "org.springframework:spring-core", - "org.springframework:spring-expression", - "org.springframework:spring-web" - ], - "org.springframework:spring-aop": [ - "org.springframework:spring-beans", - "org.springframework:spring-core" - ], - "org.springframework:spring-beans": [ - "org.springframework:spring-core" - ], - "org.springframework:spring-context": [ - "io.micrometer:micrometer-observation", - "org.springframework:spring-aop", - "org.springframework:spring-beans", - "org.springframework:spring-core", - "org.springframework:spring-expression" - ], - "org.springframework:spring-context-support": [ - "org.springframework:spring-beans", - "org.springframework:spring-context", - "org.springframework:spring-core" - ], - "org.springframework:spring-core": [ - "commons-logging:commons-logging", - "org.jspecify:jspecify" - ], - "org.springframework:spring-expression": [ - "org.springframework:spring-core" - ], - "org.springframework:spring-test": [ - "org.springframework:spring-core" - ], - "org.springframework:spring-tx": [ - "org.springframework:spring-beans", - "org.springframework:spring-core" - ], - "org.springframework:spring-web": [ - "io.micrometer:micrometer-observation", - "org.springframework:spring-beans", - "org.springframework:spring-core" - ], - "org.springframework:spring-webflux": [ - "io.projectreactor:reactor-core", - "org.springframework:spring-beans", - "org.springframework:spring-core", - "org.springframework:spring-web" - ], - "org.springframework:spring-webmvc": [ - "org.springframework:spring-aop", - "org.springframework:spring-beans", - "org.springframework:spring-context", - "org.springframework:spring-core", - "org.springframework:spring-expression", - "org.springframework:spring-web" - ], - "org.testcontainers:testcontainers": [ - "com.github.docker-java:docker-java-api", - "com.github.docker-java:docker-java-transport-zerodep", - "org.apache.commons:commons-compress", - "org.rnorth.duct-tape:duct-tape", - "org.slf4j:slf4j-api" - ], - "org.testcontainers:testcontainers-cassandra": [ - "com.datastax.cassandra:cassandra-driver-core", - "org.testcontainers:testcontainers-database-commons" - ], - "org.testcontainers:testcontainers-database-commons": [ - "org.testcontainers:testcontainers" - ], - "org.testcontainers:testcontainers-junit-jupiter": [ - "org.testcontainers:testcontainers" - ], - "org.testcontainers:testcontainers-localstack": [ - "org.testcontainers:testcontainers" - ], - "org.xmlunit:xmlunit-core": [ - "jakarta.xml.bind:jakarta.xml.bind-api" - ], - "software.amazon.awssdk:checksums": [ - "software.amazon.awssdk:annotations", - "software.amazon.awssdk:checksums-spi", - "software.amazon.awssdk:utils" - ], - "software.amazon.awssdk:checksums-spi": [ - "software.amazon.awssdk:annotations" - ], - "software.amazon.awssdk:endpoints-spi": [ - "software.amazon.awssdk:annotations" - ], - "software.amazon.awssdk:http-auth-aws": [ - "software.amazon.awssdk:annotations", - "software.amazon.awssdk:checksums", - "software.amazon.awssdk:checksums-spi", - "software.amazon.awssdk:http-auth-spi", - "software.amazon.awssdk:http-client-spi", - "software.amazon.awssdk:identity-spi", - "software.amazon.awssdk:utils" - ], - "software.amazon.awssdk:http-auth-spi": [ - "org.reactivestreams:reactive-streams", - "software.amazon.awssdk:annotations", - "software.amazon.awssdk:checksums-spi", - "software.amazon.awssdk:http-client-spi", - "software.amazon.awssdk:identity-spi", - "software.amazon.awssdk:utils" - ], - "software.amazon.awssdk:http-client-spi": [ - "org.reactivestreams:reactive-streams", - "software.amazon.awssdk:annotations", - "software.amazon.awssdk:metrics-spi", - "software.amazon.awssdk:utils" - ], - "software.amazon.awssdk:identity-spi": [ - "software.amazon.awssdk:annotations", - "software.amazon.awssdk:utils" - ], - "software.amazon.awssdk:json-utils": [ - "software.amazon.awssdk:annotations", - "software.amazon.awssdk:third-party-jackson-core", - "software.amazon.awssdk:utils" - ], - "software.amazon.awssdk:metrics-spi": [ - "software.amazon.awssdk:annotations", - "software.amazon.awssdk:utils" - ], - "software.amazon.awssdk:profiles": [ - "software.amazon.awssdk:annotations", - "software.amazon.awssdk:utils" - ], - "software.amazon.awssdk:regions": [ - "org.slf4j:slf4j-api", - "software.amazon.awssdk:annotations", - "software.amazon.awssdk:json-utils", - "software.amazon.awssdk:profiles", - "software.amazon.awssdk:sdk-core", - "software.amazon.awssdk:utils" - ], - "software.amazon.awssdk:retries": [ - "software.amazon.awssdk:annotations", - "software.amazon.awssdk:retries-spi", - "software.amazon.awssdk:utils" - ], - "software.amazon.awssdk:retries-spi": [ - "software.amazon.awssdk:annotations", - "software.amazon.awssdk:utils" - ], - "software.amazon.awssdk:sdk-core": [ - "org.reactivestreams:reactive-streams", - "org.slf4j:slf4j-api", - "software.amazon.awssdk:annotations", - "software.amazon.awssdk:checksums", - "software.amazon.awssdk:checksums-spi", - "software.amazon.awssdk:endpoints-spi", - "software.amazon.awssdk:http-auth-aws", - "software.amazon.awssdk:http-auth-spi", - "software.amazon.awssdk:http-client-spi", - "software.amazon.awssdk:identity-spi", - "software.amazon.awssdk:metrics-spi", - "software.amazon.awssdk:profiles", - "software.amazon.awssdk:retries", - "software.amazon.awssdk:retries-spi", - "software.amazon.awssdk:utils" - ], - "software.amazon.awssdk:utils": [ - "org.reactivestreams:reactive-streams", - "org.slf4j:slf4j-api", - "software.amazon.awssdk:annotations" - ], - "tools.jackson.core:jackson-databind": [ - "com.fasterxml.jackson.core:jackson-annotations", - "tools.jackson.core:jackson-core" - ], - "tools.jackson.module:jackson-module-blackbird": [ - "tools.jackson.core:jackson-core", - "tools.jackson.core:jackson-databind" - ] - }, - "packages": { - "args4j:args4j": [ - "org.kohsuke.args4j", - "org.kohsuke.args4j.spi" - ], - "at.yawk.lz4:lz4-java": [ - "net.jpountz.lz4", - "net.jpountz.util", - "net.jpountz.xxhash" - ], - "ch.qos.logback:logback-classic": [ - "ch.qos.logback.classic", - "ch.qos.logback.classic.boolex", - "ch.qos.logback.classic.encoder", - "ch.qos.logback.classic.filter", - "ch.qos.logback.classic.helpers", - "ch.qos.logback.classic.html", - "ch.qos.logback.classic.joran", - "ch.qos.logback.classic.joran.action", - "ch.qos.logback.classic.joran.sanity", - "ch.qos.logback.classic.joran.serializedModel", - "ch.qos.logback.classic.jul", - "ch.qos.logback.classic.layout", - "ch.qos.logback.classic.log4j", - "ch.qos.logback.classic.model", - "ch.qos.logback.classic.model.processor", - "ch.qos.logback.classic.model.util", - "ch.qos.logback.classic.net", - "ch.qos.logback.classic.net.server", - "ch.qos.logback.classic.pattern", - "ch.qos.logback.classic.pattern.color", - "ch.qos.logback.classic.selector", - "ch.qos.logback.classic.selector.servlet", - "ch.qos.logback.classic.servlet", - "ch.qos.logback.classic.sift", - "ch.qos.logback.classic.spi", - "ch.qos.logback.classic.turbo", - "ch.qos.logback.classic.tyler", - "ch.qos.logback.classic.util" - ], - "ch.qos.logback:logback-core": [ - "ch.qos.logback.core", - "ch.qos.logback.core.boolex", - "ch.qos.logback.core.encoder", - "ch.qos.logback.core.filter", - "ch.qos.logback.core.helpers", - "ch.qos.logback.core.hook", - "ch.qos.logback.core.html", - "ch.qos.logback.core.joran", - "ch.qos.logback.core.joran.action", - "ch.qos.logback.core.joran.conditional", - "ch.qos.logback.core.joran.event", - "ch.qos.logback.core.joran.sanity", - "ch.qos.logback.core.joran.spi", - "ch.qos.logback.core.joran.util", - "ch.qos.logback.core.joran.util.beans", - "ch.qos.logback.core.layout", - "ch.qos.logback.core.model", - "ch.qos.logback.core.model.conditional", - "ch.qos.logback.core.model.processor", - "ch.qos.logback.core.model.processor.conditional", - "ch.qos.logback.core.model.util", - "ch.qos.logback.core.net", - "ch.qos.logback.core.net.ssl", - "ch.qos.logback.core.pattern", - "ch.qos.logback.core.pattern.color", - "ch.qos.logback.core.pattern.parser", - "ch.qos.logback.core.pattern.util", - "ch.qos.logback.core.property", - "ch.qos.logback.core.read", - "ch.qos.logback.core.recovery", - "ch.qos.logback.core.rolling", - "ch.qos.logback.core.rolling.helper", - "ch.qos.logback.core.sift", - "ch.qos.logback.core.spi", - "ch.qos.logback.core.status", - "ch.qos.logback.core.subst", - "ch.qos.logback.core.testUtil", - "ch.qos.logback.core.util" - ], - "com.bucket4j:bucket4j-core": [ - "io.github.bucket4j", - "io.github.bucket4j.distributed", - "io.github.bucket4j.distributed.expiration", - "io.github.bucket4j.distributed.jdbc", - "io.github.bucket4j.distributed.proxy", - "io.github.bucket4j.distributed.proxy.generic.compare_and_swap", - "io.github.bucket4j.distributed.proxy.generic.pessimistic_locking", - "io.github.bucket4j.distributed.proxy.generic.select_for_update", - "io.github.bucket4j.distributed.proxy.optimization", - "io.github.bucket4j.distributed.proxy.optimization.batch", - "io.github.bucket4j.distributed.proxy.optimization.delay", - "io.github.bucket4j.distributed.proxy.optimization.manual", - "io.github.bucket4j.distributed.proxy.optimization.predictive", - "io.github.bucket4j.distributed.proxy.optimization.skiponzero", - "io.github.bucket4j.distributed.remote", - "io.github.bucket4j.distributed.remote.commands", - "io.github.bucket4j.distributed.serialization", - "io.github.bucket4j.distributed.versioning", - "io.github.bucket4j.local", - "io.github.bucket4j.util", - "io.github.bucket4j.util.concurrent.batch" - ], - "com.bucket4j:bucket4j_jdk17-core": [ - "io.github.bucket4j", - "io.github.bucket4j.distributed", - "io.github.bucket4j.distributed.expiration", - "io.github.bucket4j.distributed.jdbc", - "io.github.bucket4j.distributed.proxy", - "io.github.bucket4j.distributed.proxy.generic.compare_and_swap", - "io.github.bucket4j.distributed.proxy.generic.pessimistic_locking", - "io.github.bucket4j.distributed.proxy.generic.select_for_update", - "io.github.bucket4j.distributed.proxy.optimization", - "io.github.bucket4j.distributed.proxy.optimization.batch", - "io.github.bucket4j.distributed.proxy.optimization.delay", - "io.github.bucket4j.distributed.proxy.optimization.manual", - "io.github.bucket4j.distributed.proxy.optimization.predictive", - "io.github.bucket4j.distributed.proxy.optimization.skiponzero", - "io.github.bucket4j.distributed.remote", - "io.github.bucket4j.distributed.remote.commands", - "io.github.bucket4j.distributed.serialization", - "io.github.bucket4j.distributed.versioning", - "io.github.bucket4j.local", - "io.github.bucket4j.util", - "io.github.bucket4j.util.concurrent.batch" - ], - "com.datastax.cassandra:cassandra-driver-core": [ - "com.datastax.driver.core", - "com.datastax.driver.core.exceptions", - "com.datastax.driver.core.policies", - "com.datastax.driver.core.querybuilder", - "com.datastax.driver.core.schemabuilder", - "com.datastax.driver.core.utils" - ], - "com.datastax.oss:native-protocol": [ - "com.datastax.dse.protocol.internal", - "com.datastax.dse.protocol.internal.request", - "com.datastax.dse.protocol.internal.request.query", - "com.datastax.dse.protocol.internal.response.result", - "com.datastax.oss.protocol.internal", - "com.datastax.oss.protocol.internal.request", - "com.datastax.oss.protocol.internal.request.query", - "com.datastax.oss.protocol.internal.response", - "com.datastax.oss.protocol.internal.response.error", - "com.datastax.oss.protocol.internal.response.event", - "com.datastax.oss.protocol.internal.response.result", - "com.datastax.oss.protocol.internal.util", - "com.datastax.oss.protocol.internal.util.collection" - ], - "com.fasterxml.jackson.core:jackson-annotations": [ - "com.fasterxml.jackson.annotation" - ], - "com.fasterxml.jackson.core:jackson-core": [ - "com.fasterxml.jackson.core", - "com.fasterxml.jackson.core.async", - "com.fasterxml.jackson.core.base", - "com.fasterxml.jackson.core.exc", - "com.fasterxml.jackson.core.filter", - "com.fasterxml.jackson.core.format", - "com.fasterxml.jackson.core.internal.shaded.fdp.v2_21_4", - "com.fasterxml.jackson.core.internal.shaded.fdp.v2_21_4.bte", - "com.fasterxml.jackson.core.internal.shaded.fdp.v2_21_4.chr", - "com.fasterxml.jackson.core.io", - "com.fasterxml.jackson.core.io.schubfach", - "com.fasterxml.jackson.core.json", - "com.fasterxml.jackson.core.json.async", - "com.fasterxml.jackson.core.sym", - "com.fasterxml.jackson.core.type", - "com.fasterxml.jackson.core.util" - ], - "com.fasterxml.jackson.core:jackson-databind": [ - "com.fasterxml.jackson.databind", - "com.fasterxml.jackson.databind.annotation", - "com.fasterxml.jackson.databind.cfg", - "com.fasterxml.jackson.databind.deser", - "com.fasterxml.jackson.databind.deser.impl", - "com.fasterxml.jackson.databind.deser.std", - "com.fasterxml.jackson.databind.exc", - "com.fasterxml.jackson.databind.ext", - "com.fasterxml.jackson.databind.introspect", - "com.fasterxml.jackson.databind.jdk14", - "com.fasterxml.jackson.databind.json", - "com.fasterxml.jackson.databind.jsonFormatVisitors", - "com.fasterxml.jackson.databind.jsonschema", - "com.fasterxml.jackson.databind.jsontype", - "com.fasterxml.jackson.databind.jsontype.impl", - "com.fasterxml.jackson.databind.module", - "com.fasterxml.jackson.databind.node", - "com.fasterxml.jackson.databind.ser", - "com.fasterxml.jackson.databind.ser.impl", - "com.fasterxml.jackson.databind.ser.std", - "com.fasterxml.jackson.databind.type", - "com.fasterxml.jackson.databind.util", - "com.fasterxml.jackson.databind.util.internal" - ], - "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml": [ - "com.fasterxml.jackson.dataformat.yaml", - "com.fasterxml.jackson.dataformat.yaml.snakeyaml.error", - "com.fasterxml.jackson.dataformat.yaml.util" - ], - "com.fasterxml.jackson.datatype:jackson-datatype-jsr310": [ - "com.fasterxml.jackson.datatype.jsr310", - "com.fasterxml.jackson.datatype.jsr310.deser", - "com.fasterxml.jackson.datatype.jsr310.deser.key", - "com.fasterxml.jackson.datatype.jsr310.ser", - "com.fasterxml.jackson.datatype.jsr310.ser.key", - "com.fasterxml.jackson.datatype.jsr310.util" - ], - "com.fasterxml:classmate": [ - "com.fasterxml.classmate", - "com.fasterxml.classmate.members", - "com.fasterxml.classmate.types", - "com.fasterxml.classmate.util" - ], - "com.github.ben-manes.caffeine:caffeine": [ - "com.github.benmanes.caffeine.cache", - "com.github.benmanes.caffeine.cache.stats" - ], - "com.github.ben-manes.caffeine:guava": [ - "com.github.benmanes.caffeine.guava" - ], - "com.github.docker-java:docker-java-api": [ - "com.github.dockerjava.api", - "com.github.dockerjava.api.async", - "com.github.dockerjava.api.command", - "com.github.dockerjava.api.exception", - "com.github.dockerjava.api.model" - ], - "com.github.docker-java:docker-java-transport": [ - "com.github.dockerjava.transport" - ], - "com.github.docker-java:docker-java-transport-zerodep": [ - "com.github.dockerjava.zerodep", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.async", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.async.methods", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.auth", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.classic", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.classic.methods", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.config", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.cookie", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.entity", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.entity.mime", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.impl", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.impl.async", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.impl.auth", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.impl.classic", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.impl.compat", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.impl.cookie", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.impl.io", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.impl.nio", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.impl.routing", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.io", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.nio", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.protocol", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.psl", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.routing", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.socket", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.ssl", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.utils", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.validator", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.annotation", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.concurrent", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.function", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.config", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.impl", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.impl.bootstrap", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.impl.io", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.impl.nio", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.impl.routing", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.io", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.io.entity", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.io.ssl", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.io.support", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.message", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.nio", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.nio.command", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.nio.entity", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.nio.ssl", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.nio.support", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.nio.support.classic", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.protocol", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.ssl", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.support", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http2", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http2.config", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http2.frame", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http2.hpack", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http2.impl", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http2.impl.io", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http2.impl.nio", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http2.impl.nio.bootstrap", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http2.nio", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http2.nio.command", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http2.nio.pool", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http2.nio.support", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http2.protocol", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http2.ssl", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.io", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.net", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.pool", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.reactor", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.reactor.ssl", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.ssl", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.util" - ], - "com.github.java-json-tools:btf": [ - "com.github.fge" - ], - "com.github.java-json-tools:jackson-coreutils": [ - "com.github.fge.jackson", - "com.github.fge.jackson.jsonpointer" - ], - "com.github.java-json-tools:json-patch": [ - "com.github.fge.jsonpatch", - "com.github.fge.jsonpatch.diff", - "com.github.fge.jsonpatch.mergepatch" - ], - "com.github.java-json-tools:msg-simple": [ - "com.github.fge.msgsimple", - "com.github.fge.msgsimple.bundle", - "com.github.fge.msgsimple.load", - "com.github.fge.msgsimple.locale", - "com.github.fge.msgsimple.provider", - "com.github.fge.msgsimple.source" - ], - "com.github.jnr:jffi": [ - "com.kenai.jffi", - "com.kenai.jffi.internal" - ], - "com.github.jnr:jnr-constants": [ - "jnr.constants", - "jnr.constants.platform", - "jnr.constants.platform.aix", - "jnr.constants.platform.darwin", - "jnr.constants.platform.dragonflybsd", - "jnr.constants.platform.fake", - "jnr.constants.platform.freebsd", - "jnr.constants.platform.freebsd.aarch64", - "jnr.constants.platform.linux", - "jnr.constants.platform.linux.aarch64", - "jnr.constants.platform.linux.loongarch64", - "jnr.constants.platform.linux.mips64el", - "jnr.constants.platform.linux.powerpc64", - "jnr.constants.platform.linux.s390x", - "jnr.constants.platform.openbsd", - "jnr.constants.platform.solaris", - "jnr.constants.platform.windows" - ], - "com.github.jnr:jnr-ffi": [ - "jnr.ffi", - "jnr.ffi.annotations", - "jnr.ffi.byref", - "jnr.ffi.mapper", - "jnr.ffi.provider", - "jnr.ffi.provider.converters", - "jnr.ffi.provider.jffi", - "jnr.ffi.provider.jffi.platform.aarch64.linux", - "jnr.ffi.provider.jffi.platform.arm.linux", - "jnr.ffi.provider.jffi.platform.i386.darwin", - "jnr.ffi.provider.jffi.platform.i386.freebsd", - "jnr.ffi.provider.jffi.platform.i386.linux", - "jnr.ffi.provider.jffi.platform.i386.openbsd", - "jnr.ffi.provider.jffi.platform.i386.solaris", - "jnr.ffi.provider.jffi.platform.i386.windows", - "jnr.ffi.provider.jffi.platform.mips.linux", - "jnr.ffi.provider.jffi.platform.mipsel.linux", - "jnr.ffi.provider.jffi.platform.ppc.aix", - "jnr.ffi.provider.jffi.platform.ppc.darwin", - "jnr.ffi.provider.jffi.platform.ppc.linux", - "jnr.ffi.provider.jffi.platform.ppc64.linux", - "jnr.ffi.provider.jffi.platform.ppc64le.linux", - "jnr.ffi.provider.jffi.platform.s390.linux", - "jnr.ffi.provider.jffi.platform.s390x.linux", - "jnr.ffi.provider.jffi.platform.sparc.solaris", - "jnr.ffi.provider.jffi.platform.sparcv9.linux", - "jnr.ffi.provider.jffi.platform.sparcv9.solaris", - "jnr.ffi.provider.jffi.platform.x86_64.darwin", - "jnr.ffi.provider.jffi.platform.x86_64.freebsd", - "jnr.ffi.provider.jffi.platform.x86_64.linux", - "jnr.ffi.provider.jffi.platform.x86_64.openbsd", - "jnr.ffi.provider.jffi.platform.x86_64.solaris", - "jnr.ffi.provider.jffi.platform.x86_64.windows", - "jnr.ffi.types", - "jnr.ffi.util", - "jnr.ffi.util.ref", - "jnr.ffi.util.ref.internal" - ], - "com.github.jnr:jnr-posix": [ - "jnr.posix", - "jnr.posix.util", - "jnr.posix.windows" - ], - "com.github.jnr:jnr-x86asm": [ - "com.kenai.jnr.x86asm", - "jnr.x86asm" - ], - "com.github.stephenc.jcip:jcip-annotations": [ - "net.jcip.annotations" - ], - "com.google.android:annotations": [ - "android.annotation" - ], - "com.google.api.grpc:proto-google-common-protos": [ - "com.google.api", - "com.google.cloud", - "com.google.cloud.audit", - "com.google.cloud.location", - "com.google.geo.type", - "com.google.logging.type", - "com.google.longrunning", - "com.google.rpc", - "com.google.rpc.context", - "com.google.type" - ], - "com.google.code.findbugs:jsr305": [ - "javax.annotation", - "javax.annotation.concurrent", - "javax.annotation.meta" - ], - "com.google.code.gson:gson": [ - "com.google.gson", - "com.google.gson.annotations", - "com.google.gson.internal", - "com.google.gson.internal.bind", - "com.google.gson.internal.bind.util", - "com.google.gson.internal.reflect", - "com.google.gson.internal.sql", - "com.google.gson.reflect", - "com.google.gson.stream" - ], - "com.google.errorprone:error_prone_annotations": [ - "com.google.errorprone.annotations", - "com.google.errorprone.annotations.concurrent" - ], - "com.google.guava:failureaccess": [ - "com.google.common.util.concurrent.internal" - ], - "com.google.guava:guava": [ - "com.google.common.annotations", - "com.google.common.base", - "com.google.common.base.internal", - "com.google.common.cache", - "com.google.common.collect", - "com.google.common.escape", - "com.google.common.eventbus", - "com.google.common.graph", - "com.google.common.hash", - "com.google.common.html", - "com.google.common.io", - "com.google.common.math", - "com.google.common.net", - "com.google.common.primitives", - "com.google.common.reflect", - "com.google.common.util.concurrent", - "com.google.common.xml", - "com.google.thirdparty.publicsuffix" - ], - "com.google.j2objc:j2objc-annotations": [ - "com.google.j2objc.annotations" - ], - "com.google.protobuf:protobuf-java": [ - "com.google.protobuf", - "com.google.protobuf.compiler" - ], - "com.google.protobuf:protobuf-java-util": [ - "com.google.protobuf.util" - ], - "com.jayway.jsonpath:json-path": [ - "com.jayway.jsonpath", - "com.jayway.jsonpath.internal", - "com.jayway.jsonpath.internal.filter", - "com.jayway.jsonpath.internal.function", - "com.jayway.jsonpath.internal.function.json", - "com.jayway.jsonpath.internal.function.latebinding", - "com.jayway.jsonpath.internal.function.numeric", - "com.jayway.jsonpath.internal.function.sequence", - "com.jayway.jsonpath.internal.function.text", - "com.jayway.jsonpath.internal.path", - "com.jayway.jsonpath.spi.cache", - "com.jayway.jsonpath.spi.json", - "com.jayway.jsonpath.spi.mapper" - ], - "com.nimbusds:content-type": [ - "com.nimbusds.common.contenttype" - ], - "com.nimbusds:lang-tag": [ - "com.nimbusds.langtag" - ], - "com.nimbusds:nimbus-jose-jwt": [ - "com.nimbusds.jose", - "com.nimbusds.jose.crypto", - "com.nimbusds.jose.crypto.bc", - "com.nimbusds.jose.crypto.factories", - "com.nimbusds.jose.crypto.impl", - "com.nimbusds.jose.crypto.opts", - "com.nimbusds.jose.crypto.utils", - "com.nimbusds.jose.jca", - "com.nimbusds.jose.jwk", - "com.nimbusds.jose.jwk.gen", - "com.nimbusds.jose.jwk.source", - "com.nimbusds.jose.mint", - "com.nimbusds.jose.proc", - "com.nimbusds.jose.produce", - "com.nimbusds.jose.shaded.gson", - "com.nimbusds.jose.shaded.gson.annotations", - "com.nimbusds.jose.shaded.gson.internal", - "com.nimbusds.jose.shaded.gson.internal.bind", - "com.nimbusds.jose.shaded.gson.internal.bind.util", - "com.nimbusds.jose.shaded.gson.internal.reflect", - "com.nimbusds.jose.shaded.gson.internal.sql", - "com.nimbusds.jose.shaded.gson.reflect", - "com.nimbusds.jose.shaded.gson.stream", - "com.nimbusds.jose.shaded.jcip", - "com.nimbusds.jose.util", - "com.nimbusds.jose.util.cache", - "com.nimbusds.jose.util.events", - "com.nimbusds.jose.util.health", - "com.nimbusds.jwt", - "com.nimbusds.jwt.proc", - "com.nimbusds.jwt.util" - ], - "com.nimbusds:oauth2-oidc-sdk": [ - "com.nimbusds.oauth2.sdk", - "com.nimbusds.oauth2.sdk.as", - "com.nimbusds.oauth2.sdk.assertions", - "com.nimbusds.oauth2.sdk.assertions.jwt", - "com.nimbusds.oauth2.sdk.assertions.saml2", - "com.nimbusds.oauth2.sdk.auth", - "com.nimbusds.oauth2.sdk.auth.verifier", - "com.nimbusds.oauth2.sdk.ciba", - "com.nimbusds.oauth2.sdk.client", - "com.nimbusds.oauth2.sdk.cnf", - "com.nimbusds.oauth2.sdk.device", - "com.nimbusds.oauth2.sdk.dpop", - "com.nimbusds.oauth2.sdk.dpop.verifiers", - "com.nimbusds.oauth2.sdk.http", - "com.nimbusds.oauth2.sdk.id", - "com.nimbusds.oauth2.sdk.jarm", - "com.nimbusds.oauth2.sdk.jose", - "com.nimbusds.oauth2.sdk.pkce", - "com.nimbusds.oauth2.sdk.rar", - "com.nimbusds.oauth2.sdk.token", - "com.nimbusds.oauth2.sdk.tokenexchange", - "com.nimbusds.oauth2.sdk.util", - "com.nimbusds.oauth2.sdk.util.date", - "com.nimbusds.oauth2.sdk.util.singleuse", - "com.nimbusds.oauth2.sdk.util.tls", - "com.nimbusds.openid.connect.sdk", - "com.nimbusds.openid.connect.sdk.assurance", - "com.nimbusds.openid.connect.sdk.assurance.claims", - "com.nimbusds.openid.connect.sdk.assurance.evidences", - "com.nimbusds.openid.connect.sdk.assurance.evidences.attachment", - "com.nimbusds.openid.connect.sdk.assurance.request", - "com.nimbusds.openid.connect.sdk.claims", - "com.nimbusds.openid.connect.sdk.federation", - "com.nimbusds.openid.connect.sdk.federation.api", - "com.nimbusds.openid.connect.sdk.federation.config", - "com.nimbusds.openid.connect.sdk.federation.entities", - "com.nimbusds.openid.connect.sdk.federation.policy", - "com.nimbusds.openid.connect.sdk.federation.policy.language", - "com.nimbusds.openid.connect.sdk.federation.policy.operations", - "com.nimbusds.openid.connect.sdk.federation.registration", - "com.nimbusds.openid.connect.sdk.federation.trust", - "com.nimbusds.openid.connect.sdk.federation.trust.constraints", - "com.nimbusds.openid.connect.sdk.federation.trust.marks", - "com.nimbusds.openid.connect.sdk.federation.utils", - "com.nimbusds.openid.connect.sdk.id", - "com.nimbusds.openid.connect.sdk.nativesso", - "com.nimbusds.openid.connect.sdk.op", - "com.nimbusds.openid.connect.sdk.rp", - "com.nimbusds.openid.connect.sdk.rp.statement", - "com.nimbusds.openid.connect.sdk.token", - "com.nimbusds.openid.connect.sdk.validators", - "com.nimbusds.secevent.sdk.claims" - ], - "com.squareup.okhttp3:logging-interceptor": [ - "okhttp3.logging" - ], - "com.squareup.okhttp3:okhttp": [ - "okhttp3", - "okhttp3.internal", - "okhttp3.internal.authenticator", - "okhttp3.internal.cache", - "okhttp3.internal.cache2", - "okhttp3.internal.concurrent", - "okhttp3.internal.connection", - "okhttp3.internal.http", - "okhttp3.internal.http1", - "okhttp3.internal.http2", - "okhttp3.internal.io", - "okhttp3.internal.platform", - "okhttp3.internal.platform.android", - "okhttp3.internal.proxy", - "okhttp3.internal.publicsuffix", - "okhttp3.internal.tls", - "okhttp3.internal.ws" - ], - "com.squareup.okhttp3:okhttp-jvm": [ - "okhttp3", - "okhttp3.internal", - "okhttp3.internal.authenticator", - "okhttp3.internal.cache", - "okhttp3.internal.cache2", - "okhttp3.internal.concurrent", - "okhttp3.internal.connection", - "okhttp3.internal.graal", - "okhttp3.internal.http", - "okhttp3.internal.http1", - "okhttp3.internal.http2", - "okhttp3.internal.http2.flowcontrol", - "okhttp3.internal.idn", - "okhttp3.internal.platform", - "okhttp3.internal.proxy", - "okhttp3.internal.publicsuffix", - "okhttp3.internal.tls", - "okhttp3.internal.url", - "okhttp3.internal.ws" - ], - "com.squareup.okio:okio-jvm": [ - "okio", - "okio.internal" - ], - "com.typesafe:config": [ - "com.typesafe.config", - "com.typesafe.config.impl", - "com.typesafe.config.parser" - ], - "com.vaadin.external.google:android-json": [ - "org.json" - ], - "commons-codec:commons-codec": [ - "org.apache.commons.codec", - "org.apache.commons.codec.binary", - "org.apache.commons.codec.cli", - "org.apache.commons.codec.digest", - "org.apache.commons.codec.language", - "org.apache.commons.codec.language.bm", - "org.apache.commons.codec.net" - ], - "commons-io:commons-io": [ - "org.apache.commons.io", - "org.apache.commons.io.build", - "org.apache.commons.io.channels", - "org.apache.commons.io.charset", - "org.apache.commons.io.comparator", - "org.apache.commons.io.file", - "org.apache.commons.io.file.attribute", - "org.apache.commons.io.file.spi", - "org.apache.commons.io.filefilter", - "org.apache.commons.io.function", - "org.apache.commons.io.input", - "org.apache.commons.io.input.buffer", - "org.apache.commons.io.monitor", - "org.apache.commons.io.output", - "org.apache.commons.io.serialization" - ], - "commons-logging:commons-logging": [ - "org.apache.commons.logging", - "org.apache.commons.logging.impl" - ], - "io.cloudevents:cloudevents-api": [ - "io.cloudevents", - "io.cloudevents.lang", - "io.cloudevents.rw", - "io.cloudevents.types" - ], - "io.cloudevents:cloudevents-core": [ - "io.cloudevents.core", - "io.cloudevents.core.builder", - "io.cloudevents.core.data", - "io.cloudevents.core.extensions", - "io.cloudevents.core.extensions.impl", - "io.cloudevents.core.format", - "io.cloudevents.core.impl", - "io.cloudevents.core.message", - "io.cloudevents.core.message.impl", - "io.cloudevents.core.provider", - "io.cloudevents.core.v03", - "io.cloudevents.core.v1", - "io.cloudevents.core.validator" - ], - "io.cloudevents:cloudevents-json-jackson": [ - "io.cloudevents.jackson" - ], - "io.dropwizard.metrics:metrics-core": [ - "com.codahale.metrics" - ], - "io.grpc:grpc-api": [ - "io.grpc" - ], - "io.grpc:grpc-core": [ - "io.grpc.internal" - ], - "io.grpc:grpc-inprocess": [ - "io.grpc.inprocess" - ], - "io.grpc:grpc-netty-shaded": [ - "io.grpc.netty.shaded.io.grpc.netty", - "io.grpc.netty.shaded.io.netty.bootstrap", - "io.grpc.netty.shaded.io.netty.buffer", - "io.grpc.netty.shaded.io.netty.buffer.search", - "io.grpc.netty.shaded.io.netty.channel", - "io.grpc.netty.shaded.io.netty.channel.embedded", - "io.grpc.netty.shaded.io.netty.channel.epoll", - "io.grpc.netty.shaded.io.netty.channel.group", - "io.grpc.netty.shaded.io.netty.channel.internal", - "io.grpc.netty.shaded.io.netty.channel.local", - "io.grpc.netty.shaded.io.netty.channel.nio", - "io.grpc.netty.shaded.io.netty.channel.oio", - "io.grpc.netty.shaded.io.netty.channel.pool", - "io.grpc.netty.shaded.io.netty.channel.socket", - "io.grpc.netty.shaded.io.netty.channel.socket.nio", - "io.grpc.netty.shaded.io.netty.channel.socket.oio", - "io.grpc.netty.shaded.io.netty.channel.unix", - "io.grpc.netty.shaded.io.netty.handler.address", - "io.grpc.netty.shaded.io.netty.handler.codec", - "io.grpc.netty.shaded.io.netty.handler.codec.base64", - "io.grpc.netty.shaded.io.netty.handler.codec.bytes", - "io.grpc.netty.shaded.io.netty.handler.codec.compression", - "io.grpc.netty.shaded.io.netty.handler.codec.http", - "io.grpc.netty.shaded.io.netty.handler.codec.http.cookie", - "io.grpc.netty.shaded.io.netty.handler.codec.http.cors", - "io.grpc.netty.shaded.io.netty.handler.codec.http.multipart", - "io.grpc.netty.shaded.io.netty.handler.codec.http.websocketx", - "io.grpc.netty.shaded.io.netty.handler.codec.http.websocketx.extensions", - "io.grpc.netty.shaded.io.netty.handler.codec.http.websocketx.extensions.compression", - "io.grpc.netty.shaded.io.netty.handler.codec.http2", - "io.grpc.netty.shaded.io.netty.handler.codec.json", - "io.grpc.netty.shaded.io.netty.handler.codec.marshalling", - "io.grpc.netty.shaded.io.netty.handler.codec.protobuf", - "io.grpc.netty.shaded.io.netty.handler.codec.rtsp", - "io.grpc.netty.shaded.io.netty.handler.codec.serialization", - "io.grpc.netty.shaded.io.netty.handler.codec.socks", - "io.grpc.netty.shaded.io.netty.handler.codec.socksx", - "io.grpc.netty.shaded.io.netty.handler.codec.socksx.v4", - "io.grpc.netty.shaded.io.netty.handler.codec.socksx.v5", - "io.grpc.netty.shaded.io.netty.handler.codec.spdy", - "io.grpc.netty.shaded.io.netty.handler.codec.string", - "io.grpc.netty.shaded.io.netty.handler.codec.xml", - "io.grpc.netty.shaded.io.netty.handler.flow", - "io.grpc.netty.shaded.io.netty.handler.flush", - "io.grpc.netty.shaded.io.netty.handler.ipfilter", - "io.grpc.netty.shaded.io.netty.handler.logging", - "io.grpc.netty.shaded.io.netty.handler.pcap", - "io.grpc.netty.shaded.io.netty.handler.proxy", - "io.grpc.netty.shaded.io.netty.handler.ssl", - "io.grpc.netty.shaded.io.netty.handler.ssl.ocsp", - "io.grpc.netty.shaded.io.netty.handler.ssl.util", - "io.grpc.netty.shaded.io.netty.handler.stream", - "io.grpc.netty.shaded.io.netty.handler.timeout", - "io.grpc.netty.shaded.io.netty.handler.traffic", - "io.grpc.netty.shaded.io.netty.internal.tcnative", - "io.grpc.netty.shaded.io.netty.resolver", - "io.grpc.netty.shaded.io.netty.util", - "io.grpc.netty.shaded.io.netty.util.collection", - "io.grpc.netty.shaded.io.netty.util.concurrent", - "io.grpc.netty.shaded.io.netty.util.internal", - "io.grpc.netty.shaded.io.netty.util.internal.logging", - "io.grpc.netty.shaded.io.netty.util.internal.shaded.org.jctools.queues", - "io.grpc.netty.shaded.io.netty.util.internal.shaded.org.jctools.queues.atomic", - "io.grpc.netty.shaded.io.netty.util.internal.shaded.org.jctools.util", - "io.grpc.netty.shaded.io.netty.util.internal.svm" - ], - "io.grpc:grpc-protobuf": [ - "io.grpc.protobuf" - ], - "io.grpc:grpc-protobuf-lite": [ - "io.grpc.protobuf.lite" - ], - "io.grpc:grpc-services": [ - "io.grpc.binarylog.v1", - "io.grpc.channelz.v1", - "io.grpc.health.v1", - "io.grpc.protobuf.services", - "io.grpc.protobuf.services.internal", - "io.grpc.reflection.v1alpha", - "io.grpc.services" - ], - "io.grpc:grpc-stub": [ - "io.grpc.stub", - "io.grpc.stub.annotations" - ], - "io.grpc:grpc-util": [ - "io.grpc.util" - ], - "io.gsonfire:gson-fire": [ - "io.gsonfire", - "io.gsonfire.annotations", - "io.gsonfire.builders", - "io.gsonfire.gson", - "io.gsonfire.postprocessors", - "io.gsonfire.postprocessors.methodinvoker", - "io.gsonfire.util", - "io.gsonfire.util.reflection" - ], - "io.kubernetes:client-java": [ - "io.kubernetes.client", - "io.kubernetes.client.apimachinery", - "io.kubernetes.client.informer", - "io.kubernetes.client.informer.cache", - "io.kubernetes.client.informer.exception", - "io.kubernetes.client.informer.impl", - "io.kubernetes.client.monitoring", - "io.kubernetes.client.persister", - "io.kubernetes.client.simplified", - "io.kubernetes.client.util", - "io.kubernetes.client.util.annotations", - "io.kubernetes.client.util.authenticators", - "io.kubernetes.client.util.conversion", - "io.kubernetes.client.util.credentials", - "io.kubernetes.client.util.exception", - "io.kubernetes.client.util.generic", - "io.kubernetes.client.util.generic.dynamic", - "io.kubernetes.client.util.generic.options", - "io.kubernetes.client.util.labels", - "io.kubernetes.client.util.okhttp", - "io.kubernetes.client.util.taints", - "io.kubernetes.client.util.version", - "io.kubernetes.client.util.wait" - ], - "io.kubernetes:client-java-api": [ - "io.kubernetes.client.common", - "io.kubernetes.client.custom", - "io.kubernetes.client.gson", - "io.kubernetes.client.openapi", - "io.kubernetes.client.openapi.apis", - "io.kubernetes.client.openapi.auth", - "io.kubernetes.client.openapi.models" - ], - "io.kubernetes:client-java-api-fluent": [ - "io.kubernetes.client.fluent", - "io.kubernetes.client.openapi.models" - ], - "io.kubernetes:client-java-extended": [ - "io.kubernetes.client.extended.controller", - "io.kubernetes.client.extended.controller.builder", - "io.kubernetes.client.extended.controller.reconciler", - "io.kubernetes.client.extended.event", - "io.kubernetes.client.extended.event.legacy", - "io.kubernetes.client.extended.event.v1", - "io.kubernetes.client.extended.kubectl", - "io.kubernetes.client.extended.kubectl.exception", - "io.kubernetes.client.extended.kubectl.util.deployment", - "io.kubernetes.client.extended.leaderelection", - "io.kubernetes.client.extended.leaderelection.resourcelock", - "io.kubernetes.client.extended.network", - "io.kubernetes.client.extended.network.exception", - "io.kubernetes.client.extended.pager", - "io.kubernetes.client.extended.wait", - "io.kubernetes.client.extended.workqueue", - "io.kubernetes.client.extended.workqueue.ratelimiter" - ], - "io.kubernetes:client-java-proto": [ - "io.kubernetes.client.proto" - ], - "io.micrometer:context-propagation": [ - "io.micrometer.context", - "io.micrometer.context.integration" - ], - "io.micrometer:micrometer-commons": [ - "io.micrometer.common", - "io.micrometer.common.annotation", - "io.micrometer.common.docs", - "io.micrometer.common.lang", - "io.micrometer.common.lang.internal", - "io.micrometer.common.util", - "io.micrometer.common.util.internal.logging" - ], - "io.micrometer:micrometer-core": [ - "io.micrometer.core.annotation", - "io.micrometer.core.aop", - "io.micrometer.core.instrument", - "io.micrometer.core.instrument.binder", - "io.micrometer.core.instrument.binder.cache", - "io.micrometer.core.instrument.binder.commonspool2", - "io.micrometer.core.instrument.binder.db", - "io.micrometer.core.instrument.binder.grpc", - "io.micrometer.core.instrument.binder.http", - "io.micrometer.core.instrument.binder.httpcomponents", - "io.micrometer.core.instrument.binder.httpcomponents.hc5", - "io.micrometer.core.instrument.binder.hystrix", - "io.micrometer.core.instrument.binder.jersey.server", - "io.micrometer.core.instrument.binder.jetty", - "io.micrometer.core.instrument.binder.jpa", - "io.micrometer.core.instrument.binder.jvm", - "io.micrometer.core.instrument.binder.jvm.convention", - "io.micrometer.core.instrument.binder.jvm.convention.micrometer", - "io.micrometer.core.instrument.binder.jvm.convention.otel", - "io.micrometer.core.instrument.binder.kafka", - "io.micrometer.core.instrument.binder.logging", - "io.micrometer.core.instrument.binder.mongodb", - "io.micrometer.core.instrument.binder.netty4", - "io.micrometer.core.instrument.binder.okhttp3", - "io.micrometer.core.instrument.binder.system", - "io.micrometer.core.instrument.binder.tomcat", - "io.micrometer.core.instrument.composite", - "io.micrometer.core.instrument.config", - "io.micrometer.core.instrument.config.validate", - "io.micrometer.core.instrument.cumulative", - "io.micrometer.core.instrument.distribution", - "io.micrometer.core.instrument.distribution.pause", - "io.micrometer.core.instrument.docs", - "io.micrometer.core.instrument.dropwizard", - "io.micrometer.core.instrument.internal", - "io.micrometer.core.instrument.kotlin", - "io.micrometer.core.instrument.logging", - "io.micrometer.core.instrument.noop", - "io.micrometer.core.instrument.observation", - "io.micrometer.core.instrument.push", - "io.micrometer.core.instrument.search", - "io.micrometer.core.instrument.simple", - "io.micrometer.core.instrument.step", - "io.micrometer.core.instrument.util", - "io.micrometer.core.ipc.http", - "io.micrometer.core.util.internal.logging" - ], - "io.micrometer:micrometer-jakarta9": [ - "io.micrometer.jakarta9.instrument.jms", - "io.micrometer.jakarta9.instrument.mail" - ], - "io.micrometer:micrometer-observation": [ - "io.micrometer.observation", - "io.micrometer.observation.annotation", - "io.micrometer.observation.aop", - "io.micrometer.observation.contextpropagation", - "io.micrometer.observation.docs", - "io.micrometer.observation.transport" - ], - "io.micrometer:micrometer-observation-test": [ - "io.micrometer.observation.tck" - ], - "io.micrometer:micrometer-registry-prometheus": [ - "io.micrometer.prometheusmetrics" - ], - "io.micrometer:micrometer-tracing": [ - "io.micrometer.tracing", - "io.micrometer.tracing.annotation", - "io.micrometer.tracing.contextpropagation", - "io.micrometer.tracing.contextpropagation.reactor", - "io.micrometer.tracing.docs", - "io.micrometer.tracing.exporter", - "io.micrometer.tracing.handler", - "io.micrometer.tracing.internal", - "io.micrometer.tracing.propagation" - ], - "io.micrometer:micrometer-tracing-bridge-otel": [ - "io.micrometer.tracing.otel", - "io.micrometer.tracing.otel.bridge", - "io.micrometer.tracing.otel.propagation" - ], - "io.nats:jnats": [ - "io.nats.client", - "io.nats.client.api", - "io.nats.client.impl", - "io.nats.client.support", - "io.nats.service" - ], - "io.netty:netty-buffer": [ - "io.netty.buffer", - "io.netty.buffer.search" - ], - "io.netty:netty-codec-base": [ - "io.netty.handler.codec", - "io.netty.handler.codec.base64", - "io.netty.handler.codec.bytes", - "io.netty.handler.codec.json", - "io.netty.handler.codec.serialization", - "io.netty.handler.codec.string" - ], - "io.netty:netty-codec-classes-quic": [ - "io.netty.handler.codec.quic" - ], - "io.netty:netty-codec-compression": [ - "io.netty.handler.codec.compression" - ], - "io.netty:netty-codec-dns": [ - "io.netty.handler.codec.dns" - ], - "io.netty:netty-codec-http": [ - "io.netty.handler.codec.http", - "io.netty.handler.codec.http.cookie", - "io.netty.handler.codec.http.cors", - "io.netty.handler.codec.http.multipart", - "io.netty.handler.codec.http.websocketx", - "io.netty.handler.codec.http.websocketx.extensions", - "io.netty.handler.codec.http.websocketx.extensions.compression", - "io.netty.handler.codec.rtsp", - "io.netty.handler.codec.spdy" - ], - "io.netty:netty-codec-http2": [ - "io.netty.handler.codec.http2" - ], - "io.netty:netty-codec-http3": [ - "io.netty.handler.codec.http3" - ], - "io.netty:netty-codec-socks": [ - "io.netty.handler.codec.socks", - "io.netty.handler.codec.socksx", - "io.netty.handler.codec.socksx.v4", - "io.netty.handler.codec.socksx.v5" - ], - "io.netty:netty-common": [ - "io.netty.util", - "io.netty.util.collection", - "io.netty.util.concurrent", - "io.netty.util.internal", - "io.netty.util.internal.logging", - "io.netty.util.internal.shaded.org.jctools.counters", - "io.netty.util.internal.shaded.org.jctools.maps", - "io.netty.util.internal.shaded.org.jctools.queues", - "io.netty.util.internal.shaded.org.jctools.queues.atomic", - "io.netty.util.internal.shaded.org.jctools.queues.atomic.unpadded", - "io.netty.util.internal.shaded.org.jctools.queues.unpadded", - "io.netty.util.internal.shaded.org.jctools.util", - "io.netty.util.internal.svm" - ], - "io.netty:netty-handler": [ - "io.netty.handler.address", - "io.netty.handler.flow", - "io.netty.handler.flush", - "io.netty.handler.ipfilter", - "io.netty.handler.logging", - "io.netty.handler.pcap", - "io.netty.handler.ssl", - "io.netty.handler.ssl.util", - "io.netty.handler.stream", - "io.netty.handler.timeout", - "io.netty.handler.traffic" - ], - "io.netty:netty-handler-proxy": [ - "io.netty.handler.proxy" - ], - "io.netty:netty-resolver": [ - "io.netty.resolver" - ], - "io.netty:netty-resolver-dns": [ - "io.netty.resolver.dns" - ], - "io.netty:netty-resolver-dns-classes-macos": [ - "io.netty.resolver.dns.macos" - ], - "io.netty:netty-transport": [ - "io.netty.bootstrap", - "io.netty.channel", - "io.netty.channel.embedded", - "io.netty.channel.group", - "io.netty.channel.internal", - "io.netty.channel.local", - "io.netty.channel.nio", - "io.netty.channel.oio", - "io.netty.channel.pool", - "io.netty.channel.socket", - "io.netty.channel.socket.nio", - "io.netty.channel.socket.oio" - ], - "io.netty:netty-transport-classes-epoll": [ - "io.netty.channel.epoll" - ], - "io.netty:netty-transport-native-unix-common": [ - "io.netty.channel.unix" - ], - "io.opentelemetry.semconv:opentelemetry-semconv": [ - "io.opentelemetry.semconv" - ], - "io.opentelemetry:opentelemetry-api": [ - "io.opentelemetry.api", - "io.opentelemetry.api.baggage", - "io.opentelemetry.api.baggage.propagation", - "io.opentelemetry.api.common", - "io.opentelemetry.api.internal", - "io.opentelemetry.api.logs", - "io.opentelemetry.api.metrics", - "io.opentelemetry.api.trace", - "io.opentelemetry.api.trace.propagation", - "io.opentelemetry.api.trace.propagation.internal" - ], - "io.opentelemetry:opentelemetry-common": [ - "io.opentelemetry.common" - ], - "io.opentelemetry:opentelemetry-context": [ - "io.opentelemetry.context", - "io.opentelemetry.context.internal.shaded", - "io.opentelemetry.context.propagation", - "io.opentelemetry.context.propagation.internal" - ], - "io.opentelemetry:opentelemetry-exporter-common": [ - "io.opentelemetry.exporter.internal", - "io.opentelemetry.exporter.internal.compression", - "io.opentelemetry.exporter.internal.grpc", - "io.opentelemetry.exporter.internal.http", - "io.opentelemetry.exporter.internal.marshal", - "io.opentelemetry.exporter.internal.metrics" - ], - "io.opentelemetry:opentelemetry-exporter-otlp": [ - "io.opentelemetry.exporter.otlp.all.internal", - "io.opentelemetry.exporter.otlp.http.logs", - "io.opentelemetry.exporter.otlp.http.metrics", - "io.opentelemetry.exporter.otlp.http.trace", - "io.opentelemetry.exporter.otlp.internal", - "io.opentelemetry.exporter.otlp.logs", - "io.opentelemetry.exporter.otlp.metrics", - "io.opentelemetry.exporter.otlp.trace" - ], - "io.opentelemetry:opentelemetry-exporter-otlp-common": [ - "io.opentelemetry.exporter.internal.otlp", - "io.opentelemetry.exporter.internal.otlp.logs", - "io.opentelemetry.exporter.internal.otlp.metrics", - "io.opentelemetry.exporter.internal.otlp.traces", - "io.opentelemetry.proto.collector.logs.v1.internal", - "io.opentelemetry.proto.collector.metrics.v1.internal", - "io.opentelemetry.proto.collector.profiles.v1development.internal", - "io.opentelemetry.proto.collector.trace.v1.internal", - "io.opentelemetry.proto.common.v1.internal", - "io.opentelemetry.proto.logs.v1.internal", - "io.opentelemetry.proto.metrics.v1.internal", - "io.opentelemetry.proto.profiles.v1development.internal", - "io.opentelemetry.proto.resource.v1.internal", - "io.opentelemetry.proto.trace.v1.internal" - ], - "io.opentelemetry:opentelemetry-exporter-sender-okhttp": [ - "io.opentelemetry.exporter.sender.okhttp.internal" - ], - "io.opentelemetry:opentelemetry-extension-trace-propagators": [ - "io.opentelemetry.extension.trace.propagation", - "io.opentelemetry.extension.trace.propagation.internal" - ], - "io.opentelemetry:opentelemetry-sdk": [ - "io.opentelemetry.sdk" - ], - "io.opentelemetry:opentelemetry-sdk-common": [ - "io.opentelemetry.sdk.common", - "io.opentelemetry.sdk.common.export", - "io.opentelemetry.sdk.common.internal", - "io.opentelemetry.sdk.internal", - "io.opentelemetry.sdk.resources" - ], - "io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi": [ - "io.opentelemetry.sdk.autoconfigure.spi", - "io.opentelemetry.sdk.autoconfigure.spi.internal", - "io.opentelemetry.sdk.autoconfigure.spi.logs", - "io.opentelemetry.sdk.autoconfigure.spi.metrics", - "io.opentelemetry.sdk.autoconfigure.spi.traces" - ], - "io.opentelemetry:opentelemetry-sdk-logs": [ - "io.opentelemetry.sdk.logs", - "io.opentelemetry.sdk.logs.data", - "io.opentelemetry.sdk.logs.data.internal", - "io.opentelemetry.sdk.logs.export", - "io.opentelemetry.sdk.logs.internal" - ], - "io.opentelemetry:opentelemetry-sdk-metrics": [ - "io.opentelemetry.sdk.metrics", - "io.opentelemetry.sdk.metrics.data", - "io.opentelemetry.sdk.metrics.export", - "io.opentelemetry.sdk.metrics.internal", - "io.opentelemetry.sdk.metrics.internal.aggregator", - "io.opentelemetry.sdk.metrics.internal.concurrent", - "io.opentelemetry.sdk.metrics.internal.data", - "io.opentelemetry.sdk.metrics.internal.debug", - "io.opentelemetry.sdk.metrics.internal.descriptor", - "io.opentelemetry.sdk.metrics.internal.exemplar", - "io.opentelemetry.sdk.metrics.internal.export", - "io.opentelemetry.sdk.metrics.internal.state", - "io.opentelemetry.sdk.metrics.internal.view" - ], - "io.opentelemetry:opentelemetry-sdk-testing": [ - "io.opentelemetry.sdk.testing.assertj", - "io.opentelemetry.sdk.testing.context", - "io.opentelemetry.sdk.testing.exporter", - "io.opentelemetry.sdk.testing.junit4", - "io.opentelemetry.sdk.testing.junit5", - "io.opentelemetry.sdk.testing.logs", - "io.opentelemetry.sdk.testing.logs.internal", - "io.opentelemetry.sdk.testing.metrics", - "io.opentelemetry.sdk.testing.time", - "io.opentelemetry.sdk.testing.trace" - ], - "io.opentelemetry:opentelemetry-sdk-trace": [ - "io.opentelemetry.internal.shaded.jctools.counters", - "io.opentelemetry.internal.shaded.jctools.maps", - "io.opentelemetry.internal.shaded.jctools.queues", - "io.opentelemetry.internal.shaded.jctools.queues.atomic", - "io.opentelemetry.internal.shaded.jctools.queues.atomic.unpadded", - "io.opentelemetry.internal.shaded.jctools.queues.unpadded", - "io.opentelemetry.internal.shaded.jctools.util", - "io.opentelemetry.sdk.trace", - "io.opentelemetry.sdk.trace.data", - "io.opentelemetry.sdk.trace.export", - "io.opentelemetry.sdk.trace.internal", - "io.opentelemetry.sdk.trace.samplers" - ], - "io.perfmark:perfmark-api": [ - "io.perfmark" - ], - "io.projectreactor.netty:reactor-netty-core": [ - "reactor.netty", - "reactor.netty.channel", - "reactor.netty.contextpropagation", - "reactor.netty.internal.shaded.reactor.pool", - "reactor.netty.internal.shaded.reactor.pool.decorators", - "reactor.netty.internal.shaded.reactor.pool.introspection", - "reactor.netty.internal.util", - "reactor.netty.observability", - "reactor.netty.resources", - "reactor.netty.tcp", - "reactor.netty.transport", - "reactor.netty.transport.logging", - "reactor.netty.udp" - ], - "io.projectreactor.netty:reactor-netty-http": [ - "reactor.netty.http", - "reactor.netty.http.client", - "reactor.netty.http.internal", - "reactor.netty.http.logging", - "reactor.netty.http.observability", - "reactor.netty.http.server", - "reactor.netty.http.server.compression", - "reactor.netty.http.server.logging", - "reactor.netty.http.server.logging.error", - "reactor.netty.http.websocket" - ], - "io.projectreactor:reactor-core": [ - "reactor.adapter", - "reactor.core", - "reactor.core.observability", - "reactor.core.publisher", - "reactor.core.scheduler", - "reactor.util", - "reactor.util.annotation", - "reactor.util.concurrent", - "reactor.util.context", - "reactor.util.function", - "reactor.util.repeat", - "reactor.util.retry" - ], - "io.projectreactor:reactor-test": [ - "reactor.test", - "reactor.test.publisher", - "reactor.test.scheduler", - "reactor.test.subscriber", - "reactor.test.util" - ], - "io.prometheus:prometheus-metrics-config": [ - "io.prometheus.metrics.config" - ], - "io.prometheus:prometheus-metrics-core": [ - "io.prometheus.metrics.core.datapoints", - "io.prometheus.metrics.core.exemplars", - "io.prometheus.metrics.core.metrics", - "io.prometheus.metrics.core.util" - ], - "io.prometheus:prometheus-metrics-exposition-formats": [ - "io.prometheus.metrics.expositionformats.generated.com_google_protobuf_4_33_0", - "io.prometheus.metrics.expositionformats.internal", - "io.prometheus.metrics.shaded.com_google_protobuf_4_33_0", - "io.prometheus.metrics.shaded.com_google_protobuf_4_33_0.compiler" - ], - "io.prometheus:prometheus-metrics-exposition-textformats": [ - "io.prometheus.metrics.expositionformats" - ], - "io.prometheus:prometheus-metrics-model": [ - "io.prometheus.metrics.model.registry", - "io.prometheus.metrics.model.snapshots" - ], - "io.prometheus:prometheus-metrics-tracer-common": [ - "io.prometheus.metrics.tracer.common" - ], - "io.swagger.core.v3:swagger-annotations-jakarta": [ - "io.swagger.v3.oas.annotations", - "io.swagger.v3.oas.annotations.callbacks", - "io.swagger.v3.oas.annotations.enums", - "io.swagger.v3.oas.annotations.extensions", - "io.swagger.v3.oas.annotations.headers", - "io.swagger.v3.oas.annotations.info", - "io.swagger.v3.oas.annotations.links", - "io.swagger.v3.oas.annotations.media", - "io.swagger.v3.oas.annotations.parameters", - "io.swagger.v3.oas.annotations.responses", - "io.swagger.v3.oas.annotations.security", - "io.swagger.v3.oas.annotations.servers", - "io.swagger.v3.oas.annotations.tags" - ], - "io.swagger.core.v3:swagger-core-jakarta": [ - "io.swagger.v3.core.converter", - "io.swagger.v3.core.filter", - "io.swagger.v3.core.jackson", - "io.swagger.v3.core.jackson.mixin", - "io.swagger.v3.core.model", - "io.swagger.v3.core.util" - ], - "io.swagger.core.v3:swagger-models-jakarta": [ - "io.swagger.v3.oas.models", - "io.swagger.v3.oas.models.annotations", - "io.swagger.v3.oas.models.callbacks", - "io.swagger.v3.oas.models.examples", - "io.swagger.v3.oas.models.headers", - "io.swagger.v3.oas.models.info", - "io.swagger.v3.oas.models.links", - "io.swagger.v3.oas.models.media", - "io.swagger.v3.oas.models.parameters", - "io.swagger.v3.oas.models.responses", - "io.swagger.v3.oas.models.security", - "io.swagger.v3.oas.models.servers", - "io.swagger.v3.oas.models.tags" - ], - "io.swagger:swagger-annotations": [ - "io.swagger.annotations" - ], - "jakarta.activation:jakarta.activation-api": [ - "jakarta.activation", - "jakarta.activation.spi" - ], - "jakarta.annotation:jakarta.annotation-api": [ - "jakarta.annotation", - "jakarta.annotation.security", - "jakarta.annotation.sql" - ], - "jakarta.servlet:jakarta.servlet-api": [ - "jakarta.servlet", - "jakarta.servlet.annotation", - "jakarta.servlet.descriptor", - "jakarta.servlet.http" - ], - "jakarta.validation:jakarta.validation-api": [ - "jakarta.validation", - "jakarta.validation.bootstrap", - "jakarta.validation.constraints", - "jakarta.validation.constraintvalidation", - "jakarta.validation.executable", - "jakarta.validation.groups", - "jakarta.validation.metadata", - "jakarta.validation.spi", - "jakarta.validation.valueextraction" - ], - "jakarta.xml.bind:jakarta.xml.bind-api": [ - "jakarta.xml.bind", - "jakarta.xml.bind.annotation", - "jakarta.xml.bind.annotation.adapters", - "jakarta.xml.bind.attachment", - "jakarta.xml.bind.helpers", - "jakarta.xml.bind.util" - ], - "javax.annotation:javax.annotation-api": [ - "javax.annotation", - "javax.annotation.security", - "javax.annotation.sql" - ], - "net.bytebuddy:byte-buddy": [ - "net.bytebuddy", - "net.bytebuddy.agent.builder", - "net.bytebuddy.asm", - "net.bytebuddy.build", - "net.bytebuddy.description", - "net.bytebuddy.description.annotation", - "net.bytebuddy.description.enumeration", - "net.bytebuddy.description.field", - "net.bytebuddy.description.method", - "net.bytebuddy.description.modifier", - "net.bytebuddy.description.type", - "net.bytebuddy.dynamic", - "net.bytebuddy.dynamic.loading", - "net.bytebuddy.dynamic.scaffold", - "net.bytebuddy.dynamic.scaffold.inline", - "net.bytebuddy.dynamic.scaffold.subclass", - "net.bytebuddy.implementation", - "net.bytebuddy.implementation.attribute", - "net.bytebuddy.implementation.auxiliary", - "net.bytebuddy.implementation.bind", - "net.bytebuddy.implementation.bind.annotation", - "net.bytebuddy.implementation.bytecode", - "net.bytebuddy.implementation.bytecode.assign", - "net.bytebuddy.implementation.bytecode.assign.primitive", - "net.bytebuddy.implementation.bytecode.assign.reference", - "net.bytebuddy.implementation.bytecode.collection", - "net.bytebuddy.implementation.bytecode.constant", - "net.bytebuddy.implementation.bytecode.member", - "net.bytebuddy.jar.asm", - "net.bytebuddy.jar.asm.commons", - "net.bytebuddy.jar.asm.signature", - "net.bytebuddy.jar.asmjdkbridge", - "net.bytebuddy.matcher", - "net.bytebuddy.pool", - "net.bytebuddy.utility", - "net.bytebuddy.utility.dispatcher", - "net.bytebuddy.utility.nullability", - "net.bytebuddy.utility.privilege", - "net.bytebuddy.utility.visitor" - ], - "net.bytebuddy:byte-buddy-agent": [ - "net.bytebuddy.agent", - "net.bytebuddy.agent.utility.nullability" - ], - "net.devh:grpc-common-spring-boot": [ - "net.devh.boot.grpc.common.autoconfigure", - "net.devh.boot.grpc.common.codec", - "net.devh.boot.grpc.common.security", - "net.devh.boot.grpc.common.util" - ], - "net.devh:grpc-server-spring-boot-starter": [ - "net.devh.boot.grpc.server.advice", - "net.devh.boot.grpc.server.autoconfigure", - "net.devh.boot.grpc.server.condition", - "net.devh.boot.grpc.server.config", - "net.devh.boot.grpc.server.error", - "net.devh.boot.grpc.server.event", - "net.devh.boot.grpc.server.interceptor", - "net.devh.boot.grpc.server.metrics", - "net.devh.boot.grpc.server.nameresolver", - "net.devh.boot.grpc.server.scope", - "net.devh.boot.grpc.server.security.authentication", - "net.devh.boot.grpc.server.security.check", - "net.devh.boot.grpc.server.security.interceptors", - "net.devh.boot.grpc.server.serverfactory", - "net.devh.boot.grpc.server.service" - ], - "net.java.dev.jna:jna": [ - "com.sun.jna", - "com.sun.jna.internal", - "com.sun.jna.ptr", - "com.sun.jna.win32" - ], - "net.javacrumbs.shedlock:shedlock-core": [ - "net.javacrumbs.shedlock.core", - "net.javacrumbs.shedlock.support", - "net.javacrumbs.shedlock.util" - ], - "net.javacrumbs.shedlock:shedlock-provider-cassandra": [ - "net.javacrumbs.shedlock.provider.cassandra" - ], - "net.javacrumbs.shedlock:shedlock-spring": [ - "net.javacrumbs.shedlock.spring", - "net.javacrumbs.shedlock.spring.annotation", - "net.javacrumbs.shedlock.spring.aop" - ], - "net.minidev:accessors-smart": [ - "net.minidev.asm", - "net.minidev.asm.ex" - ], - "net.minidev:json-smart": [ - "net.minidev.json", - "net.minidev.json.annotate", - "net.minidev.json.parser", - "net.minidev.json.reader", - "net.minidev.json.writer" - ], - "org.apache.cassandra:java-driver-core": [ - "com.datastax.dse.driver.api.core", - "com.datastax.dse.driver.api.core.auth", - "com.datastax.dse.driver.api.core.config", - "com.datastax.dse.driver.api.core.cql.continuous", - "com.datastax.dse.driver.api.core.cql.continuous.reactive", - "com.datastax.dse.driver.api.core.cql.reactive", - "com.datastax.dse.driver.api.core.data.geometry", - "com.datastax.dse.driver.api.core.data.time", - "com.datastax.dse.driver.api.core.graph", - "com.datastax.dse.driver.api.core.graph.predicates", - "com.datastax.dse.driver.api.core.graph.reactive", - "com.datastax.dse.driver.api.core.metadata", - "com.datastax.dse.driver.api.core.metadata.schema", - "com.datastax.dse.driver.api.core.metrics", - "com.datastax.dse.driver.api.core.servererrors", - "com.datastax.dse.driver.api.core.type", - "com.datastax.dse.driver.api.core.type.codec", - "com.datastax.dse.driver.internal.core", - "com.datastax.dse.driver.internal.core.auth", - "com.datastax.dse.driver.internal.core.cql", - "com.datastax.dse.driver.internal.core.cql.continuous", - "com.datastax.dse.driver.internal.core.cql.continuous.reactive", - "com.datastax.dse.driver.internal.core.cql.reactive", - "com.datastax.dse.driver.internal.core.data.geometry", - "com.datastax.dse.driver.internal.core.graph", - "com.datastax.dse.driver.internal.core.graph.binary", - "com.datastax.dse.driver.internal.core.graph.binary.buffer", - "com.datastax.dse.driver.internal.core.graph.reactive", - "com.datastax.dse.driver.internal.core.insights", - "com.datastax.dse.driver.internal.core.insights.configuration", - "com.datastax.dse.driver.internal.core.insights.exceptions", - "com.datastax.dse.driver.internal.core.insights.schema", - "com.datastax.dse.driver.internal.core.loadbalancing", - "com.datastax.dse.driver.internal.core.metadata.schema", - "com.datastax.dse.driver.internal.core.metadata.schema.parsing", - "com.datastax.dse.driver.internal.core.protocol", - "com.datastax.dse.driver.internal.core.search", - "com.datastax.dse.driver.internal.core.session", - "com.datastax.dse.driver.internal.core.type.codec", - "com.datastax.dse.driver.internal.core.type.codec.geometry", - "com.datastax.dse.driver.internal.core.type.codec.time", - "com.datastax.dse.driver.internal.core.util.concurrent", - "com.datastax.oss.driver.api.core", - "com.datastax.oss.driver.api.core.addresstranslation", - "com.datastax.oss.driver.api.core.auth", - "com.datastax.oss.driver.api.core.config", - "com.datastax.oss.driver.api.core.connection", - "com.datastax.oss.driver.api.core.context", - "com.datastax.oss.driver.api.core.cql", - "com.datastax.oss.driver.api.core.data", - "com.datastax.oss.driver.api.core.detach", - "com.datastax.oss.driver.api.core.loadbalancing", - "com.datastax.oss.driver.api.core.metadata", - "com.datastax.oss.driver.api.core.metadata.schema", - "com.datastax.oss.driver.api.core.metadata.token", - "com.datastax.oss.driver.api.core.metrics", - "com.datastax.oss.driver.api.core.paging", - "com.datastax.oss.driver.api.core.retry", - "com.datastax.oss.driver.api.core.servererrors", - "com.datastax.oss.driver.api.core.session", - "com.datastax.oss.driver.api.core.session.throttling", - "com.datastax.oss.driver.api.core.specex", - "com.datastax.oss.driver.api.core.ssl", - "com.datastax.oss.driver.api.core.time", - "com.datastax.oss.driver.api.core.tracker", - "com.datastax.oss.driver.api.core.type", - "com.datastax.oss.driver.api.core.type.codec", - "com.datastax.oss.driver.api.core.type.codec.registry", - "com.datastax.oss.driver.api.core.type.reflect", - "com.datastax.oss.driver.api.core.uuid", - "com.datastax.oss.driver.internal.core", - "com.datastax.oss.driver.internal.core.addresstranslation", - "com.datastax.oss.driver.internal.core.adminrequest", - "com.datastax.oss.driver.internal.core.auth", - "com.datastax.oss.driver.internal.core.channel", - "com.datastax.oss.driver.internal.core.config", - "com.datastax.oss.driver.internal.core.config.cloud", - "com.datastax.oss.driver.internal.core.config.composite", - "com.datastax.oss.driver.internal.core.config.map", - "com.datastax.oss.driver.internal.core.config.typesafe", - "com.datastax.oss.driver.internal.core.connection", - "com.datastax.oss.driver.internal.core.context", - "com.datastax.oss.driver.internal.core.control", - "com.datastax.oss.driver.internal.core.cql", - "com.datastax.oss.driver.internal.core.data", - "com.datastax.oss.driver.internal.core.loadbalancing", - "com.datastax.oss.driver.internal.core.loadbalancing.helper", - "com.datastax.oss.driver.internal.core.loadbalancing.nodeset", - "com.datastax.oss.driver.internal.core.metadata", - "com.datastax.oss.driver.internal.core.metadata.schema", - "com.datastax.oss.driver.internal.core.metadata.schema.events", - "com.datastax.oss.driver.internal.core.metadata.schema.parsing", - "com.datastax.oss.driver.internal.core.metadata.schema.queries", - "com.datastax.oss.driver.internal.core.metadata.schema.refresh", - "com.datastax.oss.driver.internal.core.metadata.token", - "com.datastax.oss.driver.internal.core.metrics", - "com.datastax.oss.driver.internal.core.os", - "com.datastax.oss.driver.internal.core.pool", - "com.datastax.oss.driver.internal.core.protocol", - "com.datastax.oss.driver.internal.core.retry", - "com.datastax.oss.driver.internal.core.servererrors", - "com.datastax.oss.driver.internal.core.session", - "com.datastax.oss.driver.internal.core.session.throttling", - "com.datastax.oss.driver.internal.core.specex", - "com.datastax.oss.driver.internal.core.ssl", - "com.datastax.oss.driver.internal.core.time", - "com.datastax.oss.driver.internal.core.tracker", - "com.datastax.oss.driver.internal.core.type", - "com.datastax.oss.driver.internal.core.type.codec", - "com.datastax.oss.driver.internal.core.type.codec.extras", - "com.datastax.oss.driver.internal.core.type.codec.extras.array", - "com.datastax.oss.driver.internal.core.type.codec.extras.enums", - "com.datastax.oss.driver.internal.core.type.codec.extras.json", - "com.datastax.oss.driver.internal.core.type.codec.extras.time", - "com.datastax.oss.driver.internal.core.type.codec.extras.vector", - "com.datastax.oss.driver.internal.core.type.codec.registry", - "com.datastax.oss.driver.internal.core.type.util", - "com.datastax.oss.driver.internal.core.util", - "com.datastax.oss.driver.internal.core.util.collection", - "com.datastax.oss.driver.internal.core.util.concurrent" - ], - "org.apache.cassandra:java-driver-guava-shaded": [ - "com.datastax.oss.driver.shaded.guava.common.annotations", - "com.datastax.oss.driver.shaded.guava.common.base", - "com.datastax.oss.driver.shaded.guava.common.base.internal", - "com.datastax.oss.driver.shaded.guava.common.cache", - "com.datastax.oss.driver.shaded.guava.common.collect", - "com.datastax.oss.driver.shaded.guava.common.escape", - "com.datastax.oss.driver.shaded.guava.common.eventbus", - "com.datastax.oss.driver.shaded.guava.common.graph", - "com.datastax.oss.driver.shaded.guava.common.hash", - "com.datastax.oss.driver.shaded.guava.common.html", - "com.datastax.oss.driver.shaded.guava.common.io", - "com.datastax.oss.driver.shaded.guava.common.math", - "com.datastax.oss.driver.shaded.guava.common.net", - "com.datastax.oss.driver.shaded.guava.common.primitives", - "com.datastax.oss.driver.shaded.guava.common.reflect", - "com.datastax.oss.driver.shaded.guava.common.util.concurrent", - "com.datastax.oss.driver.shaded.guava.common.util.concurrent.internal", - "com.datastax.oss.driver.shaded.guava.common.xml", - "com.datastax.oss.driver.shaded.guava.j2objc.annotations", - "com.datastax.oss.driver.shaded.guava.thirdparty.publicsuffix" - ], - "org.apache.cassandra:java-driver-metrics-micrometer": [ - "com.datastax.oss.driver.internal.metrics.micrometer" - ], - "org.apache.cassandra:java-driver-query-builder": [ - "com.datastax.dse.driver.api.querybuilder", - "com.datastax.dse.driver.api.querybuilder.schema", - "com.datastax.dse.driver.internal.querybuilder.schema", - "com.datastax.oss.driver.api.querybuilder", - "com.datastax.oss.driver.api.querybuilder.condition", - "com.datastax.oss.driver.api.querybuilder.delete", - "com.datastax.oss.driver.api.querybuilder.insert", - "com.datastax.oss.driver.api.querybuilder.relation", - "com.datastax.oss.driver.api.querybuilder.schema", - "com.datastax.oss.driver.api.querybuilder.schema.compaction", - "com.datastax.oss.driver.api.querybuilder.select", - "com.datastax.oss.driver.api.querybuilder.term", - "com.datastax.oss.driver.api.querybuilder.truncate", - "com.datastax.oss.driver.api.querybuilder.update", - "com.datastax.oss.driver.internal.querybuilder", - "com.datastax.oss.driver.internal.querybuilder.condition", - "com.datastax.oss.driver.internal.querybuilder.delete", - "com.datastax.oss.driver.internal.querybuilder.insert", - "com.datastax.oss.driver.internal.querybuilder.lhs", - "com.datastax.oss.driver.internal.querybuilder.relation", - "com.datastax.oss.driver.internal.querybuilder.schema", - "com.datastax.oss.driver.internal.querybuilder.schema.compaction", - "com.datastax.oss.driver.internal.querybuilder.select", - "com.datastax.oss.driver.internal.querybuilder.term", - "com.datastax.oss.driver.internal.querybuilder.truncate", - "com.datastax.oss.driver.internal.querybuilder.update" - ], - "org.apache.commons:commons-collections4": [ - "org.apache.commons.collections4", - "org.apache.commons.collections4.bag", - "org.apache.commons.collections4.bidimap", - "org.apache.commons.collections4.bloomfilter", - "org.apache.commons.collections4.collection", - "org.apache.commons.collections4.comparators", - "org.apache.commons.collections4.functors", - "org.apache.commons.collections4.iterators", - "org.apache.commons.collections4.keyvalue", - "org.apache.commons.collections4.list", - "org.apache.commons.collections4.map", - "org.apache.commons.collections4.multimap", - "org.apache.commons.collections4.multiset", - "org.apache.commons.collections4.properties", - "org.apache.commons.collections4.queue", - "org.apache.commons.collections4.sequence", - "org.apache.commons.collections4.set", - "org.apache.commons.collections4.splitmap", - "org.apache.commons.collections4.trie", - "org.apache.commons.collections4.trie.analyzer" - ], - "org.apache.commons:commons-compress": [ - "org.apache.commons.compress", - "org.apache.commons.compress.archivers", - "org.apache.commons.compress.archivers.ar", - "org.apache.commons.compress.archivers.arj", - "org.apache.commons.compress.archivers.cpio", - "org.apache.commons.compress.archivers.dump", - "org.apache.commons.compress.archivers.examples", - "org.apache.commons.compress.archivers.jar", - "org.apache.commons.compress.archivers.sevenz", - "org.apache.commons.compress.archivers.tar", - "org.apache.commons.compress.archivers.zip", - "org.apache.commons.compress.changes", - "org.apache.commons.compress.compressors", - "org.apache.commons.compress.compressors.brotli", - "org.apache.commons.compress.compressors.bzip2", - "org.apache.commons.compress.compressors.deflate", - "org.apache.commons.compress.compressors.deflate64", - "org.apache.commons.compress.compressors.gzip", - "org.apache.commons.compress.compressors.lz4", - "org.apache.commons.compress.compressors.lz77support", - "org.apache.commons.compress.compressors.lzma", - "org.apache.commons.compress.compressors.lzw", - "org.apache.commons.compress.compressors.pack200", - "org.apache.commons.compress.compressors.snappy", - "org.apache.commons.compress.compressors.xz", - "org.apache.commons.compress.compressors.z", - "org.apache.commons.compress.compressors.zstandard", - "org.apache.commons.compress.harmony", - "org.apache.commons.compress.harmony.archive.internal.nls", - "org.apache.commons.compress.harmony.pack200", - "org.apache.commons.compress.harmony.unpack200", - "org.apache.commons.compress.harmony.unpack200.bytecode", - "org.apache.commons.compress.harmony.unpack200.bytecode.forms", - "org.apache.commons.compress.java.util.jar", - "org.apache.commons.compress.parallel", - "org.apache.commons.compress.utils" - ], - "org.apache.commons:commons-lang3": [ - "org.apache.commons.lang3", - "org.apache.commons.lang3.arch", - "org.apache.commons.lang3.builder", - "org.apache.commons.lang3.compare", - "org.apache.commons.lang3.concurrent", - "org.apache.commons.lang3.concurrent.locks", - "org.apache.commons.lang3.event", - "org.apache.commons.lang3.exception", - "org.apache.commons.lang3.function", - "org.apache.commons.lang3.math", - "org.apache.commons.lang3.mutable", - "org.apache.commons.lang3.reflect", - "org.apache.commons.lang3.stream", - "org.apache.commons.lang3.text", - "org.apache.commons.lang3.text.translate", - "org.apache.commons.lang3.time", - "org.apache.commons.lang3.tuple", - "org.apache.commons.lang3.util" - ], - "org.apache.logging.log4j:log4j-api": [ - "org.apache.logging.log4j", - "org.apache.logging.log4j.internal", - "org.apache.logging.log4j.internal.annotation", - "org.apache.logging.log4j.internal.map", - "org.apache.logging.log4j.message", - "org.apache.logging.log4j.simple", - "org.apache.logging.log4j.simple.internal", - "org.apache.logging.log4j.spi", - "org.apache.logging.log4j.status", - "org.apache.logging.log4j.util", - "org.apache.logging.log4j.util.internal" - ], - "org.apache.logging.log4j:log4j-to-slf4j": [ - "org.apache.logging.slf4j" - ], - "org.apache.tomcat.embed:tomcat-embed-core": [ - "jakarta.security.auth.message", - "jakarta.security.auth.message.callback", - "jakarta.security.auth.message.config", - "jakarta.security.auth.message.module", - "jakarta.servlet", - "jakarta.servlet.annotation", - "jakarta.servlet.descriptor", - "jakarta.servlet.http", - "org.apache.catalina", - "org.apache.catalina.authenticator", - "org.apache.catalina.authenticator.jaspic", - "org.apache.catalina.connector", - "org.apache.catalina.core", - "org.apache.catalina.deploy", - "org.apache.catalina.filters", - "org.apache.catalina.loader", - "org.apache.catalina.manager", - "org.apache.catalina.manager.host", - "org.apache.catalina.manager.util", - "org.apache.catalina.mapper", - "org.apache.catalina.mbeans", - "org.apache.catalina.realm", - "org.apache.catalina.security", - "org.apache.catalina.servlets", - "org.apache.catalina.session", - "org.apache.catalina.startup", - "org.apache.catalina.users", - "org.apache.catalina.util", - "org.apache.catalina.valves", - "org.apache.catalina.valves.rewrite", - "org.apache.catalina.webresources", - "org.apache.catalina.webresources.war", - "org.apache.coyote", - "org.apache.coyote.ajp", - "org.apache.coyote.http11", - "org.apache.coyote.http11.filters", - "org.apache.coyote.http11.upgrade", - "org.apache.coyote.http2", - "org.apache.juli", - "org.apache.juli.logging", - "org.apache.naming", - "org.apache.naming.factory", - "org.apache.naming.java", - "org.apache.tomcat", - "org.apache.tomcat.jni", - "org.apache.tomcat.util", - "org.apache.tomcat.util.bcel", - "org.apache.tomcat.util.bcel.classfile", - "org.apache.tomcat.util.buf", - "org.apache.tomcat.util.collections", - "org.apache.tomcat.util.compat", - "org.apache.tomcat.util.concurrent", - "org.apache.tomcat.util.descriptor", - "org.apache.tomcat.util.descriptor.tagplugin", - "org.apache.tomcat.util.descriptor.web", - "org.apache.tomcat.util.digester", - "org.apache.tomcat.util.file", - "org.apache.tomcat.util.http", - "org.apache.tomcat.util.http.fileupload", - "org.apache.tomcat.util.http.fileupload.disk", - "org.apache.tomcat.util.http.fileupload.impl", - "org.apache.tomcat.util.http.fileupload.servlet", - "org.apache.tomcat.util.http.fileupload.util", - "org.apache.tomcat.util.http.fileupload.util.mime", - "org.apache.tomcat.util.http.parser", - "org.apache.tomcat.util.json", - "org.apache.tomcat.util.log", - "org.apache.tomcat.util.modeler", - "org.apache.tomcat.util.modeler.modules", - "org.apache.tomcat.util.net", - "org.apache.tomcat.util.net.jsse", - "org.apache.tomcat.util.net.openssl", - "org.apache.tomcat.util.net.openssl.ciphers", - "org.apache.tomcat.util.res", - "org.apache.tomcat.util.scan", - "org.apache.tomcat.util.security", - "org.apache.tomcat.util.threads" - ], - "org.apache.tomcat.embed:tomcat-embed-el": [ - "jakarta.el", - "org.apache.el", - "org.apache.el.lang", - "org.apache.el.parser", - "org.apache.el.stream", - "org.apache.el.util" - ], - "org.apache.tomcat.embed:tomcat-embed-websocket": [ - "jakarta.websocket", - "jakarta.websocket.server", - "org.apache.tomcat.websocket", - "org.apache.tomcat.websocket.pojo", - "org.apache.tomcat.websocket.server" - ], - "org.apiguardian:apiguardian-api": [ - "org.apiguardian.api" - ], - "org.aspectj:aspectjweaver": [ - "aj.org.objectweb.asm", - "aj.org.objectweb.asm.commons", - "aj.org.objectweb.asm.signature", - "org.aspectj.apache.bcel", - "org.aspectj.apache.bcel.classfile", - "org.aspectj.apache.bcel.classfile.annotation", - "org.aspectj.apache.bcel.generic", - "org.aspectj.apache.bcel.util", - "org.aspectj.asm", - "org.aspectj.asm.internal", - "org.aspectj.bridge", - "org.aspectj.bridge.context", - "org.aspectj.internal.lang.annotation", - "org.aspectj.internal.lang.reflect", - "org.aspectj.lang", - "org.aspectj.lang.annotation", - "org.aspectj.lang.annotation.control", - "org.aspectj.lang.internal.lang", - "org.aspectj.lang.reflect", - "org.aspectj.runtime", - "org.aspectj.runtime.internal", - "org.aspectj.runtime.internal.cflowstack", - "org.aspectj.runtime.reflect", - "org.aspectj.util", - "org.aspectj.weaver", - "org.aspectj.weaver.ast", - "org.aspectj.weaver.bcel", - "org.aspectj.weaver.bcel.asm", - "org.aspectj.weaver.internal.tools", - "org.aspectj.weaver.loadtime", - "org.aspectj.weaver.loadtime.definition", - "org.aspectj.weaver.ltw", - "org.aspectj.weaver.model", - "org.aspectj.weaver.patterns", - "org.aspectj.weaver.reflect", - "org.aspectj.weaver.tools", - "org.aspectj.weaver.tools.cache" - ], - "org.assertj:assertj-core": [ - "org.assertj.core.annotation", - "org.assertj.core.annotations", - "org.assertj.core.api", - "org.assertj.core.api.exception", - "org.assertj.core.api.filter", - "org.assertj.core.api.iterable", - "org.assertj.core.api.junit.jupiter", - "org.assertj.core.api.recursive", - "org.assertj.core.api.recursive.assertion", - "org.assertj.core.api.recursive.comparison", - "org.assertj.core.condition", - "org.assertj.core.configuration", - "org.assertj.core.data", - "org.assertj.core.description", - "org.assertj.core.error", - "org.assertj.core.error.array2d", - "org.assertj.core.error.future", - "org.assertj.core.error.uri", - "org.assertj.core.extractor", - "org.assertj.core.groups", - "org.assertj.core.internal", - "org.assertj.core.internal.annotation", - "org.assertj.core.matcher", - "org.assertj.core.presentation", - "org.assertj.core.util", - "org.assertj.core.util.diff", - "org.assertj.core.util.diff.myers", - "org.assertj.core.util.introspection", - "org.assertj.core.util.xml" - ], - "org.awaitility:awaitility": [ - "org.awaitility", - "org.awaitility.classpath", - "org.awaitility.constraint", - "org.awaitility.core", - "org.awaitility.pollinterval", - "org.awaitility.reflect", - "org.awaitility.reflect.exception", - "org.awaitility.spi" - ], - "org.bitbucket.b_c:jose4j": [ - "org.jose4j.base64url", - "org.jose4j.base64url.internal.apache.commons.codec.binary", - "org.jose4j.http", - "org.jose4j.jca", - "org.jose4j.json", - "org.jose4j.json.internal.json_simple", - "org.jose4j.json.internal.json_simple.parser", - "org.jose4j.jwa", - "org.jose4j.jwe", - "org.jose4j.jwe.kdf", - "org.jose4j.jwk", - "org.jose4j.jws", - "org.jose4j.jwt", - "org.jose4j.jwt.consumer", - "org.jose4j.jwx", - "org.jose4j.keys", - "org.jose4j.keys.resolvers", - "org.jose4j.lang", - "org.jose4j.mac", - "org.jose4j.zip" - ], - "org.bouncycastle:bcpkix-jdk18on": [ - "org.bouncycastle.cert", - "org.bouncycastle.cert.bc", - "org.bouncycastle.cert.cmp", - "org.bouncycastle.cert.crmf", - "org.bouncycastle.cert.crmf.bc", - "org.bouncycastle.cert.crmf.jcajce", - "org.bouncycastle.cert.dane", - "org.bouncycastle.cert.dane.fetcher", - "org.bouncycastle.cert.jcajce", - "org.bouncycastle.cert.ocsp", - "org.bouncycastle.cert.ocsp.jcajce", - "org.bouncycastle.cert.path", - "org.bouncycastle.cert.path.validations", - "org.bouncycastle.cert.selector", - "org.bouncycastle.cert.selector.jcajce", - "org.bouncycastle.cmc", - "org.bouncycastle.cms", - "org.bouncycastle.cms.bc", - "org.bouncycastle.cms.jcajce", - "org.bouncycastle.dvcs", - "org.bouncycastle.eac", - "org.bouncycastle.eac.jcajce", - "org.bouncycastle.eac.operator", - "org.bouncycastle.eac.operator.jcajce", - "org.bouncycastle.est", - "org.bouncycastle.est.jcajce", - "org.bouncycastle.its", - "org.bouncycastle.its.bc", - "org.bouncycastle.its.jcajce", - "org.bouncycastle.its.operator", - "org.bouncycastle.mime", - "org.bouncycastle.mime.encoding", - "org.bouncycastle.mime.smime", - "org.bouncycastle.mozilla", - "org.bouncycastle.mozilla.jcajce", - "org.bouncycastle.openssl", - "org.bouncycastle.openssl.bc", - "org.bouncycastle.openssl.jcajce", - "org.bouncycastle.operator", - "org.bouncycastle.operator.bc", - "org.bouncycastle.operator.jcajce", - "org.bouncycastle.pkcs", - "org.bouncycastle.pkcs.bc", - "org.bouncycastle.pkcs.jcajce", - "org.bouncycastle.pkix", - "org.bouncycastle.pkix.jcajce", - "org.bouncycastle.pkix.util", - "org.bouncycastle.pkix.util.filter", - "org.bouncycastle.tsp", - "org.bouncycastle.tsp.cms", - "org.bouncycastle.tsp.ers", - "org.bouncycastle.voms" - ], - "org.bouncycastle:bcprov-jdk18on": [ - "org.bouncycastle", - "org.bouncycastle.asn1", - "org.bouncycastle.asn1.anssi", - "org.bouncycastle.asn1.bc", - "org.bouncycastle.asn1.cryptopro", - "org.bouncycastle.asn1.gm", - "org.bouncycastle.asn1.nist", - "org.bouncycastle.asn1.ocsp", - "org.bouncycastle.asn1.pkcs", - "org.bouncycastle.asn1.sec", - "org.bouncycastle.asn1.teletrust", - "org.bouncycastle.asn1.ua", - "org.bouncycastle.asn1.util", - "org.bouncycastle.asn1.x500", - "org.bouncycastle.asn1.x500.style", - "org.bouncycastle.asn1.x509", - "org.bouncycastle.asn1.x509.qualified", - "org.bouncycastle.asn1.x509.sigi", - "org.bouncycastle.asn1.x9", - "org.bouncycastle.crypto", - "org.bouncycastle.crypto.agreement", - "org.bouncycastle.crypto.agreement.ecjpake", - "org.bouncycastle.crypto.agreement.jpake", - "org.bouncycastle.crypto.agreement.kdf", - "org.bouncycastle.crypto.agreement.srp", - "org.bouncycastle.crypto.commitments", - "org.bouncycastle.crypto.constraints", - "org.bouncycastle.crypto.digests", - "org.bouncycastle.crypto.ec", - "org.bouncycastle.crypto.encodings", - "org.bouncycastle.crypto.engines", - "org.bouncycastle.crypto.examples", - "org.bouncycastle.crypto.fpe", - "org.bouncycastle.crypto.generators", - "org.bouncycastle.crypto.hash2curve", - "org.bouncycastle.crypto.hash2curve.data", - "org.bouncycastle.crypto.hash2curve.impl", - "org.bouncycastle.crypto.hpke", - "org.bouncycastle.crypto.io", - "org.bouncycastle.crypto.kems", - "org.bouncycastle.crypto.kems.mlkem", - "org.bouncycastle.crypto.macs", - "org.bouncycastle.crypto.modes", - "org.bouncycastle.crypto.modes.gcm", - "org.bouncycastle.crypto.modes.kgcm", - "org.bouncycastle.crypto.paddings", - "org.bouncycastle.crypto.params", - "org.bouncycastle.crypto.parsers", - "org.bouncycastle.crypto.prng", - "org.bouncycastle.crypto.prng.drbg", - "org.bouncycastle.crypto.signers", - "org.bouncycastle.crypto.signers.mldsa", - "org.bouncycastle.crypto.signers.slhdsa", - "org.bouncycastle.crypto.threshold", - "org.bouncycastle.crypto.tls", - "org.bouncycastle.crypto.util", - "org.bouncycastle.i18n", - "org.bouncycastle.i18n.filter", - "org.bouncycastle.iana", - "org.bouncycastle.internal.asn1.bsi", - "org.bouncycastle.internal.asn1.cms", - "org.bouncycastle.internal.asn1.cryptlib", - "org.bouncycastle.internal.asn1.eac", - "org.bouncycastle.internal.asn1.edec", - "org.bouncycastle.internal.asn1.gnu", - "org.bouncycastle.internal.asn1.iana", - "org.bouncycastle.internal.asn1.isara", - "org.bouncycastle.internal.asn1.isismtt", - "org.bouncycastle.internal.asn1.iso", - "org.bouncycastle.internal.asn1.kisa", - "org.bouncycastle.internal.asn1.microsoft", - "org.bouncycastle.internal.asn1.misc", - "org.bouncycastle.internal.asn1.nsri", - "org.bouncycastle.internal.asn1.ntt", - "org.bouncycastle.internal.asn1.oiw", - "org.bouncycastle.internal.asn1.rosstandart", - "org.bouncycastle.jcajce", - "org.bouncycastle.jcajce.interfaces", - "org.bouncycastle.jcajce.io", - "org.bouncycastle.jcajce.provider.asymmetric", - "org.bouncycastle.jcajce.provider.asymmetric.compositesignatures", - "org.bouncycastle.jcajce.provider.asymmetric.dh", - "org.bouncycastle.jcajce.provider.asymmetric.dsa", - "org.bouncycastle.jcajce.provider.asymmetric.dstu", - "org.bouncycastle.jcajce.provider.asymmetric.ec", - "org.bouncycastle.jcajce.provider.asymmetric.ecgost", - "org.bouncycastle.jcajce.provider.asymmetric.ecgost12", - "org.bouncycastle.jcajce.provider.asymmetric.edec", - "org.bouncycastle.jcajce.provider.asymmetric.elgamal", - "org.bouncycastle.jcajce.provider.asymmetric.gost", - "org.bouncycastle.jcajce.provider.asymmetric.ies", - "org.bouncycastle.jcajce.provider.asymmetric.mldsa", - "org.bouncycastle.jcajce.provider.asymmetric.mlkem", - "org.bouncycastle.jcajce.provider.asymmetric.rsa", - "org.bouncycastle.jcajce.provider.asymmetric.slhdsa", - "org.bouncycastle.jcajce.provider.asymmetric.util", - "org.bouncycastle.jcajce.provider.asymmetric.x509", - "org.bouncycastle.jcajce.provider.config", - "org.bouncycastle.jcajce.provider.digest", - "org.bouncycastle.jcajce.provider.drbg", - "org.bouncycastle.jcajce.provider.kdf", - "org.bouncycastle.jcajce.provider.kdf.hkdf", - "org.bouncycastle.jcajce.provider.kdf.pbkdf2", - "org.bouncycastle.jcajce.provider.kdf.scrypt", - "org.bouncycastle.jcajce.provider.keystore", - "org.bouncycastle.jcajce.provider.keystore.bc", - "org.bouncycastle.jcajce.provider.keystore.bcfks", - "org.bouncycastle.jcajce.provider.keystore.pkcs12", - "org.bouncycastle.jcajce.provider.keystore.util", - "org.bouncycastle.jcajce.provider.symmetric", - "org.bouncycastle.jcajce.provider.symmetric.util", - "org.bouncycastle.jcajce.provider.util", - "org.bouncycastle.jcajce.spec", - "org.bouncycastle.jcajce.util", - "org.bouncycastle.jce", - "org.bouncycastle.jce.exception", - "org.bouncycastle.jce.interfaces", - "org.bouncycastle.jce.netscape", - "org.bouncycastle.jce.provider", - "org.bouncycastle.jce.spec", - "org.bouncycastle.ldap", - "org.bouncycastle.math", - "org.bouncycastle.math.ec", - "org.bouncycastle.math.ec.custom.djb", - "org.bouncycastle.math.ec.custom.gm", - "org.bouncycastle.math.ec.custom.sec", - "org.bouncycastle.math.ec.endo", - "org.bouncycastle.math.ec.rfc7748", - "org.bouncycastle.math.ec.rfc8032", - "org.bouncycastle.math.ec.tools", - "org.bouncycastle.math.field", - "org.bouncycastle.math.raw", - "org.bouncycastle.pqc.asn1", - "org.bouncycastle.pqc.crypto", - "org.bouncycastle.pqc.crypto.cmce", - "org.bouncycastle.pqc.crypto.crystals.dilithium", - "org.bouncycastle.pqc.crypto.falcon", - "org.bouncycastle.pqc.crypto.frodo", - "org.bouncycastle.pqc.crypto.hqc", - "org.bouncycastle.pqc.crypto.lms", - "org.bouncycastle.pqc.crypto.mayo", - "org.bouncycastle.pqc.crypto.mldsa", - "org.bouncycastle.pqc.crypto.mlkem", - "org.bouncycastle.pqc.crypto.newhope", - "org.bouncycastle.pqc.crypto.ntru", - "org.bouncycastle.pqc.crypto.ntruplus", - "org.bouncycastle.pqc.crypto.ntruprime", - "org.bouncycastle.pqc.crypto.saber", - "org.bouncycastle.pqc.crypto.slhdsa", - "org.bouncycastle.pqc.crypto.snova", - "org.bouncycastle.pqc.crypto.sphincs", - "org.bouncycastle.pqc.crypto.util", - "org.bouncycastle.pqc.crypto.xmss", - "org.bouncycastle.pqc.crypto.xwing", - "org.bouncycastle.pqc.jcajce.interfaces", - "org.bouncycastle.pqc.jcajce.provider", - "org.bouncycastle.pqc.jcajce.provider.bike", - "org.bouncycastle.pqc.jcajce.provider.cmce", - "org.bouncycastle.pqc.jcajce.provider.dilithium", - "org.bouncycastle.pqc.jcajce.provider.falcon", - "org.bouncycastle.pqc.jcajce.provider.frodo", - "org.bouncycastle.pqc.jcajce.provider.hqc", - "org.bouncycastle.pqc.jcajce.provider.kyber", - "org.bouncycastle.pqc.jcajce.provider.lms", - "org.bouncycastle.pqc.jcajce.provider.mayo", - "org.bouncycastle.pqc.jcajce.provider.newhope", - "org.bouncycastle.pqc.jcajce.provider.ntru", - "org.bouncycastle.pqc.jcajce.provider.ntruplus", - "org.bouncycastle.pqc.jcajce.provider.ntruprime", - "org.bouncycastle.pqc.jcajce.provider.picnic", - "org.bouncycastle.pqc.jcajce.provider.saber", - "org.bouncycastle.pqc.jcajce.provider.snova", - "org.bouncycastle.pqc.jcajce.provider.sphincs", - "org.bouncycastle.pqc.jcajce.provider.sphincsplus", - "org.bouncycastle.pqc.jcajce.provider.util", - "org.bouncycastle.pqc.jcajce.provider.xmss", - "org.bouncycastle.pqc.jcajce.spec", - "org.bouncycastle.pqc.legacy.bike", - "org.bouncycastle.pqc.legacy.picnic", - "org.bouncycastle.pqc.legacy.rainbow", - "org.bouncycastle.pqc.legacy.sphincsplus", - "org.bouncycastle.pqc.math.ntru", - "org.bouncycastle.pqc.math.ntru.parameters", - "org.bouncycastle.util", - "org.bouncycastle.util.encoders", - "org.bouncycastle.util.io", - "org.bouncycastle.util.io.pem", - "org.bouncycastle.util.test", - "org.bouncycastle.x509", - "org.bouncycastle.x509.extension", - "org.bouncycastle.x509.util" - ], - "org.bouncycastle:bcprov-lts8on": [ - "org.bouncycastle", - "org.bouncycastle.asn1", - "org.bouncycastle.asn1.anssi", - "org.bouncycastle.asn1.bc", - "org.bouncycastle.asn1.cryptlib", - "org.bouncycastle.asn1.cryptopro", - "org.bouncycastle.asn1.edec", - "org.bouncycastle.asn1.gm", - "org.bouncycastle.asn1.gnu", - "org.bouncycastle.asn1.iana", - "org.bouncycastle.asn1.isara", - "org.bouncycastle.asn1.iso", - "org.bouncycastle.asn1.kisa", - "org.bouncycastle.asn1.microsoft", - "org.bouncycastle.asn1.misc", - "org.bouncycastle.asn1.mozilla", - "org.bouncycastle.asn1.nist", - "org.bouncycastle.asn1.nsri", - "org.bouncycastle.asn1.ntt", - "org.bouncycastle.asn1.ocsp", - "org.bouncycastle.asn1.oiw", - "org.bouncycastle.asn1.pkcs", - "org.bouncycastle.asn1.rosstandart", - "org.bouncycastle.asn1.sec", - "org.bouncycastle.asn1.teletrust", - "org.bouncycastle.asn1.ua", - "org.bouncycastle.asn1.util", - "org.bouncycastle.asn1.x500", - "org.bouncycastle.asn1.x500.style", - "org.bouncycastle.asn1.x509", - "org.bouncycastle.asn1.x509.qualified", - "org.bouncycastle.asn1.x509.sigi", - "org.bouncycastle.asn1.x9", - "org.bouncycastle.crypto", - "org.bouncycastle.crypto.agreement", - "org.bouncycastle.crypto.agreement.ecjpake", - "org.bouncycastle.crypto.agreement.jpake", - "org.bouncycastle.crypto.agreement.kdf", - "org.bouncycastle.crypto.agreement.srp", - "org.bouncycastle.crypto.commitments", - "org.bouncycastle.crypto.constraints", - "org.bouncycastle.crypto.digests", - "org.bouncycastle.crypto.ec", - "org.bouncycastle.crypto.encodings", - "org.bouncycastle.crypto.engines", - "org.bouncycastle.crypto.fpe", - "org.bouncycastle.crypto.generators", - "org.bouncycastle.crypto.hpke", - "org.bouncycastle.crypto.io", - "org.bouncycastle.crypto.kems", - "org.bouncycastle.crypto.macs", - "org.bouncycastle.crypto.modes", - "org.bouncycastle.crypto.modes.gcm", - "org.bouncycastle.crypto.modes.kgcm", - "org.bouncycastle.crypto.paddings", - "org.bouncycastle.crypto.params", - "org.bouncycastle.crypto.parsers", - "org.bouncycastle.crypto.prng", - "org.bouncycastle.crypto.prng.drbg", - "org.bouncycastle.crypto.signers", - "org.bouncycastle.crypto.tls", - "org.bouncycastle.crypto.util", - "org.bouncycastle.iana", - "org.bouncycastle.internal.asn1.bsi", - "org.bouncycastle.internal.asn1.cms", - "org.bouncycastle.internal.asn1.cryptlib", - "org.bouncycastle.internal.asn1.eac", - "org.bouncycastle.internal.asn1.edec", - "org.bouncycastle.internal.asn1.gnu", - "org.bouncycastle.internal.asn1.iana", - "org.bouncycastle.internal.asn1.isara", - "org.bouncycastle.internal.asn1.isismtt", - "org.bouncycastle.internal.asn1.iso", - "org.bouncycastle.internal.asn1.kisa", - "org.bouncycastle.internal.asn1.microsoft", - "org.bouncycastle.internal.asn1.misc", - "org.bouncycastle.internal.asn1.nsri", - "org.bouncycastle.internal.asn1.ntt", - "org.bouncycastle.internal.asn1.oiw", - "org.bouncycastle.internal.asn1.rosstandart", - "org.bouncycastle.jcajce", - "org.bouncycastle.jcajce.interfaces", - "org.bouncycastle.jcajce.io", - "org.bouncycastle.jcajce.provider.asymmetric", - "org.bouncycastle.jcajce.provider.asymmetric.compositesignatures", - "org.bouncycastle.jcajce.provider.asymmetric.dh", - "org.bouncycastle.jcajce.provider.asymmetric.dsa", - "org.bouncycastle.jcajce.provider.asymmetric.dstu", - "org.bouncycastle.jcajce.provider.asymmetric.ec", - "org.bouncycastle.jcajce.provider.asymmetric.ecgost", - "org.bouncycastle.jcajce.provider.asymmetric.ecgost12", - "org.bouncycastle.jcajce.provider.asymmetric.edec", - "org.bouncycastle.jcajce.provider.asymmetric.elgamal", - "org.bouncycastle.jcajce.provider.asymmetric.gost", - "org.bouncycastle.jcajce.provider.asymmetric.ies", - "org.bouncycastle.jcajce.provider.asymmetric.mldsa", - "org.bouncycastle.jcajce.provider.asymmetric.mlkem", - "org.bouncycastle.jcajce.provider.asymmetric.rsa", - "org.bouncycastle.jcajce.provider.asymmetric.slhdsa", - "org.bouncycastle.jcajce.provider.asymmetric.util", - "org.bouncycastle.jcajce.provider.asymmetric.x509", - "org.bouncycastle.jcajce.provider.config", - "org.bouncycastle.jcajce.provider.digest", - "org.bouncycastle.jcajce.provider.drbg", - "org.bouncycastle.jcajce.provider.keystore", - "org.bouncycastle.jcajce.provider.keystore.bc", - "org.bouncycastle.jcajce.provider.keystore.bcfks", - "org.bouncycastle.jcajce.provider.keystore.pkcs12", - "org.bouncycastle.jcajce.provider.keystore.util", - "org.bouncycastle.jcajce.provider.symmetric", - "org.bouncycastle.jcajce.provider.symmetric.util", - "org.bouncycastle.jcajce.provider.util", - "org.bouncycastle.jcajce.spec", - "org.bouncycastle.jcajce.util", - "org.bouncycastle.jce", - "org.bouncycastle.jce.exception", - "org.bouncycastle.jce.interfaces", - "org.bouncycastle.jce.netscape", - "org.bouncycastle.jce.provider", - "org.bouncycastle.jce.spec", - "org.bouncycastle.math", - "org.bouncycastle.math.ec", - "org.bouncycastle.math.ec.custom.djb", - "org.bouncycastle.math.ec.custom.gm", - "org.bouncycastle.math.ec.custom.sec", - "org.bouncycastle.math.ec.endo", - "org.bouncycastle.math.ec.rfc7748", - "org.bouncycastle.math.ec.rfc8032", - "org.bouncycastle.math.ec.tools", - "org.bouncycastle.math.field", - "org.bouncycastle.math.raw", - "org.bouncycastle.pqc.crypto", - "org.bouncycastle.pqc.crypto.lms", - "org.bouncycastle.pqc.crypto.mldsa", - "org.bouncycastle.pqc.crypto.mlkem", - "org.bouncycastle.pqc.crypto.slhdsa", - "org.bouncycastle.pqc.crypto.util", - "org.bouncycastle.pqc.jcajce.interfaces", - "org.bouncycastle.pqc.jcajce.provider.lms", - "org.bouncycastle.pqc.jcajce.provider.util", - "org.bouncycastle.pqc.jcajce.spec", - "org.bouncycastle.util", - "org.bouncycastle.util.dispose", - "org.bouncycastle.util.encoders", - "org.bouncycastle.util.io", - "org.bouncycastle.util.io.pem", - "org.bouncycastle.util.test" - ], - "org.bouncycastle:bcutil-jdk18on": [ - "org.bouncycastle.asn1.bsi", - "org.bouncycastle.asn1.cmc", - "org.bouncycastle.asn1.cmp", - "org.bouncycastle.asn1.cms", - "org.bouncycastle.asn1.cms.ecc", - "org.bouncycastle.asn1.crmf", - "org.bouncycastle.asn1.cryptlib", - "org.bouncycastle.asn1.dvcs", - "org.bouncycastle.asn1.eac", - "org.bouncycastle.asn1.edec", - "org.bouncycastle.asn1.esf", - "org.bouncycastle.asn1.ess", - "org.bouncycastle.asn1.est", - "org.bouncycastle.asn1.gnu", - "org.bouncycastle.asn1.iana", - "org.bouncycastle.asn1.icao", - "org.bouncycastle.asn1.isara", - "org.bouncycastle.asn1.isismtt", - "org.bouncycastle.asn1.isismtt.ocsp", - "org.bouncycastle.asn1.isismtt.x509", - "org.bouncycastle.asn1.iso", - "org.bouncycastle.asn1.kisa", - "org.bouncycastle.asn1.microsoft", - "org.bouncycastle.asn1.misc", - "org.bouncycastle.asn1.mozilla", - "org.bouncycastle.asn1.nsri", - "org.bouncycastle.asn1.ntt", - "org.bouncycastle.asn1.oiw", - "org.bouncycastle.asn1.rosstandart", - "org.bouncycastle.asn1.smime", - "org.bouncycastle.asn1.tsp", - "org.bouncycastle.oer", - "org.bouncycastle.oer.its", - "org.bouncycastle.oer.its.etsi102941", - "org.bouncycastle.oer.its.etsi102941.basetypes", - "org.bouncycastle.oer.its.etsi103097", - "org.bouncycastle.oer.its.etsi103097.extension", - "org.bouncycastle.oer.its.ieee1609dot2", - "org.bouncycastle.oer.its.ieee1609dot2.basetypes", - "org.bouncycastle.oer.its.ieee1609dot2dot1", - "org.bouncycastle.oer.its.template.etsi102941", - "org.bouncycastle.oer.its.template.etsi102941.basetypes", - "org.bouncycastle.oer.its.template.etsi103097", - "org.bouncycastle.oer.its.template.etsi103097.extension", - "org.bouncycastle.oer.its.template.ieee1609dot2", - "org.bouncycastle.oer.its.template.ieee1609dot2.basetypes", - "org.bouncycastle.oer.its.template.ieee1609dot2dot1" - ], - "org.codehaus.mojo:animal-sniffer-annotations": [ - "org.codehaus.mojo.animal_sniffer" - ], - "org.hamcrest:hamcrest": [ - "org.hamcrest", - "org.hamcrest.beans", - "org.hamcrest.collection", - "org.hamcrest.comparator", - "org.hamcrest.core", - "org.hamcrest.internal", - "org.hamcrest.io", - "org.hamcrest.number", - "org.hamcrest.object", - "org.hamcrest.text", - "org.hamcrest.xml" - ], - "org.hdrhistogram:HdrHistogram": [ - "org.HdrHistogram", - "org.HdrHistogram.packedarray" - ], - "org.hibernate.validator:hibernate-validator": [ - "org.hibernate.validator", - "org.hibernate.validator.cfg", - "org.hibernate.validator.cfg.context", - "org.hibernate.validator.cfg.defs", - "org.hibernate.validator.cfg.defs.br", - "org.hibernate.validator.cfg.defs.kor", - "org.hibernate.validator.cfg.defs.pl", - "org.hibernate.validator.cfg.defs.ru", - "org.hibernate.validator.constraints", - "org.hibernate.validator.constraints.br", - "org.hibernate.validator.constraints.kor", - "org.hibernate.validator.constraints.pl", - "org.hibernate.validator.constraints.ru", - "org.hibernate.validator.constraints.time", - "org.hibernate.validator.constraintvalidation", - "org.hibernate.validator.constraintvalidation.spi", - "org.hibernate.validator.constraintvalidators", - "org.hibernate.validator.engine", - "org.hibernate.validator.group", - "org.hibernate.validator.internal", - "org.hibernate.validator.internal.cfg", - "org.hibernate.validator.internal.cfg.context", - "org.hibernate.validator.internal.constraintvalidators", - "org.hibernate.validator.internal.constraintvalidators.bv", - "org.hibernate.validator.internal.constraintvalidators.bv.money", - "org.hibernate.validator.internal.constraintvalidators.bv.notempty", - "org.hibernate.validator.internal.constraintvalidators.bv.number", - "org.hibernate.validator.internal.constraintvalidators.bv.number.bound", - "org.hibernate.validator.internal.constraintvalidators.bv.number.bound.decimal", - "org.hibernate.validator.internal.constraintvalidators.bv.number.sign", - "org.hibernate.validator.internal.constraintvalidators.bv.size", - "org.hibernate.validator.internal.constraintvalidators.bv.time", - "org.hibernate.validator.internal.constraintvalidators.bv.time.future", - "org.hibernate.validator.internal.constraintvalidators.bv.time.futureorpresent", - "org.hibernate.validator.internal.constraintvalidators.bv.time.past", - "org.hibernate.validator.internal.constraintvalidators.bv.time.pastorpresent", - "org.hibernate.validator.internal.constraintvalidators.hv", - "org.hibernate.validator.internal.constraintvalidators.hv.br", - "org.hibernate.validator.internal.constraintvalidators.hv.kor", - "org.hibernate.validator.internal.constraintvalidators.hv.pl", - "org.hibernate.validator.internal.constraintvalidators.hv.ru", - "org.hibernate.validator.internal.constraintvalidators.hv.time", - "org.hibernate.validator.internal.engine", - "org.hibernate.validator.internal.engine.constraintdefinition", - "org.hibernate.validator.internal.engine.constraintvalidation", - "org.hibernate.validator.internal.engine.groups", - "org.hibernate.validator.internal.engine.messageinterpolation", - "org.hibernate.validator.internal.engine.messageinterpolation.el", - "org.hibernate.validator.internal.engine.messageinterpolation.parser", - "org.hibernate.validator.internal.engine.messageinterpolation.util", - "org.hibernate.validator.internal.engine.path", - "org.hibernate.validator.internal.engine.resolver", - "org.hibernate.validator.internal.engine.scripting", - "org.hibernate.validator.internal.engine.validationcontext", - "org.hibernate.validator.internal.engine.valuecontext", - "org.hibernate.validator.internal.engine.valueextraction", - "org.hibernate.validator.internal.metadata", - "org.hibernate.validator.internal.metadata.aggregated", - "org.hibernate.validator.internal.metadata.aggregated.rule", - "org.hibernate.validator.internal.metadata.core", - "org.hibernate.validator.internal.metadata.descriptor", - "org.hibernate.validator.internal.metadata.facets", - "org.hibernate.validator.internal.metadata.location", - "org.hibernate.validator.internal.metadata.provider", - "org.hibernate.validator.internal.metadata.raw", - "org.hibernate.validator.internal.properties", - "org.hibernate.validator.internal.properties.javabean", - "org.hibernate.validator.internal.util", - "org.hibernate.validator.internal.util.actions", - "org.hibernate.validator.internal.util.annotation", - "org.hibernate.validator.internal.util.classhierarchy", - "org.hibernate.validator.internal.util.logging", - "org.hibernate.validator.internal.util.logging.formatter", - "org.hibernate.validator.internal.util.stereotypes", - "org.hibernate.validator.internal.xml", - "org.hibernate.validator.internal.xml.config", - "org.hibernate.validator.internal.xml.mapping", - "org.hibernate.validator.messageinterpolation", - "org.hibernate.validator.metadata", - "org.hibernate.validator.parameternameprovider", - "org.hibernate.validator.path", - "org.hibernate.validator.resourceloading", - "org.hibernate.validator.spi.cfg", - "org.hibernate.validator.spi.group", - "org.hibernate.validator.spi.messageinterpolation", - "org.hibernate.validator.spi.nodenameprovider", - "org.hibernate.validator.spi.properties", - "org.hibernate.validator.spi.resourceloading", - "org.hibernate.validator.spi.scripting" - ], - "org.jacoco:org.jacoco.agent:jar:runtime": [ - "com.vladium.emma.rt", - "org.jacoco.agent.rt", - "org.jacoco.agent.rt.internal_29a6edd", - "org.jacoco.agent.rt.internal_29a6edd.asm", - "org.jacoco.agent.rt.internal_29a6edd.asm.commons", - "org.jacoco.agent.rt.internal_29a6edd.asm.tree", - "org.jacoco.agent.rt.internal_29a6edd.core", - "org.jacoco.agent.rt.internal_29a6edd.core.analysis", - "org.jacoco.agent.rt.internal_29a6edd.core.data", - "org.jacoco.agent.rt.internal_29a6edd.core.instr", - "org.jacoco.agent.rt.internal_29a6edd.core.internal", - "org.jacoco.agent.rt.internal_29a6edd.core.internal.analysis", - "org.jacoco.agent.rt.internal_29a6edd.core.internal.analysis.filter", - "org.jacoco.agent.rt.internal_29a6edd.core.internal.data", - "org.jacoco.agent.rt.internal_29a6edd.core.internal.flow", - "org.jacoco.agent.rt.internal_29a6edd.core.internal.instr", - "org.jacoco.agent.rt.internal_29a6edd.core.runtime", - "org.jacoco.agent.rt.internal_29a6edd.core.tools", - "org.jacoco.agent.rt.internal_29a6edd.output" - ], - "org.jacoco:org.jacoco.cli": [ - "org.jacoco.cli.internal", - "org.jacoco.cli.internal.commands" - ], - "org.jacoco:org.jacoco.core": [ - "org.jacoco.core", - "org.jacoco.core.analysis", - "org.jacoco.core.data", - "org.jacoco.core.instr", - "org.jacoco.core.internal", - "org.jacoco.core.internal.analysis", - "org.jacoco.core.internal.analysis.filter", - "org.jacoco.core.internal.data", - "org.jacoco.core.internal.flow", - "org.jacoco.core.internal.instr", - "org.jacoco.core.runtime", - "org.jacoco.core.tools" - ], - "org.jacoco:org.jacoco.report": [ - "org.jacoco.report", - "org.jacoco.report.check", - "org.jacoco.report.csv", - "org.jacoco.report.html", - "org.jacoco.report.internal", - "org.jacoco.report.internal.html", - "org.jacoco.report.internal.html.index", - "org.jacoco.report.internal.html.page", - "org.jacoco.report.internal.html.resources", - "org.jacoco.report.internal.html.table", - "org.jacoco.report.internal.xml", - "org.jacoco.report.xml" - ], - "org.jboss.logging:jboss-logging": [ - "org.jboss.logging" - ], - "org.jetbrains.kotlin:kotlin-stdlib": [ - "kotlin", - "kotlin.annotation", - "kotlin.collections", - "kotlin.collections.builders", - "kotlin.collections.jdk8", - "kotlin.collections.unsigned", - "kotlin.comparisons", - "kotlin.concurrent", - "kotlin.concurrent.atomics", - "kotlin.concurrent.internal", - "kotlin.contracts", - "kotlin.coroutines", - "kotlin.coroutines.cancellation", - "kotlin.coroutines.intrinsics", - "kotlin.coroutines.jvm.internal", - "kotlin.enums", - "kotlin.experimental", - "kotlin.internal", - "kotlin.internal.jdk7", - "kotlin.internal.jdk8", - "kotlin.io", - "kotlin.io.encoding", - "kotlin.io.path", - "kotlin.jdk7", - "kotlin.js", - "kotlin.jvm", - "kotlin.jvm.functions", - "kotlin.jvm.internal", - "kotlin.jvm.internal.markers", - "kotlin.jvm.internal.unsafe", - "kotlin.jvm.jdk8", - "kotlin.jvm.optionals", - "kotlin.math", - "kotlin.properties", - "kotlin.random", - "kotlin.random.jdk8", - "kotlin.ranges", - "kotlin.reflect", - "kotlin.sequences", - "kotlin.streams.jdk8", - "kotlin.system", - "kotlin.text", - "kotlin.text.jdk8", - "kotlin.time", - "kotlin.time.jdk8", - "kotlin.uuid" - ], - "org.jetbrains:annotations": [ - "org.intellij.lang.annotations", - "org.jetbrains.annotations" - ], - "org.jspecify:jspecify": [ - "org.jspecify.annotations" - ], - "org.junit.jupiter:junit-jupiter-api": [ - "org.junit.jupiter.api", - "org.junit.jupiter.api.condition", - "org.junit.jupiter.api.extension", - "org.junit.jupiter.api.extension.support", - "org.junit.jupiter.api.function", - "org.junit.jupiter.api.io", - "org.junit.jupiter.api.parallel", - "org.junit.jupiter.api.util" - ], - "org.junit.jupiter:junit-jupiter-engine": [ - "org.junit.jupiter.engine", - "org.junit.jupiter.engine.config", - "org.junit.jupiter.engine.descriptor", - "org.junit.jupiter.engine.discovery", - "org.junit.jupiter.engine.discovery.predicates", - "org.junit.jupiter.engine.execution", - "org.junit.jupiter.engine.extension", - "org.junit.jupiter.engine.support" - ], - "org.junit.jupiter:junit-jupiter-params": [ - "org.junit.jupiter.params", - "org.junit.jupiter.params.aggregator", - "org.junit.jupiter.params.converter", - "org.junit.jupiter.params.provider", - "org.junit.jupiter.params.shadow.de.siegmar.fastcsv.reader", - "org.junit.jupiter.params.shadow.de.siegmar.fastcsv.util", - "org.junit.jupiter.params.shadow.de.siegmar.fastcsv.writer", - "org.junit.jupiter.params.support" - ], - "org.junit.platform:junit-platform-commons": [ - "org.junit.platform.commons", - "org.junit.platform.commons.annotation", - "org.junit.platform.commons.function", - "org.junit.platform.commons.io", - "org.junit.platform.commons.logging", - "org.junit.platform.commons.support", - "org.junit.platform.commons.support.conversion", - "org.junit.platform.commons.support.scanning", - "org.junit.platform.commons.util" - ], - "org.junit.platform:junit-platform-console-standalone": [ - "junit.extensions", - "junit.framework", - "junit.runner", - "junit.textui", - "org.apiguardian.api", - "org.hamcrest", - "org.hamcrest.core", - "org.hamcrest.internal", - "org.junit", - "org.junit.experimental", - "org.junit.experimental.categories", - "org.junit.experimental.max", - "org.junit.experimental.results", - "org.junit.experimental.runners", - "org.junit.experimental.theories", - "org.junit.experimental.theories.internal", - "org.junit.experimental.theories.suppliers", - "org.junit.function", - "org.junit.internal", - "org.junit.internal.builders", - "org.junit.internal.management", - "org.junit.internal.matchers", - "org.junit.internal.requests", - "org.junit.internal.runners", - "org.junit.internal.runners.model", - "org.junit.internal.runners.rules", - "org.junit.internal.runners.statements", - "org.junit.jupiter.api", - "org.junit.jupiter.api.condition", - "org.junit.jupiter.api.extension", - "org.junit.jupiter.api.extension.support", - "org.junit.jupiter.api.function", - "org.junit.jupiter.api.io", - "org.junit.jupiter.api.parallel", - "org.junit.jupiter.api.util", - "org.junit.jupiter.engine", - "org.junit.jupiter.engine.config", - "org.junit.jupiter.engine.descriptor", - "org.junit.jupiter.engine.discovery", - "org.junit.jupiter.engine.discovery.predicates", - "org.junit.jupiter.engine.execution", - "org.junit.jupiter.engine.extension", - "org.junit.jupiter.engine.support", - "org.junit.jupiter.params", - "org.junit.jupiter.params.aggregator", - "org.junit.jupiter.params.converter", - "org.junit.jupiter.params.provider", - "org.junit.jupiter.params.shadow.de.siegmar.fastcsv.reader", - "org.junit.jupiter.params.shadow.de.siegmar.fastcsv.util", - "org.junit.jupiter.params.shadow.de.siegmar.fastcsv.writer", - "org.junit.jupiter.params.support", - "org.junit.matchers", - "org.junit.platform.commons", - "org.junit.platform.commons.annotation", - "org.junit.platform.commons.function", - "org.junit.platform.commons.io", - "org.junit.platform.commons.logging", - "org.junit.platform.commons.support", - "org.junit.platform.commons.support.conversion", - "org.junit.platform.commons.support.scanning", - "org.junit.platform.commons.util", - "org.junit.platform.console", - "org.junit.platform.console.command", - "org.junit.platform.console.options", - "org.junit.platform.console.output", - "org.junit.platform.console.shadow.picocli", - "org.junit.platform.engine", - "org.junit.platform.engine.discovery", - "org.junit.platform.engine.reporting", - "org.junit.platform.engine.support.config", - "org.junit.platform.engine.support.descriptor", - "org.junit.platform.engine.support.discovery", - "org.junit.platform.engine.support.hierarchical", - "org.junit.platform.engine.support.store", - "org.junit.platform.launcher", - "org.junit.platform.launcher.core", - "org.junit.platform.launcher.jfr", - "org.junit.platform.launcher.listeners", - "org.junit.platform.launcher.listeners.discovery", - "org.junit.platform.launcher.listeners.session", - "org.junit.platform.launcher.tagexpression", - "org.junit.platform.reporting", - "org.junit.platform.reporting.legacy", - "org.junit.platform.reporting.legacy.xml", - "org.junit.platform.reporting.open.xml", - "org.junit.platform.reporting.shadow.org.opentest4j.reporting.events.api", - "org.junit.platform.reporting.shadow.org.opentest4j.reporting.events.core", - "org.junit.platform.reporting.shadow.org.opentest4j.reporting.events.git", - "org.junit.platform.reporting.shadow.org.opentest4j.reporting.events.java", - "org.junit.platform.reporting.shadow.org.opentest4j.reporting.events.root", - "org.junit.platform.reporting.shadow.org.opentest4j.reporting.schema", - "org.junit.platform.suite.api", - "org.junit.platform.suite.engine", - "org.junit.rules", - "org.junit.runner", - "org.junit.runner.manipulation", - "org.junit.runner.notification", - "org.junit.runners", - "org.junit.runners.model", - "org.junit.runners.parameterized", - "org.junit.validator", - "org.junit.vintage.engine", - "org.junit.vintage.engine.descriptor", - "org.junit.vintage.engine.discovery", - "org.junit.vintage.engine.execution", - "org.junit.vintage.engine.support", - "org.opentest4j", - "org.opentest4j.reporting.tooling.spi.htmlreport" - ], - "org.junit.platform:junit-platform-engine": [ - "org.junit.platform.engine", - "org.junit.platform.engine.discovery", - "org.junit.platform.engine.reporting", - "org.junit.platform.engine.support.config", - "org.junit.platform.engine.support.descriptor", - "org.junit.platform.engine.support.discovery", - "org.junit.platform.engine.support.hierarchical", - "org.junit.platform.engine.support.store" - ], - "org.latencyutils:LatencyUtils": [ - "org.LatencyUtils" - ], - "org.mockito:mockito-core": [ - "org.mockito", - "org.mockito.configuration", - "org.mockito.creation.instance", - "org.mockito.exceptions.base", - "org.mockito.exceptions.misusing", - "org.mockito.exceptions.stacktrace", - "org.mockito.exceptions.verification", - "org.mockito.exceptions.verification.junit", - "org.mockito.exceptions.verification.opentest4j", - "org.mockito.hamcrest", - "org.mockito.internal", - "org.mockito.internal.configuration", - "org.mockito.internal.configuration.injection", - "org.mockito.internal.configuration.injection.filter", - "org.mockito.internal.configuration.injection.scanner", - "org.mockito.internal.configuration.plugins", - "org.mockito.internal.creation", - "org.mockito.internal.creation.bytebuddy", - "org.mockito.internal.creation.bytebuddy.access", - "org.mockito.internal.creation.bytebuddy.codegen", - "org.mockito.internal.creation.instance", - "org.mockito.internal.creation.proxy", - "org.mockito.internal.creation.settings", - "org.mockito.internal.creation.util", - "org.mockito.internal.debugging", - "org.mockito.internal.exceptions", - "org.mockito.internal.exceptions.stacktrace", - "org.mockito.internal.exceptions.util", - "org.mockito.internal.framework", - "org.mockito.internal.hamcrest", - "org.mockito.internal.handler", - "org.mockito.internal.invocation", - "org.mockito.internal.invocation.finder", - "org.mockito.internal.invocation.mockref", - "org.mockito.internal.junit", - "org.mockito.internal.listeners", - "org.mockito.internal.matchers", - "org.mockito.internal.matchers.apachecommons", - "org.mockito.internal.matchers.text", - "org.mockito.internal.progress", - "org.mockito.internal.reporting", - "org.mockito.internal.runners", - "org.mockito.internal.runners.util", - "org.mockito.internal.session", - "org.mockito.internal.stubbing", - "org.mockito.internal.stubbing.answers", - "org.mockito.internal.stubbing.defaultanswers", - "org.mockito.internal.util", - "org.mockito.internal.util.collections", - "org.mockito.internal.util.concurrent", - "org.mockito.internal.util.io", - "org.mockito.internal.util.reflection", - "org.mockito.internal.verification", - "org.mockito.internal.verification.api", - "org.mockito.internal.verification.argumentmatching", - "org.mockito.internal.verification.checkers", - "org.mockito.invocation", - "org.mockito.junit", - "org.mockito.listeners", - "org.mockito.mock", - "org.mockito.plugins", - "org.mockito.quality", - "org.mockito.session", - "org.mockito.stubbing", - "org.mockito.verification" - ], - "org.mockito:mockito-junit-jupiter": [ - "org.mockito.junit.jupiter", - "org.mockito.junit.jupiter.resolver" - ], - "org.objenesis:objenesis": [ - "org.objenesis", - "org.objenesis.instantiator", - "org.objenesis.instantiator.android", - "org.objenesis.instantiator.annotations", - "org.objenesis.instantiator.basic", - "org.objenesis.instantiator.gcj", - "org.objenesis.instantiator.perc", - "org.objenesis.instantiator.sun", - "org.objenesis.instantiator.util", - "org.objenesis.strategy" - ], - "org.opentest4j:opentest4j": [ - "org.opentest4j" - ], - "org.ow2.asm:asm": [ - "org.objectweb.asm", - "org.objectweb.asm.signature" - ], - "org.ow2.asm:asm-analysis": [ - "org.objectweb.asm.tree.analysis" - ], - "org.ow2.asm:asm-commons": [ - "org.objectweb.asm.commons" - ], - "org.ow2.asm:asm-tree": [ - "org.objectweb.asm.tree" - ], - "org.ow2.asm:asm-util": [ - "org.objectweb.asm.util" - ], - "org.projectlombok:lombok": [ - "lombok", - "lombok.delombok.ant", - "lombok.experimental", - "lombok.extern.apachecommons", - "lombok.extern.flogger", - "lombok.extern.jackson", - "lombok.extern.java", - "lombok.extern.jbosslog", - "lombok.extern.log4j", - "lombok.extern.slf4j", - "lombok.javac.apt", - "lombok.launch" - ], - "org.reactivestreams:reactive-streams": [ - "org.reactivestreams" - ], - "org.rnorth.duct-tape:duct-tape": [ - "org.rnorth.ducttape", - "org.rnorth.ducttape.circuitbreakers", - "org.rnorth.ducttape.inconsistents", - "org.rnorth.ducttape.ratelimits", - "org.rnorth.ducttape.timeouts", - "org.rnorth.ducttape.unreliables" - ], - "org.skyscreamer:jsonassert": [ - "org.json", - "org.skyscreamer.jsonassert", - "org.skyscreamer.jsonassert.comparator" - ], - "org.slf4j:jul-to-slf4j": [ - "org.slf4j.bridge" - ], - "org.slf4j:slf4j-api": [ - "org.slf4j", - "org.slf4j.event", - "org.slf4j.helpers", - "org.slf4j.spi" - ], - "org.springdoc:springdoc-openapi-starter-common": [ - "org.springdoc.api", - "org.springdoc.core.annotations", - "org.springdoc.core.conditions", - "org.springdoc.core.configuration", - "org.springdoc.core.configuration.hints", - "org.springdoc.core.configuration.oauth2", - "org.springdoc.core.configurer", - "org.springdoc.core.converters", - "org.springdoc.core.converters.models", - "org.springdoc.core.customizers", - "org.springdoc.core.data", - "org.springdoc.core.discoverer", - "org.springdoc.core.events", - "org.springdoc.core.extractor", - "org.springdoc.core.filters", - "org.springdoc.core.fn", - "org.springdoc.core.fn.builders.apiresponse", - "org.springdoc.core.fn.builders.arrayschema", - "org.springdoc.core.fn.builders.content", - "org.springdoc.core.fn.builders.discriminatormapping", - "org.springdoc.core.fn.builders.encoding", - "org.springdoc.core.fn.builders.exampleobject", - "org.springdoc.core.fn.builders.extension", - "org.springdoc.core.fn.builders.extensionproperty", - "org.springdoc.core.fn.builders.externaldocumentation", - "org.springdoc.core.fn.builders.header", - "org.springdoc.core.fn.builders.link", - "org.springdoc.core.fn.builders.linkparameter", - "org.springdoc.core.fn.builders.operation", - "org.springdoc.core.fn.builders.parameter", - "org.springdoc.core.fn.builders.requestbody", - "org.springdoc.core.fn.builders.schema", - "org.springdoc.core.fn.builders.securityrequirement", - "org.springdoc.core.fn.builders.server", - "org.springdoc.core.fn.builders.servervariable", - "org.springdoc.core.mixins", - "org.springdoc.core.models", - "org.springdoc.core.properties", - "org.springdoc.core.providers", - "org.springdoc.core.service", - "org.springdoc.core.utils", - "org.springdoc.core.versions", - "org.springdoc.scalar", - "org.springdoc.ui" - ], - "org.springdoc:springdoc-openapi-starter-webflux-api": [ - "org.springdoc.webflux.api", - "org.springdoc.webflux.core.configuration", - "org.springdoc.webflux.core.configuration.hints", - "org.springdoc.webflux.core.fn", - "org.springdoc.webflux.core.providers", - "org.springdoc.webflux.core.service", - "org.springdoc.webflux.core.visitor" - ], - "org.springdoc:springdoc-openapi-starter-webmvc-api": [ - "org.springdoc.webmvc.api", - "org.springdoc.webmvc.core.configuration", - "org.springdoc.webmvc.core.configuration.hints", - "org.springdoc.webmvc.core.fn", - "org.springdoc.webmvc.core.providers", - "org.springdoc.webmvc.core.service" - ], - "org.springframework.boot:spring-boot": [ - "org.springframework.boot", - "org.springframework.boot.admin", - "org.springframework.boot.ansi", - "org.springframework.boot.availability", - "org.springframework.boot.bootstrap", - "org.springframework.boot.builder", - "org.springframework.boot.cloud", - "org.springframework.boot.context", - "org.springframework.boot.context.annotation", - "org.springframework.boot.context.config", - "org.springframework.boot.context.event", - "org.springframework.boot.context.logging", - "org.springframework.boot.context.metrics.buffering", - "org.springframework.boot.context.properties", - "org.springframework.boot.context.properties.bind", - "org.springframework.boot.context.properties.bind.handler", - "org.springframework.boot.context.properties.bind.validation", - "org.springframework.boot.context.properties.source", - "org.springframework.boot.convert", - "org.springframework.boot.diagnostics", - "org.springframework.boot.diagnostics.analyzer", - "org.springframework.boot.env", - "org.springframework.boot.info", - "org.springframework.boot.io", - "org.springframework.boot.json", - "org.springframework.boot.logging", - "org.springframework.boot.logging.java", - "org.springframework.boot.logging.log4j2", - "org.springframework.boot.logging.logback", - "org.springframework.boot.logging.structured", - "org.springframework.boot.origin", - "org.springframework.boot.retry", - "org.springframework.boot.ssl", - "org.springframework.boot.ssl.jks", - "org.springframework.boot.ssl.pem", - "org.springframework.boot.support", - "org.springframework.boot.system", - "org.springframework.boot.task", - "org.springframework.boot.thread", - "org.springframework.boot.util", - "org.springframework.boot.validation", - "org.springframework.boot.validation.beanvalidation", - "org.springframework.boot.web.context.reactive", - "org.springframework.boot.web.context.servlet", - "org.springframework.boot.web.error", - "org.springframework.boot.web.servlet", - "org.springframework.boot.web.servlet.support" - ], - "org.springframework.boot:spring-boot-actuator": [ - "org.springframework.boot.actuate.audit", - "org.springframework.boot.actuate.audit.listener", - "org.springframework.boot.actuate.beans", - "org.springframework.boot.actuate.context", - "org.springframework.boot.actuate.context.properties", - "org.springframework.boot.actuate.endpoint", - "org.springframework.boot.actuate.endpoint.annotation", - "org.springframework.boot.actuate.endpoint.invoke", - "org.springframework.boot.actuate.endpoint.invoke.convert", - "org.springframework.boot.actuate.endpoint.invoke.reflect", - "org.springframework.boot.actuate.endpoint.invoker.cache", - "org.springframework.boot.actuate.endpoint.jackson", - "org.springframework.boot.actuate.endpoint.jmx", - "org.springframework.boot.actuate.endpoint.jmx.annotation", - "org.springframework.boot.actuate.endpoint.web", - "org.springframework.boot.actuate.endpoint.web.annotation", - "org.springframework.boot.actuate.env", - "org.springframework.boot.actuate.info", - "org.springframework.boot.actuate.logging", - "org.springframework.boot.actuate.management", - "org.springframework.boot.actuate.sbom", - "org.springframework.boot.actuate.scheduling", - "org.springframework.boot.actuate.security", - "org.springframework.boot.actuate.startup", - "org.springframework.boot.actuate.web.exchanges", - "org.springframework.boot.actuate.web.mappings" - ], - "org.springframework.boot:spring-boot-actuator-autoconfigure": [ - "org.springframework.boot.actuate.autoconfigure", - "org.springframework.boot.actuate.autoconfigure.audit", - "org.springframework.boot.actuate.autoconfigure.beans", - "org.springframework.boot.actuate.autoconfigure.condition", - "org.springframework.boot.actuate.autoconfigure.context", - "org.springframework.boot.actuate.autoconfigure.context.properties", - "org.springframework.boot.actuate.autoconfigure.endpoint", - "org.springframework.boot.actuate.autoconfigure.endpoint.condition", - "org.springframework.boot.actuate.autoconfigure.endpoint.expose", - "org.springframework.boot.actuate.autoconfigure.endpoint.jackson", - "org.springframework.boot.actuate.autoconfigure.endpoint.jmx", - "org.springframework.boot.actuate.autoconfigure.endpoint.web", - "org.springframework.boot.actuate.autoconfigure.env", - "org.springframework.boot.actuate.autoconfigure.info", - "org.springframework.boot.actuate.autoconfigure.logging", - "org.springframework.boot.actuate.autoconfigure.management", - "org.springframework.boot.actuate.autoconfigure.sbom", - "org.springframework.boot.actuate.autoconfigure.scheduling", - "org.springframework.boot.actuate.autoconfigure.startup", - "org.springframework.boot.actuate.autoconfigure.web", - "org.springframework.boot.actuate.autoconfigure.web.exchanges", - "org.springframework.boot.actuate.autoconfigure.web.mappings", - "org.springframework.boot.actuate.autoconfigure.web.server" - ], - "org.springframework.boot:spring-boot-autoconfigure": [ - "org.springframework.boot.autoconfigure", - "org.springframework.boot.autoconfigure.admin", - "org.springframework.boot.autoconfigure.aop", - "org.springframework.boot.autoconfigure.availability", - "org.springframework.boot.autoconfigure.cache", - "org.springframework.boot.autoconfigure.condition", - "org.springframework.boot.autoconfigure.container", - "org.springframework.boot.autoconfigure.context", - "org.springframework.boot.autoconfigure.data", - "org.springframework.boot.autoconfigure.diagnostics.analyzer", - "org.springframework.boot.autoconfigure.info", - "org.springframework.boot.autoconfigure.jmx", - "org.springframework.boot.autoconfigure.logging", - "org.springframework.boot.autoconfigure.preinitialize", - "org.springframework.boot.autoconfigure.service.connection", - "org.springframework.boot.autoconfigure.ssl", - "org.springframework.boot.autoconfigure.task", - "org.springframework.boot.autoconfigure.template", - "org.springframework.boot.autoconfigure.web", - "org.springframework.boot.autoconfigure.web.format" - ], - "org.springframework.boot:spring-boot-cassandra": [ - "org.springframework.boot.cassandra.autoconfigure", - "org.springframework.boot.cassandra.autoconfigure.health", - "org.springframework.boot.cassandra.docker.compose", - "org.springframework.boot.cassandra.health", - "org.springframework.boot.cassandra.testcontainers" - ], - "org.springframework.boot:spring-boot-data-cassandra": [ - "org.springframework.boot.data.cassandra.autoconfigure" - ], - "org.springframework.boot:spring-boot-data-cassandra-test": [ - "org.springframework.boot.data.cassandra.test.autoconfigure" - ], - "org.springframework.boot:spring-boot-data-commons": [ - "org.springframework.boot.data.autoconfigure.metrics", - "org.springframework.boot.data.autoconfigure.web", - "org.springframework.boot.data.metrics" - ], - "org.springframework.boot:spring-boot-health": [ - "org.springframework.boot.health.actuate.endpoint", - "org.springframework.boot.health.application", - "org.springframework.boot.health.autoconfigure.actuate.endpoint", - "org.springframework.boot.health.autoconfigure.application", - "org.springframework.boot.health.autoconfigure.contributor", - "org.springframework.boot.health.autoconfigure.registry", - "org.springframework.boot.health.contributor", - "org.springframework.boot.health.registry" - ], - "org.springframework.boot:spring-boot-http-client": [ - "org.springframework.boot.http.client", - "org.springframework.boot.http.client.autoconfigure", - "org.springframework.boot.http.client.autoconfigure.imperative", - "org.springframework.boot.http.client.autoconfigure.metrics", - "org.springframework.boot.http.client.autoconfigure.reactive", - "org.springframework.boot.http.client.autoconfigure.service", - "org.springframework.boot.http.client.reactive" - ], - "org.springframework.boot:spring-boot-http-codec": [ - "org.springframework.boot.http.codec", - "org.springframework.boot.http.codec.autoconfigure" - ], - "org.springframework.boot:spring-boot-http-converter": [ - "org.springframework.boot.http.converter.autoconfigure" - ], - "org.springframework.boot:spring-boot-jackson": [ - "org.springframework.boot.jackson", - "org.springframework.boot.jackson.autoconfigure" - ], - "org.springframework.boot:spring-boot-loader": [ - "org.springframework.boot.loader.jar", - "org.springframework.boot.loader.jarmode", - "org.springframework.boot.loader.launch", - "org.springframework.boot.loader.log", - "org.springframework.boot.loader.net.protocol", - "org.springframework.boot.loader.net.protocol.jar", - "org.springframework.boot.loader.net.protocol.nested", - "org.springframework.boot.loader.net.util", - "org.springframework.boot.loader.nio.file", - "org.springframework.boot.loader.ref", - "org.springframework.boot.loader.zip" - ], - "org.springframework.boot:spring-boot-micrometer-metrics": [ - "org.springframework.boot.micrometer.metrics", - "org.springframework.boot.micrometer.metrics.actuate.endpoint", - "org.springframework.boot.micrometer.metrics.autoconfigure", - "org.springframework.boot.micrometer.metrics.autoconfigure.export", - "org.springframework.boot.micrometer.metrics.autoconfigure.export.appoptics", - "org.springframework.boot.micrometer.metrics.autoconfigure.export.atlas", - "org.springframework.boot.micrometer.metrics.autoconfigure.export.datadog", - "org.springframework.boot.micrometer.metrics.autoconfigure.export.dynatrace", - "org.springframework.boot.micrometer.metrics.autoconfigure.export.elastic", - "org.springframework.boot.micrometer.metrics.autoconfigure.export.ganglia", - "org.springframework.boot.micrometer.metrics.autoconfigure.export.graphite", - "org.springframework.boot.micrometer.metrics.autoconfigure.export.humio", - "org.springframework.boot.micrometer.metrics.autoconfigure.export.influx", - "org.springframework.boot.micrometer.metrics.autoconfigure.export.jmx", - "org.springframework.boot.micrometer.metrics.autoconfigure.export.kairos", - "org.springframework.boot.micrometer.metrics.autoconfigure.export.newrelic", - "org.springframework.boot.micrometer.metrics.autoconfigure.export.otlp", - "org.springframework.boot.micrometer.metrics.autoconfigure.export.prometheus", - "org.springframework.boot.micrometer.metrics.autoconfigure.export.properties", - "org.springframework.boot.micrometer.metrics.autoconfigure.export.simple", - "org.springframework.boot.micrometer.metrics.autoconfigure.export.stackdriver", - "org.springframework.boot.micrometer.metrics.autoconfigure.export.statsd", - "org.springframework.boot.micrometer.metrics.autoconfigure.jvm", - "org.springframework.boot.micrometer.metrics.autoconfigure.logging.log4j2", - "org.springframework.boot.micrometer.metrics.autoconfigure.logging.logback", - "org.springframework.boot.micrometer.metrics.autoconfigure.ssl", - "org.springframework.boot.micrometer.metrics.autoconfigure.startup", - "org.springframework.boot.micrometer.metrics.autoconfigure.system", - "org.springframework.boot.micrometer.metrics.autoconfigure.task", - "org.springframework.boot.micrometer.metrics.docker.compose.otlp", - "org.springframework.boot.micrometer.metrics.export.prometheus", - "org.springframework.boot.micrometer.metrics.export.prometheus.endpoint", - "org.springframework.boot.micrometer.metrics.startup", - "org.springframework.boot.micrometer.metrics.system", - "org.springframework.boot.micrometer.metrics.testcontainers.otlp" - ], - "org.springframework.boot:spring-boot-micrometer-metrics-test": [ - "org.springframework.boot.micrometer.metrics.test.autoconfigure" - ], - "org.springframework.boot:spring-boot-micrometer-observation": [ - "org.springframework.boot.micrometer.observation.autoconfigure" - ], - "org.springframework.boot:spring-boot-micrometer-tracing": [ - "org.springframework.boot.micrometer.tracing.autoconfigure", - "org.springframework.boot.micrometer.tracing.autoconfigure.prometheus" - ], - "org.springframework.boot:spring-boot-micrometer-tracing-opentelemetry": [ - "org.springframework.boot.micrometer.tracing.opentelemetry.autoconfigure", - "org.springframework.boot.micrometer.tracing.opentelemetry.autoconfigure.otlp", - "org.springframework.boot.micrometer.tracing.opentelemetry.autoconfigure.zipkin", - "org.springframework.boot.micrometer.tracing.opentelemetry.docker.compose.otlp", - "org.springframework.boot.micrometer.tracing.opentelemetry.testcontainers.otlp" - ], - "org.springframework.boot:spring-boot-netty": [ - "org.springframework.boot.netty.autoconfigure" - ], - "org.springframework.boot:spring-boot-opentelemetry": [ - "org.springframework.boot.opentelemetry.autoconfigure", - "org.springframework.boot.opentelemetry.autoconfigure.logging", - "org.springframework.boot.opentelemetry.autoconfigure.logging.otlp", - "org.springframework.boot.opentelemetry.docker.compose", - "org.springframework.boot.opentelemetry.testcontainers" - ], - "org.springframework.boot:spring-boot-persistence": [ - "org.springframework.boot.persistence.autoconfigure" - ], - "org.springframework.boot:spring-boot-reactor": [ - "org.springframework.boot.reactor", - "org.springframework.boot.reactor.autoconfigure" - ], - "org.springframework.boot:spring-boot-reactor-netty": [ - "org.springframework.boot.reactor.netty", - "org.springframework.boot.reactor.netty.autoconfigure", - "org.springframework.boot.reactor.netty.autoconfigure.actuate.web.server" - ], - "org.springframework.boot:spring-boot-restclient": [ - "org.springframework.boot.restclient", - "org.springframework.boot.restclient.autoconfigure", - "org.springframework.boot.restclient.autoconfigure.service", - "org.springframework.boot.restclient.observation" - ], - "org.springframework.boot:spring-boot-resttestclient": [ - "org.springframework.boot.resttestclient", - "org.springframework.boot.resttestclient.autoconfigure" - ], - "org.springframework.boot:spring-boot-security": [ - "org.springframework.boot.security.autoconfigure", - "org.springframework.boot.security.autoconfigure.actuate.web.reactive", - "org.springframework.boot.security.autoconfigure.actuate.web.servlet", - "org.springframework.boot.security.autoconfigure.rsocket", - "org.springframework.boot.security.autoconfigure.web", - "org.springframework.boot.security.autoconfigure.web.reactive", - "org.springframework.boot.security.autoconfigure.web.servlet", - "org.springframework.boot.security.web.reactive", - "org.springframework.boot.security.web.servlet" - ], - "org.springframework.boot:spring-boot-security-oauth2-client": [ - "org.springframework.boot.security.oauth2.client.autoconfigure", - "org.springframework.boot.security.oauth2.client.autoconfigure.reactive", - "org.springframework.boot.security.oauth2.client.autoconfigure.servlet" - ], - "org.springframework.boot:spring-boot-security-oauth2-resource-server": [ - "org.springframework.boot.security.oauth2.server.resource.autoconfigure", - "org.springframework.boot.security.oauth2.server.resource.autoconfigure.reactive", - "org.springframework.boot.security.oauth2.server.resource.autoconfigure.servlet" - ], - "org.springframework.boot:spring-boot-security-test": [ - "org.springframework.boot.security.test.autoconfigure.webflux", - "org.springframework.boot.security.test.autoconfigure.webmvc" - ], - "org.springframework.boot:spring-boot-servlet": [ - "org.springframework.boot.servlet", - "org.springframework.boot.servlet.actuate.web.exchanges", - "org.springframework.boot.servlet.actuate.web.mappings", - "org.springframework.boot.servlet.autoconfigure", - "org.springframework.boot.servlet.autoconfigure.actuate.web", - "org.springframework.boot.servlet.autoconfigure.actuate.web.exchanges", - "org.springframework.boot.servlet.autoconfigure.actuate.web.mappings", - "org.springframework.boot.servlet.filter" - ], - "org.springframework.boot:spring-boot-test": [ - "org.springframework.boot.test.context", - "org.springframework.boot.test.context.assertj", - "org.springframework.boot.test.context.filter", - "org.springframework.boot.test.context.filter.annotation", - "org.springframework.boot.test.context.runner", - "org.springframework.boot.test.http.client", - "org.springframework.boot.test.http.server", - "org.springframework.boot.test.json", - "org.springframework.boot.test.mock.web", - "org.springframework.boot.test.system", - "org.springframework.boot.test.util", - "org.springframework.boot.test.web.htmlunit", - "org.springframework.boot.test.web.server" - ], - "org.springframework.boot:spring-boot-test-autoconfigure": [ - "org.springframework.boot.test.autoconfigure", - "org.springframework.boot.test.autoconfigure.jdbc", - "org.springframework.boot.test.autoconfigure.json" - ], - "org.springframework.boot:spring-boot-tomcat": [ - "org.springframework.boot.tomcat", - "org.springframework.boot.tomcat.autoconfigure", - "org.springframework.boot.tomcat.autoconfigure.actuate.web.server", - "org.springframework.boot.tomcat.autoconfigure.metrics", - "org.springframework.boot.tomcat.autoconfigure.reactive", - "org.springframework.boot.tomcat.autoconfigure.servlet", - "org.springframework.boot.tomcat.metrics", - "org.springframework.boot.tomcat.reactive", - "org.springframework.boot.tomcat.servlet" - ], - "org.springframework.boot:spring-boot-validation": [ - "org.springframework.boot.validation.autoconfigure" - ], - "org.springframework.boot:spring-boot-web-server": [ - "org.springframework.boot.web.server", - "org.springframework.boot.web.server.autoconfigure", - "org.springframework.boot.web.server.autoconfigure.reactive", - "org.springframework.boot.web.server.autoconfigure.servlet", - "org.springframework.boot.web.server.context", - "org.springframework.boot.web.server.reactive", - "org.springframework.boot.web.server.reactive.context", - "org.springframework.boot.web.server.servlet", - "org.springframework.boot.web.server.servlet.context" - ], - "org.springframework.boot:spring-boot-webclient": [ - "org.springframework.boot.webclient", - "org.springframework.boot.webclient.autoconfigure", - "org.springframework.boot.webclient.autoconfigure.service", - "org.springframework.boot.webclient.observation" - ], - "org.springframework.boot:spring-boot-webflux": [ - "org.springframework.boot.webflux", - "org.springframework.boot.webflux.actuate.endpoint.web", - "org.springframework.boot.webflux.actuate.web.exchanges", - "org.springframework.boot.webflux.actuate.web.mappings", - "org.springframework.boot.webflux.autoconfigure", - "org.springframework.boot.webflux.autoconfigure.actuate.endpoint.web", - "org.springframework.boot.webflux.autoconfigure.actuate.web", - "org.springframework.boot.webflux.autoconfigure.actuate.web.exchanges", - "org.springframework.boot.webflux.autoconfigure.actuate.web.mappings", - "org.springframework.boot.webflux.autoconfigure.error", - "org.springframework.boot.webflux.error", - "org.springframework.boot.webflux.filter" - ], - "org.springframework.boot:spring-boot-webflux-test": [ - "org.springframework.boot.webflux.test.autoconfigure" - ], - "org.springframework.boot:spring-boot-webmvc": [ - "org.springframework.boot.webmvc", - "org.springframework.boot.webmvc.actuate.endpoint.web", - "org.springframework.boot.webmvc.actuate.web.mappings", - "org.springframework.boot.webmvc.autoconfigure", - "org.springframework.boot.webmvc.autoconfigure.actuate.endpoint.web", - "org.springframework.boot.webmvc.autoconfigure.actuate.web", - "org.springframework.boot.webmvc.autoconfigure.actuate.web.mappings", - "org.springframework.boot.webmvc.autoconfigure.error", - "org.springframework.boot.webmvc.error" - ], - "org.springframework.boot:spring-boot-webmvc-test": [ - "org.springframework.boot.webmvc.test.autoconfigure" - ], - "org.springframework.boot:spring-boot-webtestclient": [ - "org.springframework.boot.webtestclient.autoconfigure" - ], - "org.springframework.cloud:spring-cloud-commons": [ - "org.springframework.cloud.client", - "org.springframework.cloud.client.actuator", - "org.springframework.cloud.client.circuitbreaker", - "org.springframework.cloud.client.circuitbreaker.httpservice", - "org.springframework.cloud.client.circuitbreaker.observation", - "org.springframework.cloud.client.discovery", - "org.springframework.cloud.client.discovery.composite", - "org.springframework.cloud.client.discovery.composite.reactive", - "org.springframework.cloud.client.discovery.event", - "org.springframework.cloud.client.discovery.health", - "org.springframework.cloud.client.discovery.health.reactive", - "org.springframework.cloud.client.discovery.simple", - "org.springframework.cloud.client.discovery.simple.reactive", - "org.springframework.cloud.client.hypermedia", - "org.springframework.cloud.client.loadbalancer", - "org.springframework.cloud.client.loadbalancer.reactive", - "org.springframework.cloud.client.serviceregistry", - "org.springframework.cloud.client.serviceregistry.endpoint", - "org.springframework.cloud.commons", - "org.springframework.cloud.commons.config", - "org.springframework.cloud.commons.publisher", - "org.springframework.cloud.commons.security", - "org.springframework.cloud.commons.util", - "org.springframework.cloud.configuration" - ], - "org.springframework.cloud:spring-cloud-context": [ - "org.springframework.cloud.autoconfigure", - "org.springframework.cloud.bootstrap", - "org.springframework.cloud.bootstrap.config", - "org.springframework.cloud.bootstrap.encrypt", - "org.springframework.cloud.bootstrap.support", - "org.springframework.cloud.context", - "org.springframework.cloud.context.config", - "org.springframework.cloud.context.config.annotation", - "org.springframework.cloud.context.encrypt", - "org.springframework.cloud.context.environment", - "org.springframework.cloud.context.named", - "org.springframework.cloud.context.properties", - "org.springframework.cloud.context.refresh", - "org.springframework.cloud.context.restart", - "org.springframework.cloud.context.scope", - "org.springframework.cloud.context.scope.refresh", - "org.springframework.cloud.context.scope.thread", - "org.springframework.cloud.endpoint", - "org.springframework.cloud.endpoint.event", - "org.springframework.cloud.env", - "org.springframework.cloud.health", - "org.springframework.cloud.logging", - "org.springframework.cloud.util", - "org.springframework.cloud.util.random" - ], - "org.springframework.cloud:spring-cloud-kubernetes-client-autoconfig": [ - "org.springframework.cloud.kubernetes.client" - ], - "org.springframework.cloud:spring-cloud-kubernetes-client-config": [ - "org.springframework.cloud.kubernetes.client.config", - "org.springframework.cloud.kubernetes.client.config.reload" - ], - "org.springframework.cloud:spring-cloud-kubernetes-commons": [ - "org.springframework.cloud.kubernetes.commons", - "org.springframework.cloud.kubernetes.commons.autoconfig", - "org.springframework.cloud.kubernetes.commons.config", - "org.springframework.cloud.kubernetes.commons.config.reload", - "org.springframework.cloud.kubernetes.commons.config.reload.condition", - "org.springframework.cloud.kubernetes.commons.configdata", - "org.springframework.cloud.kubernetes.commons.discovery", - "org.springframework.cloud.kubernetes.commons.discovery.conditionals", - "org.springframework.cloud.kubernetes.commons.leader", - "org.springframework.cloud.kubernetes.commons.leader.election", - "org.springframework.cloud.kubernetes.commons.leader.election.events", - "org.springframework.cloud.kubernetes.commons.loadbalancer", - "org.springframework.cloud.kubernetes.commons.profile" - ], - "org.springframework.cloud:spring-cloud-starter-bootstrap": [ - "org.springframework.cloud.bootstrap.marker" - ], - "org.springframework.data:spring-data-cassandra": [ - "org.springframework.data.cassandra", - "org.springframework.data.cassandra.aot", - "org.springframework.data.cassandra.config", - "org.springframework.data.cassandra.core", - "org.springframework.data.cassandra.core.convert", - "org.springframework.data.cassandra.core.cql", - "org.springframework.data.cassandra.core.cql.converter", - "org.springframework.data.cassandra.core.cql.generator", - "org.springframework.data.cassandra.core.cql.keyspace", - "org.springframework.data.cassandra.core.cql.session", - "org.springframework.data.cassandra.core.cql.session.init", - "org.springframework.data.cassandra.core.cql.session.lookup", - "org.springframework.data.cassandra.core.cql.util", - "org.springframework.data.cassandra.core.mapping", - "org.springframework.data.cassandra.core.mapping.event", - "org.springframework.data.cassandra.core.query", - "org.springframework.data.cassandra.observability", - "org.springframework.data.cassandra.repository", - "org.springframework.data.cassandra.repository.aot", - "org.springframework.data.cassandra.repository.cdi", - "org.springframework.data.cassandra.repository.config", - "org.springframework.data.cassandra.repository.query", - "org.springframework.data.cassandra.repository.support", - "org.springframework.data.cassandra.util" - ], - "org.springframework.data:spring-data-commons": [ - "org.springframework.data.annotation", - "org.springframework.data.aot", - "org.springframework.data.auditing", - "org.springframework.data.auditing.config", - "org.springframework.data.config", - "org.springframework.data.convert", - "org.springframework.data.core", - "org.springframework.data.crossstore", - "org.springframework.data.domain", - "org.springframework.data.domain.jaxb", - "org.springframework.data.expression", - "org.springframework.data.geo", - "org.springframework.data.geo.format", - "org.springframework.data.history", - "org.springframework.data.javapoet", - "org.springframework.data.mapping", - "org.springframework.data.mapping.callback", - "org.springframework.data.mapping.context", - "org.springframework.data.mapping.model", - "org.springframework.data.projection", - "org.springframework.data.querydsl", - "org.springframework.data.querydsl.aot", - "org.springframework.data.querydsl.binding", - "org.springframework.data.repository", - "org.springframework.data.repository.aot.generate", - "org.springframework.data.repository.aot.hint", - "org.springframework.data.repository.cdi", - "org.springframework.data.repository.config", - "org.springframework.data.repository.core", - "org.springframework.data.repository.core.support", - "org.springframework.data.repository.history", - "org.springframework.data.repository.history.support", - "org.springframework.data.repository.init", - "org.springframework.data.repository.kotlin", - "org.springframework.data.repository.query", - "org.springframework.data.repository.query.parser", - "org.springframework.data.repository.reactive", - "org.springframework.data.repository.support", - "org.springframework.data.repository.util", - "org.springframework.data.spel", - "org.springframework.data.spel.spi", - "org.springframework.data.support", - "org.springframework.data.transaction", - "org.springframework.data.util", - "org.springframework.data.web", - "org.springframework.data.web.aot", - "org.springframework.data.web.config", - "org.springframework.data.web.querydsl" - ], - "org.springframework.retry:spring-retry": [ - "org.springframework.classify", - "org.springframework.classify.annotation", - "org.springframework.classify.util", - "org.springframework.retry", - "org.springframework.retry.annotation", - "org.springframework.retry.backoff", - "org.springframework.retry.context", - "org.springframework.retry.interceptor", - "org.springframework.retry.listener", - "org.springframework.retry.policy", - "org.springframework.retry.stats", - "org.springframework.retry.support" - ], - "org.springframework.security:spring-security-config": [ - "org.springframework.security.config", - "org.springframework.security.config.annotation", - "org.springframework.security.config.annotation.authentication", - "org.springframework.security.config.annotation.authentication.builders", - "org.springframework.security.config.annotation.authentication.configuration", - "org.springframework.security.config.annotation.authentication.configurers.ldap", - "org.springframework.security.config.annotation.authentication.configurers.provisioning", - "org.springframework.security.config.annotation.authentication.configurers.userdetails", - "org.springframework.security.config.annotation.authorization", - "org.springframework.security.config.annotation.configuration", - "org.springframework.security.config.annotation.method.configuration", - "org.springframework.security.config.annotation.rsocket", - "org.springframework.security.config.annotation.web", - "org.springframework.security.config.annotation.web.builders", - "org.springframework.security.config.annotation.web.configuration", - "org.springframework.security.config.annotation.web.configurers", - "org.springframework.security.config.annotation.web.configurers.oauth2.client", - "org.springframework.security.config.annotation.web.configurers.oauth2.server.authorization", - "org.springframework.security.config.annotation.web.configurers.oauth2.server.resource", - "org.springframework.security.config.annotation.web.configurers.ott", - "org.springframework.security.config.annotation.web.configurers.saml2", - "org.springframework.security.config.annotation.web.headers", - "org.springframework.security.config.annotation.web.oauth2.client", - "org.springframework.security.config.annotation.web.oauth2.login", - "org.springframework.security.config.annotation.web.oauth2.resourceserver", - "org.springframework.security.config.annotation.web.reactive", - "org.springframework.security.config.annotation.web.saml2", - "org.springframework.security.config.annotation.web.servlet.configuration", - "org.springframework.security.config.annotation.web.session", - "org.springframework.security.config.annotation.web.socket", - "org.springframework.security.config.aot.hint", - "org.springframework.security.config.authentication", - "org.springframework.security.config.core", - "org.springframework.security.config.core.userdetails", - "org.springframework.security.config.crypto", - "org.springframework.security.config.debug", - "org.springframework.security.config.http", - "org.springframework.security.config.ldap", - "org.springframework.security.config.method", - "org.springframework.security.config.oauth2.client", - "org.springframework.security.config.observation", - "org.springframework.security.config.provisioning", - "org.springframework.security.config.saml2", - "org.springframework.security.config.web", - "org.springframework.security.config.web.messaging", - "org.springframework.security.config.web.server", - "org.springframework.security.config.websocket" - ], - "org.springframework.security:spring-security-core": [ - "org.springframework.security.access", - "org.springframework.security.access.annotation", - "org.springframework.security.access.expression", - "org.springframework.security.access.expression.method", - "org.springframework.security.access.hierarchicalroles", - "org.springframework.security.access.prepost", - "org.springframework.security.aot.hint", - "org.springframework.security.authentication", - "org.springframework.security.authentication.dao", - "org.springframework.security.authentication.event", - "org.springframework.security.authentication.jaas", - "org.springframework.security.authentication.jaas.event", - "org.springframework.security.authentication.jaas.memory", - "org.springframework.security.authentication.ott", - "org.springframework.security.authentication.ott.reactive", - "org.springframework.security.authentication.password", - "org.springframework.security.authorization", - "org.springframework.security.authorization.event", - "org.springframework.security.authorization.method", - "org.springframework.security.concurrent", - "org.springframework.security.context", - "org.springframework.security.converter", - "org.springframework.security.core", - "org.springframework.security.core.annotation", - "org.springframework.security.core.authority", - "org.springframework.security.core.authority.mapping", - "org.springframework.security.core.context", - "org.springframework.security.core.parameters", - "org.springframework.security.core.session", - "org.springframework.security.core.token", - "org.springframework.security.core.userdetails", - "org.springframework.security.core.userdetails.cache", - "org.springframework.security.core.userdetails.jdbc", - "org.springframework.security.core.userdetails.memory", - "org.springframework.security.jackson", - "org.springframework.security.jackson2", - "org.springframework.security.provisioning", - "org.springframework.security.scheduling", - "org.springframework.security.task", - "org.springframework.security.util" - ], - "org.springframework.security:spring-security-crypto": [ - "org.springframework.security.crypto.argon2", - "org.springframework.security.crypto.bcrypt", - "org.springframework.security.crypto.codec", - "org.springframework.security.crypto.encrypt", - "org.springframework.security.crypto.factory", - "org.springframework.security.crypto.keygen", - "org.springframework.security.crypto.password", - "org.springframework.security.crypto.password4j", - "org.springframework.security.crypto.scrypt", - "org.springframework.security.crypto.util" - ], - "org.springframework.security:spring-security-oauth2-client": [ - "org.springframework.security.oauth2.client", - "org.springframework.security.oauth2.client.annotation", - "org.springframework.security.oauth2.client.aot.hint", - "org.springframework.security.oauth2.client.authentication", - "org.springframework.security.oauth2.client.endpoint", - "org.springframework.security.oauth2.client.event", - "org.springframework.security.oauth2.client.http", - "org.springframework.security.oauth2.client.jackson", - "org.springframework.security.oauth2.client.jackson2", - "org.springframework.security.oauth2.client.oidc.authentication", - "org.springframework.security.oauth2.client.oidc.authentication.event", - "org.springframework.security.oauth2.client.oidc.authentication.logout", - "org.springframework.security.oauth2.client.oidc.server.session", - "org.springframework.security.oauth2.client.oidc.session", - "org.springframework.security.oauth2.client.oidc.userinfo", - "org.springframework.security.oauth2.client.oidc.web.logout", - "org.springframework.security.oauth2.client.oidc.web.server.logout", - "org.springframework.security.oauth2.client.registration", - "org.springframework.security.oauth2.client.userinfo", - "org.springframework.security.oauth2.client.web", - "org.springframework.security.oauth2.client.web.client", - "org.springframework.security.oauth2.client.web.client.support", - "org.springframework.security.oauth2.client.web.method.annotation", - "org.springframework.security.oauth2.client.web.reactive.function.client", - "org.springframework.security.oauth2.client.web.reactive.function.client.support", - "org.springframework.security.oauth2.client.web.reactive.result.method.annotation", - "org.springframework.security.oauth2.client.web.server", - "org.springframework.security.oauth2.client.web.server.authentication" - ], - "org.springframework.security:spring-security-oauth2-core": [ - "org.springframework.security.oauth2.core", - "org.springframework.security.oauth2.core.authorization", - "org.springframework.security.oauth2.core.converter", - "org.springframework.security.oauth2.core.endpoint", - "org.springframework.security.oauth2.core.http.converter", - "org.springframework.security.oauth2.core.oidc", - "org.springframework.security.oauth2.core.oidc.endpoint", - "org.springframework.security.oauth2.core.oidc.user", - "org.springframework.security.oauth2.core.user", - "org.springframework.security.oauth2.core.web.reactive.function" - ], - "org.springframework.security:spring-security-oauth2-jose": [ - "org.springframework.security.oauth2.jose", - "org.springframework.security.oauth2.jose.jws", - "org.springframework.security.oauth2.jwt" - ], - "org.springframework.security:spring-security-oauth2-resource-server": [ - "org.springframework.security.oauth2.server.resource", - "org.springframework.security.oauth2.server.resource.authentication", - "org.springframework.security.oauth2.server.resource.introspection", - "org.springframework.security.oauth2.server.resource.web", - "org.springframework.security.oauth2.server.resource.web.access", - "org.springframework.security.oauth2.server.resource.web.access.server", - "org.springframework.security.oauth2.server.resource.web.authentication", - "org.springframework.security.oauth2.server.resource.web.reactive.function.client", - "org.springframework.security.oauth2.server.resource.web.server", - "org.springframework.security.oauth2.server.resource.web.server.authentication" - ], - "org.springframework.security:spring-security-test": [ - "org.springframework.security.test.aot.hint", - "org.springframework.security.test.context", - "org.springframework.security.test.context.annotation", - "org.springframework.security.test.context.support", - "org.springframework.security.test.web.reactive.server", - "org.springframework.security.test.web.servlet.request", - "org.springframework.security.test.web.servlet.response", - "org.springframework.security.test.web.servlet.setup", - "org.springframework.security.test.web.support" - ], - "org.springframework.security:spring-security-web": [ - "org.springframework.security.web", - "org.springframework.security.web.access", - "org.springframework.security.web.access.expression", - "org.springframework.security.web.access.intercept", - "org.springframework.security.web.aot.hint", - "org.springframework.security.web.authentication", - "org.springframework.security.web.authentication.logout", - "org.springframework.security.web.authentication.ott", - "org.springframework.security.web.authentication.password", - "org.springframework.security.web.authentication.preauth", - "org.springframework.security.web.authentication.preauth.j2ee", - "org.springframework.security.web.authentication.preauth.websphere", - "org.springframework.security.web.authentication.preauth.x509", - "org.springframework.security.web.authentication.rememberme", - "org.springframework.security.web.authentication.session", - "org.springframework.security.web.authentication.switchuser", - "org.springframework.security.web.authentication.ui", - "org.springframework.security.web.authentication.www", - "org.springframework.security.web.bind", - "org.springframework.security.web.bind.annotation", - "org.springframework.security.web.bind.support", - "org.springframework.security.web.context", - "org.springframework.security.web.context.request.async", - "org.springframework.security.web.context.support", - "org.springframework.security.web.csrf", - "org.springframework.security.web.debug", - "org.springframework.security.web.firewall", - "org.springframework.security.web.header", - "org.springframework.security.web.header.writers", - "org.springframework.security.web.header.writers.frameoptions", - "org.springframework.security.web.http", - "org.springframework.security.web.jaasapi", - "org.springframework.security.web.jackson", - "org.springframework.security.web.jackson2", - "org.springframework.security.web.method.annotation", - "org.springframework.security.web.reactive.result.method.annotation", - "org.springframework.security.web.reactive.result.view", - "org.springframework.security.web.savedrequest", - "org.springframework.security.web.server", - "org.springframework.security.web.server.authentication", - "org.springframework.security.web.server.authentication.logout", - "org.springframework.security.web.server.authentication.ott", - "org.springframework.security.web.server.authorization", - "org.springframework.security.web.server.context", - "org.springframework.security.web.server.csrf", - "org.springframework.security.web.server.firewall", - "org.springframework.security.web.server.header", - "org.springframework.security.web.server.jackson", - "org.springframework.security.web.server.jackson2", - "org.springframework.security.web.server.savedrequest", - "org.springframework.security.web.server.transport", - "org.springframework.security.web.server.ui", - "org.springframework.security.web.server.util.matcher", - "org.springframework.security.web.servlet.support.csrf", - "org.springframework.security.web.servlet.util.matcher", - "org.springframework.security.web.servletapi", - "org.springframework.security.web.session", - "org.springframework.security.web.transport", - "org.springframework.security.web.util", - "org.springframework.security.web.util.matcher" - ], - "org.springframework:spring-aop": [ - "org.aopalliance", - "org.aopalliance.aop", - "org.aopalliance.intercept", - "org.springframework.aop", - "org.springframework.aop.aspectj", - "org.springframework.aop.aspectj.annotation", - "org.springframework.aop.aspectj.autoproxy", - "org.springframework.aop.config", - "org.springframework.aop.framework", - "org.springframework.aop.framework.adapter", - "org.springframework.aop.framework.autoproxy", - "org.springframework.aop.framework.autoproxy.target", - "org.springframework.aop.interceptor", - "org.springframework.aop.scope", - "org.springframework.aop.support", - "org.springframework.aop.support.annotation", - "org.springframework.aop.target", - "org.springframework.aop.target.dynamic" - ], - "org.springframework:spring-beans": [ - "org.springframework.beans", - "org.springframework.beans.factory", - "org.springframework.beans.factory.annotation", - "org.springframework.beans.factory.aot", - "org.springframework.beans.factory.config", - "org.springframework.beans.factory.groovy", - "org.springframework.beans.factory.parsing", - "org.springframework.beans.factory.serviceloader", - "org.springframework.beans.factory.support", - "org.springframework.beans.factory.wiring", - "org.springframework.beans.factory.xml", - "org.springframework.beans.propertyeditors", - "org.springframework.beans.support" - ], - "org.springframework:spring-context": [ - "org.springframework.cache", - "org.springframework.cache.annotation", - "org.springframework.cache.concurrent", - "org.springframework.cache.config", - "org.springframework.cache.interceptor", - "org.springframework.cache.support", - "org.springframework.context", - "org.springframework.context.annotation", - "org.springframework.context.aot", - "org.springframework.context.config", - "org.springframework.context.event", - "org.springframework.context.expression", - "org.springframework.context.i18n", - "org.springframework.context.index", - "org.springframework.context.support", - "org.springframework.context.weaving", - "org.springframework.ejb.config", - "org.springframework.format", - "org.springframework.format.annotation", - "org.springframework.format.datetime", - "org.springframework.format.datetime.standard", - "org.springframework.format.number", - "org.springframework.format.number.money", - "org.springframework.format.support", - "org.springframework.instrument.classloading", - "org.springframework.instrument.classloading.glassfish", - "org.springframework.instrument.classloading.jboss", - "org.springframework.instrument.classloading.tomcat", - "org.springframework.jmx", - "org.springframework.jmx.access", - "org.springframework.jmx.export", - "org.springframework.jmx.export.annotation", - "org.springframework.jmx.export.assembler", - "org.springframework.jmx.export.metadata", - "org.springframework.jmx.export.naming", - "org.springframework.jmx.export.notification", - "org.springframework.jmx.support", - "org.springframework.jndi", - "org.springframework.jndi.support", - "org.springframework.resilience", - "org.springframework.resilience.annotation", - "org.springframework.resilience.retry", - "org.springframework.scheduling", - "org.springframework.scheduling.annotation", - "org.springframework.scheduling.concurrent", - "org.springframework.scheduling.config", - "org.springframework.scheduling.support", - "org.springframework.scripting", - "org.springframework.scripting.bsh", - "org.springframework.scripting.config", - "org.springframework.scripting.groovy", - "org.springframework.scripting.support", - "org.springframework.stereotype", - "org.springframework.ui", - "org.springframework.validation", - "org.springframework.validation.annotation", - "org.springframework.validation.beanvalidation", - "org.springframework.validation.method", - "org.springframework.validation.support" - ], - "org.springframework:spring-context-support": [ - "org.springframework.cache.caffeine", - "org.springframework.cache.jcache", - "org.springframework.cache.jcache.config", - "org.springframework.cache.jcache.interceptor", - "org.springframework.cache.transaction", - "org.springframework.mail", - "org.springframework.mail.javamail", - "org.springframework.scheduling.quartz", - "org.springframework.ui.freemarker" - ], - "org.springframework:spring-core": [ - "org.springframework.aot", - "org.springframework.aot.generate", - "org.springframework.aot.hint", - "org.springframework.aot.hint.annotation", - "org.springframework.aot.hint.predicate", - "org.springframework.aot.hint.support", - "org.springframework.aot.nativex", - "org.springframework.aot.nativex.feature", - "org.springframework.asm", - "org.springframework.cglib", - "org.springframework.cglib.beans", - "org.springframework.cglib.core", - "org.springframework.cglib.core.internal", - "org.springframework.cglib.proxy", - "org.springframework.cglib.reflect", - "org.springframework.cglib.transform", - "org.springframework.cglib.transform.impl", - "org.springframework.cglib.util", - "org.springframework.core", - "org.springframework.core.annotation", - "org.springframework.core.codec", - "org.springframework.core.convert", - "org.springframework.core.convert.converter", - "org.springframework.core.convert.support", - "org.springframework.core.env", - "org.springframework.core.io", - "org.springframework.core.io.buffer", - "org.springframework.core.io.support", - "org.springframework.core.log", - "org.springframework.core.metrics", - "org.springframework.core.metrics.jfr", - "org.springframework.core.retry", - "org.springframework.core.retry.support", - "org.springframework.core.serializer", - "org.springframework.core.serializer.support", - "org.springframework.core.style", - "org.springframework.core.task", - "org.springframework.core.task.support", - "org.springframework.core.type", - "org.springframework.core.type.classreading", - "org.springframework.core.type.filter", - "org.springframework.javapoet", - "org.springframework.lang", - "org.springframework.objenesis", - "org.springframework.objenesis.instantiator", - "org.springframework.objenesis.instantiator.android", - "org.springframework.objenesis.instantiator.annotations", - "org.springframework.objenesis.instantiator.basic", - "org.springframework.objenesis.instantiator.gcj", - "org.springframework.objenesis.instantiator.perc", - "org.springframework.objenesis.instantiator.sun", - "org.springframework.objenesis.instantiator.util", - "org.springframework.objenesis.strategy", - "org.springframework.util", - "org.springframework.util.backoff", - "org.springframework.util.comparator", - "org.springframework.util.concurrent", - "org.springframework.util.function", - "org.springframework.util.unit", - "org.springframework.util.xml" - ], - "org.springframework:spring-expression": [ - "org.springframework.expression", - "org.springframework.expression.common", - "org.springframework.expression.spel", - "org.springframework.expression.spel.ast", - "org.springframework.expression.spel.standard", - "org.springframework.expression.spel.support" - ], - "org.springframework:spring-test": [ - "org.springframework.mock.env", - "org.springframework.mock.http", - "org.springframework.mock.http.client", - "org.springframework.mock.http.client.reactive", - "org.springframework.mock.http.server.reactive", - "org.springframework.mock.web", - "org.springframework.mock.web.reactive.function.server", - "org.springframework.mock.web.server", - "org.springframework.test.annotation", - "org.springframework.test.context", - "org.springframework.test.context.aot", - "org.springframework.test.context.bean.override", - "org.springframework.test.context.bean.override.convention", - "org.springframework.test.context.bean.override.mockito", - "org.springframework.test.context.cache", - "org.springframework.test.context.event", - "org.springframework.test.context.event.annotation", - "org.springframework.test.context.hint", - "org.springframework.test.context.jdbc", - "org.springframework.test.context.junit.jupiter", - "org.springframework.test.context.junit.jupiter.web", - "org.springframework.test.context.junit4", - "org.springframework.test.context.junit4.rules", - "org.springframework.test.context.junit4.statements", - "org.springframework.test.context.observation", - "org.springframework.test.context.support", - "org.springframework.test.context.testng", - "org.springframework.test.context.transaction", - "org.springframework.test.context.util", - "org.springframework.test.context.web", - "org.springframework.test.context.web.socket", - "org.springframework.test.http", - "org.springframework.test.jdbc", - "org.springframework.test.json", - "org.springframework.test.util", - "org.springframework.test.validation", - "org.springframework.test.web", - "org.springframework.test.web.client", - "org.springframework.test.web.client.match", - "org.springframework.test.web.client.response", - "org.springframework.test.web.reactive.server", - "org.springframework.test.web.reactive.server.assertj", - "org.springframework.test.web.servlet", - "org.springframework.test.web.servlet.assertj", - "org.springframework.test.web.servlet.client", - "org.springframework.test.web.servlet.client.assertj", - "org.springframework.test.web.servlet.htmlunit", - "org.springframework.test.web.servlet.htmlunit.webdriver", - "org.springframework.test.web.servlet.request", - "org.springframework.test.web.servlet.result", - "org.springframework.test.web.servlet.setup", - "org.springframework.test.web.support" - ], - "org.springframework:spring-tx": [ - "org.springframework.dao", - "org.springframework.dao.annotation", - "org.springframework.dao.support", - "org.springframework.jca.endpoint", - "org.springframework.jca.support", - "org.springframework.transaction", - "org.springframework.transaction.annotation", - "org.springframework.transaction.config", - "org.springframework.transaction.event", - "org.springframework.transaction.interceptor", - "org.springframework.transaction.jta", - "org.springframework.transaction.reactive", - "org.springframework.transaction.support" - ], - "org.springframework:spring-web": [ - "org.springframework.http", - "org.springframework.http.client", - "org.springframework.http.client.observation", - "org.springframework.http.client.reactive", - "org.springframework.http.client.support", - "org.springframework.http.codec", - "org.springframework.http.codec.cbor", - "org.springframework.http.codec.json", - "org.springframework.http.codec.multipart", - "org.springframework.http.codec.protobuf", - "org.springframework.http.codec.smile", - "org.springframework.http.codec.support", - "org.springframework.http.codec.xml", - "org.springframework.http.converter", - "org.springframework.http.converter.cbor", - "org.springframework.http.converter.feed", - "org.springframework.http.converter.json", - "org.springframework.http.converter.protobuf", - "org.springframework.http.converter.smile", - "org.springframework.http.converter.support", - "org.springframework.http.converter.xml", - "org.springframework.http.converter.yaml", - "org.springframework.http.server", - "org.springframework.http.server.observation", - "org.springframework.http.server.reactive", - "org.springframework.http.server.reactive.observation", - "org.springframework.http.support", - "org.springframework.web", - "org.springframework.web.accept", - "org.springframework.web.bind", - "org.springframework.web.bind.annotation", - "org.springframework.web.bind.support", - "org.springframework.web.client", - "org.springframework.web.client.support", - "org.springframework.web.context", - "org.springframework.web.context.annotation", - "org.springframework.web.context.request", - "org.springframework.web.context.request.async", - "org.springframework.web.context.support", - "org.springframework.web.cors", - "org.springframework.web.cors.reactive", - "org.springframework.web.filter", - "org.springframework.web.filter.reactive", - "org.springframework.web.jsf", - "org.springframework.web.jsf.el", - "org.springframework.web.method", - "org.springframework.web.method.annotation", - "org.springframework.web.method.support", - "org.springframework.web.multipart", - "org.springframework.web.multipart.support", - "org.springframework.web.server", - "org.springframework.web.server.adapter", - "org.springframework.web.server.handler", - "org.springframework.web.server.i18n", - "org.springframework.web.server.session", - "org.springframework.web.service", - "org.springframework.web.service.annotation", - "org.springframework.web.service.invoker", - "org.springframework.web.service.registry", - "org.springframework.web.util", - "org.springframework.web.util.pattern" - ], - "org.springframework:spring-webflux": [ - "org.springframework.web.reactive", - "org.springframework.web.reactive.accept", - "org.springframework.web.reactive.config", - "org.springframework.web.reactive.function", - "org.springframework.web.reactive.function.client", - "org.springframework.web.reactive.function.client.support", - "org.springframework.web.reactive.function.server", - "org.springframework.web.reactive.function.server.support", - "org.springframework.web.reactive.handler", - "org.springframework.web.reactive.resource", - "org.springframework.web.reactive.result", - "org.springframework.web.reactive.result.condition", - "org.springframework.web.reactive.result.method", - "org.springframework.web.reactive.result.method.annotation", - "org.springframework.web.reactive.result.view", - "org.springframework.web.reactive.result.view.freemarker", - "org.springframework.web.reactive.result.view.script", - "org.springframework.web.reactive.socket", - "org.springframework.web.reactive.socket.adapter", - "org.springframework.web.reactive.socket.client", - "org.springframework.web.reactive.socket.server", - "org.springframework.web.reactive.socket.server.support", - "org.springframework.web.reactive.socket.server.upgrade" - ], - "org.springframework:spring-webmvc": [ - "org.springframework.web.servlet", - "org.springframework.web.servlet.config", - "org.springframework.web.servlet.config.annotation", - "org.springframework.web.servlet.function", - "org.springframework.web.servlet.function.support", - "org.springframework.web.servlet.handler", - "org.springframework.web.servlet.i18n", - "org.springframework.web.servlet.mvc", - "org.springframework.web.servlet.mvc.annotation", - "org.springframework.web.servlet.mvc.condition", - "org.springframework.web.servlet.mvc.method", - "org.springframework.web.servlet.mvc.method.annotation", - "org.springframework.web.servlet.mvc.support", - "org.springframework.web.servlet.resource", - "org.springframework.web.servlet.support", - "org.springframework.web.servlet.tags", - "org.springframework.web.servlet.tags.form", - "org.springframework.web.servlet.view", - "org.springframework.web.servlet.view.document", - "org.springframework.web.servlet.view.feed", - "org.springframework.web.servlet.view.freemarker", - "org.springframework.web.servlet.view.groovy", - "org.springframework.web.servlet.view.json", - "org.springframework.web.servlet.view.script", - "org.springframework.web.servlet.view.xml", - "org.springframework.web.servlet.view.xslt" - ], - "org.testcontainers:testcontainers": [ - "org.testcontainers", - "org.testcontainers.containers", - "org.testcontainers.containers.output", - "org.testcontainers.containers.startupcheck", - "org.testcontainers.containers.traits", - "org.testcontainers.containers.wait.internal", - "org.testcontainers.containers.wait.strategy", - "org.testcontainers.core", - "org.testcontainers.dockerclient", - "org.testcontainers.images", - "org.testcontainers.images.builder", - "org.testcontainers.images.builder.dockerfile", - "org.testcontainers.images.builder.dockerfile.statement", - "org.testcontainers.images.builder.dockerfile.traits", - "org.testcontainers.images.builder.traits", - "org.testcontainers.jib", - "org.testcontainers.lifecycle", - "org.testcontainers.shaded.com.fasterxml.jackson.core", - "org.testcontainers.shaded.com.fasterxml.jackson.core.async", - "org.testcontainers.shaded.com.fasterxml.jackson.core.base", - "org.testcontainers.shaded.com.fasterxml.jackson.core.exc", - "org.testcontainers.shaded.com.fasterxml.jackson.core.filter", - "org.testcontainers.shaded.com.fasterxml.jackson.core.format", - "org.testcontainers.shaded.com.fasterxml.jackson.core.internal.shaded.fdp.v2_18_4", - "org.testcontainers.shaded.com.fasterxml.jackson.core.io", - "org.testcontainers.shaded.com.fasterxml.jackson.core.io.schubfach", - "org.testcontainers.shaded.com.fasterxml.jackson.core.json", - "org.testcontainers.shaded.com.fasterxml.jackson.core.json.async", - "org.testcontainers.shaded.com.fasterxml.jackson.core.sym", - "org.testcontainers.shaded.com.fasterxml.jackson.core.type", - "org.testcontainers.shaded.com.fasterxml.jackson.core.util", - "org.testcontainers.shaded.com.fasterxml.jackson.databind", - "org.testcontainers.shaded.com.fasterxml.jackson.databind.annotation", - "org.testcontainers.shaded.com.fasterxml.jackson.databind.cfg", - "org.testcontainers.shaded.com.fasterxml.jackson.databind.deser", - "org.testcontainers.shaded.com.fasterxml.jackson.databind.deser.impl", - "org.testcontainers.shaded.com.fasterxml.jackson.databind.deser.std", - "org.testcontainers.shaded.com.fasterxml.jackson.databind.exc", - "org.testcontainers.shaded.com.fasterxml.jackson.databind.ext", - "org.testcontainers.shaded.com.fasterxml.jackson.databind.introspect", - "org.testcontainers.shaded.com.fasterxml.jackson.databind.jdk14", - "org.testcontainers.shaded.com.fasterxml.jackson.databind.json", - "org.testcontainers.shaded.com.fasterxml.jackson.databind.jsonFormatVisitors", - "org.testcontainers.shaded.com.fasterxml.jackson.databind.jsonschema", - "org.testcontainers.shaded.com.fasterxml.jackson.databind.jsontype", - "org.testcontainers.shaded.com.fasterxml.jackson.databind.jsontype.impl", - "org.testcontainers.shaded.com.fasterxml.jackson.databind.module", - "org.testcontainers.shaded.com.fasterxml.jackson.databind.node", - "org.testcontainers.shaded.com.fasterxml.jackson.databind.ser", - "org.testcontainers.shaded.com.fasterxml.jackson.databind.ser.impl", - "org.testcontainers.shaded.com.fasterxml.jackson.databind.ser.std", - "org.testcontainers.shaded.com.fasterxml.jackson.databind.type", - "org.testcontainers.shaded.com.fasterxml.jackson.databind.util", - "org.testcontainers.shaded.com.fasterxml.jackson.databind.util.internal", - "org.testcontainers.shaded.com.github.dockerjava.core", - "org.testcontainers.shaded.com.github.dockerjava.core.async", - "org.testcontainers.shaded.com.github.dockerjava.core.command", - "org.testcontainers.shaded.com.github.dockerjava.core.dockerfile", - "org.testcontainers.shaded.com.github.dockerjava.core.exception", - "org.testcontainers.shaded.com.github.dockerjava.core.exec", - "org.testcontainers.shaded.com.github.dockerjava.core.util", - "org.testcontainers.shaded.com.google.common.annotations", - "org.testcontainers.shaded.com.google.common.base", - "org.testcontainers.shaded.com.google.common.base.internal", - "org.testcontainers.shaded.com.google.common.cache", - "org.testcontainers.shaded.com.google.common.collect", - "org.testcontainers.shaded.com.google.common.escape", - "org.testcontainers.shaded.com.google.common.eventbus", - "org.testcontainers.shaded.com.google.common.graph", - "org.testcontainers.shaded.com.google.common.hash", - "org.testcontainers.shaded.com.google.common.html", - "org.testcontainers.shaded.com.google.common.io", - "org.testcontainers.shaded.com.google.common.math", - "org.testcontainers.shaded.com.google.common.net", - "org.testcontainers.shaded.com.google.common.primitives", - "org.testcontainers.shaded.com.google.common.reflect", - "org.testcontainers.shaded.com.google.common.util.concurrent", - "org.testcontainers.shaded.com.google.common.util.concurrent.internal", - "org.testcontainers.shaded.com.google.common.xml", - "org.testcontainers.shaded.com.google.errorprone.annotations", - "org.testcontainers.shaded.com.google.errorprone.annotations.concurrent", - "org.testcontainers.shaded.com.google.thirdparty.publicsuffix", - "org.testcontainers.shaded.com.trilead.ssh2", - "org.testcontainers.shaded.com.trilead.ssh2.auth", - "org.testcontainers.shaded.com.trilead.ssh2.channel", - "org.testcontainers.shaded.com.trilead.ssh2.crypto", - "org.testcontainers.shaded.com.trilead.ssh2.crypto.cipher", - "org.testcontainers.shaded.com.trilead.ssh2.crypto.dh", - "org.testcontainers.shaded.com.trilead.ssh2.crypto.digest", - "org.testcontainers.shaded.com.trilead.ssh2.log", - "org.testcontainers.shaded.com.trilead.ssh2.packets", - "org.testcontainers.shaded.com.trilead.ssh2.sftp", - "org.testcontainers.shaded.com.trilead.ssh2.signature", - "org.testcontainers.shaded.com.trilead.ssh2.transport", - "org.testcontainers.shaded.com.trilead.ssh2.util", - "org.testcontainers.shaded.org.awaitility", - "org.testcontainers.shaded.org.awaitility.classpath", - "org.testcontainers.shaded.org.awaitility.constraint", - "org.testcontainers.shaded.org.awaitility.core", - "org.testcontainers.shaded.org.awaitility.pollinterval", - "org.testcontainers.shaded.org.awaitility.reflect", - "org.testcontainers.shaded.org.awaitility.reflect.exception", - "org.testcontainers.shaded.org.awaitility.spi", - "org.testcontainers.shaded.org.bouncycastle", - "org.testcontainers.shaded.org.bouncycastle.asn1", - "org.testcontainers.shaded.org.bouncycastle.asn1.anssi", - "org.testcontainers.shaded.org.bouncycastle.asn1.bc", - "org.testcontainers.shaded.org.bouncycastle.asn1.bsi", - "org.testcontainers.shaded.org.bouncycastle.asn1.cmc", - "org.testcontainers.shaded.org.bouncycastle.asn1.cmp", - "org.testcontainers.shaded.org.bouncycastle.asn1.cms", - "org.testcontainers.shaded.org.bouncycastle.asn1.cms.ecc", - "org.testcontainers.shaded.org.bouncycastle.asn1.crmf", - "org.testcontainers.shaded.org.bouncycastle.asn1.cryptlib", - "org.testcontainers.shaded.org.bouncycastle.asn1.cryptopro", - "org.testcontainers.shaded.org.bouncycastle.asn1.dvcs", - "org.testcontainers.shaded.org.bouncycastle.asn1.eac", - "org.testcontainers.shaded.org.bouncycastle.asn1.edec", - "org.testcontainers.shaded.org.bouncycastle.asn1.esf", - "org.testcontainers.shaded.org.bouncycastle.asn1.ess", - "org.testcontainers.shaded.org.bouncycastle.asn1.est", - "org.testcontainers.shaded.org.bouncycastle.asn1.gm", - "org.testcontainers.shaded.org.bouncycastle.asn1.gnu", - "org.testcontainers.shaded.org.bouncycastle.asn1.iana", - "org.testcontainers.shaded.org.bouncycastle.asn1.icao", - "org.testcontainers.shaded.org.bouncycastle.asn1.isara", - "org.testcontainers.shaded.org.bouncycastle.asn1.isismtt", - "org.testcontainers.shaded.org.bouncycastle.asn1.isismtt.ocsp", - "org.testcontainers.shaded.org.bouncycastle.asn1.isismtt.x509", - "org.testcontainers.shaded.org.bouncycastle.asn1.iso", - "org.testcontainers.shaded.org.bouncycastle.asn1.kisa", - "org.testcontainers.shaded.org.bouncycastle.asn1.microsoft", - "org.testcontainers.shaded.org.bouncycastle.asn1.misc", - "org.testcontainers.shaded.org.bouncycastle.asn1.mod", - "org.testcontainers.shaded.org.bouncycastle.asn1.mozilla", - "org.testcontainers.shaded.org.bouncycastle.asn1.nist", - "org.testcontainers.shaded.org.bouncycastle.asn1.nsri", - "org.testcontainers.shaded.org.bouncycastle.asn1.ntt", - "org.testcontainers.shaded.org.bouncycastle.asn1.ocsp", - "org.testcontainers.shaded.org.bouncycastle.asn1.oiw", - "org.testcontainers.shaded.org.bouncycastle.asn1.pkcs", - "org.testcontainers.shaded.org.bouncycastle.asn1.rosstandart", - "org.testcontainers.shaded.org.bouncycastle.asn1.sec", - "org.testcontainers.shaded.org.bouncycastle.asn1.smime", - "org.testcontainers.shaded.org.bouncycastle.asn1.teletrust", - "org.testcontainers.shaded.org.bouncycastle.asn1.tsp", - "org.testcontainers.shaded.org.bouncycastle.asn1.ua", - "org.testcontainers.shaded.org.bouncycastle.asn1.util", - "org.testcontainers.shaded.org.bouncycastle.asn1.x500", - "org.testcontainers.shaded.org.bouncycastle.asn1.x500.style", - "org.testcontainers.shaded.org.bouncycastle.asn1.x509", - "org.testcontainers.shaded.org.bouncycastle.asn1.x509.qualified", - "org.testcontainers.shaded.org.bouncycastle.asn1.x509.sigi", - "org.testcontainers.shaded.org.bouncycastle.asn1.x9", - "org.testcontainers.shaded.org.bouncycastle.cert", - "org.testcontainers.shaded.org.bouncycastle.cert.bc", - "org.testcontainers.shaded.org.bouncycastle.cert.cmp", - "org.testcontainers.shaded.org.bouncycastle.cert.crmf", - "org.testcontainers.shaded.org.bouncycastle.cert.crmf.bc", - "org.testcontainers.shaded.org.bouncycastle.cert.crmf.jcajce", - "org.testcontainers.shaded.org.bouncycastle.cert.dane", - "org.testcontainers.shaded.org.bouncycastle.cert.dane.fetcher", - "org.testcontainers.shaded.org.bouncycastle.cert.jcajce", - "org.testcontainers.shaded.org.bouncycastle.cert.ocsp", - "org.testcontainers.shaded.org.bouncycastle.cert.ocsp.jcajce", - "org.testcontainers.shaded.org.bouncycastle.cert.path", - "org.testcontainers.shaded.org.bouncycastle.cert.path.validations", - "org.testcontainers.shaded.org.bouncycastle.cert.selector", - "org.testcontainers.shaded.org.bouncycastle.cert.selector.jcajce", - "org.testcontainers.shaded.org.bouncycastle.cmc", - "org.testcontainers.shaded.org.bouncycastle.cms", - "org.testcontainers.shaded.org.bouncycastle.cms.bc", - "org.testcontainers.shaded.org.bouncycastle.cms.jcajce", - "org.testcontainers.shaded.org.bouncycastle.crypto", - "org.testcontainers.shaded.org.bouncycastle.crypto.agreement", - "org.testcontainers.shaded.org.bouncycastle.crypto.agreement.ecjpake", - "org.testcontainers.shaded.org.bouncycastle.crypto.agreement.jpake", - "org.testcontainers.shaded.org.bouncycastle.crypto.agreement.kdf", - "org.testcontainers.shaded.org.bouncycastle.crypto.agreement.srp", - "org.testcontainers.shaded.org.bouncycastle.crypto.commitments", - "org.testcontainers.shaded.org.bouncycastle.crypto.constraints", - "org.testcontainers.shaded.org.bouncycastle.crypto.digests", - "org.testcontainers.shaded.org.bouncycastle.crypto.ec", - "org.testcontainers.shaded.org.bouncycastle.crypto.encodings", - "org.testcontainers.shaded.org.bouncycastle.crypto.engines", - "org.testcontainers.shaded.org.bouncycastle.crypto.examples", - "org.testcontainers.shaded.org.bouncycastle.crypto.fpe", - "org.testcontainers.shaded.org.bouncycastle.crypto.generators", - "org.testcontainers.shaded.org.bouncycastle.crypto.hpke", - "org.testcontainers.shaded.org.bouncycastle.crypto.io", - "org.testcontainers.shaded.org.bouncycastle.crypto.kems", - "org.testcontainers.shaded.org.bouncycastle.crypto.macs", - "org.testcontainers.shaded.org.bouncycastle.crypto.modes", - "org.testcontainers.shaded.org.bouncycastle.crypto.modes.gcm", - "org.testcontainers.shaded.org.bouncycastle.crypto.modes.kgcm", - "org.testcontainers.shaded.org.bouncycastle.crypto.paddings", - "org.testcontainers.shaded.org.bouncycastle.crypto.params", - "org.testcontainers.shaded.org.bouncycastle.crypto.parsers", - "org.testcontainers.shaded.org.bouncycastle.crypto.prng", - "org.testcontainers.shaded.org.bouncycastle.crypto.prng.drbg", - "org.testcontainers.shaded.org.bouncycastle.crypto.signers", - "org.testcontainers.shaded.org.bouncycastle.crypto.threshold", - "org.testcontainers.shaded.org.bouncycastle.crypto.tls", - "org.testcontainers.shaded.org.bouncycastle.crypto.util", - "org.testcontainers.shaded.org.bouncycastle.dvcs", - "org.testcontainers.shaded.org.bouncycastle.eac", - "org.testcontainers.shaded.org.bouncycastle.eac.jcajce", - "org.testcontainers.shaded.org.bouncycastle.eac.operator", - "org.testcontainers.shaded.org.bouncycastle.eac.operator.jcajce", - "org.testcontainers.shaded.org.bouncycastle.est", - "org.testcontainers.shaded.org.bouncycastle.est.jcajce", - "org.testcontainers.shaded.org.bouncycastle.i18n", - "org.testcontainers.shaded.org.bouncycastle.i18n.filter", - "org.testcontainers.shaded.org.bouncycastle.iana", - "org.testcontainers.shaded.org.bouncycastle.internal.asn1.bsi", - "org.testcontainers.shaded.org.bouncycastle.internal.asn1.cms", - "org.testcontainers.shaded.org.bouncycastle.internal.asn1.cryptlib", - "org.testcontainers.shaded.org.bouncycastle.internal.asn1.eac", - "org.testcontainers.shaded.org.bouncycastle.internal.asn1.edec", - "org.testcontainers.shaded.org.bouncycastle.internal.asn1.gnu", - "org.testcontainers.shaded.org.bouncycastle.internal.asn1.iana", - "org.testcontainers.shaded.org.bouncycastle.internal.asn1.isara", - "org.testcontainers.shaded.org.bouncycastle.internal.asn1.isismtt", - "org.testcontainers.shaded.org.bouncycastle.internal.asn1.iso", - "org.testcontainers.shaded.org.bouncycastle.internal.asn1.kisa", - "org.testcontainers.shaded.org.bouncycastle.internal.asn1.microsoft", - "org.testcontainers.shaded.org.bouncycastle.internal.asn1.misc", - "org.testcontainers.shaded.org.bouncycastle.internal.asn1.nsri", - "org.testcontainers.shaded.org.bouncycastle.internal.asn1.ntt", - "org.testcontainers.shaded.org.bouncycastle.internal.asn1.oiw", - "org.testcontainers.shaded.org.bouncycastle.internal.asn1.rosstandart", - "org.testcontainers.shaded.org.bouncycastle.its", - "org.testcontainers.shaded.org.bouncycastle.its.bc", - "org.testcontainers.shaded.org.bouncycastle.its.jcajce", - "org.testcontainers.shaded.org.bouncycastle.its.operator", - "org.testcontainers.shaded.org.bouncycastle.jcajce", - "org.testcontainers.shaded.org.bouncycastle.jcajce.interfaces", - "org.testcontainers.shaded.org.bouncycastle.jcajce.io", - "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.asymmetric", - "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.asymmetric.compositesignatures", - "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.asymmetric.dh", - "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.asymmetric.dsa", - "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.asymmetric.dstu", - "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.asymmetric.ec", - "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.asymmetric.ecgost", - "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.asymmetric.ecgost12", - "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.asymmetric.edec", - "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.asymmetric.elgamal", - "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.asymmetric.gost", - "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.asymmetric.ies", - "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.asymmetric.mldsa", - "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.asymmetric.mlkem", - "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.asymmetric.rsa", - "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.asymmetric.slhdsa", - "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.asymmetric.util", - "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.asymmetric.x509", - "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.config", - "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.digest", - "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.drbg", - "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.keystore", - "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.keystore.bc", - "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.keystore.bcfks", - "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.keystore.pkcs12", - "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.keystore.util", - "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.symmetric", - "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.symmetric.util", - "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.util", - "org.testcontainers.shaded.org.bouncycastle.jcajce.spec", - "org.testcontainers.shaded.org.bouncycastle.jcajce.util", - "org.testcontainers.shaded.org.bouncycastle.jce", - "org.testcontainers.shaded.org.bouncycastle.jce.exception", - "org.testcontainers.shaded.org.bouncycastle.jce.interfaces", - "org.testcontainers.shaded.org.bouncycastle.jce.netscape", - "org.testcontainers.shaded.org.bouncycastle.jce.provider", - "org.testcontainers.shaded.org.bouncycastle.jce.spec", - "org.testcontainers.shaded.org.bouncycastle.math", - "org.testcontainers.shaded.org.bouncycastle.math.ec", - "org.testcontainers.shaded.org.bouncycastle.math.ec.custom.djb", - "org.testcontainers.shaded.org.bouncycastle.math.ec.custom.gm", - "org.testcontainers.shaded.org.bouncycastle.math.ec.custom.sec", - "org.testcontainers.shaded.org.bouncycastle.math.ec.endo", - "org.testcontainers.shaded.org.bouncycastle.math.ec.rfc7748", - "org.testcontainers.shaded.org.bouncycastle.math.ec.rfc8032", - "org.testcontainers.shaded.org.bouncycastle.math.ec.tools", - "org.testcontainers.shaded.org.bouncycastle.math.field", - "org.testcontainers.shaded.org.bouncycastle.math.raw", - "org.testcontainers.shaded.org.bouncycastle.mime", - "org.testcontainers.shaded.org.bouncycastle.mime.encoding", - "org.testcontainers.shaded.org.bouncycastle.mime.smime", - "org.testcontainers.shaded.org.bouncycastle.mozilla", - "org.testcontainers.shaded.org.bouncycastle.mozilla.jcajce", - "org.testcontainers.shaded.org.bouncycastle.oer", - "org.testcontainers.shaded.org.bouncycastle.oer.its", - "org.testcontainers.shaded.org.bouncycastle.oer.its.etsi102941", - "org.testcontainers.shaded.org.bouncycastle.oer.its.etsi102941.basetypes", - "org.testcontainers.shaded.org.bouncycastle.oer.its.etsi103097", - "org.testcontainers.shaded.org.bouncycastle.oer.its.etsi103097.extension", - "org.testcontainers.shaded.org.bouncycastle.oer.its.ieee1609dot2", - "org.testcontainers.shaded.org.bouncycastle.oer.its.ieee1609dot2.basetypes", - "org.testcontainers.shaded.org.bouncycastle.oer.its.ieee1609dot2dot1", - "org.testcontainers.shaded.org.bouncycastle.oer.its.template.etsi102941", - "org.testcontainers.shaded.org.bouncycastle.oer.its.template.etsi102941.basetypes", - "org.testcontainers.shaded.org.bouncycastle.oer.its.template.etsi103097", - "org.testcontainers.shaded.org.bouncycastle.oer.its.template.etsi103097.extension", - "org.testcontainers.shaded.org.bouncycastle.oer.its.template.ieee1609dot2", - "org.testcontainers.shaded.org.bouncycastle.oer.its.template.ieee1609dot2.basetypes", - "org.testcontainers.shaded.org.bouncycastle.oer.its.template.ieee1609dot2dot1", - "org.testcontainers.shaded.org.bouncycastle.openssl", - "org.testcontainers.shaded.org.bouncycastle.openssl.bc", - "org.testcontainers.shaded.org.bouncycastle.openssl.jcajce", - "org.testcontainers.shaded.org.bouncycastle.operator", - "org.testcontainers.shaded.org.bouncycastle.operator.bc", - "org.testcontainers.shaded.org.bouncycastle.operator.jcajce", - "org.testcontainers.shaded.org.bouncycastle.pkcs", - "org.testcontainers.shaded.org.bouncycastle.pkcs.bc", - "org.testcontainers.shaded.org.bouncycastle.pkcs.jcajce", - "org.testcontainers.shaded.org.bouncycastle.pkix", - "org.testcontainers.shaded.org.bouncycastle.pkix.jcajce", - "org.testcontainers.shaded.org.bouncycastle.pkix.util", - "org.testcontainers.shaded.org.bouncycastle.pkix.util.filter", - "org.testcontainers.shaded.org.bouncycastle.pqc.asn1", - "org.testcontainers.shaded.org.bouncycastle.pqc.crypto", - "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.bike", - "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.cmce", - "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.crystals.dilithium", - "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.falcon", - "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.frodo", - "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.hqc", - "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.lms", - "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.mayo", - "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.mldsa", - "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.mlkem", - "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.newhope", - "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.ntru", - "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.ntruprime", - "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.picnic", - "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.rainbow", - "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.saber", - "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.slhdsa", - "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.snova", - "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.sphincs", - "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.sphincsplus", - "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.util", - "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.xmss", - "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.xwing", - "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.interfaces", - "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider", - "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider.bike", - "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider.cmce", - "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider.dilithium", - "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider.falcon", - "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider.frodo", - "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider.hqc", - "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider.kyber", - "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider.lms", - "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider.mayo", - "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider.newhope", - "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider.ntru", - "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider.ntruprime", - "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider.picnic", - "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider.saber", - "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider.snova", - "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider.sphincs", - "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider.sphincsplus", - "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider.util", - "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider.xmss", - "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.spec", - "org.testcontainers.shaded.org.bouncycastle.pqc.math.ntru", - "org.testcontainers.shaded.org.bouncycastle.pqc.math.ntru.parameters", - "org.testcontainers.shaded.org.bouncycastle.tsp", - "org.testcontainers.shaded.org.bouncycastle.tsp.cms", - "org.testcontainers.shaded.org.bouncycastle.tsp.ers", - "org.testcontainers.shaded.org.bouncycastle.util", - "org.testcontainers.shaded.org.bouncycastle.util.encoders", - "org.testcontainers.shaded.org.bouncycastle.util.io", - "org.testcontainers.shaded.org.bouncycastle.util.io.pem", - "org.testcontainers.shaded.org.bouncycastle.util.test", - "org.testcontainers.shaded.org.bouncycastle.voms", - "org.testcontainers.shaded.org.bouncycastle.x509", - "org.testcontainers.shaded.org.bouncycastle.x509.extension", - "org.testcontainers.shaded.org.bouncycastle.x509.util", - "org.testcontainers.shaded.org.checkerframework.checker.builder.qual", - "org.testcontainers.shaded.org.checkerframework.checker.calledmethods.qual", - "org.testcontainers.shaded.org.checkerframework.checker.compilermsgs.qual", - "org.testcontainers.shaded.org.checkerframework.checker.fenum.qual", - "org.testcontainers.shaded.org.checkerframework.checker.formatter.qual", - "org.testcontainers.shaded.org.checkerframework.checker.guieffect.qual", - "org.testcontainers.shaded.org.checkerframework.checker.i18n.qual", - "org.testcontainers.shaded.org.checkerframework.checker.i18nformatter.qual", - "org.testcontainers.shaded.org.checkerframework.checker.index.qual", - "org.testcontainers.shaded.org.checkerframework.checker.initialization.qual", - "org.testcontainers.shaded.org.checkerframework.checker.interning.qual", - "org.testcontainers.shaded.org.checkerframework.checker.lock.qual", - "org.testcontainers.shaded.org.checkerframework.checker.mustcall.qual", - "org.testcontainers.shaded.org.checkerframework.checker.nullness.qual", - "org.testcontainers.shaded.org.checkerframework.checker.optional.qual", - "org.testcontainers.shaded.org.checkerframework.checker.propkey.qual", - "org.testcontainers.shaded.org.checkerframework.checker.regex.qual", - "org.testcontainers.shaded.org.checkerframework.checker.signature.qual", - "org.testcontainers.shaded.org.checkerframework.checker.signedness.qual", - "org.testcontainers.shaded.org.checkerframework.checker.tainting.qual", - "org.testcontainers.shaded.org.checkerframework.checker.units.qual", - "org.testcontainers.shaded.org.checkerframework.common.aliasing.qual", - "org.testcontainers.shaded.org.checkerframework.common.initializedfields.qual", - "org.testcontainers.shaded.org.checkerframework.common.reflection.qual", - "org.testcontainers.shaded.org.checkerframework.common.returnsreceiver.qual", - "org.testcontainers.shaded.org.checkerframework.common.subtyping.qual", - "org.testcontainers.shaded.org.checkerframework.common.util.count.report.qual", - "org.testcontainers.shaded.org.checkerframework.common.value.qual", - "org.testcontainers.shaded.org.checkerframework.dataflow.qual", - "org.testcontainers.shaded.org.checkerframework.framework.qual", - "org.testcontainers.shaded.org.hamcrest", - "org.testcontainers.shaded.org.hamcrest.beans", - "org.testcontainers.shaded.org.hamcrest.collection", - "org.testcontainers.shaded.org.hamcrest.comparator", - "org.testcontainers.shaded.org.hamcrest.core", - "org.testcontainers.shaded.org.hamcrest.internal", - "org.testcontainers.shaded.org.hamcrest.io", - "org.testcontainers.shaded.org.hamcrest.number", - "org.testcontainers.shaded.org.hamcrest.object", - "org.testcontainers.shaded.org.hamcrest.text", - "org.testcontainers.shaded.org.hamcrest.xml", - "org.testcontainers.shaded.org.yaml.snakeyaml", - "org.testcontainers.shaded.org.yaml.snakeyaml.comments", - "org.testcontainers.shaded.org.yaml.snakeyaml.composer", - "org.testcontainers.shaded.org.yaml.snakeyaml.constructor", - "org.testcontainers.shaded.org.yaml.snakeyaml.emitter", - "org.testcontainers.shaded.org.yaml.snakeyaml.env", - "org.testcontainers.shaded.org.yaml.snakeyaml.error", - "org.testcontainers.shaded.org.yaml.snakeyaml.events", - "org.testcontainers.shaded.org.yaml.snakeyaml.extensions.compactnotation", - "org.testcontainers.shaded.org.yaml.snakeyaml.external.com.google.gdata.util.common.base", - "org.testcontainers.shaded.org.yaml.snakeyaml.inspector", - "org.testcontainers.shaded.org.yaml.snakeyaml.internal", - "org.testcontainers.shaded.org.yaml.snakeyaml.introspector", - "org.testcontainers.shaded.org.yaml.snakeyaml.nodes", - "org.testcontainers.shaded.org.yaml.snakeyaml.parser", - "org.testcontainers.shaded.org.yaml.snakeyaml.reader", - "org.testcontainers.shaded.org.yaml.snakeyaml.representer", - "org.testcontainers.shaded.org.yaml.snakeyaml.resolver", - "org.testcontainers.shaded.org.yaml.snakeyaml.scanner", - "org.testcontainers.shaded.org.yaml.snakeyaml.serializer", - "org.testcontainers.shaded.org.yaml.snakeyaml.tokens", - "org.testcontainers.shaded.org.yaml.snakeyaml.util", - "org.testcontainers.shaded.org.zeroturnaround.exec", - "org.testcontainers.shaded.org.zeroturnaround.exec.close", - "org.testcontainers.shaded.org.zeroturnaround.exec.listener", - "org.testcontainers.shaded.org.zeroturnaround.exec.stop", - "org.testcontainers.shaded.org.zeroturnaround.exec.stream", - "org.testcontainers.shaded.org.zeroturnaround.exec.stream.slf4j", - "org.testcontainers.utility" - ], - "org.testcontainers:testcontainers-cassandra": [ - "org.testcontainers.cassandra", - "org.testcontainers.containers", - "org.testcontainers.containers.delegate", - "org.testcontainers.containers.wait" - ], - "org.testcontainers:testcontainers-database-commons": [ - "org.testcontainers.delegate", - "org.testcontainers.exception", - "org.testcontainers.ext" - ], - "org.testcontainers:testcontainers-junit-jupiter": [ - "org.testcontainers.junit.jupiter" - ], - "org.testcontainers:testcontainers-localstack": [ - "org.testcontainers.containers.localstack", - "org.testcontainers.localstack" - ], - "org.wiremock:wiremock-standalone": [ - "com.github.tomakehurst.wiremock", - "com.github.tomakehurst.wiremock.admin", - "com.github.tomakehurst.wiremock.admin.model", - "com.github.tomakehurst.wiremock.admin.tasks", - "com.github.tomakehurst.wiremock.client", - "com.github.tomakehurst.wiremock.common", - "com.github.tomakehurst.wiremock.common.filemaker", - "com.github.tomakehurst.wiremock.common.ssl", - "com.github.tomakehurst.wiremock.common.url", - "com.github.tomakehurst.wiremock.common.xml", - "com.github.tomakehurst.wiremock.core", - "com.github.tomakehurst.wiremock.direct", - "com.github.tomakehurst.wiremock.extension", - "com.github.tomakehurst.wiremock.extension.requestfilter", - "com.github.tomakehurst.wiremock.extension.responsetemplating", - "com.github.tomakehurst.wiremock.extension.responsetemplating.helpers", - "com.github.tomakehurst.wiremock.global", - "com.github.tomakehurst.wiremock.http", - "com.github.tomakehurst.wiremock.http.client", - "com.github.tomakehurst.wiremock.http.multipart", - "com.github.tomakehurst.wiremock.http.ssl", - "com.github.tomakehurst.wiremock.http.trafficlistener", - "com.github.tomakehurst.wiremock.jetty", - "com.github.tomakehurst.wiremock.jetty11", - "com.github.tomakehurst.wiremock.junit", - "com.github.tomakehurst.wiremock.junit5", - "com.github.tomakehurst.wiremock.matching", - "com.github.tomakehurst.wiremock.recording", - "com.github.tomakehurst.wiremock.security", - "com.github.tomakehurst.wiremock.servlet", - "com.github.tomakehurst.wiremock.standalone", - "com.github.tomakehurst.wiremock.store", - "com.github.tomakehurst.wiremock.store.files", - "com.github.tomakehurst.wiremock.stubbing", - "com.github.tomakehurst.wiremock.verification", - "com.github.tomakehurst.wiremock.verification.diff", - "com.github.tomakehurst.wiremock.verification.notmatched", - "org.jspecify.annotations", - "org.wiremock.annotations", - "org.wiremock.webhooks", - "wiremock", - "wiremock.com.ethlo.time", - "wiremock.com.ethlo.time.internal", - "wiremock.com.ethlo.time.internal.fixed", - "wiremock.com.ethlo.time.internal.token", - "wiremock.com.ethlo.time.internal.util", - "wiremock.com.ethlo.time.token", - "wiremock.com.fasterxml.jackson.annotation", - "wiremock.com.fasterxml.jackson.core", - "wiremock.com.fasterxml.jackson.core.async", - "wiremock.com.fasterxml.jackson.core.base", - "wiremock.com.fasterxml.jackson.core.exc", - "wiremock.com.fasterxml.jackson.core.filter", - "wiremock.com.fasterxml.jackson.core.format", - "wiremock.com.fasterxml.jackson.core.internal.shaded.fdp.v2_20_1", - "wiremock.com.fasterxml.jackson.core.internal.shaded.fdp.v2_20_1.bte", - "wiremock.com.fasterxml.jackson.core.internal.shaded.fdp.v2_20_1.chr", - "wiremock.com.fasterxml.jackson.core.io", - "wiremock.com.fasterxml.jackson.core.io.schubfach", - "wiremock.com.fasterxml.jackson.core.json", - "wiremock.com.fasterxml.jackson.core.json.async", - "wiremock.com.fasterxml.jackson.core.sym", - "wiremock.com.fasterxml.jackson.core.type", - "wiremock.com.fasterxml.jackson.core.util", - "wiremock.com.fasterxml.jackson.databind", - "wiremock.com.fasterxml.jackson.databind.annotation", - "wiremock.com.fasterxml.jackson.databind.cfg", - "wiremock.com.fasterxml.jackson.databind.deser", - "wiremock.com.fasterxml.jackson.databind.deser.impl", - "wiremock.com.fasterxml.jackson.databind.deser.std", - "wiremock.com.fasterxml.jackson.databind.exc", - "wiremock.com.fasterxml.jackson.databind.ext", - "wiremock.com.fasterxml.jackson.databind.introspect", - "wiremock.com.fasterxml.jackson.databind.jdk14", - "wiremock.com.fasterxml.jackson.databind.json", - "wiremock.com.fasterxml.jackson.databind.jsonFormatVisitors", - "wiremock.com.fasterxml.jackson.databind.jsonschema", - "wiremock.com.fasterxml.jackson.databind.jsontype", - "wiremock.com.fasterxml.jackson.databind.jsontype.impl", - "wiremock.com.fasterxml.jackson.databind.module", - "wiremock.com.fasterxml.jackson.databind.node", - "wiremock.com.fasterxml.jackson.databind.ser", - "wiremock.com.fasterxml.jackson.databind.ser.impl", - "wiremock.com.fasterxml.jackson.databind.ser.std", - "wiremock.com.fasterxml.jackson.databind.type", - "wiremock.com.fasterxml.jackson.databind.util", - "wiremock.com.fasterxml.jackson.databind.util.internal", - "wiremock.com.fasterxml.jackson.dataformat.yaml", - "wiremock.com.fasterxml.jackson.dataformat.yaml.snakeyaml.error", - "wiremock.com.fasterxml.jackson.dataformat.yaml.util", - "wiremock.com.fasterxml.jackson.datatype.jsr310", - "wiremock.com.fasterxml.jackson.datatype.jsr310.deser", - "wiremock.com.fasterxml.jackson.datatype.jsr310.deser.key", - "wiremock.com.fasterxml.jackson.datatype.jsr310.ser", - "wiremock.com.fasterxml.jackson.datatype.jsr310.ser.key", - "wiremock.com.fasterxml.jackson.datatype.jsr310.util", - "wiremock.com.github.jknack.handlebars", - "wiremock.com.github.jknack.handlebars.cache", - "wiremock.com.github.jknack.handlebars.context", - "wiremock.com.github.jknack.handlebars.helper", - "wiremock.com.github.jknack.handlebars.internal", - "wiremock.com.github.jknack.handlebars.internal.antlr", - "wiremock.com.github.jknack.handlebars.internal.antlr.atn", - "wiremock.com.github.jknack.handlebars.internal.antlr.dfa", - "wiremock.com.github.jknack.handlebars.internal.antlr.misc", - "wiremock.com.github.jknack.handlebars.internal.antlr.tree", - "wiremock.com.github.jknack.handlebars.internal.antlr.tree.pattern", - "wiremock.com.github.jknack.handlebars.internal.antlr.tree.xpath", - "wiremock.com.github.jknack.handlebars.internal.lang3", - "wiremock.com.github.jknack.handlebars.internal.lang3.builder", - "wiremock.com.github.jknack.handlebars.internal.lang3.exception", - "wiremock.com.github.jknack.handlebars.internal.lang3.function", - "wiremock.com.github.jknack.handlebars.internal.lang3.math", - "wiremock.com.github.jknack.handlebars.internal.lang3.mutable", - "wiremock.com.github.jknack.handlebars.internal.lang3.text", - "wiremock.com.github.jknack.handlebars.internal.lang3.text.translate", - "wiremock.com.github.jknack.handlebars.internal.lang3.time", - "wiremock.com.github.jknack.handlebars.internal.lang3.tuple", - "wiremock.com.github.jknack.handlebars.internal.path", - "wiremock.com.github.jknack.handlebars.internal.text", - "wiremock.com.github.jknack.handlebars.internal.text.diff", - "wiremock.com.github.jknack.handlebars.internal.text.io", - "wiremock.com.github.jknack.handlebars.internal.text.lookup", - "wiremock.com.github.jknack.handlebars.internal.text.matcher", - "wiremock.com.github.jknack.handlebars.internal.text.numbers", - "wiremock.com.github.jknack.handlebars.internal.text.similarity", - "wiremock.com.github.jknack.handlebars.internal.text.translate", - "wiremock.com.github.jknack.handlebars.io", - "wiremock.com.google.common.annotations", - "wiremock.com.google.common.base", - "wiremock.com.google.common.base.internal", - "wiremock.com.google.common.cache", - "wiremock.com.google.common.collect", - "wiremock.com.google.common.escape", - "wiremock.com.google.common.eventbus", - "wiremock.com.google.common.graph", - "wiremock.com.google.common.hash", - "wiremock.com.google.common.html", - "wiremock.com.google.common.io", - "wiremock.com.google.common.math", - "wiremock.com.google.common.net", - "wiremock.com.google.common.primitives", - "wiremock.com.google.common.reflect", - "wiremock.com.google.common.util.concurrent", - "wiremock.com.google.common.util.concurrent.internal", - "wiremock.com.google.common.xml", - "wiremock.com.google.errorprone.annotations", - "wiremock.com.google.errorprone.annotations.concurrent", - "wiremock.com.google.j2objc.annotations", - "wiremock.com.google.thirdparty.publicsuffix", - "wiremock.com.jayway.jsonpath", - "wiremock.com.jayway.jsonpath.internal", - "wiremock.com.jayway.jsonpath.internal.filter", - "wiremock.com.jayway.jsonpath.internal.function", - "wiremock.com.jayway.jsonpath.internal.function.json", - "wiremock.com.jayway.jsonpath.internal.function.latebinding", - "wiremock.com.jayway.jsonpath.internal.function.numeric", - "wiremock.com.jayway.jsonpath.internal.function.sequence", - "wiremock.com.jayway.jsonpath.internal.function.text", - "wiremock.com.jayway.jsonpath.internal.path", - "wiremock.com.jayway.jsonpath.spi.cache", - "wiremock.com.jayway.jsonpath.spi.json", - "wiremock.com.jayway.jsonpath.spi.mapper", - "wiremock.com.networknt.org.apache.commons.validator.routines", - "wiremock.com.networknt.schema", - "wiremock.com.networknt.schema.annotation", - "wiremock.com.networknt.schema.format", - "wiremock.com.networknt.schema.i18n", - "wiremock.com.networknt.schema.oas", - "wiremock.com.networknt.schema.output", - "wiremock.com.networknt.schema.regex", - "wiremock.com.networknt.schema.resource", - "wiremock.com.networknt.schema.result", - "wiremock.com.networknt.schema.serialization", - "wiremock.com.networknt.schema.serialization.node", - "wiremock.com.networknt.schema.utils", - "wiremock.com.networknt.schema.walk", - "wiremock.jakarta.servlet", - "wiremock.jakarta.servlet.annotation", - "wiremock.jakarta.servlet.descriptor", - "wiremock.jakarta.servlet.http", - "wiremock.joptsimple", - "wiremock.joptsimple.internal", - "wiremock.joptsimple.util", - "wiremock.net.javacrumbs.jsonunit.core", - "wiremock.net.javacrumbs.jsonunit.core.internal", - "wiremock.net.javacrumbs.jsonunit.core.internal.matchers", - "wiremock.net.javacrumbs.jsonunit.core.listener", - "wiremock.net.javacrumbs.jsonunit.core.util", - "wiremock.net.javacrumbs.jsonunit.providers", - "wiremock.net.minidev.asm", - "wiremock.net.minidev.asm.ex", - "wiremock.net.minidev.json", - "wiremock.net.minidev.json.annotate", - "wiremock.net.minidev.json.parser", - "wiremock.net.minidev.json.reader", - "wiremock.net.minidev.json.writer", - "wiremock.org.apache.commons.fileupload", - "wiremock.org.apache.commons.fileupload.disk", - "wiremock.org.apache.commons.fileupload.portlet", - "wiremock.org.apache.commons.fileupload.servlet", - "wiremock.org.apache.commons.fileupload.util", - "wiremock.org.apache.commons.fileupload.util.mime", - "wiremock.org.apache.commons.io", - "wiremock.org.apache.commons.io.build", - "wiremock.org.apache.commons.io.channels", - "wiremock.org.apache.commons.io.charset", - "wiremock.org.apache.commons.io.comparator", - "wiremock.org.apache.commons.io.file", - "wiremock.org.apache.commons.io.file.attribute", - "wiremock.org.apache.commons.io.file.spi", - "wiremock.org.apache.commons.io.filefilter", - "wiremock.org.apache.commons.io.function", - "wiremock.org.apache.commons.io.input", - "wiremock.org.apache.commons.io.input.buffer", - "wiremock.org.apache.commons.io.monitor", - "wiremock.org.apache.commons.io.output", - "wiremock.org.apache.commons.io.serialization", - "wiremock.org.apache.hc.client5.http", - "wiremock.org.apache.hc.client5.http.async", - "wiremock.org.apache.hc.client5.http.async.methods", - "wiremock.org.apache.hc.client5.http.auth", - "wiremock.org.apache.hc.client5.http.classic", - "wiremock.org.apache.hc.client5.http.classic.methods", - "wiremock.org.apache.hc.client5.http.config", - "wiremock.org.apache.hc.client5.http.cookie", - "wiremock.org.apache.hc.client5.http.entity", - "wiremock.org.apache.hc.client5.http.entity.mime", - "wiremock.org.apache.hc.client5.http.impl", - "wiremock.org.apache.hc.client5.http.impl.async", - "wiremock.org.apache.hc.client5.http.impl.auth", - "wiremock.org.apache.hc.client5.http.impl.classic", - "wiremock.org.apache.hc.client5.http.impl.compat", - "wiremock.org.apache.hc.client5.http.impl.cookie", - "wiremock.org.apache.hc.client5.http.impl.io", - "wiremock.org.apache.hc.client5.http.impl.nio", - "wiremock.org.apache.hc.client5.http.impl.routing", - "wiremock.org.apache.hc.client5.http.io", - "wiremock.org.apache.hc.client5.http.nio", - "wiremock.org.apache.hc.client5.http.protocol", - "wiremock.org.apache.hc.client5.http.psl", - "wiremock.org.apache.hc.client5.http.routing", - "wiremock.org.apache.hc.client5.http.socket", - "wiremock.org.apache.hc.client5.http.ssl", - "wiremock.org.apache.hc.client5.http.utils", - "wiremock.org.apache.hc.client5.http.validator", - "wiremock.org.apache.hc.core5.annotation", - "wiremock.org.apache.hc.core5.concurrent", - "wiremock.org.apache.hc.core5.function", - "wiremock.org.apache.hc.core5.http", - "wiremock.org.apache.hc.core5.http.config", - "wiremock.org.apache.hc.core5.http.impl", - "wiremock.org.apache.hc.core5.http.impl.bootstrap", - "wiremock.org.apache.hc.core5.http.impl.io", - "wiremock.org.apache.hc.core5.http.impl.nio", - "wiremock.org.apache.hc.core5.http.impl.routing", - "wiremock.org.apache.hc.core5.http.io", - "wiremock.org.apache.hc.core5.http.io.entity", - "wiremock.org.apache.hc.core5.http.io.ssl", - "wiremock.org.apache.hc.core5.http.io.support", - "wiremock.org.apache.hc.core5.http.message", - "wiremock.org.apache.hc.core5.http.nio", - "wiremock.org.apache.hc.core5.http.nio.command", - "wiremock.org.apache.hc.core5.http.nio.entity", - "wiremock.org.apache.hc.core5.http.nio.ssl", - "wiremock.org.apache.hc.core5.http.nio.support", - "wiremock.org.apache.hc.core5.http.nio.support.classic", - "wiremock.org.apache.hc.core5.http.protocol", - "wiremock.org.apache.hc.core5.http.ssl", - "wiremock.org.apache.hc.core5.http.support", - "wiremock.org.apache.hc.core5.http2", - "wiremock.org.apache.hc.core5.http2.config", - "wiremock.org.apache.hc.core5.http2.frame", - "wiremock.org.apache.hc.core5.http2.hpack", - "wiremock.org.apache.hc.core5.http2.impl", - "wiremock.org.apache.hc.core5.http2.impl.io", - "wiremock.org.apache.hc.core5.http2.impl.nio", - "wiremock.org.apache.hc.core5.http2.impl.nio.bootstrap", - "wiremock.org.apache.hc.core5.http2.nio", - "wiremock.org.apache.hc.core5.http2.nio.command", - "wiremock.org.apache.hc.core5.http2.nio.pool", - "wiremock.org.apache.hc.core5.http2.nio.support", - "wiremock.org.apache.hc.core5.http2.protocol", - "wiremock.org.apache.hc.core5.http2.ssl", - "wiremock.org.apache.hc.core5.io", - "wiremock.org.apache.hc.core5.net", - "wiremock.org.apache.hc.core5.pool", - "wiremock.org.apache.hc.core5.reactor", - "wiremock.org.apache.hc.core5.reactor.ssl", - "wiremock.org.apache.hc.core5.ssl", - "wiremock.org.apache.hc.core5.util", - "wiremock.org.custommonkey.xmlunit", - "wiremock.org.custommonkey.xmlunit.examples", - "wiremock.org.custommonkey.xmlunit.exceptions", - "wiremock.org.custommonkey.xmlunit.jaxp13", - "wiremock.org.custommonkey.xmlunit.util", - "wiremock.org.eclipse.jetty.alpn.client", - "wiremock.org.eclipse.jetty.alpn.java.client", - "wiremock.org.eclipse.jetty.alpn.java.server", - "wiremock.org.eclipse.jetty.alpn.server", - "wiremock.org.eclipse.jetty.client", - "wiremock.org.eclipse.jetty.client.api", - "wiremock.org.eclipse.jetty.client.dynamic", - "wiremock.org.eclipse.jetty.client.http", - "wiremock.org.eclipse.jetty.client.internal", - "wiremock.org.eclipse.jetty.client.jmx", - "wiremock.org.eclipse.jetty.client.util", - "wiremock.org.eclipse.jetty.http", - "wiremock.org.eclipse.jetty.http.compression", - "wiremock.org.eclipse.jetty.http.pathmap", - "wiremock.org.eclipse.jetty.http2", - "wiremock.org.eclipse.jetty.http2.api", - "wiremock.org.eclipse.jetty.http2.api.server", - "wiremock.org.eclipse.jetty.http2.frames", - "wiremock.org.eclipse.jetty.http2.generator", - "wiremock.org.eclipse.jetty.http2.hpack", - "wiremock.org.eclipse.jetty.http2.parser", - "wiremock.org.eclipse.jetty.http2.server", - "wiremock.org.eclipse.jetty.io", - "wiremock.org.eclipse.jetty.io.jmx", - "wiremock.org.eclipse.jetty.io.ssl", - "wiremock.org.eclipse.jetty.proxy", - "wiremock.org.eclipse.jetty.security", - "wiremock.org.eclipse.jetty.security.authentication", - "wiremock.org.eclipse.jetty.server", - "wiremock.org.eclipse.jetty.server.handler", - "wiremock.org.eclipse.jetty.server.handler.gzip", - "wiremock.org.eclipse.jetty.server.handler.jmx", - "wiremock.org.eclipse.jetty.server.jmx", - "wiremock.org.eclipse.jetty.server.resource", - "wiremock.org.eclipse.jetty.server.session", - "wiremock.org.eclipse.jetty.servlet", - "wiremock.org.eclipse.jetty.servlet.jmx", - "wiremock.org.eclipse.jetty.servlet.listener", - "wiremock.org.eclipse.jetty.servlets", - "wiremock.org.eclipse.jetty.util", - "wiremock.org.eclipse.jetty.util.annotation", - "wiremock.org.eclipse.jetty.util.component", - "wiremock.org.eclipse.jetty.util.compression", - "wiremock.org.eclipse.jetty.util.log", - "wiremock.org.eclipse.jetty.util.preventers", - "wiremock.org.eclipse.jetty.util.resource", - "wiremock.org.eclipse.jetty.util.security", - "wiremock.org.eclipse.jetty.util.ssl", - "wiremock.org.eclipse.jetty.util.statistic", - "wiremock.org.eclipse.jetty.util.thread", - "wiremock.org.eclipse.jetty.util.thread.strategy", - "wiremock.org.eclipse.jetty.webapp", - "wiremock.org.eclipse.jetty.xml", - "wiremock.org.hamcrest", - "wiremock.org.hamcrest.beans", - "wiremock.org.hamcrest.collection", - "wiremock.org.hamcrest.comparator", - "wiremock.org.hamcrest.core", - "wiremock.org.hamcrest.core.deprecated", - "wiremock.org.hamcrest.internal", - "wiremock.org.hamcrest.io", - "wiremock.org.hamcrest.number", - "wiremock.org.hamcrest.object", - "wiremock.org.hamcrest.text", - "wiremock.org.hamcrest.xml", - "wiremock.org.slf4j", - "wiremock.org.slf4j.event", - "wiremock.org.slf4j.helpers", - "wiremock.org.slf4j.spi", - "wiremock.org.xmlunit", - "wiremock.org.xmlunit.builder", - "wiremock.org.xmlunit.builder.javax_jaxb", - "wiremock.org.xmlunit.diff", - "wiremock.org.xmlunit.input", - "wiremock.org.xmlunit.placeholder", - "wiremock.org.xmlunit.transform", - "wiremock.org.xmlunit.util", - "wiremock.org.xmlunit.validation", - "wiremock.org.xmlunit.xpath", - "wiremock.org.yaml.snakeyaml", - "wiremock.org.yaml.snakeyaml.comments", - "wiremock.org.yaml.snakeyaml.composer", - "wiremock.org.yaml.snakeyaml.constructor", - "wiremock.org.yaml.snakeyaml.emitter", - "wiremock.org.yaml.snakeyaml.env", - "wiremock.org.yaml.snakeyaml.error", - "wiremock.org.yaml.snakeyaml.events", - "wiremock.org.yaml.snakeyaml.extensions.compactnotation", - "wiremock.org.yaml.snakeyaml.external.com.google.gdata.util.common.base", - "wiremock.org.yaml.snakeyaml.inspector", - "wiremock.org.yaml.snakeyaml.internal", - "wiremock.org.yaml.snakeyaml.introspector", - "wiremock.org.yaml.snakeyaml.nodes", - "wiremock.org.yaml.snakeyaml.parser", - "wiremock.org.yaml.snakeyaml.reader", - "wiremock.org.yaml.snakeyaml.representer", - "wiremock.org.yaml.snakeyaml.resolver", - "wiremock.org.yaml.snakeyaml.scanner", - "wiremock.org.yaml.snakeyaml.serializer", - "wiremock.org.yaml.snakeyaml.tokens", - "wiremock.org.yaml.snakeyaml.util" - ], - "org.xmlunit:xmlunit-core": [ - "org.xmlunit", - "org.xmlunit.builder", - "org.xmlunit.builder.javax_jaxb", - "org.xmlunit.diff", - "org.xmlunit.input", - "org.xmlunit.transform", - "org.xmlunit.util", - "org.xmlunit.validation", - "org.xmlunit.xpath" - ], - "org.yaml:snakeyaml": [ - "org.yaml.snakeyaml", - "org.yaml.snakeyaml.comments", - "org.yaml.snakeyaml.composer", - "org.yaml.snakeyaml.constructor", - "org.yaml.snakeyaml.emitter", - "org.yaml.snakeyaml.env", - "org.yaml.snakeyaml.error", - "org.yaml.snakeyaml.events", - "org.yaml.snakeyaml.extensions.compactnotation", - "org.yaml.snakeyaml.external.com.google.gdata.util.common.base", - "org.yaml.snakeyaml.inspector", - "org.yaml.snakeyaml.internal", - "org.yaml.snakeyaml.introspector", - "org.yaml.snakeyaml.nodes", - "org.yaml.snakeyaml.parser", - "org.yaml.snakeyaml.reader", - "org.yaml.snakeyaml.representer", - "org.yaml.snakeyaml.resolver", - "org.yaml.snakeyaml.scanner", - "org.yaml.snakeyaml.serializer", - "org.yaml.snakeyaml.tokens", - "org.yaml.snakeyaml.util" - ], - "software.amazon.awssdk:annotations": [ - "software.amazon.awssdk.annotations" - ], - "software.amazon.awssdk:checksums": [ - "software.amazon.awssdk.checksums", - "software.amazon.awssdk.checksums.internal" - ], - "software.amazon.awssdk:checksums-spi": [ - "software.amazon.awssdk.checksums.spi" - ], - "software.amazon.awssdk:endpoints-spi": [ - "software.amazon.awssdk.endpoints" - ], - "software.amazon.awssdk:http-auth-aws": [ - "software.amazon.awssdk.http.auth.aws.crt.internal.io", - "software.amazon.awssdk.http.auth.aws.crt.internal.signer", - "software.amazon.awssdk.http.auth.aws.crt.internal.util", - "software.amazon.awssdk.http.auth.aws.eventstream.internal.io", - "software.amazon.awssdk.http.auth.aws.eventstream.internal.signer", - "software.amazon.awssdk.http.auth.aws.internal.scheme", - "software.amazon.awssdk.http.auth.aws.internal.signer", - "software.amazon.awssdk.http.auth.aws.internal.signer.checksums", - "software.amazon.awssdk.http.auth.aws.internal.signer.chunkedencoding", - "software.amazon.awssdk.http.auth.aws.internal.signer.io", - "software.amazon.awssdk.http.auth.aws.internal.signer.util", - "software.amazon.awssdk.http.auth.aws.scheme", - "software.amazon.awssdk.http.auth.aws.signer" - ], - "software.amazon.awssdk:http-auth-spi": [ - "software.amazon.awssdk.http.auth.spi.internal.scheme", - "software.amazon.awssdk.http.auth.spi.internal.signer", - "software.amazon.awssdk.http.auth.spi.scheme", - "software.amazon.awssdk.http.auth.spi.signer" - ], - "software.amazon.awssdk:http-client-spi": [ - "software.amazon.awssdk.http", - "software.amazon.awssdk.http.async", - "software.amazon.awssdk.internal.http" - ], - "software.amazon.awssdk:identity-spi": [ - "software.amazon.awssdk.identity.spi", - "software.amazon.awssdk.identity.spi.internal" - ], - "software.amazon.awssdk:json-utils": [ - "software.amazon.awssdk.protocols.jsoncore", - "software.amazon.awssdk.protocols.jsoncore.internal" - ], - "software.amazon.awssdk:metrics-spi": [ - "software.amazon.awssdk.metrics", - "software.amazon.awssdk.metrics.internal" - ], - "software.amazon.awssdk:profiles": [ - "software.amazon.awssdk.profiles", - "software.amazon.awssdk.profiles.internal" - ], - "software.amazon.awssdk:regions": [ - "software.amazon.awssdk.regions", - "software.amazon.awssdk.regions.internal", - "software.amazon.awssdk.regions.internal.util", - "software.amazon.awssdk.regions.partitionmetadata", - "software.amazon.awssdk.regions.providers", - "software.amazon.awssdk.regions.regionmetadata", - "software.amazon.awssdk.regions.servicemetadata", - "software.amazon.awssdk.regions.util" - ], - "software.amazon.awssdk:retries": [ - "software.amazon.awssdk.retries", - "software.amazon.awssdk.retries.internal", - "software.amazon.awssdk.retries.internal.circuitbreaker", - "software.amazon.awssdk.retries.internal.ratelimiter" - ], - "software.amazon.awssdk:retries-spi": [ - "software.amazon.awssdk.retries.api", - "software.amazon.awssdk.retries.api.internal", - "software.amazon.awssdk.retries.api.internal.backoff" - ], - "software.amazon.awssdk:sdk-core": [ - "software.amazon.awssdk.core", - "software.amazon.awssdk.core.adapter", - "software.amazon.awssdk.core.async", - "software.amazon.awssdk.core.async.listener", - "software.amazon.awssdk.core.checksums", - "software.amazon.awssdk.core.client.builder", - "software.amazon.awssdk.core.client.config", - "software.amazon.awssdk.core.client.handler", - "software.amazon.awssdk.core.document", - "software.amazon.awssdk.core.document.internal", - "software.amazon.awssdk.core.endpointdiscovery", - "software.amazon.awssdk.core.endpointdiscovery.providers", - "software.amazon.awssdk.core.exception", - "software.amazon.awssdk.core.http", - "software.amazon.awssdk.core.identity", - "software.amazon.awssdk.core.interceptor", - "software.amazon.awssdk.core.interceptor.trait", - "software.amazon.awssdk.core.internal", - "software.amazon.awssdk.core.internal.async", - "software.amazon.awssdk.core.internal.capacity", - "software.amazon.awssdk.core.internal.checksums", - "software.amazon.awssdk.core.internal.chunked", - "software.amazon.awssdk.core.internal.compression", - "software.amazon.awssdk.core.internal.handler", - "software.amazon.awssdk.core.internal.http", - "software.amazon.awssdk.core.internal.http.async", - "software.amazon.awssdk.core.internal.http.loader", - "software.amazon.awssdk.core.internal.http.pipeline", - "software.amazon.awssdk.core.internal.http.pipeline.stages", - "software.amazon.awssdk.core.internal.http.pipeline.stages.utils", - "software.amazon.awssdk.core.internal.http.timers", - "software.amazon.awssdk.core.internal.interceptor", - "software.amazon.awssdk.core.internal.interceptor.trait", - "software.amazon.awssdk.core.internal.io", - "software.amazon.awssdk.core.internal.metrics", - "software.amazon.awssdk.core.internal.pagination.async", - "software.amazon.awssdk.core.internal.retry", - "software.amazon.awssdk.core.internal.signer", - "software.amazon.awssdk.core.internal.sync", - "software.amazon.awssdk.core.internal.transform", - "software.amazon.awssdk.core.internal.useragent", - "software.amazon.awssdk.core.internal.util", - "software.amazon.awssdk.core.internal.waiters", - "software.amazon.awssdk.core.io", - "software.amazon.awssdk.core.metrics", - "software.amazon.awssdk.core.pagination.async", - "software.amazon.awssdk.core.pagination.sync", - "software.amazon.awssdk.core.protocol", - "software.amazon.awssdk.core.retry", - "software.amazon.awssdk.core.retry.backoff", - "software.amazon.awssdk.core.retry.conditions", - "software.amazon.awssdk.core.runtime", - "software.amazon.awssdk.core.runtime.transform", - "software.amazon.awssdk.core.signer", - "software.amazon.awssdk.core.sync", - "software.amazon.awssdk.core.traits", - "software.amazon.awssdk.core.useragent", - "software.amazon.awssdk.core.util", - "software.amazon.awssdk.core.waiters" - ], - "software.amazon.awssdk:third-party-jackson-core": [ - "software.amazon.awssdk.thirdparty.jackson.core", - "software.amazon.awssdk.thirdparty.jackson.core.async", - "software.amazon.awssdk.thirdparty.jackson.core.base", - "software.amazon.awssdk.thirdparty.jackson.core.exc", - "software.amazon.awssdk.thirdparty.jackson.core.filter", - "software.amazon.awssdk.thirdparty.jackson.core.format", - "software.amazon.awssdk.thirdparty.jackson.core.internal.shaded.fdp.v2_19_4", - "software.amazon.awssdk.thirdparty.jackson.core.io", - "software.amazon.awssdk.thirdparty.jackson.core.io.schubfach", - "software.amazon.awssdk.thirdparty.jackson.core.json", - "software.amazon.awssdk.thirdparty.jackson.core.json.async", - "software.amazon.awssdk.thirdparty.jackson.core.sym", - "software.amazon.awssdk.thirdparty.jackson.core.type", - "software.amazon.awssdk.thirdparty.jackson.core.util" - ], - "software.amazon.awssdk:utils": [ - "software.amazon.awssdk.utils", - "software.amazon.awssdk.utils.async", - "software.amazon.awssdk.utils.builder", - "software.amazon.awssdk.utils.cache", - "software.amazon.awssdk.utils.cache.bounded", - "software.amazon.awssdk.utils.cache.lru", - "software.amazon.awssdk.utils.http", - "software.amazon.awssdk.utils.internal", - "software.amazon.awssdk.utils.internal.async", - "software.amazon.awssdk.utils.internal.proxy", - "software.amazon.awssdk.utils.io", - "software.amazon.awssdk.utils.uri", - "software.amazon.awssdk.utils.uri.internal" - ], - "tools.jackson.core:jackson-core": [ - "tools.jackson.core", - "tools.jackson.core.async", - "tools.jackson.core.base", - "tools.jackson.core.exc", - "tools.jackson.core.filter", - "tools.jackson.core.internal.shaded.fdp", - "tools.jackson.core.internal.shaded.fdp.bte", - "tools.jackson.core.internal.shaded.fdp.chr", - "tools.jackson.core.io", - "tools.jackson.core.io.schubfach", - "tools.jackson.core.json", - "tools.jackson.core.json.async", - "tools.jackson.core.sym", - "tools.jackson.core.tree", - "tools.jackson.core.type", - "tools.jackson.core.util" - ], - "tools.jackson.core:jackson-databind": [ - "tools.jackson.databind", - "tools.jackson.databind.annotation", - "tools.jackson.databind.cfg", - "tools.jackson.databind.deser", - "tools.jackson.databind.deser.bean", - "tools.jackson.databind.deser.impl", - "tools.jackson.databind.deser.jackson", - "tools.jackson.databind.deser.jdk", - "tools.jackson.databind.deser.std", - "tools.jackson.databind.exc", - "tools.jackson.databind.ext", - "tools.jackson.databind.ext.beans", - "tools.jackson.databind.ext.javatime", - "tools.jackson.databind.ext.javatime.deser", - "tools.jackson.databind.ext.javatime.deser.key", - "tools.jackson.databind.ext.javatime.ser", - "tools.jackson.databind.ext.javatime.ser.key", - "tools.jackson.databind.ext.javatime.util", - "tools.jackson.databind.ext.jdk8", - "tools.jackson.databind.ext.sql", - "tools.jackson.databind.introspect", - "tools.jackson.databind.json", - "tools.jackson.databind.jsonFormatVisitors", - "tools.jackson.databind.jsontype", - "tools.jackson.databind.jsontype.impl", - "tools.jackson.databind.module", - "tools.jackson.databind.node", - "tools.jackson.databind.ser", - "tools.jackson.databind.ser.bean", - "tools.jackson.databind.ser.impl", - "tools.jackson.databind.ser.jackson", - "tools.jackson.databind.ser.jdk", - "tools.jackson.databind.ser.std", - "tools.jackson.databind.type", - "tools.jackson.databind.util", - "tools.jackson.databind.util.internal" - ], - "tools.jackson.module:jackson-module-blackbird": [ - "tools.jackson.module.blackbird", - "tools.jackson.module.blackbird.deser", - "tools.jackson.module.blackbird.ser", - "tools.jackson.module.blackbird.util" - ] - }, - "repositories": { - "https://maven-central.storage-download.googleapis.com/maven2/": [ - "args4j:args4j", - "args4j:args4j:jar:sources", - "at.yawk.lz4:lz4-java", - "at.yawk.lz4:lz4-java:jar:sources", - "ch.qos.logback:logback-classic", - "ch.qos.logback:logback-classic:jar:sources", - "ch.qos.logback:logback-core", - "ch.qos.logback:logback-core:jar:sources", - "com.bucket4j:bucket4j-core", - "com.bucket4j:bucket4j-core:jar:sources", - "com.bucket4j:bucket4j_jdk17-core", - "com.bucket4j:bucket4j_jdk17-core:jar:sources", - "com.datastax.cassandra:cassandra-driver-core", - "com.datastax.cassandra:cassandra-driver-core:jar:sources", - "com.datastax.oss:native-protocol", - "com.datastax.oss:native-protocol:jar:sources", - "com.fasterxml.jackson.core:jackson-annotations", - "com.fasterxml.jackson.core:jackson-annotations:jar:sources", - "com.fasterxml.jackson.core:jackson-core", - "com.fasterxml.jackson.core:jackson-core:jar:sources", - "com.fasterxml.jackson.core:jackson-databind", - "com.fasterxml.jackson.core:jackson-databind:jar:sources", - "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml", - "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:jar:sources", - "com.fasterxml.jackson.datatype:jackson-datatype-jsr310", - "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:jar:sources", - "com.fasterxml:classmate", - "com.fasterxml:classmate:jar:sources", - "com.github.ben-manes.caffeine:caffeine", - "com.github.ben-manes.caffeine:caffeine:jar:sources", - "com.github.ben-manes.caffeine:guava", - "com.github.ben-manes.caffeine:guava:jar:sources", - "com.github.docker-java:docker-java-api", - "com.github.docker-java:docker-java-api:jar:sources", - "com.github.docker-java:docker-java-transport", - "com.github.docker-java:docker-java-transport-zerodep", - "com.github.docker-java:docker-java-transport-zerodep:jar:sources", - "com.github.docker-java:docker-java-transport:jar:sources", - "com.github.java-json-tools:btf", - "com.github.java-json-tools:btf:jar:sources", - "com.github.java-json-tools:jackson-coreutils", - "com.github.java-json-tools:jackson-coreutils:jar:sources", - "com.github.java-json-tools:json-patch", - "com.github.java-json-tools:json-patch:jar:sources", - "com.github.java-json-tools:msg-simple", - "com.github.java-json-tools:msg-simple:jar:sources", - "com.github.jnr:jffi", - "com.github.jnr:jffi:jar:native", - "com.github.jnr:jffi:jar:sources", - "com.github.jnr:jnr-constants", - "com.github.jnr:jnr-constants:jar:sources", - "com.github.jnr:jnr-ffi", - "com.github.jnr:jnr-ffi:jar:sources", - "com.github.jnr:jnr-posix", - "com.github.jnr:jnr-posix:jar:sources", - "com.github.jnr:jnr-x86asm", - "com.github.jnr:jnr-x86asm:jar:sources", - "com.github.stephenc.jcip:jcip-annotations", - "com.github.stephenc.jcip:jcip-annotations:jar:sources", - "com.google.android:annotations", - "com.google.android:annotations:jar:sources", - "com.google.api.grpc:proto-google-common-protos", - "com.google.api.grpc:proto-google-common-protos:jar:sources", - "com.google.code.findbugs:jsr305", - "com.google.code.findbugs:jsr305:jar:sources", - "com.google.code.gson:gson", - "com.google.code.gson:gson:jar:sources", - "com.google.errorprone:error_prone_annotations", - "com.google.errorprone:error_prone_annotations:jar:sources", - "com.google.guava:failureaccess", - "com.google.guava:failureaccess:jar:sources", - "com.google.guava:guava", - "com.google.guava:guava:jar:sources", - "com.google.guava:listenablefuture", - "com.google.j2objc:j2objc-annotations", - "com.google.j2objc:j2objc-annotations:jar:sources", - "com.google.protobuf:protobuf-java", - "com.google.protobuf:protobuf-java-util", - "com.google.protobuf:protobuf-java-util:jar:sources", - "com.google.protobuf:protobuf-java:jar:sources", - "com.jayway.jsonpath:json-path", - "com.jayway.jsonpath:json-path:jar:sources", - "com.nimbusds:content-type", - "com.nimbusds:content-type:jar:sources", - "com.nimbusds:lang-tag", - "com.nimbusds:lang-tag:jar:sources", - "com.nimbusds:nimbus-jose-jwt", - "com.nimbusds:nimbus-jose-jwt:jar:sources", - "com.nimbusds:oauth2-oidc-sdk", - "com.nimbusds:oauth2-oidc-sdk:jar:sources", - "com.squareup.okhttp3:logging-interceptor", - "com.squareup.okhttp3:logging-interceptor:jar:sources", - "com.squareup.okhttp3:okhttp", - "com.squareup.okhttp3:okhttp-jvm", - "com.squareup.okhttp3:okhttp-jvm:jar:sources", - "com.squareup.okhttp3:okhttp:jar:sources", - "com.squareup.okio:okio", - "com.squareup.okio:okio-jvm", - "com.squareup.okio:okio-jvm:jar:sources", - "com.squareup.okio:okio:jar:sources", - "com.typesafe:config", - "com.typesafe:config:jar:sources", - "com.vaadin.external.google:android-json", - "com.vaadin.external.google:android-json:jar:sources", - "commons-codec:commons-codec", - "commons-codec:commons-codec:jar:sources", - "commons-io:commons-io", - "commons-io:commons-io:jar:sources", - "commons-logging:commons-logging", - "commons-logging:commons-logging:jar:sources", - "io.cloudevents:cloudevents-api", - "io.cloudevents:cloudevents-api:jar:sources", - "io.cloudevents:cloudevents-core", - "io.cloudevents:cloudevents-core:jar:sources", - "io.cloudevents:cloudevents-json-jackson", - "io.cloudevents:cloudevents-json-jackson:jar:sources", - "io.dropwizard.metrics:metrics-core", - "io.dropwizard.metrics:metrics-core:jar:sources", - "io.grpc:grpc-api", - "io.grpc:grpc-api:jar:sources", - "io.grpc:grpc-context", - "io.grpc:grpc-context:jar:sources", - "io.grpc:grpc-core", - "io.grpc:grpc-core:jar:sources", - "io.grpc:grpc-inprocess", - "io.grpc:grpc-inprocess:jar:sources", - "io.grpc:grpc-netty-shaded", - "io.grpc:grpc-netty-shaded:jar:sources", - "io.grpc:grpc-protobuf", - "io.grpc:grpc-protobuf-lite", - "io.grpc:grpc-protobuf-lite:jar:sources", - "io.grpc:grpc-protobuf:jar:sources", - "io.grpc:grpc-services", - "io.grpc:grpc-services:jar:sources", - "io.grpc:grpc-stub", - "io.grpc:grpc-stub:jar:sources", - "io.grpc:grpc-util", - "io.grpc:grpc-util:jar:sources", - "io.gsonfire:gson-fire", - "io.gsonfire:gson-fire:jar:sources", - "io.kubernetes:client-java", - "io.kubernetes:client-java-api", - "io.kubernetes:client-java-api-fluent", - "io.kubernetes:client-java-api-fluent:jar:sources", - "io.kubernetes:client-java-api:jar:sources", - "io.kubernetes:client-java-extended", - "io.kubernetes:client-java-extended:jar:sources", - "io.kubernetes:client-java-proto", - "io.kubernetes:client-java-proto:jar:sources", - "io.kubernetes:client-java:jar:sources", - "io.micrometer:context-propagation", - "io.micrometer:context-propagation:jar:sources", - "io.micrometer:micrometer-commons", - "io.micrometer:micrometer-commons:jar:sources", - "io.micrometer:micrometer-core", - "io.micrometer:micrometer-core:jar:sources", - "io.micrometer:micrometer-jakarta9", - "io.micrometer:micrometer-jakarta9:jar:sources", - "io.micrometer:micrometer-observation", - "io.micrometer:micrometer-observation-test", - "io.micrometer:micrometer-observation-test:jar:sources", - "io.micrometer:micrometer-observation:jar:sources", - "io.micrometer:micrometer-registry-prometheus", - "io.micrometer:micrometer-registry-prometheus:jar:sources", - "io.micrometer:micrometer-tracing", - "io.micrometer:micrometer-tracing-bridge-otel", - "io.micrometer:micrometer-tracing-bridge-otel:jar:sources", - "io.micrometer:micrometer-tracing:jar:sources", - "io.nats:jnats", - "io.nats:jnats:jar:sources", - "io.netty:netty-buffer", - "io.netty:netty-buffer:jar:sources", - "io.netty:netty-codec-base", - "io.netty:netty-codec-base:jar:sources", - "io.netty:netty-codec-classes-quic", - "io.netty:netty-codec-classes-quic:jar:sources", - "io.netty:netty-codec-compression", - "io.netty:netty-codec-compression:jar:sources", - "io.netty:netty-codec-dns", - "io.netty:netty-codec-dns:jar:sources", - "io.netty:netty-codec-http", - "io.netty:netty-codec-http2", - "io.netty:netty-codec-http2:jar:sources", - "io.netty:netty-codec-http3", - "io.netty:netty-codec-http3:jar:sources", - "io.netty:netty-codec-http:jar:sources", - "io.netty:netty-codec-native-quic:jar:linux-aarch_64", - "io.netty:netty-codec-native-quic:jar:linux-x86_64", - "io.netty:netty-codec-native-quic:jar:osx-aarch_64", - "io.netty:netty-codec-native-quic:jar:osx-x86_64", - "io.netty:netty-codec-native-quic:jar:sources", - "io.netty:netty-codec-native-quic:jar:windows-x86_64", - "io.netty:netty-codec-socks", - "io.netty:netty-codec-socks:jar:sources", - "io.netty:netty-common", - "io.netty:netty-common:jar:sources", - "io.netty:netty-handler", - "io.netty:netty-handler-proxy", - "io.netty:netty-handler-proxy:jar:sources", - "io.netty:netty-handler:jar:sources", - "io.netty:netty-resolver", - "io.netty:netty-resolver-dns", - "io.netty:netty-resolver-dns-classes-macos", - "io.netty:netty-resolver-dns-classes-macos:jar:sources", - "io.netty:netty-resolver-dns-native-macos:jar:osx-x86_64", - "io.netty:netty-resolver-dns-native-macos:jar:sources", - "io.netty:netty-resolver-dns:jar:sources", - "io.netty:netty-resolver:jar:sources", - "io.netty:netty-transport", - "io.netty:netty-transport-classes-epoll", - "io.netty:netty-transport-classes-epoll:jar:sources", - "io.netty:netty-transport-native-epoll:jar:linux-x86_64", - "io.netty:netty-transport-native-epoll:jar:sources", - "io.netty:netty-transport-native-unix-common", - "io.netty:netty-transport-native-unix-common:jar:sources", - "io.netty:netty-transport:jar:sources", - "io.opentelemetry.semconv:opentelemetry-semconv", - "io.opentelemetry.semconv:opentelemetry-semconv:jar:sources", - "io.opentelemetry:opentelemetry-api", - "io.opentelemetry:opentelemetry-api:jar:sources", - "io.opentelemetry:opentelemetry-common", - "io.opentelemetry:opentelemetry-common:jar:sources", - "io.opentelemetry:opentelemetry-context", - "io.opentelemetry:opentelemetry-context:jar:sources", - "io.opentelemetry:opentelemetry-exporter-common", - "io.opentelemetry:opentelemetry-exporter-common:jar:sources", - "io.opentelemetry:opentelemetry-exporter-otlp", - "io.opentelemetry:opentelemetry-exporter-otlp-common", - "io.opentelemetry:opentelemetry-exporter-otlp-common:jar:sources", - "io.opentelemetry:opentelemetry-exporter-otlp:jar:sources", - "io.opentelemetry:opentelemetry-exporter-sender-okhttp", - "io.opentelemetry:opentelemetry-exporter-sender-okhttp:jar:sources", - "io.opentelemetry:opentelemetry-extension-trace-propagators", - "io.opentelemetry:opentelemetry-extension-trace-propagators:jar:sources", - "io.opentelemetry:opentelemetry-sdk", - "io.opentelemetry:opentelemetry-sdk-common", - "io.opentelemetry:opentelemetry-sdk-common:jar:sources", - "io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi", - "io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi:jar:sources", - "io.opentelemetry:opentelemetry-sdk-logs", - "io.opentelemetry:opentelemetry-sdk-logs:jar:sources", - "io.opentelemetry:opentelemetry-sdk-metrics", - "io.opentelemetry:opentelemetry-sdk-metrics:jar:sources", - "io.opentelemetry:opentelemetry-sdk-testing", - "io.opentelemetry:opentelemetry-sdk-testing:jar:sources", - "io.opentelemetry:opentelemetry-sdk-trace", - "io.opentelemetry:opentelemetry-sdk-trace:jar:sources", - "io.opentelemetry:opentelemetry-sdk:jar:sources", - "io.perfmark:perfmark-api", - "io.perfmark:perfmark-api:jar:sources", - "io.projectreactor.netty:reactor-netty-core", - "io.projectreactor.netty:reactor-netty-core:jar:sources", - "io.projectreactor.netty:reactor-netty-http", - "io.projectreactor.netty:reactor-netty-http:jar:sources", - "io.projectreactor:reactor-core", - "io.projectreactor:reactor-core:jar:sources", - "io.projectreactor:reactor-test", - "io.projectreactor:reactor-test:jar:sources", - "io.prometheus:prometheus-metrics-config", - "io.prometheus:prometheus-metrics-config:jar:sources", - "io.prometheus:prometheus-metrics-core", - "io.prometheus:prometheus-metrics-core:jar:sources", - "io.prometheus:prometheus-metrics-exposition-formats", - "io.prometheus:prometheus-metrics-exposition-formats:jar:sources", - "io.prometheus:prometheus-metrics-exposition-textformats", - "io.prometheus:prometheus-metrics-exposition-textformats:jar:sources", - "io.prometheus:prometheus-metrics-model", - "io.prometheus:prometheus-metrics-model:jar:sources", - "io.prometheus:prometheus-metrics-tracer-common", - "io.prometheus:prometheus-metrics-tracer-common:jar:sources", - "io.swagger.core.v3:swagger-annotations-jakarta", - "io.swagger.core.v3:swagger-annotations-jakarta:jar:sources", - "io.swagger.core.v3:swagger-core-jakarta", - "io.swagger.core.v3:swagger-core-jakarta:jar:sources", - "io.swagger.core.v3:swagger-models-jakarta", - "io.swagger.core.v3:swagger-models-jakarta:jar:sources", - "io.swagger:swagger-annotations", - "io.swagger:swagger-annotations:jar:sources", - "jakarta.activation:jakarta.activation-api", - "jakarta.activation:jakarta.activation-api:jar:sources", - "jakarta.annotation:jakarta.annotation-api", - "jakarta.annotation:jakarta.annotation-api:jar:sources", - "jakarta.servlet:jakarta.servlet-api", - "jakarta.servlet:jakarta.servlet-api:jar:sources", - "jakarta.validation:jakarta.validation-api", - "jakarta.validation:jakarta.validation-api:jar:sources", - "jakarta.xml.bind:jakarta.xml.bind-api", - "jakarta.xml.bind:jakarta.xml.bind-api:jar:sources", - "javax.annotation:javax.annotation-api", - "javax.annotation:javax.annotation-api:jar:sources", - "net.bytebuddy:byte-buddy", - "net.bytebuddy:byte-buddy-agent", - "net.bytebuddy:byte-buddy-agent:jar:sources", - "net.bytebuddy:byte-buddy:jar:sources", - "net.devh:grpc-common-spring-boot", - "net.devh:grpc-common-spring-boot:jar:sources", - "net.devh:grpc-server-spring-boot-starter", - "net.devh:grpc-server-spring-boot-starter:jar:sources", - "net.java.dev.jna:jna", - "net.java.dev.jna:jna:jar:sources", - "net.javacrumbs.shedlock:shedlock-core", - "net.javacrumbs.shedlock:shedlock-core:jar:sources", - "net.javacrumbs.shedlock:shedlock-provider-cassandra", - "net.javacrumbs.shedlock:shedlock-provider-cassandra:jar:sources", - "net.javacrumbs.shedlock:shedlock-spring", - "net.javacrumbs.shedlock:shedlock-spring:jar:sources", - "net.minidev:accessors-smart", - "net.minidev:accessors-smart:jar:sources", - "net.minidev:json-smart", - "net.minidev:json-smart:jar:sources", - "org.apache.cassandra:java-driver-core", - "org.apache.cassandra:java-driver-core:jar:sources", - "org.apache.cassandra:java-driver-guava-shaded", - "org.apache.cassandra:java-driver-guava-shaded:jar:sources", - "org.apache.cassandra:java-driver-metrics-micrometer", - "org.apache.cassandra:java-driver-metrics-micrometer:jar:sources", - "org.apache.cassandra:java-driver-query-builder", - "org.apache.cassandra:java-driver-query-builder:jar:sources", - "org.apache.commons:commons-collections4", - "org.apache.commons:commons-collections4:jar:sources", - "org.apache.commons:commons-compress", - "org.apache.commons:commons-compress:jar:sources", - "org.apache.commons:commons-lang3", - "org.apache.commons:commons-lang3:jar:sources", - "org.apache.logging.log4j:log4j-api", - "org.apache.logging.log4j:log4j-api:jar:sources", - "org.apache.logging.log4j:log4j-to-slf4j", - "org.apache.logging.log4j:log4j-to-slf4j:jar:sources", - "org.apache.tomcat.embed:tomcat-embed-core", - "org.apache.tomcat.embed:tomcat-embed-core:jar:sources", - "org.apache.tomcat.embed:tomcat-embed-el", - "org.apache.tomcat.embed:tomcat-embed-el:jar:sources", - "org.apache.tomcat.embed:tomcat-embed-websocket", - "org.apache.tomcat.embed:tomcat-embed-websocket:jar:sources", - "org.apiguardian:apiguardian-api", - "org.apiguardian:apiguardian-api:jar:sources", - "org.aspectj:aspectjweaver", - "org.aspectj:aspectjweaver:jar:sources", - "org.assertj:assertj-core", - "org.assertj:assertj-core:jar:sources", - "org.awaitility:awaitility", - "org.awaitility:awaitility:jar:sources", - "org.bitbucket.b_c:jose4j", - "org.bitbucket.b_c:jose4j:jar:sources", - "org.bouncycastle:bcpkix-jdk18on", - "org.bouncycastle:bcpkix-jdk18on:jar:sources", - "org.bouncycastle:bcprov-jdk18on", - "org.bouncycastle:bcprov-jdk18on:jar:sources", - "org.bouncycastle:bcprov-lts8on", - "org.bouncycastle:bcprov-lts8on:jar:sources", - "org.bouncycastle:bcutil-jdk18on", - "org.bouncycastle:bcutil-jdk18on:jar:sources", - "org.codehaus.mojo:animal-sniffer-annotations", - "org.codehaus.mojo:animal-sniffer-annotations:jar:sources", - "org.hamcrest:hamcrest", - "org.hamcrest:hamcrest:jar:sources", - "org.hdrhistogram:HdrHistogram", - "org.hdrhistogram:HdrHistogram:jar:sources", - "org.hibernate.validator:hibernate-validator", - "org.hibernate.validator:hibernate-validator:jar:sources", - "org.jacoco:org.jacoco.agent:jar:runtime", - "org.jacoco:org.jacoco.agent:jar:sources", - "org.jacoco:org.jacoco.cli", - "org.jacoco:org.jacoco.cli:jar:sources", - "org.jacoco:org.jacoco.core", - "org.jacoco:org.jacoco.core:jar:sources", - "org.jacoco:org.jacoco.report", - "org.jacoco:org.jacoco.report:jar:sources", - "org.jboss.logging:jboss-logging", - "org.jboss.logging:jboss-logging:jar:sources", - "org.jetbrains.kotlin:kotlin-stdlib", - "org.jetbrains.kotlin:kotlin-stdlib-jdk7", - "org.jetbrains.kotlin:kotlin-stdlib-jdk7:jar:sources", - "org.jetbrains.kotlin:kotlin-stdlib-jdk8", - "org.jetbrains.kotlin:kotlin-stdlib-jdk8:jar:sources", - "org.jetbrains.kotlin:kotlin-stdlib:jar:sources", - "org.jetbrains:annotations", - "org.jetbrains:annotations:jar:sources", - "org.jspecify:jspecify", - "org.jspecify:jspecify:jar:sources", - "org.junit.jupiter:junit-jupiter", - "org.junit.jupiter:junit-jupiter-api", - "org.junit.jupiter:junit-jupiter-api:jar:sources", - "org.junit.jupiter:junit-jupiter-engine", - "org.junit.jupiter:junit-jupiter-engine:jar:sources", - "org.junit.jupiter:junit-jupiter-params", - "org.junit.jupiter:junit-jupiter-params:jar:sources", - "org.junit.jupiter:junit-jupiter:jar:sources", - "org.junit.platform:junit-platform-commons", - "org.junit.platform:junit-platform-commons:jar:sources", - "org.junit.platform:junit-platform-console-standalone", - "org.junit.platform:junit-platform-console-standalone:jar:sources", - "org.junit.platform:junit-platform-engine", - "org.junit.platform:junit-platform-engine:jar:sources", - "org.latencyutils:LatencyUtils", - "org.latencyutils:LatencyUtils:jar:sources", - "org.mockito:mockito-core", - "org.mockito:mockito-core:jar:sources", - "org.mockito:mockito-junit-jupiter", - "org.mockito:mockito-junit-jupiter:jar:sources", - "org.objenesis:objenesis", - "org.objenesis:objenesis:jar:sources", - "org.opentest4j:opentest4j", - "org.opentest4j:opentest4j:jar:sources", - "org.ow2.asm:asm", - "org.ow2.asm:asm-analysis", - "org.ow2.asm:asm-analysis:jar:sources", - "org.ow2.asm:asm-commons", - "org.ow2.asm:asm-commons:jar:sources", - "org.ow2.asm:asm-tree", - "org.ow2.asm:asm-tree:jar:sources", - "org.ow2.asm:asm-util", - "org.ow2.asm:asm-util:jar:sources", - "org.ow2.asm:asm:jar:sources", - "org.projectlombok:lombok", - "org.projectlombok:lombok:jar:sources", - "org.reactivestreams:reactive-streams", - "org.reactivestreams:reactive-streams:jar:sources", - "org.rnorth.duct-tape:duct-tape", - "org.rnorth.duct-tape:duct-tape:jar:sources", - "org.skyscreamer:jsonassert", - "org.skyscreamer:jsonassert:jar:sources", - "org.slf4j:jul-to-slf4j", - "org.slf4j:jul-to-slf4j:jar:sources", - "org.slf4j:slf4j-api", - "org.slf4j:slf4j-api:jar:sources", - "org.springdoc:springdoc-openapi-starter-common", - "org.springdoc:springdoc-openapi-starter-common:jar:sources", - "org.springdoc:springdoc-openapi-starter-webflux-api", - "org.springdoc:springdoc-openapi-starter-webflux-api:jar:sources", - "org.springdoc:springdoc-openapi-starter-webmvc-api", - "org.springdoc:springdoc-openapi-starter-webmvc-api:jar:sources", - "org.springframework.boot:spring-boot", - "org.springframework.boot:spring-boot-actuator", - "org.springframework.boot:spring-boot-actuator-autoconfigure", - "org.springframework.boot:spring-boot-actuator-autoconfigure:jar:sources", - "org.springframework.boot:spring-boot-actuator:jar:sources", - "org.springframework.boot:spring-boot-autoconfigure", - "org.springframework.boot:spring-boot-autoconfigure:jar:sources", - "org.springframework.boot:spring-boot-cassandra", - "org.springframework.boot:spring-boot-cassandra:jar:sources", - "org.springframework.boot:spring-boot-data-cassandra", - "org.springframework.boot:spring-boot-data-cassandra-test", - "org.springframework.boot:spring-boot-data-cassandra-test:jar:sources", - "org.springframework.boot:spring-boot-data-cassandra:jar:sources", - "org.springframework.boot:spring-boot-data-commons", - "org.springframework.boot:spring-boot-data-commons:jar:sources", - "org.springframework.boot:spring-boot-health", - "org.springframework.boot:spring-boot-health:jar:sources", - "org.springframework.boot:spring-boot-http-client", - "org.springframework.boot:spring-boot-http-client:jar:sources", - "org.springframework.boot:spring-boot-http-codec", - "org.springframework.boot:spring-boot-http-codec:jar:sources", - "org.springframework.boot:spring-boot-http-converter", - "org.springframework.boot:spring-boot-http-converter:jar:sources", - "org.springframework.boot:spring-boot-jackson", - "org.springframework.boot:spring-boot-jackson:jar:sources", - "org.springframework.boot:spring-boot-loader", - "org.springframework.boot:spring-boot-loader:jar:sources", - "org.springframework.boot:spring-boot-micrometer-metrics", - "org.springframework.boot:spring-boot-micrometer-metrics-test", - "org.springframework.boot:spring-boot-micrometer-metrics-test:jar:sources", - "org.springframework.boot:spring-boot-micrometer-metrics:jar:sources", - "org.springframework.boot:spring-boot-micrometer-observation", - "org.springframework.boot:spring-boot-micrometer-observation:jar:sources", - "org.springframework.boot:spring-boot-micrometer-tracing", - "org.springframework.boot:spring-boot-micrometer-tracing-opentelemetry", - "org.springframework.boot:spring-boot-micrometer-tracing-opentelemetry:jar:sources", - "org.springframework.boot:spring-boot-micrometer-tracing:jar:sources", - "org.springframework.boot:spring-boot-netty", - "org.springframework.boot:spring-boot-netty:jar:sources", - "org.springframework.boot:spring-boot-opentelemetry", - "org.springframework.boot:spring-boot-opentelemetry:jar:sources", - "org.springframework.boot:spring-boot-persistence", - "org.springframework.boot:spring-boot-persistence:jar:sources", - "org.springframework.boot:spring-boot-reactor", - "org.springframework.boot:spring-boot-reactor-netty", - "org.springframework.boot:spring-boot-reactor-netty:jar:sources", - "org.springframework.boot:spring-boot-reactor:jar:sources", - "org.springframework.boot:spring-boot-restclient", - "org.springframework.boot:spring-boot-restclient:jar:sources", - "org.springframework.boot:spring-boot-resttestclient", - "org.springframework.boot:spring-boot-resttestclient:jar:sources", - "org.springframework.boot:spring-boot-security", - "org.springframework.boot:spring-boot-security-oauth2-client", - "org.springframework.boot:spring-boot-security-oauth2-client:jar:sources", - "org.springframework.boot:spring-boot-security-oauth2-resource-server", - "org.springframework.boot:spring-boot-security-oauth2-resource-server:jar:sources", - "org.springframework.boot:spring-boot-security-test", - "org.springframework.boot:spring-boot-security-test:jar:sources", - "org.springframework.boot:spring-boot-security:jar:sources", - "org.springframework.boot:spring-boot-servlet", - "org.springframework.boot:spring-boot-servlet:jar:sources", - "org.springframework.boot:spring-boot-starter", - "org.springframework.boot:spring-boot-starter-actuator", - "org.springframework.boot:spring-boot-starter-actuator-test", - "org.springframework.boot:spring-boot-starter-actuator-test:jar:sources", - "org.springframework.boot:spring-boot-starter-actuator:jar:sources", - "org.springframework.boot:spring-boot-starter-aspectj", - "org.springframework.boot:spring-boot-starter-aspectj:jar:sources", - "org.springframework.boot:spring-boot-starter-data-cassandra", - "org.springframework.boot:spring-boot-starter-data-cassandra-test", - "org.springframework.boot:spring-boot-starter-data-cassandra-test:jar:sources", - "org.springframework.boot:spring-boot-starter-data-cassandra:jar:sources", - "org.springframework.boot:spring-boot-starter-jackson", - "org.springframework.boot:spring-boot-starter-jackson-test", - "org.springframework.boot:spring-boot-starter-jackson-test:jar:sources", - "org.springframework.boot:spring-boot-starter-jackson:jar:sources", - "org.springframework.boot:spring-boot-starter-logging", - "org.springframework.boot:spring-boot-starter-logging:jar:sources", - "org.springframework.boot:spring-boot-starter-micrometer-metrics", - "org.springframework.boot:spring-boot-starter-micrometer-metrics-test", - "org.springframework.boot:spring-boot-starter-micrometer-metrics-test:jar:sources", - "org.springframework.boot:spring-boot-starter-micrometer-metrics:jar:sources", - "org.springframework.boot:spring-boot-starter-reactor-netty", - "org.springframework.boot:spring-boot-starter-reactor-netty:jar:sources", - "org.springframework.boot:spring-boot-starter-security", - "org.springframework.boot:spring-boot-starter-security-oauth2-client", - "org.springframework.boot:spring-boot-starter-security-oauth2-client:jar:sources", - "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server", - "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server-test", - "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server-test:jar:sources", - "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server:jar:sources", - "org.springframework.boot:spring-boot-starter-security-test", - "org.springframework.boot:spring-boot-starter-security-test:jar:sources", - "org.springframework.boot:spring-boot-starter-security:jar:sources", - "org.springframework.boot:spring-boot-starter-test", - "org.springframework.boot:spring-boot-starter-test:jar:sources", - "org.springframework.boot:spring-boot-starter-tomcat", - "org.springframework.boot:spring-boot-starter-tomcat-runtime", - "org.springframework.boot:spring-boot-starter-tomcat-runtime:jar:sources", - "org.springframework.boot:spring-boot-starter-tomcat:jar:sources", - "org.springframework.boot:spring-boot-starter-validation", - "org.springframework.boot:spring-boot-starter-validation:jar:sources", - "org.springframework.boot:spring-boot-starter-webflux", - "org.springframework.boot:spring-boot-starter-webflux-test", - "org.springframework.boot:spring-boot-starter-webflux-test:jar:sources", - "org.springframework.boot:spring-boot-starter-webflux:jar:sources", - "org.springframework.boot:spring-boot-starter-webmvc", - "org.springframework.boot:spring-boot-starter-webmvc-test", - "org.springframework.boot:spring-boot-starter-webmvc-test:jar:sources", - "org.springframework.boot:spring-boot-starter-webmvc:jar:sources", - "org.springframework.boot:spring-boot-starter:jar:sources", - "org.springframework.boot:spring-boot-test", - "org.springframework.boot:spring-boot-test-autoconfigure", - "org.springframework.boot:spring-boot-test-autoconfigure:jar:sources", - "org.springframework.boot:spring-boot-test:jar:sources", - "org.springframework.boot:spring-boot-tomcat", - "org.springframework.boot:spring-boot-tomcat:jar:sources", - "org.springframework.boot:spring-boot-validation", - "org.springframework.boot:spring-boot-validation:jar:sources", - "org.springframework.boot:spring-boot-web-server", - "org.springframework.boot:spring-boot-web-server:jar:sources", - "org.springframework.boot:spring-boot-webclient", - "org.springframework.boot:spring-boot-webclient:jar:sources", - "org.springframework.boot:spring-boot-webflux", - "org.springframework.boot:spring-boot-webflux-test", - "org.springframework.boot:spring-boot-webflux-test:jar:sources", - "org.springframework.boot:spring-boot-webflux:jar:sources", - "org.springframework.boot:spring-boot-webmvc", - "org.springframework.boot:spring-boot-webmvc-test", - "org.springframework.boot:spring-boot-webmvc-test:jar:sources", - "org.springframework.boot:spring-boot-webmvc:jar:sources", - "org.springframework.boot:spring-boot-webtestclient", - "org.springframework.boot:spring-boot-webtestclient:jar:sources", - "org.springframework.boot:spring-boot:jar:sources", - "org.springframework.cloud:spring-cloud-commons", - "org.springframework.cloud:spring-cloud-commons:jar:sources", - "org.springframework.cloud:spring-cloud-context", - "org.springframework.cloud:spring-cloud-context:jar:sources", - "org.springframework.cloud:spring-cloud-kubernetes-client-autoconfig", - "org.springframework.cloud:spring-cloud-kubernetes-client-autoconfig:jar:sources", - "org.springframework.cloud:spring-cloud-kubernetes-client-config", - "org.springframework.cloud:spring-cloud-kubernetes-client-config:jar:sources", - "org.springframework.cloud:spring-cloud-kubernetes-commons", - "org.springframework.cloud:spring-cloud-kubernetes-commons:jar:sources", - "org.springframework.cloud:spring-cloud-starter", - "org.springframework.cloud:spring-cloud-starter-bootstrap", - "org.springframework.cloud:spring-cloud-starter-bootstrap:jar:sources", - "org.springframework.cloud:spring-cloud-starter-kubernetes-client-config", - "org.springframework.data:spring-data-cassandra", - "org.springframework.data:spring-data-cassandra:jar:sources", - "org.springframework.data:spring-data-commons", - "org.springframework.data:spring-data-commons:jar:sources", - "org.springframework.retry:spring-retry", - "org.springframework.retry:spring-retry:jar:sources", - "org.springframework.security:spring-security-config", - "org.springframework.security:spring-security-config:jar:sources", - "org.springframework.security:spring-security-core", - "org.springframework.security:spring-security-core:jar:sources", - "org.springframework.security:spring-security-crypto", - "org.springframework.security:spring-security-crypto:jar:sources", - "org.springframework.security:spring-security-oauth2-client", - "org.springframework.security:spring-security-oauth2-client:jar:sources", - "org.springframework.security:spring-security-oauth2-core", - "org.springframework.security:spring-security-oauth2-core:jar:sources", - "org.springframework.security:spring-security-oauth2-jose", - "org.springframework.security:spring-security-oauth2-jose:jar:sources", - "org.springframework.security:spring-security-oauth2-resource-server", - "org.springframework.security:spring-security-oauth2-resource-server:jar:sources", - "org.springframework.security:spring-security-test", - "org.springframework.security:spring-security-test:jar:sources", - "org.springframework.security:spring-security-web", - "org.springframework.security:spring-security-web:jar:sources", - "org.springframework:spring-aop", - "org.springframework:spring-aop:jar:sources", - "org.springframework:spring-beans", - "org.springframework:spring-beans:jar:sources", - "org.springframework:spring-context", - "org.springframework:spring-context-support", - "org.springframework:spring-context-support:jar:sources", - "org.springframework:spring-context:jar:sources", - "org.springframework:spring-core", - "org.springframework:spring-core:jar:sources", - "org.springframework:spring-expression", - "org.springframework:spring-expression:jar:sources", - "org.springframework:spring-test", - "org.springframework:spring-test:jar:sources", - "org.springframework:spring-tx", - "org.springframework:spring-tx:jar:sources", - "org.springframework:spring-web", - "org.springframework:spring-web:jar:sources", - "org.springframework:spring-webflux", - "org.springframework:spring-webflux:jar:sources", - "org.springframework:spring-webmvc", - "org.springframework:spring-webmvc:jar:sources", - "org.testcontainers:testcontainers", - "org.testcontainers:testcontainers-cassandra", - "org.testcontainers:testcontainers-cassandra:jar:sources", - "org.testcontainers:testcontainers-database-commons", - "org.testcontainers:testcontainers-database-commons:jar:sources", - "org.testcontainers:testcontainers-junit-jupiter", - "org.testcontainers:testcontainers-junit-jupiter:jar:sources", - "org.testcontainers:testcontainers-localstack", - "org.testcontainers:testcontainers-localstack:jar:sources", - "org.testcontainers:testcontainers:jar:sources", - "org.wiremock:wiremock-standalone", - "org.wiremock:wiremock-standalone:jar:sources", - "org.xmlunit:xmlunit-core", - "org.xmlunit:xmlunit-core:jar:sources", - "org.yaml:snakeyaml", - "org.yaml:snakeyaml:jar:sources", - "software.amazon.awssdk:annotations", - "software.amazon.awssdk:annotations:jar:sources", - "software.amazon.awssdk:checksums", - "software.amazon.awssdk:checksums-spi", - "software.amazon.awssdk:checksums-spi:jar:sources", - "software.amazon.awssdk:checksums:jar:sources", - "software.amazon.awssdk:endpoints-spi", - "software.amazon.awssdk:endpoints-spi:jar:sources", - "software.amazon.awssdk:http-auth-aws", - "software.amazon.awssdk:http-auth-aws:jar:sources", - "software.amazon.awssdk:http-auth-spi", - "software.amazon.awssdk:http-auth-spi:jar:sources", - "software.amazon.awssdk:http-client-spi", - "software.amazon.awssdk:http-client-spi:jar:sources", - "software.amazon.awssdk:identity-spi", - "software.amazon.awssdk:identity-spi:jar:sources", - "software.amazon.awssdk:json-utils", - "software.amazon.awssdk:json-utils:jar:sources", - "software.amazon.awssdk:metrics-spi", - "software.amazon.awssdk:metrics-spi:jar:sources", - "software.amazon.awssdk:profiles", - "software.amazon.awssdk:profiles:jar:sources", - "software.amazon.awssdk:regions", - "software.amazon.awssdk:regions:jar:sources", - "software.amazon.awssdk:retries", - "software.amazon.awssdk:retries-spi", - "software.amazon.awssdk:retries-spi:jar:sources", - "software.amazon.awssdk:retries:jar:sources", - "software.amazon.awssdk:sdk-core", - "software.amazon.awssdk:sdk-core:jar:sources", - "software.amazon.awssdk:third-party-jackson-core", - "software.amazon.awssdk:third-party-jackson-core:jar:sources", - "software.amazon.awssdk:utils", - "software.amazon.awssdk:utils:jar:sources", - "tools.jackson.core:jackson-core", - "tools.jackson.core:jackson-core:jar:sources", - "tools.jackson.core:jackson-databind", - "tools.jackson.core:jackson-databind:jar:sources", - "tools.jackson.module:jackson-module-blackbird", - "tools.jackson.module:jackson-module-blackbird:jar:sources" - ], - "https://repo.maven.apache.org/maven2/": [ - "args4j:args4j", - "args4j:args4j:jar:sources", - "at.yawk.lz4:lz4-java", - "at.yawk.lz4:lz4-java:jar:sources", - "ch.qos.logback:logback-classic", - "ch.qos.logback:logback-classic:jar:sources", - "ch.qos.logback:logback-core", - "ch.qos.logback:logback-core:jar:sources", - "com.bucket4j:bucket4j-core", - "com.bucket4j:bucket4j-core:jar:sources", - "com.bucket4j:bucket4j_jdk17-core", - "com.bucket4j:bucket4j_jdk17-core:jar:sources", - "com.datastax.cassandra:cassandra-driver-core", - "com.datastax.cassandra:cassandra-driver-core:jar:sources", - "com.datastax.oss:native-protocol", - "com.datastax.oss:native-protocol:jar:sources", - "com.fasterxml.jackson.core:jackson-annotations", - "com.fasterxml.jackson.core:jackson-annotations:jar:sources", - "com.fasterxml.jackson.core:jackson-core", - "com.fasterxml.jackson.core:jackson-core:jar:sources", - "com.fasterxml.jackson.core:jackson-databind", - "com.fasterxml.jackson.core:jackson-databind:jar:sources", - "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml", - "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:jar:sources", - "com.fasterxml.jackson.datatype:jackson-datatype-jsr310", - "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:jar:sources", - "com.fasterxml:classmate", - "com.fasterxml:classmate:jar:sources", - "com.github.ben-manes.caffeine:caffeine", - "com.github.ben-manes.caffeine:caffeine:jar:sources", - "com.github.ben-manes.caffeine:guava", - "com.github.ben-manes.caffeine:guava:jar:sources", - "com.github.docker-java:docker-java-api", - "com.github.docker-java:docker-java-api:jar:sources", - "com.github.docker-java:docker-java-transport", - "com.github.docker-java:docker-java-transport-zerodep", - "com.github.docker-java:docker-java-transport-zerodep:jar:sources", - "com.github.docker-java:docker-java-transport:jar:sources", - "com.github.java-json-tools:btf", - "com.github.java-json-tools:btf:jar:sources", - "com.github.java-json-tools:jackson-coreutils", - "com.github.java-json-tools:jackson-coreutils:jar:sources", - "com.github.java-json-tools:json-patch", - "com.github.java-json-tools:json-patch:jar:sources", - "com.github.java-json-tools:msg-simple", - "com.github.java-json-tools:msg-simple:jar:sources", - "com.github.jnr:jffi", - "com.github.jnr:jffi:jar:native", - "com.github.jnr:jffi:jar:sources", - "com.github.jnr:jnr-constants", - "com.github.jnr:jnr-constants:jar:sources", - "com.github.jnr:jnr-ffi", - "com.github.jnr:jnr-ffi:jar:sources", - "com.github.jnr:jnr-posix", - "com.github.jnr:jnr-posix:jar:sources", - "com.github.jnr:jnr-x86asm", - "com.github.jnr:jnr-x86asm:jar:sources", - "com.github.stephenc.jcip:jcip-annotations", - "com.github.stephenc.jcip:jcip-annotations:jar:sources", - "com.google.android:annotations", - "com.google.android:annotations:jar:sources", - "com.google.api.grpc:proto-google-common-protos", - "com.google.api.grpc:proto-google-common-protos:jar:sources", - "com.google.code.findbugs:jsr305", - "com.google.code.findbugs:jsr305:jar:sources", - "com.google.code.gson:gson", - "com.google.code.gson:gson:jar:sources", - "com.google.errorprone:error_prone_annotations", - "com.google.errorprone:error_prone_annotations:jar:sources", - "com.google.guava:failureaccess", - "com.google.guava:failureaccess:jar:sources", - "com.google.guava:guava", - "com.google.guava:guava:jar:sources", - "com.google.guava:listenablefuture", - "com.google.j2objc:j2objc-annotations", - "com.google.j2objc:j2objc-annotations:jar:sources", - "com.google.protobuf:protobuf-java", - "com.google.protobuf:protobuf-java-util", - "com.google.protobuf:protobuf-java-util:jar:sources", - "com.google.protobuf:protobuf-java:jar:sources", - "com.jayway.jsonpath:json-path", - "com.jayway.jsonpath:json-path:jar:sources", - "com.nimbusds:content-type", - "com.nimbusds:content-type:jar:sources", - "com.nimbusds:lang-tag", - "com.nimbusds:lang-tag:jar:sources", - "com.nimbusds:nimbus-jose-jwt", - "com.nimbusds:nimbus-jose-jwt:jar:sources", - "com.nimbusds:oauth2-oidc-sdk", - "com.nimbusds:oauth2-oidc-sdk:jar:sources", - "com.squareup.okhttp3:logging-interceptor", - "com.squareup.okhttp3:logging-interceptor:jar:sources", - "com.squareup.okhttp3:okhttp", - "com.squareup.okhttp3:okhttp-jvm", - "com.squareup.okhttp3:okhttp-jvm:jar:sources", - "com.squareup.okhttp3:okhttp:jar:sources", - "com.squareup.okio:okio", - "com.squareup.okio:okio-jvm", - "com.squareup.okio:okio-jvm:jar:sources", - "com.squareup.okio:okio:jar:sources", - "com.typesafe:config", - "com.typesafe:config:jar:sources", - "com.vaadin.external.google:android-json", - "com.vaadin.external.google:android-json:jar:sources", - "commons-codec:commons-codec", - "commons-codec:commons-codec:jar:sources", - "commons-io:commons-io", - "commons-io:commons-io:jar:sources", - "commons-logging:commons-logging", - "commons-logging:commons-logging:jar:sources", - "io.cloudevents:cloudevents-api", - "io.cloudevents:cloudevents-api:jar:sources", - "io.cloudevents:cloudevents-core", - "io.cloudevents:cloudevents-core:jar:sources", - "io.cloudevents:cloudevents-json-jackson", - "io.cloudevents:cloudevents-json-jackson:jar:sources", - "io.dropwizard.metrics:metrics-core", - "io.dropwizard.metrics:metrics-core:jar:sources", - "io.grpc:grpc-api", - "io.grpc:grpc-api:jar:sources", - "io.grpc:grpc-context", - "io.grpc:grpc-context:jar:sources", - "io.grpc:grpc-core", - "io.grpc:grpc-core:jar:sources", - "io.grpc:grpc-inprocess", - "io.grpc:grpc-inprocess:jar:sources", - "io.grpc:grpc-netty-shaded", - "io.grpc:grpc-netty-shaded:jar:sources", - "io.grpc:grpc-protobuf", - "io.grpc:grpc-protobuf-lite", - "io.grpc:grpc-protobuf-lite:jar:sources", - "io.grpc:grpc-protobuf:jar:sources", - "io.grpc:grpc-services", - "io.grpc:grpc-services:jar:sources", - "io.grpc:grpc-stub", - "io.grpc:grpc-stub:jar:sources", - "io.grpc:grpc-util", - "io.grpc:grpc-util:jar:sources", - "io.gsonfire:gson-fire", - "io.gsonfire:gson-fire:jar:sources", - "io.kubernetes:client-java", - "io.kubernetes:client-java-api", - "io.kubernetes:client-java-api-fluent", - "io.kubernetes:client-java-api-fluent:jar:sources", - "io.kubernetes:client-java-api:jar:sources", - "io.kubernetes:client-java-extended", - "io.kubernetes:client-java-extended:jar:sources", - "io.kubernetes:client-java-proto", - "io.kubernetes:client-java-proto:jar:sources", - "io.kubernetes:client-java:jar:sources", - "io.micrometer:context-propagation", - "io.micrometer:context-propagation:jar:sources", - "io.micrometer:micrometer-commons", - "io.micrometer:micrometer-commons:jar:sources", - "io.micrometer:micrometer-core", - "io.micrometer:micrometer-core:jar:sources", - "io.micrometer:micrometer-jakarta9", - "io.micrometer:micrometer-jakarta9:jar:sources", - "io.micrometer:micrometer-observation", - "io.micrometer:micrometer-observation-test", - "io.micrometer:micrometer-observation-test:jar:sources", - "io.micrometer:micrometer-observation:jar:sources", - "io.micrometer:micrometer-registry-prometheus", - "io.micrometer:micrometer-registry-prometheus:jar:sources", - "io.micrometer:micrometer-tracing", - "io.micrometer:micrometer-tracing-bridge-otel", - "io.micrometer:micrometer-tracing-bridge-otel:jar:sources", - "io.micrometer:micrometer-tracing:jar:sources", - "io.nats:jnats", - "io.nats:jnats:jar:sources", - "io.netty:netty-buffer", - "io.netty:netty-buffer:jar:sources", - "io.netty:netty-codec-base", - "io.netty:netty-codec-base:jar:sources", - "io.netty:netty-codec-classes-quic", - "io.netty:netty-codec-classes-quic:jar:sources", - "io.netty:netty-codec-compression", - "io.netty:netty-codec-compression:jar:sources", - "io.netty:netty-codec-dns", - "io.netty:netty-codec-dns:jar:sources", - "io.netty:netty-codec-http", - "io.netty:netty-codec-http2", - "io.netty:netty-codec-http2:jar:sources", - "io.netty:netty-codec-http3", - "io.netty:netty-codec-http3:jar:sources", - "io.netty:netty-codec-http:jar:sources", - "io.netty:netty-codec-native-quic:jar:linux-aarch_64", - "io.netty:netty-codec-native-quic:jar:linux-x86_64", - "io.netty:netty-codec-native-quic:jar:osx-aarch_64", - "io.netty:netty-codec-native-quic:jar:osx-x86_64", - "io.netty:netty-codec-native-quic:jar:sources", - "io.netty:netty-codec-native-quic:jar:windows-x86_64", - "io.netty:netty-codec-socks", - "io.netty:netty-codec-socks:jar:sources", - "io.netty:netty-common", - "io.netty:netty-common:jar:sources", - "io.netty:netty-handler", - "io.netty:netty-handler-proxy", - "io.netty:netty-handler-proxy:jar:sources", - "io.netty:netty-handler:jar:sources", - "io.netty:netty-resolver", - "io.netty:netty-resolver-dns", - "io.netty:netty-resolver-dns-classes-macos", - "io.netty:netty-resolver-dns-classes-macos:jar:sources", - "io.netty:netty-resolver-dns-native-macos:jar:osx-x86_64", - "io.netty:netty-resolver-dns-native-macos:jar:sources", - "io.netty:netty-resolver-dns:jar:sources", - "io.netty:netty-resolver:jar:sources", - "io.netty:netty-transport", - "io.netty:netty-transport-classes-epoll", - "io.netty:netty-transport-classes-epoll:jar:sources", - "io.netty:netty-transport-native-epoll:jar:linux-x86_64", - "io.netty:netty-transport-native-epoll:jar:sources", - "io.netty:netty-transport-native-unix-common", - "io.netty:netty-transport-native-unix-common:jar:sources", - "io.netty:netty-transport:jar:sources", - "io.opentelemetry.semconv:opentelemetry-semconv", - "io.opentelemetry.semconv:opentelemetry-semconv:jar:sources", - "io.opentelemetry:opentelemetry-api", - "io.opentelemetry:opentelemetry-api:jar:sources", - "io.opentelemetry:opentelemetry-common", - "io.opentelemetry:opentelemetry-common:jar:sources", - "io.opentelemetry:opentelemetry-context", - "io.opentelemetry:opentelemetry-context:jar:sources", - "io.opentelemetry:opentelemetry-exporter-common", - "io.opentelemetry:opentelemetry-exporter-common:jar:sources", - "io.opentelemetry:opentelemetry-exporter-otlp", - "io.opentelemetry:opentelemetry-exporter-otlp-common", - "io.opentelemetry:opentelemetry-exporter-otlp-common:jar:sources", - "io.opentelemetry:opentelemetry-exporter-otlp:jar:sources", - "io.opentelemetry:opentelemetry-exporter-sender-okhttp", - "io.opentelemetry:opentelemetry-exporter-sender-okhttp:jar:sources", - "io.opentelemetry:opentelemetry-extension-trace-propagators", - "io.opentelemetry:opentelemetry-extension-trace-propagators:jar:sources", - "io.opentelemetry:opentelemetry-sdk", - "io.opentelemetry:opentelemetry-sdk-common", - "io.opentelemetry:opentelemetry-sdk-common:jar:sources", - "io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi", - "io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi:jar:sources", - "io.opentelemetry:opentelemetry-sdk-logs", - "io.opentelemetry:opentelemetry-sdk-logs:jar:sources", - "io.opentelemetry:opentelemetry-sdk-metrics", - "io.opentelemetry:opentelemetry-sdk-metrics:jar:sources", - "io.opentelemetry:opentelemetry-sdk-testing", - "io.opentelemetry:opentelemetry-sdk-testing:jar:sources", - "io.opentelemetry:opentelemetry-sdk-trace", - "io.opentelemetry:opentelemetry-sdk-trace:jar:sources", - "io.opentelemetry:opentelemetry-sdk:jar:sources", - "io.perfmark:perfmark-api", - "io.perfmark:perfmark-api:jar:sources", - "io.projectreactor.netty:reactor-netty-core", - "io.projectreactor.netty:reactor-netty-core:jar:sources", - "io.projectreactor.netty:reactor-netty-http", - "io.projectreactor.netty:reactor-netty-http:jar:sources", - "io.projectreactor:reactor-core", - "io.projectreactor:reactor-core:jar:sources", - "io.projectreactor:reactor-test", - "io.projectreactor:reactor-test:jar:sources", - "io.prometheus:prometheus-metrics-config", - "io.prometheus:prometheus-metrics-config:jar:sources", - "io.prometheus:prometheus-metrics-core", - "io.prometheus:prometheus-metrics-core:jar:sources", - "io.prometheus:prometheus-metrics-exposition-formats", - "io.prometheus:prometheus-metrics-exposition-formats:jar:sources", - "io.prometheus:prometheus-metrics-exposition-textformats", - "io.prometheus:prometheus-metrics-exposition-textformats:jar:sources", - "io.prometheus:prometheus-metrics-model", - "io.prometheus:prometheus-metrics-model:jar:sources", - "io.prometheus:prometheus-metrics-tracer-common", - "io.prometheus:prometheus-metrics-tracer-common:jar:sources", - "io.swagger.core.v3:swagger-annotations-jakarta", - "io.swagger.core.v3:swagger-annotations-jakarta:jar:sources", - "io.swagger.core.v3:swagger-core-jakarta", - "io.swagger.core.v3:swagger-core-jakarta:jar:sources", - "io.swagger.core.v3:swagger-models-jakarta", - "io.swagger.core.v3:swagger-models-jakarta:jar:sources", - "io.swagger:swagger-annotations", - "io.swagger:swagger-annotations:jar:sources", - "jakarta.activation:jakarta.activation-api", - "jakarta.activation:jakarta.activation-api:jar:sources", - "jakarta.annotation:jakarta.annotation-api", - "jakarta.annotation:jakarta.annotation-api:jar:sources", - "jakarta.servlet:jakarta.servlet-api", - "jakarta.servlet:jakarta.servlet-api:jar:sources", - "jakarta.validation:jakarta.validation-api", - "jakarta.validation:jakarta.validation-api:jar:sources", - "jakarta.xml.bind:jakarta.xml.bind-api", - "jakarta.xml.bind:jakarta.xml.bind-api:jar:sources", - "javax.annotation:javax.annotation-api", - "javax.annotation:javax.annotation-api:jar:sources", - "net.bytebuddy:byte-buddy", - "net.bytebuddy:byte-buddy-agent", - "net.bytebuddy:byte-buddy-agent:jar:sources", - "net.bytebuddy:byte-buddy:jar:sources", - "net.devh:grpc-common-spring-boot", - "net.devh:grpc-common-spring-boot:jar:sources", - "net.devh:grpc-server-spring-boot-starter", - "net.devh:grpc-server-spring-boot-starter:jar:sources", - "net.java.dev.jna:jna", - "net.java.dev.jna:jna:jar:sources", - "net.javacrumbs.shedlock:shedlock-core", - "net.javacrumbs.shedlock:shedlock-core:jar:sources", - "net.javacrumbs.shedlock:shedlock-provider-cassandra", - "net.javacrumbs.shedlock:shedlock-provider-cassandra:jar:sources", - "net.javacrumbs.shedlock:shedlock-spring", - "net.javacrumbs.shedlock:shedlock-spring:jar:sources", - "net.minidev:accessors-smart", - "net.minidev:accessors-smart:jar:sources", - "net.minidev:json-smart", - "net.minidev:json-smart:jar:sources", - "org.apache.cassandra:java-driver-core", - "org.apache.cassandra:java-driver-core:jar:sources", - "org.apache.cassandra:java-driver-guava-shaded", - "org.apache.cassandra:java-driver-guava-shaded:jar:sources", - "org.apache.cassandra:java-driver-metrics-micrometer", - "org.apache.cassandra:java-driver-metrics-micrometer:jar:sources", - "org.apache.cassandra:java-driver-query-builder", - "org.apache.cassandra:java-driver-query-builder:jar:sources", - "org.apache.commons:commons-collections4", - "org.apache.commons:commons-collections4:jar:sources", - "org.apache.commons:commons-compress", - "org.apache.commons:commons-compress:jar:sources", - "org.apache.commons:commons-lang3", - "org.apache.commons:commons-lang3:jar:sources", - "org.apache.logging.log4j:log4j-api", - "org.apache.logging.log4j:log4j-api:jar:sources", - "org.apache.logging.log4j:log4j-to-slf4j", - "org.apache.logging.log4j:log4j-to-slf4j:jar:sources", - "org.apache.tomcat.embed:tomcat-embed-core", - "org.apache.tomcat.embed:tomcat-embed-core:jar:sources", - "org.apache.tomcat.embed:tomcat-embed-el", - "org.apache.tomcat.embed:tomcat-embed-el:jar:sources", - "org.apache.tomcat.embed:tomcat-embed-websocket", - "org.apache.tomcat.embed:tomcat-embed-websocket:jar:sources", - "org.apiguardian:apiguardian-api", - "org.apiguardian:apiguardian-api:jar:sources", - "org.aspectj:aspectjweaver", - "org.aspectj:aspectjweaver:jar:sources", - "org.assertj:assertj-core", - "org.assertj:assertj-core:jar:sources", - "org.awaitility:awaitility", - "org.awaitility:awaitility:jar:sources", - "org.bitbucket.b_c:jose4j", - "org.bitbucket.b_c:jose4j:jar:sources", - "org.bouncycastle:bcpkix-jdk18on", - "org.bouncycastle:bcpkix-jdk18on:jar:sources", - "org.bouncycastle:bcprov-jdk18on", - "org.bouncycastle:bcprov-jdk18on:jar:sources", - "org.bouncycastle:bcprov-lts8on", - "org.bouncycastle:bcprov-lts8on:jar:sources", - "org.bouncycastle:bcutil-jdk18on", - "org.bouncycastle:bcutil-jdk18on:jar:sources", - "org.codehaus.mojo:animal-sniffer-annotations", - "org.codehaus.mojo:animal-sniffer-annotations:jar:sources", - "org.hamcrest:hamcrest", - "org.hamcrest:hamcrest:jar:sources", - "org.hdrhistogram:HdrHistogram", - "org.hdrhistogram:HdrHistogram:jar:sources", - "org.hibernate.validator:hibernate-validator", - "org.hibernate.validator:hibernate-validator:jar:sources", - "org.jacoco:org.jacoco.agent:jar:runtime", - "org.jacoco:org.jacoco.agent:jar:sources", - "org.jacoco:org.jacoco.cli", - "org.jacoco:org.jacoco.cli:jar:sources", - "org.jacoco:org.jacoco.core", - "org.jacoco:org.jacoco.core:jar:sources", - "org.jacoco:org.jacoco.report", - "org.jacoco:org.jacoco.report:jar:sources", - "org.jboss.logging:jboss-logging", - "org.jboss.logging:jboss-logging:jar:sources", - "org.jetbrains.kotlin:kotlin-stdlib", - "org.jetbrains.kotlin:kotlin-stdlib-jdk7", - "org.jetbrains.kotlin:kotlin-stdlib-jdk7:jar:sources", - "org.jetbrains.kotlin:kotlin-stdlib-jdk8", - "org.jetbrains.kotlin:kotlin-stdlib-jdk8:jar:sources", - "org.jetbrains.kotlin:kotlin-stdlib:jar:sources", - "org.jetbrains:annotations", - "org.jetbrains:annotations:jar:sources", - "org.jspecify:jspecify", - "org.jspecify:jspecify:jar:sources", - "org.junit.jupiter:junit-jupiter", - "org.junit.jupiter:junit-jupiter-api", - "org.junit.jupiter:junit-jupiter-api:jar:sources", - "org.junit.jupiter:junit-jupiter-engine", - "org.junit.jupiter:junit-jupiter-engine:jar:sources", - "org.junit.jupiter:junit-jupiter-params", - "org.junit.jupiter:junit-jupiter-params:jar:sources", - "org.junit.jupiter:junit-jupiter:jar:sources", - "org.junit.platform:junit-platform-commons", - "org.junit.platform:junit-platform-commons:jar:sources", - "org.junit.platform:junit-platform-console-standalone", - "org.junit.platform:junit-platform-console-standalone:jar:sources", - "org.junit.platform:junit-platform-engine", - "org.junit.platform:junit-platform-engine:jar:sources", - "org.latencyutils:LatencyUtils", - "org.latencyutils:LatencyUtils:jar:sources", - "org.mockito:mockito-core", - "org.mockito:mockito-core:jar:sources", - "org.mockito:mockito-junit-jupiter", - "org.mockito:mockito-junit-jupiter:jar:sources", - "org.objenesis:objenesis", - "org.objenesis:objenesis:jar:sources", - "org.opentest4j:opentest4j", - "org.opentest4j:opentest4j:jar:sources", - "org.ow2.asm:asm", - "org.ow2.asm:asm-analysis", - "org.ow2.asm:asm-analysis:jar:sources", - "org.ow2.asm:asm-commons", - "org.ow2.asm:asm-commons:jar:sources", - "org.ow2.asm:asm-tree", - "org.ow2.asm:asm-tree:jar:sources", - "org.ow2.asm:asm-util", - "org.ow2.asm:asm-util:jar:sources", - "org.ow2.asm:asm:jar:sources", - "org.projectlombok:lombok", - "org.projectlombok:lombok:jar:sources", - "org.reactivestreams:reactive-streams", - "org.reactivestreams:reactive-streams:jar:sources", - "org.rnorth.duct-tape:duct-tape", - "org.rnorth.duct-tape:duct-tape:jar:sources", - "org.skyscreamer:jsonassert", - "org.skyscreamer:jsonassert:jar:sources", - "org.slf4j:jul-to-slf4j", - "org.slf4j:jul-to-slf4j:jar:sources", - "org.slf4j:slf4j-api", - "org.slf4j:slf4j-api:jar:sources", - "org.springdoc:springdoc-openapi-starter-common", - "org.springdoc:springdoc-openapi-starter-common:jar:sources", - "org.springdoc:springdoc-openapi-starter-webflux-api", - "org.springdoc:springdoc-openapi-starter-webflux-api:jar:sources", - "org.springdoc:springdoc-openapi-starter-webmvc-api", - "org.springdoc:springdoc-openapi-starter-webmvc-api:jar:sources", - "org.springframework.boot:spring-boot", - "org.springframework.boot:spring-boot-actuator", - "org.springframework.boot:spring-boot-actuator-autoconfigure", - "org.springframework.boot:spring-boot-actuator-autoconfigure:jar:sources", - "org.springframework.boot:spring-boot-actuator:jar:sources", - "org.springframework.boot:spring-boot-autoconfigure", - "org.springframework.boot:spring-boot-autoconfigure:jar:sources", - "org.springframework.boot:spring-boot-cassandra", - "org.springframework.boot:spring-boot-cassandra:jar:sources", - "org.springframework.boot:spring-boot-data-cassandra", - "org.springframework.boot:spring-boot-data-cassandra-test", - "org.springframework.boot:spring-boot-data-cassandra-test:jar:sources", - "org.springframework.boot:spring-boot-data-cassandra:jar:sources", - "org.springframework.boot:spring-boot-data-commons", - "org.springframework.boot:spring-boot-data-commons:jar:sources", - "org.springframework.boot:spring-boot-health", - "org.springframework.boot:spring-boot-health:jar:sources", - "org.springframework.boot:spring-boot-http-client", - "org.springframework.boot:spring-boot-http-client:jar:sources", - "org.springframework.boot:spring-boot-http-codec", - "org.springframework.boot:spring-boot-http-codec:jar:sources", - "org.springframework.boot:spring-boot-http-converter", - "org.springframework.boot:spring-boot-http-converter:jar:sources", - "org.springframework.boot:spring-boot-jackson", - "org.springframework.boot:spring-boot-jackson:jar:sources", - "org.springframework.boot:spring-boot-loader", - "org.springframework.boot:spring-boot-loader:jar:sources", - "org.springframework.boot:spring-boot-micrometer-metrics", - "org.springframework.boot:spring-boot-micrometer-metrics-test", - "org.springframework.boot:spring-boot-micrometer-metrics-test:jar:sources", - "org.springframework.boot:spring-boot-micrometer-metrics:jar:sources", - "org.springframework.boot:spring-boot-micrometer-observation", - "org.springframework.boot:spring-boot-micrometer-observation:jar:sources", - "org.springframework.boot:spring-boot-micrometer-tracing", - "org.springframework.boot:spring-boot-micrometer-tracing-opentelemetry", - "org.springframework.boot:spring-boot-micrometer-tracing-opentelemetry:jar:sources", - "org.springframework.boot:spring-boot-micrometer-tracing:jar:sources", - "org.springframework.boot:spring-boot-netty", - "org.springframework.boot:spring-boot-netty:jar:sources", - "org.springframework.boot:spring-boot-opentelemetry", - "org.springframework.boot:spring-boot-opentelemetry:jar:sources", - "org.springframework.boot:spring-boot-persistence", - "org.springframework.boot:spring-boot-persistence:jar:sources", - "org.springframework.boot:spring-boot-reactor", - "org.springframework.boot:spring-boot-reactor-netty", - "org.springframework.boot:spring-boot-reactor-netty:jar:sources", - "org.springframework.boot:spring-boot-reactor:jar:sources", - "org.springframework.boot:spring-boot-restclient", - "org.springframework.boot:spring-boot-restclient:jar:sources", - "org.springframework.boot:spring-boot-resttestclient", - "org.springframework.boot:spring-boot-resttestclient:jar:sources", - "org.springframework.boot:spring-boot-security", - "org.springframework.boot:spring-boot-security-oauth2-client", - "org.springframework.boot:spring-boot-security-oauth2-client:jar:sources", - "org.springframework.boot:spring-boot-security-oauth2-resource-server", - "org.springframework.boot:spring-boot-security-oauth2-resource-server:jar:sources", - "org.springframework.boot:spring-boot-security-test", - "org.springframework.boot:spring-boot-security-test:jar:sources", - "org.springframework.boot:spring-boot-security:jar:sources", - "org.springframework.boot:spring-boot-servlet", - "org.springframework.boot:spring-boot-servlet:jar:sources", - "org.springframework.boot:spring-boot-starter", - "org.springframework.boot:spring-boot-starter-actuator", - "org.springframework.boot:spring-boot-starter-actuator-test", - "org.springframework.boot:spring-boot-starter-actuator-test:jar:sources", - "org.springframework.boot:spring-boot-starter-actuator:jar:sources", - "org.springframework.boot:spring-boot-starter-aspectj", - "org.springframework.boot:spring-boot-starter-aspectj:jar:sources", - "org.springframework.boot:spring-boot-starter-data-cassandra", - "org.springframework.boot:spring-boot-starter-data-cassandra-test", - "org.springframework.boot:spring-boot-starter-data-cassandra-test:jar:sources", - "org.springframework.boot:spring-boot-starter-data-cassandra:jar:sources", - "org.springframework.boot:spring-boot-starter-jackson", - "org.springframework.boot:spring-boot-starter-jackson-test", - "org.springframework.boot:spring-boot-starter-jackson-test:jar:sources", - "org.springframework.boot:spring-boot-starter-jackson:jar:sources", - "org.springframework.boot:spring-boot-starter-logging", - "org.springframework.boot:spring-boot-starter-logging:jar:sources", - "org.springframework.boot:spring-boot-starter-micrometer-metrics", - "org.springframework.boot:spring-boot-starter-micrometer-metrics-test", - "org.springframework.boot:spring-boot-starter-micrometer-metrics-test:jar:sources", - "org.springframework.boot:spring-boot-starter-micrometer-metrics:jar:sources", - "org.springframework.boot:spring-boot-starter-reactor-netty", - "org.springframework.boot:spring-boot-starter-reactor-netty:jar:sources", - "org.springframework.boot:spring-boot-starter-security", - "org.springframework.boot:spring-boot-starter-security-oauth2-client", - "org.springframework.boot:spring-boot-starter-security-oauth2-client:jar:sources", - "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server", - "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server-test", - "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server-test:jar:sources", - "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server:jar:sources", - "org.springframework.boot:spring-boot-starter-security-test", - "org.springframework.boot:spring-boot-starter-security-test:jar:sources", - "org.springframework.boot:spring-boot-starter-security:jar:sources", - "org.springframework.boot:spring-boot-starter-test", - "org.springframework.boot:spring-boot-starter-test:jar:sources", - "org.springframework.boot:spring-boot-starter-tomcat", - "org.springframework.boot:spring-boot-starter-tomcat-runtime", - "org.springframework.boot:spring-boot-starter-tomcat-runtime:jar:sources", - "org.springframework.boot:spring-boot-starter-tomcat:jar:sources", - "org.springframework.boot:spring-boot-starter-validation", - "org.springframework.boot:spring-boot-starter-validation:jar:sources", - "org.springframework.boot:spring-boot-starter-webflux", - "org.springframework.boot:spring-boot-starter-webflux-test", - "org.springframework.boot:spring-boot-starter-webflux-test:jar:sources", - "org.springframework.boot:spring-boot-starter-webflux:jar:sources", - "org.springframework.boot:spring-boot-starter-webmvc", - "org.springframework.boot:spring-boot-starter-webmvc-test", - "org.springframework.boot:spring-boot-starter-webmvc-test:jar:sources", - "org.springframework.boot:spring-boot-starter-webmvc:jar:sources", - "org.springframework.boot:spring-boot-starter:jar:sources", - "org.springframework.boot:spring-boot-test", - "org.springframework.boot:spring-boot-test-autoconfigure", - "org.springframework.boot:spring-boot-test-autoconfigure:jar:sources", - "org.springframework.boot:spring-boot-test:jar:sources", - "org.springframework.boot:spring-boot-tomcat", - "org.springframework.boot:spring-boot-tomcat:jar:sources", - "org.springframework.boot:spring-boot-validation", - "org.springframework.boot:spring-boot-validation:jar:sources", - "org.springframework.boot:spring-boot-web-server", - "org.springframework.boot:spring-boot-web-server:jar:sources", - "org.springframework.boot:spring-boot-webclient", - "org.springframework.boot:spring-boot-webclient:jar:sources", - "org.springframework.boot:spring-boot-webflux", - "org.springframework.boot:spring-boot-webflux-test", - "org.springframework.boot:spring-boot-webflux-test:jar:sources", - "org.springframework.boot:spring-boot-webflux:jar:sources", - "org.springframework.boot:spring-boot-webmvc", - "org.springframework.boot:spring-boot-webmvc-test", - "org.springframework.boot:spring-boot-webmvc-test:jar:sources", - "org.springframework.boot:spring-boot-webmvc:jar:sources", - "org.springframework.boot:spring-boot-webtestclient", - "org.springframework.boot:spring-boot-webtestclient:jar:sources", - "org.springframework.boot:spring-boot:jar:sources", - "org.springframework.cloud:spring-cloud-commons", - "org.springframework.cloud:spring-cloud-commons:jar:sources", - "org.springframework.cloud:spring-cloud-context", - "org.springframework.cloud:spring-cloud-context:jar:sources", - "org.springframework.cloud:spring-cloud-kubernetes-client-autoconfig", - "org.springframework.cloud:spring-cloud-kubernetes-client-autoconfig:jar:sources", - "org.springframework.cloud:spring-cloud-kubernetes-client-config", - "org.springframework.cloud:spring-cloud-kubernetes-client-config:jar:sources", - "org.springframework.cloud:spring-cloud-kubernetes-commons", - "org.springframework.cloud:spring-cloud-kubernetes-commons:jar:sources", - "org.springframework.cloud:spring-cloud-starter", - "org.springframework.cloud:spring-cloud-starter-bootstrap", - "org.springframework.cloud:spring-cloud-starter-bootstrap:jar:sources", - "org.springframework.cloud:spring-cloud-starter-kubernetes-client-config", - "org.springframework.data:spring-data-cassandra", - "org.springframework.data:spring-data-cassandra:jar:sources", - "org.springframework.data:spring-data-commons", - "org.springframework.data:spring-data-commons:jar:sources", - "org.springframework.retry:spring-retry", - "org.springframework.retry:spring-retry:jar:sources", - "org.springframework.security:spring-security-config", - "org.springframework.security:spring-security-config:jar:sources", - "org.springframework.security:spring-security-core", - "org.springframework.security:spring-security-core:jar:sources", - "org.springframework.security:spring-security-crypto", - "org.springframework.security:spring-security-crypto:jar:sources", - "org.springframework.security:spring-security-oauth2-client", - "org.springframework.security:spring-security-oauth2-client:jar:sources", - "org.springframework.security:spring-security-oauth2-core", - "org.springframework.security:spring-security-oauth2-core:jar:sources", - "org.springframework.security:spring-security-oauth2-jose", - "org.springframework.security:spring-security-oauth2-jose:jar:sources", - "org.springframework.security:spring-security-oauth2-resource-server", - "org.springframework.security:spring-security-oauth2-resource-server:jar:sources", - "org.springframework.security:spring-security-test", - "org.springframework.security:spring-security-test:jar:sources", - "org.springframework.security:spring-security-web", - "org.springframework.security:spring-security-web:jar:sources", - "org.springframework:spring-aop", - "org.springframework:spring-aop:jar:sources", - "org.springframework:spring-beans", - "org.springframework:spring-beans:jar:sources", - "org.springframework:spring-context", - "org.springframework:spring-context-support", - "org.springframework:spring-context-support:jar:sources", - "org.springframework:spring-context:jar:sources", - "org.springframework:spring-core", - "org.springframework:spring-core:jar:sources", - "org.springframework:spring-expression", - "org.springframework:spring-expression:jar:sources", - "org.springframework:spring-test", - "org.springframework:spring-test:jar:sources", - "org.springframework:spring-tx", - "org.springframework:spring-tx:jar:sources", - "org.springframework:spring-web", - "org.springframework:spring-web:jar:sources", - "org.springframework:spring-webflux", - "org.springframework:spring-webflux:jar:sources", - "org.springframework:spring-webmvc", - "org.springframework:spring-webmvc:jar:sources", - "org.testcontainers:testcontainers", - "org.testcontainers:testcontainers-cassandra", - "org.testcontainers:testcontainers-cassandra:jar:sources", - "org.testcontainers:testcontainers-database-commons", - "org.testcontainers:testcontainers-database-commons:jar:sources", - "org.testcontainers:testcontainers-junit-jupiter", - "org.testcontainers:testcontainers-junit-jupiter:jar:sources", - "org.testcontainers:testcontainers-localstack", - "org.testcontainers:testcontainers-localstack:jar:sources", - "org.testcontainers:testcontainers:jar:sources", - "org.wiremock:wiremock-standalone", - "org.wiremock:wiremock-standalone:jar:sources", - "org.xmlunit:xmlunit-core", - "org.xmlunit:xmlunit-core:jar:sources", - "org.yaml:snakeyaml", - "org.yaml:snakeyaml:jar:sources", - "software.amazon.awssdk:annotations", - "software.amazon.awssdk:annotations:jar:sources", - "software.amazon.awssdk:checksums", - "software.amazon.awssdk:checksums-spi", - "software.amazon.awssdk:checksums-spi:jar:sources", - "software.amazon.awssdk:checksums:jar:sources", - "software.amazon.awssdk:endpoints-spi", - "software.amazon.awssdk:endpoints-spi:jar:sources", - "software.amazon.awssdk:http-auth-aws", - "software.amazon.awssdk:http-auth-aws:jar:sources", - "software.amazon.awssdk:http-auth-spi", - "software.amazon.awssdk:http-auth-spi:jar:sources", - "software.amazon.awssdk:http-client-spi", - "software.amazon.awssdk:http-client-spi:jar:sources", - "software.amazon.awssdk:identity-spi", - "software.amazon.awssdk:identity-spi:jar:sources", - "software.amazon.awssdk:json-utils", - "software.amazon.awssdk:json-utils:jar:sources", - "software.amazon.awssdk:metrics-spi", - "software.amazon.awssdk:metrics-spi:jar:sources", - "software.amazon.awssdk:profiles", - "software.amazon.awssdk:profiles:jar:sources", - "software.amazon.awssdk:regions", - "software.amazon.awssdk:regions:jar:sources", - "software.amazon.awssdk:retries", - "software.amazon.awssdk:retries-spi", - "software.amazon.awssdk:retries-spi:jar:sources", - "software.amazon.awssdk:retries:jar:sources", - "software.amazon.awssdk:sdk-core", - "software.amazon.awssdk:sdk-core:jar:sources", - "software.amazon.awssdk:third-party-jackson-core", - "software.amazon.awssdk:third-party-jackson-core:jar:sources", - "software.amazon.awssdk:utils", - "software.amazon.awssdk:utils:jar:sources", - "tools.jackson.core:jackson-core", - "tools.jackson.core:jackson-core:jar:sources", - "tools.jackson.core:jackson-databind", - "tools.jackson.core:jackson-databind:jar:sources", - "tools.jackson.module:jackson-module-blackbird", - "tools.jackson.module:jackson-module-blackbird:jar:sources" - ] - }, - "services": { - "ch.qos.logback:logback-classic": { - "jakarta.servlet.ServletContainerInitializer": [ - "ch.qos.logback.classic.servlet.LogbackServletContainerInitializer" - ], - "org.slf4j.spi.SLF4JServiceProvider": [ - "ch.qos.logback.classic.spi.LogbackServiceProvider" - ] - }, - "com.fasterxml.jackson.core:jackson-core": { - "com.fasterxml.jackson.core.JsonFactory": [ - "com.fasterxml.jackson.core.JsonFactory" - ] - }, - "com.fasterxml.jackson.core:jackson-databind": { - "com.fasterxml.jackson.core.ObjectCodec": [ - "com.fasterxml.jackson.databind.ObjectMapper" - ] - }, - "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml": { - "com.fasterxml.jackson.core.JsonFactory": [ - "com.fasterxml.jackson.dataformat.yaml.YAMLFactory" - ], - "com.fasterxml.jackson.core.ObjectCodec": [ - "com.fasterxml.jackson.dataformat.yaml.YAMLMapper" - ] - }, - "com.fasterxml.jackson.datatype:jackson-datatype-jsr310": { - "com.fasterxml.jackson.databind.Module": [ - "com.fasterxml.jackson.datatype.jsr310.JavaTimeModule" - ] - }, - "io.cloudevents:cloudevents-json-jackson": { - "io.cloudevents.core.format.EventFormat": [ - "io.cloudevents.jackson.JsonFormat" - ] - }, - "io.grpc:grpc-core": { - "io.grpc.LoadBalancerProvider": [ - "io.grpc.internal.PickFirstLoadBalancerProvider" - ], - "io.grpc.NameResolverProvider": [ - "io.grpc.internal.DnsNameResolverProvider" - ] - }, - "io.grpc:grpc-netty-shaded": { - "io.grpc.ManagedChannelProvider": [ - "io.grpc.netty.shaded.io.grpc.netty.NettyChannelProvider", - "io.grpc.netty.shaded.io.grpc.netty.UdsNettyChannelProvider" - ], - "io.grpc.NameResolverProvider": [ - "io.grpc.netty.shaded.io.grpc.netty.UdsNameResolverProvider" - ], - "io.grpc.ServerProvider": [ - "io.grpc.netty.shaded.io.grpc.netty.NettyServerProvider" - ], - "reactor.blockhound.integration.BlockHoundIntegration": [ - "io.grpc.netty.shaded.io.netty.util.internal.Hidden$NettyBlockHoundIntegration" - ] - }, - "io.grpc:grpc-services": { - "io.grpc.LoadBalancerProvider": [ - "io.grpc.protobuf.services.internal.HealthCheckingRoundRobinLoadBalancerProvider" - ] - }, - "io.grpc:grpc-util": { - "io.grpc.LoadBalancerProvider": [ - "io.grpc.util.OutlierDetectionLoadBalancerProvider", - "io.grpc.util.SecretRoundRobinLoadBalancerProvider$Provider" - ] - }, - "io.micrometer:micrometer-observation": { - "io.micrometer.context.ThreadLocalAccessor": [ - "io.micrometer.observation.contextpropagation.ObservationThreadLocalAccessor" - ] - }, - "io.netty:netty-common": { - "reactor.blockhound.integration.BlockHoundIntegration": [ - "io.netty.util.internal.Hidden$NettyBlockHoundIntegration" - ] - }, - "io.opentelemetry:opentelemetry-exporter-otlp": { - "io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider": [ - "io.opentelemetry.exporter.otlp.internal.OtlpGrpcLogRecordExporterComponentProvider", - "io.opentelemetry.exporter.otlp.internal.OtlpGrpcMetricExporterComponentProvider", - "io.opentelemetry.exporter.otlp.internal.OtlpGrpcSpanExporterComponentProvider", - "io.opentelemetry.exporter.otlp.internal.OtlpHttpLogRecordExporterComponentProvider", - "io.opentelemetry.exporter.otlp.internal.OtlpHttpMetricExporterComponentProvider", - "io.opentelemetry.exporter.otlp.internal.OtlpHttpSpanExporterComponentProvider" - ], - "io.opentelemetry.sdk.autoconfigure.spi.logs.ConfigurableLogRecordExporterProvider": [ - "io.opentelemetry.exporter.otlp.internal.OtlpLogRecordExporterProvider" - ], - "io.opentelemetry.sdk.autoconfigure.spi.metrics.ConfigurableMetricExporterProvider": [ - "io.opentelemetry.exporter.otlp.internal.OtlpMetricExporterProvider" - ], - "io.opentelemetry.sdk.autoconfigure.spi.traces.ConfigurableSpanExporterProvider": [ - "io.opentelemetry.exporter.otlp.internal.OtlpSpanExporterProvider" - ] - }, - "io.opentelemetry:opentelemetry-exporter-sender-okhttp": { - "io.opentelemetry.exporter.internal.grpc.GrpcSenderProvider": [ - "io.opentelemetry.exporter.sender.okhttp.internal.OkHttpGrpcSenderProvider" - ], - "io.opentelemetry.exporter.internal.http.HttpSenderProvider": [ - "io.opentelemetry.exporter.sender.okhttp.internal.OkHttpHttpSenderProvider" - ] - }, - "io.opentelemetry:opentelemetry-extension-trace-propagators": { - "io.opentelemetry.sdk.autoconfigure.spi.ConfigurablePropagatorProvider": [ - "io.opentelemetry.extension.trace.propagation.B3ConfigurablePropagator", - "io.opentelemetry.extension.trace.propagation.B3MultiConfigurablePropagator", - "io.opentelemetry.extension.trace.propagation.JaegerConfigurablePropagator", - "io.opentelemetry.extension.trace.propagation.OtTraceConfigurablePropagator" - ], - "io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider": [ - "io.opentelemetry.extension.trace.propagation.internal.B3ComponentProvider", - "io.opentelemetry.extension.trace.propagation.internal.B3MultiComponentProvider", - "io.opentelemetry.extension.trace.propagation.internal.JaegerComponentProvider", - "io.opentelemetry.extension.trace.propagation.internal.OtTraceComponentProvider" - ] - }, - "io.opentelemetry:opentelemetry-sdk-testing": { - "io.opentelemetry.context.ContextStorageProvider": [ - "io.opentelemetry.sdk.testing.context.SettableContextStorageProvider" - ] - }, - "io.projectreactor.netty:reactor-netty-core": { - "io.micrometer.context.ContextAccessor": [ - "reactor.netty.contextpropagation.ChannelContextAccessor" - ] - }, - "io.projectreactor:reactor-core": { - "io.micrometer.context.ContextAccessor": [ - "reactor.util.context.ReactorContextAccessor" - ], - "reactor.blockhound.integration.BlockHoundIntegration": [ - "reactor.core.scheduler.ReactorBlockHoundIntegration" - ] - }, - "org.apache.cassandra:java-driver-core": { - "reactor.blockhound.integration.BlockHoundIntegration": [ - "com.datastax.oss.driver.internal.core.util.concurrent.DriverBlockHoundIntegration" - ] - }, - "org.apache.logging.log4j:log4j-api": { - "org.apache.logging.log4j.util.PropertySource": [ - "org.apache.logging.log4j.util.EnvironmentPropertySource", - "org.apache.logging.log4j.util.SystemPropertiesPropertySource" - ] - }, - "org.apache.logging.log4j:log4j-to-slf4j": { - "org.apache.logging.log4j.spi.Provider": [ - "org.apache.logging.slf4j.SLF4JProvider" - ] - }, - "org.apache.tomcat.embed:tomcat-embed-el": { - "jakarta.el.ExpressionFactory": [ - "org.apache.el.ExpressionFactoryImpl" - ] - }, - "org.apache.tomcat.embed:tomcat-embed-websocket": { - "jakarta.servlet.ServletContainerInitializer": [ - "org.apache.tomcat.websocket.server.WsSci" - ], - "jakarta.websocket.ContainerProvider": [ - "org.apache.tomcat.websocket.WsContainerProvider" - ], - "jakarta.websocket.server.ServerEndpointConfig$Configurator": [ - "org.apache.tomcat.websocket.server.DefaultServerEndpointConfigurator" - ] - }, - "org.bouncycastle:bcprov-jdk18on": { - "java.security.Provider": [ - "org.bouncycastle.jce.provider.BouncyCastleProvider", - "org.bouncycastle.pqc.jcajce.provider.BouncyCastlePQCProvider" - ] - }, - "org.bouncycastle:bcprov-lts8on": { - "java.security.Provider": [ - "org.bouncycastle.jce.provider.BouncyCastleProvider", - "org.bouncycastle.pqc.jcajce.provider.BouncyCastlePQCProvider" - ] - }, - "org.hibernate.validator:hibernate-validator": { - "jakarta.validation.spi.ValidationProvider": [ - "org.hibernate.validator.HibernateValidator" - ] - }, - "org.junit.jupiter:junit-jupiter-engine": { - "org.junit.platform.engine.TestEngine": [ - "org.junit.jupiter.engine.JupiterTestEngine" - ] - }, - "org.junit.platform:junit-platform-console-standalone": { - "java.util.spi.ToolProvider": [ - "org.junit.platform.console.ConsoleLauncherToolProvider" - ], - "org.junit.platform.engine.TestEngine": [ - "org.junit.jupiter.engine.JupiterTestEngine", - "org.junit.platform.suite.engine.SuiteTestEngine", - "org.junit.vintage.engine.VintageTestEngine" - ], - "org.junit.platform.engine.discovery.DiscoverySelectorIdentifierParser": [ - "org.junit.platform.engine.discovery.ClassSelector$IdentifierParser", - "org.junit.platform.engine.discovery.ClasspathResourceSelector$IdentifierParser", - "org.junit.platform.engine.discovery.ClasspathRootSelector$IdentifierParser", - "org.junit.platform.engine.discovery.DirectorySelector$IdentifierParser", - "org.junit.platform.engine.discovery.FileSelector$IdentifierParser", - "org.junit.platform.engine.discovery.IterationSelector$IdentifierParser", - "org.junit.platform.engine.discovery.MethodSelector$IdentifierParser", - "org.junit.platform.engine.discovery.ModuleSelector$IdentifierParser", - "org.junit.platform.engine.discovery.NestedClassSelector$IdentifierParser", - "org.junit.platform.engine.discovery.NestedMethodSelector$IdentifierParser", - "org.junit.platform.engine.discovery.PackageSelector$IdentifierParser", - "org.junit.platform.engine.discovery.UniqueIdSelector$IdentifierParser", - "org.junit.platform.engine.discovery.UriSelector$IdentifierParser" - ], - "org.junit.platform.launcher.TestExecutionListener": [ - "org.junit.platform.launcher.listeners.UniqueIdTrackingListener", - "org.junit.platform.reporting.open.xml.OpenTestReportGeneratingListener" - ], - "org.opentest4j.reporting.tooling.spi.htmlreport.Contributor": [ - "org.junit.platform.reporting.open.xml.JUnitContributor" - ] - }, - "org.junit.platform:junit-platform-engine": { - "org.junit.platform.engine.discovery.DiscoverySelectorIdentifierParser": [ - "org.junit.platform.engine.discovery.ClassSelector$IdentifierParser", - "org.junit.platform.engine.discovery.ClasspathResourceSelector$IdentifierParser", - "org.junit.platform.engine.discovery.ClasspathRootSelector$IdentifierParser", - "org.junit.platform.engine.discovery.DirectorySelector$IdentifierParser", - "org.junit.platform.engine.discovery.FileSelector$IdentifierParser", - "org.junit.platform.engine.discovery.IterationSelector$IdentifierParser", - "org.junit.platform.engine.discovery.MethodSelector$IdentifierParser", - "org.junit.platform.engine.discovery.ModuleSelector$IdentifierParser", - "org.junit.platform.engine.discovery.NestedClassSelector$IdentifierParser", - "org.junit.platform.engine.discovery.NestedMethodSelector$IdentifierParser", - "org.junit.platform.engine.discovery.PackageSelector$IdentifierParser", - "org.junit.platform.engine.discovery.UniqueIdSelector$IdentifierParser", - "org.junit.platform.engine.discovery.UriSelector$IdentifierParser" - ] - }, - "org.projectlombok:lombok": { - "javax.annotation.processing.Processor": [ - "lombok.launch.AnnotationProcessorHider$AnnotationProcessor", - "lombok.launch.AnnotationProcessorHider$ClaimingProcessor" - ], - "lombok.core.LombokApp": [ - "lombok.bytecode.PoolConstantsApp", - "lombok.bytecode.PostCompilerApp", - "lombok.core.Main$LicenseApp", - "lombok.core.Main$VersionApp", - "lombok.core.PublicApiCreatorApp", - "lombok.core.configuration.ConfigurationApp", - "lombok.core.runtimeDependencies.CreateLombokRuntimeApp", - "lombok.delombok.DelombokApp", - "lombok.eclipse.agent.MavenEcjBootstrapApp", - "lombok.installer.Installer$CommandLineInstallerApp", - "lombok.installer.Installer$CommandLineUninstallerApp", - "lombok.installer.Installer$GraphicalInstallerApp" - ], - "lombok.core.PostCompilerTransformation": [ - "lombok.bytecode.PreventNullAnalysisRemover", - "lombok.bytecode.SneakyThrowsRemover" - ], - "lombok.core.runtimeDependencies.RuntimeDependencyInfo": [ - "lombok.core.handlers.SneakyThrowsAndCleanupDependencyInfo" - ], - "lombok.eclipse.EclipseASTVisitor": [ - "lombok.eclipse.handlers.HandleFieldDefaults", - "lombok.eclipse.handlers.HandleVal" - ], - "lombok.eclipse.EclipseAnnotationHandler": [ - "lombok.eclipse.handlers.HandleAccessors", - "lombok.eclipse.handlers.HandleBuilder", - "lombok.eclipse.handlers.HandleBuilderDefault", - "lombok.eclipse.handlers.HandleCleanup", - "lombok.eclipse.handlers.HandleConstructor$HandleAllArgsConstructor", - "lombok.eclipse.handlers.HandleConstructor$HandleNoArgsConstructor", - "lombok.eclipse.handlers.HandleConstructor$HandleRequiredArgsConstructor", - "lombok.eclipse.handlers.HandleData", - "lombok.eclipse.handlers.HandleDelegate", - "lombok.eclipse.handlers.HandleEqualsAndHashCode", - "lombok.eclipse.handlers.HandleExtensionMethod", - "lombok.eclipse.handlers.HandleFieldNameConstants", - "lombok.eclipse.handlers.HandleGetter", - "lombok.eclipse.handlers.HandleHelper", - "lombok.eclipse.handlers.HandleJacksonized", - "lombok.eclipse.handlers.HandleLocked", - "lombok.eclipse.handlers.HandleLockedRead", - "lombok.eclipse.handlers.HandleLockedWrite", - "lombok.eclipse.handlers.HandleLog$HandleCommonsLog", - "lombok.eclipse.handlers.HandleLog$HandleCustomLog", - "lombok.eclipse.handlers.HandleLog$HandleFloggerLog", - "lombok.eclipse.handlers.HandleLog$HandleJBossLog", - "lombok.eclipse.handlers.HandleLog$HandleJulLog", - "lombok.eclipse.handlers.HandleLog$HandleLog4j2Log", - "lombok.eclipse.handlers.HandleLog$HandleLog4jLog", - "lombok.eclipse.handlers.HandleLog$HandleSlf4jLog", - "lombok.eclipse.handlers.HandleLog$HandleXSlf4jLog", - "lombok.eclipse.handlers.HandleNonNull", - "lombok.eclipse.handlers.HandlePrintAST", - "lombok.eclipse.handlers.HandleSetter", - "lombok.eclipse.handlers.HandleSneakyThrows", - "lombok.eclipse.handlers.HandleStandardException", - "lombok.eclipse.handlers.HandleSuperBuilder", - "lombok.eclipse.handlers.HandleSynchronized", - "lombok.eclipse.handlers.HandleToString", - "lombok.eclipse.handlers.HandleUtilityClass", - "lombok.eclipse.handlers.HandleValue", - "lombok.eclipse.handlers.HandleWith", - "lombok.eclipse.handlers.HandleWithBy" - ], - "lombok.eclipse.handlers.EclipseSingularsRecipes$EclipseSingularizer": [ - "lombok.eclipse.handlers.singulars.EclipseGuavaMapSingularizer", - "lombok.eclipse.handlers.singulars.EclipseGuavaSetListSingularizer", - "lombok.eclipse.handlers.singulars.EclipseGuavaTableSingularizer", - "lombok.eclipse.handlers.singulars.EclipseJavaUtilListSingularizer", - "lombok.eclipse.handlers.singulars.EclipseJavaUtilMapSingularizer", - "lombok.eclipse.handlers.singulars.EclipseJavaUtilSetSingularizer" - ], - "lombok.installer.IdeLocationProvider": [ - "lombok.installer.eclipse.AngularIDELocationProvider", - "lombok.installer.eclipse.EclipseLocationProvider", - "lombok.installer.eclipse.JbdsLocationProvider", - "lombok.installer.eclipse.MyEclipseLocationProvider", - "lombok.installer.eclipse.RhcrLocationProvider", - "lombok.installer.eclipse.RhdsLocationProvider", - "lombok.installer.eclipse.STS4LocationProvider", - "lombok.installer.eclipse.STS5LocationProvider", - "lombok.installer.eclipse.STSLocationProvider" - ], - "lombok.javac.JavacASTVisitor": [ - "lombok.javac.handlers.HandleFieldDefaults", - "lombok.javac.handlers.HandleVal" - ], - "lombok.javac.JavacAnnotationHandler": [ - "lombok.javac.handlers.HandleAccessors", - "lombok.javac.handlers.HandleBuilder", - "lombok.javac.handlers.HandleBuilderDefault", - "lombok.javac.handlers.HandleBuilderDefaultRemove", - "lombok.javac.handlers.HandleBuilderRemove", - "lombok.javac.handlers.HandleCleanup", - "lombok.javac.handlers.HandleConstructor$HandleAllArgsConstructor", - "lombok.javac.handlers.HandleConstructor$HandleNoArgsConstructor", - "lombok.javac.handlers.HandleConstructor$HandleRequiredArgsConstructor", - "lombok.javac.handlers.HandleData", - "lombok.javac.handlers.HandleDelegate", - "lombok.javac.handlers.HandleEqualsAndHashCode", - "lombok.javac.handlers.HandleExtensionMethod", - "lombok.javac.handlers.HandleFieldNameConstants", - "lombok.javac.handlers.HandleGetter", - "lombok.javac.handlers.HandleHelper", - "lombok.javac.handlers.HandleJacksonized", - "lombok.javac.handlers.HandleLocked", - "lombok.javac.handlers.HandleLockedRead", - "lombok.javac.handlers.HandleLockedWrite", - "lombok.javac.handlers.HandleLog$HandleCommonsLog", - "lombok.javac.handlers.HandleLog$HandleCustomLog", - "lombok.javac.handlers.HandleLog$HandleFloggerLog", - "lombok.javac.handlers.HandleLog$HandleJBossLog", - "lombok.javac.handlers.HandleLog$HandleJulLog", - "lombok.javac.handlers.HandleLog$HandleLog4j2Log", - "lombok.javac.handlers.HandleLog$HandleLog4jLog", - "lombok.javac.handlers.HandleLog$HandleSlf4jLog", - "lombok.javac.handlers.HandleLog$HandleXSlf4jLog", - "lombok.javac.handlers.HandleNonNull", - "lombok.javac.handlers.HandlePrintAST", - "lombok.javac.handlers.HandleSetter", - "lombok.javac.handlers.HandleSingularRemove", - "lombok.javac.handlers.HandleSneakyThrows", - "lombok.javac.handlers.HandleStandardException", - "lombok.javac.handlers.HandleSuperBuilder", - "lombok.javac.handlers.HandleSuperBuilderRemove", - "lombok.javac.handlers.HandleSynchronized", - "lombok.javac.handlers.HandleToString", - "lombok.javac.handlers.HandleUtilityClass", - "lombok.javac.handlers.HandleValue", - "lombok.javac.handlers.HandleWith", - "lombok.javac.handlers.HandleWithBy" - ], - "lombok.javac.handlers.JavacSingularsRecipes$JavacSingularizer": [ - "lombok.javac.handlers.singulars.JavacGuavaMapSingularizer", - "lombok.javac.handlers.singulars.JavacGuavaSetListSingularizer", - "lombok.javac.handlers.singulars.JavacGuavaTableSingularizer", - "lombok.javac.handlers.singulars.JavacJavaUtilListSingularizer", - "lombok.javac.handlers.singulars.JavacJavaUtilMapSingularizer", - "lombok.javac.handlers.singulars.JavacJavaUtilSetSingularizer" - ] - }, - "org.springframework.boot:spring-boot": { - "ch.qos.logback.classic.spi.Configurator": [ - "org.springframework.boot.logging.logback.RootLogLevelConfigurator" - ], - "org.apache.logging.log4j.util.PropertySource": [ - "org.springframework.boot.logging.log4j2.SpringBootPropertySource" - ] - }, - "org.springframework.boot:spring-boot-loader": { - "java.nio.file.spi.FileSystemProvider": [ - "org.springframework.boot.loader.nio.file.NestedFileSystemProvider" - ] - }, - "org.springframework.boot:spring-boot-micrometer-tracing-opentelemetry": { - "org.junit.platform.launcher.TestExecutionListener": [ - "org.springframework.boot.micrometer.tracing.opentelemetry.autoconfigure.OpenTelemetryEventPublisherBeansTestExecutionListener" - ] - }, - "org.springframework.data:spring-data-cassandra": { - "jakarta.enterprise.inject.spi.Extension": [ - "org.springframework.data.cassandra.repository.cdi.CassandraRepositoryExtension" - ] - }, - "org.springframework.security:spring-security-core": { - "io.micrometer.context.ThreadLocalAccessor": [ - "org.springframework.security.core.context.ReactiveSecurityContextHolderThreadLocalAccessor", - "org.springframework.security.core.context.SecurityContextHolderThreadLocalAccessor" - ] - }, - "org.springframework.security:spring-security-web": { - "io.micrometer.context.ThreadLocalAccessor": [ - "org.springframework.security.web.server.ServerWebExchangeThreadLocalAccessor" - ] - }, - "org.springframework:spring-core": { - "reactor.blockhound.integration.BlockHoundIntegration": [ - "org.springframework.core.ReactiveAdapterRegistry$SpringCoreBlockHoundIntegration" - ] - }, - "org.springframework:spring-web": { - "jakarta.servlet.ServletContainerInitializer": [ - "org.springframework.web.SpringServletContainerInitializer" - ], - "reactor.blockhound.integration.BlockHoundIntegration": [ - "org.springframework.web.server.adapter.WebHttpHandlerBuilder$SpringWebBlockHoundIntegration" - ] - }, - "org.testcontainers:testcontainers": { - "org.testcontainers.dockerclient.DockerClientProviderStrategy": [ - "org.testcontainers.dockerclient.DockerDesktopClientProviderStrategy", - "org.testcontainers.dockerclient.DockerMachineClientProviderStrategy", - "org.testcontainers.dockerclient.EnvironmentAndSystemPropertyClientProviderStrategy", - "org.testcontainers.dockerclient.NpipeSocketClientProviderStrategy", - "org.testcontainers.dockerclient.RootlessDockerClientProviderStrategy", - "org.testcontainers.dockerclient.TestcontainersHostPropertyClientProviderStrategy", - "org.testcontainers.dockerclient.UnixSocketClientProviderStrategy" - ], - "org.testcontainers.shaded.com.fasterxml.jackson.core.JsonFactory": [ - "org.testcontainers.shaded.com.fasterxml.jackson.core.JsonFactory" - ], - "org.testcontainers.shaded.com.fasterxml.jackson.core.ObjectCodec": [ - "org.testcontainers.shaded.com.fasterxml.jackson.databind.ObjectMapper" - ] - }, - "org.wiremock:wiremock-standalone": { - "wiremock.com.fasterxml.jackson.core.JsonFactory": [ - "wiremock.com.fasterxml.jackson.core.JsonFactory", - "wiremock.com.fasterxml.jackson.dataformat.yaml.YAMLFactory" - ], - "wiremock.com.fasterxml.jackson.core.ObjectCodec": [ - "wiremock.com.fasterxml.jackson.databind.ObjectMapper", - "wiremock.com.fasterxml.jackson.dataformat.yaml.YAMLMapper" - ], - "wiremock.com.fasterxml.jackson.databind.Module": [ - "wiremock.com.fasterxml.jackson.datatype.jsr310.JavaTimeModule" - ], - "wiremock.org.eclipse.jetty.http.HttpFieldPreEncoder": [ - "wiremock.org.eclipse.jetty.http.Http1FieldPreEncoder", - "wiremock.org.eclipse.jetty.http2.hpack.HpackFieldPreEncoder" - ], - "wiremock.org.eclipse.jetty.io.ssl.ALPNProcessor$Client": [ - "wiremock.org.eclipse.jetty.alpn.java.client.JDK9ClientALPNProcessor" - ], - "wiremock.org.eclipse.jetty.io.ssl.ALPNProcessor$Server": [ - "wiremock.org.eclipse.jetty.alpn.java.server.JDK9ServerALPNProcessor" - ], - "wiremock.org.eclipse.jetty.webapp.Configuration": [ - "wiremock.org.eclipse.jetty.webapp.FragmentConfiguration", - "wiremock.org.eclipse.jetty.webapp.JaasConfiguration", - "wiremock.org.eclipse.jetty.webapp.JaspiConfiguration", - "wiremock.org.eclipse.jetty.webapp.JettyWebXmlConfiguration", - "wiremock.org.eclipse.jetty.webapp.JmxConfiguration", - "wiremock.org.eclipse.jetty.webapp.JndiConfiguration", - "wiremock.org.eclipse.jetty.webapp.JspConfiguration", - "wiremock.org.eclipse.jetty.webapp.MetaInfConfiguration", - "wiremock.org.eclipse.jetty.webapp.ServletsConfiguration", - "wiremock.org.eclipse.jetty.webapp.WebAppConfiguration", - "wiremock.org.eclipse.jetty.webapp.WebInfConfiguration", - "wiremock.org.eclipse.jetty.webapp.WebXmlConfiguration" - ], - "wiremock.org.slf4j.spi.SLF4JServiceProvider": [ - "wiremock.org.slf4j.helpers.NOP_FallbackServiceProvider" - ], - "wiremock.org.xmlunit.placeholder.PlaceholderHandler": [ - "wiremock.org.xmlunit.placeholder.IgnorePlaceholderHandler", - "wiremock.org.xmlunit.placeholder.IsDateTimePlaceholderHandler", - "wiremock.org.xmlunit.placeholder.IsNumberPlaceholderHandler", - "wiremock.org.xmlunit.placeholder.MatchesRegexPlaceholderHandler" - ] - }, - "software.amazon.awssdk:third-party-jackson-core": { - "software.amazon.awssdk.thirdparty.jackson.core.JsonFactory": [ - "software.amazon.awssdk.thirdparty.jackson.core.JsonFactory" - ] - }, - "tools.jackson.core:jackson-core": { - "tools.jackson.core.TokenStreamFactory": [ - "tools.jackson.core.json.JsonFactory" - ] - }, - "tools.jackson.core:jackson-databind": { - "tools.jackson.databind.ObjectMapper": [ - "tools.jackson.databind.json.JsonMapper" - ] - }, - "tools.jackson.module:jackson-module-blackbird": { - "tools.jackson.databind.JacksonModule": [ - "tools.jackson.module.blackbird.BlackbirdModule" - ] - } - }, - "skipped": [], - "version": "3" -} diff --git a/src/control-plane-services/cloud-tasks/tools/bazel/notice_metadata.json b/src/control-plane-services/cloud-tasks/notice_metadata.json similarity index 100% rename from src/control-plane-services/cloud-tasks/tools/bazel/notice_metadata.json rename to src/control-plane-services/cloud-tasks/notice_metadata.json diff --git a/src/control-plane-services/cloud-tasks/nvct-core/BUILD.bazel b/src/control-plane-services/cloud-tasks/nvct-core/BUILD.bazel index 7a9fa8c7a..dc9ca4be4 100644 --- a/src/control-plane-services/cloud-tasks/nvct-core/BUILD.bazel +++ b/src/control-plane-services/cloud-tasks/nvct-core/BUILD.bazel @@ -1,7 +1,7 @@ -load("@protobuf//bazel:proto_library.bzl", "proto_library") +load("@com_google_protobuf//bazel:proto_library.bzl", "proto_library") load("@rules_java//java:defs.bzl", "java_library") -load("//tools/bazel:java.bzl", "nvct_library", "nvct_library_test") -load("//tools/bazel:proto.bzl", "nvct_java_grpc_compile") +load("//rules/java:defs.bzl", "nvct_library", "nvct_library_test") +load("//rules/java:proto.bzl", "nvct_java_grpc_compile") package(default_visibility = ["//visibility:public"]) @@ -10,13 +10,13 @@ NVCT_CORE_SRCS = glob(["src/main/java/**/*.java"]) NVCT_CORE_TEST_SRCS = glob(["src/test/java/**/*.java"]) NVCT_CORE_TEST_RESOURCES = glob(["src/test/resources/**"]) + [ - "//:integration_local_env_files", + "//src/control-plane-services/cloud-tasks:integration_local_env_files", ] proto_library( name = "nvct_proto", srcs = ["src/main/proto/nvct.proto"], - deps = ["@protobuf//:timestamp_proto"], + deps = ["@com_google_protobuf//:timestamp_proto"], ) nvct_java_grpc_compile( @@ -63,13 +63,13 @@ nvct_library( "@nv_third_party_deps//:com_google_guava_guava", "@nv_third_party_deps//:com_google_protobuf_protobuf_java", "@nv_third_party_deps//:com_nimbusds_oauth2_oidc_sdk", - "@nv_boot_parent//nv-boot-starter-audit:nv_boot_starter_audit", - "@nv_boot_parent//nv-boot-starter-cassandra:nv_boot_starter_cassandra", - "@nv_boot_parent//nv-boot-starter-core:nv_boot_starter_core", - "@nv_boot_parent//nv-boot-starter-exceptions:nv_boot_starter_exceptions", - "@nv_boot_parent//nv-boot-starter-observability:nv_boot_starter_observability", - "@nv_boot_parent//nv-boot-starter-registries:nv_boot_starter_registries", - "@nv_boot_parent//nv-boot-starter-reloadable-properties:nv_boot_starter_reloadable_properties", + "//src/libraries/java/nv-boot-parent/nv-boot-starter-audit:nv_boot_starter_audit", + "//src/libraries/java/nv-boot-parent/nv-boot-starter-cassandra:nv_boot_starter_cassandra", + "//src/libraries/java/nv-boot-parent/nv-boot-starter-core:nv_boot_starter_core", + "//src/libraries/java/nv-boot-parent/nv-boot-starter-exceptions:nv_boot_starter_exceptions", + "//src/libraries/java/nv-boot-parent/nv-boot-starter-observability:nv_boot_starter_observability", + "//src/libraries/java/nv-boot-parent/nv-boot-starter-registries:nv_boot_starter_registries", + "//src/libraries/java/nv-boot-parent/nv-boot-starter-reloadable-properties:nv_boot_starter_reloadable_properties", "@nv_third_party_deps//:io_grpc_grpc_api", "@nv_third_party_deps//:io_grpc_grpc_netty_shaded", "@nv_third_party_deps//:io_grpc_grpc_stub", @@ -148,13 +148,13 @@ NVCT_CORE_TEST_DEPS = [ "@nv_third_party_deps//:com_google_guava_guava", "@nv_third_party_deps//:com_google_protobuf_protobuf_java", "@nv_third_party_deps//:com_nimbusds_nimbus_jose_jwt", - "@nv_boot_parent//nv-boot-mock-servers-test:nv_boot_mock_servers_test", - "@nv_boot_parent//nv-boot-starter-audit:nv_boot_starter_audit", - "@nv_boot_parent//nv-boot-starter-core:nv_boot_starter_core", - "@nv_boot_parent//nv-boot-starter-exceptions:nv_boot_starter_exceptions", - "@nv_boot_parent//nv-boot-starter-observability:nv_boot_starter_observability", - "@nv_boot_parent//nv-boot-starter-registries:nv_boot_starter_registries", - "@nv_boot_parent//nv-boot-starter-reloadable-properties:nv_boot_starter_reloadable_properties", + "//src/libraries/java/nv-boot-parent/nv-boot-mock-servers-test:nv_boot_mock_servers_test", + "//src/libraries/java/nv-boot-parent/nv-boot-starter-audit:nv_boot_starter_audit", + "//src/libraries/java/nv-boot-parent/nv-boot-starter-core:nv_boot_starter_core", + "//src/libraries/java/nv-boot-parent/nv-boot-starter-exceptions:nv_boot_starter_exceptions", + "//src/libraries/java/nv-boot-parent/nv-boot-starter-observability:nv_boot_starter_observability", + "//src/libraries/java/nv-boot-parent/nv-boot-starter-registries:nv_boot_starter_registries", + "//src/libraries/java/nv-boot-parent/nv-boot-starter-reloadable-properties:nv_boot_starter_reloadable_properties", "@nv_third_party_deps//:io_grpc_grpc_api", "@nv_third_party_deps//:io_grpc_grpc_stub", "@nv_third_party_deps//:io_micrometer_micrometer_core", @@ -213,7 +213,7 @@ nvct_library_test( srcs = NVCT_CORE_TEST_SRCS, deps = NVCT_CORE_TEST_DEPS, data = [ - "//:integration_local_env", + "//src/control-plane-services/cloud-tasks:integration_local_env", ], # Spring Framework 7 pauses cached contexts when switching configurations. # The embedded gRPC server cannot reliably rebind its random port during diff --git a/src/control-plane-services/cloud-tasks/nvct-service/BUILD.bazel b/src/control-plane-services/cloud-tasks/nvct-service/BUILD.bazel index d27aab763..5b07d030b 100644 --- a/src/control-plane-services/cloud-tasks/nvct-service/BUILD.bazel +++ b/src/control-plane-services/cloud-tasks/nvct-service/BUILD.bazel @@ -1,5 +1,5 @@ -load("//tools/bazel:java.bzl", "nvct_library", "nvct_library_test") -load("//tools/bazel:spring_boot.bzl", "spring_boot_app") +load("//rules/java:defs.bzl", "nvct_library", "nvct_library_test") +load("//rules/java:spring.bzl", "spring_boot_app") package(default_visibility = ["//visibility:public"]) @@ -10,11 +10,11 @@ NVCT_SERVICE_RESOURCES = glob(["src/main/resources/**"]) NVCT_SERVICE_TEST_SRCS = glob(["src/test/java/**/*.java"]) NVCT_SERVICE_TEST_RESOURCES = glob(["src/test/resources/**"]) + [ - "//:integration_local_env_files", + "//src/control-plane-services/cloud-tasks:integration_local_env_files", ] NVCT_SERVICE_DEPS = [ - "//nvct-core:nvct_core", + "//src/control-plane-services/cloud-tasks/nvct-core:nvct_core", "@nv_third_party_deps//:org_slf4j_slf4j_api", "@nv_third_party_deps//:org_springframework_boot_spring_boot", "@nv_third_party_deps//:org_springframework_boot_spring_boot_autoconfigure", @@ -27,7 +27,7 @@ nvct_library( name = "app_classes", srcs = NVCT_SERVICE_SRCS, deps = NVCT_SERVICE_DEPS, - resource_strip_prefix = "nvct-service/src/main/resources", + resource_strip_prefix = "src/control-plane-services/cloud-tasks/nvct-service/src/main/resources", resources = NVCT_SERVICE_RESOURCES, visibility = ["//visibility:private"], ) @@ -49,9 +49,9 @@ nvct_library_test( srcs = NVCT_SERVICE_TEST_SRCS, deps = [ ":app_classes", - "//nvct-core:nvct_core", - "//nvct-core:nvct_core_test_fixtures", - "@nv_boot_parent//nv-boot-mock-servers-test:nv_boot_mock_servers_test", + "//src/control-plane-services/cloud-tasks/nvct-core:nvct_core", + "//src/control-plane-services/cloud-tasks/nvct-core:nvct_core_test_fixtures", + "//src/libraries/java/nv-boot-parent/nv-boot-mock-servers-test:nv_boot_mock_servers_test", "@nv_third_party_deps//:io_opentelemetry_opentelemetry_sdk_testing", "@nv_third_party_deps//:org_springframework_boot_spring_boot", "@nv_third_party_deps//:org_springframework_boot_spring_boot_restclient", @@ -65,7 +65,7 @@ nvct_library_test( "@nv_third_party_deps//:org_testcontainers_testcontainers_cassandra", ], data = [ - "//:integration_local_env", + "//src/control-plane-services/cloud-tasks:integration_local_env", ], resources = NVCT_SERVICE_TEST_RESOURCES, tags = [ diff --git a/src/control-plane-services/cloud-tasks/tools/bazel/java.bzl b/src/control-plane-services/cloud-tasks/tools/bazel/java.bzl deleted file mode 100644 index dc0f99500..000000000 --- a/src/control-plane-services/cloud-tasks/tools/bazel/java.bzl +++ /dev/null @@ -1,177 +0,0 @@ -load("@rules_java//java:defs.bzl", _java_binary = "java_binary", _java_library = "java_library") -load("@rules_shell//shell:sh_test.bzl", _sh_test = "sh_test") - -NVCT_JAVACOPTS = [ - "--release", - "25", - "-Xep:CheckReturnValue:OFF", - "-Xep:ImpossibleNullComparison:OFF", - "-Xep:OptionalOfRedundantMethod:OFF", - "-Xlint:deprecation", -] - -NVCT_LOMBOK_COMPILE_DEPS = [ - "//tools/bazel:lombok_annotations", -] - -NVCT_LOMBOK_PLUGINS = [ - "//tools/bazel:lombok_plugin", -] - -NVCT_JUNIT_ARGS = [ - "execute", - "--details=flat", - "--disable-ansi-colors", - "--details-theme=ascii", - "--include-classname=.*(Test|IntegrationTest)", - "--fail-if-no-tests", -] - -NVCT_JUNIT_COMPILE_DEPS = [ - "@nv_third_party_deps//:org_assertj_assertj_core", - "@nv_third_party_deps//:org_junit_jupiter_junit_jupiter_api", - "@nv_third_party_deps//:org_junit_jupiter_junit_jupiter_params", - "@nv_third_party_deps//:org_mockito_mockito_core", - "@nv_third_party_deps//:org_mockito_mockito_junit_jupiter", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_test", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_test_autoconfigure", - "@nv_third_party_deps//:org_springframework_spring_test", -] - -NVCT_JUNIT_RUNTIME_DEPS = [ - "@nv_third_party_deps//:org_junit_platform_junit_platform_console_standalone", -] - -NVCT_MOCKITO_CORE = "@nv_third_party_deps//:org_mockito_mockito_core" - -NVCT_JACOCO_AGENT = "@nv_third_party_deps//:org_jacoco_org_jacoco_agent_runtime" - -NVCT_JACOCO_JVM_FLAGS = [ - ( - "-javaagent:$(location %s)=destfile=jacoco.exec,append=false," - + "dumponexit=true,includes=com.nvidia.*" - ) % NVCT_JACOCO_AGENT, -] - -def _unique(values): - seen = {} - result = [] - for value in values: - if value not in seen: - seen[value] = True - result.append(value) - return result - -def _nvct_workspace_runfiles_impl(ctx): - symlinks = {} - strip_prefix = ctx.attr.strip_prefix - - for src in ctx.files.srcs: - runfiles_path = src.short_path - if strip_prefix: - if not runfiles_path.startswith(strip_prefix): - fail("Expected %s to start with strip_prefix %s" % (runfiles_path, strip_prefix)) - runfiles_path = runfiles_path[len(strip_prefix):] - - if runfiles_path in symlinks: - fail("Duplicate runfiles path: %s" % runfiles_path) - symlinks[runfiles_path] = src - - return [DefaultInfo(runfiles = ctx.runfiles(symlinks = symlinks))] - -nvct_workspace_runfiles = rule( - implementation = _nvct_workspace_runfiles_impl, - attrs = { - "srcs": attr.label_list(allow_files = True), - "strip_prefix": attr.string(), - }, -) - -def nvct_library( - name, - srcs, - deps = [], - resources = [], - runtime_deps = [], - visibility = None, - resource_strip_prefix = ""): - _java_library( - name = name, - srcs = srcs, - deps = deps + NVCT_LOMBOK_COMPILE_DEPS, - javacopts = NVCT_JAVACOPTS, - plugins = NVCT_LOMBOK_PLUGINS, - resources = resources, - resource_strip_prefix = resource_strip_prefix, - runtime_deps = runtime_deps, - visibility = visibility, - ) - -def nvct_library_test( - name, - deps, - coverage_library, - data = [], - jvm_flags = [], - resources = [], - runtime_deps = [], - size = "large", - srcs = [], - tags = [], - timeout = "long", - visibility = None): - if type(coverage_library) != "string" or not coverage_library.startswith(":"): - fail( - "coverage_library must be the module library target as a local " - + "label starting with ':'", - ) - - coverage_sourcefiles = native.glob(["src/main/java/**/*.java"]) - coverage_source_root = native.package_name() + "/src/main/java" - junit_runner = name + "_junit_runner" - - _java_binary( - name = junit_runner, - srcs = srcs, - data = _unique(data + [ - NVCT_JACOCO_AGENT, - NVCT_MOCKITO_CORE, - ]), - deps = _unique(deps + NVCT_LOMBOK_COMPILE_DEPS + NVCT_JUNIT_COMPILE_DEPS), - javacopts = NVCT_JAVACOPTS, - jvm_flags = NVCT_JACOCO_JVM_FLAGS + [ - "-javaagent:$(location %s)" % NVCT_MOCKITO_CORE, - ] + jvm_flags, - main_class = "org.junit.platform.console.ConsoleLauncher", - plugins = NVCT_LOMBOK_PLUGINS, - resources = resources, - runtime_deps = runtime_deps + NVCT_JUNIT_RUNTIME_DEPS, - tags = ["manual"], - testonly = True, - visibility = ["//visibility:private"], - ) - - _sh_test( - name = name, - srcs = ["//tools/bazel:jacoco_test_runner.sh"], - args = [ - "$(location :%s)" % junit_runner, - "$(location %s)" % coverage_library, - coverage_source_root if coverage_sourcefiles else "", - native.package_name(), - "$(location //tools/bazel:jacoco_cli)", - ] + NVCT_JUNIT_ARGS + [ - "--class-path=$(location :%s.jar)" % junit_runner, - "--scan-classpath=$(location :%s.jar)" % junit_runner, - ], - data = _unique([ - ":" + junit_runner, - ":%s.jar" % junit_runner, - coverage_library, - "//tools/bazel:jacoco_cli", - ] + coverage_sourcefiles), - size = size, - tags = tags, - timeout = timeout, - visibility = visibility, - ) diff --git a/src/control-plane-services/cloud-tasks/tools/bazel/notice_check_test.sh b/src/control-plane-services/cloud-tasks/tools/bazel/notice_check_test.sh deleted file mode 100755 index 49256c3ef..000000000 --- a/src/control-plane-services/cloud-tasks/tools/bazel/notice_check_test.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -runfiles_root="${TEST_SRCDIR:?TEST_SRCDIR is not set}" -workspace="${runfiles_root}/_main" - -generator="$(find "${runfiles_root}" -path '*/tools/bazel/generate_notice.py' -print -quit)" -runtime_jar="$(find "${runfiles_root}" -path '*/nvct-service/app.jar' -print -quit)" - -if [[ -z "${generator}" || -z "${runtime_jar}" ]]; then - printf 'Could not locate NOTICE generator or app.jar in test runfiles\n' >&2 - exit 1 -fi - -exec python3 "${generator}" \ - --maven-install "${workspace}/maven_install.json" \ - --metadata "${workspace}/tools/bazel/notice_metadata.json" \ - --notice "${workspace}/NOTICE" \ - --runtime-jar "${runtime_jar}" \ - --first-party-group com.nvidia.nvct \ - --check diff --git a/src/control-plane-services/cloud-tasks/tools/bazel/workspace_status.sh b/src/control-plane-services/cloud-tasks/tools/bazel/workspace_status.sh deleted file mode 100755 index fe655c43e..000000000 --- a/src/control-plane-services/cloud-tasks/tools/bazel/workspace_status.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/usr/bin/env bash -set -eu - -if git rev-parse --is-inside-work-tree >/dev/null 2>&1; then - full_commit="$(git rev-parse HEAD)" - abbrev_commit="$(git rev-parse --short=7 HEAD)" - tags="$(git tag --points-at HEAD | paste -sd, -)" - closest_tag="$(git describe --tags --abbrev=0 2>/dev/null || true)" -else - full_commit="unknown" - abbrev_commit="unknown" - tags="" - closest_tag="" -fi - -printf 'STABLE_GIT_COMMIT_ID_FULL %s\n' "${full_commit}" -printf 'STABLE_GIT_COMMIT_ID_ABBREV %s\n' "${abbrev_commit}" -printf 'STABLE_GIT_TAGS %s\n' "${tags}" -printf 'STABLE_GIT_CLOSEST_TAG_NAME %s\n' "${closest_tag}" -printf 'STABLE_BUILD_VERSION %s\n' "${NEXT_VERSION:-0.0.1-SNAPSHOT}" diff --git a/src/libraries/java/nv-boot-parent/.bazelrc b/src/libraries/java/nv-boot-parent/.bazelrc deleted file mode 100644 index d63d1b9a9..000000000 --- a/src/libraries/java/nv-boot-parent/.bazelrc +++ /dev/null @@ -1,9 +0,0 @@ -build --enable_bzlmod -build --java_language_version=25 -build --tool_java_language_version=25 -build --java_runtime_version=local_jdk -build --tool_java_runtime_version=local_jdk -build --java_header_compilation=false -build --javacopt=-Xlint:deprecation - -test --test_output=errors diff --git a/src/libraries/java/nv-boot-parent/.bazelversion b/src/libraries/java/nv-boot-parent/.bazelversion deleted file mode 100644 index 44931da26..000000000 --- a/src/libraries/java/nv-boot-parent/.bazelversion +++ /dev/null @@ -1 +0,0 @@ -9.1.1 diff --git a/src/libraries/java/nv-boot-parent/BUILD.bazel b/src/libraries/java/nv-boot-parent/BUILD.bazel index bc2af9c2a..17f61bf3c 100644 --- a/src/libraries/java/nv-boot-parent/BUILD.bazel +++ b/src/libraries/java/nv-boot-parent/BUILD.bazel @@ -1,26 +1,29 @@ package(default_visibility = ["//visibility:public"]) +# NOTICE and its generator inputs are owned by this subtree. The third-party +# artifact lock is the single root //:maven_install.json; the generation +# algorithm is the root-owned //tools/bazel/java:generate_notice_tool. exports_files([ - "maven_install.json", - "MODULE.bazel", "NOTICE", + "notice_metadata.json", + "notice_roots.json", ]) genrule( name = "third_party_notice", srcs = [ - ":maven_install.json", - "//tools/bazel:notice_metadata.json", - "//tools/bazel:notice_roots.json", + "//:maven_install.json", + ":notice_metadata.json", + ":notice_roots.json", ], - tools = ["//tools/bazel:generate_notice_tool"], + tools = ["//tools/bazel/java:generate_notice_tool"], outs = ["THIRD_PARTY_NOTICE"], cmd = """ set -eu -"$(execpath //tools/bazel:generate_notice_tool)" \ - --maven-install "$(location :maven_install.json)" \ - --metadata "$(location //tools/bazel:notice_metadata.json)" \ - --root-manifest "$(location //tools/bazel:notice_roots.json)" \ +"$(execpath //tools/bazel/java:generate_notice_tool)" \ + --maven-install "$(location //:maven_install.json)" \ + --metadata "$(location :notice_metadata.json)" \ + --root-manifest "$(location :notice_roots.json)" \ --output "$@" \ --write """, @@ -29,11 +32,11 @@ set -eu genrule( name = "generate_notice", srcs = [ - ":maven_install.json", - "//tools/bazel:notice_metadata.json", - "//tools/bazel:notice_roots.json", + "//:maven_install.json", + ":notice_metadata.json", + ":notice_roots.json", ], - tools = ["//tools/bazel:generate_notice_tool"], + tools = ["//tools/bazel/java:generate_notice_tool"], outs = ["generate_notice.sh"], cmd = """ cat > "$@" <<'EOF' @@ -41,11 +44,12 @@ cat > "$@" <<'EOF' set -euo pipefail workspace="$${BUILD_WORKSPACE_DIRECTORY:-$$(pwd)}" -exec "$(execpath //tools/bazel:generate_notice_tool)" \ - --maven-install "$(location :maven_install.json)" \ - --metadata "$${workspace}/tools/bazel/notice_metadata.json" \ - --notice "$${workspace}/NOTICE" \ - --root-manifest "$(location //tools/bazel:notice_roots.json)" \ +service="$${workspace}/src/libraries/java/nv-boot-parent" +exec "$(execpath //tools/bazel/java:generate_notice_tool)" \ + --maven-install "$${workspace}/maven_install.json" \ + --metadata "$${service}/notice_metadata.json" \ + --notice "$${service}/NOTICE" \ + --root-manifest "$${service}/notice_roots.json" \ "$$@" EOF chmod +x "$@" diff --git a/src/libraries/java/nv-boot-parent/MODULE.bazel b/src/libraries/java/nv-boot-parent/MODULE.bazel deleted file mode 100644 index 3bbbf6245..000000000 --- a/src/libraries/java/nv-boot-parent/MODULE.bazel +++ /dev/null @@ -1,105 +0,0 @@ -module(name = "nv_boot_parent") - -bazel_dep(name = "rules_jvm_external", version = "7.0") -bazel_dep(name = "rules_java", version = "9.3.0") -bazel_dep(name = "rules_python", version = "1.7.0") -bazel_dep(name = "rules_shell", version = "0.8.0") - -maven = use_extension("@rules_jvm_external//:extensions.bzl", "maven") -maven.install( - name = "nv_third_party_deps", - # Keep this list to root coordinates: BOM-managed starters/modules, parent-owned - # explicit pins, and build/test tools. This file is the source of truth for - # Bazel/Coursier dependency resolution and explicit version pins. Generated - # publication metadata reads versions from here rather than owning a separate - # version map. - # BUILD files may still reference transitive labels when source code imports - # those classes. - artifacts = [ - # Security override example: - # Maven property overrides from spring-boot-dependencies, such as - # tomcat.version, become explicit artifact pins in Bazel. If a Tomcat - # CVE fix is available before Spring Boot imports it, temporarily add - # the concrete Tomcat artifacts with the fixed version: - # - # "org.apache.tomcat.embed:tomcat-embed-core:<fixed-version>", - # "org.apache.tomcat.embed:tomcat-embed-el:<fixed-version>", - # "org.apache.tomcat.embed:tomcat-embed-websocket:<fixed-version>", - # - # Then repin and test: - # export BAZEL_OUTPUT_USER_ROOT="${TMPDIR:-/tmp}/nv-boot-parent-bazel-cache" - # REPIN=1 bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" run @nv_third_party_deps//:pin - # bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" test //... - # - # Remove the explicit pins once the imported Spring Boot BOM manages - # the fixed version. - "at.yawk.lz4:lz4-java:1.10.3", - "com.github.ben-manes.caffeine:guava", - "com.github.java-json-tools:json-patch:1.13", - "commons-codec:commons-codec", - "io.cloudevents:cloudevents-core:4.1.1", - "io.cloudevents:cloudevents-json-jackson:4.1.1", - "io.micrometer:micrometer-tracing-bridge-otel", - "io.nats:jnats:2.23.0", - "io.opentelemetry:opentelemetry-exporter-otlp", - "io.opentelemetry:opentelemetry-sdk-testing", - "jakarta.servlet:jakarta.servlet-api", - "org.apache.cassandra:java-driver-metrics-micrometer", - "org.apache.commons:commons-lang3:3.20.0", - "org.bouncycastle:bcprov-jdk18on:1.84", - "org.jacoco:org.jacoco.agent:jar:runtime:0.8.14", - "org.jacoco:org.jacoco.cli:0.8.14", - "org.junit.platform:junit-platform-console-standalone:6.0.3", - # JaCoCo resolves asm, asm-commons, and asm-tree to 9.9 in the shared - # hub, while jnr-ffi otherwise leaves these two modules at 5.0.3. - # Keep the ASM family aligned so production and test tooling do not - # share a partially upgraded runtime graph. - "org.ow2.asm:asm-analysis:9.9", - "org.ow2.asm:asm-util:9.9", - "org.projectlombok:lombok", - "org.springdoc:springdoc-openapi-starter-webflux-api:3.0.3", - "org.springdoc:springdoc-openapi-starter-webmvc-api:3.0.3", - "org.springframework.boot:spring-boot-micrometer-tracing-opentelemetry", - "org.springframework.boot:spring-boot-restclient", - "org.springframework.boot:spring-boot-starter", - "org.springframework.boot:spring-boot-starter-actuator", - "org.springframework.boot:spring-boot-starter-actuator-test", - "org.springframework.boot:spring-boot-starter-data-cassandra", - "org.springframework.boot:spring-boot-starter-data-cassandra-test", - "org.springframework.boot:spring-boot-starter-jackson", - "org.springframework.boot:spring-boot-starter-security-oauth2-client", - "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server", - "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server-test", - "org.springframework.boot:spring-boot-starter-test", - "org.springframework.boot:spring-boot-starter-validation", - "org.springframework.boot:spring-boot-starter-webflux", - "org.springframework.boot:spring-boot-starter-webflux-test", - "org.springframework.boot:spring-boot-starter-webmvc-test", - "org.springframework.boot:spring-boot-webclient", - "org.springframework.cloud:spring-cloud-commons", - "org.springframework.cloud:spring-cloud-context", - "org.springframework.cloud:spring-cloud-starter-bootstrap", - "org.springframework.security:spring-security-test", - "org.testcontainers:testcontainers-cassandra", - "org.testcontainers:testcontainers-junit-jupiter", - "org.wiremock:wiremock-standalone:3.13.2", - "software.amazon.awssdk:regions:2.40.1", - "tools.jackson.module:jackson-module-blackbird", - ], - boms = [ - "net.javacrumbs.shedlock:shedlock-bom:7.7.0", - "org.springframework.boot:spring-boot-dependencies:4.0.7", - "org.springframework.cloud:spring-cloud-dependencies:2025.1.2", - "org.testcontainers:testcontainers-bom:2.0.5", - ], - fail_on_missing_checksum = True, - fetch_sources = True, - known_contributing_modules = ["protobuf"], - lock_file = "//:maven_install.json", - repositories = [ - "https://maven-central.storage-download.googleapis.com/maven2", - "https://repo.maven.apache.org/maven2", - ], - resolver = "maven", -) -use_repo(maven, "nv_third_party_deps") diff --git a/src/libraries/java/nv-boot-parent/MODULE.bazel.lock b/src/libraries/java/nv-boot-parent/MODULE.bazel.lock deleted file mode 100644 index 480155120..000000000 --- a/src/libraries/java/nv-boot-parent/MODULE.bazel.lock +++ /dev/null @@ -1,808 +0,0 @@ -{ - "lockFileVersion": 26, - "registryFileHashes": { - "https://bcr.bazel.build/bazel_registry.json": "8a28e4aff06ee60aed2a8c281907fb8bcbf3b753c91fb5a5c57da3215d5b3497", - "https://bcr.bazel.build/modules/abseil-cpp/20210324.2/MODULE.bazel": "7cd0312e064fde87c8d1cd79ba06c876bd23630c83466e9500321be55c96ace2", - "https://bcr.bazel.build/modules/abseil-cpp/20211102.0/MODULE.bazel": "70390338f7a5106231d20620712f7cccb659cd0e9d073d1991c038eb9fc57589", - "https://bcr.bazel.build/modules/abseil-cpp/20230125.1/MODULE.bazel": "89047429cb0207707b2dface14ba7f8df85273d484c2572755be4bab7ce9c3a0", - "https://bcr.bazel.build/modules/abseil-cpp/20230802.0.bcr.1/MODULE.bazel": "1c8cec495288dccd14fdae6e3f95f772c1c91857047a098fad772034264cc8cb", - "https://bcr.bazel.build/modules/abseil-cpp/20230802.0/MODULE.bazel": "d253ae36a8bd9ee3c5955384096ccb6baf16a1b1e93e858370da0a3b94f77c16", - "https://bcr.bazel.build/modules/abseil-cpp/20230802.1/MODULE.bazel": "fa92e2eb41a04df73cdabeec37107316f7e5272650f81d6cc096418fe647b915", - "https://bcr.bazel.build/modules/abseil-cpp/20240116.1/MODULE.bazel": "37bcdb4440fbb61df6a1c296ae01b327f19e9bb521f9b8e26ec854b6f97309ed", - "https://bcr.bazel.build/modules/abseil-cpp/20240116.2/MODULE.bazel": "73939767a4686cd9a520d16af5ab440071ed75cec1a876bf2fcfaf1f71987a16", - "https://bcr.bazel.build/modules/abseil-cpp/20250127.0/MODULE.bazel": "d1086e248cda6576862b4b3fe9ad76a214e08c189af5b42557a6e1888812c5d5", - "https://bcr.bazel.build/modules/abseil-cpp/20250127.1/MODULE.bazel": "c4a89e7ceb9bf1e25cf84a9f830ff6b817b72874088bf5141b314726e46a57c1", - "https://bcr.bazel.build/modules/abseil-cpp/20250512.1/MODULE.bazel": "d209fdb6f36ffaf61c509fcc81b19e81b411a999a934a032e10cd009a0226215", - "https://bcr.bazel.build/modules/abseil-cpp/20250814.1/MODULE.bazel": "51f2312901470cdab0dbdf3b88c40cd21c62a7ed58a3de45b365ddc5b11bcab2", - "https://bcr.bazel.build/modules/abseil-cpp/20250814.1/source.json": "cea3901d7e299da7320700abbaafe57a65d039f10d0d7ea601c4a66938ea4b0c", - "https://bcr.bazel.build/modules/abseil-py/2.1.0/MODULE.bazel": "5ebe5bf853769c65707e5c28f216798f7a4b1042015e6a36e6d03094d94bec8a", - "https://bcr.bazel.build/modules/abseil-py/2.1.0/source.json": "0e8fc4f088ce07099c1cd6594c20c7ddbb48b4b3c0849b7d94ba94be88ff042b", - "https://bcr.bazel.build/modules/apple_support/1.11.1/MODULE.bazel": "1843d7cd8a58369a444fc6000e7304425fba600ff641592161d9f15b179fb896", - "https://bcr.bazel.build/modules/apple_support/1.15.1/MODULE.bazel": "a0556fefca0b1bb2de8567b8827518f94db6a6e7e7d632b4c48dc5f865bc7c85", - "https://bcr.bazel.build/modules/apple_support/1.21.0/MODULE.bazel": "ac1824ed5edf17dee2fdd4927ada30c9f8c3b520be1b5fd02a5da15bc10bff3e", - "https://bcr.bazel.build/modules/apple_support/1.21.1/MODULE.bazel": "5809fa3efab15d1f3c3c635af6974044bac8a4919c62238cce06acee8a8c11f1", - "https://bcr.bazel.build/modules/apple_support/1.24.2/MODULE.bazel": "0e62471818affb9f0b26f128831d5c40b074d32e6dda5a0d3852847215a41ca4", - "https://bcr.bazel.build/modules/apple_support/1.24.2/source.json": "2c22c9827093250406c5568da6c54e6fdf0ef06238def3d99c71b12feb057a8d", - "https://bcr.bazel.build/modules/bazel_features/1.1.0/MODULE.bazel": "cfd42ff3b815a5f39554d97182657f8c4b9719568eb7fded2b9135f084bf760b", - "https://bcr.bazel.build/modules/bazel_features/1.1.1/MODULE.bazel": "27b8c79ef57efe08efccbd9dd6ef70d61b4798320b8d3c134fd571f78963dbcd", - "https://bcr.bazel.build/modules/bazel_features/1.10.0/MODULE.bazel": "f75e8807570484a99be90abcd52b5e1f390362c258bcb73106f4544957a48101", - "https://bcr.bazel.build/modules/bazel_features/1.11.0/MODULE.bazel": "f9382337dd5a474c3b7d334c2f83e50b6eaedc284253334cf823044a26de03e8", - "https://bcr.bazel.build/modules/bazel_features/1.13.0/MODULE.bazel": "c14c33c7c3c730612bdbe14ebbb5e61936b6f11322ea95a6e91cd1ba962f94df", - "https://bcr.bazel.build/modules/bazel_features/1.15.0/MODULE.bazel": "d38ff6e517149dc509406aca0db3ad1efdd890a85e049585b7234d04238e2a4d", - "https://bcr.bazel.build/modules/bazel_features/1.17.0/MODULE.bazel": "039de32d21b816b47bd42c778e0454217e9c9caac4a3cf8e15c7231ee3ddee4d", - "https://bcr.bazel.build/modules/bazel_features/1.18.0/MODULE.bazel": "1be0ae2557ab3a72a57aeb31b29be347bcdc5d2b1eb1e70f39e3851a7e97041a", - "https://bcr.bazel.build/modules/bazel_features/1.19.0/MODULE.bazel": "59adcdf28230d220f0067b1f435b8537dd033bfff8db21335ef9217919c7fb58", - "https://bcr.bazel.build/modules/bazel_features/1.21.0/MODULE.bazel": "675642261665d8eea09989aa3b8afb5c37627f1be178382c320d1b46afba5e3b", - "https://bcr.bazel.build/modules/bazel_features/1.23.0/MODULE.bazel": "fd1ac84bc4e97a5a0816b7fd7d4d4f6d837b0047cf4cbd81652d616af3a6591a", - "https://bcr.bazel.build/modules/bazel_features/1.25.0/MODULE.bazel": "e2e60a10a6da64bbf533f15ca652bf61a033e41c2ed734d79a9a08ba87f68c1a", - "https://bcr.bazel.build/modules/bazel_features/1.27.0/MODULE.bazel": "621eeee06c4458a9121d1f104efb80f39d34deff4984e778359c60eaf1a8cb65", - "https://bcr.bazel.build/modules/bazel_features/1.28.0/MODULE.bazel": "4b4200e6cbf8fa335b2c3f43e1d6ef3e240319c33d43d60cc0fbd4b87ece299d", - "https://bcr.bazel.build/modules/bazel_features/1.3.0/MODULE.bazel": "cdcafe83ec318cda34e02948e81d790aab8df7a929cec6f6969f13a489ccecd9", - "https://bcr.bazel.build/modules/bazel_features/1.30.0/MODULE.bazel": "a14b62d05969a293b80257e72e597c2da7f717e1e69fa8b339703ed6731bec87", - "https://bcr.bazel.build/modules/bazel_features/1.33.0/MODULE.bazel": "8b8dc9d2a4c88609409c3191165bccec0e4cb044cd7a72ccbe826583303459f6", - "https://bcr.bazel.build/modules/bazel_features/1.4.1/MODULE.bazel": "e45b6bb2350aff3e442ae1111c555e27eac1d915e77775f6fdc4b351b758b5d7", - "https://bcr.bazel.build/modules/bazel_features/1.42.1/MODULE.bazel": "275a59b5406ff18c01739860aa70ad7ccb3cfb474579411decca11c93b951080", - "https://bcr.bazel.build/modules/bazel_features/1.42.1/source.json": "fcd4396b2df85f64f2b3bb436ad870793ecf39180f1d796f913cc9276d355309", - "https://bcr.bazel.build/modules/bazel_features/1.9.0/MODULE.bazel": "885151d58d90d8d9c811eb75e3288c11f850e1d6b481a8c9f766adee4712358b", - "https://bcr.bazel.build/modules/bazel_features/1.9.1/MODULE.bazel": "8f679097876a9b609ad1f60249c49d68bfab783dd9be012faf9d82547b14815a", - "https://bcr.bazel.build/modules/bazel_lib/3.0.0/MODULE.bazel": "22b70b80ac89ad3f3772526cd9feee2fa412c2b01933fea7ed13238a448d370d", - "https://bcr.bazel.build/modules/bazel_lib/3.0.0/source.json": "895f21909c6fba01d7c17914bb6c8e135982275a1b18cdaa4e62272217ef1751", - "https://bcr.bazel.build/modules/bazel_skylib/1.0.3/MODULE.bazel": "bcb0fd896384802d1ad283b4e4eb4d718eebd8cb820b0a2c3a347fb971afd9d8", - "https://bcr.bazel.build/modules/bazel_skylib/1.1.1/MODULE.bazel": "1add3e7d93ff2e6998f9e118022c84d163917d912f5afafb3058e3d2f1545b5e", - "https://bcr.bazel.build/modules/bazel_skylib/1.2.0/MODULE.bazel": "44fe84260e454ed94ad326352a698422dbe372b21a1ac9f3eab76eb531223686", - "https://bcr.bazel.build/modules/bazel_skylib/1.2.1/MODULE.bazel": "f35baf9da0efe45fa3da1696ae906eea3d615ad41e2e3def4aeb4e8bc0ef9a7a", - "https://bcr.bazel.build/modules/bazel_skylib/1.3.0/MODULE.bazel": "20228b92868bf5cfc41bda7afc8a8ba2a543201851de39d990ec957b513579c5", - "https://bcr.bazel.build/modules/bazel_skylib/1.4.1/MODULE.bazel": "a0dcb779424be33100dcae821e9e27e4f2901d9dfd5333efe5ac6a8d7ab75e1d", - "https://bcr.bazel.build/modules/bazel_skylib/1.4.2/MODULE.bazel": "3bd40978e7a1fac911d5989e6b09d8f64921865a45822d8b09e815eaa726a651", - "https://bcr.bazel.build/modules/bazel_skylib/1.5.0/MODULE.bazel": "32880f5e2945ce6a03d1fbd588e9198c0a959bb42297b2cfaf1685b7bc32e138", - "https://bcr.bazel.build/modules/bazel_skylib/1.6.1/MODULE.bazel": "8fdee2dbaace6c252131c00e1de4b165dc65af02ea278476187765e1a617b917", - "https://bcr.bazel.build/modules/bazel_skylib/1.7.0/MODULE.bazel": "0db596f4563de7938de764cc8deeabec291f55e8ec15299718b93c4423e9796d", - "https://bcr.bazel.build/modules/bazel_skylib/1.7.1/MODULE.bazel": "3120d80c5861aa616222ec015332e5f8d3171e062e3e804a2a0253e1be26e59b", - "https://bcr.bazel.build/modules/bazel_skylib/1.8.1/MODULE.bazel": "88ade7293becda963e0e3ea33e7d54d3425127e0a326e0d17da085a5f1f03ff6", - "https://bcr.bazel.build/modules/bazel_skylib/1.8.2/MODULE.bazel": "69ad6927098316848b34a9142bcc975e018ba27f08c4ff403f50c1b6e646ca67", - "https://bcr.bazel.build/modules/bazel_skylib/1.8.2/source.json": "34a3c8bcf233b835eb74be9d628899bb32999d3e0eadef1947a0a562a2b16ffb", - "https://bcr.bazel.build/modules/bazel_worker_api/0.0.1/MODULE.bazel": "02a13b77321773b2042e70ee5e4c5e099c8ddee4cf2da9cd420442c36938d4bd", - "https://bcr.bazel.build/modules/bazel_worker_api/0.0.4/MODULE.bazel": "460aa12d01231a80cce03c548287b433b321d205b0028ae596728c35e5ee442e", - "https://bcr.bazel.build/modules/bazel_worker_api/0.0.8/MODULE.bazel": "396c1ef53835aafe3d42ce6619080531ee770648303731f16cfaa33fa056bf0c", - "https://bcr.bazel.build/modules/bazel_worker_api/0.0.8/source.json": "abaf8ac9d2ab2f47bda9af4c0c080ff7907378888e1f4bc62a0539dd13ba61e8", - "https://bcr.bazel.build/modules/bazel_worker_java/0.0.4/MODULE.bazel": "82494a01018bb7ef06d4a17ec4cd7a758721f10eb8b6c820a818e70d669500db", - "https://bcr.bazel.build/modules/bazel_worker_java/0.0.8/MODULE.bazel": "e76479eae70bd4e8f5f4c2dfc5d03ab971cfb18750246c7b3f3454c5c2ee6629", - "https://bcr.bazel.build/modules/bazel_worker_java/0.0.8/source.json": "9395c4679444bc47bf7e51a710366a4480aa371c6f6bed01868e2fabcf11acec", - "https://bcr.bazel.build/modules/buildozer/8.5.1/MODULE.bazel": "a35d9561b3fc5b18797c330793e99e3b834a473d5fbd3d7d7634aafc9bdb6f8f", - "https://bcr.bazel.build/modules/buildozer/8.5.1/source.json": "e3386e6ff4529f2442800dee47ad28d3e6487f36a1f75ae39ae56c70f0cd2fbd", - "https://bcr.bazel.build/modules/gazelle/0.32.0/MODULE.bazel": "b499f58a5d0d3537f3cf5b76d8ada18242f64ec474d8391247438bf04f58c7b8", - "https://bcr.bazel.build/modules/gazelle/0.33.0/MODULE.bazel": "a13a0f279b462b784fb8dd52a4074526c4a2afe70e114c7d09066097a46b3350", - "https://bcr.bazel.build/modules/gazelle/0.34.0/MODULE.bazel": "abdd8ce4d70978933209db92e436deb3a8b737859e9354fb5fd11fb5c2004c8a", - "https://bcr.bazel.build/modules/gazelle/0.36.0/MODULE.bazel": "e375d5d6e9a6ca59b0cb38b0540bc9a05b6aa926d322f2de268ad267a2ee74c0", - "https://bcr.bazel.build/modules/gazelle/0.40.0/MODULE.bazel": "42ba5378ebe845fca43989a53186ab436d956db498acde790685fe0e8f9c6146", - "https://bcr.bazel.build/modules/gazelle/0.47.0/MODULE.bazel": "b61bb007c4efad134aa30ee7f4a8e2a39b22aa5685f005edaa022fbd1de43ebc", - "https://bcr.bazel.build/modules/gazelle/0.47.0/source.json": "aeb2e5df14b7fb298625d75d08b9c65bdb0b56014c5eb89da9e5dd0572280ae6", - "https://bcr.bazel.build/modules/google_benchmark/1.8.2/MODULE.bazel": "a70cf1bba851000ba93b58ae2f6d76490a9feb74192e57ab8e8ff13c34ec50cb", - "https://bcr.bazel.build/modules/googletest/1.11.0/MODULE.bazel": "3a83f095183f66345ca86aa13c58b59f9f94a2f81999c093d4eeaa2d262d12f4", - "https://bcr.bazel.build/modules/googletest/1.14.0.bcr.1/MODULE.bazel": "22c31a561553727960057361aa33bf20fb2e98584bc4fec007906e27053f80c6", - "https://bcr.bazel.build/modules/googletest/1.14.0/MODULE.bazel": "cfbcbf3e6eac06ef9d85900f64424708cc08687d1b527f0ef65aa7517af8118f", - "https://bcr.bazel.build/modules/googletest/1.15.2/MODULE.bazel": "6de1edc1d26cafb0ea1a6ab3f4d4192d91a312fd2d360b63adaa213cd00b2108", - "https://bcr.bazel.build/modules/googletest/1.17.0/MODULE.bazel": "dbec758171594a705933a29fcf69293d2468c49ec1f2ebca65c36f504d72df46", - "https://bcr.bazel.build/modules/googletest/1.17.0/source.json": "38e4454b25fc30f15439c0378e57909ab1fd0a443158aa35aec685da727cd713", - "https://bcr.bazel.build/modules/jsoncpp/1.9.5/MODULE.bazel": "31271aedc59e815656f5736f282bb7509a97c7ecb43e927ac1a37966e0578075", - "https://bcr.bazel.build/modules/jsoncpp/1.9.6/MODULE.bazel": "2f8d20d3b7d54143213c4dfc3d98225c42de7d666011528dc8fe91591e2e17b0", - "https://bcr.bazel.build/modules/jsoncpp/1.9.6/source.json": "a04756d367a2126c3541682864ecec52f92cdee80a35735a3cb249ce015ca000", - "https://bcr.bazel.build/modules/libpfm/4.11.0/MODULE.bazel": "45061ff025b301940f1e30d2c16bea596c25b176c8b6b3087e92615adbd52902", - "https://bcr.bazel.build/modules/nlohmann_json/3.6.1/MODULE.bazel": "6f7b417dcc794d9add9e556673ad25cb3ba835224290f4f848f8e2db1e1fca74", - "https://bcr.bazel.build/modules/nlohmann_json/3.6.1/source.json": "f448c6e8963fdfa7eb831457df83ad63d3d6355018f6574fb017e8169deb43a9", - "https://bcr.bazel.build/modules/package_metadata/0.0.2/MODULE.bazel": "fb8d25550742674d63d7b250063d4580ca530499f045d70748b1b142081ebb92", - "https://bcr.bazel.build/modules/package_metadata/0.0.3/MODULE.bazel": "77890552ecea9e284b5424c9de827a58099348763a4359e975c359a83d4faa83", - "https://bcr.bazel.build/modules/package_metadata/0.0.5/MODULE.bazel": "ef4f9439e3270fdd6b9fd4dbc3d2f29d13888e44c529a1b243f7a31dfbc2e8e4", - "https://bcr.bazel.build/modules/package_metadata/0.0.7/MODULE.bazel": "7adb03933fc8401f495800cf4eafcff0edc6da0ff55c7db223ef69d19f689486", - "https://bcr.bazel.build/modules/package_metadata/0.0.7/source.json": "50639625e937b56115012674c797cca7a05a96b4878c87d803c13dc2b31de8a0", - "https://bcr.bazel.build/modules/platforms/0.0.10/MODULE.bazel": "8cb8efaf200bdeb2150d93e162c40f388529a25852b332cec879373771e48ed5", - "https://bcr.bazel.build/modules/platforms/0.0.11/MODULE.bazel": "0daefc49732e227caa8bfa834d65dc52e8cc18a2faf80df25e8caea151a9413f", - "https://bcr.bazel.build/modules/platforms/0.0.4/MODULE.bazel": "9b328e31ee156f53f3c416a64f8491f7eb731742655a47c9eec4703a71644aee", - "https://bcr.bazel.build/modules/platforms/0.0.5/MODULE.bazel": "5733b54ea419d5eaf7997054bb55f6a1d0b5ff8aedf0176fef9eea44f3acda37", - "https://bcr.bazel.build/modules/platforms/0.0.6/MODULE.bazel": "ad6eeef431dc52aefd2d77ed20a4b353f8ebf0f4ecdd26a807d2da5aa8cd0615", - "https://bcr.bazel.build/modules/platforms/0.0.7/MODULE.bazel": "72fd4a0ede9ee5c021f6a8dd92b503e089f46c227ba2813ff183b71616034814", - "https://bcr.bazel.build/modules/platforms/0.0.8/MODULE.bazel": "9f142c03e348f6d263719f5074b21ef3adf0b139ee4c5133e2aa35664da9eb2d", - "https://bcr.bazel.build/modules/platforms/0.0.9/MODULE.bazel": "4a87a60c927b56ddd67db50c89acaa62f4ce2a1d2149ccb63ffd871d5ce29ebc", - "https://bcr.bazel.build/modules/platforms/1.0.0/MODULE.bazel": "f05feb42b48f1b3c225e4ccf351f367be0371411a803198ec34a389fb22aa580", - "https://bcr.bazel.build/modules/platforms/1.0.0/source.json": "f4ff1fd412e0246fd38c82328eb209130ead81d62dcd5a9e40910f867f733d96", - "https://bcr.bazel.build/modules/protobuf/21.7/MODULE.bazel": "a5a29bb89544f9b97edce05642fac225a808b5b7be74038ea3640fae2f8e66a7", - "https://bcr.bazel.build/modules/protobuf/23.1/MODULE.bazel": "88b393b3eb4101d18129e5db51847cd40a5517a53e81216144a8c32dfeeca52a", - "https://bcr.bazel.build/modules/protobuf/24.4/MODULE.bazel": "7bc7ce5f2abf36b3b7b7c8218d3acdebb9426aeb35c2257c96445756f970eb12", - "https://bcr.bazel.build/modules/protobuf/27.0/MODULE.bazel": "7873b60be88844a0a1d8f80b9d5d20cfbd8495a689b8763e76c6372998d3f64c", - "https://bcr.bazel.build/modules/protobuf/27.1/MODULE.bazel": "703a7b614728bb06647f965264967a8ef1c39e09e8f167b3ca0bb1fd80449c0d", - "https://bcr.bazel.build/modules/protobuf/27.2/MODULE.bazel": "32450b50673882e4c8c3d10a83f3bc82161b213ed2f80d17e38bece8f165c295", - "https://bcr.bazel.build/modules/protobuf/29.0-rc2.bcr.1/MODULE.bazel": "52f4126f63a2f0bbf36b99c2a87648f08467a4eaf92ba726bc7d6a500bbf770c", - "https://bcr.bazel.build/modules/protobuf/29.0-rc2/MODULE.bazel": "6241d35983510143049943fc0d57937937122baf1b287862f9dc8590fc4c37df", - "https://bcr.bazel.build/modules/protobuf/29.0-rc3/MODULE.bazel": "33c2dfa286578573afc55a7acaea3cada4122b9631007c594bf0729f41c8de92", - "https://bcr.bazel.build/modules/protobuf/29.0/MODULE.bazel": "319dc8bf4c679ff87e71b1ccfb5a6e90a6dbc4693501d471f48662ac46d04e4e", - "https://bcr.bazel.build/modules/protobuf/29.1/MODULE.bazel": "557c3457560ff49e122ed76c0bc3397a64af9574691cb8201b4e46d4ab2ecb95", - "https://bcr.bazel.build/modules/protobuf/29.3/MODULE.bazel": "77480eea5fb5541903e49683f24dc3e09f4a79e0eea247414887bb9fc0066e94", - "https://bcr.bazel.build/modules/protobuf/3.19.0/MODULE.bazel": "6b5fbb433f760a99a22b18b6850ed5784ef0e9928a72668b66e4d7ccd47db9b0", - "https://bcr.bazel.build/modules/protobuf/3.19.2/MODULE.bazel": "532ffe5f2186b69fdde039efe6df13ba726ff338c6bc82275ad433013fa10573", - "https://bcr.bazel.build/modules/protobuf/3.19.6/MODULE.bazel": "9233edc5e1f2ee276a60de3eaa47ac4132302ef9643238f23128fea53ea12858", - "https://bcr.bazel.build/modules/protobuf/31.1/MODULE.bazel": "379a389bb330b7b8c1cdf331cc90bf3e13de5614799b3b52cdb7c6f389f6b38e", - "https://bcr.bazel.build/modules/protobuf/32.1/MODULE.bazel": "89cd2866a9cb07fee9ff74c41ceace11554f32e0d849de4e23ac55515cfada4d", - "https://bcr.bazel.build/modules/protobuf/33.4/MODULE.bazel": "114775b816b38b6d0ca620450d6b02550c60ceedfdc8d9a229833b34a223dc42", - "https://bcr.bazel.build/modules/protobuf/33.4/source.json": "555f8686b4c7d6b5ba731fbea13bf656b4bfd9a7ff629c1d9d3f6e1d6155de79", - "https://bcr.bazel.build/modules/pybind11_bazel/2.11.1/MODULE.bazel": "88af1c246226d87e65be78ed49ecd1e6f5e98648558c14ce99176da041dc378e", - "https://bcr.bazel.build/modules/pybind11_bazel/2.12.0/MODULE.bazel": "e6f4c20442eaa7c90d7190d8dc539d0ab422f95c65a57cc59562170c58ae3d34", - "https://bcr.bazel.build/modules/pybind11_bazel/2.12.0/source.json": "6900fdc8a9e95866b8c0d4ad4aba4d4236317b5c1cd04c502df3f0d33afed680", - "https://bcr.bazel.build/modules/re2/2023-09-01/MODULE.bazel": "cb3d511531b16cfc78a225a9e2136007a48cf8a677e4264baeab57fe78a80206", - "https://bcr.bazel.build/modules/re2/2024-07-02.bcr.1/MODULE.bazel": "b4963dda9b31080be1905ef085ecd7dd6cd47c05c79b9cdf83ade83ab2ab271a", - "https://bcr.bazel.build/modules/re2/2024-07-02.bcr.1/source.json": "2ff292be6ef3340325ce8a045ecc326e92cbfab47c7cbab4bd85d28971b97ac4", - "https://bcr.bazel.build/modules/re2/2024-07-02/MODULE.bazel": "0eadc4395959969297cbcf31a249ff457f2f1d456228c67719480205aa306daa", - "https://bcr.bazel.build/modules/rules_android/0.1.1/MODULE.bazel": "48809ab0091b07ad0182defb787c4c5328bd3a278938415c00a7b69b50c4d3a8", - "https://bcr.bazel.build/modules/rules_android/0.6.4/MODULE.bazel": "b4cde12d506dd65d82b2be39761f49f5797303343a3d5b4ee191c0cdf9ef387c", - "https://bcr.bazel.build/modules/rules_android/0.7.1/MODULE.bazel": "a806fc382a774252f228a40e3b11b9fcc6276f8778c7fb33e9f72937c6258363", - "https://bcr.bazel.build/modules/rules_android/0.7.1/source.json": "151440aed3f0f73a00d4ed5cec5d31f63a6fef9b95d8fab1eb1810150fa525f2", - "https://bcr.bazel.build/modules/rules_apple/3.16.0/MODULE.bazel": "0d1caf0b8375942ce98ea944be754a18874041e4e0459401d925577624d3a54a", - "https://bcr.bazel.build/modules/rules_apple/4.1.0/MODULE.bazel": "76e10fd4a48038d3fc7c5dc6e63b7063bbf5304a2e3bd42edda6ec660eebea68", - "https://bcr.bazel.build/modules/rules_apple/4.1.0/source.json": "8ee81e1708756f81b343a5eb2b2f0b953f1d25c4ab3d4a68dc02754872e80715", - "https://bcr.bazel.build/modules/rules_cc/0.0.1/MODULE.bazel": "cb2aa0747f84c6c3a78dad4e2049c154f08ab9d166b1273835a8174940365647", - "https://bcr.bazel.build/modules/rules_cc/0.0.10/MODULE.bazel": "ec1705118f7eaedd6e118508d3d26deba2a4e76476ada7e0e3965211be012002", - "https://bcr.bazel.build/modules/rules_cc/0.0.13/MODULE.bazel": "0e8529ed7b323dad0775ff924d2ae5af7640b23553dfcd4d34344c7e7a867191", - "https://bcr.bazel.build/modules/rules_cc/0.0.15/MODULE.bazel": "6704c35f7b4a72502ee81f61bf88706b54f06b3cbe5558ac17e2e14666cd5dcc", - "https://bcr.bazel.build/modules/rules_cc/0.0.16/MODULE.bazel": "7661303b8fc1b4d7f532e54e9d6565771fea666fbdf839e0a86affcd02defe87", - "https://bcr.bazel.build/modules/rules_cc/0.0.17/MODULE.bazel": "2ae1d8f4238ec67d7185d8861cb0a2cdf4bc608697c331b95bf990e69b62e64a", - "https://bcr.bazel.build/modules/rules_cc/0.0.2/MODULE.bazel": "6915987c90970493ab97393024c156ea8fb9f3bea953b2f3ec05c34f19b5695c", - "https://bcr.bazel.build/modules/rules_cc/0.0.6/MODULE.bazel": "abf360251023dfe3efcef65ab9d56beefa8394d4176dd29529750e1c57eaa33f", - "https://bcr.bazel.build/modules/rules_cc/0.0.8/MODULE.bazel": "964c85c82cfeb6f3855e6a07054fdb159aced38e99a5eecf7bce9d53990afa3e", - "https://bcr.bazel.build/modules/rules_cc/0.0.9/MODULE.bazel": "836e76439f354b89afe6a911a7adf59a6b2518fafb174483ad78a2a2fde7b1c5", - "https://bcr.bazel.build/modules/rules_cc/0.1.1/MODULE.bazel": "2f0222a6f229f0bf44cd711dc13c858dad98c62d52bd51d8fc3a764a83125513", - "https://bcr.bazel.build/modules/rules_cc/0.1.2/MODULE.bazel": "557ddc3a96858ec0d465a87c0a931054d7dcfd6583af2c7ed3baf494407fd8d0", - "https://bcr.bazel.build/modules/rules_cc/0.1.5/MODULE.bazel": "88dfc9361e8b5ae1008ac38f7cdfd45ad738e4fa676a3ad67d19204f045a1fd8", - "https://bcr.bazel.build/modules/rules_cc/0.2.0/MODULE.bazel": "b5c17f90458caae90d2ccd114c81970062946f49f355610ed89bebf954f5783c", - "https://bcr.bazel.build/modules/rules_cc/0.2.13/MODULE.bazel": "eecdd666eda6be16a8d9dc15e44b5c75133405e820f620a234acc4b1fdc5aa37", - "https://bcr.bazel.build/modules/rules_cc/0.2.14/MODULE.bazel": "353c99ed148887ee89c54a17d4100ae7e7e436593d104b668476019023b58df8", - "https://bcr.bazel.build/modules/rules_cc/0.2.17/MODULE.bazel": "1849602c86cb60da8613d2de887f9566a6d354a6df6d7009f9d04a14402f9a84", - "https://bcr.bazel.build/modules/rules_cc/0.2.17/source.json": "3832f45d145354049137c0090df04629d9c2b5493dc5c2bf46f1834040133a07", - "https://bcr.bazel.build/modules/rules_cc/0.2.8/MODULE.bazel": "f1df20f0bf22c28192a794f29b501ee2018fa37a3862a1a2132ae2940a23a642", - "https://bcr.bazel.build/modules/rules_foreign_cc/0.9.0/MODULE.bazel": "c9e8c682bf75b0e7c704166d79b599f93b72cfca5ad7477df596947891feeef6", - "https://bcr.bazel.build/modules/rules_fuzzing/0.5.2/MODULE.bazel": "40c97d1144356f52905566c55811f13b299453a14ac7769dfba2ac38192337a8", - "https://bcr.bazel.build/modules/rules_go/0.41.0/MODULE.bazel": "55861d8e8bb0e62cbd2896f60ff303f62ffcb0eddb74ecb0e5c0cbe36fc292c8", - "https://bcr.bazel.build/modules/rules_go/0.42.0/MODULE.bazel": "8cfa875b9aa8c6fce2b2e5925e73c1388173ea3c32a0db4d2b4804b453c14270", - "https://bcr.bazel.build/modules/rules_go/0.46.0/MODULE.bazel": "3477df8bdcc49e698b9d25f734c4f3a9f5931ff34ee48a2c662be168f5f2d3fd", - "https://bcr.bazel.build/modules/rules_go/0.50.1/MODULE.bazel": "b91a308dc5782bb0a8021ad4330c81fea5bda77f96b9e4c117b9b9c8f6665ee0", - "https://bcr.bazel.build/modules/rules_go/0.51.0-rc2/MODULE.bazel": "edfc3a9cea7bedb0eaaff37b0d7817c1a4bf72b3c615580b0ffcee6c52690fd4", - "https://bcr.bazel.build/modules/rules_go/0.53.0/MODULE.bazel": "a4ed760d3ac0dbc0d7b967631a9a3fd9100d28f7d9fcf214b4df87d4bfff5f9a", - "https://bcr.bazel.build/modules/rules_go/0.59.0/MODULE.bazel": "b7e43e7414a3139a7547d1b4909b29085fbe5182b6c58cbe1ed4c6272815aeae", - "https://bcr.bazel.build/modules/rules_go/0.59.0/source.json": "1df17bb7865cfc029492c30163cee891d0dd8658ea0d5bfdf252c4b6db5c1ef6", - "https://bcr.bazel.build/modules/rules_java/4.0.0/MODULE.bazel": "5a78a7ae82cd1a33cef56dc578c7d2a46ed0dca12643ee45edbb8417899e6f74", - "https://bcr.bazel.build/modules/rules_java/5.3.5/MODULE.bazel": "a4ec4f2db570171e3e5eb753276ee4b389bae16b96207e9d3230895c99644b86", - "https://bcr.bazel.build/modules/rules_java/6.3.0/MODULE.bazel": "a97c7678c19f236a956ad260d59c86e10a463badb7eb2eda787490f4c969b963", - "https://bcr.bazel.build/modules/rules_java/6.5.2/MODULE.bazel": "1d440d262d0e08453fa0c4d8f699ba81609ed0e9a9a0f02cd10b3e7942e61e31", - "https://bcr.bazel.build/modules/rules_java/7.1.0/MODULE.bazel": "30d9135a2b6561c761bd67bd4990da591e6bdc128790ce3e7afd6a3558b2fb64", - "https://bcr.bazel.build/modules/rules_java/7.10.0/MODULE.bazel": "530c3beb3067e870561739f1144329a21c851ff771cd752a49e06e3dc9c2e71a", - "https://bcr.bazel.build/modules/rules_java/7.12.2/MODULE.bazel": "579c505165ee757a4280ef83cda0150eea193eed3bef50b1004ba88b99da6de6", - "https://bcr.bazel.build/modules/rules_java/7.2.0/MODULE.bazel": "06c0334c9be61e6cef2c8c84a7800cef502063269a5af25ceb100b192453d4ab", - "https://bcr.bazel.build/modules/rules_java/7.4.0/MODULE.bazel": "a592852f8a3dd539e82ee6542013bf2cadfc4c6946be8941e189d224500a8934", - "https://bcr.bazel.build/modules/rules_java/7.6.1/MODULE.bazel": "2f14b7e8a1aa2f67ae92bc69d1ec0fa8d9f827c4e17ff5e5f02e91caa3b2d0fe", - "https://bcr.bazel.build/modules/rules_java/8.3.2/MODULE.bazel": "7336d5511ad5af0b8615fdc7477535a2e4e723a357b6713af439fe8cf0195017", - "https://bcr.bazel.build/modules/rules_java/8.5.1/MODULE.bazel": "d8a9e38cc5228881f7055a6079f6f7821a073df3744d441978e7a43e20226939", - "https://bcr.bazel.build/modules/rules_java/8.6.0/MODULE.bazel": "9c064c434606d75a086f15ade5edb514308cccd1544c2b2a89bbac4310e41c71", - "https://bcr.bazel.build/modules/rules_java/8.6.1/MODULE.bazel": "f4808e2ab5b0197f094cabce9f4b006a27766beb6a9975931da07099560ca9c2", - "https://bcr.bazel.build/modules/rules_java/8.6.3/MODULE.bazel": "e90505b7a931d194245ffcfb6ff4ca8ef9d46b4e830d12e64817752e0198e2ed", - "https://bcr.bazel.build/modules/rules_java/8.9.0/MODULE.bazel": "e17c876cb53dcd817b7b7f0d2985b710610169729e8c371b2221cacdcd3dce4a", - "https://bcr.bazel.build/modules/rules_java/9.1.0/MODULE.bazel": "ee63f27e36a3fada80342869361182f120a9819c74320e8e65b1e04ba0cd7a9d", - "https://bcr.bazel.build/modules/rules_java/9.3.0/MODULE.bazel": "f657c72d65ac449caae9abf2e68e66c0d36f9416848c4c4903d0b3234229e7f2", - "https://bcr.bazel.build/modules/rules_java/9.3.0/source.json": "59ae7e662c3c7042b88bbb42ad12483523e234c65ebe4c51611baa43e85cb248", - "https://bcr.bazel.build/modules/rules_jvm_external/4.4.2/MODULE.bazel": "a56b85e418c83eb1839819f0b515c431010160383306d13ec21959ac412d2fe7", - "https://bcr.bazel.build/modules/rules_jvm_external/5.1/MODULE.bazel": "33f6f999e03183f7d088c9be518a63467dfd0be94a11d0055fe2d210f89aa909", - "https://bcr.bazel.build/modules/rules_jvm_external/5.2/MODULE.bazel": "d9351ba35217ad0de03816ef3ed63f89d411349353077348a45348b096615036", - "https://bcr.bazel.build/modules/rules_jvm_external/6.2/MODULE.bazel": "36a6e52487a855f33cb960724eb56547fa87e2c98a0474c3acad94339d7f8e99", - "https://bcr.bazel.build/modules/rules_jvm_external/6.3/MODULE.bazel": "c998e060b85f71e00de5ec552019347c8bca255062c990ac02d051bb80a38df0", - "https://bcr.bazel.build/modules/rules_jvm_external/6.6/MODULE.bazel": "153042249c7060536dc95b6bb9f9bb8063b8a0b0cb7acdb381bddbc2374aed55", - "https://bcr.bazel.build/modules/rules_jvm_external/6.7/MODULE.bazel": "e717beabc4d091ecb2c803c2d341b88590e9116b8bf7947915eeb33aab4f96dd", - "https://bcr.bazel.build/modules/rules_jvm_external/6.9/MODULE.bazel": "07c5db05527db7744a54fcffd653e1550d40e0540207a7f7e6d0a4de5bef8274", - "https://bcr.bazel.build/modules/rules_jvm_external/7.0/MODULE.bazel": "421482bdbcf05709f933c96b867a599deb517f2804ceb3e74511880610cfbf71", - "https://bcr.bazel.build/modules/rules_jvm_external/7.0/source.json": "714cd003eadf5be5c83268311fe8e951db39f802babeaddc536b3560dc8f6faf", - "https://bcr.bazel.build/modules/rules_kotlin/1.9.5/MODULE.bazel": "043a16a572f610558ec2030db3ff0c9938574e7dd9f58bded1bb07c0192ef025", - "https://bcr.bazel.build/modules/rules_kotlin/1.9.6/MODULE.bazel": "d269a01a18ee74d0335450b10f62c9ed81f2321d7958a2934e44272fe82dcef3", - "https://bcr.bazel.build/modules/rules_kotlin/2.2.2/MODULE.bazel": "00d39c5e0fa78cd86193946265bb849e7878c24e44260f9525108428852b315c", - "https://bcr.bazel.build/modules/rules_kotlin/2.2.2/source.json": "7a32c2259c79ae0c9a036121f120de825e3ba5f0f3a209ffbbdccf4dc62489b9", - "https://bcr.bazel.build/modules/rules_license/0.0.3/MODULE.bazel": "627e9ab0247f7d1e05736b59dbb1b6871373de5ad31c3011880b4133cafd4bd0", - "https://bcr.bazel.build/modules/rules_license/0.0.7/MODULE.bazel": "088fbeb0b6a419005b89cf93fe62d9517c0a2b8bb56af3244af65ecfe37e7d5d", - "https://bcr.bazel.build/modules/rules_license/1.0.0/MODULE.bazel": "a7fda60eefdf3d8c827262ba499957e4df06f659330bbe6cdbdb975b768bb65c", - "https://bcr.bazel.build/modules/rules_license/1.0.0/source.json": "a52c89e54cc311196e478f8382df91c15f7a2bfdf4c6cd0e2675cc2ff0b56efb", - "https://bcr.bazel.build/modules/rules_pkg/0.7.0/MODULE.bazel": "df99f03fc7934a4737122518bb87e667e62d780b610910f0447665a7e2be62dc", - "https://bcr.bazel.build/modules/rules_pkg/1.0.1/MODULE.bazel": "5b1df97dbc29623bccdf2b0dcd0f5cb08e2f2c9050aab1092fd39a41e82686ff", - "https://bcr.bazel.build/modules/rules_pkg/1.0.1/source.json": "bd82e5d7b9ce2d31e380dd9f50c111d678c3bdaca190cb76b0e1c71b05e1ba8a", - "https://bcr.bazel.build/modules/rules_proto/4.0.0/MODULE.bazel": "a7a7b6ce9bee418c1a760b3d84f83a299ad6952f9903c67f19e4edd964894e06", - "https://bcr.bazel.build/modules/rules_proto/5.3.0-21.7/MODULE.bazel": "e8dff86b0971688790ae75528fe1813f71809b5afd57facb44dad9e8eca631b7", - "https://bcr.bazel.build/modules/rules_proto/6.0.0-rc1/MODULE.bazel": "1e5b502e2e1a9e825eef74476a5a1ee524a92297085015a052510b09a1a09483", - "https://bcr.bazel.build/modules/rules_proto/6.0.0/MODULE.bazel": "b531d7f09f58dce456cd61b4579ce8c86b38544da75184eadaf0a7cb7966453f", - "https://bcr.bazel.build/modules/rules_proto/6.0.2/MODULE.bazel": "ce916b775a62b90b61888052a416ccdda405212b6aaeb39522f7dc53431a5e73", - "https://bcr.bazel.build/modules/rules_proto/7.0.2/MODULE.bazel": "bf81793bd6d2ad89a37a40693e56c61b0ee30f7a7fdbaf3eabbf5f39de47dea2", - "https://bcr.bazel.build/modules/rules_proto/7.1.0/MODULE.bazel": "002d62d9108f75bb807cd56245d45648f38275cb3a99dcd45dfb864c5d74cb96", - "https://bcr.bazel.build/modules/rules_proto/7.1.0/source.json": "39f89066c12c24097854e8f57ab8558929f9c8d474d34b2c00ac04630ad8940e", - "https://bcr.bazel.build/modules/rules_python/0.10.2/MODULE.bazel": "cc82bc96f2997baa545ab3ce73f196d040ffb8756fd2d66125a530031cd90e5f", - "https://bcr.bazel.build/modules/rules_python/0.23.1/MODULE.bazel": "49ffccf0511cb8414de28321f5fcf2a31312b47c40cc21577144b7447f2bf300", - "https://bcr.bazel.build/modules/rules_python/0.25.0/MODULE.bazel": "72f1506841c920a1afec76975b35312410eea3aa7b63267436bfb1dd91d2d382", - "https://bcr.bazel.build/modules/rules_python/0.28.0/MODULE.bazel": "cba2573d870babc976664a912539b320cbaa7114cd3e8f053c720171cde331ed", - "https://bcr.bazel.build/modules/rules_python/0.31.0/MODULE.bazel": "93a43dc47ee570e6ec9f5779b2e64c1476a6ce921c48cc9a1678a91dd5f8fd58", - "https://bcr.bazel.build/modules/rules_python/0.33.2/MODULE.bazel": "3e036c4ad8d804a4dad897d333d8dce200d943df4827cb849840055be8d2e937", - "https://bcr.bazel.build/modules/rules_python/0.37.1/MODULE.bazel": "3faeb2d9fa0a81f8980643ee33f212308f4d93eea4b9ce6f36d0b742e71e9500", - "https://bcr.bazel.build/modules/rules_python/0.37.2/MODULE.bazel": "b5ffde91410745750b6c13be1c5dc4555ef5bc50562af4a89fd77807fdde626a", - "https://bcr.bazel.build/modules/rules_python/0.4.0/MODULE.bazel": "9208ee05fd48bf09ac60ed269791cf17fb343db56c8226a720fbb1cdf467166c", - "https://bcr.bazel.build/modules/rules_python/1.0.0/MODULE.bazel": "898a3d999c22caa585eb062b600f88654bf92efb204fa346fb55f6f8edffca43", - "https://bcr.bazel.build/modules/rules_python/1.3.0/MODULE.bazel": "8361d57eafb67c09b75bf4bbe6be360e1b8f4f18118ab48037f2bd50aa2ccb13", - "https://bcr.bazel.build/modules/rules_python/1.4.1/MODULE.bazel": "8991ad45bdc25018301d6b7e1d3626afc3c8af8aaf4bc04f23d0b99c938b73a6", - "https://bcr.bazel.build/modules/rules_python/1.6.0/MODULE.bazel": "7e04ad8f8d5bea40451cf80b1bd8262552aa73f841415d20db96b7241bd027d8", - "https://bcr.bazel.build/modules/rules_python/1.7.0/MODULE.bazel": "d01f995ecd137abf30238ad9ce97f8fc3ac57289c8b24bd0bf53324d937a14f8", - "https://bcr.bazel.build/modules/rules_python/1.7.0/source.json": "028a084b65dcf8f4dc4f82f8778dbe65df133f234b316828a82e060d81bdce32", - "https://bcr.bazel.build/modules/rules_robolectric/4.14.1.2/MODULE.bazel": "d44fec647d0aeb67b9f3b980cf68ba634976f3ae7ccd6c07d790b59b87a4f251", - "https://bcr.bazel.build/modules/rules_robolectric/4.14.1.2/source.json": "37c10335f2361c337c5c1f34ed36d2da70534c23088062b33a8bdaab68aa9dea", - "https://bcr.bazel.build/modules/rules_shell/0.1.2/MODULE.bazel": "66e4ca3ce084b04af0b9ff05ff14cab4e5df7503973818bb91cbc6cda08d32fc", - "https://bcr.bazel.build/modules/rules_shell/0.2.0/MODULE.bazel": "fda8a652ab3c7d8fee214de05e7a9916d8b28082234e8d2c0094505c5268ed3c", - "https://bcr.bazel.build/modules/rules_shell/0.3.0/MODULE.bazel": "de4402cd12f4cc8fda2354fce179fdb068c0b9ca1ec2d2b17b3e21b24c1a937b", - "https://bcr.bazel.build/modules/rules_shell/0.4.1/MODULE.bazel": "00e501db01bbf4e3e1dd1595959092c2fadf2087b2852d3f553b5370f5633592", - "https://bcr.bazel.build/modules/rules_shell/0.6.1/MODULE.bazel": "72e76b0eea4e81611ef5452aa82b3da34caca0c8b7b5c0c9584338aa93bae26b", - "https://bcr.bazel.build/modules/rules_shell/0.8.0/MODULE.bazel": "f6a89f1d6a669a26f28fe814503857055d76306b79cfc11d12399af08d0b80ae", - "https://bcr.bazel.build/modules/rules_shell/0.8.0/source.json": "eb53cc815bc503c6683c5fe12d943f98883f81fc22f51403ec8a95610cba4195", - "https://bcr.bazel.build/modules/rules_swift/1.16.0/MODULE.bazel": "4a09f199545a60d09895e8281362b1ff3bb08bbde69c6fc87aff5b92fcc916ca", - "https://bcr.bazel.build/modules/rules_swift/2.1.1/MODULE.bazel": "494900a80f944fc7aa61500c2073d9729dff0b764f0e89b824eb746959bc1046", - "https://bcr.bazel.build/modules/rules_swift/2.4.0/MODULE.bazel": "1639617eb1ede28d774d967a738b4a68b0accb40650beadb57c21846beab5efd", - "https://bcr.bazel.build/modules/rules_swift/3.1.2/MODULE.bazel": "72c8f5cf9d26427cee6c76c8e3853eb46ce6b0412a081b2b6db6e8ad56267400", - "https://bcr.bazel.build/modules/rules_swift/3.1.2/source.json": "e85761f3098a6faf40b8187695e3de6d97944e98abd0d8ce579cb2daf6319a66", - "https://bcr.bazel.build/modules/stardoc/0.5.1/MODULE.bazel": "1a05d92974d0c122f5ccf09291442580317cdd859f07a8655f1db9a60374f9f8", - "https://bcr.bazel.build/modules/stardoc/0.5.3/MODULE.bazel": "c7f6948dae6999bf0db32c1858ae345f112cacf98f174c7a8bb707e41b974f1c", - "https://bcr.bazel.build/modules/stardoc/0.6.2/MODULE.bazel": "7060193196395f5dd668eda046ccbeacebfd98efc77fed418dbe2b82ffaa39fd", - "https://bcr.bazel.build/modules/stardoc/0.7.0/MODULE.bazel": "05e3d6d30c099b6770e97da986c53bd31844d7f13d41412480ea265ac9e8079c", - "https://bcr.bazel.build/modules/stardoc/0.7.2/MODULE.bazel": "fc152419aa2ea0f51c29583fab1e8c99ddefd5b3778421845606ee628629e0e5", - "https://bcr.bazel.build/modules/stardoc/0.7.2/source.json": "58b029e5e901d6802967754adf0a9056747e8176f017cfe3607c0851f4d42216", - "https://bcr.bazel.build/modules/swift_argument_parser/1.3.1.1/MODULE.bazel": "5e463fbfba7b1701d957555ed45097d7f984211330106ccd1352c6e0af0dcf91", - "https://bcr.bazel.build/modules/swift_argument_parser/1.3.1.2/MODULE.bazel": "75aab2373a4bbe2a1260b9bf2a1ebbdbf872d3bd36f80bff058dccd82e89422f", - "https://bcr.bazel.build/modules/swift_argument_parser/1.3.1.2/source.json": "5fba48bbe0ba48761f9e9f75f92876cafb5d07c0ce059cc7a8027416de94a05b", - "https://bcr.bazel.build/modules/toml.bzl/0.3.0/MODULE.bazel": "5016e5dd1ad2200e119a4b28b2b3935e276c4b480f2fe3e952bea7eeba88f578", - "https://bcr.bazel.build/modules/toml.bzl/0.3.0/source.json": "0cf7c878c419b37ddb55f3dd93dd7c0c409bd7c4efacb3da504e0748780b2fa9", - "https://bcr.bazel.build/modules/upb/0.0.0-20220923-a547704/MODULE.bazel": "7298990c00040a0e2f121f6c32544bab27d4452f80d9ce51349b1a28f3005c43", - "https://bcr.bazel.build/modules/upb/0.0.0-20230516-61a97ef/MODULE.bazel": "c0df5e35ad55e264160417fd0875932ee3c9dda63d9fccace35ac62f45e1b6f9", - "https://bcr.bazel.build/modules/zlib/1.2.11/MODULE.bazel": "07b389abc85fdbca459b69e2ec656ae5622873af3f845e1c9d80fe179f3effa0", - "https://bcr.bazel.build/modules/zlib/1.2.12/MODULE.bazel": "3b1a8834ada2a883674be8cbd36ede1b6ec481477ada359cd2d3ddc562340b27", - "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.5/MODULE.bazel": "eec517b5bbe5492629466e11dae908d043364302283de25581e3eb944326c4ca", - "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.5/source.json": "22bc55c47af97246cfc093d0acf683a7869377de362b5d1c552c2c2e16b7a806", - "https://bcr.bazel.build/modules/zlib/1.3.1/MODULE.bazel": "751c9940dcfe869f5f7274e1295422a34623555916eb98c174c1e945594bf198" - }, - "selectedYankedVersions": {}, - "moduleExtensions": { - "@@rules_android+//rules/android_sdk_repository:rule.bzl%android_sdk_repository_extension": { - "general": { - "bzlTransitiveDigest": "+rMrzIrv7sImYmkbXJYv+gFpTJQ79X3MpwwMLI2A+oA=", - "usagesDigest": "iEGI2aNDMkHt9LXCdViLNUUOslpiVj2DrevWWXZEFnU=", - "recordedInputs": [], - "generatedRepoSpecs": { - "androidsdk": { - "repoRuleId": "@@rules_android+//rules/android_sdk_repository:rule.bzl%_android_sdk_repository", - "attributes": {} - } - } - } - }, - "@@rules_python+//python/extensions:config.bzl%config": { - "general": { - "bzlTransitiveDigest": "iibnRYgg8LpcfmH7EAnVwYePC3jsVaJ6Id8XxUjSZps=", - "usagesDigest": "ZVSXMAGpD+xzVNPuvF1IoLBkty7TROO0+akMapt1pAg=", - "recordedInputs": [ - "REPO_MAPPING:rules_python+,bazel_tools bazel_tools", - "REPO_MAPPING:rules_python+,pypi__build rules_python++config+pypi__build", - "REPO_MAPPING:rules_python+,pypi__click rules_python++config+pypi__click", - "REPO_MAPPING:rules_python+,pypi__colorama rules_python++config+pypi__colorama", - "REPO_MAPPING:rules_python+,pypi__importlib_metadata rules_python++config+pypi__importlib_metadata", - "REPO_MAPPING:rules_python+,pypi__installer rules_python++config+pypi__installer", - "REPO_MAPPING:rules_python+,pypi__more_itertools rules_python++config+pypi__more_itertools", - "REPO_MAPPING:rules_python+,pypi__packaging rules_python++config+pypi__packaging", - "REPO_MAPPING:rules_python+,pypi__pep517 rules_python++config+pypi__pep517", - "REPO_MAPPING:rules_python+,pypi__pip rules_python++config+pypi__pip", - "REPO_MAPPING:rules_python+,pypi__pip_tools rules_python++config+pypi__pip_tools", - "REPO_MAPPING:rules_python+,pypi__pyproject_hooks rules_python++config+pypi__pyproject_hooks", - "REPO_MAPPING:rules_python+,pypi__setuptools rules_python++config+pypi__setuptools", - "REPO_MAPPING:rules_python+,pypi__tomli rules_python++config+pypi__tomli", - "REPO_MAPPING:rules_python+,pypi__wheel rules_python++config+pypi__wheel", - "REPO_MAPPING:rules_python+,pypi__zipp rules_python++config+pypi__zipp" - ], - "generatedRepoSpecs": { - "rules_python_internal": { - "repoRuleId": "@@rules_python+//python/private:internal_config_repo.bzl%internal_config_repo", - "attributes": { - "transition_setting_generators": {}, - "transition_settings": [] - } - }, - "pypi__build": { - "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", - "attributes": { - "url": "https://files.pythonhosted.org/packages/e2/03/f3c8ba0a6b6e30d7d18c40faab90807c9bb5e9a1e3b2fe2008af624a9c97/build-1.2.1-py3-none-any.whl", - "sha256": "75e10f767a433d9a86e50d83f418e83efc18ede923ee5ff7df93b6cb0306c5d4", - "type": "zip", - "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" - } - }, - "pypi__click": { - "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", - "attributes": { - "url": "https://files.pythonhosted.org/packages/00/2e/d53fa4befbf2cfa713304affc7ca780ce4fc1fd8710527771b58311a3229/click-8.1.7-py3-none-any.whl", - "sha256": "ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", - "type": "zip", - "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" - } - }, - "pypi__colorama": { - "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", - "attributes": { - "url": "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", - "sha256": "4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", - "type": "zip", - "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" - } - }, - "pypi__importlib_metadata": { - "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", - "attributes": { - "url": "https://files.pythonhosted.org/packages/2d/0a/679461c511447ffaf176567d5c496d1de27cbe34a87df6677d7171b2fbd4/importlib_metadata-7.1.0-py3-none-any.whl", - "sha256": "30962b96c0c223483ed6cc7280e7f0199feb01a0e40cfae4d4450fc6fab1f570", - "type": "zip", - "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" - } - }, - "pypi__installer": { - "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", - "attributes": { - "url": "https://files.pythonhosted.org/packages/e5/ca/1172b6638d52f2d6caa2dd262ec4c811ba59eee96d54a7701930726bce18/installer-0.7.0-py3-none-any.whl", - "sha256": "05d1933f0a5ba7d8d6296bb6d5018e7c94fa473ceb10cf198a92ccea19c27b53", - "type": "zip", - "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" - } - }, - "pypi__more_itertools": { - "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", - "attributes": { - "url": "https://files.pythonhosted.org/packages/50/e2/8e10e465ee3987bb7c9ab69efb91d867d93959095f4807db102d07995d94/more_itertools-10.2.0-py3-none-any.whl", - "sha256": "686b06abe565edfab151cb8fd385a05651e1fdf8f0a14191e4439283421f8684", - "type": "zip", - "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" - } - }, - "pypi__packaging": { - "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", - "attributes": { - "url": "https://files.pythonhosted.org/packages/49/df/1fceb2f8900f8639e278b056416d49134fb8d84c5942ffaa01ad34782422/packaging-24.0-py3-none-any.whl", - "sha256": "2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5", - "type": "zip", - "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" - } - }, - "pypi__pep517": { - "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", - "attributes": { - "url": "https://files.pythonhosted.org/packages/25/6e/ca4a5434eb0e502210f591b97537d322546e4833dcb4d470a48c375c5540/pep517-0.13.1-py3-none-any.whl", - "sha256": "31b206f67165b3536dd577c5c3f1518e8fbaf38cbc57efff8369a392feff1721", - "type": "zip", - "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" - } - }, - "pypi__pip": { - "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", - "attributes": { - "url": "https://files.pythonhosted.org/packages/8a/6a/19e9fe04fca059ccf770861c7d5721ab4c2aebc539889e97c7977528a53b/pip-24.0-py3-none-any.whl", - "sha256": "ba0d021a166865d2265246961bec0152ff124de910c5cc39f1156ce3fa7c69dc", - "type": "zip", - "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" - } - }, - "pypi__pip_tools": { - "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", - "attributes": { - "url": "https://files.pythonhosted.org/packages/0d/dc/38f4ce065e92c66f058ea7a368a9c5de4e702272b479c0992059f7693941/pip_tools-7.4.1-py3-none-any.whl", - "sha256": "4c690e5fbae2f21e87843e89c26191f0d9454f362d8acdbd695716493ec8b3a9", - "type": "zip", - "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" - } - }, - "pypi__pyproject_hooks": { - "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", - "attributes": { - "url": "https://files.pythonhosted.org/packages/ae/f3/431b9d5fe7d14af7a32340792ef43b8a714e7726f1d7b69cc4e8e7a3f1d7/pyproject_hooks-1.1.0-py3-none-any.whl", - "sha256": "7ceeefe9aec63a1064c18d939bdc3adf2d8aa1988a510afec15151578b232aa2", - "type": "zip", - "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" - } - }, - "pypi__setuptools": { - "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", - "attributes": { - "url": "https://files.pythonhosted.org/packages/90/99/158ad0609729111163fc1f674a5a42f2605371a4cf036d0441070e2f7455/setuptools-78.1.1-py3-none-any.whl", - "sha256": "c3a9c4211ff4c309edb8b8c4f1cbfa7ae324c4ba9f91ff254e3d305b9fd54561", - "type": "zip", - "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" - } - }, - "pypi__tomli": { - "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", - "attributes": { - "url": "https://files.pythonhosted.org/packages/97/75/10a9ebee3fd790d20926a90a2547f0bf78f371b2f13aa822c759680ca7b9/tomli-2.0.1-py3-none-any.whl", - "sha256": "939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc", - "type": "zip", - "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" - } - }, - "pypi__wheel": { - "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", - "attributes": { - "url": "https://files.pythonhosted.org/packages/7d/cd/d7460c9a869b16c3dd4e1e403cce337df165368c71d6af229a74699622ce/wheel-0.43.0-py3-none-any.whl", - "sha256": "55c570405f142630c6b9f72fe09d9b67cf1477fcf543ae5b8dcb1f5b7377da81", - "type": "zip", - "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" - } - }, - "pypi__zipp": { - "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", - "attributes": { - "url": "https://files.pythonhosted.org/packages/da/55/a03fd7240714916507e1fcf7ae355bd9d9ed2e6db492595f1a67f61681be/zipp-3.18.2-py3-none-any.whl", - "sha256": "dce197b859eb796242b0622af1b8beb0a722d52aa2f57133ead08edd5bf5374e", - "type": "zip", - "build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n" - } - } - } - } - }, - "@@rules_python+//python/uv:uv.bzl%uv": { - "general": { - "bzlTransitiveDigest": "ijW9KS7qsIY+yBVvJ+Nr1mzwQox09j13DnE3iIwaeTM=", - "usagesDigest": "H8dQoNZcoqP+Mu0tHZTi4KHATzvNkM5ePuEqoQdklIU=", - "recordedInputs": [ - "REPO_MAPPING:rules_python+,bazel_tools bazel_tools", - "REPO_MAPPING:rules_python+,platforms platforms" - ], - "generatedRepoSpecs": { - "uv": { - "repoRuleId": "@@rules_python+//python/uv/private:uv_toolchains_repo.bzl%uv_toolchains_repo", - "attributes": { - "toolchain_type": "'@@rules_python+//python/uv:uv_toolchain_type'", - "toolchain_names": [ - "none" - ], - "toolchain_implementations": { - "none": "'@@rules_python+//python:none'" - }, - "toolchain_compatible_with": { - "none": [ - "@platforms//:incompatible" - ] - }, - "toolchain_target_settings": {} - } - } - } - } - } - }, - "facts": { - "@@rules_go+//go:extensions.bzl%go_sdk": { - "1.22.4": { - "aix_ppc64": [ - "go1.22.4.aix-ppc64.tar.gz", - "b9647fa9fc83a0cc5d4f092a19eaeaecf45f063a5aa7d4962fde65aeb7ae6ce1" - ], - "darwin_amd64": [ - "go1.22.4.darwin-amd64.tar.gz", - "c95967f50aa4ace34af0c236cbdb49a9a3e80ee2ad09d85775cb4462a5c19ed3" - ], - "darwin_arm64": [ - "go1.22.4.darwin-arm64.tar.gz", - "242b78dc4c8f3d5435d28a0d2cec9b4c1aa999b601fb8aa59fb4e5a1364bf827" - ], - "dragonfly_amd64": [ - "go1.22.4.dragonfly-amd64.tar.gz", - "f2fbb51af4719d3616efb482d6ed2b96579b474156f85a7ddc6f126764feec4b" - ], - "freebsd_386": [ - "go1.22.4.freebsd-386.tar.gz", - "7c54884bb9f274884651d41e61d1bc12738863ad1497e97ea19ad0e9aa6bf7b5" - ], - "freebsd_amd64": [ - "go1.22.4.freebsd-amd64.tar.gz", - "88d44500e1701dd35797619774d6dd51bf60f45a8338b0a82ddc018e4e63fb78" - ], - "freebsd_arm64": [ - "go1.22.4.freebsd-arm64.tar.gz", - "726dc093cf020277be45debf03c3b02b43c2efb3e2a5d4fba8f52579d65327dc" - ], - "freebsd_armv6l": [ - "go1.22.4.freebsd-arm.tar.gz", - "3d9efe47db142a22679aba46b1772e3900b0d87ae13bd2b3bc80dbf2ac0b2cd6" - ], - "freebsd_riscv64": [ - "go1.22.4.freebsd-riscv64.tar.gz", - "5f6b67e5e32f1d6ccb2d4dcb44934a5e2e870a877ba7443d86ec43cfc28afa71" - ], - "illumos_amd64": [ - "go1.22.4.illumos-amd64.tar.gz", - "d56ecc2f85b6418a21ef83879594d0c42ab4f65391a676bb12254870e6690d63" - ], - "linux_386": [ - "go1.22.4.linux-386.tar.gz", - "47a2a8d249a91eb8605c33bceec63aedda0441a43eac47b4721e3975ff916cec" - ], - "linux_amd64": [ - "go1.22.4.linux-amd64.tar.gz", - "ba79d4526102575196273416239cca418a651e049c2b099f3159db85e7bade7d" - ], - "linux_arm64": [ - "go1.22.4.linux-arm64.tar.gz", - "a8e177c354d2e4a1b61020aca3562e27ea3e8f8247eca3170e3fa1e0c2f9e771" - ], - "linux_armv6l": [ - "go1.22.4.linux-armv6l.tar.gz", - "e2b143fbacbc9cbd448e9ef41ac3981f0488ce849af1cf37e2341d09670661de" - ], - "linux_loong64": [ - "go1.22.4.linux-loong64.tar.gz", - "e2ff9436e4b34bf6926b06d97916e26d67a909a2effec17967245900f0816f1d" - ], - "linux_mips": [ - "go1.22.4.linux-mips.tar.gz", - "73f0dcc60458c4770593b05a7bc01cc0d31fc98f948c0c2334812c7a1f2fc3f1" - ], - "linux_mips64": [ - "go1.22.4.linux-mips64.tar.gz", - "417af97fc2630a647052375768be4c38adcc5af946352ea5b28613ea81ca5d45" - ], - "linux_mips64le": [ - "go1.22.4.linux-mips64le.tar.gz", - "7486e2d7dd8c98eb44df815ace35a7fe7f30b7c02326e3741bd934077508139b" - ], - "linux_mipsle": [ - "go1.22.4.linux-mipsle.tar.gz", - "69479c8aad301e459a8365b40cad1074a0dbba5defb9291669f94809c4c4be6e" - ], - "linux_ppc64": [ - "go1.22.4.linux-ppc64.tar.gz", - "dd238847e65bc3e2745caca475a5db6522a2fcf85cf6c38fc36a06642b19efd7" - ], - "linux_ppc64le": [ - "go1.22.4.linux-ppc64le.tar.gz", - "a3e5834657ef92523f570f798fed42f1f87bc18222a16815ec76b84169649ec4" - ], - "linux_riscv64": [ - "go1.22.4.linux-riscv64.tar.gz", - "56a827ff7dc6245bcd7a1e9288dffaa1d8b0fd7468562264c1523daf3b4f1b4a" - ], - "linux_s390x": [ - "go1.22.4.linux-s390x.tar.gz", - "7590c3e278e2dc6040aae0a39da3ca1eb2e3921673a7304cc34d588c45889eec" - ], - "netbsd_386": [ - "go1.22.4.netbsd-386.tar.gz", - "ddd2eebe34471a2502de6c5dad04ab27c9fc80cbde7a9ad5b3c66ecec4504e1d" - ], - "netbsd_amd64": [ - "go1.22.4.netbsd-amd64.tar.gz", - "33af79f6f935f6fbacc5d23876450b3567b79348fc065beef8e64081127dd234" - ], - "netbsd_arm64": [ - "go1.22.4.netbsd-arm64.tar.gz", - "c9a2971dec9f6d320c6f2b049b2353c6d0a2d35e87b8a4b2d78a2f0d62545f8e" - ], - "netbsd_armv6l": [ - "go1.22.4.netbsd-arm.tar.gz", - "fa3550ebd5375a70b3bcd342b5a71f4bd271dcbbfaf4eabefa2144ab5d8924b6" - ], - "openbsd_386": [ - "go1.22.4.openbsd-386.tar.gz", - "d21af022331bfdc2b5b161d616c3a1a4573d33cf7a30416ee509a8f3641deb47" - ], - "openbsd_amd64": [ - "go1.22.4.openbsd-amd64.tar.gz", - "72c0094c43f7e5722ec49c2a3e9dfa7a1123ac43a5f3a63eecf3e3795d3ff0ae" - ], - "openbsd_arm64": [ - "go1.22.4.openbsd-arm64.tar.gz", - "a7ab8d4e0b02bf06ed144ba42c61c0e93ee00f2b433415dfd4ad4b6e79f31650" - ], - "openbsd_armv6l": [ - "go1.22.4.openbsd-arm.tar.gz", - "1096831ea3c5ea3ca57d14251d9eda3786889531eb40d7d6775dcaa324d4b065" - ], - "openbsd_ppc64": [ - "go1.22.4.openbsd-ppc64.tar.gz", - "9716327c8a628358798898dc5148c49dbbeb5196bf2cbf088e550721a6e4f60b" - ], - "plan9_386": [ - "go1.22.4.plan9-386.tar.gz", - "a8dd4503c95c32a502a616ab78870a19889c9325fe9bd31eb16dd69346e4bfa8" - ], - "plan9_amd64": [ - "go1.22.4.plan9-amd64.tar.gz", - "5423a25808d76fe5aca8607a2e5ac5673abf45446b168cb5e9d8519ee9fe39a1" - ], - "plan9_armv6l": [ - "go1.22.4.plan9-arm.tar.gz", - "6af939ad583f5c85c09c53728ab7d38c3cc2b39167562d6c18a07c5c6608b370" - ], - "solaris_amd64": [ - "go1.22.4.solaris-amd64.tar.gz", - "e8cabe69c03085725afdb32a6f9998191a3e55a747b270d835fd05000d56abba" - ], - "windows_386": [ - "go1.22.4.windows-386.zip", - "aca4e2c37278a10f1c70dd0df142f7d66b50334fcee48978d409202d308d6d25" - ], - "windows_amd64": [ - "go1.22.4.windows-amd64.zip", - "26321c4d945a0035d8a5bc4a1965b0df401ff8ceac66ce2daadabf9030419a98" - ], - "windows_arm64": [ - "go1.22.4.windows-arm64.zip", - "8a2daa9ea28cbdafddc6171aefed384f4e5b6e714fb52116fe9ed25a132f37ed" - ], - "windows_armv6l": [ - "go1.22.4.windows-arm.zip", - "5fcd0671a49cecf39b41021621ee1b6e7aa1370f37122b72e80d4fd4185833b6" - ] - }, - "1.25.0": { - "aix_ppc64": [ - "go1.25.0.aix-ppc64.tar.gz", - "e5234a7dac67bc86c528fe9752fc9d63557918627707a733ab4cac1a6faed2d4" - ], - "darwin_amd64": [ - "go1.25.0.darwin-amd64.tar.gz", - "5bd60e823037062c2307c71e8111809865116714d6f6b410597cf5075dfd80ef" - ], - "darwin_arm64": [ - "go1.25.0.darwin-arm64.tar.gz", - "544932844156d8172f7a28f77f2ac9c15a23046698b6243f633b0a0b00c0749c" - ], - "dragonfly_amd64": [ - "go1.25.0.dragonfly-amd64.tar.gz", - "5ed3cf9a810a1483822538674f1336c06b51aa1b94d6d545a1a0319a48177120" - ], - "freebsd_386": [ - "go1.25.0.freebsd-386.tar.gz", - "abea5d5c6697e6b5c224731f2158fe87c602996a2a233ac0c4730cd57bf8374e" - ], - "freebsd_amd64": [ - "go1.25.0.freebsd-amd64.tar.gz", - "86e6fe0a29698d7601c4442052dac48bd58d532c51cccb8f1917df648138730b" - ], - "freebsd_arm": [ - "go1.25.0.freebsd-arm.tar.gz", - "d90b78e41921f72f30e8bbc81d9dec2cff7ff384a33d8d8debb24053e4336bfe" - ], - "freebsd_arm64": [ - "go1.25.0.freebsd-arm64.tar.gz", - "451d0da1affd886bfb291b7c63a6018527b269505db21ce6e14724f22ab0662e" - ], - "freebsd_riscv64": [ - "go1.25.0.freebsd-riscv64.tar.gz", - "7b565f76bd8bda46549eeaaefe0e53b251e644c230577290c0f66b1ecdb3cdbe" - ], - "illumos_amd64": [ - "go1.25.0.illumos-amd64.tar.gz", - "b1e1fdaab1ad25aa1c08d7a36c97d45d74b98b89c3f78c6d2145f77face54a2c" - ], - "linux_386": [ - "go1.25.0.linux-386.tar.gz", - "8c602dd9d99bc9453b3995d20ce4baf382cc50855900a0ece5de9929df4a993a" - ], - "linux_amd64": [ - "go1.25.0.linux-amd64.tar.gz", - "2852af0cb20a13139b3448992e69b868e50ed0f8a1e5940ee1de9e19a123b613" - ], - "linux_arm64": [ - "go1.25.0.linux-arm64.tar.gz", - "05de75d6994a2783699815ee553bd5a9327d8b79991de36e38b66862782f54ae" - ], - "linux_armv6l": [ - "go1.25.0.linux-armv6l.tar.gz", - "a5a8f8198fcf00e1e485b8ecef9ee020778bf32a408a4e8873371bfce458cd09" - ], - "linux_loong64": [ - "go1.25.0.linux-loong64.tar.gz", - "cab86b1cf761b1cb3bac86a8877cfc92e7b036fc0d3084123d77013d61432afc" - ], - "linux_mips": [ - "go1.25.0.linux-mips.tar.gz", - "d66b6fb74c3d91b9829dc95ec10ca1f047ef5e89332152f92e136cf0e2da5be1" - ], - "linux_mips64": [ - "go1.25.0.linux-mips64.tar.gz", - "4082e4381a8661bc2a839ff94ba3daf4f6cde20f8fb771b5b3d4762dc84198a2" - ], - "linux_mips64le": [ - "go1.25.0.linux-mips64le.tar.gz", - "70002c299ec7f7175ac2ef673b1b347eecfa54ae11f34416a6053c17f855afcc" - ], - "linux_mipsle": [ - "go1.25.0.linux-mipsle.tar.gz", - "b00a3a39eff099f6df9f1c7355bf28e4589d0586f42d7d4a394efb763d145a73" - ], - "linux_ppc64": [ - "go1.25.0.linux-ppc64.tar.gz", - "df166f33bd98160662560a72ff0b4ba731f969a80f088922bddcf566a88c1ec1" - ], - "linux_ppc64le": [ - "go1.25.0.linux-ppc64le.tar.gz", - "0f18a89e7576cf2c5fa0b487a1635d9bcbf843df5f110e9982c64df52a983ad0" - ], - "linux_riscv64": [ - "go1.25.0.linux-riscv64.tar.gz", - "c018ff74a2c48d55c8ca9b07c8e24163558ffec8bea08b326d6336905d956b67" - ], - "linux_s390x": [ - "go1.25.0.linux-s390x.tar.gz", - "34e5a2e19f2292fbaf8783e3a241e6e49689276aef6510a8060ea5ef54eee408" - ], - "netbsd_386": [ - "go1.25.0.netbsd-386.tar.gz", - "f8586cdb7aa855657609a5c5f6dbf523efa00c2bbd7c76d3936bec80aa6c0aba" - ], - "netbsd_amd64": [ - "go1.25.0.netbsd-amd64.tar.gz", - "ae8dc1469385b86a157a423bb56304ba45730de8a897615874f57dd096db2c2a" - ], - "netbsd_arm": [ - "go1.25.0.netbsd-arm.tar.gz", - "1ff7e4cc764425fc9dd6825eaee79d02b3c7cafffbb3691687c8d672ade76cb7" - ], - "netbsd_arm64": [ - "go1.25.0.netbsd-arm64.tar.gz", - "e1b310739f26724216aa6d7d7208c4031f9ff54c9b5b9a796ddc8bebcb4a5f16" - ], - "openbsd_386": [ - "go1.25.0.openbsd-386.tar.gz", - "4802a9b20e533da91adb84aab42e94aa56cfe3e5475d0550bed3385b182e69d8" - ], - "openbsd_amd64": [ - "go1.25.0.openbsd-amd64.tar.gz", - "c016cd984bebe317b19a4f297c4f50def120dc9788490540c89f28e42f1dabe1" - ], - "openbsd_arm": [ - "go1.25.0.openbsd-arm.tar.gz", - "a1e31d0bf22172ddde42edf5ec811ef81be43433df0948ece52fecb247ccfd8d" - ], - "openbsd_arm64": [ - "go1.25.0.openbsd-arm64.tar.gz", - "343ea8edd8c218196e15a859c6072d0dd3246fbbb168481ab665eb4c4140458d" - ], - "openbsd_ppc64": [ - "go1.25.0.openbsd-ppc64.tar.gz", - "694c14da1bcaeb5e3332d49bdc2b6d155067648f8fe1540c5de8f3cf8e157154" - ], - "openbsd_riscv64": [ - "go1.25.0.openbsd-riscv64.tar.gz", - "aa510ad25cf54c06cd9c70b6d80ded69cb20188ac6e1735655eef29ff7e7885f" - ], - "plan9_386": [ - "go1.25.0.plan9-386.tar.gz", - "46f8cef02086cf04bf186c5912776b56535178d4cb319cd19c9fdbdd29231986" - ], - "plan9_amd64": [ - "go1.25.0.plan9-amd64.tar.gz", - "29b34391d84095e44608a228f63f2f88113a37b74a79781353ec043dfbcb427b" - ], - "plan9_arm": [ - "go1.25.0.plan9-arm.tar.gz", - "0a047107d13ebe7943aaa6d54b1d7bbd2e45e68ce449b52915a818da715799c2" - ], - "solaris_amd64": [ - "go1.25.0.solaris-amd64.tar.gz", - "9977f9e4351984364a3b2b78f8b88bfd1d339812356d5237678514594b7d3611" - ], - "windows_386": [ - "go1.25.0.windows-386.zip", - "df9f39db82a803af0db639e3613a36681ab7a42866b1384b3f3a1045663961a7" - ], - "windows_amd64": [ - "go1.25.0.windows-amd64.zip", - "89efb4f9b30812eee083cc1770fdd2913c14d301064f6454851428f9707d190b" - ], - "windows_arm64": [ - "go1.25.0.windows-arm64.zip", - "27bab004c72b3d7bd05a69b6ec0fc54a309b4b78cc569dd963d8b3ec28bfdb8c" - ] - } - } - } -} diff --git a/src/libraries/java/nv-boot-parent/maven_install.json b/src/libraries/java/nv-boot-parent/maven_install.json deleted file mode 100644 index dbdfb4db2..000000000 --- a/src/libraries/java/nv-boot-parent/maven_install.json +++ /dev/null @@ -1,10040 +0,0 @@ -{ - "__AUTOGENERATED_FILE_DO_NOT_MODIFY_THIS_FILE_MANUALLY": "THERE_IS_NO_DATA_ONLY_ZUUL", - "__INPUT_ARTIFACTS_HASH": { - "at.yawk.lz4:lz4-java": 1725015399, - "com.github.ben-manes.caffeine:guava": 1054685015, - "com.github.java-json-tools:json-patch": -1031005245, - "commons-codec:commons-codec": -1269462382, - "io.cloudevents:cloudevents-core": -2103567774, - "io.cloudevents:cloudevents-json-jackson": -1197487309, - "io.micrometer:micrometer-tracing-bridge-otel": -754588172, - "io.nats:jnats": 572014237, - "io.opentelemetry:opentelemetry-exporter-otlp": -12806658, - "io.opentelemetry:opentelemetry-sdk-testing": -32635354, - "jakarta.servlet:jakarta.servlet-api": 2120044853, - "net.javacrumbs.shedlock:shedlock-bom": -1406345450, - "org.apache.cassandra:java-driver-metrics-micrometer": -465267397, - "org.apache.commons:commons-lang3": -278168457, - "org.bouncycastle:bcprov-jdk18on": -1405390253, - "org.jacoco:org.jacoco.agent": -2069397525, - "org.jacoco:org.jacoco.cli": -1856875155, - "org.junit.platform:junit-platform-console-standalone": -1481831078, - "org.ow2.asm:asm-analysis": -1027574299, - "org.ow2.asm:asm-util": -307204853, - "org.projectlombok:lombok": -2073039513, - "org.springdoc:springdoc-openapi-starter-webflux-api": 1102747448, - "org.springdoc:springdoc-openapi-starter-webmvc-api": 655186513, - "org.springframework.boot:spring-boot-dependencies": 70164638, - "org.springframework.boot:spring-boot-micrometer-tracing-opentelemetry": 238152322, - "org.springframework.boot:spring-boot-restclient": 525086533, - "org.springframework.boot:spring-boot-starter": 1358725161, - "org.springframework.boot:spring-boot-starter-actuator": -1082017891, - "org.springframework.boot:spring-boot-starter-actuator-test": 536870722, - "org.springframework.boot:spring-boot-starter-data-cassandra": 699136521, - "org.springframework.boot:spring-boot-starter-data-cassandra-test": -667262890, - "org.springframework.boot:spring-boot-starter-jackson": -1899095121, - "org.springframework.boot:spring-boot-starter-security-oauth2-client": -1248590284, - "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server": 185843737, - "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server-test": -1173625786, - "org.springframework.boot:spring-boot-starter-test": -1561809354, - "org.springframework.boot:spring-boot-starter-validation": 113118493, - "org.springframework.boot:spring-boot-starter-webflux": 1788530073, - "org.springframework.boot:spring-boot-starter-webflux-test": 5326534, - "org.springframework.boot:spring-boot-starter-webmvc-test": -2111356331, - "org.springframework.boot:spring-boot-webclient": -1835278023, - "org.springframework.cloud:spring-cloud-commons": -673836000, - "org.springframework.cloud:spring-cloud-context": -1724959431, - "org.springframework.cloud:spring-cloud-dependencies": 46341733, - "org.springframework.cloud:spring-cloud-starter-bootstrap": -213001704, - "org.springframework.security:spring-security-test": 1317137564, - "org.testcontainers:testcontainers-bom": 483223872, - "org.testcontainers:testcontainers-cassandra": -1027104267, - "org.testcontainers:testcontainers-junit-jupiter": -918230293, - "org.wiremock:wiremock-standalone": -1242936487, - "repositories": -1624298853, - "software.amazon.awssdk:regions": -1274787064, - "tools.jackson.module:jackson-module-blackbird": -423541381 - }, - "__RESOLVED_ARTIFACTS_HASH": { - "aopalliance:aopalliance": -1763688673, - "aopalliance:aopalliance:jar:sources": 758113234, - "args4j:args4j": -572028113, - "args4j:args4j:jar:sources": 74047526, - "at.yawk.lz4:lz4-java": -1985362494, - "at.yawk.lz4:lz4-java:jar:sources": -2141970549, - "ch.qos.logback:logback-classic": -619930806, - "ch.qos.logback:logback-classic:jar:sources": -390128445, - "ch.qos.logback:logback-core": -1554021729, - "ch.qos.logback:logback-core:jar:sources": 77538609, - "com.datastax.cassandra:cassandra-driver-core": -681774303, - "com.datastax.cassandra:cassandra-driver-core:jar:sources": -2045236197, - "com.datastax.oss:native-protocol": 447263174, - "com.datastax.oss:native-protocol:jar:sources": 396473389, - "com.fasterxml.jackson.core:jackson-annotations": 1407322119, - "com.fasterxml.jackson.core:jackson-annotations:jar:sources": -1408285999, - "com.fasterxml.jackson.core:jackson-core": -1715692416, - "com.fasterxml.jackson.core:jackson-core:jar:sources": 1404881423, - "com.fasterxml.jackson.core:jackson-databind": -1922910990, - "com.fasterxml.jackson.core:jackson-databind:jar:sources": -802304801, - "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml": 2129087476, - "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:jar:sources": -175522790, - "com.fasterxml.jackson.datatype:jackson-datatype-jsr310": 1940996847, - "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:jar:sources": 1241536710, - "com.fasterxml:classmate": -1468141616, - "com.fasterxml:classmate:jar:sources": -179492269, - "com.github.ben-manes.caffeine:caffeine": 96455941, - "com.github.ben-manes.caffeine:caffeine:jar:sources": -967473790, - "com.github.ben-manes.caffeine:guava": 1187631417, - "com.github.ben-manes.caffeine:guava:jar:sources": 1956210603, - "com.github.docker-java:docker-java-api": 1857041788, - "com.github.docker-java:docker-java-api:jar:sources": 300128277, - "com.github.docker-java:docker-java-transport": 689281477, - "com.github.docker-java:docker-java-transport-zerodep": -1848983763, - "com.github.docker-java:docker-java-transport-zerodep:jar:sources": 1882881505, - "com.github.docker-java:docker-java-transport:jar:sources": 864522470, - "com.github.java-json-tools:btf": -1747700664, - "com.github.java-json-tools:btf:jar:sources": 1539011915, - "com.github.java-json-tools:jackson-coreutils": 2047023685, - "com.github.java-json-tools:jackson-coreutils:jar:sources": 323093438, - "com.github.java-json-tools:json-patch": -399792119, - "com.github.java-json-tools:json-patch:jar:sources": -1320375757, - "com.github.java-json-tools:msg-simple": 986302814, - "com.github.java-json-tools:msg-simple:jar:sources": 1013495835, - "com.github.jnr:jffi": 1952487985, - "com.github.jnr:jffi:jar:native": 1426144838, - "com.github.jnr:jffi:jar:sources": -252446498, - "com.github.jnr:jnr-constants": 1522135714, - "com.github.jnr:jnr-constants:jar:sources": -1920781516, - "com.github.jnr:jnr-ffi": 1663045836, - "com.github.jnr:jnr-ffi:jar:sources": -150631029, - "com.github.jnr:jnr-posix": 1594911544, - "com.github.jnr:jnr-posix:jar:sources": -992203730, - "com.github.jnr:jnr-x86asm": 1097235222, - "com.github.jnr:jnr-x86asm:jar:sources": -1784079536, - "com.github.stephenc.jcip:jcip-annotations": -121928928, - "com.github.stephenc.jcip:jcip-annotations:jar:sources": -2051941468, - "com.google.code.findbugs:jsr305": 1838181273, - "com.google.errorprone:error_prone_annotations": -1266099896, - "com.google.errorprone:error_prone_annotations:jar:sources": 936701586, - "com.google.guava:failureaccess": -56291903, - "com.google.guava:failureaccess:jar:sources": -820168004, - "com.google.guava:guava": -1132194940, - "com.google.guava:guava:jar:sources": -1505508770, - "com.google.guava:listenablefuture": 1588902908, - "com.google.j2objc:j2objc-annotations": -2074422376, - "com.google.j2objc:j2objc-annotations:jar:sources": -597974451, - "com.jayway.jsonpath:json-path": 626712679, - "com.jayway.jsonpath:json-path:jar:sources": -343427302, - "com.nimbusds:content-type": -444977683, - "com.nimbusds:content-type:jar:sources": -634646164, - "com.nimbusds:lang-tag": -694347345, - "com.nimbusds:lang-tag:jar:sources": 266930896, - "com.nimbusds:nimbus-jose-jwt": -286981492, - "com.nimbusds:nimbus-jose-jwt:jar:sources": 24935039, - "com.nimbusds:oauth2-oidc-sdk": -498816278, - "com.nimbusds:oauth2-oidc-sdk:jar:sources": 1276926642, - "com.squareup.okhttp3:okhttp-jvm": -314031254, - "com.squareup.okhttp3:okhttp-jvm:jar:sources": 447067750, - "com.squareup.okio:okio-jvm": -391120506, - "com.squareup.okio:okio-jvm:jar:sources": 1375453359, - "com.typesafe:config": 96906638, - "com.typesafe:config:jar:sources": -892423283, - "com.vaadin.external.google:android-json": -1531950165, - "com.vaadin.external.google:android-json:jar:sources": -116078240, - "commons-codec:commons-codec": -835030550, - "commons-codec:commons-codec:jar:sources": 990790236, - "commons-io:commons-io": -1021273518, - "commons-io:commons-io:jar:sources": 2066085027, - "commons-logging:commons-logging": 1061992981, - "commons-logging:commons-logging:jar:sources": 1867783947, - "io.cloudevents:cloudevents-api": -617548735, - "io.cloudevents:cloudevents-api:jar:sources": 924762007, - "io.cloudevents:cloudevents-core": -688560325, - "io.cloudevents:cloudevents-core:jar:sources": 223693387, - "io.cloudevents:cloudevents-json-jackson": -807987873, - "io.cloudevents:cloudevents-json-jackson:jar:sources": -166751855, - "io.dropwizard.metrics:metrics-core": 1029463962, - "io.dropwizard.metrics:metrics-core:jar:sources": 1607397396, - "io.micrometer:context-propagation": -1130727419, - "io.micrometer:context-propagation:jar:sources": -1135393170, - "io.micrometer:micrometer-commons": 326693391, - "io.micrometer:micrometer-commons:jar:sources": -57818626, - "io.micrometer:micrometer-core": 829567043, - "io.micrometer:micrometer-core:jar:sources": 265175165, - "io.micrometer:micrometer-jakarta9": -15933884, - "io.micrometer:micrometer-jakarta9:jar:sources": 1275065742, - "io.micrometer:micrometer-observation": -319705914, - "io.micrometer:micrometer-observation-test": -1818068529, - "io.micrometer:micrometer-observation-test:jar:sources": 117373145, - "io.micrometer:micrometer-observation:jar:sources": 1279306785, - "io.micrometer:micrometer-tracing": -109714346, - "io.micrometer:micrometer-tracing-bridge-otel": 975863312, - "io.micrometer:micrometer-tracing-bridge-otel:jar:sources": 1300289348, - "io.micrometer:micrometer-tracing:jar:sources": 266031561, - "io.nats:jnats": 1273546329, - "io.nats:jnats:jar:sources": 194791155, - "io.netty:netty-buffer": -1740802869, - "io.netty:netty-buffer:jar:sources": 622468392, - "io.netty:netty-codec-base": -1042304993, - "io.netty:netty-codec-base:jar:sources": -612797714, - "io.netty:netty-codec-classes-quic": -702276906, - "io.netty:netty-codec-classes-quic:jar:sources": 1548159851, - "io.netty:netty-codec-compression": -789209831, - "io.netty:netty-codec-compression:jar:sources": -1402960067, - "io.netty:netty-codec-dns": 81169397, - "io.netty:netty-codec-dns:jar:sources": -1086447458, - "io.netty:netty-codec-http": -95764323, - "io.netty:netty-codec-http2": 544878123, - "io.netty:netty-codec-http2:jar:sources": -83820759, - "io.netty:netty-codec-http3": -194972071, - "io.netty:netty-codec-http3:jar:sources": 1699772273, - "io.netty:netty-codec-http:jar:sources": -116842177, - "io.netty:netty-codec-native-quic:jar:linux-aarch_64": -2075260519, - "io.netty:netty-codec-native-quic:jar:linux-x86_64": -1982796133, - "io.netty:netty-codec-native-quic:jar:osx-aarch_64": -632727283, - "io.netty:netty-codec-native-quic:jar:osx-x86_64": 1253945631, - "io.netty:netty-codec-native-quic:jar:sources": -986328940, - "io.netty:netty-codec-native-quic:jar:windows-x86_64": -115110822, - "io.netty:netty-codec-socks": 336734625, - "io.netty:netty-codec-socks:jar:sources": -1241946572, - "io.netty:netty-common": -1557278455, - "io.netty:netty-common:jar:sources": -467395659, - "io.netty:netty-handler": -1757690436, - "io.netty:netty-handler-proxy": -892232184, - "io.netty:netty-handler-proxy:jar:sources": -216040607, - "io.netty:netty-handler:jar:sources": -1379156289, - "io.netty:netty-resolver": -1571627366, - "io.netty:netty-resolver-dns": 954988644, - "io.netty:netty-resolver-dns-classes-macos": -441663783, - "io.netty:netty-resolver-dns-classes-macos:jar:sources": 776580055, - "io.netty:netty-resolver-dns-native-macos:jar:osx-x86_64": -354533951, - "io.netty:netty-resolver-dns-native-macos:jar:sources": -120739665, - "io.netty:netty-resolver-dns:jar:sources": 1652413066, - "io.netty:netty-resolver:jar:sources": 2084403340, - "io.netty:netty-transport": 44555455, - "io.netty:netty-transport-classes-epoll": -588470325, - "io.netty:netty-transport-classes-epoll:jar:sources": -1697662320, - "io.netty:netty-transport-native-epoll:jar:linux-x86_64": -563523863, - "io.netty:netty-transport-native-epoll:jar:sources": -1040259378, - "io.netty:netty-transport-native-unix-common": -166041147, - "io.netty:netty-transport-native-unix-common:jar:sources": -1674017507, - "io.netty:netty-transport:jar:sources": -820889350, - "io.opentelemetry.semconv:opentelemetry-semconv": 1195624836, - "io.opentelemetry.semconv:opentelemetry-semconv:jar:sources": -893534237, - "io.opentelemetry:opentelemetry-api": 885391408, - "io.opentelemetry:opentelemetry-api:jar:sources": -1404426315, - "io.opentelemetry:opentelemetry-common": 676580228, - "io.opentelemetry:opentelemetry-common:jar:sources": 1797051654, - "io.opentelemetry:opentelemetry-context": 747746024, - "io.opentelemetry:opentelemetry-context:jar:sources": 560193252, - "io.opentelemetry:opentelemetry-exporter-common": 42591217, - "io.opentelemetry:opentelemetry-exporter-common:jar:sources": 2032641450, - "io.opentelemetry:opentelemetry-exporter-otlp": 1346623356, - "io.opentelemetry:opentelemetry-exporter-otlp-common": -2043450521, - "io.opentelemetry:opentelemetry-exporter-otlp-common:jar:sources": -1909225648, - "io.opentelemetry:opentelemetry-exporter-otlp:jar:sources": -1536215787, - "io.opentelemetry:opentelemetry-exporter-sender-okhttp": -2026614746, - "io.opentelemetry:opentelemetry-exporter-sender-okhttp:jar:sources": -1387239258, - "io.opentelemetry:opentelemetry-extension-trace-propagators": -480191373, - "io.opentelemetry:opentelemetry-extension-trace-propagators:jar:sources": 517135536, - "io.opentelemetry:opentelemetry-sdk": -369820209, - "io.opentelemetry:opentelemetry-sdk-common": -1049102876, - "io.opentelemetry:opentelemetry-sdk-common:jar:sources": -1004050981, - "io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi": -928104061, - "io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi:jar:sources": -1626691242, - "io.opentelemetry:opentelemetry-sdk-logs": -1310291573, - "io.opentelemetry:opentelemetry-sdk-logs:jar:sources": 1572252989, - "io.opentelemetry:opentelemetry-sdk-metrics": -2038069517, - "io.opentelemetry:opentelemetry-sdk-metrics:jar:sources": -323022280, - "io.opentelemetry:opentelemetry-sdk-testing": 19519171, - "io.opentelemetry:opentelemetry-sdk-testing:jar:sources": -578292790, - "io.opentelemetry:opentelemetry-sdk-trace": 2083919234, - "io.opentelemetry:opentelemetry-sdk-trace:jar:sources": 818630467, - "io.opentelemetry:opentelemetry-sdk:jar:sources": -1478160490, - "io.projectreactor.netty:reactor-netty-core": -1310988391, - "io.projectreactor.netty:reactor-netty-core:jar:sources": 160926198, - "io.projectreactor.netty:reactor-netty-http": -1289714469, - "io.projectreactor.netty:reactor-netty-http:jar:sources": 1066415166, - "io.projectreactor:reactor-core": -745004757, - "io.projectreactor:reactor-core:jar:sources": -717353230, - "io.projectreactor:reactor-test": 947112823, - "io.projectreactor:reactor-test:jar:sources": 383025302, - "io.swagger.core.v3:swagger-annotations-jakarta": -842428034, - "io.swagger.core.v3:swagger-annotations-jakarta:jar:sources": 133934665, - "io.swagger.core.v3:swagger-core-jakarta": -439612282, - "io.swagger.core.v3:swagger-core-jakarta:jar:sources": 449241668, - "io.swagger.core.v3:swagger-models-jakarta": -1439553498, - "io.swagger.core.v3:swagger-models-jakarta:jar:sources": 2092063988, - "jakarta.activation:jakarta.activation-api": -1560267684, - "jakarta.activation:jakarta.activation-api:jar:sources": 759160467, - "jakarta.annotation:jakarta.annotation-api": -1904975463, - "jakarta.annotation:jakarta.annotation-api:jar:sources": -247204066, - "jakarta.servlet:jakarta.servlet-api": 972614879, - "jakarta.servlet:jakarta.servlet-api:jar:sources": 2070183472, - "jakarta.validation:jakarta.validation-api": 666686261, - "jakarta.validation:jakarta.validation-api:jar:sources": -131796339, - "jakarta.xml.bind:jakarta.xml.bind-api": 1157993223, - "jakarta.xml.bind:jakarta.xml.bind-api:jar:sources": -945798747, - "net.bytebuddy:byte-buddy": 383637760, - "net.bytebuddy:byte-buddy-agent": -1380713096, - "net.bytebuddy:byte-buddy-agent:jar:sources": 564051985, - "net.bytebuddy:byte-buddy:jar:sources": -1360611642, - "net.java.dev.jna:jna": -1951542637, - "net.java.dev.jna:jna:jar:sources": -545183654, - "net.minidev:accessors-smart": -325667575, - "net.minidev:accessors-smart:jar:sources": -124254155, - "net.minidev:json-smart": 1673421716, - "net.minidev:json-smart:jar:sources": -1084786431, - "org.apache.cassandra:java-driver-core": 42196324, - "org.apache.cassandra:java-driver-core:jar:sources": -1508814165, - "org.apache.cassandra:java-driver-guava-shaded": 568990261, - "org.apache.cassandra:java-driver-guava-shaded:jar:sources": 1291502230, - "org.apache.cassandra:java-driver-metrics-micrometer": -93817708, - "org.apache.cassandra:java-driver-metrics-micrometer:jar:sources": -2019023443, - "org.apache.cassandra:java-driver-query-builder": 303143232, - "org.apache.cassandra:java-driver-query-builder:jar:sources": -1665027563, - "org.apache.commons:commons-compress": -134181577, - "org.apache.commons:commons-compress:jar:sources": -1845261624, - "org.apache.commons:commons-lang3": 759645435, - "org.apache.commons:commons-lang3:jar:sources": 1890991939, - "org.apache.logging.log4j:log4j-api": 191755139, - "org.apache.logging.log4j:log4j-api:jar:sources": 1226633672, - "org.apache.logging.log4j:log4j-to-slf4j": 357996538, - "org.apache.logging.log4j:log4j-to-slf4j:jar:sources": -1847454236, - "org.apache.tomcat.embed:tomcat-embed-core": -2079786590, - "org.apache.tomcat.embed:tomcat-embed-core:jar:sources": -745705587, - "org.apache.tomcat.embed:tomcat-embed-el": -727131551, - "org.apache.tomcat.embed:tomcat-embed-el:jar:sources": 1938415424, - "org.apache.tomcat.embed:tomcat-embed-websocket": 1876889190, - "org.apache.tomcat.embed:tomcat-embed-websocket:jar:sources": -1809736441, - "org.apiguardian:apiguardian-api": -1579303244, - "org.apiguardian:apiguardian-api:jar:sources": 768152577, - "org.assertj:assertj-core": -536770136, - "org.assertj:assertj-core:jar:sources": -1826278818, - "org.awaitility:awaitility": 755971515, - "org.awaitility:awaitility:jar:sources": -1322650242, - "org.bouncycastle:bcprov-jdk18on": -709136978, - "org.bouncycastle:bcprov-jdk18on:jar:sources": 106463766, - "org.bouncycastle:bcprov-lts8on": 973431866, - "org.bouncycastle:bcprov-lts8on:jar:sources": -196135755, - "org.hamcrest:hamcrest": 1116842741, - "org.hamcrest:hamcrest:jar:sources": -996443755, - "org.hdrhistogram:HdrHistogram": 1379183334, - "org.hdrhistogram:HdrHistogram:jar:sources": -1235434218, - "org.hibernate.validator:hibernate-validator": 1976561513, - "org.hibernate.validator:hibernate-validator:jar:sources": 367698734, - "org.jacoco:org.jacoco.agent:jar:runtime": -111724801, - "org.jacoco:org.jacoco.agent:jar:sources": 1432778515, - "org.jacoco:org.jacoco.cli": 2021870981, - "org.jacoco:org.jacoco.cli:jar:sources": 47843733, - "org.jacoco:org.jacoco.core": 579589309, - "org.jacoco:org.jacoco.core:jar:sources": -458393909, - "org.jacoco:org.jacoco.report": -1287135579, - "org.jacoco:org.jacoco.report:jar:sources": -2068401168, - "org.jboss.logging:jboss-logging": -2136063667, - "org.jboss.logging:jboss-logging:jar:sources": 2066441551, - "org.jetbrains.kotlin:kotlin-stdlib": -570435334, - "org.jetbrains.kotlin:kotlin-stdlib:jar:sources": 1404576391, - "org.jetbrains:annotations": 643765179, - "org.jetbrains:annotations:jar:sources": 1009912224, - "org.jspecify:jspecify": -1402924792, - "org.jspecify:jspecify:jar:sources": -841008091, - "org.junit.jupiter:junit-jupiter": -313198921, - "org.junit.jupiter:junit-jupiter-api": 80944698, - "org.junit.jupiter:junit-jupiter-api:jar:sources": -1650654944, - "org.junit.jupiter:junit-jupiter-engine": 730848020, - "org.junit.jupiter:junit-jupiter-engine:jar:sources": 1805473715, - "org.junit.jupiter:junit-jupiter-params": -1923494954, - "org.junit.jupiter:junit-jupiter-params:jar:sources": 1561682205, - "org.junit.jupiter:junit-jupiter:jar:sources": 1809716175, - "org.junit.platform:junit-platform-commons": -1304725543, - "org.junit.platform:junit-platform-commons:jar:sources": -139331649, - "org.junit.platform:junit-platform-console-standalone": -406221538, - "org.junit.platform:junit-platform-console-standalone:jar:sources": -103511349, - "org.junit.platform:junit-platform-engine": -748595950, - "org.junit.platform:junit-platform-engine:jar:sources": -191078126, - "org.latencyutils:LatencyUtils": 1082471286, - "org.latencyutils:LatencyUtils:jar:sources": 1894864087, - "org.mockito:mockito-core": 734095861, - "org.mockito:mockito-core:jar:sources": 1757924088, - "org.mockito:mockito-junit-jupiter": -501680015, - "org.mockito:mockito-junit-jupiter:jar:sources": -1281757309, - "org.objenesis:objenesis": 1083875484, - "org.objenesis:objenesis:jar:sources": 703772823, - "org.opentest4j:opentest4j": 793813175, - "org.opentest4j:opentest4j:jar:sources": 1210936723, - "org.ow2.asm:asm": 716467505, - "org.ow2.asm:asm-analysis": 129370658, - "org.ow2.asm:asm-analysis:jar:sources": -2126326860, - "org.ow2.asm:asm-commons": 530868933, - "org.ow2.asm:asm-commons:jar:sources": 1248498766, - "org.ow2.asm:asm-tree": 369430530, - "org.ow2.asm:asm-tree:jar:sources": -1850601298, - "org.ow2.asm:asm-util": -803635337, - "org.ow2.asm:asm-util:jar:sources": 51483494, - "org.ow2.asm:asm:jar:sources": -947428423, - "org.projectlombok:lombok": -1095750717, - "org.projectlombok:lombok:jar:sources": 1834083797, - "org.reactivestreams:reactive-streams": -1996658890, - "org.reactivestreams:reactive-streams:jar:sources": -258070571, - "org.rnorth.duct-tape:duct-tape": 615461963, - "org.rnorth.duct-tape:duct-tape:jar:sources": 427419407, - "org.skyscreamer:jsonassert": -1571197746, - "org.skyscreamer:jsonassert:jar:sources": -392658057, - "org.slf4j:jul-to-slf4j": -911724984, - "org.slf4j:jul-to-slf4j:jar:sources": -662175280, - "org.slf4j:slf4j-api": -1249720338, - "org.slf4j:slf4j-api:jar:sources": -297247278, - "org.springdoc:springdoc-openapi-starter-common": -50810541, - "org.springdoc:springdoc-openapi-starter-common:jar:sources": 776689800, - "org.springdoc:springdoc-openapi-starter-webflux-api": -2128144311, - "org.springdoc:springdoc-openapi-starter-webflux-api:jar:sources": -1775632648, - "org.springdoc:springdoc-openapi-starter-webmvc-api": 479427887, - "org.springdoc:springdoc-openapi-starter-webmvc-api:jar:sources": -1201450538, - "org.springframework.boot:spring-boot": -1519545366, - "org.springframework.boot:spring-boot-actuator": 1868004981, - "org.springframework.boot:spring-boot-actuator-autoconfigure": 437017470, - "org.springframework.boot:spring-boot-actuator-autoconfigure:jar:sources": 1090885133, - "org.springframework.boot:spring-boot-actuator:jar:sources": 1545596535, - "org.springframework.boot:spring-boot-autoconfigure": -491644458, - "org.springframework.boot:spring-boot-autoconfigure:jar:sources": 562322138, - "org.springframework.boot:spring-boot-cassandra": 1880514148, - "org.springframework.boot:spring-boot-cassandra:jar:sources": -285158244, - "org.springframework.boot:spring-boot-data-cassandra": -1136414714, - "org.springframework.boot:spring-boot-data-cassandra-test": 1687171774, - "org.springframework.boot:spring-boot-data-cassandra-test:jar:sources": -601584645, - "org.springframework.boot:spring-boot-data-cassandra:jar:sources": 73983427, - "org.springframework.boot:spring-boot-data-commons": 1096447250, - "org.springframework.boot:spring-boot-data-commons:jar:sources": 867332098, - "org.springframework.boot:spring-boot-health": 988376788, - "org.springframework.boot:spring-boot-health:jar:sources": 1156692002, - "org.springframework.boot:spring-boot-http-client": -294534102, - "org.springframework.boot:spring-boot-http-client:jar:sources": 881974750, - "org.springframework.boot:spring-boot-http-codec": 434302862, - "org.springframework.boot:spring-boot-http-codec:jar:sources": 585983495, - "org.springframework.boot:spring-boot-http-converter": -1456188332, - "org.springframework.boot:spring-boot-http-converter:jar:sources": 678862764, - "org.springframework.boot:spring-boot-jackson": -886310726, - "org.springframework.boot:spring-boot-jackson:jar:sources": -928970153, - "org.springframework.boot:spring-boot-micrometer-metrics": -971815116, - "org.springframework.boot:spring-boot-micrometer-metrics-test": 1059861465, - "org.springframework.boot:spring-boot-micrometer-metrics-test:jar:sources": 539702709, - "org.springframework.boot:spring-boot-micrometer-metrics:jar:sources": -1326033951, - "org.springframework.boot:spring-boot-micrometer-observation": -515345138, - "org.springframework.boot:spring-boot-micrometer-observation:jar:sources": -1374159176, - "org.springframework.boot:spring-boot-micrometer-tracing": -1769177987, - "org.springframework.boot:spring-boot-micrometer-tracing-opentelemetry": 686601187, - "org.springframework.boot:spring-boot-micrometer-tracing-opentelemetry:jar:sources": 2058843242, - "org.springframework.boot:spring-boot-micrometer-tracing:jar:sources": -531678236, - "org.springframework.boot:spring-boot-netty": -1868279944, - "org.springframework.boot:spring-boot-netty:jar:sources": 2079852054, - "org.springframework.boot:spring-boot-opentelemetry": -1423093456, - "org.springframework.boot:spring-boot-opentelemetry:jar:sources": 1840051882, - "org.springframework.boot:spring-boot-persistence": -1485790991, - "org.springframework.boot:spring-boot-persistence:jar:sources": -1027448649, - "org.springframework.boot:spring-boot-reactor": 1298372962, - "org.springframework.boot:spring-boot-reactor-netty": 1434335970, - "org.springframework.boot:spring-boot-reactor-netty:jar:sources": -732886702, - "org.springframework.boot:spring-boot-reactor:jar:sources": -1373689055, - "org.springframework.boot:spring-boot-restclient": -67067992, - "org.springframework.boot:spring-boot-restclient:jar:sources": -1554622109, - "org.springframework.boot:spring-boot-resttestclient": 1078416021, - "org.springframework.boot:spring-boot-resttestclient:jar:sources": 1128597445, - "org.springframework.boot:spring-boot-security": -528218864, - "org.springframework.boot:spring-boot-security-oauth2-client": 1972725629, - "org.springframework.boot:spring-boot-security-oauth2-client:jar:sources": -1211778370, - "org.springframework.boot:spring-boot-security-oauth2-resource-server": -1021125134, - "org.springframework.boot:spring-boot-security-oauth2-resource-server:jar:sources": 1301519418, - "org.springframework.boot:spring-boot-security-test": -1810341741, - "org.springframework.boot:spring-boot-security-test:jar:sources": -311791400, - "org.springframework.boot:spring-boot-security:jar:sources": -1644906067, - "org.springframework.boot:spring-boot-servlet": -1040246830, - "org.springframework.boot:spring-boot-servlet:jar:sources": 1162002660, - "org.springframework.boot:spring-boot-starter": 191814674, - "org.springframework.boot:spring-boot-starter-actuator": 1761935967, - "org.springframework.boot:spring-boot-starter-actuator-test": 910069034, - "org.springframework.boot:spring-boot-starter-actuator-test:jar:sources": 314973026, - "org.springframework.boot:spring-boot-starter-actuator:jar:sources": -2079433447, - "org.springframework.boot:spring-boot-starter-data-cassandra": -1305411192, - "org.springframework.boot:spring-boot-starter-data-cassandra-test": 1049224325, - "org.springframework.boot:spring-boot-starter-data-cassandra-test:jar:sources": 464889083, - "org.springframework.boot:spring-boot-starter-data-cassandra:jar:sources": 62860247, - "org.springframework.boot:spring-boot-starter-jackson": 211326145, - "org.springframework.boot:spring-boot-starter-jackson-test": 538761659, - "org.springframework.boot:spring-boot-starter-jackson-test:jar:sources": 1211585483, - "org.springframework.boot:spring-boot-starter-jackson:jar:sources": 1689728463, - "org.springframework.boot:spring-boot-starter-logging": 51215582, - "org.springframework.boot:spring-boot-starter-logging:jar:sources": 1271111015, - "org.springframework.boot:spring-boot-starter-micrometer-metrics": 546085162, - "org.springframework.boot:spring-boot-starter-micrometer-metrics-test": -835747019, - "org.springframework.boot:spring-boot-starter-micrometer-metrics-test:jar:sources": 1830581000, - "org.springframework.boot:spring-boot-starter-micrometer-metrics:jar:sources": -1130818080, - "org.springframework.boot:spring-boot-starter-reactor-netty": 812139334, - "org.springframework.boot:spring-boot-starter-reactor-netty:jar:sources": 1164956430, - "org.springframework.boot:spring-boot-starter-security": 1058973423, - "org.springframework.boot:spring-boot-starter-security-oauth2-client": -1355057519, - "org.springframework.boot:spring-boot-starter-security-oauth2-client:jar:sources": 1707609356, - "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server": -265511875, - "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server-test": -17384836, - "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server-test:jar:sources": -746940353, - "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server:jar:sources": 2136275088, - "org.springframework.boot:spring-boot-starter-security-test": 1690721902, - "org.springframework.boot:spring-boot-starter-security-test:jar:sources": 468207576, - "org.springframework.boot:spring-boot-starter-security:jar:sources": -1720617031, - "org.springframework.boot:spring-boot-starter-test": -1087542039, - "org.springframework.boot:spring-boot-starter-test:jar:sources": -480189945, - "org.springframework.boot:spring-boot-starter-tomcat": -521361670, - "org.springframework.boot:spring-boot-starter-tomcat-runtime": -1912812722, - "org.springframework.boot:spring-boot-starter-tomcat-runtime:jar:sources": 1011838045, - "org.springframework.boot:spring-boot-starter-tomcat:jar:sources": 1319064174, - "org.springframework.boot:spring-boot-starter-validation": -321633530, - "org.springframework.boot:spring-boot-starter-validation:jar:sources": -1002865328, - "org.springframework.boot:spring-boot-starter-webflux": -818164168, - "org.springframework.boot:spring-boot-starter-webflux-test": -415179163, - "org.springframework.boot:spring-boot-starter-webflux-test:jar:sources": -1654084055, - "org.springframework.boot:spring-boot-starter-webflux:jar:sources": 1008425882, - "org.springframework.boot:spring-boot-starter-webmvc": 170962824, - "org.springframework.boot:spring-boot-starter-webmvc-test": -1343848488, - "org.springframework.boot:spring-boot-starter-webmvc-test:jar:sources": -1751111514, - "org.springframework.boot:spring-boot-starter-webmvc:jar:sources": -2120956724, - "org.springframework.boot:spring-boot-starter:jar:sources": 1138639700, - "org.springframework.boot:spring-boot-test": -927444958, - "org.springframework.boot:spring-boot-test-autoconfigure": -669950838, - "org.springframework.boot:spring-boot-test-autoconfigure:jar:sources": 392165449, - "org.springframework.boot:spring-boot-test:jar:sources": -1764708648, - "org.springframework.boot:spring-boot-tomcat": -1113349252, - "org.springframework.boot:spring-boot-tomcat:jar:sources": -1529683395, - "org.springframework.boot:spring-boot-validation": 1270368638, - "org.springframework.boot:spring-boot-validation:jar:sources": -1684576067, - "org.springframework.boot:spring-boot-web-server": 285708094, - "org.springframework.boot:spring-boot-web-server:jar:sources": 990724443, - "org.springframework.boot:spring-boot-webclient": -507647, - "org.springframework.boot:spring-boot-webclient:jar:sources": 71538120, - "org.springframework.boot:spring-boot-webflux": -231291542, - "org.springframework.boot:spring-boot-webflux-test": 1600114323, - "org.springframework.boot:spring-boot-webflux-test:jar:sources": 1452173744, - "org.springframework.boot:spring-boot-webflux:jar:sources": -1118813321, - "org.springframework.boot:spring-boot-webmvc": -2104103221, - "org.springframework.boot:spring-boot-webmvc-test": 749235095, - "org.springframework.boot:spring-boot-webmvc-test:jar:sources": 444837917, - "org.springframework.boot:spring-boot-webmvc:jar:sources": -1895028417, - "org.springframework.boot:spring-boot-webtestclient": -705991472, - "org.springframework.boot:spring-boot-webtestclient:jar:sources": -542316343, - "org.springframework.boot:spring-boot:jar:sources": 580880564, - "org.springframework.cloud:spring-cloud-commons": -788453967, - "org.springframework.cloud:spring-cloud-commons:jar:sources": 1320616004, - "org.springframework.cloud:spring-cloud-context": 1118197933, - "org.springframework.cloud:spring-cloud-context:jar:sources": -1413797918, - "org.springframework.cloud:spring-cloud-starter": -1812063683, - "org.springframework.cloud:spring-cloud-starter-bootstrap": -1263482746, - "org.springframework.cloud:spring-cloud-starter-bootstrap:jar:sources": 1965832056, - "org.springframework.data:spring-data-cassandra": -1548120966, - "org.springframework.data:spring-data-cassandra:jar:sources": -1628107854, - "org.springframework.data:spring-data-commons": 1312199320, - "org.springframework.data:spring-data-commons:jar:sources": 544548950, - "org.springframework.security:spring-security-config": 2001744589, - "org.springframework.security:spring-security-config:jar:sources": -756968726, - "org.springframework.security:spring-security-core": -1251894794, - "org.springframework.security:spring-security-core:jar:sources": 1285888871, - "org.springframework.security:spring-security-crypto": 424824057, - "org.springframework.security:spring-security-crypto:jar:sources": 1862561396, - "org.springframework.security:spring-security-oauth2-client": -1975050683, - "org.springframework.security:spring-security-oauth2-client:jar:sources": 1833974239, - "org.springframework.security:spring-security-oauth2-core": -1658804453, - "org.springframework.security:spring-security-oauth2-core:jar:sources": -948845785, - "org.springframework.security:spring-security-oauth2-jose": 502613895, - "org.springframework.security:spring-security-oauth2-jose:jar:sources": 17294361, - "org.springframework.security:spring-security-oauth2-resource-server": -1894007153, - "org.springframework.security:spring-security-oauth2-resource-server:jar:sources": -1508178760, - "org.springframework.security:spring-security-test": 1672796517, - "org.springframework.security:spring-security-test:jar:sources": -1326480212, - "org.springframework.security:spring-security-web": -1696304083, - "org.springframework.security:spring-security-web:jar:sources": 1443816202, - "org.springframework:spring-aop": -819786825, - "org.springframework:spring-aop:jar:sources": 1924976574, - "org.springframework:spring-beans": -698130853, - "org.springframework:spring-beans:jar:sources": -2147408778, - "org.springframework:spring-context": -846077202, - "org.springframework:spring-context:jar:sources": -1263444176, - "org.springframework:spring-core": -253727183, - "org.springframework:spring-core:jar:sources": -173347576, - "org.springframework:spring-expression": 1724609785, - "org.springframework:spring-expression:jar:sources": 1135225455, - "org.springframework:spring-test": -279979944, - "org.springframework:spring-test:jar:sources": -6017836, - "org.springframework:spring-tx": 1899606770, - "org.springframework:spring-tx:jar:sources": -1007028336, - "org.springframework:spring-web": 2084009704, - "org.springframework:spring-web:jar:sources": 1608360284, - "org.springframework:spring-webflux": 1763806581, - "org.springframework:spring-webflux:jar:sources": -1419709374, - "org.springframework:spring-webmvc": 56813816, - "org.springframework:spring-webmvc:jar:sources": -837106767, - "org.testcontainers:testcontainers": 450183679, - "org.testcontainers:testcontainers-cassandra": -1886187917, - "org.testcontainers:testcontainers-cassandra:jar:sources": 2024290088, - "org.testcontainers:testcontainers-database-commons": -1213526598, - "org.testcontainers:testcontainers-database-commons:jar:sources": 315333060, - "org.testcontainers:testcontainers-junit-jupiter": -1827576744, - "org.testcontainers:testcontainers-junit-jupiter:jar:sources": 975697823, - "org.testcontainers:testcontainers:jar:sources": 76092129, - "org.wiremock:wiremock-standalone": -1817681233, - "org.wiremock:wiremock-standalone:jar:sources": 695361099, - "org.xmlunit:xmlunit-core": 1938864481, - "org.xmlunit:xmlunit-core:jar:sources": -54376142, - "org.yaml:snakeyaml": -1432706414, - "org.yaml:snakeyaml:jar:sources": 393768628, - "software.amazon.awssdk:annotations": -647669452, - "software.amazon.awssdk:annotations:jar:sources": -277384386, - "software.amazon.awssdk:checksums": 573213413, - "software.amazon.awssdk:checksums-spi": -720493267, - "software.amazon.awssdk:checksums-spi:jar:sources": -650776626, - "software.amazon.awssdk:checksums:jar:sources": -241565759, - "software.amazon.awssdk:endpoints-spi": 1412926322, - "software.amazon.awssdk:endpoints-spi:jar:sources": -1092637607, - "software.amazon.awssdk:http-auth-aws": -589182304, - "software.amazon.awssdk:http-auth-aws:jar:sources": -993506252, - "software.amazon.awssdk:http-auth-spi": -45686548, - "software.amazon.awssdk:http-auth-spi:jar:sources": -1486999869, - "software.amazon.awssdk:http-client-spi": 1386281563, - "software.amazon.awssdk:http-client-spi:jar:sources": 541891925, - "software.amazon.awssdk:identity-spi": -969758372, - "software.amazon.awssdk:identity-spi:jar:sources": -1418587191, - "software.amazon.awssdk:json-utils": -1666742251, - "software.amazon.awssdk:json-utils:jar:sources": 1618084806, - "software.amazon.awssdk:metrics-spi": -500500368, - "software.amazon.awssdk:metrics-spi:jar:sources": -1496041869, - "software.amazon.awssdk:profiles": 1556987661, - "software.amazon.awssdk:profiles:jar:sources": 517790158, - "software.amazon.awssdk:regions": 1394259783, - "software.amazon.awssdk:regions:jar:sources": 927040140, - "software.amazon.awssdk:retries": 1273159411, - "software.amazon.awssdk:retries-spi": 1857446587, - "software.amazon.awssdk:retries-spi:jar:sources": -974151310, - "software.amazon.awssdk:retries:jar:sources": 1826499536, - "software.amazon.awssdk:sdk-core": 1641186658, - "software.amazon.awssdk:sdk-core:jar:sources": -769872481, - "software.amazon.awssdk:third-party-jackson-core": -1062653941, - "software.amazon.awssdk:third-party-jackson-core:jar:sources": -230379012, - "software.amazon.awssdk:utils": 1497168994, - "software.amazon.awssdk:utils:jar:sources": 249477790, - "tools.jackson.core:jackson-core": -1258054011, - "tools.jackson.core:jackson-core:jar:sources": -1689479769, - "tools.jackson.core:jackson-databind": 1443518747, - "tools.jackson.core:jackson-databind:jar:sources": -871567409, - "tools.jackson.module:jackson-module-blackbird": 1038981586, - "tools.jackson.module:jackson-module-blackbird:jar:sources": -9825245 - }, - "artifacts": { - "aopalliance:aopalliance": { - "shasums": { - "jar": "0addec670fedcd3f113c5c8091d783280d23f75e3acb841b61a9cdb079376a08", - "sources": "e6ef91d439ada9045f419c77543ebe0416c3cdfc5b063448343417a3e4a72123" - }, - "version": "1.0" - }, - "args4j:args4j": { - "shasums": { - "jar": "11b029a602e787e2bc08eb3b77eda1a4f5e8b263d22e3c5d6220cd5c51f30b18", - "sources": "ec1eb6aa4859b9b4fd9da4d58efb28b2eb629a4c14919e9078054879540243b7" - }, - "version": "2.0.28" - }, - "at.yawk.lz4:lz4-java": { - "shasums": { - "jar": "49753ae8a9b7dc3ce48cb2989cc6605e43eb8269748ad3466251836ec4cd02a8", - "sources": "3b9a0590c53a4f4e45b204695af0e480dbd4f3a589913c6a36f7c2c3d31b0eaa" - }, - "version": "1.10.3" - }, - "ch.qos.logback:logback-classic": { - "shasums": { - "jar": "b65e05076a5c1aadb659b4fe4bc5fee31cb26cd70390292eb03e4a7a24cff10f", - "sources": "c2e39cb4d6d9b8c2343c6da2469e21e1d6aef2dde16c2227762c084d549ad0a0" - }, - "version": "1.5.34" - }, - "ch.qos.logback:logback-core": { - "shasums": { - "jar": "42eda264c0c650c2bec59e66151a88b708a8663dc1b49d788202d53e78b8caae", - "sources": "6a9f217ef206caf2880810c505e057fd2bb90a6024013906815e9513c6e488c5" - }, - "version": "1.5.34" - }, - "com.datastax.cassandra:cassandra-driver-core": { - "shasums": { - "jar": "09c4d54009e942e3afb8755c5fd51abac8ba721e407b61dcb22f435d1a33c1a1", - "sources": "b0e1d20dd052986f1cc1511fee039801ebb1ae3474a14f0708bedf9b6278083d" - }, - "version": "3.10.0" - }, - "com.datastax.oss:native-protocol": { - "shasums": { - "jar": "190dc40f3c63d6d803c48f90d457e06c65e6c5d955e47d4735dc9954a6743655", - "sources": "6029f3fd12ebe066826642d42f0efb63108b051577828458b66a8637847e88c9" - }, - "version": "1.5.2" - }, - "com.fasterxml.jackson.core:jackson-annotations": { - "shasums": { - "jar": "53ca085f4a150f703f49e1aabd935bd03b43e1ea3d55d135438292af22cef56b", - "sources": "71fe6323d91b16d5d1007fd1e1533fa06bb369abde74f68a42a68c0f8f061a8b" - }, - "version": "2.21" - }, - "com.fasterxml.jackson.core:jackson-core": { - "shasums": { - "jar": "4b40a06396f239f8de2da57419adde6e94e5edc18a2171d471ea05eeed4e5c2d", - "sources": "90ccada55626ce4f00a81bde235af0a942ec2bc4c701fcc86a93af1be9b3e08d" - }, - "version": "2.21.4" - }, - "com.fasterxml.jackson.core:jackson-databind": { - "shasums": { - "jar": "3888e9e69ab66fbacaacc9aea0e9ffbf15368288e4aca468b024dba11c09fbf9", - "sources": "23188e78e912c9866367bf038fb7f729e79f1c2724174ca66e0a00915de70e61" - }, - "version": "2.21.4" - }, - "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml": { - "shasums": { - "jar": "055eb4c008ab12f0cb63e93a6454463d032fde0fca85943d69f8dc7469489e4b", - "sources": "164cef68956eb2797e421dd6cf74bfd648581965a8df2389c260bb363d1f3baa" - }, - "version": "2.21.4" - }, - "com.fasterxml.jackson.datatype:jackson-datatype-jsr310": { - "shasums": { - "jar": "d1ac4b98b70304e56448423589fde5e775b100889643ad1ead62cc7811633684", - "sources": "884a8812af289bb56f38f09a4b3b7b73b4a16dbc184ae735fbe6c4aa1089161f" - }, - "version": "2.21.4" - }, - "com.fasterxml:classmate": { - "shasums": { - "jar": "75fbda45456f123fb6e2028a6189442d8d0730b357adce4c0a6d7e789f70669b", - "sources": "b0690a771dc54865c3d0ad9ab6abb319633b6b88849900a28f719e792c15fc68" - }, - "version": "1.7.3" - }, - "com.github.ben-manes.caffeine:caffeine": { - "shasums": { - "jar": "9d9d2cfd681fd9272ded3d27c9930db12f89f732345975aa113ebc223bbf1224", - "sources": "5079e1b327d79e2fc8ae3f5927587e59c968603e63785fb33479acd8b732211d" - }, - "version": "3.2.4" - }, - "com.github.ben-manes.caffeine:guava": { - "shasums": { - "jar": "7819335459a43b3d2d501bd19b6cf880041a1ad47a9a118d018d89c432357358", - "sources": "2de42779d0ee1807262065382a9302715b2d8daa186f9b39aca1043c10681ab5" - }, - "version": "3.2.4" - }, - "com.github.docker-java:docker-java-api": { - "shasums": { - "jar": "dad153d484b1f4ef009e2fdbad27e07aeb3191122da52b8985507ac504300081", - "sources": "57c9b5bc37d48c256a2a0de556095158f363b10eec58052e58f299c542cf9391" - }, - "version": "3.7.1" - }, - "com.github.docker-java:docker-java-transport": { - "shasums": { - "jar": "d15eec8034bf0f92c2a48ca9172691804048115c96dc853272f9486fa2695c3c", - "sources": "131ed62714d94125f89a3c3ad966e517c8ad48fbbc1905b08bcdafc0d6e9de45" - }, - "version": "3.7.1" - }, - "com.github.docker-java:docker-java-transport-zerodep": { - "shasums": { - "jar": "b89bdb1754160323597f9ea32a7fe7a4a3aa8f5b3b43b88e8d71fff3b267ab21", - "sources": "f4d1457f9e2e151d19713e46cf2b49796887d5a9744664a15a4ce07c76660883" - }, - "version": "3.7.1" - }, - "com.github.java-json-tools:btf": { - "shasums": { - "jar": "67c3e462eb50807f4e0a5f4dee304bbf17cd986a42ee5eb0b2f4c9bf64d130d9", - "sources": "97f8bfb9a8876534bf2832a5be4b913b695d72c6ff6f9c8c6719bd38fd4aeb73" - }, - "version": "1.3" - }, - "com.github.java-json-tools:jackson-coreutils": { - "shasums": { - "jar": "16b3aabd3a9eb25655dda433e35f9bd9c7c1aa7991427702f5f11f000813dbb0", - "sources": "6f39b6beed5b000702ade7014be2ca21f895a0b70ab6c199f6ca5bebc1807080" - }, - "version": "2.0" - }, - "com.github.java-json-tools:json-patch": { - "shasums": { - "jar": "1f794d256965b53ef37e70b55505e2ed00ddc0184d44e2e8e1fdce5a3cacc7de", - "sources": "f4ba54ca57611123fe972f05537d44d4b61fd8ed6f71541b3ca37e09a6e3e318" - }, - "version": "1.13" - }, - "com.github.java-json-tools:msg-simple": { - "shasums": { - "jar": "bef4111b993a5b3e6148d8f585621cceac2a1889cdbc34448b11632e0d8a9a8f", - "sources": "eeb0ecd504611cec75f261a6d282bb8b80214e473ef235481c8067b6b121f1cd" - }, - "version": "1.2" - }, - "com.github.jnr:jffi": { - "shasums": { - "jar": "7a616bb7dc6e10531a28a098078f8184df9b008d5231bdc5f1c131839385335f", - "native": "ef78953e3dbf47fab94469190bc2a6d601566a21d4651f73c822bad1c02b64fe", - "sources": "45ad89d2774e9d03de89905cf990d49d5821ce8012a841faddf23dca02538d72" - }, - "version": "1.2.16" - }, - "com.github.jnr:jnr-constants": { - "shasums": { - "jar": "a617b0d8463d3ea36435bd1611113dedb3749157afd2269908ab306c992aefed", - "sources": "9406718df04cd893a94933213b370d99c613d94d80e23119e2cf8dc51394ea12" - }, - "version": "0.10.3" - }, - "com.github.jnr:jnr-ffi": { - "shasums": { - "jar": "2ed1bedf59935cd3cc0964bac5cd91638b2e966a82041fe0a6c85f52279c9b34", - "sources": "61842708c7e617ae2ca3a389931142f506f854104392fa6f7aaac6f51c93cf58" - }, - "version": "2.1.7" - }, - "com.github.jnr:jnr-posix": { - "shasums": { - "jar": "c38ecfccd24e5f21f17a62e45d5bd454842c5db17ed42b01b868f9206d0e99e7", - "sources": "abfff56a7628d223ba86c3ccb3bcb5101aeefdeedbe58c3c52b1917a92d7e332" - }, - "version": "3.1.15" - }, - "com.github.jnr:jnr-x86asm": { - "shasums": { - "jar": "39f3675b910e6e9b93825f8284bec9f4ad3044cd20a6f7c8ff9e2f8695ebf21e", - "sources": "3c983efd496f95ea5382ca014f96613786826136e0ce13d5c1cbc3097ea92ca0" - }, - "version": "1.0.2" - }, - "com.github.stephenc.jcip:jcip-annotations": { - "shasums": { - "jar": "4fccff8382aafc589962c4edb262f6aa595e34f1e11e61057d1c6a96e8fc7323", - "sources": "d60bb3bf4e03a5e405f9b16f4c2625de86089d6ce4f999bcc2548dcac090ae19" - }, - "version": "1.0-1" - }, - "com.google.code.findbugs:jsr305": { - "shasums": { - "jar": "1e7f53fa5b8b5c807e986ba335665da03f18d660802d8bf061823089d1bee468" - }, - "version": "2.0.1" - }, - "com.google.errorprone:error_prone_annotations": { - "shasums": { - "jar": "3b1003e51b8ae56fdbd7c71073e81d1683b97e6c4dff5a9151164d59b769d13c", - "sources": "69d2de7f69033ff914ba06f0858adb96ac7b1436959f04fca7de5805c834b281" - }, - "version": "2.49.0" - }, - "com.google.guava:failureaccess": { - "shasums": { - "jar": "cbfc3906b19b8f55dd7cfd6dfe0aa4532e834250d7f080bd8d211a3e246b59cb", - "sources": "6fef4dfd2eb9f961655f2a3c4ea87c023618d9fcbfb6b104c17862e5afe66b97" - }, - "version": "1.0.3" - }, - "com.google.guava:guava": { - "shasums": { - "jar": "dc573e1fca4fd5454f4a5fd3d7da2df03002876a4175bafc14a95980dd7713b3", - "sources": "eff31867dd63a92d63ca856127a424a6836418d8bfa044162cac20430abd3500" - }, - "version": "33.6.0-jre" - }, - "com.google.guava:listenablefuture": { - "shasums": { - "jar": "b372a037d4230aa57fbeffdef30fd6123f9c0c2db85d0aced00c91b974f33f99" - }, - "version": "9999.0-empty-to-avoid-conflict-with-guava" - }, - "com.google.j2objc:j2objc-annotations": { - "shasums": { - "jar": "84d3a150518485f8140ea99b8a985656749629f6433c92b80c75b36aba3b099b", - "sources": "295938307f4016b3f128f7347101b236ada1394808104519c9e93cd61b64602b" - }, - "version": "3.1" - }, - "com.jayway.jsonpath:json-path": { - "shasums": { - "jar": "890daa95dd3892d34d9fabc27cd5153656e6f369358625c88f4dc7b79cbd6c5a", - "sources": "357f1c52217497c4251fae715ba8ef76ae310b1aae77ea319260bf4c6ad61440" - }, - "version": "2.10.0" - }, - "com.nimbusds:content-type": { - "shasums": { - "jar": "60349793e006fba96b532cb0c21e10e969fe0db8d87f91c3b9eaf82ba2998895", - "sources": "9a154c802659594d8745a0e364bd2e6b418e010268467cd222354445dd77d626" - }, - "version": "2.3" - }, - "com.nimbusds:lang-tag": { - "shasums": { - "jar": "e8c1c594e2425bdbea2d860de55c69b69fc5d59454452449a0f0913c2a5b8a31", - "sources": "8d37da312db366d702bd7254df6bceca0a7814e18da9c32db9cc1d8ca038c468" - }, - "version": "1.7" - }, - "com.nimbusds:nimbus-jose-jwt": { - "shasums": { - "jar": "6f13f3480ddc53d820d276f582f54843cff1daf5c6e35e534947e9de7723b46b", - "sources": "b3fd3b569013246fb9a1ac6b43ff3e3033065bce16de92ecf4c971d14875eb30" - }, - "version": "10.4" - }, - "com.nimbusds:oauth2-oidc-sdk": { - "shasums": { - "jar": "648494b00da090a4df23aa6a05e4dc03f6e8603b29dd807a4491f33d586f7f78", - "sources": "e4de2ef818fbb57aa3731b65e2f5edc1a40dc1e3f6e6541306ca9f45490aed2a" - }, - "version": "11.26.1" - }, - "com.squareup.okhttp3:okhttp-jvm": { - "shasums": { - "jar": "9632c08567dbb21c569b13d793107834c8580d44e4eea74b2eae0722f0506179", - "sources": "9fa32be62c7a46ffe70cdb1bf7e195f5ee3fc885999379292cb636b5aa311704" - }, - "version": "5.2.1" - }, - "com.squareup.okio:okio-jvm": { - "shasums": { - "jar": "31f48e6463ec587d6d262d042c91da00659c983b6ad20d5982bf31e85222693c", - "sources": "b29b5f4ad1adfd7cbfb3d388f7bf29d1702f0b85be1b6c61b0185ce7e2b2e6dc" - }, - "version": "3.16.1" - }, - "com.typesafe:config": { - "shasums": { - "jar": "4c0aa7e223c75c8840c41fc183d4cd3118140a1ee503e3e08ce66ed2794c948f", - "sources": "89af318a607f7e2b2691ed1ef4b4890bd37ea17d6986b0aec50dd4d5f889520c" - }, - "version": "1.4.1" - }, - "com.vaadin.external.google:android-json": { - "shasums": { - "jar": "dfb7bae2f404cfe0b72b4d23944698cb716b7665171812a0a4d0f5926c0fac79", - "sources": "54c781eea645c450cbbc4a5a1b5a474745465452cec1354cb567b781ea6622c3" - }, - "version": "0.0.20131108.vaadin1" - }, - "commons-codec:commons-codec": { - "shasums": { - "jar": "5c3881e4f556855e9c532927ee0c9dfde94cc66760d5805c031a59887070af5f", - "sources": "b0462142585d45fc15bc8091b7b02f1e3a85c83595068659548c82cac9cdc7a2" - }, - "version": "1.19.0" - }, - "commons-io:commons-io": { - "shasums": { - "jar": "df90bba0fe3cb586b7f164e78fe8f8f4da3f2dd5c27fa645f888100ccc25dd72", - "sources": "7a87277538cce40da6389a7163a4d9458bc7a9c39937a329881b91d144be8e0d" - }, - "version": "2.20.0" - }, - "commons-logging:commons-logging": { - "shasums": { - "jar": "f8ead8943401081dea0aa824b5b1ba40a0e4ed297a572a0f02258150a0b62357", - "sources": "6e821e03cfc64e509cc162d428af84697b6c4188eb14c0b137c75b69649976ef" - }, - "version": "1.3.6" - }, - "io.cloudevents:cloudevents-api": { - "shasums": { - "jar": "95751500be617f0c795ea3cd7c370fa712459da500fbd22bb8b7f69fcba46e97", - "sources": "962306ae4d9c9aaea5958a3e5e837c895bc683098c2da7f2fa8e972dfea82ebd" - }, - "version": "4.1.1" - }, - "io.cloudevents:cloudevents-core": { - "shasums": { - "jar": "25c3756d184eebf20aceadbd2357cd48516938ca458a1b77a3ebdc09f8dfc592", - "sources": "869ae88ca9b7f7e62af3f34ae6269e7c816b58d08ef371040530164e2aaea02a" - }, - "version": "4.1.1" - }, - "io.cloudevents:cloudevents-json-jackson": { - "shasums": { - "jar": "28aa328c61ae1783cecb430f7b51880e365ea8678628eca416e12654eafbb66d", - "sources": "b4ee1b7db2dfa50101a9fa7a3beef610b6931546be1bc5a61ae28cc929473406" - }, - "version": "4.1.1" - }, - "io.dropwizard.metrics:metrics-core": { - "shasums": { - "jar": "5c6f685e41664d10c70c65837cba9e58d39ff3896811e3b5707a934b11c85ad0", - "sources": "773164a026ea78df51d14608def3a746a2270f630e9a2f5f6f99d6e155ad5bcf" - }, - "version": "3.2.2" - }, - "io.micrometer:context-propagation": { - "shasums": { - "jar": "5b69e2100640879ccf4b20673ced86de560b8e217b55542f85a53d3563b72aaa", - "sources": "719639b819c3ecc76f2b3d4da4b17ca7a8ed6c73b93a770c69aa9d86276f8bf2" - }, - "version": "1.2.1" - }, - "io.micrometer:micrometer-commons": { - "shasums": { - "jar": "45aff76226830db257f4bc39a5bcff83d633e572fee9dc4e45cfa12af9a0a49a", - "sources": "0e4a336c7bca50bfa6cbea274ea681e42d86bfdac1038af3041301c8454f76ff" - }, - "version": "1.16.6" - }, - "io.micrometer:micrometer-core": { - "shasums": { - "jar": "1957ef2deaffbc1fb98cebfd0f5b3109ecf19c994d7e5378598c20747ba8d68b", - "sources": "f85d566a76d98891cdecd54c106b7ad7f8948cddad3b393debe341ecfba18bce" - }, - "version": "1.16.6" - }, - "io.micrometer:micrometer-jakarta9": { - "shasums": { - "jar": "987722add6461c5a4c796be11e7452e8813fba341f2cc067b1d283eef2bd4f40", - "sources": "83fa1c6356611b3381d6309a6159b2739c9c29446c8b52183b2111fb13ce5301" - }, - "version": "1.16.6" - }, - "io.micrometer:micrometer-observation": { - "shasums": { - "jar": "4c0826d5e7c8522a8e111470b4e77f77b0a10f520eb5502ddd143fdbcedb2340", - "sources": "ff5525482df358e7502d4c8680fb654ec700e3b01341149d870bd6cfd8ce04c0" - }, - "version": "1.16.6" - }, - "io.micrometer:micrometer-observation-test": { - "shasums": { - "jar": "e69bf8df81458f4ad6f6027a7310d75c8ca8d11df2e95d44dd4616f8637069ad", - "sources": "1ebcdbf4e14e6a4dcec4ad188bc4227ebd5ce0a3f361f5f0ed6df2bebb10cfb2" - }, - "version": "1.16.6" - }, - "io.micrometer:micrometer-tracing": { - "shasums": { - "jar": "b335096393e4d070dfda4fb30808f8488d31d43811b93b2d7496703c5f1315ef", - "sources": "a089a2bcc462d6ced28d7f67b01a9f54baf6c52984cd13f3ed713f2fda0810c6" - }, - "version": "1.6.6" - }, - "io.micrometer:micrometer-tracing-bridge-otel": { - "shasums": { - "jar": "581b6908d46ed2df6b9bb8167df4c44deddc5c2567c430c73bca66326138f661", - "sources": "2aa7115e2f0562e3c50149e77d6fc41340b20d5111b737ea443e0b8bf53a75b3" - }, - "version": "1.6.6" - }, - "io.nats:jnats": { - "shasums": { - "jar": "a5705531ff8fc96657d99d2fc4436178c04463df6a216ba6b5528a5d5228f240", - "sources": "40d6500a369ad57822074fa2a838367e4818ac61eba5c038c95b54772c4ef96f" - }, - "version": "2.23.0" - }, - "io.netty:netty-buffer": { - "shasums": { - "jar": "1361fd9c9ba85b9831cf54a1b2e45ddc3ce34a768931726c099d3f5ef0efe4a3", - "sources": "13259b636c4a91c0f34a8536d621178fba302f9ba61f3e4aaec3a17ca291dc2a" - }, - "version": "4.2.15.Final" - }, - "io.netty:netty-codec-base": { - "shasums": { - "jar": "2c6d39d7270628b8cfc3166fbd7a93d595958e59c461bc32ddb383c8c91bf811", - "sources": "029bea433dfc710c640338954c7403cc7ac31cc5bf4c192904c837b0ebda5fb2" - }, - "version": "4.2.15.Final" - }, - "io.netty:netty-codec-classes-quic": { - "shasums": { - "jar": "ec1d5da906ea0139741cd8c570907c399df5995e48a2b07fe3155272e0be21a6", - "sources": "edfbbece45f21e8f214c0f08f33666ef09ae4580322ffa27020633b5fdee6250" - }, - "version": "4.2.15.Final" - }, - "io.netty:netty-codec-compression": { - "shasums": { - "jar": "4adaa5cdd4d2e9b50b23e4c3eff42e73de6eb40848718b3aa84cd5b454da6ce8", - "sources": "58d61aa4f781657f955a196f17e28fcd9b02e21658b996571e4604a2dadbd8af" - }, - "version": "4.2.15.Final" - }, - "io.netty:netty-codec-dns": { - "shasums": { - "jar": "c5e2c05b4faeba3cf374cc6af29d6f4a7e969d7ca222be958e0800c79a02ee4e", - "sources": "f10017539ab2816efee10b70b47b262c04b881fca685327769d576dd8b222b47" - }, - "version": "4.2.15.Final" - }, - "io.netty:netty-codec-http": { - "shasums": { - "jar": "76ae57e87af37b3c4107140f50b9244b1456163a6a225510838f7c5a4458ec22", - "sources": "76b25b4884e7bec78cd310415b068204e67da5a87162774abfad9a0e6c7a0e78" - }, - "version": "4.2.15.Final" - }, - "io.netty:netty-codec-http2": { - "shasums": { - "jar": "4a9b052bd815c765d9c05e27b32abbd32a2c7c3e3364ccb992ce71da1a26bc0d", - "sources": "01f8ad714e5abb989b0e782da9ec467068821299cd17d80c2db833a6472507f6" - }, - "version": "4.2.15.Final" - }, - "io.netty:netty-codec-http3": { - "shasums": { - "jar": "f2f96b7557317c1378dd8d84b4d9b1865db285c5e665b1220ea519e9f868929d", - "sources": "3a35802b80f536b5693d53d6dfbf4102e94edd0e7b26b3b8d8ab400a12d0f9e0" - }, - "version": "4.2.15.Final" - }, - "io.netty:netty-codec-native-quic": { - "shasums": { - "linux-aarch_64": "59a8e59aa9d3a886cd7fae30fb3d3a18ebee40fa9dc08b83eb88bee58cf46774", - "linux-x86_64": "850ed59fac6679b5e205bf53187b45dbaf2d105ee5f669440645d2acd89524ec", - "osx-aarch_64": "ce18ffeccef21adb3caca5534061c921ef750662f29028fdde62d65196d63a9d", - "osx-x86_64": "10999923bf08ff5e3a75106bd8dbc5b5e4d06b5e614f8c135981ecb4377c944a", - "sources": "d9772d6d7d0eb6fdf82ccaeb9558f88b5600c6f0696a724f5e067b67bdc049f3", - "windows-x86_64": "40adba6df605302bf98a4a462bb002c4697f60958cea7cfec38f0fab6331eb7a" - }, - "version": "4.2.15.Final" - }, - "io.netty:netty-codec-socks": { - "shasums": { - "jar": "4230d43481241e49382a83da2fa9d5980c5702668fc5aa5a980346ce03d30828", - "sources": "f126a6f94589b56b1c056a5dbbda4e76e4e749cec1591a3e878e4d6854144a43" - }, - "version": "4.2.15.Final" - }, - "io.netty:netty-common": { - "shasums": { - "jar": "78206aa7f6d197caa926291408c01889b6b910ca0f74017d3fcbdaccf9562959", - "sources": "de720a128534ba1072b354c863d671ab1999900a8fddaadc4a68ee74c2e33fd6" - }, - "version": "4.2.15.Final" - }, - "io.netty:netty-handler": { - "shasums": { - "jar": "99b59e4bea72220d2aed52df8baf37d97431b06ade0b135226cdf73168975eab", - "sources": "68306697d15d870e7bb29ab9ce725d121ac3170428e8a5d7a33767c5fb0ffa0e" - }, - "version": "4.2.15.Final" - }, - "io.netty:netty-handler-proxy": { - "shasums": { - "jar": "a06aaaaa1a2e6eb26824e53566bfd020ba930a9390d57a1f0bbf57316e357373", - "sources": "91fa7fc64aaa39982b30cc19974f80021090c91023d1d5f6a8e4179aa3a5056b" - }, - "version": "4.2.15.Final" - }, - "io.netty:netty-resolver": { - "shasums": { - "jar": "24318497f2a3a645964fed418f48879ba11365cab8e1f8d66c47fa7da15ef19a", - "sources": "c87b295c43265b34c749331e12ee667f7d43329338618bee2a08027b839220d2" - }, - "version": "4.2.15.Final" - }, - "io.netty:netty-resolver-dns": { - "shasums": { - "jar": "2e8dd2d861775483d689329ab2546045647c8f8bf5ae3ed2dd48eefbb748952d", - "sources": "4db838a89ec84479476e71956d59c67a957779dc5f9781f1a9964f9a6b607c29" - }, - "version": "4.2.15.Final" - }, - "io.netty:netty-resolver-dns-classes-macos": { - "shasums": { - "jar": "dc91d81e0f6c8987ed34f6ca005b4b97cc6032f933a49f7500940e846ade7c43", - "sources": "00067617cc0927d804091590f9ea5041e39c4f907357e3c969c45078fe10be3d" - }, - "version": "4.2.15.Final" - }, - "io.netty:netty-resolver-dns-native-macos": { - "shasums": { - "osx-x86_64": "a1115fb0fd88fe50209fbd645cbfe09e41fe2d264bb1854dc545f44a1bd020cf", - "sources": "87a85f239a73c9a4e7dde8ca31e0a8dea711b3b5e3cff9df18b8c07f31f5dc50" - }, - "version": "4.2.15.Final" - }, - "io.netty:netty-transport": { - "shasums": { - "jar": "9fb671e96651066cf1a28dad3f1382c7c99df5b8326d4a214d9a375b311f8dc1", - "sources": "e17c0a4c7324a93fa01f00bc6ddd2bf2f6eb94702ad8de7af777dec87f89eaf8" - }, - "version": "4.2.15.Final" - }, - "io.netty:netty-transport-classes-epoll": { - "shasums": { - "jar": "be509407fd71a4b83378567c613420db544d659bb522df7b253a1dbe8ca297fe", - "sources": "bb095191a070714f769bff1dd0e5d2496305d10bd566bdc16dbca5773df48b4e" - }, - "version": "4.2.15.Final" - }, - "io.netty:netty-transport-native-epoll": { - "shasums": { - "linux-x86_64": "5440e38f5ca2858fee8d7898e65291e05b665736c9e8a14c832e707511f5dba6", - "sources": "d48e8de50b0994842bec4e65725a7f8e9734144dd4f08b78ffe5396a70ab06b6" - }, - "version": "4.2.15.Final" - }, - "io.netty:netty-transport-native-unix-common": { - "shasums": { - "jar": "b9ea9fc5ad5eba04e99afdff75b2eb97b5ddfb2ad772e2f2ef5d8f277f3cbd76", - "sources": "2b82c54d1b2b9908ec0104664edf58ded4848ae5b34266ee1cf90707efc420ab" - }, - "version": "4.2.15.Final" - }, - "io.opentelemetry.semconv:opentelemetry-semconv": { - "shasums": { - "jar": "693ad6f04f29b4b593a04adef5f575d28b3a91ea3449ab5b1e1e2e5c6efc6cdc", - "sources": "186f9e009d914ebe31f5994d42ff67c5dba8e0893569a4f0f0eeb7958b956d4f" - }, - "version": "1.37.0" - }, - "io.opentelemetry:opentelemetry-api": { - "shasums": { - "jar": "387b4bf98631fc2ede9470879a8ff28dd8c5cb2d3dcf5b6ef77f5ee2bdb7b4f1", - "sources": "3abc57abcaaff4521a5fb2b89593031da5feca24aa54816ec58a8d08ab71fd4a" - }, - "version": "1.55.0" - }, - "io.opentelemetry:opentelemetry-common": { - "shasums": { - "jar": "fca14bb87309d1193347d179b91c63045fa05a856f1fbeec6ef61c4a7f81b227", - "sources": "4219708637e60172c347e48b677b71f5ad97ab8e4850cfda2f85ed59da74e250" - }, - "version": "1.55.0" - }, - "io.opentelemetry:opentelemetry-context": { - "shasums": { - "jar": "f34a4718b70446ec462703ced5cc2c9ad4c9b7c69dcb41d0f032ba51c625a3dd", - "sources": "e0b63b17ccb407f6208a89a180ad48c6add5cca05d29047e858a6ebe8442b3fb" - }, - "version": "1.55.0" - }, - "io.opentelemetry:opentelemetry-exporter-common": { - "shasums": { - "jar": "3b4faaae49dd87bdefae13528d069a271f8476e2a64420e32f4e959a8d09c132", - "sources": "b795169dce773a549f6f3ce2202886ad93622306f2991bd5771547e3c649a2dc" - }, - "version": "1.55.0" - }, - "io.opentelemetry:opentelemetry-exporter-otlp": { - "shasums": { - "jar": "cf42ce6e7cc6755182149f269447f6677f69c0a31e101464594dbcf62fe874c3", - "sources": "a94ebfb492577503d49d43423328f5d0042206f309a18407386a4ab5375bcc82" - }, - "version": "1.55.0" - }, - "io.opentelemetry:opentelemetry-exporter-otlp-common": { - "shasums": { - "jar": "7ddfa417d88a5ff8626dad9ebe0c8c59776491478ab1f72aedfacd75b984931f", - "sources": "7b36e1080bbb2c4dbc7ce009393c568e3d968328f0e5891beb1e45ebd894337a" - }, - "version": "1.55.0" - }, - "io.opentelemetry:opentelemetry-exporter-sender-okhttp": { - "shasums": { - "jar": "e9cd97f59b18a89772ececbebccd773740eec2cd3ff67a4542eff73738acd60f", - "sources": "55f2f24814971e7b476db3713ec82f29285b679fbcaa434c481863f503e2a6e2" - }, - "version": "1.55.0" - }, - "io.opentelemetry:opentelemetry-extension-trace-propagators": { - "shasums": { - "jar": "27861a2b49b3acf3166f489426808032c3addd9c082999f74a110eb7ac6985ce", - "sources": "784afdd2a2a6fca26f8bf237b8aae7f6bfcb44c65d141901a110b4ff769bee0c" - }, - "version": "1.55.0" - }, - "io.opentelemetry:opentelemetry-sdk": { - "shasums": { - "jar": "d63231ea6fd33e0457c776a9aa8ae7ba778379b03119228ec56a5c8c16f9480e", - "sources": "3685819f7d9efb6761d35ecf5b6053dfc1d0161835da744b0fdb2c4d89c87a42" - }, - "version": "1.55.0" - }, - "io.opentelemetry:opentelemetry-sdk-common": { - "shasums": { - "jar": "e28bb83d0ae5a760ba95952daf820180ee7defb0c5783c9d21f9c00ada80020e", - "sources": "cb9423298f9c42ac2c568af5271d335e468d7730b21d7ca6c246c16c6eca25f7" - }, - "version": "1.55.0" - }, - "io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi": { - "shasums": { - "jar": "3ee1f647238bb77df7b7bde47bc87a35a7807b3c5bb389ca81b0ba16c77824ff", - "sources": "71760407f00ba82b762335ff2c3470daf3d5ff1c6a798eb9ae52a24c7772f418" - }, - "version": "1.55.0" - }, - "io.opentelemetry:opentelemetry-sdk-logs": { - "shasums": { - "jar": "d917bb833899057c7cbdbcc30290e816071b90e52c965693aaad4cc1b32ecc11", - "sources": "edb0008c29edf69671865945a1c47d1944c1f498ef7e895f7b21b916fea2f14c" - }, - "version": "1.55.0" - }, - "io.opentelemetry:opentelemetry-sdk-metrics": { - "shasums": { - "jar": "6219d69c3abdd6113bee35df94826f48e84b742041f5124b5857a2b801f74573", - "sources": "5f9c8dab78339e402caa7f7aa4616b6b5c8e2d50201335c73e23bd21aba147fd" - }, - "version": "1.55.0" - }, - "io.opentelemetry:opentelemetry-sdk-testing": { - "shasums": { - "jar": "9e257ac45834e5d184abdc238b5ee146a74a259d940c57722999ef400cdc2232", - "sources": "b40c580007e26d721d406e0b85385e87f6e2e8c36bea55adfd8837d77f57ccee" - }, - "version": "1.55.0" - }, - "io.opentelemetry:opentelemetry-sdk-trace": { - "shasums": { - "jar": "e593660b9fad8bfdb5e981ccd392aa030f788d577c55f8bac3b6c4c6dae509bb", - "sources": "2f374e9b5f2e7e33157bd6fc97eb5c629d0dac0f22a975075b52714916dfc6c5" - }, - "version": "1.55.0" - }, - "io.projectreactor.netty:reactor-netty-core": { - "shasums": { - "jar": "b8aaddd6025af42c2d810a76dc5b9a7717f0fde84beb93d6d4a778dac25fc287", - "sources": "061136ccc1bc3bed6938cea77a7343dc47de275aad4851b3407fb7ac15854121" - }, - "version": "1.3.6" - }, - "io.projectreactor.netty:reactor-netty-http": { - "shasums": { - "jar": "0ffdcaafe718327ca4687dd41c21318a267e93cea7b43f42db6f3fb3175256a5", - "sources": "712c12723e57d68e909ce9221cb12e04be105435ca518d13f63075af81cbaa44" - }, - "version": "1.3.6" - }, - "io.projectreactor:reactor-core": { - "shasums": { - "jar": "ffc646b225465efce55d3ea350f1bcd1d27d4a56e912323e316dd8e6d04bff11", - "sources": "d6180835f642a1f6d8b330fac98876488994187a89c3df48b369f37344ea6845" - }, - "version": "3.8.6" - }, - "io.projectreactor:reactor-test": { - "shasums": { - "jar": "27acda356a59c19bc3db033f1ed4cff9a6469da6caf424a4004ffaabbfe24d2a", - "sources": "882b7654b056b77f721a03a804e4830030f072a2f4afb92638d6925568d6d930" - }, - "version": "3.8.6" - }, - "io.swagger.core.v3:swagger-annotations-jakarta": { - "shasums": { - "jar": "9b30b319f1c31993e6128d22e12652be9a688589e30c67819ed84e95b96e7f88", - "sources": "b9324b72ab6c498fad2d766f5074b1b24be0cf2c1e55f6c937b4b8345ca90bf9" - }, - "version": "2.2.47" - }, - "io.swagger.core.v3:swagger-core-jakarta": { - "shasums": { - "jar": "e63b78c1e5b049e6670ca9bb43c3f35cf362ecc08ac59a783994a6a732a7d7eb", - "sources": "55b6e465caf14b019ebe4ab9d886915afd1a4796c6c790ffdd4789b36997f556" - }, - "version": "2.2.47" - }, - "io.swagger.core.v3:swagger-models-jakarta": { - "shasums": { - "jar": "15d10f4f7eac1e02a8ff940b430c634fc9dfe08368a54dffa3216cc2dc811aa2", - "sources": "4770b07fcb362a2c1b289fd255d5bf9ec11619bc0cbfcfc07e49599f24fef753" - }, - "version": "2.2.47" - }, - "jakarta.activation:jakarta.activation-api": { - "shasums": { - "jar": "c9db52100ce6c8aac95cc39075f95720d2e561b11f8051b81c121ad4effd7004", - "sources": "2aa5a3ba55059b778a3b467269404d7ac3b9485ed4a23ad26d2e63aa769ec35f" - }, - "version": "2.1.4" - }, - "jakarta.annotation:jakarta.annotation-api": { - "shasums": { - "jar": "b01f55552284cfb149411e64eabca75e942d26d2e1786b32914250e4330afaa2", - "sources": "142dfd2343429df2aac3e1cfacfacc21c8393112c0e0280d3628648d9b612470" - }, - "version": "3.0.0" - }, - "jakarta.servlet:jakarta.servlet-api": { - "shasums": { - "jar": "8a31f465f3593bf2351531a5c952014eb839da96a605b5825b93dd54714c48c4", - "sources": "6eb958543e0548bb93d2519e40224d13c8003b10cc615b5652bfd9899350bfb4" - }, - "version": "6.1.0" - }, - "jakarta.validation:jakarta.validation-api": { - "shasums": { - "jar": "63ce00156388c365f3ac1be71fcfaf114682fc0c452020b5df6e7ec236e142ab", - "sources": "941cc2028fe8f5e6b912954bca360ed347ace453aca4f8e2fd58dc3845a0c792" - }, - "version": "3.1.1" - }, - "jakarta.xml.bind:jakarta.xml.bind-api": { - "shasums": { - "jar": "5e489b6c874c4119e003ff1403db523ee3a8959ec499f3de29e77245efccf216", - "sources": "5bcf811e6719582ab2be21c84bc48f963ba377dfe1dae5ecb2673c1efa00e422" - }, - "version": "4.0.5" - }, - "net.bytebuddy:byte-buddy": { - "shasums": { - "jar": "2b5ddc8c1f4234bdb7cb45338a8e10a13e0e3ca473e91d5d821d681127ea8ba1", - "sources": "5211140f46c380a5e9630a86b2c07b396a9c374128fa603ca1d321b3c7da7449" - }, - "version": "1.17.8" - }, - "net.bytebuddy:byte-buddy-agent": { - "shasums": { - "jar": "5b17113e66e77ca6f8af07ff367c216df964a980f0e9f11e3b1aa793253aa64f", - "sources": "a205437d772e3edaf4a7a1a709e9d59c666e8a05218d0e000deb5651c52de2d2" - }, - "version": "1.17.8" - }, - "net.java.dev.jna:jna": { - "shasums": { - "jar": "260c4b1e22b1db9e110ee441c4f13ce115f841fa48c41d78750986214b395557", - "sources": "0b9224e215b3c6a464959e3f994ddd64c14d46fb4014facd6afa1cc18e469466" - }, - "version": "5.18.1" - }, - "net.minidev:accessors-smart": { - "shasums": { - "jar": "222c9f547bb20a99fc486403a398352d1306fb671b38abd7ecab6401df170e61", - "sources": "10880e44ed732de27ae424a9698a041c398102098b5b1bae3cc597ec62dac43e" - }, - "version": "2.6.0" - }, - "net.minidev:json-smart": { - "shasums": { - "jar": "1ae4b561458afb540be8ec5c6dbb4f2e715a319a7ae64854998aaf924770d61b", - "sources": "a4af3f3773286fe3f76f94d38d977611fd2493685f589466b76dd25cf70b400c" - }, - "version": "2.6.0" - }, - "org.apache.cassandra:java-driver-core": { - "shasums": { - "jar": "6276a8e25c8821eeaa5d2d67c50b81615d551dd7ec943302689996f6bdb2add1", - "sources": "80a95f2d4d61091a8f54bf76f2d26269ee7b8ac82e261314108d7ad83c083838" - }, - "version": "4.19.3" - }, - "org.apache.cassandra:java-driver-guava-shaded": { - "shasums": { - "jar": "fa5e6dfb61a987e69cd8559464145b6ceb6610d28760b0d8cff17eba052c8264", - "sources": "9415d1dd6132671cefc43eb5ac560f34d5e4a1b73ac25310fbfc4584a8033ec3" - }, - "version": "4.19.3" - }, - "org.apache.cassandra:java-driver-metrics-micrometer": { - "shasums": { - "jar": "4f61ed8dabc978f7c9bfdae578915480b6242468feea1c73571be7d832ee3d0a", - "sources": "6214d824dc8e72fd6221165b1497f4c46099027b7ad220ce17f44a8f3f58807f" - }, - "version": "4.19.3" - }, - "org.apache.cassandra:java-driver-query-builder": { - "shasums": { - "jar": "b6e4c84dff2448aaa67f5e3e867b1bf284ca6ad0c15701a4d4d7283384d8df12", - "sources": "dd63fa1af436d1b01155fdca72563338007e265fd8c05c3a8b2e80e76b2d4aa8" - }, - "version": "4.19.3" - }, - "org.apache.commons:commons-compress": { - "shasums": { - "jar": "e1522945218456f3649a39bc4afd70ce4bd466221519dba7d378f2141a4642ca", - "sources": "6de9de4559f12bba6d41789c72f6a2a424514f2d2a3f7f49e2a3c52414db9632" - }, - "version": "1.28.0" - }, - "org.apache.commons:commons-lang3": { - "shasums": { - "jar": "69e5c9fa35da7a51a5fd2099dfe56a2d8d32cf233e2f6d770e796146440263f4", - "sources": "eec245e820ec2800a1780cf756aefb427c1c6170e06902e67ac15b6910ce6335" - }, - "version": "3.20.0" - }, - "org.apache.logging.log4j:log4j-api": { - "shasums": { - "jar": "c4b642a7f047275215de117e0e3847eb2c7711d84a0aa7433e7b3c096daf341d", - "sources": "b86680bcf8ffa25897b6114cae508bb8e6ecac8081a0fc8985e0c00e27d4f4ec" - }, - "version": "2.25.4" - }, - "org.apache.logging.log4j:log4j-to-slf4j": { - "shasums": { - "jar": "d7b78fc0aaaa5e8ada388b29d718b0ab187e512965bed0b259bb4ab299f13db2", - "sources": "ca9159da173bf88fb621adf745fe1d313ba4074f4c66576ae70f5dd99eab89c9" - }, - "version": "2.25.4" - }, - "org.apache.tomcat.embed:tomcat-embed-core": { - "shasums": { - "jar": "78cd7cd7c104b6b87142c1b0bd902e1ce005b0245c3cefa8a06759148947200b", - "sources": "0bfbdc27e60d4db5b83e0f51193bae5f4bd02ac270fd78b06945e219fc473359" - }, - "version": "11.0.22" - }, - "org.apache.tomcat.embed:tomcat-embed-el": { - "shasums": { - "jar": "1b34c33b858c141df36c501b4d809e68036c406bca3671a86facae297917c7de", - "sources": "da3724004575f5c8fa7e45649f2900ec53e7ecfb502b6ce227ca9cf86b36a156" - }, - "version": "11.0.22" - }, - "org.apache.tomcat.embed:tomcat-embed-websocket": { - "shasums": { - "jar": "210e0c7ab194a76cc7283df0be365276091b042369dae125fb477828ba67e922", - "sources": "711f09af528ac5af172c664244bcba4748eac00811ef7c6b52ddd6836b5a4a28" - }, - "version": "11.0.22" - }, - "org.apiguardian:apiguardian-api": { - "shasums": { - "jar": "b509448ac506d607319f182537f0b35d71007582ec741832a1f111e5b5b70b38", - "sources": "277a7a4315412817beb6655b324dc7276621e95ebff00b8bf65e17a27b685e2d" - }, - "version": "1.1.2" - }, - "org.assertj:assertj-core": { - "shasums": { - "jar": "c4a445426c3c2861666863b842cc4ec7bbb1c4226fefd370b6d2fe83d6c4ff0f", - "sources": "5ba6de05730cf76021001f8437f35db4cb5b513465d4ace8c3a6fcd68d9a19ee" - }, - "version": "3.27.7" - }, - "org.awaitility:awaitility": { - "shasums": { - "jar": "ee58568ea5945dcf988551501655183dc184e23e45a8e013fdfd9036194e6f7b", - "sources": "92d209bd0135b04ca6bb7689c6b921819896ec2d517a5357760f598faafee46c" - }, - "version": "4.3.0" - }, - "org.bouncycastle:bcprov-jdk18on": { - "shasums": { - "jar": "64d6c5a6121fcd927152dd182cbed39afe0fda641a970d9bcc0c9cb1858b2731", - "sources": "e5f04550f7740e588edcbd1654c59277cd7ee8725d8b674e44f7f8f4b9c5674a" - }, - "version": "1.84" - }, - "org.bouncycastle:bcprov-lts8on": { - "shasums": { - "jar": "492049b928f8baab535af0185bbab8734d14e1c7648ae2a2037d58486cafb676", - "sources": "d4447a4f412b328f3e43595ab99603dd38b08ee1db9f1ea341e6158eeb86a70d" - }, - "version": "2.73.8" - }, - "org.hamcrest:hamcrest": { - "shasums": { - "jar": "5d66b6a4a680755cb6ed7cb104fa7835ef644667586ff0737adeb977c39ecdbc", - "sources": "7a4050b1898f7e1aa395cf2be78fb6683f9e2766fcb8e1507926b204fa24d1bf" - }, - "version": "3.0" - }, - "org.hdrhistogram:HdrHistogram": { - "shasums": { - "jar": "22d1d4316c4ec13a68b559e98c8256d69071593731da96136640f864fa14fad8", - "sources": "d3933c83a764994930f4477d4199539eaf413b42e32127ec2b68c61d711ac1a9" - }, - "version": "2.2.2" - }, - "org.hibernate.validator:hibernate-validator": { - "shasums": { - "jar": "25f40118fa4c50f8522d090d25d52d5a38953b0ccd1250835f052e7bd3164ce0", - "sources": "db6a3d49eceaae0a880de8749cd7f7e8928c18458b44fac84633c3ee8db7ac0d" - }, - "version": "9.0.1.Final" - }, - "org.jacoco:org.jacoco.agent": { - "shasums": { - "runtime": "3fb76eea65f81bd9415202bab34b6571728841dff1ab8e6bbe81adc2e299face", - "sources": "8a643b749deb255d7a42c445c3053c9ec263e27103becdaaf88cedda44357255" - }, - "version": "0.8.14" - }, - "org.jacoco:org.jacoco.cli": { - "shasums": { - "jar": "12d5d78351c638efeea71ac840f6a5cf7bcff89001ddb05eb89f956d1079a2c6", - "sources": "52f715f15b890960f70f4ae8fbdd4bca70eba59c0283b37af2d79ad9215d2e37" - }, - "version": "0.8.14" - }, - "org.jacoco:org.jacoco.core": { - "shasums": { - "jar": "28abbf0eea5a08e4f24097f2fbac663ca17c341c25c3a04d90d6cd325943c995", - "sources": "1550fd5081ecd2c2ad053994c23d91a4cef6dcbed4c4dac95130e7d75fa9cd3c" - }, - "version": "0.8.14" - }, - "org.jacoco:org.jacoco.report": { - "shasums": { - "jar": "a3e2026060ab8b8d5c650706406234bb4c033dfd5376afeb8b1666e8ed27c453", - "sources": "80ac2fac212d6a4583b7f025dc7b602f384a9dfcdbccd0e9cb78c415e9f5ffc6" - }, - "version": "0.8.14" - }, - "org.jboss.logging:jboss-logging": { - "shasums": { - "jar": "7c12ee575508f81e22b1db9334b969d0ec54ef0fd1dcba24eeab1a44235fc366", - "sources": "e8a2b9aaac82b0082aa040e6bdf6cd7f225cdbc75d2bd1a79fa7b17007ec1b15" - }, - "version": "3.6.3.Final" - }, - "org.jetbrains.kotlin:kotlin-stdlib": { - "shasums": { - "jar": "6558a3d233da56a20934b32159f9db5f86ed5816ef098f78a2c223dc6abb79dd", - "sources": "664f515359444a92267a13266101431a630f99d6b8d04407a92b1a0e558d33ee" - }, - "version": "2.2.21" - }, - "org.jetbrains:annotations": { - "shasums": { - "jar": "195fb0da046d55bb042e91543484cf1da68b02bb7afbfe031f229e45ac84b3f2", - "sources": "b2c0d02e0a32c56d359e99634e7d769f9b1a8cd6e25061995abad1c1baf86f56" - }, - "version": "17.0.0" - }, - "org.jspecify:jspecify": { - "shasums": { - "jar": "1fad6e6be7557781e4d33729d49ae1cdc8fdda6fe477bb0cc68ce351eafdfbab", - "sources": "adf0898191d55937fb3192ba971826f4f294292c4a960740f3c27310e7b70296" - }, - "version": "1.0.0" - }, - "org.junit.jupiter:junit-jupiter": { - "shasums": { - "jar": "784b65815f479a0c99a9d3a573b142e2a525efb6025d97f751b19e72f90aeda3", - "sources": "402f86a4fdce930bb68b592f2ed5a9d57dc4d1b2747aa2d66c0b3cb7a2adceeb" - }, - "version": "6.0.3" - }, - "org.junit.jupiter:junit-jupiter-api": { - "shasums": { - "jar": "d655d7e6f0c7ae07f10a2f3bbaaebb6d30e9b26204a068ad9e9b3950aa28792c", - "sources": "8266d8da51d0c7d6a2ed4895a3cb76e0ec22194907f24364f2a4f3efd05f00a5" - }, - "version": "6.0.3" - }, - "org.junit.jupiter:junit-jupiter-engine": { - "shasums": { - "jar": "1e2fab61ad27ea08fc7c70dd9677cf8c6d1ae5434d42dcfdd633b12c7e7c04d0", - "sources": "35706a9edf1b580bf22d6eca9d6a9165f478f75b0108840ad6f31481cd662d6c" - }, - "version": "6.0.3" - }, - "org.junit.jupiter:junit-jupiter-params": { - "shasums": { - "jar": "cf2947e2302b9f8c8a059259a277881c1cadae8fbc2514c16a925cfeb7beb2e5", - "sources": "f0dcf217100b06b98cd36c2e74fb919c74e3024faad868bac9eba6ff00c7c263" - }, - "version": "6.0.3" - }, - "org.junit.platform:junit-platform-commons": { - "shasums": { - "jar": "39f262d09c3d52719fe0b77f080e90a3695e285d779a41b232e17963ae5da200", - "sources": "06cbe4a4bbd79339c3817983510cf3adc3d6a88a8a556c80c5b84eeb1ebd13dc" - }, - "version": "6.0.3" - }, - "org.junit.platform:junit-platform-console-standalone": { - "shasums": { - "jar": "3ba0d6150af79214a1411f9ea2fbef864eef68b68c89a17f672c0b89bff9d3a2", - "sources": "c4e79459727c6fe6afbddcc04daa67767fb73d7044d29846dd4ab90de1d0fa0c" - }, - "version": "6.0.3" - }, - "org.junit.platform:junit-platform-engine": { - "shasums": { - "jar": "491e9e4f745f161b8a8e4186a1a7c6a450ea12c70930c9aedae427215301d947", - "sources": "89a893566a97557dbbcb0706d9b5565c4e7a402050841753dc527f3e9139c9ac" - }, - "version": "6.0.3" - }, - "org.latencyutils:LatencyUtils": { - "shasums": { - "jar": "a32a9ffa06b2f4e01c5360f8f9df7bc5d9454a5d373cd8f361347fa5a57165ec", - "sources": "717e271b5d67c190afba092795d79bba496434256aca7151cf6a02f83564e724" - }, - "version": "2.0.3" - }, - "org.mockito:mockito-core": { - "shasums": { - "jar": "d1a96d252128d3a4247cfd8a2e76412efa3cc103977be17933c942117a24f374", - "sources": "dcde489c1db6449c162f05105ace4c172850d3dc7f6633bb4f54d47a16a0fd1b" - }, - "version": "5.20.0" - }, - "org.mockito:mockito-junit-jupiter": { - "shasums": { - "jar": "fd6c703c2b00b914f3adbc27b18077a708f3d6992f19242c444e737c6cce024e", - "sources": "3c199479a2319db4395fd9fd209946ecc4530f48fe5cdeed7677c285bf70fbb5" - }, - "version": "5.20.0" - }, - "org.objenesis:objenesis": { - "shasums": { - "jar": "02dfd0b0439a5591e35b708ed2f5474eb0948f53abf74637e959b8e4ef69bfeb", - "sources": "d06164f8ca002c8ef193cef2d682822014dd330505616af93a3fb64226fc131d" - }, - "version": "3.3" - }, - "org.opentest4j:opentest4j": { - "shasums": { - "jar": "48e2df636cab6563ced64dcdff8abb2355627cb236ef0bf37598682ddf742f1b", - "sources": "724a24e3a68267d5ebac9411389a15638a71e50c62448ffa58f59c34d5c1ebb2" - }, - "version": "1.3.0" - }, - "org.ow2.asm:asm": { - "shasums": { - "jar": "03d99a74ad1ee5c71334ef67437f4ef4fe3488caa7c96d8645abc73c8e2017d4", - "sources": "e37000a2a0bc9f0bef373714ad7dde4082212351847b74618d483057a4ae186c" - }, - "version": "9.9" - }, - "org.ow2.asm:asm-analysis": { - "shasums": { - "jar": "6a15d28e8bd29ba4fd5bca4baf9b50e8fba2d7b51fbf78cfa0c875a7214c678b", - "sources": "ff731d401ea2407759ea19b4b025800d32495a51a912f2553d987cddda424773" - }, - "version": "9.9" - }, - "org.ow2.asm:asm-commons": { - "shasums": { - "jar": "db2f6f26150bbe7c126606b4a1151836bcc22a1e05a423b3585698bece995ff8", - "sources": "218bbb648e24578a385cb6b6a21ceff222a2a8f8b2d5f6a256a8099dd336dc76" - }, - "version": "9.9" - }, - "org.ow2.asm:asm-tree": { - "shasums": { - "jar": "42178f3775c9c63f9e5e1446747d29b4eca4d91bd6e75e5c43cfa372a47d38c6", - "sources": "9d1fe261fa1d29904ca9dbc76878396e76bc225191676a8c16ad2669a205321a" - }, - "version": "9.9" - }, - "org.ow2.asm:asm-util": { - "shasums": { - "jar": "3842e13cfe324ee9ab7cdc4914be9943541ead397c17e26daf0b8a755bede717", - "sources": "e518a00b1d004832e72c6448351c4865971ac95a7cfe78fb0315d76acb393a46" - }, - "version": "9.9" - }, - "org.projectlombok:lombok": { - "shasums": { - "jar": "01f7b1a015e33e2b62d5f5f37053306357ab1415fd181fcba7794f5d198c1126", - "sources": "5b78c305a65fbe257d57878bff6530e2b79e1a2cd660f45dcb7d7f8f5e56a483" - }, - "version": "1.18.46" - }, - "org.reactivestreams:reactive-streams": { - "shasums": { - "jar": "f75ca597789b3dac58f61857b9ac2e1034a68fa672db35055a8fb4509e325f28", - "sources": "5a7a36ae9536698c434ebe119feb374d721210fee68eb821a37ef3859b64b708" - }, - "version": "1.0.4" - }, - "org.rnorth.duct-tape:duct-tape": { - "shasums": { - "jar": "31cef12ddec979d1f86d7cf708c41a17da523d05c685fd6642e9d0b2addb7240", - "sources": "b385fd2c2b435c313b3f02988d351503230c9631bfb432261cbd8ce9765d2a26" - }, - "version": "1.0.8" - }, - "org.skyscreamer:jsonassert": { - "shasums": { - "jar": "719095c07d4203961320da593441d8b3b643c18eb1d81aa98ea933bb7eb351ba", - "sources": "a825c29f8cc40f85ea4e7a431a55d4278a785c34acdeef4cd1be7367f70ea6bb" - }, - "version": "1.5.3" - }, - "org.slf4j:jul-to-slf4j": { - "shasums": { - "jar": "cbb7d1aaaa9e871eb1a06594abd911bf97027152976edf1edc315be75239204e", - "sources": "b6dd2138f3e83d876bf07206d09f2b48ca655bc36a8e80b0c2a32ad19ab8f1d5" - }, - "version": "2.0.18" - }, - "org.slf4j:slf4j-api": { - "shasums": { - "jar": "44508fd1576500688c790b190acdd16fec4f8c79a3e0b900afd70503cf055f55", - "sources": "192e007cf7f2be41d40574e44521fc0b7ce55e01f13dbe0fa8707c8ae3329075" - }, - "version": "2.0.18" - }, - "org.springdoc:springdoc-openapi-starter-common": { - "shasums": { - "jar": "a0b5a6a5384b4a36718fd7a69efbd48311fd5f404c96ce286a6c285c5d0038e6", - "sources": "19a2612f56ea7d867c70cdae5e8fdf9d2b7a3cbdcba257c1d9ddfe88e48a74b0" - }, - "version": "3.0.3" - }, - "org.springdoc:springdoc-openapi-starter-webflux-api": { - "shasums": { - "jar": "a58f130aa60c47001e0d7b6b5e611edbbf187f58aa7d697dd720ac220f57b384", - "sources": "90968a39c963a144ee30248146dff38eb568edf57109ccddb843d6a92c1ef756" - }, - "version": "3.0.3" - }, - "org.springdoc:springdoc-openapi-starter-webmvc-api": { - "shasums": { - "jar": "c7e0221797240037eaf20c834f2d03fabec3f26051bd7052be8bf169f2c02876", - "sources": "e0fad37b01fefa5b52aec1cc09101017a397ae93f7ba8dace72ed29d1f2a3106" - }, - "version": "3.0.3" - }, - "org.springframework.boot:spring-boot": { - "shasums": { - "jar": "edb984d0bc80d209bed271e6d334fbfbfcf11cc4c1ef5059adc31c5bde7b1d7c", - "sources": "850ec7c91b0ff92c46797e0adcf1f47369d64a0cf4a8427d01b4834df129d0d4" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-actuator": { - "shasums": { - "jar": "edfedbcc5d33c8b0a8d0156dcc8cbf6234a33dc861001c7ec8ef63af19197b7e", - "sources": "d74a19a07e1eaf70bfe00b33332c3d61d82621e887b1a8af3b4dbb05051ca197" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-actuator-autoconfigure": { - "shasums": { - "jar": "59b188a313fda88bbe6cba613dd13aa00d1cc49135b11120ae5d451f72d49c00", - "sources": "c4aa275f1a4c97020d56d96cdb5f1b9a0b8157da06b62313c55e2d861e683c59" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-autoconfigure": { - "shasums": { - "jar": "1e8a953294fe76727965970de31e3bb08fba2b65e3ca0ee9b8bca492d0818d10", - "sources": "477e9834d7982b080b485c7baeb27ea399fca324d0442dc2f694a473b6a394fd" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-cassandra": { - "shasums": { - "jar": "8a69a41383b36eed9b58b462c698cf7ec825ea0ac3b131ce7c2f92419dbc3bc7", - "sources": "e580260c129670d80a96c84c2241d5cbad3d9f9a183d3af201b2b5acab96e3cd" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-data-cassandra": { - "shasums": { - "jar": "f17d6ed4fe4825abb68ec4743a3248d9e456c94e099e2653c392ee75cef4b8a6", - "sources": "d2fcf562626d79bc13f71284c2a9b820975ce0bd35e9e9daeef8deb05fb14e53" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-data-cassandra-test": { - "shasums": { - "jar": "5ad17d2ffcd040eae3f425e7588e2b2604461b47ac7801c5ccfb5179e6725832", - "sources": "73ca527b7a6d67b0e8a20865d91f0bb15092ef3415c7ebefe475bc14894440da" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-data-commons": { - "shasums": { - "jar": "991f28c95c3b5687d41429ec1da258d6ebdf33c1778dab2057361df9983dc6c7", - "sources": "bbfa0f3571ee162c21597e7fc7a925a5919e1267ebb55eb5b3698c2832de9ec0" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-health": { - "shasums": { - "jar": "e1c81e0e8d89ba7d25a3522d52159a4bcfa9bf7ee4e0d53cef61244e75a244bb", - "sources": "0d664e89d03dffde004f79e9aa5a7482128d0358c284edb0b5c2895eb25a43b7" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-http-client": { - "shasums": { - "jar": "7881d09b33f278b39fd1018d0cb7d91b73b72406d2350351166511b1c3a76c6b", - "sources": "17ee08d609a1d4d1d64198b9cf0cf79920974400460022b4b97117d22b7ea73a" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-http-codec": { - "shasums": { - "jar": "dd3e79f5bf872e34eca182f3a6f050278263562da042a1a0bc338f5d70d4ab60", - "sources": "4f2231f549e7353f3095b58995520bcb073d4c155aadc839f3f66d1b6543059e" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-http-converter": { - "shasums": { - "jar": "9f620c36cb98103ef664a9fccad4173ae20120d1abc790b795130be4e02dbb90", - "sources": "9f4378bcb3caa6696d8fe340c519bd673287f2c046098607cbe079ba9aa98874" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-jackson": { - "shasums": { - "jar": "0cdbadd10bcc3b23d32dffd419caceda4a4ed6b3da0262617f543732e9105ece", - "sources": "efe6e9f38861e94fbf36045bb23d23076407d26fed5752efb852ad2accaea3bb" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-micrometer-metrics": { - "shasums": { - "jar": "1cd20b112104d244fdc96b44b3a8193e0916686a819a6be93127c1c7eefc1c9d", - "sources": "b61f894a893ef3f3e0b978e7430f08c6b3580c19ac963bbbf8901a28b2d18f6b" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-micrometer-metrics-test": { - "shasums": { - "jar": "124e88e2d8ef0331653bb9d2c849143e210e97d3ded4e8cbdb0bd68c05ea2e65", - "sources": "b17d0251cee5454db0d3e573a8c23d6b0055de534fa49b75c18bc0af6ea9f100" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-micrometer-observation": { - "shasums": { - "jar": "aced85ab6f7a2a8b15d8bd52c2b75dfe47c9890dc08d39e24b2e7b78f79b6ac2", - "sources": "8e159976cbcf123f3333793f47e88c71932ff6f2f785db8c69831bfbcf75bc3b" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-micrometer-tracing": { - "shasums": { - "jar": "dfb60c9422c80957a020e8751317bc3515f3ed56d5d92da685bfece6c0ba780a", - "sources": "c0d8f28ffbd343b00586195ee8fd34d2441562c67f01cc100578f62145e51846" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-micrometer-tracing-opentelemetry": { - "shasums": { - "jar": "3463de0849ee471c99726b8c9a334cde69a96c78c496aa452db9d9f34b53603e", - "sources": "01b024f9530bce7dabf3592a3f50fe8063c1f9f5ae6d982edf73ba85410b3cd6" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-netty": { - "shasums": { - "jar": "d5526be25b050ad5e4dd7a56095b78357bf73bbe447d900588fe7f895873ff3f", - "sources": "34b0173a82c5b35275a773b213b20591c4047b87e3f0b6dc9c1d0736b5084591" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-opentelemetry": { - "shasums": { - "jar": "42ce3e301fb94f6d15efbed5bae1c3ea9f8fe8da93afa1ac4aacf1819c1d2cd4", - "sources": "f07c50fd5e2dc2b27fbcf08f2d7ad1b8663b8611788b6bf1f4b66fe5c5dbee5b" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-persistence": { - "shasums": { - "jar": "201cd088c5fddbcff7ece343f42eee0cabbab64083d339f35e5eb4edbcdbd4bb", - "sources": "863fc339ae51cc5b5287cac067ff5527cdff2ec8da85358d8bf61fa9a460568c" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-reactor": { - "shasums": { - "jar": "abb8ac783f1a3e2de68f2ececfb22ef4ba47c74089ce377a1476f3ccf5c35539", - "sources": "0753ac2c9596f010acdac06e9bc69d3d5a35dd9abec4e44c1de600dbb7577c13" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-reactor-netty": { - "shasums": { - "jar": "5679a1518fece25f608b6abdb165bae59c4ba1aa76833700fb6cf35d528575a1", - "sources": "35281bbd1465a0a22c1f6a2188c64e2efc8535f2e30807687c77ec15197b58ca" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-restclient": { - "shasums": { - "jar": "4438e7cbe09fe2d1aa40da4112cbc2a7f0067046dbfd153e79122be6e143c82a", - "sources": "87f4a654821800a30f5d41ac5320877cd96cf436a60ac2dd541369b159a4eff2" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-resttestclient": { - "shasums": { - "jar": "976fada4921b1817e1ced3c0da93a709d85638b519a9e63c3075e76c1e3c0593", - "sources": "ad2de8d55af3be0eba0e59259eb6427fd83eca7fdd134454a0c9cde2cde4c9bc" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-security": { - "shasums": { - "jar": "fef4d4952d7c4f86112d4a27cb98cf1d71001373f9d8f88fbf0af9d908fdaa3c", - "sources": "edc45113d48d5b3f7e3ef6f722ffb905a2b0bd5791e79879b591cfe74972178e" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-security-oauth2-client": { - "shasums": { - "jar": "37a6474b11b65f39b444971572e66553512992f4434280365cedcb396b8afbec", - "sources": "dcf7f976f5e8216498d3415508598fa6e8da7248a9ae3056f94fc3abfb76c65f" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-security-oauth2-resource-server": { - "shasums": { - "jar": "d33c17f53bab6054589d94bbc36f8ed017fb0c1cd353c9b8a85359b72d4d25e8", - "sources": "2d598d95730fca23bc1ab8d08af3cad04c6cd69e5d4f728d7ce25f3f5e410953" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-security-test": { - "shasums": { - "jar": "7e34b14edd632dc3cd911931d3e3d74de40d863aa1a1849be4b217a293b14004", - "sources": "ad5a8312d621e12e659b198ded8b8c1b1a2066b34940443856e6302bd8e885b1" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-servlet": { - "shasums": { - "jar": "fb1af769617daa2808a82921d98ca94efde8cb20fcefc55e71b2e0bf93de1423", - "sources": "172a6736933d75bdeeee725078769e27d8142a826e811940c595aea815913512" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-starter": { - "shasums": { - "jar": "d70f5f300c9e7af18813799bffce38974398f6429c578c825822a32560c4b202", - "sources": "d70f5f300c9e7af18813799bffce38974398f6429c578c825822a32560c4b202" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-starter-actuator": { - "shasums": { - "jar": "576d445c6d0b7920f098822f45d74c2239f363d06508f8acf2a181f0b69c2cb9", - "sources": "576d445c6d0b7920f098822f45d74c2239f363d06508f8acf2a181f0b69c2cb9" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-starter-actuator-test": { - "shasums": { - "jar": "9f87aeefd9049094dd1fd64d96632bee353f871e0999c7c0531d69a2dcf7a945", - "sources": "9f87aeefd9049094dd1fd64d96632bee353f871e0999c7c0531d69a2dcf7a945" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-starter-data-cassandra": { - "shasums": { - "jar": "32abc561b414e781bc1998e1a6cd1167f3eff2247e6bb2b1b08a347bb3054acb", - "sources": "32abc561b414e781bc1998e1a6cd1167f3eff2247e6bb2b1b08a347bb3054acb" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-starter-data-cassandra-test": { - "shasums": { - "jar": "aacd60f7f5cab180a23dbd87fd5b53d524c2c89ce42635d5eaa4331075dec548", - "sources": "aacd60f7f5cab180a23dbd87fd5b53d524c2c89ce42635d5eaa4331075dec548" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-starter-jackson": { - "shasums": { - "jar": "bd042218bf291c4ee821d7ec3e86f7f747223d32cd87066aa5e3730a2dd5c3b6", - "sources": "bd042218bf291c4ee821d7ec3e86f7f747223d32cd87066aa5e3730a2dd5c3b6" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-starter-jackson-test": { - "shasums": { - "jar": "72ad611e32e370446bb2de890da4f084def1d354f4526522f0ae1182265b545a", - "sources": "72ad611e32e370446bb2de890da4f084def1d354f4526522f0ae1182265b545a" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-starter-logging": { - "shasums": { - "jar": "b5f1d01cd179ffc24b125a6ce971854b7b141c4e19e9c050a0b82d514983b1f6", - "sources": "b5f1d01cd179ffc24b125a6ce971854b7b141c4e19e9c050a0b82d514983b1f6" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-starter-micrometer-metrics": { - "shasums": { - "jar": "a5d302b2d6e9a8e1989455888aad2f69349f4c0b43b7ef41c8063c4bb92dec32", - "sources": "a5d302b2d6e9a8e1989455888aad2f69349f4c0b43b7ef41c8063c4bb92dec32" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-starter-micrometer-metrics-test": { - "shasums": { - "jar": "dd6d8969ce0e7736d29c5ce1dbdf9d9d89ac0c7ecbae41485abeb5b3efe87546", - "sources": "dd6d8969ce0e7736d29c5ce1dbdf9d9d89ac0c7ecbae41485abeb5b3efe87546" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-starter-reactor-netty": { - "shasums": { - "jar": "ceebf772bae1c9492fce1c766fdc18a7a17388f02f639a6ba20824b8a3dd848c", - "sources": "ceebf772bae1c9492fce1c766fdc18a7a17388f02f639a6ba20824b8a3dd848c" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-starter-security": { - "shasums": { - "jar": "04e806b5737be0d399c85d356b060599684df6fc4f56cc08b85a563ae1a066dd", - "sources": "04e806b5737be0d399c85d356b060599684df6fc4f56cc08b85a563ae1a066dd" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-starter-security-oauth2-client": { - "shasums": { - "jar": "1afd7f96736afc19451ad2a4f001e54af93d9d9d788802df9f4e536860560aca", - "sources": "1afd7f96736afc19451ad2a4f001e54af93d9d9d788802df9f4e536860560aca" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server": { - "shasums": { - "jar": "72dbb14dc0b21f43cee18ae6caa6bf7b0c4efe4bac11702e34529280865ecd83", - "sources": "72dbb14dc0b21f43cee18ae6caa6bf7b0c4efe4bac11702e34529280865ecd83" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server-test": { - "shasums": { - "jar": "8e13abf7c7754171c83c8236b796ef3d6e8d841a3ddafd84dfec0e5615b77e75", - "sources": "8e13abf7c7754171c83c8236b796ef3d6e8d841a3ddafd84dfec0e5615b77e75" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-starter-security-test": { - "shasums": { - "jar": "a7320624975022865468e255b8e0c414f76d380eef7793faeca87f98496998ad", - "sources": "a7320624975022865468e255b8e0c414f76d380eef7793faeca87f98496998ad" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-starter-test": { - "shasums": { - "jar": "e4844ae2375d569711af218763620993ea434b4836d3463cf26d9f6b6e589340", - "sources": "e4844ae2375d569711af218763620993ea434b4836d3463cf26d9f6b6e589340" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-starter-tomcat": { - "shasums": { - "jar": "f4a81ce616baa9c715be0dc0735210d770aa67301f92d3b11942f780056fc7ad", - "sources": "f4a81ce616baa9c715be0dc0735210d770aa67301f92d3b11942f780056fc7ad" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-starter-tomcat-runtime": { - "shasums": { - "jar": "8d0c7cbd6bd43d47e664a9127f70ceddab952828797f20e2b0b93848796d82f2", - "sources": "8d0c7cbd6bd43d47e664a9127f70ceddab952828797f20e2b0b93848796d82f2" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-starter-validation": { - "shasums": { - "jar": "bc449f60bb483374e7358afcda3fccb6e01906e158c7e1e00d9035277a6545b7", - "sources": "bc449f60bb483374e7358afcda3fccb6e01906e158c7e1e00d9035277a6545b7" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-starter-webflux": { - "shasums": { - "jar": "dd99ab79bd18c6358183b146c3eb35730652dd36d2225d5795405efa7137b1a0", - "sources": "dd99ab79bd18c6358183b146c3eb35730652dd36d2225d5795405efa7137b1a0" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-starter-webflux-test": { - "shasums": { - "jar": "78c866953b611065c85b8f069b18d330c1f2051db932fc3a3e8213b852b7f8eb", - "sources": "78c866953b611065c85b8f069b18d330c1f2051db932fc3a3e8213b852b7f8eb" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-starter-webmvc": { - "shasums": { - "jar": "b70e0d9e1bc667a3a9ad509f98a6e9ac443af8eab5143f8c77a38aec0a014a2c", - "sources": "b70e0d9e1bc667a3a9ad509f98a6e9ac443af8eab5143f8c77a38aec0a014a2c" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-starter-webmvc-test": { - "shasums": { - "jar": "d11fd7bbd613040f88ddba503c486970dd282abb92f12158bc9655ee533e9f31", - "sources": "d11fd7bbd613040f88ddba503c486970dd282abb92f12158bc9655ee533e9f31" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-test": { - "shasums": { - "jar": "8879b4a336972eb498ca6606266e6ecdae911964c0a480d3f4bf37a6c2455b33", - "sources": "4dc67a1a332d75fa3dcf517f4b6dc66ed146793307aa9d23c0ebb5f4b399850a" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-test-autoconfigure": { - "shasums": { - "jar": "99ca7ab8be0dde10fa6c03e1026969619e826fcc914b6bc0d09090e75ba17cb4", - "sources": "f94cf34c24539cc3752fae1a0bf182282086452e9c83cfae5241574f20951eb3" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-tomcat": { - "shasums": { - "jar": "ad7c6527319f5cac0b5638a28820847f64d21282147fb98daaaa1f515ee17323", - "sources": "2388d2eaeb9d413d3d7525983fe14030d3b48bc0cca1530c8c7e9dc73e05e8b5" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-validation": { - "shasums": { - "jar": "15161d6eda4589a24ea30d1fd466bfe3843861c3b55963d49a26bfc0bf2ebbb2", - "sources": "52beb1b2b90adb6cec5bf8523e534e56fed771a7f0fe3d42191a4d3b8a5d3873" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-web-server": { - "shasums": { - "jar": "26a13c73ee85e7a851b73eb2d683ed4d3b7a4ca581b608dfd627bd4551997cf2", - "sources": "41e1dddf6e1be5fc35c4849f51639c097e7a8eb9c6627a780791a1d9e430c311" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-webclient": { - "shasums": { - "jar": "119d82faa651b35964eab73ea3d962b1c7434792647cbf82c9dde44785749671", - "sources": "bf3dd5bf566482bc32c0c75548eb9c6a598b4d26c66677cfb84fca4cd21ccf81" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-webflux": { - "shasums": { - "jar": "7eca957fe0ad8ee60642d58e6a8e652ebaf64198b72f9ccfa959bea056fb7091", - "sources": "fc7dcb5570215a40c78fdab85c60876b740be714cb479d03b3bd39b2c7b26e5f" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-webflux-test": { - "shasums": { - "jar": "3ed73416ab316d0247d9c2efbb922db1247f03d114fada897f70f9d59408c839", - "sources": "5164cd1c633380d2f2616855a2773f099f15aebc2ad70c04a942e673be12be6b" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-webmvc": { - "shasums": { - "jar": "95250948bda9a0a1e1f2ad3f413bd23e36dfedefb89fe59d309d447c6c4c5010", - "sources": "26a04367e170092463c619c886f4f8b688644eecc4a6c91c18d17c242a8f4211" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-webmvc-test": { - "shasums": { - "jar": "06180d3ee7f9019880b0528cc93164f8f038e35007bd99a40fbe52892d96a955", - "sources": "4c5b614a96d50a44fce7c3269b82f26fed6d3d04933140ecf52db5e4d32e2480" - }, - "version": "4.0.7" - }, - "org.springframework.boot:spring-boot-webtestclient": { - "shasums": { - "jar": "7015636f7e41b69d80fd903acdcb1554f2b062551c1ce353e625ea4a11f52903", - "sources": "b1175e4937c93d493bbae0a2c7e2cee13cd60a6b7dd859fb6e662091f986e28f" - }, - "version": "4.0.7" - }, - "org.springframework.cloud:spring-cloud-commons": { - "shasums": { - "jar": "6973e75b09d7ccb98566e4e980f600cd98ffcdc76d19fd822e93c7c2166ffa49", - "sources": "fd39f42ebda40c120a450256bbca653d250ff105ea640a530680c1251ced5ca3" - }, - "version": "5.0.2" - }, - "org.springframework.cloud:spring-cloud-context": { - "shasums": { - "jar": "8972e4677e511dc518280d13a16d1a3e6e3ed4ee91e643d3f0c66676f6078f75", - "sources": "3765a79f4a43fe01a1298b09cd8ee51f0e9692971555478fd157bdf456a70c7b" - }, - "version": "5.0.2" - }, - "org.springframework.cloud:spring-cloud-starter": { - "shasums": { - "jar": "7568b8ced4069bc055af52b5455b206092401a44dcbd4f89d6fa00f89df1cc18" - }, - "version": "5.0.2" - }, - "org.springframework.cloud:spring-cloud-starter-bootstrap": { - "shasums": { - "jar": "366aa9da9bd1e8222bed83fa698649b16ba4b2a976a028d565b95afe610735df", - "sources": "46bb02036834b9db0cfe086ca2b4e9581319029e9dff2b420ddf3eb8094f3d62" - }, - "version": "5.0.2" - }, - "org.springframework.data:spring-data-cassandra": { - "shasums": { - "jar": "d9e4f2656df238d5561d02d0521036f52518b91d0ef840fd8f25d113b4325610", - "sources": "35340468867c3c37447606312f1d2e2ab18b5123885967a364743f77f196bdb7" - }, - "version": "5.0.6" - }, - "org.springframework.data:spring-data-commons": { - "shasums": { - "jar": "626151b9c33ab98ebec7f1a2e9746cfe1aa428b0de513f9bb90383533ab8ba6d", - "sources": "8d08a88e7b6761bfb84a79fadde38bafaeeed90ddf4595ba9cbf71c25ed7e2dd" - }, - "version": "4.0.6" - }, - "org.springframework.security:spring-security-config": { - "shasums": { - "jar": "7aeafd876d48d8b5660356953ed7a607d2d09e8f2b9844acba3fcbc32beb63cc", - "sources": "aeb9131e5cd38ea7ebeb0d348c90da837c807f8b68ae3c0fc3152a46682f16ee" - }, - "version": "7.0.6" - }, - "org.springframework.security:spring-security-core": { - "shasums": { - "jar": "f9e1aebb39e051f6f92be029a6fca31e2977a06d417aa51504bfb298bc2a7c69", - "sources": "73d208a0dd021cad8cbbb85a71c8efc66df0161f49e91cd9d877a55def6bc9d0" - }, - "version": "7.0.6" - }, - "org.springframework.security:spring-security-crypto": { - "shasums": { - "jar": "baf9f76bc5b15d090a82841fd5713fa11b75f91fc86de27029d972ce85d3d2e2", - "sources": "bb183230f96711625bdc1d0fc45398917062c2b6b605f94f8dbf0de6a7a1f862" - }, - "version": "7.0.6" - }, - "org.springframework.security:spring-security-oauth2-client": { - "shasums": { - "jar": "2c50bff8f60f08a46bef837dca50d1270f0dba64a60f551c0b96b33a1f608487", - "sources": "47549b16e028266bf4836b4bf00e9111a46143ae486aaed1ff0370c56ddbe82a" - }, - "version": "7.0.6" - }, - "org.springframework.security:spring-security-oauth2-core": { - "shasums": { - "jar": "01cc03b6f30e5b526e85fc276b32af25f34b119f601bc17ba3cbe023f45b0271", - "sources": "68bc19e0b85c108766d92bc4a9e9948a641d65d23d1d93cca7f724998665f88f" - }, - "version": "7.0.6" - }, - "org.springframework.security:spring-security-oauth2-jose": { - "shasums": { - "jar": "c8cd9a8aefc42a02e34166ff02f3f7def2f6028f555932f04f163dea729bdff9", - "sources": "1a33db514d2ce33222aae9bb3ba41227112de08986aac4e58be857417e7332ea" - }, - "version": "7.0.6" - }, - "org.springframework.security:spring-security-oauth2-resource-server": { - "shasums": { - "jar": "4c53ad5b6a06b9f6272212b5a0a71d003b4ba01dd16de691fd63ddf37554f098", - "sources": "97d33151cd02afcded341ab7ad65f1bcca4798789f5626a5d948809ba529373a" - }, - "version": "7.0.6" - }, - "org.springframework.security:spring-security-test": { - "shasums": { - "jar": "4b65c38c7fcf372793cdf6e57651be1332ec241fff9481b15ed8f3ea2207382c", - "sources": "61886c39c6853ebafa91718c1bc44ebaad6f834dcb8d0524e509135033c9498c" - }, - "version": "7.0.6" - }, - "org.springframework.security:spring-security-web": { - "shasums": { - "jar": "6ef060f97271218c0bff56273dc2edb8e2e001a253a0291278d5fdafa5d70573", - "sources": "33298fd169429984bb6cebf9f4a6176ae9eee047e8b5a3ab6b3d752526db03d9" - }, - "version": "7.0.6" - }, - "org.springframework:spring-aop": { - "shasums": { - "jar": "1178f039e087884174e2affc46e484f4a8bd7f2a4e011d33dd9137709f740f80", - "sources": "580610d9e5e2418ea48f64850673ed1d1fdc2d9c8e5cf6e9cfaece1e61b70522" - }, - "version": "7.0.8" - }, - "org.springframework:spring-beans": { - "shasums": { - "jar": "6ec2e361a8872a71d8b1ff66f1bcb8cfa29fcc437931998919da7cecfb59b45b", - "sources": "d75bdcfe142b1576f72356748292cad5c21872a52be2c7f2920a9795bb3c52a5" - }, - "version": "7.0.8" - }, - "org.springframework:spring-context": { - "shasums": { - "jar": "1eb7d552414ebac00e30ab3e809138d810785f6d2c4271db77cdf0181f308f19", - "sources": "a28b30679b51bcf8aac7f06cb564a379cc2d6c4891b2e2dfc738ddd750c6278e" - }, - "version": "7.0.8" - }, - "org.springframework:spring-core": { - "shasums": { - "jar": "726ba2a5130833644bdf267a55ff26e1f52e8dcc9aa1ffa06904ca9c14619f25", - "sources": "3cbdaed9f2b1eea10d8ac27148ac5e6407d2861fa2d373253a09a1220a232919" - }, - "version": "7.0.8" - }, - "org.springframework:spring-expression": { - "shasums": { - "jar": "3c97c38ab59c77ee886e08ccf8096f6bb58a1245f68dfed7a40e93f41c435f9a", - "sources": "35517249c504d1d4550186808665587c8bb5be953cb6cbbb3856804194e790e9" - }, - "version": "7.0.8" - }, - "org.springframework:spring-test": { - "shasums": { - "jar": "6ffb7796075a204915edc4bb9e54dc420183cecb520d753004f660f153763c8e", - "sources": "7bc670e2e1c9cc902da5557a857dde0a4d8089c267ccfcc1bb554cbf2a8c5a05" - }, - "version": "7.0.8" - }, - "org.springframework:spring-tx": { - "shasums": { - "jar": "57e8fdb6de949e7ec2617683fec03af0253bdbdf4bf3d2651a926a94413df283", - "sources": "7887541d74a7221ca92e21d1a2ecc13e8f98767b1603b3b6bb81d7bbd5aede48" - }, - "version": "7.0.8" - }, - "org.springframework:spring-web": { - "shasums": { - "jar": "4d4ed7ecb0453d25d735ea27d025ea36b003c3d29cb7d006bedd6d5188a2f5c0", - "sources": "281cbbd965844cdf2e08396924eacd8a369cd38f56fdfb9519c7492217d8b411" - }, - "version": "7.0.8" - }, - "org.springframework:spring-webflux": { - "shasums": { - "jar": "3e48db9c30d3768ac14898cfad4bad21f4cfc6a8979a12071b75e725143e5eb9", - "sources": "9b00f6ad4a63f3c636e455f3e733d0f75cf5dcdd8225820a1498469b707652ba" - }, - "version": "7.0.8" - }, - "org.springframework:spring-webmvc": { - "shasums": { - "jar": "48f7e1e2d0d46e98ed3fa30d5a64cb1f7ed2aa339a82edcd87289ed8ff216f04", - "sources": "6dcbc3dc4d5222121f83d1eb0d30807e389771b8d233be38b8e413b92b88a106" - }, - "version": "7.0.8" - }, - "org.testcontainers:testcontainers": { - "shasums": { - "jar": "0466f481343d5f350a91274cd7bf984308cbaf90d706247fd1cf4b1a8010c2e1", - "sources": "b4dfdb7d0f8dadc6bfa6d817df703b5c6881b83b6d0452148fd9a00434387e24" - }, - "version": "2.0.5" - }, - "org.testcontainers:testcontainers-cassandra": { - "shasums": { - "jar": "c6ce343636e40330da6ffa317ca4a56bf09affd3e272445d0176498497218cbe", - "sources": "4b2324b4336a0e6d928467abef387ded2b9014ab1353f85cf715f87d1dbb5be3" - }, - "version": "2.0.5" - }, - "org.testcontainers:testcontainers-database-commons": { - "shasums": { - "jar": "0ebbc62bdcfb315cb840a63fbaa148b455927666d9034b5e5c00009d84c755b0", - "sources": "017efc160847bf209b3fdfa3561fa6eb1a5b5b5b82d2214f965caabe9c2cf9ab" - }, - "version": "2.0.5" - }, - "org.testcontainers:testcontainers-junit-jupiter": { - "shasums": { - "jar": "d66eb7f257a85833a8cc973e3814d740967d40a7db1a0de0040653c6ed236748", - "sources": "0dd4463ca900cbce90894cdaafb18fd146ea50b92ee0ee72a9c3e1e48b53a8e6" - }, - "version": "2.0.5" - }, - "org.wiremock:wiremock-standalone": { - "shasums": { - "jar": "d097b19bd483c5038479b13a5c71e9faf8f2f5106584f0c120a7770ab0bdb367", - "sources": "76cda98377991ed09088773fe7127f9787e14f8bd41bcd285f94cbd7cd95546f" - }, - "version": "3.13.2" - }, - "org.xmlunit:xmlunit-core": { - "shasums": { - "jar": "208e0cee82aedd9183937e4b9ae44b83884179f724a706bef5795477acfcca91", - "sources": "bb8dba65e8bc1ade346e4bfd98d7f620f51ae8b9034e9758cd6f3031838e79fd" - }, - "version": "2.10.4" - }, - "org.yaml:snakeyaml": { - "shasums": { - "jar": "e6682acf1ace77508ef13649cbf4f8d09d2cf5457bdb61d25ffb6ac0233d78dd", - "sources": "7a7d307ca9fe1663219a60045a8e5a113a69331566f9ebbe1d3b12c6781909ac" - }, - "version": "2.5" - }, - "software.amazon.awssdk:annotations": { - "shasums": { - "jar": "fa3ba3b1b635dfc4d0b20f3910b325f8b70419d1fdb56b487d2e1c423c85e041", - "sources": "2c15cad3cec83ce99c86b9f135d24f42429c5c9a4d032351adfc42330cde8b97" - }, - "version": "2.40.1" - }, - "software.amazon.awssdk:checksums": { - "shasums": { - "jar": "6770fdd0d970c1869cd869d784cc20963a4a6b2bee09f125da0504ba2c9e818d", - "sources": "3a5de1a7994ab25bef0eda898645ba6f02ab584bd3d904f21014bfd9d7cb98b5" - }, - "version": "2.40.1" - }, - "software.amazon.awssdk:checksums-spi": { - "shasums": { - "jar": "1f9d68cd2f5ec133757e37b794ab06de015d1b35f4c1452b43ab8b612318a8c3", - "sources": "d17d8d92268f9c6773aa6b72564774dc394ae2fb2149bed26152385a9b6751ff" - }, - "version": "2.40.1" - }, - "software.amazon.awssdk:endpoints-spi": { - "shasums": { - "jar": "05a48200f243664fa9ca8f05cf29725cbd059a9a6f3cdd55bac44a8fc12903de", - "sources": "24644eb6a36a38df7a31e81fb9fcd106298f188215b6e2ec178732711fc4b0ba" - }, - "version": "2.40.1" - }, - "software.amazon.awssdk:http-auth-aws": { - "shasums": { - "jar": "9b182f3697acc111b213524126f857f844fed5fdf95f734470d16b96097fcd3a", - "sources": "6de3c527d996a46a4e14e268fc13a32b314383a3b2976e7820720c9ddff483a5" - }, - "version": "2.40.1" - }, - "software.amazon.awssdk:http-auth-spi": { - "shasums": { - "jar": "d0cd6f8dd1ef77a990c4b0ae45132707490f886307d9ee446ae1eae93a80ae5a", - "sources": "6bd36a3bfbce87b5550d73ad7ff6d0950dc6aec1baf071b0c47bd02cd98daa3d" - }, - "version": "2.40.1" - }, - "software.amazon.awssdk:http-client-spi": { - "shasums": { - "jar": "87c6fc3ec6c79e088ebfcc818963715bc0a5e103f5612bd4b6d5c49720bb06e3", - "sources": "d6667c353cc231efee460dae061be2b654d3319ffb66d16804da30f5a8475d84" - }, - "version": "2.40.1" - }, - "software.amazon.awssdk:identity-spi": { - "shasums": { - "jar": "b4693f3832b3669850a11f29608a2a3d6e0150ab1528d01cad2a7a32848db591", - "sources": "56ab003dea16ded5f70c1a3af840433c6f5f8fd33435500535e7b888cdf8c923" - }, - "version": "2.40.1" - }, - "software.amazon.awssdk:json-utils": { - "shasums": { - "jar": "f565187ae223ab13a4b959f213933540475652269c414b0c82f33cab45977a74", - "sources": "3fbd4a882a672587b93b9cdd2ee7c2c1faa0f5a848509d3d3d7931ef714d6d95" - }, - "version": "2.40.1" - }, - "software.amazon.awssdk:metrics-spi": { - "shasums": { - "jar": "033b5d20384c9b4ac98a17eba0656711738da94a9d33a292b414aa0905177471", - "sources": "373fbebacc328596dda847d8183f22b9e6abef85f7c6287d7c71615cab3d4939" - }, - "version": "2.40.1" - }, - "software.amazon.awssdk:profiles": { - "shasums": { - "jar": "602cac04531cf13d4c06d8d70d7b5b0e109517c73a4c91473058886fbe574cc1", - "sources": "e498cf7ef147b8fc789a448554561b5706daae1062a5e23bc4870149b42d8002" - }, - "version": "2.40.1" - }, - "software.amazon.awssdk:regions": { - "shasums": { - "jar": "6b1c788306fd7a4fac6bc788a8f5d2300be13049197adacfca072d1b69eb9ddb", - "sources": "1bae6ad3cb124a6850fbede87c9dcd72f7c7eab1f570c9ae71a98f3597c4b59f" - }, - "version": "2.40.1" - }, - "software.amazon.awssdk:retries": { - "shasums": { - "jar": "198f5f0202fe8e861f3ad2fa8ecb70d0a8180dd568f4d136c898f824b3cd0dd3", - "sources": "2305b334eceb894749d281a3f48be9198e9305f09cb3b40b948a5c661c20c41a" - }, - "version": "2.40.1" - }, - "software.amazon.awssdk:retries-spi": { - "shasums": { - "jar": "af1c67e4212fffe7d215b41fb74e6994c36a0499234e325954c38db6b14e0e28", - "sources": "c8e5f28924cc8e0cb017a2a25c370a0d0ed9223cfb0051c6a1b0c769a5a46e0b" - }, - "version": "2.40.1" - }, - "software.amazon.awssdk:sdk-core": { - "shasums": { - "jar": "6c6b1a49b18538060d1f9a797998ca8d589910b274b345bbf0a61c4540e41f27", - "sources": "560156fe956a48cd171077edc2ccb1bcfe2f93c09e3ce62667018228b6144450" - }, - "version": "2.40.1" - }, - "software.amazon.awssdk:third-party-jackson-core": { - "shasums": { - "jar": "9939a77038dd0d53675a44fc06afb9b34805cef8fc7b3641d2e861740c1655fc", - "sources": "92ce15d5817f97d935c595b780135666d4674eaf3aeb94ae13b1e4e553f93e42" - }, - "version": "2.40.1" - }, - "software.amazon.awssdk:utils": { - "shasums": { - "jar": "40f19e6ce26acc6a78204aa493833f578e2245cc0bc9749cc9ba431bb8f855e1", - "sources": "2ddd7c56fbc36d7c4e0c84739d68388faff130f51855ce2b80466c8784cf1b25" - }, - "version": "2.40.1" - }, - "tools.jackson.core:jackson-core": { - "shasums": { - "jar": "3bda1cd6eff0a8d47bdfcaeae7c2bd5311d6c8ed494ef5f3e51029bb44aa9bdf", - "sources": "5aa481c1c120505fc1d204510ec201a40c2bb0bb6bdea24560e0b5fb66484e60" - }, - "version": "3.1.4" - }, - "tools.jackson.core:jackson-databind": { - "shasums": { - "jar": "14034bfdf392b6ebec1b4bb6c1de29d604f0aa97251259a19d5f19af8719bb20", - "sources": "109baa39968ff6fdcc4389dd4249f04d2edcab7387421ea17bfb51bf18e24189" - }, - "version": "3.1.4" - }, - "tools.jackson.module:jackson-module-blackbird": { - "shasums": { - "jar": "d93aef324acdbffeb4e943e75ed0772f43101930b70fe37219147e5d3b84b3cd", - "sources": "5c7f6900e8b888c6c3edad9b13cd4df0d11f5bd8307064bb79881cb4edd389ef" - }, - "version": "3.1.4" - } - }, - "conflict_resolution": { - "com.github.jnr:jnr-ffi:2.2.11": "com.github.jnr:jnr-ffi:2.1.7", - "com.github.jnr:jnr-posix:3.0.44": "com.github.jnr:jnr-posix:3.1.15", - "com.google.code.findbugs:jsr305:3.0.2": "com.google.code.findbugs:jsr305:2.0.1", - "com.google.errorprone:error_prone_annotations:2.47.0": "com.google.errorprone:error_prone_annotations:2.49.0", - "com.google.guava:guava:19.0": "com.google.guava:guava:33.6.0-jre", - "org.jetbrains:annotations:13.0": "org.jetbrains:annotations:17.0.0", - "org.ow2.asm:asm-commons:5.0.3": "org.ow2.asm:asm-commons:9.9", - "org.ow2.asm:asm-tree:5.0.3": "org.ow2.asm:asm-tree:9.9", - "org.ow2.asm:asm:5.0.3": "org.ow2.asm:asm:9.9", - "org.ow2.asm:asm:9.7.1": "org.ow2.asm:asm:9.9" - }, - "dependencies": { - "ch.qos.logback:logback-classic": [ - "ch.qos.logback:logback-core", - "org.slf4j:slf4j-api" - ], - "com.datastax.cassandra:cassandra-driver-core": [ - "com.fasterxml.jackson.core:jackson-databind", - "com.github.jnr:jnr-ffi", - "com.github.jnr:jnr-posix", - "com.google.guava:guava", - "io.dropwizard.metrics:metrics-core", - "io.netty:netty-handler", - "org.slf4j:slf4j-api" - ], - "com.fasterxml.jackson.core:jackson-databind": [ - "com.fasterxml.jackson.core:jackson-annotations", - "com.fasterxml.jackson.core:jackson-core" - ], - "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml": [ - "com.fasterxml.jackson.core:jackson-core", - "com.fasterxml.jackson.core:jackson-databind", - "org.yaml:snakeyaml" - ], - "com.fasterxml.jackson.datatype:jackson-datatype-jsr310": [ - "com.fasterxml.jackson.core:jackson-annotations", - "com.fasterxml.jackson.core:jackson-core", - "com.fasterxml.jackson.core:jackson-databind" - ], - "com.github.ben-manes.caffeine:caffeine": [ - "com.google.errorprone:error_prone_annotations", - "org.jspecify:jspecify" - ], - "com.github.ben-manes.caffeine:guava": [ - "com.github.ben-manes.caffeine:caffeine", - "com.google.guava:guava" - ], - "com.github.docker-java:docker-java-api": [ - "com.fasterxml.jackson.core:jackson-annotations", - "org.slf4j:slf4j-api" - ], - "com.github.docker-java:docker-java-transport-zerodep": [ - "com.github.docker-java:docker-java-transport", - "net.java.dev.jna:jna", - "org.slf4j:slf4j-api" - ], - "com.github.java-json-tools:btf": [ - "com.google.code.findbugs:jsr305" - ], - "com.github.java-json-tools:jackson-coreutils": [ - "com.fasterxml.jackson.core:jackson-databind", - "com.github.java-json-tools:msg-simple", - "com.google.code.findbugs:jsr305" - ], - "com.github.java-json-tools:json-patch": [ - "com.fasterxml.jackson.core:jackson-databind", - "com.github.java-json-tools:jackson-coreutils", - "com.github.java-json-tools:msg-simple" - ], - "com.github.java-json-tools:msg-simple": [ - "com.github.java-json-tools:btf", - "com.google.code.findbugs:jsr305" - ], - "com.github.jnr:jnr-ffi": [ - "com.github.jnr:jffi", - "com.github.jnr:jffi:jar:native", - "com.github.jnr:jnr-x86asm", - "org.ow2.asm:asm", - "org.ow2.asm:asm-analysis", - "org.ow2.asm:asm-commons", - "org.ow2.asm:asm-tree", - "org.ow2.asm:asm-util" - ], - "com.github.jnr:jnr-posix": [ - "com.github.jnr:jnr-constants", - "com.github.jnr:jnr-ffi" - ], - "com.google.guava:guava": [ - "com.google.errorprone:error_prone_annotations", - "com.google.guava:failureaccess", - "com.google.guava:listenablefuture", - "com.google.j2objc:j2objc-annotations", - "org.jspecify:jspecify" - ], - "com.jayway.jsonpath:json-path": [ - "net.minidev:json-smart", - "org.slf4j:slf4j-api" - ], - "com.nimbusds:oauth2-oidc-sdk": [ - "com.github.stephenc.jcip:jcip-annotations", - "com.nimbusds:content-type", - "com.nimbusds:lang-tag", - "com.nimbusds:nimbus-jose-jwt", - "net.minidev:json-smart" - ], - "com.squareup.okhttp3:okhttp-jvm": [ - "com.squareup.okio:okio-jvm", - "org.jetbrains.kotlin:kotlin-stdlib" - ], - "com.squareup.okio:okio-jvm": [ - "org.jetbrains.kotlin:kotlin-stdlib" - ], - "io.cloudevents:cloudevents-core": [ - "io.cloudevents:cloudevents-api" - ], - "io.cloudevents:cloudevents-json-jackson": [ - "com.fasterxml.jackson.core:jackson-core", - "com.fasterxml.jackson.core:jackson-databind", - "io.cloudevents:cloudevents-core" - ], - "io.dropwizard.metrics:metrics-core": [ - "org.slf4j:slf4j-api" - ], - "io.micrometer:context-propagation": [ - "org.jspecify:jspecify" - ], - "io.micrometer:micrometer-commons": [ - "org.jspecify:jspecify" - ], - "io.micrometer:micrometer-core": [ - "io.micrometer:micrometer-commons", - "io.micrometer:micrometer-observation", - "org.hdrhistogram:HdrHistogram", - "org.jspecify:jspecify", - "org.latencyutils:LatencyUtils" - ], - "io.micrometer:micrometer-jakarta9": [ - "io.micrometer:micrometer-commons", - "io.micrometer:micrometer-core", - "io.micrometer:micrometer-observation", - "org.jspecify:jspecify" - ], - "io.micrometer:micrometer-observation": [ - "io.micrometer:micrometer-commons", - "org.jspecify:jspecify" - ], - "io.micrometer:micrometer-observation-test": [ - "io.micrometer:micrometer-observation", - "org.assertj:assertj-core", - "org.jspecify:jspecify", - "org.junit.jupiter:junit-jupiter", - "org.mockito:mockito-core" - ], - "io.micrometer:micrometer-tracing": [ - "aopalliance:aopalliance", - "io.micrometer:context-propagation", - "io.micrometer:micrometer-observation", - "org.jspecify:jspecify" - ], - "io.micrometer:micrometer-tracing-bridge-otel": [ - "io.micrometer:micrometer-observation", - "io.micrometer:micrometer-tracing", - "io.opentelemetry.semconv:opentelemetry-semconv", - "io.opentelemetry:opentelemetry-api", - "io.opentelemetry:opentelemetry-extension-trace-propagators", - "io.opentelemetry:opentelemetry-sdk", - "io.opentelemetry:opentelemetry-sdk-common", - "io.opentelemetry:opentelemetry-sdk-trace", - "org.jspecify:jspecify", - "org.slf4j:slf4j-api" - ], - "io.nats:jnats": [ - "org.bouncycastle:bcprov-lts8on", - "org.jspecify:jspecify" - ], - "io.netty:netty-buffer": [ - "io.netty:netty-common" - ], - "io.netty:netty-codec-base": [ - "io.netty:netty-buffer", - "io.netty:netty-common", - "io.netty:netty-transport" - ], - "io.netty:netty-codec-compression": [ - "io.netty:netty-buffer", - "io.netty:netty-codec-base", - "io.netty:netty-common", - "io.netty:netty-transport" - ], - "io.netty:netty-codec-dns": [ - "io.netty:netty-buffer", - "io.netty:netty-codec-base", - "io.netty:netty-common", - "io.netty:netty-transport" - ], - "io.netty:netty-codec-http": [ - "io.netty:netty-buffer", - "io.netty:netty-codec-base", - "io.netty:netty-codec-compression", - "io.netty:netty-common", - "io.netty:netty-handler", - "io.netty:netty-transport" - ], - "io.netty:netty-codec-http2": [ - "io.netty:netty-buffer", - "io.netty:netty-codec-base", - "io.netty:netty-codec-http", - "io.netty:netty-common", - "io.netty:netty-handler", - "io.netty:netty-transport" - ], - "io.netty:netty-codec-http3": [ - "io.netty:netty-buffer", - "io.netty:netty-codec-base", - "io.netty:netty-codec-classes-quic", - "io.netty:netty-codec-compression", - "io.netty:netty-codec-http", - "io.netty:netty-codec-native-quic:jar:linux-aarch_64", - "io.netty:netty-codec-native-quic:jar:linux-x86_64", - "io.netty:netty-codec-native-quic:jar:osx-aarch_64", - "io.netty:netty-codec-native-quic:jar:osx-x86_64", - "io.netty:netty-codec-native-quic:jar:windows-x86_64", - "io.netty:netty-common", - "io.netty:netty-handler", - "io.netty:netty-resolver", - "io.netty:netty-transport", - "io.netty:netty-transport-native-unix-common" - ], - "io.netty:netty-codec-native-quic:jar:linux-aarch_64": [ - "io.netty:netty-codec-classes-quic" - ], - "io.netty:netty-codec-native-quic:jar:linux-x86_64": [ - "io.netty:netty-codec-classes-quic" - ], - "io.netty:netty-codec-native-quic:jar:osx-aarch_64": [ - "io.netty:netty-codec-classes-quic" - ], - "io.netty:netty-codec-native-quic:jar:osx-x86_64": [ - "io.netty:netty-codec-classes-quic" - ], - "io.netty:netty-codec-native-quic:jar:windows-x86_64": [ - "io.netty:netty-codec-classes-quic" - ], - "io.netty:netty-codec-socks": [ - "io.netty:netty-buffer", - "io.netty:netty-codec-base", - "io.netty:netty-common", - "io.netty:netty-transport" - ], - "io.netty:netty-handler": [ - "io.netty:netty-buffer", - "io.netty:netty-codec-base", - "io.netty:netty-common", - "io.netty:netty-resolver", - "io.netty:netty-transport", - "io.netty:netty-transport-native-unix-common" - ], - "io.netty:netty-handler-proxy": [ - "io.netty:netty-buffer", - "io.netty:netty-codec-base", - "io.netty:netty-codec-http", - "io.netty:netty-codec-socks", - "io.netty:netty-common", - "io.netty:netty-handler", - "io.netty:netty-transport" - ], - "io.netty:netty-resolver": [ - "io.netty:netty-common" - ], - "io.netty:netty-resolver-dns": [ - "io.netty:netty-buffer", - "io.netty:netty-codec-base", - "io.netty:netty-codec-dns", - "io.netty:netty-common", - "io.netty:netty-handler", - "io.netty:netty-resolver", - "io.netty:netty-transport" - ], - "io.netty:netty-resolver-dns-classes-macos": [ - "io.netty:netty-common", - "io.netty:netty-resolver-dns", - "io.netty:netty-transport-native-unix-common" - ], - "io.netty:netty-resolver-dns-native-macos:jar:osx-x86_64": [ - "io.netty:netty-resolver-dns-classes-macos" - ], - "io.netty:netty-transport": [ - "io.netty:netty-buffer", - "io.netty:netty-common", - "io.netty:netty-resolver" - ], - "io.netty:netty-transport-classes-epoll": [ - "io.netty:netty-buffer", - "io.netty:netty-common", - "io.netty:netty-transport", - "io.netty:netty-transport-native-unix-common" - ], - "io.netty:netty-transport-native-epoll:jar:linux-x86_64": [ - "io.netty:netty-buffer", - "io.netty:netty-common", - "io.netty:netty-transport", - "io.netty:netty-transport-classes-epoll", - "io.netty:netty-transport-native-unix-common" - ], - "io.netty:netty-transport-native-unix-common": [ - "io.netty:netty-buffer", - "io.netty:netty-common", - "io.netty:netty-transport" - ], - "io.opentelemetry:opentelemetry-api": [ - "io.opentelemetry:opentelemetry-context" - ], - "io.opentelemetry:opentelemetry-context": [ - "io.opentelemetry:opentelemetry-common" - ], - "io.opentelemetry:opentelemetry-exporter-common": [ - "io.opentelemetry:opentelemetry-api", - "io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi" - ], - "io.opentelemetry:opentelemetry-exporter-otlp": [ - "io.opentelemetry:opentelemetry-exporter-otlp-common", - "io.opentelemetry:opentelemetry-exporter-sender-okhttp", - "io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi", - "io.opentelemetry:opentelemetry-sdk-logs", - "io.opentelemetry:opentelemetry-sdk-metrics", - "io.opentelemetry:opentelemetry-sdk-trace" - ], - "io.opentelemetry:opentelemetry-exporter-otlp-common": [ - "io.opentelemetry:opentelemetry-exporter-common" - ], - "io.opentelemetry:opentelemetry-exporter-sender-okhttp": [ - "com.squareup.okhttp3:okhttp-jvm", - "io.opentelemetry:opentelemetry-exporter-common", - "io.opentelemetry:opentelemetry-sdk-common" - ], - "io.opentelemetry:opentelemetry-extension-trace-propagators": [ - "io.opentelemetry:opentelemetry-api" - ], - "io.opentelemetry:opentelemetry-sdk": [ - "io.opentelemetry:opentelemetry-api", - "io.opentelemetry:opentelemetry-sdk-common", - "io.opentelemetry:opentelemetry-sdk-logs", - "io.opentelemetry:opentelemetry-sdk-metrics", - "io.opentelemetry:opentelemetry-sdk-trace" - ], - "io.opentelemetry:opentelemetry-sdk-common": [ - "io.opentelemetry:opentelemetry-api" - ], - "io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi": [ - "io.opentelemetry:opentelemetry-sdk" - ], - "io.opentelemetry:opentelemetry-sdk-logs": [ - "io.opentelemetry:opentelemetry-api", - "io.opentelemetry:opentelemetry-sdk-common" - ], - "io.opentelemetry:opentelemetry-sdk-metrics": [ - "io.opentelemetry:opentelemetry-api", - "io.opentelemetry:opentelemetry-sdk-common" - ], - "io.opentelemetry:opentelemetry-sdk-testing": [ - "io.opentelemetry:opentelemetry-api", - "io.opentelemetry:opentelemetry-sdk" - ], - "io.opentelemetry:opentelemetry-sdk-trace": [ - "io.opentelemetry:opentelemetry-api", - "io.opentelemetry:opentelemetry-sdk-common" - ], - "io.projectreactor.netty:reactor-netty-core": [ - "io.netty:netty-handler", - "io.netty:netty-handler-proxy", - "io.netty:netty-resolver-dns", - "io.netty:netty-resolver-dns-native-macos:jar:osx-x86_64", - "io.netty:netty-transport-native-epoll:jar:linux-x86_64", - "io.projectreactor:reactor-core", - "org.jspecify:jspecify" - ], - "io.projectreactor.netty:reactor-netty-http": [ - "io.netty:netty-codec-http", - "io.netty:netty-codec-http2", - "io.netty:netty-codec-http3", - "io.netty:netty-resolver-dns", - "io.netty:netty-resolver-dns-native-macos:jar:osx-x86_64", - "io.netty:netty-transport-native-epoll:jar:linux-x86_64", - "io.projectreactor.netty:reactor-netty-core", - "io.projectreactor:reactor-core", - "org.jspecify:jspecify" - ], - "io.projectreactor:reactor-core": [ - "org.jspecify:jspecify", - "org.reactivestreams:reactive-streams" - ], - "io.projectreactor:reactor-test": [ - "io.projectreactor:reactor-core", - "org.jspecify:jspecify" - ], - "io.swagger.core.v3:swagger-core-jakarta": [ - "com.fasterxml.jackson.core:jackson-annotations", - "com.fasterxml.jackson.core:jackson-databind", - "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml", - "com.fasterxml.jackson.datatype:jackson-datatype-jsr310", - "io.swagger.core.v3:swagger-annotations-jakarta", - "io.swagger.core.v3:swagger-models-jakarta", - "jakarta.validation:jakarta.validation-api", - "jakarta.xml.bind:jakarta.xml.bind-api", - "org.apache.commons:commons-lang3", - "org.slf4j:slf4j-api", - "org.yaml:snakeyaml" - ], - "io.swagger.core.v3:swagger-models-jakarta": [ - "com.fasterxml.jackson.core:jackson-annotations" - ], - "jakarta.xml.bind:jakarta.xml.bind-api": [ - "jakarta.activation:jakarta.activation-api" - ], - "net.minidev:accessors-smart": [ - "org.ow2.asm:asm" - ], - "net.minidev:json-smart": [ - "net.minidev:accessors-smart" - ], - "org.apache.cassandra:java-driver-core": [ - "com.datastax.oss:native-protocol", - "com.fasterxml.jackson.core:jackson-core", - "com.fasterxml.jackson.core:jackson-databind", - "com.github.jnr:jnr-posix", - "com.typesafe:config", - "io.netty:netty-handler", - "org.apache.cassandra:java-driver-guava-shaded", - "org.reactivestreams:reactive-streams", - "org.slf4j:slf4j-api" - ], - "org.apache.cassandra:java-driver-metrics-micrometer": [ - "io.micrometer:micrometer-core", - "org.apache.cassandra:java-driver-core" - ], - "org.apache.cassandra:java-driver-query-builder": [ - "org.apache.cassandra:java-driver-core", - "org.apache.cassandra:java-driver-guava-shaded" - ], - "org.apache.commons:commons-compress": [ - "commons-codec:commons-codec", - "commons-io:commons-io", - "org.apache.commons:commons-lang3" - ], - "org.apache.logging.log4j:log4j-to-slf4j": [ - "org.apache.logging.log4j:log4j-api", - "org.slf4j:slf4j-api" - ], - "org.apache.tomcat.embed:tomcat-embed-websocket": [ - "org.apache.tomcat.embed:tomcat-embed-core" - ], - "org.assertj:assertj-core": [ - "net.bytebuddy:byte-buddy" - ], - "org.awaitility:awaitility": [ - "org.hamcrest:hamcrest" - ], - "org.hibernate.validator:hibernate-validator": [ - "com.fasterxml:classmate", - "jakarta.validation:jakarta.validation-api", - "org.jboss.logging:jboss-logging" - ], - "org.jacoco:org.jacoco.cli": [ - "args4j:args4j", - "org.jacoco:org.jacoco.core", - "org.jacoco:org.jacoco.report" - ], - "org.jacoco:org.jacoco.core": [ - "org.ow2.asm:asm", - "org.ow2.asm:asm-commons", - "org.ow2.asm:asm-tree" - ], - "org.jacoco:org.jacoco.report": [ - "org.jacoco:org.jacoco.core" - ], - "org.jetbrains.kotlin:kotlin-stdlib": [ - "org.jetbrains:annotations" - ], - "org.junit.jupiter:junit-jupiter": [ - "org.junit.jupiter:junit-jupiter-api", - "org.junit.jupiter:junit-jupiter-engine", - "org.junit.jupiter:junit-jupiter-params" - ], - "org.junit.jupiter:junit-jupiter-api": [ - "org.apiguardian:apiguardian-api", - "org.jspecify:jspecify", - "org.junit.platform:junit-platform-commons", - "org.opentest4j:opentest4j" - ], - "org.junit.jupiter:junit-jupiter-engine": [ - "org.apiguardian:apiguardian-api", - "org.jspecify:jspecify", - "org.junit.jupiter:junit-jupiter-api", - "org.junit.platform:junit-platform-engine" - ], - "org.junit.jupiter:junit-jupiter-params": [ - "org.apiguardian:apiguardian-api", - "org.jspecify:jspecify", - "org.junit.jupiter:junit-jupiter-api" - ], - "org.junit.platform:junit-platform-commons": [ - "org.apiguardian:apiguardian-api", - "org.jspecify:jspecify" - ], - "org.junit.platform:junit-platform-engine": [ - "org.apiguardian:apiguardian-api", - "org.jspecify:jspecify", - "org.junit.platform:junit-platform-commons", - "org.opentest4j:opentest4j" - ], - "org.mockito:mockito-core": [ - "net.bytebuddy:byte-buddy", - "net.bytebuddy:byte-buddy-agent", - "org.objenesis:objenesis" - ], - "org.mockito:mockito-junit-jupiter": [ - "org.junit.jupiter:junit-jupiter-api", - "org.mockito:mockito-core" - ], - "org.ow2.asm:asm-analysis": [ - "org.ow2.asm:asm-tree" - ], - "org.ow2.asm:asm-commons": [ - "org.ow2.asm:asm", - "org.ow2.asm:asm-tree" - ], - "org.ow2.asm:asm-tree": [ - "org.ow2.asm:asm" - ], - "org.ow2.asm:asm-util": [ - "org.ow2.asm:asm", - "org.ow2.asm:asm-analysis", - "org.ow2.asm:asm-tree" - ], - "org.rnorth.duct-tape:duct-tape": [ - "org.jetbrains:annotations" - ], - "org.skyscreamer:jsonassert": [ - "com.vaadin.external.google:android-json" - ], - "org.slf4j:jul-to-slf4j": [ - "org.slf4j:slf4j-api" - ], - "org.springdoc:springdoc-openapi-starter-common": [ - "io.swagger.core.v3:swagger-core-jakarta", - "org.springframework.boot:spring-boot-autoconfigure", - "org.springframework.boot:spring-boot-jackson", - "org.springframework.boot:spring-boot-starter", - "org.springframework.boot:spring-boot-validation" - ], - "org.springdoc:springdoc-openapi-starter-webflux-api": [ - "org.springdoc:springdoc-openapi-starter-common", - "org.springframework.boot:spring-boot-web-server", - "org.springframework.boot:spring-boot-webflux" - ], - "org.springdoc:springdoc-openapi-starter-webmvc-api": [ - "org.springdoc:springdoc-openapi-starter-common", - "org.springframework.boot:spring-boot-web-server", - "org.springframework.boot:spring-boot-webmvc" - ], - "org.springframework.boot:spring-boot": [ - "org.springframework:spring-context", - "org.springframework:spring-core" - ], - "org.springframework.boot:spring-boot-actuator": [ - "org.springframework.boot:spring-boot" - ], - "org.springframework.boot:spring-boot-actuator-autoconfigure": [ - "org.springframework.boot:spring-boot-actuator", - "org.springframework.boot:spring-boot-autoconfigure" - ], - "org.springframework.boot:spring-boot-autoconfigure": [ - "org.springframework.boot:spring-boot" - ], - "org.springframework.boot:spring-boot-cassandra": [ - "org.apache.cassandra:java-driver-core", - "org.springframework.boot:spring-boot" - ], - "org.springframework.boot:spring-boot-data-cassandra": [ - "org.springframework.boot:spring-boot-cassandra", - "org.springframework.boot:spring-boot-data-commons", - "org.springframework.data:spring-data-cassandra" - ], - "org.springframework.boot:spring-boot-data-cassandra-test": [ - "org.springframework.boot:spring-boot-data-cassandra", - "org.springframework.boot:spring-boot-test-autoconfigure" - ], - "org.springframework.boot:spring-boot-data-commons": [ - "org.springframework.boot:spring-boot", - "org.springframework.boot:spring-boot-persistence", - "org.springframework.data:spring-data-commons" - ], - "org.springframework.boot:spring-boot-health": [ - "org.springframework.boot:spring-boot" - ], - "org.springframework.boot:spring-boot-http-client": [ - "org.springframework.boot:spring-boot", - "org.springframework.boot:spring-boot-http-converter", - "org.springframework:spring-web" - ], - "org.springframework.boot:spring-boot-http-codec": [ - "org.springframework.boot:spring-boot", - "org.springframework:spring-web" - ], - "org.springframework.boot:spring-boot-http-converter": [ - "org.springframework.boot:spring-boot", - "org.springframework:spring-web" - ], - "org.springframework.boot:spring-boot-jackson": [ - "org.springframework.boot:spring-boot", - "tools.jackson.core:jackson-databind" - ], - "org.springframework.boot:spring-boot-micrometer-metrics": [ - "io.micrometer:micrometer-core", - "org.springframework.boot:spring-boot", - "org.springframework.boot:spring-boot-micrometer-observation" - ], - "org.springframework.boot:spring-boot-micrometer-metrics-test": [ - "io.micrometer:micrometer-observation-test", - "org.springframework.boot:spring-boot-micrometer-metrics", - "org.springframework.boot:spring-boot-test-autoconfigure" - ], - "org.springframework.boot:spring-boot-micrometer-observation": [ - "io.micrometer:micrometer-observation", - "org.springframework.boot:spring-boot" - ], - "org.springframework.boot:spring-boot-micrometer-tracing": [ - "io.micrometer:micrometer-tracing", - "org.springframework.boot:spring-boot", - "org.springframework.boot:spring-boot-micrometer-observation" - ], - "org.springframework.boot:spring-boot-micrometer-tracing-opentelemetry": [ - "io.micrometer:micrometer-tracing", - "org.springframework.boot:spring-boot", - "org.springframework.boot:spring-boot-micrometer-observation", - "org.springframework.boot:spring-boot-micrometer-tracing", - "org.springframework.boot:spring-boot-opentelemetry" - ], - "org.springframework.boot:spring-boot-netty": [ - "io.netty:netty-common", - "org.springframework.boot:spring-boot" - ], - "org.springframework.boot:spring-boot-opentelemetry": [ - "io.opentelemetry:opentelemetry-api", - "io.opentelemetry:opentelemetry-sdk", - "org.springframework.boot:spring-boot" - ], - "org.springframework.boot:spring-boot-persistence": [ - "org.springframework.boot:spring-boot", - "org.springframework:spring-tx" - ], - "org.springframework.boot:spring-boot-reactor": [ - "io.projectreactor:reactor-core", - "org.springframework.boot:spring-boot" - ], - "org.springframework.boot:spring-boot-reactor-netty": [ - "io.projectreactor.netty:reactor-netty-http", - "org.springframework.boot:spring-boot-netty", - "org.springframework.boot:spring-boot-web-server", - "org.springframework:spring-web" - ], - "org.springframework.boot:spring-boot-restclient": [ - "org.springframework.boot:spring-boot", - "org.springframework.boot:spring-boot-http-client", - "org.springframework.boot:spring-boot-http-converter" - ], - "org.springframework.boot:spring-boot-resttestclient": [ - "org.springframework.boot:spring-boot-http-converter", - "org.springframework.boot:spring-boot-test", - "org.springframework:spring-web" - ], - "org.springframework.boot:spring-boot-security": [ - "org.springframework.boot:spring-boot", - "org.springframework.security:spring-security-config", - "org.springframework.security:spring-security-web" - ], - "org.springframework.boot:spring-boot-security-oauth2-client": [ - "org.springframework.boot:spring-boot", - "org.springframework.boot:spring-boot-security", - "org.springframework.security:spring-security-oauth2-client" - ], - "org.springframework.boot:spring-boot-security-oauth2-resource-server": [ - "org.springframework.boot:spring-boot", - "org.springframework.boot:spring-boot-security", - "org.springframework.security:spring-security-oauth2-jose", - "org.springframework.security:spring-security-oauth2-resource-server" - ], - "org.springframework.boot:spring-boot-security-test": [ - "org.springframework.boot:spring-boot-security", - "org.springframework.boot:spring-boot-test-autoconfigure", - "org.springframework.security:spring-security-test" - ], - "org.springframework.boot:spring-boot-servlet": [ - "org.springframework.boot:spring-boot", - "org.springframework:spring-web" - ], - "org.springframework.boot:spring-boot-starter": [ - "jakarta.annotation:jakarta.annotation-api", - "org.springframework.boot:spring-boot-autoconfigure", - "org.springframework.boot:spring-boot-starter-logging", - "org.yaml:snakeyaml" - ], - "org.springframework.boot:spring-boot-starter-actuator": [ - "io.micrometer:micrometer-jakarta9", - "io.micrometer:micrometer-observation", - "org.springframework.boot:spring-boot-actuator-autoconfigure", - "org.springframework.boot:spring-boot-health", - "org.springframework.boot:spring-boot-starter", - "org.springframework.boot:spring-boot-starter-micrometer-metrics" - ], - "org.springframework.boot:spring-boot-starter-actuator-test": [ - "org.springframework.boot:spring-boot-starter-actuator", - "org.springframework.boot:spring-boot-starter-micrometer-metrics-test", - "org.springframework.boot:spring-boot-starter-test" - ], - "org.springframework.boot:spring-boot-starter-data-cassandra": [ - "org.springframework.boot:spring-boot-cassandra", - "org.springframework.boot:spring-boot-data-cassandra", - "org.springframework.boot:spring-boot-starter" - ], - "org.springframework.boot:spring-boot-starter-data-cassandra-test": [ - "org.springframework.boot:spring-boot-data-cassandra-test", - "org.springframework.boot:spring-boot-starter-data-cassandra", - "org.springframework.boot:spring-boot-starter-test" - ], - "org.springframework.boot:spring-boot-starter-jackson": [ - "org.springframework.boot:spring-boot-jackson", - "org.springframework.boot:spring-boot-starter" - ], - "org.springframework.boot:spring-boot-starter-jackson-test": [ - "org.springframework.boot:spring-boot-starter-jackson", - "org.springframework.boot:spring-boot-starter-test" - ], - "org.springframework.boot:spring-boot-starter-logging": [ - "ch.qos.logback:logback-classic", - "org.apache.logging.log4j:log4j-to-slf4j", - "org.slf4j:jul-to-slf4j" - ], - "org.springframework.boot:spring-boot-starter-micrometer-metrics": [ - "org.springframework.boot:spring-boot-micrometer-metrics", - "org.springframework.boot:spring-boot-starter" - ], - "org.springframework.boot:spring-boot-starter-micrometer-metrics-test": [ - "org.springframework.boot:spring-boot-micrometer-metrics-test", - "org.springframework.boot:spring-boot-starter-micrometer-metrics", - "org.springframework.boot:spring-boot-starter-test" - ], - "org.springframework.boot:spring-boot-starter-reactor-netty": [ - "org.springframework.boot:spring-boot-reactor", - "org.springframework.boot:spring-boot-reactor-netty", - "org.springframework.boot:spring-boot-starter" - ], - "org.springframework.boot:spring-boot-starter-security": [ - "org.springframework.boot:spring-boot-security", - "org.springframework.boot:spring-boot-starter", - "org.springframework:spring-aop" - ], - "org.springframework.boot:spring-boot-starter-security-oauth2-client": [ - "org.springframework.boot:spring-boot-security-oauth2-client", - "org.springframework.boot:spring-boot-starter", - "org.springframework.boot:spring-boot-starter-security", - "org.springframework.security:spring-security-oauth2-jose" - ], - "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server": [ - "org.springframework.boot:spring-boot-security-oauth2-resource-server", - "org.springframework.boot:spring-boot-starter", - "org.springframework.boot:spring-boot-starter-security" - ], - "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server-test": [ - "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server", - "org.springframework.boot:spring-boot-starter-security-test", - "org.springframework.boot:spring-boot-starter-test" - ], - "org.springframework.boot:spring-boot-starter-security-test": [ - "org.springframework.boot:spring-boot-security-test", - "org.springframework.boot:spring-boot-starter-security", - "org.springframework.boot:spring-boot-starter-test" - ], - "org.springframework.boot:spring-boot-starter-test": [ - "com.jayway.jsonpath:json-path", - "jakarta.xml.bind:jakarta.xml.bind-api", - "net.minidev:json-smart", - "org.assertj:assertj-core", - "org.awaitility:awaitility", - "org.hamcrest:hamcrest", - "org.junit.jupiter:junit-jupiter", - "org.mockito:mockito-core", - "org.mockito:mockito-junit-jupiter", - "org.skyscreamer:jsonassert", - "org.springframework.boot:spring-boot-starter", - "org.springframework.boot:spring-boot-test", - "org.springframework.boot:spring-boot-test-autoconfigure", - "org.springframework:spring-core", - "org.springframework:spring-test", - "org.xmlunit:xmlunit-core" - ], - "org.springframework.boot:spring-boot-starter-tomcat": [ - "org.springframework.boot:spring-boot-starter", - "org.springframework.boot:spring-boot-starter-tomcat-runtime", - "org.springframework.boot:spring-boot-tomcat" - ], - "org.springframework.boot:spring-boot-starter-tomcat-runtime": [ - "jakarta.annotation:jakarta.annotation-api", - "org.apache.tomcat.embed:tomcat-embed-core", - "org.apache.tomcat.embed:tomcat-embed-el", - "org.apache.tomcat.embed:tomcat-embed-websocket", - "org.springframework.boot:spring-boot-tomcat", - "org.springframework.boot:spring-boot-web-server" - ], - "org.springframework.boot:spring-boot-starter-validation": [ - "org.springframework.boot:spring-boot-starter", - "org.springframework.boot:spring-boot-validation" - ], - "org.springframework.boot:spring-boot-starter-webflux": [ - "org.springframework.boot:spring-boot-reactor", - "org.springframework.boot:spring-boot-starter", - "org.springframework.boot:spring-boot-starter-jackson", - "org.springframework.boot:spring-boot-starter-reactor-netty", - "org.springframework.boot:spring-boot-webflux" - ], - "org.springframework.boot:spring-boot-starter-webflux-test": [ - "io.projectreactor:reactor-test", - "org.springframework.boot:spring-boot-starter-jackson-test", - "org.springframework.boot:spring-boot-starter-test", - "org.springframework.boot:spring-boot-starter-webflux", - "org.springframework.boot:spring-boot-webflux-test", - "org.springframework.boot:spring-boot-webtestclient" - ], - "org.springframework.boot:spring-boot-starter-webmvc": [ - "org.springframework.boot:spring-boot-http-converter", - "org.springframework.boot:spring-boot-starter", - "org.springframework.boot:spring-boot-starter-jackson", - "org.springframework.boot:spring-boot-starter-tomcat", - "org.springframework.boot:spring-boot-webmvc" - ], - "org.springframework.boot:spring-boot-starter-webmvc-test": [ - "org.springframework.boot:spring-boot-resttestclient", - "org.springframework.boot:spring-boot-starter-jackson-test", - "org.springframework.boot:spring-boot-starter-test", - "org.springframework.boot:spring-boot-starter-webmvc", - "org.springframework.boot:spring-boot-webmvc-test" - ], - "org.springframework.boot:spring-boot-test": [ - "org.springframework.boot:spring-boot", - "org.springframework:spring-test" - ], - "org.springframework.boot:spring-boot-test-autoconfigure": [ - "org.springframework.boot:spring-boot-test" - ], - "org.springframework.boot:spring-boot-tomcat": [ - "jakarta.annotation:jakarta.annotation-api", - "org.apache.tomcat.embed:tomcat-embed-core", - "org.springframework.boot:spring-boot-web-server" - ], - "org.springframework.boot:spring-boot-validation": [ - "org.apache.tomcat.embed:tomcat-embed-el", - "org.hibernate.validator:hibernate-validator", - "org.springframework.boot:spring-boot" - ], - "org.springframework.boot:spring-boot-web-server": [ - "org.springframework.boot:spring-boot", - "org.springframework:spring-web" - ], - "org.springframework.boot:spring-boot-webclient": [ - "org.springframework.boot:spring-boot", - "org.springframework.boot:spring-boot-http-client", - "org.springframework.boot:spring-boot-http-codec", - "org.springframework:spring-webflux" - ], - "org.springframework.boot:spring-boot-webflux": [ - "org.springframework.boot:spring-boot", - "org.springframework.boot:spring-boot-http-codec", - "org.springframework.boot:spring-boot-web-server", - "org.springframework:spring-webflux" - ], - "org.springframework.boot:spring-boot-webflux-test": [ - "org.springframework.boot:spring-boot-test-autoconfigure", - "org.springframework.boot:spring-boot-webflux", - "org.springframework.boot:spring-boot-webtestclient" - ], - "org.springframework.boot:spring-boot-webmvc": [ - "org.springframework.boot:spring-boot-http-converter", - "org.springframework.boot:spring-boot-servlet", - "org.springframework:spring-web", - "org.springframework:spring-webmvc" - ], - "org.springframework.boot:spring-boot-webmvc-test": [ - "org.springframework.boot:spring-boot-http-converter", - "org.springframework.boot:spring-boot-test-autoconfigure", - "org.springframework.boot:spring-boot-web-server", - "org.springframework.boot:spring-boot-webmvc" - ], - "org.springframework.boot:spring-boot-webtestclient": [ - "org.springframework.boot:spring-boot-http-codec", - "org.springframework.boot:spring-boot-test", - "org.springframework:spring-webflux" - ], - "org.springframework.cloud:spring-cloud-commons": [ - "org.springframework.security:spring-security-crypto" - ], - "org.springframework.cloud:spring-cloud-context": [ - "org.springframework.security:spring-security-crypto" - ], - "org.springframework.cloud:spring-cloud-starter": [ - "org.bouncycastle:bcprov-jdk18on", - "org.springframework.boot:spring-boot-starter", - "org.springframework.cloud:spring-cloud-commons", - "org.springframework.cloud:spring-cloud-context" - ], - "org.springframework.cloud:spring-cloud-starter-bootstrap": [ - "org.springframework.cloud:spring-cloud-starter" - ], - "org.springframework.data:spring-data-cassandra": [ - "org.apache.cassandra:java-driver-core", - "org.apache.cassandra:java-driver-query-builder", - "org.slf4j:slf4j-api", - "org.springframework.data:spring-data-commons", - "org.springframework:spring-beans", - "org.springframework:spring-context", - "org.springframework:spring-core", - "org.springframework:spring-expression", - "org.springframework:spring-tx" - ], - "org.springframework.data:spring-data-commons": [ - "org.slf4j:slf4j-api", - "org.springframework:spring-beans", - "org.springframework:spring-core" - ], - "org.springframework.security:spring-security-config": [ - "org.springframework.security:spring-security-core", - "org.springframework:spring-aop", - "org.springframework:spring-beans", - "org.springframework:spring-context", - "org.springframework:spring-core" - ], - "org.springframework.security:spring-security-core": [ - "io.micrometer:micrometer-observation", - "org.springframework.security:spring-security-crypto", - "org.springframework:spring-aop", - "org.springframework:spring-beans", - "org.springframework:spring-context", - "org.springframework:spring-core", - "org.springframework:spring-expression" - ], - "org.springframework.security:spring-security-oauth2-client": [ - "com.nimbusds:oauth2-oidc-sdk", - "org.springframework.security:spring-security-core", - "org.springframework.security:spring-security-oauth2-core", - "org.springframework.security:spring-security-web", - "org.springframework:spring-core" - ], - "org.springframework.security:spring-security-oauth2-core": [ - "org.springframework.security:spring-security-core", - "org.springframework:spring-core", - "org.springframework:spring-web" - ], - "org.springframework.security:spring-security-oauth2-jose": [ - "com.nimbusds:nimbus-jose-jwt", - "org.springframework.security:spring-security-core", - "org.springframework.security:spring-security-oauth2-core", - "org.springframework:spring-core" - ], - "org.springframework.security:spring-security-oauth2-resource-server": [ - "org.springframework.security:spring-security-core", - "org.springframework.security:spring-security-oauth2-core", - "org.springframework.security:spring-security-web", - "org.springframework:spring-core" - ], - "org.springframework.security:spring-security-test": [ - "org.springframework.security:spring-security-core", - "org.springframework.security:spring-security-web", - "org.springframework:spring-core", - "org.springframework:spring-test" - ], - "org.springframework.security:spring-security-web": [ - "org.springframework.security:spring-security-core", - "org.springframework:spring-aop", - "org.springframework:spring-beans", - "org.springframework:spring-context", - "org.springframework:spring-core", - "org.springframework:spring-expression", - "org.springframework:spring-web" - ], - "org.springframework:spring-aop": [ - "org.springframework:spring-beans", - "org.springframework:spring-core" - ], - "org.springframework:spring-beans": [ - "org.springframework:spring-core" - ], - "org.springframework:spring-context": [ - "io.micrometer:micrometer-observation", - "org.springframework:spring-aop", - "org.springframework:spring-beans", - "org.springframework:spring-core", - "org.springframework:spring-expression" - ], - "org.springframework:spring-core": [ - "commons-logging:commons-logging", - "org.jspecify:jspecify" - ], - "org.springframework:spring-expression": [ - "org.springframework:spring-core" - ], - "org.springframework:spring-test": [ - "org.springframework:spring-core" - ], - "org.springframework:spring-tx": [ - "org.springframework:spring-beans", - "org.springframework:spring-core" - ], - "org.springframework:spring-web": [ - "io.micrometer:micrometer-observation", - "org.springframework:spring-beans", - "org.springframework:spring-core" - ], - "org.springframework:spring-webflux": [ - "io.projectreactor:reactor-core", - "org.springframework:spring-beans", - "org.springframework:spring-core", - "org.springframework:spring-web" - ], - "org.springframework:spring-webmvc": [ - "org.springframework:spring-aop", - "org.springframework:spring-beans", - "org.springframework:spring-context", - "org.springframework:spring-core", - "org.springframework:spring-expression", - "org.springframework:spring-web" - ], - "org.testcontainers:testcontainers": [ - "com.github.docker-java:docker-java-api", - "com.github.docker-java:docker-java-transport-zerodep", - "org.apache.commons:commons-compress", - "org.rnorth.duct-tape:duct-tape", - "org.slf4j:slf4j-api" - ], - "org.testcontainers:testcontainers-cassandra": [ - "com.datastax.cassandra:cassandra-driver-core", - "org.testcontainers:testcontainers-database-commons" - ], - "org.testcontainers:testcontainers-database-commons": [ - "org.testcontainers:testcontainers" - ], - "org.testcontainers:testcontainers-junit-jupiter": [ - "org.testcontainers:testcontainers" - ], - "org.xmlunit:xmlunit-core": [ - "jakarta.xml.bind:jakarta.xml.bind-api" - ], - "software.amazon.awssdk:checksums": [ - "software.amazon.awssdk:annotations", - "software.amazon.awssdk:checksums-spi", - "software.amazon.awssdk:utils" - ], - "software.amazon.awssdk:checksums-spi": [ - "software.amazon.awssdk:annotations" - ], - "software.amazon.awssdk:endpoints-spi": [ - "software.amazon.awssdk:annotations" - ], - "software.amazon.awssdk:http-auth-aws": [ - "software.amazon.awssdk:annotations", - "software.amazon.awssdk:checksums", - "software.amazon.awssdk:checksums-spi", - "software.amazon.awssdk:http-auth-spi", - "software.amazon.awssdk:http-client-spi", - "software.amazon.awssdk:identity-spi", - "software.amazon.awssdk:utils" - ], - "software.amazon.awssdk:http-auth-spi": [ - "org.reactivestreams:reactive-streams", - "software.amazon.awssdk:annotations", - "software.amazon.awssdk:checksums-spi", - "software.amazon.awssdk:http-client-spi", - "software.amazon.awssdk:identity-spi", - "software.amazon.awssdk:utils" - ], - "software.amazon.awssdk:http-client-spi": [ - "org.reactivestreams:reactive-streams", - "software.amazon.awssdk:annotations", - "software.amazon.awssdk:metrics-spi", - "software.amazon.awssdk:utils" - ], - "software.amazon.awssdk:identity-spi": [ - "software.amazon.awssdk:annotations", - "software.amazon.awssdk:utils" - ], - "software.amazon.awssdk:json-utils": [ - "software.amazon.awssdk:annotations", - "software.amazon.awssdk:third-party-jackson-core", - "software.amazon.awssdk:utils" - ], - "software.amazon.awssdk:metrics-spi": [ - "software.amazon.awssdk:annotations", - "software.amazon.awssdk:utils" - ], - "software.amazon.awssdk:profiles": [ - "software.amazon.awssdk:annotations", - "software.amazon.awssdk:utils" - ], - "software.amazon.awssdk:regions": [ - "org.slf4j:slf4j-api", - "software.amazon.awssdk:annotations", - "software.amazon.awssdk:json-utils", - "software.amazon.awssdk:profiles", - "software.amazon.awssdk:sdk-core", - "software.amazon.awssdk:utils" - ], - "software.amazon.awssdk:retries": [ - "software.amazon.awssdk:annotations", - "software.amazon.awssdk:retries-spi", - "software.amazon.awssdk:utils" - ], - "software.amazon.awssdk:retries-spi": [ - "software.amazon.awssdk:annotations", - "software.amazon.awssdk:utils" - ], - "software.amazon.awssdk:sdk-core": [ - "org.reactivestreams:reactive-streams", - "org.slf4j:slf4j-api", - "software.amazon.awssdk:annotations", - "software.amazon.awssdk:checksums", - "software.amazon.awssdk:checksums-spi", - "software.amazon.awssdk:endpoints-spi", - "software.amazon.awssdk:http-auth-aws", - "software.amazon.awssdk:http-auth-spi", - "software.amazon.awssdk:http-client-spi", - "software.amazon.awssdk:identity-spi", - "software.amazon.awssdk:metrics-spi", - "software.amazon.awssdk:profiles", - "software.amazon.awssdk:retries", - "software.amazon.awssdk:retries-spi", - "software.amazon.awssdk:utils" - ], - "software.amazon.awssdk:utils": [ - "org.reactivestreams:reactive-streams", - "org.slf4j:slf4j-api", - "software.amazon.awssdk:annotations" - ], - "tools.jackson.core:jackson-databind": [ - "com.fasterxml.jackson.core:jackson-annotations", - "tools.jackson.core:jackson-core" - ], - "tools.jackson.module:jackson-module-blackbird": [ - "tools.jackson.core:jackson-core", - "tools.jackson.core:jackson-databind" - ] - }, - "packages": { - "aopalliance:aopalliance": [ - "org.aopalliance.aop", - "org.aopalliance.intercept" - ], - "args4j:args4j": [ - "org.kohsuke.args4j", - "org.kohsuke.args4j.spi" - ], - "at.yawk.lz4:lz4-java": [ - "net.jpountz.lz4", - "net.jpountz.util", - "net.jpountz.xxhash" - ], - "ch.qos.logback:logback-classic": [ - "ch.qos.logback.classic", - "ch.qos.logback.classic.boolex", - "ch.qos.logback.classic.encoder", - "ch.qos.logback.classic.filter", - "ch.qos.logback.classic.helpers", - "ch.qos.logback.classic.html", - "ch.qos.logback.classic.joran", - "ch.qos.logback.classic.joran.action", - "ch.qos.logback.classic.joran.sanity", - "ch.qos.logback.classic.joran.serializedModel", - "ch.qos.logback.classic.jul", - "ch.qos.logback.classic.layout", - "ch.qos.logback.classic.log4j", - "ch.qos.logback.classic.model", - "ch.qos.logback.classic.model.processor", - "ch.qos.logback.classic.model.util", - "ch.qos.logback.classic.net", - "ch.qos.logback.classic.net.server", - "ch.qos.logback.classic.pattern", - "ch.qos.logback.classic.pattern.color", - "ch.qos.logback.classic.selector", - "ch.qos.logback.classic.selector.servlet", - "ch.qos.logback.classic.servlet", - "ch.qos.logback.classic.sift", - "ch.qos.logback.classic.spi", - "ch.qos.logback.classic.turbo", - "ch.qos.logback.classic.tyler", - "ch.qos.logback.classic.util" - ], - "ch.qos.logback:logback-core": [ - "ch.qos.logback.core", - "ch.qos.logback.core.boolex", - "ch.qos.logback.core.encoder", - "ch.qos.logback.core.filter", - "ch.qos.logback.core.helpers", - "ch.qos.logback.core.hook", - "ch.qos.logback.core.html", - "ch.qos.logback.core.joran", - "ch.qos.logback.core.joran.action", - "ch.qos.logback.core.joran.conditional", - "ch.qos.logback.core.joran.event", - "ch.qos.logback.core.joran.sanity", - "ch.qos.logback.core.joran.spi", - "ch.qos.logback.core.joran.util", - "ch.qos.logback.core.joran.util.beans", - "ch.qos.logback.core.layout", - "ch.qos.logback.core.model", - "ch.qos.logback.core.model.conditional", - "ch.qos.logback.core.model.processor", - "ch.qos.logback.core.model.processor.conditional", - "ch.qos.logback.core.model.util", - "ch.qos.logback.core.net", - "ch.qos.logback.core.net.ssl", - "ch.qos.logback.core.pattern", - "ch.qos.logback.core.pattern.color", - "ch.qos.logback.core.pattern.parser", - "ch.qos.logback.core.pattern.util", - "ch.qos.logback.core.property", - "ch.qos.logback.core.read", - "ch.qos.logback.core.recovery", - "ch.qos.logback.core.rolling", - "ch.qos.logback.core.rolling.helper", - "ch.qos.logback.core.sift", - "ch.qos.logback.core.spi", - "ch.qos.logback.core.status", - "ch.qos.logback.core.subst", - "ch.qos.logback.core.testUtil", - "ch.qos.logback.core.util" - ], - "com.datastax.cassandra:cassandra-driver-core": [ - "com.datastax.driver.core", - "com.datastax.driver.core.exceptions", - "com.datastax.driver.core.policies", - "com.datastax.driver.core.querybuilder", - "com.datastax.driver.core.schemabuilder", - "com.datastax.driver.core.utils" - ], - "com.datastax.oss:native-protocol": [ - "com.datastax.dse.protocol.internal", - "com.datastax.dse.protocol.internal.request", - "com.datastax.dse.protocol.internal.request.query", - "com.datastax.dse.protocol.internal.response.result", - "com.datastax.oss.protocol.internal", - "com.datastax.oss.protocol.internal.request", - "com.datastax.oss.protocol.internal.request.query", - "com.datastax.oss.protocol.internal.response", - "com.datastax.oss.protocol.internal.response.error", - "com.datastax.oss.protocol.internal.response.event", - "com.datastax.oss.protocol.internal.response.result", - "com.datastax.oss.protocol.internal.util", - "com.datastax.oss.protocol.internal.util.collection" - ], - "com.fasterxml.jackson.core:jackson-annotations": [ - "com.fasterxml.jackson.annotation" - ], - "com.fasterxml.jackson.core:jackson-core": [ - "com.fasterxml.jackson.core", - "com.fasterxml.jackson.core.async", - "com.fasterxml.jackson.core.base", - "com.fasterxml.jackson.core.exc", - "com.fasterxml.jackson.core.filter", - "com.fasterxml.jackson.core.format", - "com.fasterxml.jackson.core.internal.shaded.fdp.v2_21_4", - "com.fasterxml.jackson.core.internal.shaded.fdp.v2_21_4.bte", - "com.fasterxml.jackson.core.internal.shaded.fdp.v2_21_4.chr", - "com.fasterxml.jackson.core.io", - "com.fasterxml.jackson.core.io.schubfach", - "com.fasterxml.jackson.core.json", - "com.fasterxml.jackson.core.json.async", - "com.fasterxml.jackson.core.sym", - "com.fasterxml.jackson.core.type", - "com.fasterxml.jackson.core.util" - ], - "com.fasterxml.jackson.core:jackson-databind": [ - "com.fasterxml.jackson.databind", - "com.fasterxml.jackson.databind.annotation", - "com.fasterxml.jackson.databind.cfg", - "com.fasterxml.jackson.databind.deser", - "com.fasterxml.jackson.databind.deser.impl", - "com.fasterxml.jackson.databind.deser.std", - "com.fasterxml.jackson.databind.exc", - "com.fasterxml.jackson.databind.ext", - "com.fasterxml.jackson.databind.introspect", - "com.fasterxml.jackson.databind.jdk14", - "com.fasterxml.jackson.databind.json", - "com.fasterxml.jackson.databind.jsonFormatVisitors", - "com.fasterxml.jackson.databind.jsonschema", - "com.fasterxml.jackson.databind.jsontype", - "com.fasterxml.jackson.databind.jsontype.impl", - "com.fasterxml.jackson.databind.module", - "com.fasterxml.jackson.databind.node", - "com.fasterxml.jackson.databind.ser", - "com.fasterxml.jackson.databind.ser.impl", - "com.fasterxml.jackson.databind.ser.std", - "com.fasterxml.jackson.databind.type", - "com.fasterxml.jackson.databind.util", - "com.fasterxml.jackson.databind.util.internal" - ], - "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml": [ - "com.fasterxml.jackson.dataformat.yaml", - "com.fasterxml.jackson.dataformat.yaml.snakeyaml.error", - "com.fasterxml.jackson.dataformat.yaml.util" - ], - "com.fasterxml.jackson.datatype:jackson-datatype-jsr310": [ - "com.fasterxml.jackson.datatype.jsr310", - "com.fasterxml.jackson.datatype.jsr310.deser", - "com.fasterxml.jackson.datatype.jsr310.deser.key", - "com.fasterxml.jackson.datatype.jsr310.ser", - "com.fasterxml.jackson.datatype.jsr310.ser.key", - "com.fasterxml.jackson.datatype.jsr310.util" - ], - "com.fasterxml:classmate": [ - "com.fasterxml.classmate", - "com.fasterxml.classmate.members", - "com.fasterxml.classmate.types", - "com.fasterxml.classmate.util" - ], - "com.github.ben-manes.caffeine:caffeine": [ - "com.github.benmanes.caffeine.cache", - "com.github.benmanes.caffeine.cache.stats" - ], - "com.github.ben-manes.caffeine:guava": [ - "com.github.benmanes.caffeine.guava" - ], - "com.github.docker-java:docker-java-api": [ - "com.github.dockerjava.api", - "com.github.dockerjava.api.async", - "com.github.dockerjava.api.command", - "com.github.dockerjava.api.exception", - "com.github.dockerjava.api.model" - ], - "com.github.docker-java:docker-java-transport": [ - "com.github.dockerjava.transport" - ], - "com.github.docker-java:docker-java-transport-zerodep": [ - "com.github.dockerjava.zerodep", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.async", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.async.methods", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.auth", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.classic", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.classic.methods", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.config", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.cookie", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.entity", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.entity.mime", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.impl", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.impl.async", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.impl.auth", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.impl.classic", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.impl.compat", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.impl.cookie", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.impl.io", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.impl.nio", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.impl.routing", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.io", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.nio", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.protocol", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.psl", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.routing", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.socket", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.ssl", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.utils", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.client5.http.validator", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.annotation", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.concurrent", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.function", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.config", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.impl", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.impl.bootstrap", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.impl.io", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.impl.nio", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.impl.routing", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.io", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.io.entity", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.io.ssl", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.io.support", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.message", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.nio", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.nio.command", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.nio.entity", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.nio.ssl", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.nio.support", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.nio.support.classic", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.protocol", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.ssl", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http.support", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http2", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http2.config", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http2.frame", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http2.hpack", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http2.impl", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http2.impl.io", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http2.impl.nio", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http2.impl.nio.bootstrap", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http2.nio", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http2.nio.command", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http2.nio.pool", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http2.nio.support", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http2.protocol", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.http2.ssl", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.io", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.net", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.pool", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.reactor", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.reactor.ssl", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.ssl", - "com.github.dockerjava.zerodep.shaded.org.apache.hc.core5.util" - ], - "com.github.java-json-tools:btf": [ - "com.github.fge" - ], - "com.github.java-json-tools:jackson-coreutils": [ - "com.github.fge.jackson", - "com.github.fge.jackson.jsonpointer" - ], - "com.github.java-json-tools:json-patch": [ - "com.github.fge.jsonpatch", - "com.github.fge.jsonpatch.diff", - "com.github.fge.jsonpatch.mergepatch" - ], - "com.github.java-json-tools:msg-simple": [ - "com.github.fge.msgsimple", - "com.github.fge.msgsimple.bundle", - "com.github.fge.msgsimple.load", - "com.github.fge.msgsimple.locale", - "com.github.fge.msgsimple.provider", - "com.github.fge.msgsimple.source" - ], - "com.github.jnr:jffi": [ - "com.kenai.jffi", - "com.kenai.jffi.internal" - ], - "com.github.jnr:jnr-constants": [ - "jnr.constants", - "jnr.constants.platform", - "jnr.constants.platform.aix", - "jnr.constants.platform.darwin", - "jnr.constants.platform.dragonflybsd", - "jnr.constants.platform.fake", - "jnr.constants.platform.freebsd", - "jnr.constants.platform.freebsd.aarch64", - "jnr.constants.platform.linux", - "jnr.constants.platform.linux.aarch64", - "jnr.constants.platform.linux.loongarch64", - "jnr.constants.platform.linux.mips64el", - "jnr.constants.platform.linux.powerpc64", - "jnr.constants.platform.linux.s390x", - "jnr.constants.platform.openbsd", - "jnr.constants.platform.solaris", - "jnr.constants.platform.windows" - ], - "com.github.jnr:jnr-ffi": [ - "jnr.ffi", - "jnr.ffi.annotations", - "jnr.ffi.byref", - "jnr.ffi.mapper", - "jnr.ffi.provider", - "jnr.ffi.provider.converters", - "jnr.ffi.provider.jffi", - "jnr.ffi.provider.jffi.platform.aarch64.linux", - "jnr.ffi.provider.jffi.platform.arm.linux", - "jnr.ffi.provider.jffi.platform.i386.darwin", - "jnr.ffi.provider.jffi.platform.i386.freebsd", - "jnr.ffi.provider.jffi.platform.i386.linux", - "jnr.ffi.provider.jffi.platform.i386.openbsd", - "jnr.ffi.provider.jffi.platform.i386.solaris", - "jnr.ffi.provider.jffi.platform.i386.windows", - "jnr.ffi.provider.jffi.platform.mips.linux", - "jnr.ffi.provider.jffi.platform.mipsel.linux", - "jnr.ffi.provider.jffi.platform.ppc.aix", - "jnr.ffi.provider.jffi.platform.ppc.darwin", - "jnr.ffi.provider.jffi.platform.ppc.linux", - "jnr.ffi.provider.jffi.platform.ppc64.linux", - "jnr.ffi.provider.jffi.platform.ppc64le.linux", - "jnr.ffi.provider.jffi.platform.s390.linux", - "jnr.ffi.provider.jffi.platform.s390x.linux", - "jnr.ffi.provider.jffi.platform.sparc.solaris", - "jnr.ffi.provider.jffi.platform.sparcv9.linux", - "jnr.ffi.provider.jffi.platform.sparcv9.solaris", - "jnr.ffi.provider.jffi.platform.x86_64.darwin", - "jnr.ffi.provider.jffi.platform.x86_64.freebsd", - "jnr.ffi.provider.jffi.platform.x86_64.linux", - "jnr.ffi.provider.jffi.platform.x86_64.openbsd", - "jnr.ffi.provider.jffi.platform.x86_64.solaris", - "jnr.ffi.provider.jffi.platform.x86_64.windows", - "jnr.ffi.types", - "jnr.ffi.util", - "jnr.ffi.util.ref", - "jnr.ffi.util.ref.internal" - ], - "com.github.jnr:jnr-posix": [ - "jnr.posix", - "jnr.posix.util", - "jnr.posix.windows" - ], - "com.github.jnr:jnr-x86asm": [ - "com.kenai.jnr.x86asm", - "jnr.x86asm" - ], - "com.github.stephenc.jcip:jcip-annotations": [ - "net.jcip.annotations" - ], - "com.google.code.findbugs:jsr305": [ - "javax.annotation", - "javax.annotation.concurrent", - "javax.annotation.meta" - ], - "com.google.errorprone:error_prone_annotations": [ - "com.google.errorprone.annotations", - "com.google.errorprone.annotations.concurrent" - ], - "com.google.guava:failureaccess": [ - "com.google.common.util.concurrent.internal" - ], - "com.google.guava:guava": [ - "com.google.common.annotations", - "com.google.common.base", - "com.google.common.base.internal", - "com.google.common.cache", - "com.google.common.collect", - "com.google.common.escape", - "com.google.common.eventbus", - "com.google.common.graph", - "com.google.common.hash", - "com.google.common.html", - "com.google.common.io", - "com.google.common.math", - "com.google.common.net", - "com.google.common.primitives", - "com.google.common.reflect", - "com.google.common.util.concurrent", - "com.google.common.xml", - "com.google.thirdparty.publicsuffix" - ], - "com.google.j2objc:j2objc-annotations": [ - "com.google.j2objc.annotations" - ], - "com.jayway.jsonpath:json-path": [ - "com.jayway.jsonpath", - "com.jayway.jsonpath.internal", - "com.jayway.jsonpath.internal.filter", - "com.jayway.jsonpath.internal.function", - "com.jayway.jsonpath.internal.function.json", - "com.jayway.jsonpath.internal.function.latebinding", - "com.jayway.jsonpath.internal.function.numeric", - "com.jayway.jsonpath.internal.function.sequence", - "com.jayway.jsonpath.internal.function.text", - "com.jayway.jsonpath.internal.path", - "com.jayway.jsonpath.spi.cache", - "com.jayway.jsonpath.spi.json", - "com.jayway.jsonpath.spi.mapper" - ], - "com.nimbusds:content-type": [ - "com.nimbusds.common.contenttype" - ], - "com.nimbusds:lang-tag": [ - "com.nimbusds.langtag" - ], - "com.nimbusds:nimbus-jose-jwt": [ - "com.nimbusds.jose", - "com.nimbusds.jose.crypto", - "com.nimbusds.jose.crypto.bc", - "com.nimbusds.jose.crypto.factories", - "com.nimbusds.jose.crypto.impl", - "com.nimbusds.jose.crypto.opts", - "com.nimbusds.jose.crypto.utils", - "com.nimbusds.jose.jca", - "com.nimbusds.jose.jwk", - "com.nimbusds.jose.jwk.gen", - "com.nimbusds.jose.jwk.source", - "com.nimbusds.jose.mint", - "com.nimbusds.jose.proc", - "com.nimbusds.jose.produce", - "com.nimbusds.jose.shaded.gson", - "com.nimbusds.jose.shaded.gson.annotations", - "com.nimbusds.jose.shaded.gson.internal", - "com.nimbusds.jose.shaded.gson.internal.bind", - "com.nimbusds.jose.shaded.gson.internal.bind.util", - "com.nimbusds.jose.shaded.gson.internal.reflect", - "com.nimbusds.jose.shaded.gson.internal.sql", - "com.nimbusds.jose.shaded.gson.reflect", - "com.nimbusds.jose.shaded.gson.stream", - "com.nimbusds.jose.shaded.jcip", - "com.nimbusds.jose.util", - "com.nimbusds.jose.util.cache", - "com.nimbusds.jose.util.events", - "com.nimbusds.jose.util.health", - "com.nimbusds.jwt", - "com.nimbusds.jwt.proc", - "com.nimbusds.jwt.util" - ], - "com.nimbusds:oauth2-oidc-sdk": [ - "com.nimbusds.oauth2.sdk", - "com.nimbusds.oauth2.sdk.as", - "com.nimbusds.oauth2.sdk.assertions", - "com.nimbusds.oauth2.sdk.assertions.jwt", - "com.nimbusds.oauth2.sdk.assertions.saml2", - "com.nimbusds.oauth2.sdk.auth", - "com.nimbusds.oauth2.sdk.auth.verifier", - "com.nimbusds.oauth2.sdk.ciba", - "com.nimbusds.oauth2.sdk.client", - "com.nimbusds.oauth2.sdk.cnf", - "com.nimbusds.oauth2.sdk.device", - "com.nimbusds.oauth2.sdk.dpop", - "com.nimbusds.oauth2.sdk.dpop.verifiers", - "com.nimbusds.oauth2.sdk.http", - "com.nimbusds.oauth2.sdk.id", - "com.nimbusds.oauth2.sdk.jarm", - "com.nimbusds.oauth2.sdk.jose", - "com.nimbusds.oauth2.sdk.pkce", - "com.nimbusds.oauth2.sdk.rar", - "com.nimbusds.oauth2.sdk.token", - "com.nimbusds.oauth2.sdk.tokenexchange", - "com.nimbusds.oauth2.sdk.util", - "com.nimbusds.oauth2.sdk.util.date", - "com.nimbusds.oauth2.sdk.util.singleuse", - "com.nimbusds.oauth2.sdk.util.tls", - "com.nimbusds.openid.connect.sdk", - "com.nimbusds.openid.connect.sdk.assurance", - "com.nimbusds.openid.connect.sdk.assurance.claims", - "com.nimbusds.openid.connect.sdk.assurance.evidences", - "com.nimbusds.openid.connect.sdk.assurance.evidences.attachment", - "com.nimbusds.openid.connect.sdk.assurance.request", - "com.nimbusds.openid.connect.sdk.claims", - "com.nimbusds.openid.connect.sdk.federation", - "com.nimbusds.openid.connect.sdk.federation.api", - "com.nimbusds.openid.connect.sdk.federation.config", - "com.nimbusds.openid.connect.sdk.federation.entities", - "com.nimbusds.openid.connect.sdk.federation.policy", - "com.nimbusds.openid.connect.sdk.federation.policy.language", - "com.nimbusds.openid.connect.sdk.federation.policy.operations", - "com.nimbusds.openid.connect.sdk.federation.registration", - "com.nimbusds.openid.connect.sdk.federation.trust", - "com.nimbusds.openid.connect.sdk.federation.trust.constraints", - "com.nimbusds.openid.connect.sdk.federation.trust.marks", - "com.nimbusds.openid.connect.sdk.federation.utils", - "com.nimbusds.openid.connect.sdk.id", - "com.nimbusds.openid.connect.sdk.nativesso", - "com.nimbusds.openid.connect.sdk.op", - "com.nimbusds.openid.connect.sdk.rp", - "com.nimbusds.openid.connect.sdk.rp.statement", - "com.nimbusds.openid.connect.sdk.token", - "com.nimbusds.openid.connect.sdk.validators", - "com.nimbusds.secevent.sdk.claims" - ], - "com.squareup.okhttp3:okhttp-jvm": [ - "okhttp3", - "okhttp3.internal", - "okhttp3.internal.authenticator", - "okhttp3.internal.cache", - "okhttp3.internal.cache2", - "okhttp3.internal.concurrent", - "okhttp3.internal.connection", - "okhttp3.internal.graal", - "okhttp3.internal.http", - "okhttp3.internal.http1", - "okhttp3.internal.http2", - "okhttp3.internal.http2.flowcontrol", - "okhttp3.internal.idn", - "okhttp3.internal.platform", - "okhttp3.internal.proxy", - "okhttp3.internal.publicsuffix", - "okhttp3.internal.tls", - "okhttp3.internal.url", - "okhttp3.internal.ws" - ], - "com.squareup.okio:okio-jvm": [ - "okio", - "okio.internal" - ], - "com.typesafe:config": [ - "com.typesafe.config", - "com.typesafe.config.impl", - "com.typesafe.config.parser" - ], - "com.vaadin.external.google:android-json": [ - "org.json" - ], - "commons-codec:commons-codec": [ - "org.apache.commons.codec", - "org.apache.commons.codec.binary", - "org.apache.commons.codec.cli", - "org.apache.commons.codec.digest", - "org.apache.commons.codec.language", - "org.apache.commons.codec.language.bm", - "org.apache.commons.codec.net" - ], - "commons-io:commons-io": [ - "org.apache.commons.io", - "org.apache.commons.io.build", - "org.apache.commons.io.channels", - "org.apache.commons.io.charset", - "org.apache.commons.io.comparator", - "org.apache.commons.io.file", - "org.apache.commons.io.file.attribute", - "org.apache.commons.io.file.spi", - "org.apache.commons.io.filefilter", - "org.apache.commons.io.function", - "org.apache.commons.io.input", - "org.apache.commons.io.input.buffer", - "org.apache.commons.io.monitor", - "org.apache.commons.io.output", - "org.apache.commons.io.serialization" - ], - "commons-logging:commons-logging": [ - "org.apache.commons.logging", - "org.apache.commons.logging.impl" - ], - "io.cloudevents:cloudevents-api": [ - "io.cloudevents", - "io.cloudevents.lang", - "io.cloudevents.rw", - "io.cloudevents.types" - ], - "io.cloudevents:cloudevents-core": [ - "io.cloudevents.core", - "io.cloudevents.core.builder", - "io.cloudevents.core.data", - "io.cloudevents.core.extensions", - "io.cloudevents.core.extensions.impl", - "io.cloudevents.core.format", - "io.cloudevents.core.impl", - "io.cloudevents.core.message", - "io.cloudevents.core.message.impl", - "io.cloudevents.core.provider", - "io.cloudevents.core.v03", - "io.cloudevents.core.v1", - "io.cloudevents.core.validator" - ], - "io.cloudevents:cloudevents-json-jackson": [ - "io.cloudevents.jackson" - ], - "io.dropwizard.metrics:metrics-core": [ - "com.codahale.metrics" - ], - "io.micrometer:context-propagation": [ - "io.micrometer.context", - "io.micrometer.context.integration" - ], - "io.micrometer:micrometer-commons": [ - "io.micrometer.common", - "io.micrometer.common.annotation", - "io.micrometer.common.docs", - "io.micrometer.common.lang", - "io.micrometer.common.lang.internal", - "io.micrometer.common.util", - "io.micrometer.common.util.internal.logging" - ], - "io.micrometer:micrometer-core": [ - "io.micrometer.core.annotation", - "io.micrometer.core.aop", - "io.micrometer.core.instrument", - "io.micrometer.core.instrument.binder", - "io.micrometer.core.instrument.binder.cache", - "io.micrometer.core.instrument.binder.commonspool2", - "io.micrometer.core.instrument.binder.db", - "io.micrometer.core.instrument.binder.grpc", - "io.micrometer.core.instrument.binder.http", - "io.micrometer.core.instrument.binder.httpcomponents", - "io.micrometer.core.instrument.binder.httpcomponents.hc5", - "io.micrometer.core.instrument.binder.hystrix", - "io.micrometer.core.instrument.binder.jersey.server", - "io.micrometer.core.instrument.binder.jetty", - "io.micrometer.core.instrument.binder.jpa", - "io.micrometer.core.instrument.binder.jvm", - "io.micrometer.core.instrument.binder.jvm.convention", - "io.micrometer.core.instrument.binder.jvm.convention.micrometer", - "io.micrometer.core.instrument.binder.jvm.convention.otel", - "io.micrometer.core.instrument.binder.kafka", - "io.micrometer.core.instrument.binder.logging", - "io.micrometer.core.instrument.binder.mongodb", - "io.micrometer.core.instrument.binder.netty4", - "io.micrometer.core.instrument.binder.okhttp3", - "io.micrometer.core.instrument.binder.system", - "io.micrometer.core.instrument.binder.tomcat", - "io.micrometer.core.instrument.composite", - "io.micrometer.core.instrument.config", - "io.micrometer.core.instrument.config.validate", - "io.micrometer.core.instrument.cumulative", - "io.micrometer.core.instrument.distribution", - "io.micrometer.core.instrument.distribution.pause", - "io.micrometer.core.instrument.docs", - "io.micrometer.core.instrument.dropwizard", - "io.micrometer.core.instrument.internal", - "io.micrometer.core.instrument.kotlin", - "io.micrometer.core.instrument.logging", - "io.micrometer.core.instrument.noop", - "io.micrometer.core.instrument.observation", - "io.micrometer.core.instrument.push", - "io.micrometer.core.instrument.search", - "io.micrometer.core.instrument.simple", - "io.micrometer.core.instrument.step", - "io.micrometer.core.instrument.util", - "io.micrometer.core.ipc.http", - "io.micrometer.core.util.internal.logging" - ], - "io.micrometer:micrometer-jakarta9": [ - "io.micrometer.jakarta9.instrument.jms", - "io.micrometer.jakarta9.instrument.mail" - ], - "io.micrometer:micrometer-observation": [ - "io.micrometer.observation", - "io.micrometer.observation.annotation", - "io.micrometer.observation.aop", - "io.micrometer.observation.contextpropagation", - "io.micrometer.observation.docs", - "io.micrometer.observation.transport" - ], - "io.micrometer:micrometer-observation-test": [ - "io.micrometer.observation.tck" - ], - "io.micrometer:micrometer-tracing": [ - "io.micrometer.tracing", - "io.micrometer.tracing.annotation", - "io.micrometer.tracing.contextpropagation", - "io.micrometer.tracing.contextpropagation.reactor", - "io.micrometer.tracing.docs", - "io.micrometer.tracing.exporter", - "io.micrometer.tracing.handler", - "io.micrometer.tracing.internal", - "io.micrometer.tracing.propagation" - ], - "io.micrometer:micrometer-tracing-bridge-otel": [ - "io.micrometer.tracing.otel", - "io.micrometer.tracing.otel.bridge", - "io.micrometer.tracing.otel.propagation" - ], - "io.nats:jnats": [ - "io.nats.client", - "io.nats.client.api", - "io.nats.client.impl", - "io.nats.client.support", - "io.nats.service" - ], - "io.netty:netty-buffer": [ - "io.netty.buffer", - "io.netty.buffer.search" - ], - "io.netty:netty-codec-base": [ - "io.netty.handler.codec", - "io.netty.handler.codec.base64", - "io.netty.handler.codec.bytes", - "io.netty.handler.codec.json", - "io.netty.handler.codec.serialization", - "io.netty.handler.codec.string" - ], - "io.netty:netty-codec-classes-quic": [ - "io.netty.handler.codec.quic" - ], - "io.netty:netty-codec-compression": [ - "io.netty.handler.codec.compression" - ], - "io.netty:netty-codec-dns": [ - "io.netty.handler.codec.dns" - ], - "io.netty:netty-codec-http": [ - "io.netty.handler.codec.http", - "io.netty.handler.codec.http.cookie", - "io.netty.handler.codec.http.cors", - "io.netty.handler.codec.http.multipart", - "io.netty.handler.codec.http.websocketx", - "io.netty.handler.codec.http.websocketx.extensions", - "io.netty.handler.codec.http.websocketx.extensions.compression", - "io.netty.handler.codec.rtsp", - "io.netty.handler.codec.spdy" - ], - "io.netty:netty-codec-http2": [ - "io.netty.handler.codec.http2" - ], - "io.netty:netty-codec-http3": [ - "io.netty.handler.codec.http3" - ], - "io.netty:netty-codec-socks": [ - "io.netty.handler.codec.socks", - "io.netty.handler.codec.socksx", - "io.netty.handler.codec.socksx.v4", - "io.netty.handler.codec.socksx.v5" - ], - "io.netty:netty-common": [ - "io.netty.util", - "io.netty.util.collection", - "io.netty.util.concurrent", - "io.netty.util.internal", - "io.netty.util.internal.logging", - "io.netty.util.internal.shaded.org.jctools.counters", - "io.netty.util.internal.shaded.org.jctools.maps", - "io.netty.util.internal.shaded.org.jctools.queues", - "io.netty.util.internal.shaded.org.jctools.queues.atomic", - "io.netty.util.internal.shaded.org.jctools.queues.atomic.unpadded", - "io.netty.util.internal.shaded.org.jctools.queues.unpadded", - "io.netty.util.internal.shaded.org.jctools.util", - "io.netty.util.internal.svm" - ], - "io.netty:netty-handler": [ - "io.netty.handler.address", - "io.netty.handler.flow", - "io.netty.handler.flush", - "io.netty.handler.ipfilter", - "io.netty.handler.logging", - "io.netty.handler.pcap", - "io.netty.handler.ssl", - "io.netty.handler.ssl.util", - "io.netty.handler.stream", - "io.netty.handler.timeout", - "io.netty.handler.traffic" - ], - "io.netty:netty-handler-proxy": [ - "io.netty.handler.proxy" - ], - "io.netty:netty-resolver": [ - "io.netty.resolver" - ], - "io.netty:netty-resolver-dns": [ - "io.netty.resolver.dns" - ], - "io.netty:netty-resolver-dns-classes-macos": [ - "io.netty.resolver.dns.macos" - ], - "io.netty:netty-transport": [ - "io.netty.bootstrap", - "io.netty.channel", - "io.netty.channel.embedded", - "io.netty.channel.group", - "io.netty.channel.internal", - "io.netty.channel.local", - "io.netty.channel.nio", - "io.netty.channel.oio", - "io.netty.channel.pool", - "io.netty.channel.socket", - "io.netty.channel.socket.nio", - "io.netty.channel.socket.oio" - ], - "io.netty:netty-transport-classes-epoll": [ - "io.netty.channel.epoll" - ], - "io.netty:netty-transport-native-unix-common": [ - "io.netty.channel.unix" - ], - "io.opentelemetry.semconv:opentelemetry-semconv": [ - "io.opentelemetry.semconv" - ], - "io.opentelemetry:opentelemetry-api": [ - "io.opentelemetry.api", - "io.opentelemetry.api.baggage", - "io.opentelemetry.api.baggage.propagation", - "io.opentelemetry.api.common", - "io.opentelemetry.api.internal", - "io.opentelemetry.api.logs", - "io.opentelemetry.api.metrics", - "io.opentelemetry.api.trace", - "io.opentelemetry.api.trace.propagation", - "io.opentelemetry.api.trace.propagation.internal" - ], - "io.opentelemetry:opentelemetry-common": [ - "io.opentelemetry.common" - ], - "io.opentelemetry:opentelemetry-context": [ - "io.opentelemetry.context", - "io.opentelemetry.context.internal.shaded", - "io.opentelemetry.context.propagation", - "io.opentelemetry.context.propagation.internal" - ], - "io.opentelemetry:opentelemetry-exporter-common": [ - "io.opentelemetry.exporter.internal", - "io.opentelemetry.exporter.internal.compression", - "io.opentelemetry.exporter.internal.grpc", - "io.opentelemetry.exporter.internal.http", - "io.opentelemetry.exporter.internal.marshal", - "io.opentelemetry.exporter.internal.metrics" - ], - "io.opentelemetry:opentelemetry-exporter-otlp": [ - "io.opentelemetry.exporter.otlp.all.internal", - "io.opentelemetry.exporter.otlp.http.logs", - "io.opentelemetry.exporter.otlp.http.metrics", - "io.opentelemetry.exporter.otlp.http.trace", - "io.opentelemetry.exporter.otlp.internal", - "io.opentelemetry.exporter.otlp.logs", - "io.opentelemetry.exporter.otlp.metrics", - "io.opentelemetry.exporter.otlp.trace" - ], - "io.opentelemetry:opentelemetry-exporter-otlp-common": [ - "io.opentelemetry.exporter.internal.otlp", - "io.opentelemetry.exporter.internal.otlp.logs", - "io.opentelemetry.exporter.internal.otlp.metrics", - "io.opentelemetry.exporter.internal.otlp.traces", - "io.opentelemetry.proto.collector.logs.v1.internal", - "io.opentelemetry.proto.collector.metrics.v1.internal", - "io.opentelemetry.proto.collector.profiles.v1development.internal", - "io.opentelemetry.proto.collector.trace.v1.internal", - "io.opentelemetry.proto.common.v1.internal", - "io.opentelemetry.proto.logs.v1.internal", - "io.opentelemetry.proto.metrics.v1.internal", - "io.opentelemetry.proto.profiles.v1development.internal", - "io.opentelemetry.proto.resource.v1.internal", - "io.opentelemetry.proto.trace.v1.internal" - ], - "io.opentelemetry:opentelemetry-exporter-sender-okhttp": [ - "io.opentelemetry.exporter.sender.okhttp.internal" - ], - "io.opentelemetry:opentelemetry-extension-trace-propagators": [ - "io.opentelemetry.extension.trace.propagation", - "io.opentelemetry.extension.trace.propagation.internal" - ], - "io.opentelemetry:opentelemetry-sdk": [ - "io.opentelemetry.sdk" - ], - "io.opentelemetry:opentelemetry-sdk-common": [ - "io.opentelemetry.sdk.common", - "io.opentelemetry.sdk.common.export", - "io.opentelemetry.sdk.common.internal", - "io.opentelemetry.sdk.internal", - "io.opentelemetry.sdk.resources" - ], - "io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi": [ - "io.opentelemetry.sdk.autoconfigure.spi", - "io.opentelemetry.sdk.autoconfigure.spi.internal", - "io.opentelemetry.sdk.autoconfigure.spi.logs", - "io.opentelemetry.sdk.autoconfigure.spi.metrics", - "io.opentelemetry.sdk.autoconfigure.spi.traces" - ], - "io.opentelemetry:opentelemetry-sdk-logs": [ - "io.opentelemetry.sdk.logs", - "io.opentelemetry.sdk.logs.data", - "io.opentelemetry.sdk.logs.data.internal", - "io.opentelemetry.sdk.logs.export", - "io.opentelemetry.sdk.logs.internal" - ], - "io.opentelemetry:opentelemetry-sdk-metrics": [ - "io.opentelemetry.sdk.metrics", - "io.opentelemetry.sdk.metrics.data", - "io.opentelemetry.sdk.metrics.export", - "io.opentelemetry.sdk.metrics.internal", - "io.opentelemetry.sdk.metrics.internal.aggregator", - "io.opentelemetry.sdk.metrics.internal.concurrent", - "io.opentelemetry.sdk.metrics.internal.data", - "io.opentelemetry.sdk.metrics.internal.debug", - "io.opentelemetry.sdk.metrics.internal.descriptor", - "io.opentelemetry.sdk.metrics.internal.exemplar", - "io.opentelemetry.sdk.metrics.internal.export", - "io.opentelemetry.sdk.metrics.internal.state", - "io.opentelemetry.sdk.metrics.internal.view" - ], - "io.opentelemetry:opentelemetry-sdk-testing": [ - "io.opentelemetry.sdk.testing.assertj", - "io.opentelemetry.sdk.testing.context", - "io.opentelemetry.sdk.testing.exporter", - "io.opentelemetry.sdk.testing.junit4", - "io.opentelemetry.sdk.testing.junit5", - "io.opentelemetry.sdk.testing.logs", - "io.opentelemetry.sdk.testing.logs.internal", - "io.opentelemetry.sdk.testing.metrics", - "io.opentelemetry.sdk.testing.time", - "io.opentelemetry.sdk.testing.trace" - ], - "io.opentelemetry:opentelemetry-sdk-trace": [ - "io.opentelemetry.internal.shaded.jctools.counters", - "io.opentelemetry.internal.shaded.jctools.maps", - "io.opentelemetry.internal.shaded.jctools.queues", - "io.opentelemetry.internal.shaded.jctools.queues.atomic", - "io.opentelemetry.internal.shaded.jctools.queues.atomic.unpadded", - "io.opentelemetry.internal.shaded.jctools.queues.unpadded", - "io.opentelemetry.internal.shaded.jctools.util", - "io.opentelemetry.sdk.trace", - "io.opentelemetry.sdk.trace.data", - "io.opentelemetry.sdk.trace.export", - "io.opentelemetry.sdk.trace.internal", - "io.opentelemetry.sdk.trace.samplers" - ], - "io.projectreactor.netty:reactor-netty-core": [ - "reactor.netty", - "reactor.netty.channel", - "reactor.netty.contextpropagation", - "reactor.netty.internal.shaded.reactor.pool", - "reactor.netty.internal.shaded.reactor.pool.decorators", - "reactor.netty.internal.shaded.reactor.pool.introspection", - "reactor.netty.internal.util", - "reactor.netty.observability", - "reactor.netty.resources", - "reactor.netty.tcp", - "reactor.netty.transport", - "reactor.netty.transport.logging", - "reactor.netty.udp" - ], - "io.projectreactor.netty:reactor-netty-http": [ - "reactor.netty.http", - "reactor.netty.http.client", - "reactor.netty.http.internal", - "reactor.netty.http.logging", - "reactor.netty.http.observability", - "reactor.netty.http.server", - "reactor.netty.http.server.compression", - "reactor.netty.http.server.logging", - "reactor.netty.http.server.logging.error", - "reactor.netty.http.websocket" - ], - "io.projectreactor:reactor-core": [ - "reactor.adapter", - "reactor.core", - "reactor.core.observability", - "reactor.core.publisher", - "reactor.core.scheduler", - "reactor.util", - "reactor.util.annotation", - "reactor.util.concurrent", - "reactor.util.context", - "reactor.util.function", - "reactor.util.repeat", - "reactor.util.retry" - ], - "io.projectreactor:reactor-test": [ - "reactor.test", - "reactor.test.publisher", - "reactor.test.scheduler", - "reactor.test.subscriber", - "reactor.test.util" - ], - "io.swagger.core.v3:swagger-annotations-jakarta": [ - "io.swagger.v3.oas.annotations", - "io.swagger.v3.oas.annotations.callbacks", - "io.swagger.v3.oas.annotations.enums", - "io.swagger.v3.oas.annotations.extensions", - "io.swagger.v3.oas.annotations.headers", - "io.swagger.v3.oas.annotations.info", - "io.swagger.v3.oas.annotations.links", - "io.swagger.v3.oas.annotations.media", - "io.swagger.v3.oas.annotations.parameters", - "io.swagger.v3.oas.annotations.responses", - "io.swagger.v3.oas.annotations.security", - "io.swagger.v3.oas.annotations.servers", - "io.swagger.v3.oas.annotations.tags" - ], - "io.swagger.core.v3:swagger-core-jakarta": [ - "io.swagger.v3.core.converter", - "io.swagger.v3.core.filter", - "io.swagger.v3.core.jackson", - "io.swagger.v3.core.jackson.mixin", - "io.swagger.v3.core.model", - "io.swagger.v3.core.util" - ], - "io.swagger.core.v3:swagger-models-jakarta": [ - "io.swagger.v3.oas.models", - "io.swagger.v3.oas.models.annotations", - "io.swagger.v3.oas.models.callbacks", - "io.swagger.v3.oas.models.examples", - "io.swagger.v3.oas.models.headers", - "io.swagger.v3.oas.models.info", - "io.swagger.v3.oas.models.links", - "io.swagger.v3.oas.models.media", - "io.swagger.v3.oas.models.parameters", - "io.swagger.v3.oas.models.responses", - "io.swagger.v3.oas.models.security", - "io.swagger.v3.oas.models.servers", - "io.swagger.v3.oas.models.tags" - ], - "jakarta.activation:jakarta.activation-api": [ - "jakarta.activation", - "jakarta.activation.spi" - ], - "jakarta.annotation:jakarta.annotation-api": [ - "jakarta.annotation", - "jakarta.annotation.security", - "jakarta.annotation.sql" - ], - "jakarta.servlet:jakarta.servlet-api": [ - "jakarta.servlet", - "jakarta.servlet.annotation", - "jakarta.servlet.descriptor", - "jakarta.servlet.http" - ], - "jakarta.validation:jakarta.validation-api": [ - "jakarta.validation", - "jakarta.validation.bootstrap", - "jakarta.validation.constraints", - "jakarta.validation.constraintvalidation", - "jakarta.validation.executable", - "jakarta.validation.groups", - "jakarta.validation.metadata", - "jakarta.validation.spi", - "jakarta.validation.valueextraction" - ], - "jakarta.xml.bind:jakarta.xml.bind-api": [ - "jakarta.xml.bind", - "jakarta.xml.bind.annotation", - "jakarta.xml.bind.annotation.adapters", - "jakarta.xml.bind.attachment", - "jakarta.xml.bind.helpers", - "jakarta.xml.bind.util" - ], - "net.bytebuddy:byte-buddy": [ - "net.bytebuddy", - "net.bytebuddy.agent.builder", - "net.bytebuddy.asm", - "net.bytebuddy.build", - "net.bytebuddy.description", - "net.bytebuddy.description.annotation", - "net.bytebuddy.description.enumeration", - "net.bytebuddy.description.field", - "net.bytebuddy.description.method", - "net.bytebuddy.description.modifier", - "net.bytebuddy.description.type", - "net.bytebuddy.dynamic", - "net.bytebuddy.dynamic.loading", - "net.bytebuddy.dynamic.scaffold", - "net.bytebuddy.dynamic.scaffold.inline", - "net.bytebuddy.dynamic.scaffold.subclass", - "net.bytebuddy.implementation", - "net.bytebuddy.implementation.attribute", - "net.bytebuddy.implementation.auxiliary", - "net.bytebuddy.implementation.bind", - "net.bytebuddy.implementation.bind.annotation", - "net.bytebuddy.implementation.bytecode", - "net.bytebuddy.implementation.bytecode.assign", - "net.bytebuddy.implementation.bytecode.assign.primitive", - "net.bytebuddy.implementation.bytecode.assign.reference", - "net.bytebuddy.implementation.bytecode.collection", - "net.bytebuddy.implementation.bytecode.constant", - "net.bytebuddy.implementation.bytecode.member", - "net.bytebuddy.jar.asm", - "net.bytebuddy.jar.asm.commons", - "net.bytebuddy.jar.asm.signature", - "net.bytebuddy.jar.asmjdkbridge", - "net.bytebuddy.matcher", - "net.bytebuddy.pool", - "net.bytebuddy.utility", - "net.bytebuddy.utility.dispatcher", - "net.bytebuddy.utility.nullability", - "net.bytebuddy.utility.privilege", - "net.bytebuddy.utility.visitor" - ], - "net.bytebuddy:byte-buddy-agent": [ - "net.bytebuddy.agent", - "net.bytebuddy.agent.utility.nullability" - ], - "net.java.dev.jna:jna": [ - "com.sun.jna", - "com.sun.jna.internal", - "com.sun.jna.ptr", - "com.sun.jna.win32" - ], - "net.minidev:accessors-smart": [ - "net.minidev.asm", - "net.minidev.asm.ex" - ], - "net.minidev:json-smart": [ - "net.minidev.json", - "net.minidev.json.annotate", - "net.minidev.json.parser", - "net.minidev.json.reader", - "net.minidev.json.writer" - ], - "org.apache.cassandra:java-driver-core": [ - "com.datastax.dse.driver.api.core", - "com.datastax.dse.driver.api.core.auth", - "com.datastax.dse.driver.api.core.config", - "com.datastax.dse.driver.api.core.cql.continuous", - "com.datastax.dse.driver.api.core.cql.continuous.reactive", - "com.datastax.dse.driver.api.core.cql.reactive", - "com.datastax.dse.driver.api.core.data.geometry", - "com.datastax.dse.driver.api.core.data.time", - "com.datastax.dse.driver.api.core.graph", - "com.datastax.dse.driver.api.core.graph.predicates", - "com.datastax.dse.driver.api.core.graph.reactive", - "com.datastax.dse.driver.api.core.metadata", - "com.datastax.dse.driver.api.core.metadata.schema", - "com.datastax.dse.driver.api.core.metrics", - "com.datastax.dse.driver.api.core.servererrors", - "com.datastax.dse.driver.api.core.type", - "com.datastax.dse.driver.api.core.type.codec", - "com.datastax.dse.driver.internal.core", - "com.datastax.dse.driver.internal.core.auth", - "com.datastax.dse.driver.internal.core.cql", - "com.datastax.dse.driver.internal.core.cql.continuous", - "com.datastax.dse.driver.internal.core.cql.continuous.reactive", - "com.datastax.dse.driver.internal.core.cql.reactive", - "com.datastax.dse.driver.internal.core.data.geometry", - "com.datastax.dse.driver.internal.core.graph", - "com.datastax.dse.driver.internal.core.graph.binary", - "com.datastax.dse.driver.internal.core.graph.binary.buffer", - "com.datastax.dse.driver.internal.core.graph.reactive", - "com.datastax.dse.driver.internal.core.insights", - "com.datastax.dse.driver.internal.core.insights.configuration", - "com.datastax.dse.driver.internal.core.insights.exceptions", - "com.datastax.dse.driver.internal.core.insights.schema", - "com.datastax.dse.driver.internal.core.loadbalancing", - "com.datastax.dse.driver.internal.core.metadata.schema", - "com.datastax.dse.driver.internal.core.metadata.schema.parsing", - "com.datastax.dse.driver.internal.core.protocol", - "com.datastax.dse.driver.internal.core.search", - "com.datastax.dse.driver.internal.core.session", - "com.datastax.dse.driver.internal.core.type.codec", - "com.datastax.dse.driver.internal.core.type.codec.geometry", - "com.datastax.dse.driver.internal.core.type.codec.time", - "com.datastax.dse.driver.internal.core.util.concurrent", - "com.datastax.oss.driver.api.core", - "com.datastax.oss.driver.api.core.addresstranslation", - "com.datastax.oss.driver.api.core.auth", - "com.datastax.oss.driver.api.core.config", - "com.datastax.oss.driver.api.core.connection", - "com.datastax.oss.driver.api.core.context", - "com.datastax.oss.driver.api.core.cql", - "com.datastax.oss.driver.api.core.data", - "com.datastax.oss.driver.api.core.detach", - "com.datastax.oss.driver.api.core.loadbalancing", - "com.datastax.oss.driver.api.core.metadata", - "com.datastax.oss.driver.api.core.metadata.schema", - "com.datastax.oss.driver.api.core.metadata.token", - "com.datastax.oss.driver.api.core.metrics", - "com.datastax.oss.driver.api.core.paging", - "com.datastax.oss.driver.api.core.retry", - "com.datastax.oss.driver.api.core.servererrors", - "com.datastax.oss.driver.api.core.session", - "com.datastax.oss.driver.api.core.session.throttling", - "com.datastax.oss.driver.api.core.specex", - "com.datastax.oss.driver.api.core.ssl", - "com.datastax.oss.driver.api.core.time", - "com.datastax.oss.driver.api.core.tracker", - "com.datastax.oss.driver.api.core.type", - "com.datastax.oss.driver.api.core.type.codec", - "com.datastax.oss.driver.api.core.type.codec.registry", - "com.datastax.oss.driver.api.core.type.reflect", - "com.datastax.oss.driver.api.core.uuid", - "com.datastax.oss.driver.internal.core", - "com.datastax.oss.driver.internal.core.addresstranslation", - "com.datastax.oss.driver.internal.core.adminrequest", - "com.datastax.oss.driver.internal.core.auth", - "com.datastax.oss.driver.internal.core.channel", - "com.datastax.oss.driver.internal.core.config", - "com.datastax.oss.driver.internal.core.config.cloud", - "com.datastax.oss.driver.internal.core.config.composite", - "com.datastax.oss.driver.internal.core.config.map", - "com.datastax.oss.driver.internal.core.config.typesafe", - "com.datastax.oss.driver.internal.core.connection", - "com.datastax.oss.driver.internal.core.context", - "com.datastax.oss.driver.internal.core.control", - "com.datastax.oss.driver.internal.core.cql", - "com.datastax.oss.driver.internal.core.data", - "com.datastax.oss.driver.internal.core.loadbalancing", - "com.datastax.oss.driver.internal.core.loadbalancing.helper", - "com.datastax.oss.driver.internal.core.loadbalancing.nodeset", - "com.datastax.oss.driver.internal.core.metadata", - "com.datastax.oss.driver.internal.core.metadata.schema", - "com.datastax.oss.driver.internal.core.metadata.schema.events", - "com.datastax.oss.driver.internal.core.metadata.schema.parsing", - "com.datastax.oss.driver.internal.core.metadata.schema.queries", - "com.datastax.oss.driver.internal.core.metadata.schema.refresh", - "com.datastax.oss.driver.internal.core.metadata.token", - "com.datastax.oss.driver.internal.core.metrics", - "com.datastax.oss.driver.internal.core.os", - "com.datastax.oss.driver.internal.core.pool", - "com.datastax.oss.driver.internal.core.protocol", - "com.datastax.oss.driver.internal.core.retry", - "com.datastax.oss.driver.internal.core.servererrors", - "com.datastax.oss.driver.internal.core.session", - "com.datastax.oss.driver.internal.core.session.throttling", - "com.datastax.oss.driver.internal.core.specex", - "com.datastax.oss.driver.internal.core.ssl", - "com.datastax.oss.driver.internal.core.time", - "com.datastax.oss.driver.internal.core.tracker", - "com.datastax.oss.driver.internal.core.type", - "com.datastax.oss.driver.internal.core.type.codec", - "com.datastax.oss.driver.internal.core.type.codec.extras", - "com.datastax.oss.driver.internal.core.type.codec.extras.array", - "com.datastax.oss.driver.internal.core.type.codec.extras.enums", - "com.datastax.oss.driver.internal.core.type.codec.extras.json", - "com.datastax.oss.driver.internal.core.type.codec.extras.time", - "com.datastax.oss.driver.internal.core.type.codec.extras.vector", - "com.datastax.oss.driver.internal.core.type.codec.registry", - "com.datastax.oss.driver.internal.core.type.util", - "com.datastax.oss.driver.internal.core.util", - "com.datastax.oss.driver.internal.core.util.collection", - "com.datastax.oss.driver.internal.core.util.concurrent" - ], - "org.apache.cassandra:java-driver-guava-shaded": [ - "com.datastax.oss.driver.shaded.guava.common.annotations", - "com.datastax.oss.driver.shaded.guava.common.base", - "com.datastax.oss.driver.shaded.guava.common.base.internal", - "com.datastax.oss.driver.shaded.guava.common.cache", - "com.datastax.oss.driver.shaded.guava.common.collect", - "com.datastax.oss.driver.shaded.guava.common.escape", - "com.datastax.oss.driver.shaded.guava.common.eventbus", - "com.datastax.oss.driver.shaded.guava.common.graph", - "com.datastax.oss.driver.shaded.guava.common.hash", - "com.datastax.oss.driver.shaded.guava.common.html", - "com.datastax.oss.driver.shaded.guava.common.io", - "com.datastax.oss.driver.shaded.guava.common.math", - "com.datastax.oss.driver.shaded.guava.common.net", - "com.datastax.oss.driver.shaded.guava.common.primitives", - "com.datastax.oss.driver.shaded.guava.common.reflect", - "com.datastax.oss.driver.shaded.guava.common.util.concurrent", - "com.datastax.oss.driver.shaded.guava.common.util.concurrent.internal", - "com.datastax.oss.driver.shaded.guava.common.xml", - "com.datastax.oss.driver.shaded.guava.j2objc.annotations", - "com.datastax.oss.driver.shaded.guava.thirdparty.publicsuffix" - ], - "org.apache.cassandra:java-driver-metrics-micrometer": [ - "com.datastax.oss.driver.internal.metrics.micrometer" - ], - "org.apache.cassandra:java-driver-query-builder": [ - "com.datastax.dse.driver.api.querybuilder", - "com.datastax.dse.driver.api.querybuilder.schema", - "com.datastax.dse.driver.internal.querybuilder.schema", - "com.datastax.oss.driver.api.querybuilder", - "com.datastax.oss.driver.api.querybuilder.condition", - "com.datastax.oss.driver.api.querybuilder.delete", - "com.datastax.oss.driver.api.querybuilder.insert", - "com.datastax.oss.driver.api.querybuilder.relation", - "com.datastax.oss.driver.api.querybuilder.schema", - "com.datastax.oss.driver.api.querybuilder.schema.compaction", - "com.datastax.oss.driver.api.querybuilder.select", - "com.datastax.oss.driver.api.querybuilder.term", - "com.datastax.oss.driver.api.querybuilder.truncate", - "com.datastax.oss.driver.api.querybuilder.update", - "com.datastax.oss.driver.internal.querybuilder", - "com.datastax.oss.driver.internal.querybuilder.condition", - "com.datastax.oss.driver.internal.querybuilder.delete", - "com.datastax.oss.driver.internal.querybuilder.insert", - "com.datastax.oss.driver.internal.querybuilder.lhs", - "com.datastax.oss.driver.internal.querybuilder.relation", - "com.datastax.oss.driver.internal.querybuilder.schema", - "com.datastax.oss.driver.internal.querybuilder.schema.compaction", - "com.datastax.oss.driver.internal.querybuilder.select", - "com.datastax.oss.driver.internal.querybuilder.term", - "com.datastax.oss.driver.internal.querybuilder.truncate", - "com.datastax.oss.driver.internal.querybuilder.update" - ], - "org.apache.commons:commons-compress": [ - "org.apache.commons.compress", - "org.apache.commons.compress.archivers", - "org.apache.commons.compress.archivers.ar", - "org.apache.commons.compress.archivers.arj", - "org.apache.commons.compress.archivers.cpio", - "org.apache.commons.compress.archivers.dump", - "org.apache.commons.compress.archivers.examples", - "org.apache.commons.compress.archivers.jar", - "org.apache.commons.compress.archivers.sevenz", - "org.apache.commons.compress.archivers.tar", - "org.apache.commons.compress.archivers.zip", - "org.apache.commons.compress.changes", - "org.apache.commons.compress.compressors", - "org.apache.commons.compress.compressors.brotli", - "org.apache.commons.compress.compressors.bzip2", - "org.apache.commons.compress.compressors.deflate", - "org.apache.commons.compress.compressors.deflate64", - "org.apache.commons.compress.compressors.gzip", - "org.apache.commons.compress.compressors.lz4", - "org.apache.commons.compress.compressors.lz77support", - "org.apache.commons.compress.compressors.lzma", - "org.apache.commons.compress.compressors.lzw", - "org.apache.commons.compress.compressors.pack200", - "org.apache.commons.compress.compressors.snappy", - "org.apache.commons.compress.compressors.xz", - "org.apache.commons.compress.compressors.z", - "org.apache.commons.compress.compressors.zstandard", - "org.apache.commons.compress.harmony", - "org.apache.commons.compress.harmony.archive.internal.nls", - "org.apache.commons.compress.harmony.pack200", - "org.apache.commons.compress.harmony.unpack200", - "org.apache.commons.compress.harmony.unpack200.bytecode", - "org.apache.commons.compress.harmony.unpack200.bytecode.forms", - "org.apache.commons.compress.java.util.jar", - "org.apache.commons.compress.parallel", - "org.apache.commons.compress.utils" - ], - "org.apache.commons:commons-lang3": [ - "org.apache.commons.lang3", - "org.apache.commons.lang3.arch", - "org.apache.commons.lang3.builder", - "org.apache.commons.lang3.compare", - "org.apache.commons.lang3.concurrent", - "org.apache.commons.lang3.concurrent.locks", - "org.apache.commons.lang3.event", - "org.apache.commons.lang3.exception", - "org.apache.commons.lang3.function", - "org.apache.commons.lang3.math", - "org.apache.commons.lang3.mutable", - "org.apache.commons.lang3.reflect", - "org.apache.commons.lang3.stream", - "org.apache.commons.lang3.text", - "org.apache.commons.lang3.text.translate", - "org.apache.commons.lang3.time", - "org.apache.commons.lang3.tuple", - "org.apache.commons.lang3.util" - ], - "org.apache.logging.log4j:log4j-api": [ - "org.apache.logging.log4j", - "org.apache.logging.log4j.internal", - "org.apache.logging.log4j.internal.annotation", - "org.apache.logging.log4j.internal.map", - "org.apache.logging.log4j.message", - "org.apache.logging.log4j.simple", - "org.apache.logging.log4j.simple.internal", - "org.apache.logging.log4j.spi", - "org.apache.logging.log4j.status", - "org.apache.logging.log4j.util", - "org.apache.logging.log4j.util.internal" - ], - "org.apache.logging.log4j:log4j-to-slf4j": [ - "org.apache.logging.slf4j" - ], - "org.apache.tomcat.embed:tomcat-embed-core": [ - "jakarta.security.auth.message", - "jakarta.security.auth.message.callback", - "jakarta.security.auth.message.config", - "jakarta.security.auth.message.module", - "jakarta.servlet", - "jakarta.servlet.annotation", - "jakarta.servlet.descriptor", - "jakarta.servlet.http", - "org.apache.catalina", - "org.apache.catalina.authenticator", - "org.apache.catalina.authenticator.jaspic", - "org.apache.catalina.connector", - "org.apache.catalina.core", - "org.apache.catalina.deploy", - "org.apache.catalina.filters", - "org.apache.catalina.loader", - "org.apache.catalina.manager", - "org.apache.catalina.manager.host", - "org.apache.catalina.manager.util", - "org.apache.catalina.mapper", - "org.apache.catalina.mbeans", - "org.apache.catalina.realm", - "org.apache.catalina.security", - "org.apache.catalina.servlets", - "org.apache.catalina.session", - "org.apache.catalina.startup", - "org.apache.catalina.users", - "org.apache.catalina.util", - "org.apache.catalina.valves", - "org.apache.catalina.valves.rewrite", - "org.apache.catalina.webresources", - "org.apache.catalina.webresources.war", - "org.apache.coyote", - "org.apache.coyote.ajp", - "org.apache.coyote.http11", - "org.apache.coyote.http11.filters", - "org.apache.coyote.http11.upgrade", - "org.apache.coyote.http2", - "org.apache.juli", - "org.apache.juli.logging", - "org.apache.naming", - "org.apache.naming.factory", - "org.apache.naming.java", - "org.apache.tomcat", - "org.apache.tomcat.jni", - "org.apache.tomcat.util", - "org.apache.tomcat.util.bcel", - "org.apache.tomcat.util.bcel.classfile", - "org.apache.tomcat.util.buf", - "org.apache.tomcat.util.collections", - "org.apache.tomcat.util.compat", - "org.apache.tomcat.util.concurrent", - "org.apache.tomcat.util.descriptor", - "org.apache.tomcat.util.descriptor.tagplugin", - "org.apache.tomcat.util.descriptor.web", - "org.apache.tomcat.util.digester", - "org.apache.tomcat.util.file", - "org.apache.tomcat.util.http", - "org.apache.tomcat.util.http.fileupload", - "org.apache.tomcat.util.http.fileupload.disk", - "org.apache.tomcat.util.http.fileupload.impl", - "org.apache.tomcat.util.http.fileupload.servlet", - "org.apache.tomcat.util.http.fileupload.util", - "org.apache.tomcat.util.http.fileupload.util.mime", - "org.apache.tomcat.util.http.parser", - "org.apache.tomcat.util.json", - "org.apache.tomcat.util.log", - "org.apache.tomcat.util.modeler", - "org.apache.tomcat.util.modeler.modules", - "org.apache.tomcat.util.net", - "org.apache.tomcat.util.net.jsse", - "org.apache.tomcat.util.net.openssl", - "org.apache.tomcat.util.net.openssl.ciphers", - "org.apache.tomcat.util.res", - "org.apache.tomcat.util.scan", - "org.apache.tomcat.util.security", - "org.apache.tomcat.util.threads" - ], - "org.apache.tomcat.embed:tomcat-embed-el": [ - "jakarta.el", - "org.apache.el", - "org.apache.el.lang", - "org.apache.el.parser", - "org.apache.el.stream", - "org.apache.el.util" - ], - "org.apache.tomcat.embed:tomcat-embed-websocket": [ - "jakarta.websocket", - "jakarta.websocket.server", - "org.apache.tomcat.websocket", - "org.apache.tomcat.websocket.pojo", - "org.apache.tomcat.websocket.server" - ], - "org.apiguardian:apiguardian-api": [ - "org.apiguardian.api" - ], - "org.assertj:assertj-core": [ - "org.assertj.core.annotation", - "org.assertj.core.annotations", - "org.assertj.core.api", - "org.assertj.core.api.exception", - "org.assertj.core.api.filter", - "org.assertj.core.api.iterable", - "org.assertj.core.api.junit.jupiter", - "org.assertj.core.api.recursive", - "org.assertj.core.api.recursive.assertion", - "org.assertj.core.api.recursive.comparison", - "org.assertj.core.condition", - "org.assertj.core.configuration", - "org.assertj.core.data", - "org.assertj.core.description", - "org.assertj.core.error", - "org.assertj.core.error.array2d", - "org.assertj.core.error.future", - "org.assertj.core.error.uri", - "org.assertj.core.extractor", - "org.assertj.core.groups", - "org.assertj.core.internal", - "org.assertj.core.internal.annotation", - "org.assertj.core.matcher", - "org.assertj.core.presentation", - "org.assertj.core.util", - "org.assertj.core.util.diff", - "org.assertj.core.util.diff.myers", - "org.assertj.core.util.introspection", - "org.assertj.core.util.xml" - ], - "org.awaitility:awaitility": [ - "org.awaitility", - "org.awaitility.classpath", - "org.awaitility.constraint", - "org.awaitility.core", - "org.awaitility.pollinterval", - "org.awaitility.reflect", - "org.awaitility.reflect.exception", - "org.awaitility.spi" - ], - "org.bouncycastle:bcprov-jdk18on": [ - "org.bouncycastle", - "org.bouncycastle.asn1", - "org.bouncycastle.asn1.anssi", - "org.bouncycastle.asn1.bc", - "org.bouncycastle.asn1.cryptopro", - "org.bouncycastle.asn1.gm", - "org.bouncycastle.asn1.nist", - "org.bouncycastle.asn1.ocsp", - "org.bouncycastle.asn1.pkcs", - "org.bouncycastle.asn1.sec", - "org.bouncycastle.asn1.teletrust", - "org.bouncycastle.asn1.ua", - "org.bouncycastle.asn1.util", - "org.bouncycastle.asn1.x500", - "org.bouncycastle.asn1.x500.style", - "org.bouncycastle.asn1.x509", - "org.bouncycastle.asn1.x509.qualified", - "org.bouncycastle.asn1.x509.sigi", - "org.bouncycastle.asn1.x9", - "org.bouncycastle.crypto", - "org.bouncycastle.crypto.agreement", - "org.bouncycastle.crypto.agreement.ecjpake", - "org.bouncycastle.crypto.agreement.jpake", - "org.bouncycastle.crypto.agreement.kdf", - "org.bouncycastle.crypto.agreement.srp", - "org.bouncycastle.crypto.commitments", - "org.bouncycastle.crypto.constraints", - "org.bouncycastle.crypto.digests", - "org.bouncycastle.crypto.ec", - "org.bouncycastle.crypto.encodings", - "org.bouncycastle.crypto.engines", - "org.bouncycastle.crypto.examples", - "org.bouncycastle.crypto.fpe", - "org.bouncycastle.crypto.generators", - "org.bouncycastle.crypto.hash2curve", - "org.bouncycastle.crypto.hash2curve.data", - "org.bouncycastle.crypto.hash2curve.impl", - "org.bouncycastle.crypto.hpke", - "org.bouncycastle.crypto.io", - "org.bouncycastle.crypto.kems", - "org.bouncycastle.crypto.kems.mlkem", - "org.bouncycastle.crypto.macs", - "org.bouncycastle.crypto.modes", - "org.bouncycastle.crypto.modes.gcm", - "org.bouncycastle.crypto.modes.kgcm", - "org.bouncycastle.crypto.paddings", - "org.bouncycastle.crypto.params", - "org.bouncycastle.crypto.parsers", - "org.bouncycastle.crypto.prng", - "org.bouncycastle.crypto.prng.drbg", - "org.bouncycastle.crypto.signers", - "org.bouncycastle.crypto.signers.mldsa", - "org.bouncycastle.crypto.signers.slhdsa", - "org.bouncycastle.crypto.threshold", - "org.bouncycastle.crypto.tls", - "org.bouncycastle.crypto.util", - "org.bouncycastle.i18n", - "org.bouncycastle.i18n.filter", - "org.bouncycastle.iana", - "org.bouncycastle.internal.asn1.bsi", - "org.bouncycastle.internal.asn1.cms", - "org.bouncycastle.internal.asn1.cryptlib", - "org.bouncycastle.internal.asn1.eac", - "org.bouncycastle.internal.asn1.edec", - "org.bouncycastle.internal.asn1.gnu", - "org.bouncycastle.internal.asn1.iana", - "org.bouncycastle.internal.asn1.isara", - "org.bouncycastle.internal.asn1.isismtt", - "org.bouncycastle.internal.asn1.iso", - "org.bouncycastle.internal.asn1.kisa", - "org.bouncycastle.internal.asn1.microsoft", - "org.bouncycastle.internal.asn1.misc", - "org.bouncycastle.internal.asn1.nsri", - "org.bouncycastle.internal.asn1.ntt", - "org.bouncycastle.internal.asn1.oiw", - "org.bouncycastle.internal.asn1.rosstandart", - "org.bouncycastle.jcajce", - "org.bouncycastle.jcajce.interfaces", - "org.bouncycastle.jcajce.io", - "org.bouncycastle.jcajce.provider.asymmetric", - "org.bouncycastle.jcajce.provider.asymmetric.compositesignatures", - "org.bouncycastle.jcajce.provider.asymmetric.dh", - "org.bouncycastle.jcajce.provider.asymmetric.dsa", - "org.bouncycastle.jcajce.provider.asymmetric.dstu", - "org.bouncycastle.jcajce.provider.asymmetric.ec", - "org.bouncycastle.jcajce.provider.asymmetric.ecgost", - "org.bouncycastle.jcajce.provider.asymmetric.ecgost12", - "org.bouncycastle.jcajce.provider.asymmetric.edec", - "org.bouncycastle.jcajce.provider.asymmetric.elgamal", - "org.bouncycastle.jcajce.provider.asymmetric.gost", - "org.bouncycastle.jcajce.provider.asymmetric.ies", - "org.bouncycastle.jcajce.provider.asymmetric.mldsa", - "org.bouncycastle.jcajce.provider.asymmetric.mlkem", - "org.bouncycastle.jcajce.provider.asymmetric.rsa", - "org.bouncycastle.jcajce.provider.asymmetric.slhdsa", - "org.bouncycastle.jcajce.provider.asymmetric.util", - "org.bouncycastle.jcajce.provider.asymmetric.x509", - "org.bouncycastle.jcajce.provider.config", - "org.bouncycastle.jcajce.provider.digest", - "org.bouncycastle.jcajce.provider.drbg", - "org.bouncycastle.jcajce.provider.kdf", - "org.bouncycastle.jcajce.provider.kdf.hkdf", - "org.bouncycastle.jcajce.provider.kdf.pbkdf2", - "org.bouncycastle.jcajce.provider.kdf.scrypt", - "org.bouncycastle.jcajce.provider.keystore", - "org.bouncycastle.jcajce.provider.keystore.bc", - "org.bouncycastle.jcajce.provider.keystore.bcfks", - "org.bouncycastle.jcajce.provider.keystore.pkcs12", - "org.bouncycastle.jcajce.provider.keystore.util", - "org.bouncycastle.jcajce.provider.symmetric", - "org.bouncycastle.jcajce.provider.symmetric.util", - "org.bouncycastle.jcajce.provider.util", - "org.bouncycastle.jcajce.spec", - "org.bouncycastle.jcajce.util", - "org.bouncycastle.jce", - "org.bouncycastle.jce.exception", - "org.bouncycastle.jce.interfaces", - "org.bouncycastle.jce.netscape", - "org.bouncycastle.jce.provider", - "org.bouncycastle.jce.spec", - "org.bouncycastle.ldap", - "org.bouncycastle.math", - "org.bouncycastle.math.ec", - "org.bouncycastle.math.ec.custom.djb", - "org.bouncycastle.math.ec.custom.gm", - "org.bouncycastle.math.ec.custom.sec", - "org.bouncycastle.math.ec.endo", - "org.bouncycastle.math.ec.rfc7748", - "org.bouncycastle.math.ec.rfc8032", - "org.bouncycastle.math.ec.tools", - "org.bouncycastle.math.field", - "org.bouncycastle.math.raw", - "org.bouncycastle.pqc.asn1", - "org.bouncycastle.pqc.crypto", - "org.bouncycastle.pqc.crypto.cmce", - "org.bouncycastle.pqc.crypto.crystals.dilithium", - "org.bouncycastle.pqc.crypto.falcon", - "org.bouncycastle.pqc.crypto.frodo", - "org.bouncycastle.pqc.crypto.hqc", - "org.bouncycastle.pqc.crypto.lms", - "org.bouncycastle.pqc.crypto.mayo", - "org.bouncycastle.pqc.crypto.mldsa", - "org.bouncycastle.pqc.crypto.mlkem", - "org.bouncycastle.pqc.crypto.newhope", - "org.bouncycastle.pqc.crypto.ntru", - "org.bouncycastle.pqc.crypto.ntruplus", - "org.bouncycastle.pqc.crypto.ntruprime", - "org.bouncycastle.pqc.crypto.saber", - "org.bouncycastle.pqc.crypto.slhdsa", - "org.bouncycastle.pqc.crypto.snova", - "org.bouncycastle.pqc.crypto.sphincs", - "org.bouncycastle.pqc.crypto.util", - "org.bouncycastle.pqc.crypto.xmss", - "org.bouncycastle.pqc.crypto.xwing", - "org.bouncycastle.pqc.jcajce.interfaces", - "org.bouncycastle.pqc.jcajce.provider", - "org.bouncycastle.pqc.jcajce.provider.bike", - "org.bouncycastle.pqc.jcajce.provider.cmce", - "org.bouncycastle.pqc.jcajce.provider.dilithium", - "org.bouncycastle.pqc.jcajce.provider.falcon", - "org.bouncycastle.pqc.jcajce.provider.frodo", - "org.bouncycastle.pqc.jcajce.provider.hqc", - "org.bouncycastle.pqc.jcajce.provider.kyber", - "org.bouncycastle.pqc.jcajce.provider.lms", - "org.bouncycastle.pqc.jcajce.provider.mayo", - "org.bouncycastle.pqc.jcajce.provider.newhope", - "org.bouncycastle.pqc.jcajce.provider.ntru", - "org.bouncycastle.pqc.jcajce.provider.ntruplus", - "org.bouncycastle.pqc.jcajce.provider.ntruprime", - "org.bouncycastle.pqc.jcajce.provider.picnic", - "org.bouncycastle.pqc.jcajce.provider.saber", - "org.bouncycastle.pqc.jcajce.provider.snova", - "org.bouncycastle.pqc.jcajce.provider.sphincs", - "org.bouncycastle.pqc.jcajce.provider.sphincsplus", - "org.bouncycastle.pqc.jcajce.provider.util", - "org.bouncycastle.pqc.jcajce.provider.xmss", - "org.bouncycastle.pqc.jcajce.spec", - "org.bouncycastle.pqc.legacy.bike", - "org.bouncycastle.pqc.legacy.picnic", - "org.bouncycastle.pqc.legacy.rainbow", - "org.bouncycastle.pqc.legacy.sphincsplus", - "org.bouncycastle.pqc.math.ntru", - "org.bouncycastle.pqc.math.ntru.parameters", - "org.bouncycastle.util", - "org.bouncycastle.util.encoders", - "org.bouncycastle.util.io", - "org.bouncycastle.util.io.pem", - "org.bouncycastle.util.test", - "org.bouncycastle.x509", - "org.bouncycastle.x509.extension", - "org.bouncycastle.x509.util" - ], - "org.bouncycastle:bcprov-lts8on": [ - "org.bouncycastle", - "org.bouncycastle.asn1", - "org.bouncycastle.asn1.anssi", - "org.bouncycastle.asn1.bc", - "org.bouncycastle.asn1.cryptlib", - "org.bouncycastle.asn1.cryptopro", - "org.bouncycastle.asn1.edec", - "org.bouncycastle.asn1.gm", - "org.bouncycastle.asn1.gnu", - "org.bouncycastle.asn1.iana", - "org.bouncycastle.asn1.isara", - "org.bouncycastle.asn1.iso", - "org.bouncycastle.asn1.kisa", - "org.bouncycastle.asn1.microsoft", - "org.bouncycastle.asn1.misc", - "org.bouncycastle.asn1.mozilla", - "org.bouncycastle.asn1.nist", - "org.bouncycastle.asn1.nsri", - "org.bouncycastle.asn1.ntt", - "org.bouncycastle.asn1.ocsp", - "org.bouncycastle.asn1.oiw", - "org.bouncycastle.asn1.pkcs", - "org.bouncycastle.asn1.rosstandart", - "org.bouncycastle.asn1.sec", - "org.bouncycastle.asn1.teletrust", - "org.bouncycastle.asn1.ua", - "org.bouncycastle.asn1.util", - "org.bouncycastle.asn1.x500", - "org.bouncycastle.asn1.x500.style", - "org.bouncycastle.asn1.x509", - "org.bouncycastle.asn1.x509.qualified", - "org.bouncycastle.asn1.x509.sigi", - "org.bouncycastle.asn1.x9", - "org.bouncycastle.crypto", - "org.bouncycastle.crypto.agreement", - "org.bouncycastle.crypto.agreement.ecjpake", - "org.bouncycastle.crypto.agreement.jpake", - "org.bouncycastle.crypto.agreement.kdf", - "org.bouncycastle.crypto.agreement.srp", - "org.bouncycastle.crypto.commitments", - "org.bouncycastle.crypto.constraints", - "org.bouncycastle.crypto.digests", - "org.bouncycastle.crypto.ec", - "org.bouncycastle.crypto.encodings", - "org.bouncycastle.crypto.engines", - "org.bouncycastle.crypto.fpe", - "org.bouncycastle.crypto.generators", - "org.bouncycastle.crypto.hpke", - "org.bouncycastle.crypto.io", - "org.bouncycastle.crypto.kems", - "org.bouncycastle.crypto.macs", - "org.bouncycastle.crypto.modes", - "org.bouncycastle.crypto.modes.gcm", - "org.bouncycastle.crypto.modes.kgcm", - "org.bouncycastle.crypto.paddings", - "org.bouncycastle.crypto.params", - "org.bouncycastle.crypto.parsers", - "org.bouncycastle.crypto.prng", - "org.bouncycastle.crypto.prng.drbg", - "org.bouncycastle.crypto.signers", - "org.bouncycastle.crypto.tls", - "org.bouncycastle.crypto.util", - "org.bouncycastle.iana", - "org.bouncycastle.internal.asn1.bsi", - "org.bouncycastle.internal.asn1.cms", - "org.bouncycastle.internal.asn1.cryptlib", - "org.bouncycastle.internal.asn1.eac", - "org.bouncycastle.internal.asn1.edec", - "org.bouncycastle.internal.asn1.gnu", - "org.bouncycastle.internal.asn1.iana", - "org.bouncycastle.internal.asn1.isara", - "org.bouncycastle.internal.asn1.isismtt", - "org.bouncycastle.internal.asn1.iso", - "org.bouncycastle.internal.asn1.kisa", - "org.bouncycastle.internal.asn1.microsoft", - "org.bouncycastle.internal.asn1.misc", - "org.bouncycastle.internal.asn1.nsri", - "org.bouncycastle.internal.asn1.ntt", - "org.bouncycastle.internal.asn1.oiw", - "org.bouncycastle.internal.asn1.rosstandart", - "org.bouncycastle.jcajce", - "org.bouncycastle.jcajce.interfaces", - "org.bouncycastle.jcajce.io", - "org.bouncycastle.jcajce.provider.asymmetric", - "org.bouncycastle.jcajce.provider.asymmetric.compositesignatures", - "org.bouncycastle.jcajce.provider.asymmetric.dh", - "org.bouncycastle.jcajce.provider.asymmetric.dsa", - "org.bouncycastle.jcajce.provider.asymmetric.dstu", - "org.bouncycastle.jcajce.provider.asymmetric.ec", - "org.bouncycastle.jcajce.provider.asymmetric.ecgost", - "org.bouncycastle.jcajce.provider.asymmetric.ecgost12", - "org.bouncycastle.jcajce.provider.asymmetric.edec", - "org.bouncycastle.jcajce.provider.asymmetric.elgamal", - "org.bouncycastle.jcajce.provider.asymmetric.gost", - "org.bouncycastle.jcajce.provider.asymmetric.ies", - "org.bouncycastle.jcajce.provider.asymmetric.mldsa", - "org.bouncycastle.jcajce.provider.asymmetric.mlkem", - "org.bouncycastle.jcajce.provider.asymmetric.rsa", - "org.bouncycastle.jcajce.provider.asymmetric.slhdsa", - "org.bouncycastle.jcajce.provider.asymmetric.util", - "org.bouncycastle.jcajce.provider.asymmetric.x509", - "org.bouncycastle.jcajce.provider.config", - "org.bouncycastle.jcajce.provider.digest", - "org.bouncycastle.jcajce.provider.drbg", - "org.bouncycastle.jcajce.provider.keystore", - "org.bouncycastle.jcajce.provider.keystore.bc", - "org.bouncycastle.jcajce.provider.keystore.bcfks", - "org.bouncycastle.jcajce.provider.keystore.pkcs12", - "org.bouncycastle.jcajce.provider.keystore.util", - "org.bouncycastle.jcajce.provider.symmetric", - "org.bouncycastle.jcajce.provider.symmetric.util", - "org.bouncycastle.jcajce.provider.util", - "org.bouncycastle.jcajce.spec", - "org.bouncycastle.jcajce.util", - "org.bouncycastle.jce", - "org.bouncycastle.jce.exception", - "org.bouncycastle.jce.interfaces", - "org.bouncycastle.jce.netscape", - "org.bouncycastle.jce.provider", - "org.bouncycastle.jce.spec", - "org.bouncycastle.math", - "org.bouncycastle.math.ec", - "org.bouncycastle.math.ec.custom.djb", - "org.bouncycastle.math.ec.custom.gm", - "org.bouncycastle.math.ec.custom.sec", - "org.bouncycastle.math.ec.endo", - "org.bouncycastle.math.ec.rfc7748", - "org.bouncycastle.math.ec.rfc8032", - "org.bouncycastle.math.ec.tools", - "org.bouncycastle.math.field", - "org.bouncycastle.math.raw", - "org.bouncycastle.pqc.crypto", - "org.bouncycastle.pqc.crypto.lms", - "org.bouncycastle.pqc.crypto.mldsa", - "org.bouncycastle.pqc.crypto.mlkem", - "org.bouncycastle.pqc.crypto.slhdsa", - "org.bouncycastle.pqc.crypto.util", - "org.bouncycastle.pqc.jcajce.interfaces", - "org.bouncycastle.pqc.jcajce.provider.lms", - "org.bouncycastle.pqc.jcajce.provider.util", - "org.bouncycastle.pqc.jcajce.spec", - "org.bouncycastle.util", - "org.bouncycastle.util.dispose", - "org.bouncycastle.util.encoders", - "org.bouncycastle.util.io", - "org.bouncycastle.util.io.pem", - "org.bouncycastle.util.test" - ], - "org.hamcrest:hamcrest": [ - "org.hamcrest", - "org.hamcrest.beans", - "org.hamcrest.collection", - "org.hamcrest.comparator", - "org.hamcrest.core", - "org.hamcrest.internal", - "org.hamcrest.io", - "org.hamcrest.number", - "org.hamcrest.object", - "org.hamcrest.text", - "org.hamcrest.xml" - ], - "org.hdrhistogram:HdrHistogram": [ - "org.HdrHistogram", - "org.HdrHistogram.packedarray" - ], - "org.hibernate.validator:hibernate-validator": [ - "org.hibernate.validator", - "org.hibernate.validator.cfg", - "org.hibernate.validator.cfg.context", - "org.hibernate.validator.cfg.defs", - "org.hibernate.validator.cfg.defs.br", - "org.hibernate.validator.cfg.defs.kor", - "org.hibernate.validator.cfg.defs.pl", - "org.hibernate.validator.cfg.defs.ru", - "org.hibernate.validator.constraints", - "org.hibernate.validator.constraints.br", - "org.hibernate.validator.constraints.kor", - "org.hibernate.validator.constraints.pl", - "org.hibernate.validator.constraints.ru", - "org.hibernate.validator.constraints.time", - "org.hibernate.validator.constraintvalidation", - "org.hibernate.validator.constraintvalidation.spi", - "org.hibernate.validator.constraintvalidators", - "org.hibernate.validator.engine", - "org.hibernate.validator.group", - "org.hibernate.validator.internal", - "org.hibernate.validator.internal.cfg", - "org.hibernate.validator.internal.cfg.context", - "org.hibernate.validator.internal.constraintvalidators", - "org.hibernate.validator.internal.constraintvalidators.bv", - "org.hibernate.validator.internal.constraintvalidators.bv.money", - "org.hibernate.validator.internal.constraintvalidators.bv.notempty", - "org.hibernate.validator.internal.constraintvalidators.bv.number", - "org.hibernate.validator.internal.constraintvalidators.bv.number.bound", - "org.hibernate.validator.internal.constraintvalidators.bv.number.bound.decimal", - "org.hibernate.validator.internal.constraintvalidators.bv.number.sign", - "org.hibernate.validator.internal.constraintvalidators.bv.size", - "org.hibernate.validator.internal.constraintvalidators.bv.time", - "org.hibernate.validator.internal.constraintvalidators.bv.time.future", - "org.hibernate.validator.internal.constraintvalidators.bv.time.futureorpresent", - "org.hibernate.validator.internal.constraintvalidators.bv.time.past", - "org.hibernate.validator.internal.constraintvalidators.bv.time.pastorpresent", - "org.hibernate.validator.internal.constraintvalidators.hv", - "org.hibernate.validator.internal.constraintvalidators.hv.br", - "org.hibernate.validator.internal.constraintvalidators.hv.kor", - "org.hibernate.validator.internal.constraintvalidators.hv.pl", - "org.hibernate.validator.internal.constraintvalidators.hv.ru", - "org.hibernate.validator.internal.constraintvalidators.hv.time", - "org.hibernate.validator.internal.engine", - "org.hibernate.validator.internal.engine.constraintdefinition", - "org.hibernate.validator.internal.engine.constraintvalidation", - "org.hibernate.validator.internal.engine.groups", - "org.hibernate.validator.internal.engine.messageinterpolation", - "org.hibernate.validator.internal.engine.messageinterpolation.el", - "org.hibernate.validator.internal.engine.messageinterpolation.parser", - "org.hibernate.validator.internal.engine.messageinterpolation.util", - "org.hibernate.validator.internal.engine.path", - "org.hibernate.validator.internal.engine.resolver", - "org.hibernate.validator.internal.engine.scripting", - "org.hibernate.validator.internal.engine.validationcontext", - "org.hibernate.validator.internal.engine.valuecontext", - "org.hibernate.validator.internal.engine.valueextraction", - "org.hibernate.validator.internal.metadata", - "org.hibernate.validator.internal.metadata.aggregated", - "org.hibernate.validator.internal.metadata.aggregated.rule", - "org.hibernate.validator.internal.metadata.core", - "org.hibernate.validator.internal.metadata.descriptor", - "org.hibernate.validator.internal.metadata.facets", - "org.hibernate.validator.internal.metadata.location", - "org.hibernate.validator.internal.metadata.provider", - "org.hibernate.validator.internal.metadata.raw", - "org.hibernate.validator.internal.properties", - "org.hibernate.validator.internal.properties.javabean", - "org.hibernate.validator.internal.util", - "org.hibernate.validator.internal.util.actions", - "org.hibernate.validator.internal.util.annotation", - "org.hibernate.validator.internal.util.classhierarchy", - "org.hibernate.validator.internal.util.logging", - "org.hibernate.validator.internal.util.logging.formatter", - "org.hibernate.validator.internal.util.stereotypes", - "org.hibernate.validator.internal.xml", - "org.hibernate.validator.internal.xml.config", - "org.hibernate.validator.internal.xml.mapping", - "org.hibernate.validator.messageinterpolation", - "org.hibernate.validator.metadata", - "org.hibernate.validator.parameternameprovider", - "org.hibernate.validator.path", - "org.hibernate.validator.resourceloading", - "org.hibernate.validator.spi.cfg", - "org.hibernate.validator.spi.group", - "org.hibernate.validator.spi.messageinterpolation", - "org.hibernate.validator.spi.nodenameprovider", - "org.hibernate.validator.spi.properties", - "org.hibernate.validator.spi.resourceloading", - "org.hibernate.validator.spi.scripting" - ], - "org.jacoco:org.jacoco.agent:jar:runtime": [ - "com.vladium.emma.rt", - "org.jacoco.agent.rt", - "org.jacoco.agent.rt.internal_29a6edd", - "org.jacoco.agent.rt.internal_29a6edd.asm", - "org.jacoco.agent.rt.internal_29a6edd.asm.commons", - "org.jacoco.agent.rt.internal_29a6edd.asm.tree", - "org.jacoco.agent.rt.internal_29a6edd.core", - "org.jacoco.agent.rt.internal_29a6edd.core.analysis", - "org.jacoco.agent.rt.internal_29a6edd.core.data", - "org.jacoco.agent.rt.internal_29a6edd.core.instr", - "org.jacoco.agent.rt.internal_29a6edd.core.internal", - "org.jacoco.agent.rt.internal_29a6edd.core.internal.analysis", - "org.jacoco.agent.rt.internal_29a6edd.core.internal.analysis.filter", - "org.jacoco.agent.rt.internal_29a6edd.core.internal.data", - "org.jacoco.agent.rt.internal_29a6edd.core.internal.flow", - "org.jacoco.agent.rt.internal_29a6edd.core.internal.instr", - "org.jacoco.agent.rt.internal_29a6edd.core.runtime", - "org.jacoco.agent.rt.internal_29a6edd.core.tools", - "org.jacoco.agent.rt.internal_29a6edd.output" - ], - "org.jacoco:org.jacoco.cli": [ - "org.jacoco.cli.internal", - "org.jacoco.cli.internal.commands" - ], - "org.jacoco:org.jacoco.core": [ - "org.jacoco.core", - "org.jacoco.core.analysis", - "org.jacoco.core.data", - "org.jacoco.core.instr", - "org.jacoco.core.internal", - "org.jacoco.core.internal.analysis", - "org.jacoco.core.internal.analysis.filter", - "org.jacoco.core.internal.data", - "org.jacoco.core.internal.flow", - "org.jacoco.core.internal.instr", - "org.jacoco.core.runtime", - "org.jacoco.core.tools" - ], - "org.jacoco:org.jacoco.report": [ - "org.jacoco.report", - "org.jacoco.report.check", - "org.jacoco.report.csv", - "org.jacoco.report.html", - "org.jacoco.report.internal", - "org.jacoco.report.internal.html", - "org.jacoco.report.internal.html.index", - "org.jacoco.report.internal.html.page", - "org.jacoco.report.internal.html.resources", - "org.jacoco.report.internal.html.table", - "org.jacoco.report.internal.xml", - "org.jacoco.report.xml" - ], - "org.jboss.logging:jboss-logging": [ - "org.jboss.logging" - ], - "org.jetbrains.kotlin:kotlin-stdlib": [ - "kotlin", - "kotlin.annotation", - "kotlin.collections", - "kotlin.collections.builders", - "kotlin.collections.jdk8", - "kotlin.collections.unsigned", - "kotlin.comparisons", - "kotlin.concurrent", - "kotlin.concurrent.atomics", - "kotlin.concurrent.internal", - "kotlin.contracts", - "kotlin.coroutines", - "kotlin.coroutines.cancellation", - "kotlin.coroutines.intrinsics", - "kotlin.coroutines.jvm.internal", - "kotlin.enums", - "kotlin.experimental", - "kotlin.internal", - "kotlin.internal.jdk7", - "kotlin.internal.jdk8", - "kotlin.io", - "kotlin.io.encoding", - "kotlin.io.path", - "kotlin.jdk7", - "kotlin.js", - "kotlin.jvm", - "kotlin.jvm.functions", - "kotlin.jvm.internal", - "kotlin.jvm.internal.markers", - "kotlin.jvm.internal.unsafe", - "kotlin.jvm.jdk8", - "kotlin.jvm.optionals", - "kotlin.math", - "kotlin.properties", - "kotlin.random", - "kotlin.random.jdk8", - "kotlin.ranges", - "kotlin.reflect", - "kotlin.sequences", - "kotlin.streams.jdk8", - "kotlin.system", - "kotlin.text", - "kotlin.text.jdk8", - "kotlin.time", - "kotlin.time.jdk8", - "kotlin.uuid" - ], - "org.jetbrains:annotations": [ - "org.intellij.lang.annotations", - "org.jetbrains.annotations" - ], - "org.jspecify:jspecify": [ - "org.jspecify.annotations" - ], - "org.junit.jupiter:junit-jupiter-api": [ - "org.junit.jupiter.api", - "org.junit.jupiter.api.condition", - "org.junit.jupiter.api.extension", - "org.junit.jupiter.api.extension.support", - "org.junit.jupiter.api.function", - "org.junit.jupiter.api.io", - "org.junit.jupiter.api.parallel", - "org.junit.jupiter.api.util" - ], - "org.junit.jupiter:junit-jupiter-engine": [ - "org.junit.jupiter.engine", - "org.junit.jupiter.engine.config", - "org.junit.jupiter.engine.descriptor", - "org.junit.jupiter.engine.discovery", - "org.junit.jupiter.engine.discovery.predicates", - "org.junit.jupiter.engine.execution", - "org.junit.jupiter.engine.extension", - "org.junit.jupiter.engine.support" - ], - "org.junit.jupiter:junit-jupiter-params": [ - "org.junit.jupiter.params", - "org.junit.jupiter.params.aggregator", - "org.junit.jupiter.params.converter", - "org.junit.jupiter.params.provider", - "org.junit.jupiter.params.shadow.de.siegmar.fastcsv.reader", - "org.junit.jupiter.params.shadow.de.siegmar.fastcsv.util", - "org.junit.jupiter.params.shadow.de.siegmar.fastcsv.writer", - "org.junit.jupiter.params.support" - ], - "org.junit.platform:junit-platform-commons": [ - "org.junit.platform.commons", - "org.junit.platform.commons.annotation", - "org.junit.platform.commons.function", - "org.junit.platform.commons.io", - "org.junit.platform.commons.logging", - "org.junit.platform.commons.support", - "org.junit.platform.commons.support.conversion", - "org.junit.platform.commons.support.scanning", - "org.junit.platform.commons.util" - ], - "org.junit.platform:junit-platform-console-standalone": [ - "junit.extensions", - "junit.framework", - "junit.runner", - "junit.textui", - "org.apiguardian.api", - "org.hamcrest", - "org.hamcrest.core", - "org.hamcrest.internal", - "org.junit", - "org.junit.experimental", - "org.junit.experimental.categories", - "org.junit.experimental.max", - "org.junit.experimental.results", - "org.junit.experimental.runners", - "org.junit.experimental.theories", - "org.junit.experimental.theories.internal", - "org.junit.experimental.theories.suppliers", - "org.junit.function", - "org.junit.internal", - "org.junit.internal.builders", - "org.junit.internal.management", - "org.junit.internal.matchers", - "org.junit.internal.requests", - "org.junit.internal.runners", - "org.junit.internal.runners.model", - "org.junit.internal.runners.rules", - "org.junit.internal.runners.statements", - "org.junit.jupiter.api", - "org.junit.jupiter.api.condition", - "org.junit.jupiter.api.extension", - "org.junit.jupiter.api.extension.support", - "org.junit.jupiter.api.function", - "org.junit.jupiter.api.io", - "org.junit.jupiter.api.parallel", - "org.junit.jupiter.api.util", - "org.junit.jupiter.engine", - "org.junit.jupiter.engine.config", - "org.junit.jupiter.engine.descriptor", - "org.junit.jupiter.engine.discovery", - "org.junit.jupiter.engine.discovery.predicates", - "org.junit.jupiter.engine.execution", - "org.junit.jupiter.engine.extension", - "org.junit.jupiter.engine.support", - "org.junit.jupiter.params", - "org.junit.jupiter.params.aggregator", - "org.junit.jupiter.params.converter", - "org.junit.jupiter.params.provider", - "org.junit.jupiter.params.shadow.de.siegmar.fastcsv.reader", - "org.junit.jupiter.params.shadow.de.siegmar.fastcsv.util", - "org.junit.jupiter.params.shadow.de.siegmar.fastcsv.writer", - "org.junit.jupiter.params.support", - "org.junit.matchers", - "org.junit.platform.commons", - "org.junit.platform.commons.annotation", - "org.junit.platform.commons.function", - "org.junit.platform.commons.io", - "org.junit.platform.commons.logging", - "org.junit.platform.commons.support", - "org.junit.platform.commons.support.conversion", - "org.junit.platform.commons.support.scanning", - "org.junit.platform.commons.util", - "org.junit.platform.console", - "org.junit.platform.console.command", - "org.junit.platform.console.options", - "org.junit.platform.console.output", - "org.junit.platform.console.shadow.picocli", - "org.junit.platform.engine", - "org.junit.platform.engine.discovery", - "org.junit.platform.engine.reporting", - "org.junit.platform.engine.support.config", - "org.junit.platform.engine.support.descriptor", - "org.junit.platform.engine.support.discovery", - "org.junit.platform.engine.support.hierarchical", - "org.junit.platform.engine.support.store", - "org.junit.platform.launcher", - "org.junit.platform.launcher.core", - "org.junit.platform.launcher.jfr", - "org.junit.platform.launcher.listeners", - "org.junit.platform.launcher.listeners.discovery", - "org.junit.platform.launcher.listeners.session", - "org.junit.platform.launcher.tagexpression", - "org.junit.platform.reporting", - "org.junit.platform.reporting.legacy", - "org.junit.platform.reporting.legacy.xml", - "org.junit.platform.reporting.open.xml", - "org.junit.platform.reporting.shadow.org.opentest4j.reporting.events.api", - "org.junit.platform.reporting.shadow.org.opentest4j.reporting.events.core", - "org.junit.platform.reporting.shadow.org.opentest4j.reporting.events.git", - "org.junit.platform.reporting.shadow.org.opentest4j.reporting.events.java", - "org.junit.platform.reporting.shadow.org.opentest4j.reporting.events.root", - "org.junit.platform.reporting.shadow.org.opentest4j.reporting.schema", - "org.junit.platform.suite.api", - "org.junit.platform.suite.engine", - "org.junit.rules", - "org.junit.runner", - "org.junit.runner.manipulation", - "org.junit.runner.notification", - "org.junit.runners", - "org.junit.runners.model", - "org.junit.runners.parameterized", - "org.junit.validator", - "org.junit.vintage.engine", - "org.junit.vintage.engine.descriptor", - "org.junit.vintage.engine.discovery", - "org.junit.vintage.engine.execution", - "org.junit.vintage.engine.support", - "org.opentest4j", - "org.opentest4j.reporting.tooling.spi.htmlreport" - ], - "org.junit.platform:junit-platform-engine": [ - "org.junit.platform.engine", - "org.junit.platform.engine.discovery", - "org.junit.platform.engine.reporting", - "org.junit.platform.engine.support.config", - "org.junit.platform.engine.support.descriptor", - "org.junit.platform.engine.support.discovery", - "org.junit.platform.engine.support.hierarchical", - "org.junit.platform.engine.support.store" - ], - "org.latencyutils:LatencyUtils": [ - "org.LatencyUtils" - ], - "org.mockito:mockito-core": [ - "org.mockito", - "org.mockito.configuration", - "org.mockito.creation.instance", - "org.mockito.exceptions.base", - "org.mockito.exceptions.misusing", - "org.mockito.exceptions.stacktrace", - "org.mockito.exceptions.verification", - "org.mockito.exceptions.verification.junit", - "org.mockito.exceptions.verification.opentest4j", - "org.mockito.hamcrest", - "org.mockito.internal", - "org.mockito.internal.configuration", - "org.mockito.internal.configuration.injection", - "org.mockito.internal.configuration.injection.filter", - "org.mockito.internal.configuration.injection.scanner", - "org.mockito.internal.configuration.plugins", - "org.mockito.internal.creation", - "org.mockito.internal.creation.bytebuddy", - "org.mockito.internal.creation.bytebuddy.access", - "org.mockito.internal.creation.bytebuddy.codegen", - "org.mockito.internal.creation.instance", - "org.mockito.internal.creation.proxy", - "org.mockito.internal.creation.settings", - "org.mockito.internal.creation.util", - "org.mockito.internal.debugging", - "org.mockito.internal.exceptions", - "org.mockito.internal.exceptions.stacktrace", - "org.mockito.internal.exceptions.util", - "org.mockito.internal.framework", - "org.mockito.internal.hamcrest", - "org.mockito.internal.handler", - "org.mockito.internal.invocation", - "org.mockito.internal.invocation.finder", - "org.mockito.internal.invocation.mockref", - "org.mockito.internal.junit", - "org.mockito.internal.listeners", - "org.mockito.internal.matchers", - "org.mockito.internal.matchers.apachecommons", - "org.mockito.internal.matchers.text", - "org.mockito.internal.progress", - "org.mockito.internal.reporting", - "org.mockito.internal.runners", - "org.mockito.internal.runners.util", - "org.mockito.internal.session", - "org.mockito.internal.stubbing", - "org.mockito.internal.stubbing.answers", - "org.mockito.internal.stubbing.defaultanswers", - "org.mockito.internal.util", - "org.mockito.internal.util.collections", - "org.mockito.internal.util.concurrent", - "org.mockito.internal.util.io", - "org.mockito.internal.util.reflection", - "org.mockito.internal.verification", - "org.mockito.internal.verification.api", - "org.mockito.internal.verification.argumentmatching", - "org.mockito.internal.verification.checkers", - "org.mockito.invocation", - "org.mockito.junit", - "org.mockito.listeners", - "org.mockito.mock", - "org.mockito.plugins", - "org.mockito.quality", - "org.mockito.session", - "org.mockito.stubbing", - "org.mockito.verification" - ], - "org.mockito:mockito-junit-jupiter": [ - "org.mockito.junit.jupiter", - "org.mockito.junit.jupiter.resolver" - ], - "org.objenesis:objenesis": [ - "org.objenesis", - "org.objenesis.instantiator", - "org.objenesis.instantiator.android", - "org.objenesis.instantiator.annotations", - "org.objenesis.instantiator.basic", - "org.objenesis.instantiator.gcj", - "org.objenesis.instantiator.perc", - "org.objenesis.instantiator.sun", - "org.objenesis.instantiator.util", - "org.objenesis.strategy" - ], - "org.opentest4j:opentest4j": [ - "org.opentest4j" - ], - "org.ow2.asm:asm": [ - "org.objectweb.asm", - "org.objectweb.asm.signature" - ], - "org.ow2.asm:asm-analysis": [ - "org.objectweb.asm.tree.analysis" - ], - "org.ow2.asm:asm-commons": [ - "org.objectweb.asm.commons" - ], - "org.ow2.asm:asm-tree": [ - "org.objectweb.asm.tree" - ], - "org.ow2.asm:asm-util": [ - "org.objectweb.asm.util" - ], - "org.projectlombok:lombok": [ - "lombok", - "lombok.delombok.ant", - "lombok.experimental", - "lombok.extern.apachecommons", - "lombok.extern.flogger", - "lombok.extern.jackson", - "lombok.extern.java", - "lombok.extern.jbosslog", - "lombok.extern.log4j", - "lombok.extern.slf4j", - "lombok.javac.apt", - "lombok.launch" - ], - "org.reactivestreams:reactive-streams": [ - "org.reactivestreams" - ], - "org.rnorth.duct-tape:duct-tape": [ - "org.rnorth.ducttape", - "org.rnorth.ducttape.circuitbreakers", - "org.rnorth.ducttape.inconsistents", - "org.rnorth.ducttape.ratelimits", - "org.rnorth.ducttape.timeouts", - "org.rnorth.ducttape.unreliables" - ], - "org.skyscreamer:jsonassert": [ - "org.json", - "org.skyscreamer.jsonassert", - "org.skyscreamer.jsonassert.comparator" - ], - "org.slf4j:jul-to-slf4j": [ - "org.slf4j.bridge" - ], - "org.slf4j:slf4j-api": [ - "org.slf4j", - "org.slf4j.event", - "org.slf4j.helpers", - "org.slf4j.spi" - ], - "org.springdoc:springdoc-openapi-starter-common": [ - "org.springdoc.api", - "org.springdoc.core.annotations", - "org.springdoc.core.conditions", - "org.springdoc.core.configuration", - "org.springdoc.core.configuration.hints", - "org.springdoc.core.configuration.oauth2", - "org.springdoc.core.configurer", - "org.springdoc.core.converters", - "org.springdoc.core.converters.models", - "org.springdoc.core.customizers", - "org.springdoc.core.data", - "org.springdoc.core.discoverer", - "org.springdoc.core.events", - "org.springdoc.core.extractor", - "org.springdoc.core.filters", - "org.springdoc.core.fn", - "org.springdoc.core.fn.builders.apiresponse", - "org.springdoc.core.fn.builders.arrayschema", - "org.springdoc.core.fn.builders.content", - "org.springdoc.core.fn.builders.discriminatormapping", - "org.springdoc.core.fn.builders.encoding", - "org.springdoc.core.fn.builders.exampleobject", - "org.springdoc.core.fn.builders.extension", - "org.springdoc.core.fn.builders.extensionproperty", - "org.springdoc.core.fn.builders.externaldocumentation", - "org.springdoc.core.fn.builders.header", - "org.springdoc.core.fn.builders.link", - "org.springdoc.core.fn.builders.linkparameter", - "org.springdoc.core.fn.builders.operation", - "org.springdoc.core.fn.builders.parameter", - "org.springdoc.core.fn.builders.requestbody", - "org.springdoc.core.fn.builders.schema", - "org.springdoc.core.fn.builders.securityrequirement", - "org.springdoc.core.fn.builders.server", - "org.springdoc.core.fn.builders.servervariable", - "org.springdoc.core.mixins", - "org.springdoc.core.models", - "org.springdoc.core.properties", - "org.springdoc.core.providers", - "org.springdoc.core.service", - "org.springdoc.core.utils", - "org.springdoc.core.versions", - "org.springdoc.scalar", - "org.springdoc.ui" - ], - "org.springdoc:springdoc-openapi-starter-webflux-api": [ - "org.springdoc.webflux.api", - "org.springdoc.webflux.core.configuration", - "org.springdoc.webflux.core.configuration.hints", - "org.springdoc.webflux.core.fn", - "org.springdoc.webflux.core.providers", - "org.springdoc.webflux.core.service", - "org.springdoc.webflux.core.visitor" - ], - "org.springdoc:springdoc-openapi-starter-webmvc-api": [ - "org.springdoc.webmvc.api", - "org.springdoc.webmvc.core.configuration", - "org.springdoc.webmvc.core.configuration.hints", - "org.springdoc.webmvc.core.fn", - "org.springdoc.webmvc.core.providers", - "org.springdoc.webmvc.core.service" - ], - "org.springframework.boot:spring-boot": [ - "org.springframework.boot", - "org.springframework.boot.admin", - "org.springframework.boot.ansi", - "org.springframework.boot.availability", - "org.springframework.boot.bootstrap", - "org.springframework.boot.builder", - "org.springframework.boot.cloud", - "org.springframework.boot.context", - "org.springframework.boot.context.annotation", - "org.springframework.boot.context.config", - "org.springframework.boot.context.event", - "org.springframework.boot.context.logging", - "org.springframework.boot.context.metrics.buffering", - "org.springframework.boot.context.properties", - "org.springframework.boot.context.properties.bind", - "org.springframework.boot.context.properties.bind.handler", - "org.springframework.boot.context.properties.bind.validation", - "org.springframework.boot.context.properties.source", - "org.springframework.boot.convert", - "org.springframework.boot.diagnostics", - "org.springframework.boot.diagnostics.analyzer", - "org.springframework.boot.env", - "org.springframework.boot.info", - "org.springframework.boot.io", - "org.springframework.boot.json", - "org.springframework.boot.logging", - "org.springframework.boot.logging.java", - "org.springframework.boot.logging.log4j2", - "org.springframework.boot.logging.logback", - "org.springframework.boot.logging.structured", - "org.springframework.boot.origin", - "org.springframework.boot.retry", - "org.springframework.boot.ssl", - "org.springframework.boot.ssl.jks", - "org.springframework.boot.ssl.pem", - "org.springframework.boot.support", - "org.springframework.boot.system", - "org.springframework.boot.task", - "org.springframework.boot.thread", - "org.springframework.boot.util", - "org.springframework.boot.validation", - "org.springframework.boot.validation.beanvalidation", - "org.springframework.boot.web.context.reactive", - "org.springframework.boot.web.context.servlet", - "org.springframework.boot.web.error", - "org.springframework.boot.web.servlet", - "org.springframework.boot.web.servlet.support" - ], - "org.springframework.boot:spring-boot-actuator": [ - "org.springframework.boot.actuate.audit", - "org.springframework.boot.actuate.audit.listener", - "org.springframework.boot.actuate.beans", - "org.springframework.boot.actuate.context", - "org.springframework.boot.actuate.context.properties", - "org.springframework.boot.actuate.endpoint", - "org.springframework.boot.actuate.endpoint.annotation", - "org.springframework.boot.actuate.endpoint.invoke", - "org.springframework.boot.actuate.endpoint.invoke.convert", - "org.springframework.boot.actuate.endpoint.invoke.reflect", - "org.springframework.boot.actuate.endpoint.invoker.cache", - "org.springframework.boot.actuate.endpoint.jackson", - "org.springframework.boot.actuate.endpoint.jmx", - "org.springframework.boot.actuate.endpoint.jmx.annotation", - "org.springframework.boot.actuate.endpoint.web", - "org.springframework.boot.actuate.endpoint.web.annotation", - "org.springframework.boot.actuate.env", - "org.springframework.boot.actuate.info", - "org.springframework.boot.actuate.logging", - "org.springframework.boot.actuate.management", - "org.springframework.boot.actuate.sbom", - "org.springframework.boot.actuate.scheduling", - "org.springframework.boot.actuate.security", - "org.springframework.boot.actuate.startup", - "org.springframework.boot.actuate.web.exchanges", - "org.springframework.boot.actuate.web.mappings" - ], - "org.springframework.boot:spring-boot-actuator-autoconfigure": [ - "org.springframework.boot.actuate.autoconfigure", - "org.springframework.boot.actuate.autoconfigure.audit", - "org.springframework.boot.actuate.autoconfigure.beans", - "org.springframework.boot.actuate.autoconfigure.condition", - "org.springframework.boot.actuate.autoconfigure.context", - "org.springframework.boot.actuate.autoconfigure.context.properties", - "org.springframework.boot.actuate.autoconfigure.endpoint", - "org.springframework.boot.actuate.autoconfigure.endpoint.condition", - "org.springframework.boot.actuate.autoconfigure.endpoint.expose", - "org.springframework.boot.actuate.autoconfigure.endpoint.jackson", - "org.springframework.boot.actuate.autoconfigure.endpoint.jmx", - "org.springframework.boot.actuate.autoconfigure.endpoint.web", - "org.springframework.boot.actuate.autoconfigure.env", - "org.springframework.boot.actuate.autoconfigure.info", - "org.springframework.boot.actuate.autoconfigure.logging", - "org.springframework.boot.actuate.autoconfigure.management", - "org.springframework.boot.actuate.autoconfigure.sbom", - "org.springframework.boot.actuate.autoconfigure.scheduling", - "org.springframework.boot.actuate.autoconfigure.startup", - "org.springframework.boot.actuate.autoconfigure.web", - "org.springframework.boot.actuate.autoconfigure.web.exchanges", - "org.springframework.boot.actuate.autoconfigure.web.mappings", - "org.springframework.boot.actuate.autoconfigure.web.server" - ], - "org.springframework.boot:spring-boot-autoconfigure": [ - "org.springframework.boot.autoconfigure", - "org.springframework.boot.autoconfigure.admin", - "org.springframework.boot.autoconfigure.aop", - "org.springframework.boot.autoconfigure.availability", - "org.springframework.boot.autoconfigure.cache", - "org.springframework.boot.autoconfigure.condition", - "org.springframework.boot.autoconfigure.container", - "org.springframework.boot.autoconfigure.context", - "org.springframework.boot.autoconfigure.data", - "org.springframework.boot.autoconfigure.diagnostics.analyzer", - "org.springframework.boot.autoconfigure.info", - "org.springframework.boot.autoconfigure.jmx", - "org.springframework.boot.autoconfigure.logging", - "org.springframework.boot.autoconfigure.preinitialize", - "org.springframework.boot.autoconfigure.service.connection", - "org.springframework.boot.autoconfigure.ssl", - "org.springframework.boot.autoconfigure.task", - "org.springframework.boot.autoconfigure.template", - "org.springframework.boot.autoconfigure.web", - "org.springframework.boot.autoconfigure.web.format" - ], - "org.springframework.boot:spring-boot-cassandra": [ - "org.springframework.boot.cassandra.autoconfigure", - "org.springframework.boot.cassandra.autoconfigure.health", - "org.springframework.boot.cassandra.docker.compose", - "org.springframework.boot.cassandra.health", - "org.springframework.boot.cassandra.testcontainers" - ], - "org.springframework.boot:spring-boot-data-cassandra": [ - "org.springframework.boot.data.cassandra.autoconfigure" - ], - "org.springframework.boot:spring-boot-data-cassandra-test": [ - "org.springframework.boot.data.cassandra.test.autoconfigure" - ], - "org.springframework.boot:spring-boot-data-commons": [ - "org.springframework.boot.data.autoconfigure.metrics", - "org.springframework.boot.data.autoconfigure.web", - "org.springframework.boot.data.metrics" - ], - "org.springframework.boot:spring-boot-health": [ - "org.springframework.boot.health.actuate.endpoint", - "org.springframework.boot.health.application", - "org.springframework.boot.health.autoconfigure.actuate.endpoint", - "org.springframework.boot.health.autoconfigure.application", - "org.springframework.boot.health.autoconfigure.contributor", - "org.springframework.boot.health.autoconfigure.registry", - "org.springframework.boot.health.contributor", - "org.springframework.boot.health.registry" - ], - "org.springframework.boot:spring-boot-http-client": [ - "org.springframework.boot.http.client", - "org.springframework.boot.http.client.autoconfigure", - "org.springframework.boot.http.client.autoconfigure.imperative", - "org.springframework.boot.http.client.autoconfigure.metrics", - "org.springframework.boot.http.client.autoconfigure.reactive", - "org.springframework.boot.http.client.autoconfigure.service", - "org.springframework.boot.http.client.reactive" - ], - "org.springframework.boot:spring-boot-http-codec": [ - "org.springframework.boot.http.codec", - "org.springframework.boot.http.codec.autoconfigure" - ], - "org.springframework.boot:spring-boot-http-converter": [ - "org.springframework.boot.http.converter.autoconfigure" - ], - "org.springframework.boot:spring-boot-jackson": [ - "org.springframework.boot.jackson", - "org.springframework.boot.jackson.autoconfigure" - ], - "org.springframework.boot:spring-boot-micrometer-metrics": [ - "org.springframework.boot.micrometer.metrics", - "org.springframework.boot.micrometer.metrics.actuate.endpoint", - "org.springframework.boot.micrometer.metrics.autoconfigure", - "org.springframework.boot.micrometer.metrics.autoconfigure.export", - "org.springframework.boot.micrometer.metrics.autoconfigure.export.appoptics", - "org.springframework.boot.micrometer.metrics.autoconfigure.export.atlas", - "org.springframework.boot.micrometer.metrics.autoconfigure.export.datadog", - "org.springframework.boot.micrometer.metrics.autoconfigure.export.dynatrace", - "org.springframework.boot.micrometer.metrics.autoconfigure.export.elastic", - "org.springframework.boot.micrometer.metrics.autoconfigure.export.ganglia", - "org.springframework.boot.micrometer.metrics.autoconfigure.export.graphite", - "org.springframework.boot.micrometer.metrics.autoconfigure.export.humio", - "org.springframework.boot.micrometer.metrics.autoconfigure.export.influx", - "org.springframework.boot.micrometer.metrics.autoconfigure.export.jmx", - "org.springframework.boot.micrometer.metrics.autoconfigure.export.kairos", - "org.springframework.boot.micrometer.metrics.autoconfigure.export.newrelic", - "org.springframework.boot.micrometer.metrics.autoconfigure.export.otlp", - "org.springframework.boot.micrometer.metrics.autoconfigure.export.prometheus", - "org.springframework.boot.micrometer.metrics.autoconfigure.export.properties", - "org.springframework.boot.micrometer.metrics.autoconfigure.export.simple", - "org.springframework.boot.micrometer.metrics.autoconfigure.export.stackdriver", - "org.springframework.boot.micrometer.metrics.autoconfigure.export.statsd", - "org.springframework.boot.micrometer.metrics.autoconfigure.jvm", - "org.springframework.boot.micrometer.metrics.autoconfigure.logging.log4j2", - "org.springframework.boot.micrometer.metrics.autoconfigure.logging.logback", - "org.springframework.boot.micrometer.metrics.autoconfigure.ssl", - "org.springframework.boot.micrometer.metrics.autoconfigure.startup", - "org.springframework.boot.micrometer.metrics.autoconfigure.system", - "org.springframework.boot.micrometer.metrics.autoconfigure.task", - "org.springframework.boot.micrometer.metrics.docker.compose.otlp", - "org.springframework.boot.micrometer.metrics.export.prometheus", - "org.springframework.boot.micrometer.metrics.export.prometheus.endpoint", - "org.springframework.boot.micrometer.metrics.startup", - "org.springframework.boot.micrometer.metrics.system", - "org.springframework.boot.micrometer.metrics.testcontainers.otlp" - ], - "org.springframework.boot:spring-boot-micrometer-metrics-test": [ - "org.springframework.boot.micrometer.metrics.test.autoconfigure" - ], - "org.springframework.boot:spring-boot-micrometer-observation": [ - "org.springframework.boot.micrometer.observation.autoconfigure" - ], - "org.springframework.boot:spring-boot-micrometer-tracing": [ - "org.springframework.boot.micrometer.tracing.autoconfigure", - "org.springframework.boot.micrometer.tracing.autoconfigure.prometheus" - ], - "org.springframework.boot:spring-boot-micrometer-tracing-opentelemetry": [ - "org.springframework.boot.micrometer.tracing.opentelemetry.autoconfigure", - "org.springframework.boot.micrometer.tracing.opentelemetry.autoconfigure.otlp", - "org.springframework.boot.micrometer.tracing.opentelemetry.autoconfigure.zipkin", - "org.springframework.boot.micrometer.tracing.opentelemetry.docker.compose.otlp", - "org.springframework.boot.micrometer.tracing.opentelemetry.testcontainers.otlp" - ], - "org.springframework.boot:spring-boot-netty": [ - "org.springframework.boot.netty.autoconfigure" - ], - "org.springframework.boot:spring-boot-opentelemetry": [ - "org.springframework.boot.opentelemetry.autoconfigure", - "org.springframework.boot.opentelemetry.autoconfigure.logging", - "org.springframework.boot.opentelemetry.autoconfigure.logging.otlp", - "org.springframework.boot.opentelemetry.docker.compose", - "org.springframework.boot.opentelemetry.testcontainers" - ], - "org.springframework.boot:spring-boot-persistence": [ - "org.springframework.boot.persistence.autoconfigure" - ], - "org.springframework.boot:spring-boot-reactor": [ - "org.springframework.boot.reactor", - "org.springframework.boot.reactor.autoconfigure" - ], - "org.springframework.boot:spring-boot-reactor-netty": [ - "org.springframework.boot.reactor.netty", - "org.springframework.boot.reactor.netty.autoconfigure", - "org.springframework.boot.reactor.netty.autoconfigure.actuate.web.server" - ], - "org.springframework.boot:spring-boot-restclient": [ - "org.springframework.boot.restclient", - "org.springframework.boot.restclient.autoconfigure", - "org.springframework.boot.restclient.autoconfigure.service", - "org.springframework.boot.restclient.observation" - ], - "org.springframework.boot:spring-boot-resttestclient": [ - "org.springframework.boot.resttestclient", - "org.springframework.boot.resttestclient.autoconfigure" - ], - "org.springframework.boot:spring-boot-security": [ - "org.springframework.boot.security.autoconfigure", - "org.springframework.boot.security.autoconfigure.actuate.web.reactive", - "org.springframework.boot.security.autoconfigure.actuate.web.servlet", - "org.springframework.boot.security.autoconfigure.rsocket", - "org.springframework.boot.security.autoconfigure.web", - "org.springframework.boot.security.autoconfigure.web.reactive", - "org.springframework.boot.security.autoconfigure.web.servlet", - "org.springframework.boot.security.web.reactive", - "org.springframework.boot.security.web.servlet" - ], - "org.springframework.boot:spring-boot-security-oauth2-client": [ - "org.springframework.boot.security.oauth2.client.autoconfigure", - "org.springframework.boot.security.oauth2.client.autoconfigure.reactive", - "org.springframework.boot.security.oauth2.client.autoconfigure.servlet" - ], - "org.springframework.boot:spring-boot-security-oauth2-resource-server": [ - "org.springframework.boot.security.oauth2.server.resource.autoconfigure", - "org.springframework.boot.security.oauth2.server.resource.autoconfigure.reactive", - "org.springframework.boot.security.oauth2.server.resource.autoconfigure.servlet" - ], - "org.springframework.boot:spring-boot-security-test": [ - "org.springframework.boot.security.test.autoconfigure.webflux", - "org.springframework.boot.security.test.autoconfigure.webmvc" - ], - "org.springframework.boot:spring-boot-servlet": [ - "org.springframework.boot.servlet", - "org.springframework.boot.servlet.actuate.web.exchanges", - "org.springframework.boot.servlet.actuate.web.mappings", - "org.springframework.boot.servlet.autoconfigure", - "org.springframework.boot.servlet.autoconfigure.actuate.web", - "org.springframework.boot.servlet.autoconfigure.actuate.web.exchanges", - "org.springframework.boot.servlet.autoconfigure.actuate.web.mappings", - "org.springframework.boot.servlet.filter" - ], - "org.springframework.boot:spring-boot-test": [ - "org.springframework.boot.test.context", - "org.springframework.boot.test.context.assertj", - "org.springframework.boot.test.context.filter", - "org.springframework.boot.test.context.filter.annotation", - "org.springframework.boot.test.context.runner", - "org.springframework.boot.test.http.client", - "org.springframework.boot.test.http.server", - "org.springframework.boot.test.json", - "org.springframework.boot.test.mock.web", - "org.springframework.boot.test.system", - "org.springframework.boot.test.util", - "org.springframework.boot.test.web.htmlunit", - "org.springframework.boot.test.web.server" - ], - "org.springframework.boot:spring-boot-test-autoconfigure": [ - "org.springframework.boot.test.autoconfigure", - "org.springframework.boot.test.autoconfigure.jdbc", - "org.springframework.boot.test.autoconfigure.json" - ], - "org.springframework.boot:spring-boot-tomcat": [ - "org.springframework.boot.tomcat", - "org.springframework.boot.tomcat.autoconfigure", - "org.springframework.boot.tomcat.autoconfigure.actuate.web.server", - "org.springframework.boot.tomcat.autoconfigure.metrics", - "org.springframework.boot.tomcat.autoconfigure.reactive", - "org.springframework.boot.tomcat.autoconfigure.servlet", - "org.springframework.boot.tomcat.metrics", - "org.springframework.boot.tomcat.reactive", - "org.springframework.boot.tomcat.servlet" - ], - "org.springframework.boot:spring-boot-validation": [ - "org.springframework.boot.validation.autoconfigure" - ], - "org.springframework.boot:spring-boot-web-server": [ - "org.springframework.boot.web.server", - "org.springframework.boot.web.server.autoconfigure", - "org.springframework.boot.web.server.autoconfigure.reactive", - "org.springframework.boot.web.server.autoconfigure.servlet", - "org.springframework.boot.web.server.context", - "org.springframework.boot.web.server.reactive", - "org.springframework.boot.web.server.reactive.context", - "org.springframework.boot.web.server.servlet", - "org.springframework.boot.web.server.servlet.context" - ], - "org.springframework.boot:spring-boot-webclient": [ - "org.springframework.boot.webclient", - "org.springframework.boot.webclient.autoconfigure", - "org.springframework.boot.webclient.autoconfigure.service", - "org.springframework.boot.webclient.observation" - ], - "org.springframework.boot:spring-boot-webflux": [ - "org.springframework.boot.webflux", - "org.springframework.boot.webflux.actuate.endpoint.web", - "org.springframework.boot.webflux.actuate.web.exchanges", - "org.springframework.boot.webflux.actuate.web.mappings", - "org.springframework.boot.webflux.autoconfigure", - "org.springframework.boot.webflux.autoconfigure.actuate.endpoint.web", - "org.springframework.boot.webflux.autoconfigure.actuate.web", - "org.springframework.boot.webflux.autoconfigure.actuate.web.exchanges", - "org.springframework.boot.webflux.autoconfigure.actuate.web.mappings", - "org.springframework.boot.webflux.autoconfigure.error", - "org.springframework.boot.webflux.error", - "org.springframework.boot.webflux.filter" - ], - "org.springframework.boot:spring-boot-webflux-test": [ - "org.springframework.boot.webflux.test.autoconfigure" - ], - "org.springframework.boot:spring-boot-webmvc": [ - "org.springframework.boot.webmvc", - "org.springframework.boot.webmvc.actuate.endpoint.web", - "org.springframework.boot.webmvc.actuate.web.mappings", - "org.springframework.boot.webmvc.autoconfigure", - "org.springframework.boot.webmvc.autoconfigure.actuate.endpoint.web", - "org.springframework.boot.webmvc.autoconfigure.actuate.web", - "org.springframework.boot.webmvc.autoconfigure.actuate.web.mappings", - "org.springframework.boot.webmvc.autoconfigure.error", - "org.springframework.boot.webmvc.error" - ], - "org.springframework.boot:spring-boot-webmvc-test": [ - "org.springframework.boot.webmvc.test.autoconfigure" - ], - "org.springframework.boot:spring-boot-webtestclient": [ - "org.springframework.boot.webtestclient.autoconfigure" - ], - "org.springframework.cloud:spring-cloud-commons": [ - "org.springframework.cloud.client", - "org.springframework.cloud.client.actuator", - "org.springframework.cloud.client.circuitbreaker", - "org.springframework.cloud.client.circuitbreaker.httpservice", - "org.springframework.cloud.client.circuitbreaker.observation", - "org.springframework.cloud.client.discovery", - "org.springframework.cloud.client.discovery.composite", - "org.springframework.cloud.client.discovery.composite.reactive", - "org.springframework.cloud.client.discovery.event", - "org.springframework.cloud.client.discovery.health", - "org.springframework.cloud.client.discovery.health.reactive", - "org.springframework.cloud.client.discovery.simple", - "org.springframework.cloud.client.discovery.simple.reactive", - "org.springframework.cloud.client.hypermedia", - "org.springframework.cloud.client.loadbalancer", - "org.springframework.cloud.client.loadbalancer.reactive", - "org.springframework.cloud.client.serviceregistry", - "org.springframework.cloud.client.serviceregistry.endpoint", - "org.springframework.cloud.commons", - "org.springframework.cloud.commons.config", - "org.springframework.cloud.commons.publisher", - "org.springframework.cloud.commons.security", - "org.springframework.cloud.commons.util", - "org.springframework.cloud.configuration" - ], - "org.springframework.cloud:spring-cloud-context": [ - "org.springframework.cloud.autoconfigure", - "org.springframework.cloud.bootstrap", - "org.springframework.cloud.bootstrap.config", - "org.springframework.cloud.bootstrap.encrypt", - "org.springframework.cloud.bootstrap.support", - "org.springframework.cloud.context", - "org.springframework.cloud.context.config", - "org.springframework.cloud.context.config.annotation", - "org.springframework.cloud.context.encrypt", - "org.springframework.cloud.context.environment", - "org.springframework.cloud.context.named", - "org.springframework.cloud.context.properties", - "org.springframework.cloud.context.refresh", - "org.springframework.cloud.context.restart", - "org.springframework.cloud.context.scope", - "org.springframework.cloud.context.scope.refresh", - "org.springframework.cloud.context.scope.thread", - "org.springframework.cloud.endpoint", - "org.springframework.cloud.endpoint.event", - "org.springframework.cloud.env", - "org.springframework.cloud.health", - "org.springframework.cloud.logging", - "org.springframework.cloud.util", - "org.springframework.cloud.util.random" - ], - "org.springframework.cloud:spring-cloud-starter-bootstrap": [ - "org.springframework.cloud.bootstrap.marker" - ], - "org.springframework.data:spring-data-cassandra": [ - "org.springframework.data.cassandra", - "org.springframework.data.cassandra.aot", - "org.springframework.data.cassandra.config", - "org.springframework.data.cassandra.core", - "org.springframework.data.cassandra.core.convert", - "org.springframework.data.cassandra.core.cql", - "org.springframework.data.cassandra.core.cql.converter", - "org.springframework.data.cassandra.core.cql.generator", - "org.springframework.data.cassandra.core.cql.keyspace", - "org.springframework.data.cassandra.core.cql.session", - "org.springframework.data.cassandra.core.cql.session.init", - "org.springframework.data.cassandra.core.cql.session.lookup", - "org.springframework.data.cassandra.core.cql.util", - "org.springframework.data.cassandra.core.mapping", - "org.springframework.data.cassandra.core.mapping.event", - "org.springframework.data.cassandra.core.query", - "org.springframework.data.cassandra.observability", - "org.springframework.data.cassandra.repository", - "org.springframework.data.cassandra.repository.aot", - "org.springframework.data.cassandra.repository.cdi", - "org.springframework.data.cassandra.repository.config", - "org.springframework.data.cassandra.repository.query", - "org.springframework.data.cassandra.repository.support", - "org.springframework.data.cassandra.util" - ], - "org.springframework.data:spring-data-commons": [ - "org.springframework.data.annotation", - "org.springframework.data.aot", - "org.springframework.data.auditing", - "org.springframework.data.auditing.config", - "org.springframework.data.config", - "org.springframework.data.convert", - "org.springframework.data.core", - "org.springframework.data.crossstore", - "org.springframework.data.domain", - "org.springframework.data.domain.jaxb", - "org.springframework.data.expression", - "org.springframework.data.geo", - "org.springframework.data.geo.format", - "org.springframework.data.history", - "org.springframework.data.javapoet", - "org.springframework.data.mapping", - "org.springframework.data.mapping.callback", - "org.springframework.data.mapping.context", - "org.springframework.data.mapping.model", - "org.springframework.data.projection", - "org.springframework.data.querydsl", - "org.springframework.data.querydsl.aot", - "org.springframework.data.querydsl.binding", - "org.springframework.data.repository", - "org.springframework.data.repository.aot.generate", - "org.springframework.data.repository.aot.hint", - "org.springframework.data.repository.cdi", - "org.springframework.data.repository.config", - "org.springframework.data.repository.core", - "org.springframework.data.repository.core.support", - "org.springframework.data.repository.history", - "org.springframework.data.repository.history.support", - "org.springframework.data.repository.init", - "org.springframework.data.repository.kotlin", - "org.springframework.data.repository.query", - "org.springframework.data.repository.query.parser", - "org.springframework.data.repository.reactive", - "org.springframework.data.repository.support", - "org.springframework.data.repository.util", - "org.springframework.data.spel", - "org.springframework.data.spel.spi", - "org.springframework.data.support", - "org.springframework.data.transaction", - "org.springframework.data.util", - "org.springframework.data.web", - "org.springframework.data.web.aot", - "org.springframework.data.web.config", - "org.springframework.data.web.querydsl" - ], - "org.springframework.security:spring-security-config": [ - "org.springframework.security.config", - "org.springframework.security.config.annotation", - "org.springframework.security.config.annotation.authentication", - "org.springframework.security.config.annotation.authentication.builders", - "org.springframework.security.config.annotation.authentication.configuration", - "org.springframework.security.config.annotation.authentication.configurers.ldap", - "org.springframework.security.config.annotation.authentication.configurers.provisioning", - "org.springframework.security.config.annotation.authentication.configurers.userdetails", - "org.springframework.security.config.annotation.authorization", - "org.springframework.security.config.annotation.configuration", - "org.springframework.security.config.annotation.method.configuration", - "org.springframework.security.config.annotation.rsocket", - "org.springframework.security.config.annotation.web", - "org.springframework.security.config.annotation.web.builders", - "org.springframework.security.config.annotation.web.configuration", - "org.springframework.security.config.annotation.web.configurers", - "org.springframework.security.config.annotation.web.configurers.oauth2.client", - "org.springframework.security.config.annotation.web.configurers.oauth2.server.authorization", - "org.springframework.security.config.annotation.web.configurers.oauth2.server.resource", - "org.springframework.security.config.annotation.web.configurers.ott", - "org.springframework.security.config.annotation.web.configurers.saml2", - "org.springframework.security.config.annotation.web.headers", - "org.springframework.security.config.annotation.web.oauth2.client", - "org.springframework.security.config.annotation.web.oauth2.login", - "org.springframework.security.config.annotation.web.oauth2.resourceserver", - "org.springframework.security.config.annotation.web.reactive", - "org.springframework.security.config.annotation.web.saml2", - "org.springframework.security.config.annotation.web.servlet.configuration", - "org.springframework.security.config.annotation.web.session", - "org.springframework.security.config.annotation.web.socket", - "org.springframework.security.config.aot.hint", - "org.springframework.security.config.authentication", - "org.springframework.security.config.core", - "org.springframework.security.config.core.userdetails", - "org.springframework.security.config.crypto", - "org.springframework.security.config.debug", - "org.springframework.security.config.http", - "org.springframework.security.config.ldap", - "org.springframework.security.config.method", - "org.springframework.security.config.oauth2.client", - "org.springframework.security.config.observation", - "org.springframework.security.config.provisioning", - "org.springframework.security.config.saml2", - "org.springframework.security.config.web", - "org.springframework.security.config.web.messaging", - "org.springframework.security.config.web.server", - "org.springframework.security.config.websocket" - ], - "org.springframework.security:spring-security-core": [ - "org.springframework.security.access", - "org.springframework.security.access.annotation", - "org.springframework.security.access.expression", - "org.springframework.security.access.expression.method", - "org.springframework.security.access.hierarchicalroles", - "org.springframework.security.access.prepost", - "org.springframework.security.aot.hint", - "org.springframework.security.authentication", - "org.springframework.security.authentication.dao", - "org.springframework.security.authentication.event", - "org.springframework.security.authentication.jaas", - "org.springframework.security.authentication.jaas.event", - "org.springframework.security.authentication.jaas.memory", - "org.springframework.security.authentication.ott", - "org.springframework.security.authentication.ott.reactive", - "org.springframework.security.authentication.password", - "org.springframework.security.authorization", - "org.springframework.security.authorization.event", - "org.springframework.security.authorization.method", - "org.springframework.security.concurrent", - "org.springframework.security.context", - "org.springframework.security.converter", - "org.springframework.security.core", - "org.springframework.security.core.annotation", - "org.springframework.security.core.authority", - "org.springframework.security.core.authority.mapping", - "org.springframework.security.core.context", - "org.springframework.security.core.parameters", - "org.springframework.security.core.session", - "org.springframework.security.core.token", - "org.springframework.security.core.userdetails", - "org.springframework.security.core.userdetails.cache", - "org.springframework.security.core.userdetails.jdbc", - "org.springframework.security.core.userdetails.memory", - "org.springframework.security.jackson", - "org.springframework.security.jackson2", - "org.springframework.security.provisioning", - "org.springframework.security.scheduling", - "org.springframework.security.task", - "org.springframework.security.util" - ], - "org.springframework.security:spring-security-crypto": [ - "org.springframework.security.crypto.argon2", - "org.springframework.security.crypto.bcrypt", - "org.springframework.security.crypto.codec", - "org.springframework.security.crypto.encrypt", - "org.springframework.security.crypto.factory", - "org.springframework.security.crypto.keygen", - "org.springframework.security.crypto.password", - "org.springframework.security.crypto.password4j", - "org.springframework.security.crypto.scrypt", - "org.springframework.security.crypto.util" - ], - "org.springframework.security:spring-security-oauth2-client": [ - "org.springframework.security.oauth2.client", - "org.springframework.security.oauth2.client.annotation", - "org.springframework.security.oauth2.client.aot.hint", - "org.springframework.security.oauth2.client.authentication", - "org.springframework.security.oauth2.client.endpoint", - "org.springframework.security.oauth2.client.event", - "org.springframework.security.oauth2.client.http", - "org.springframework.security.oauth2.client.jackson", - "org.springframework.security.oauth2.client.jackson2", - "org.springframework.security.oauth2.client.oidc.authentication", - "org.springframework.security.oauth2.client.oidc.authentication.event", - "org.springframework.security.oauth2.client.oidc.authentication.logout", - "org.springframework.security.oauth2.client.oidc.server.session", - "org.springframework.security.oauth2.client.oidc.session", - "org.springframework.security.oauth2.client.oidc.userinfo", - "org.springframework.security.oauth2.client.oidc.web.logout", - "org.springframework.security.oauth2.client.oidc.web.server.logout", - "org.springframework.security.oauth2.client.registration", - "org.springframework.security.oauth2.client.userinfo", - "org.springframework.security.oauth2.client.web", - "org.springframework.security.oauth2.client.web.client", - "org.springframework.security.oauth2.client.web.client.support", - "org.springframework.security.oauth2.client.web.method.annotation", - "org.springframework.security.oauth2.client.web.reactive.function.client", - "org.springframework.security.oauth2.client.web.reactive.function.client.support", - "org.springframework.security.oauth2.client.web.reactive.result.method.annotation", - "org.springframework.security.oauth2.client.web.server", - "org.springframework.security.oauth2.client.web.server.authentication" - ], - "org.springframework.security:spring-security-oauth2-core": [ - "org.springframework.security.oauth2.core", - "org.springframework.security.oauth2.core.authorization", - "org.springframework.security.oauth2.core.converter", - "org.springframework.security.oauth2.core.endpoint", - "org.springframework.security.oauth2.core.http.converter", - "org.springframework.security.oauth2.core.oidc", - "org.springframework.security.oauth2.core.oidc.endpoint", - "org.springframework.security.oauth2.core.oidc.user", - "org.springframework.security.oauth2.core.user", - "org.springframework.security.oauth2.core.web.reactive.function" - ], - "org.springframework.security:spring-security-oauth2-jose": [ - "org.springframework.security.oauth2.jose", - "org.springframework.security.oauth2.jose.jws", - "org.springframework.security.oauth2.jwt" - ], - "org.springframework.security:spring-security-oauth2-resource-server": [ - "org.springframework.security.oauth2.server.resource", - "org.springframework.security.oauth2.server.resource.authentication", - "org.springframework.security.oauth2.server.resource.introspection", - "org.springframework.security.oauth2.server.resource.web", - "org.springframework.security.oauth2.server.resource.web.access", - "org.springframework.security.oauth2.server.resource.web.access.server", - "org.springframework.security.oauth2.server.resource.web.authentication", - "org.springframework.security.oauth2.server.resource.web.reactive.function.client", - "org.springframework.security.oauth2.server.resource.web.server", - "org.springframework.security.oauth2.server.resource.web.server.authentication" - ], - "org.springframework.security:spring-security-test": [ - "org.springframework.security.test.aot.hint", - "org.springframework.security.test.context", - "org.springframework.security.test.context.annotation", - "org.springframework.security.test.context.support", - "org.springframework.security.test.web.reactive.server", - "org.springframework.security.test.web.servlet.request", - "org.springframework.security.test.web.servlet.response", - "org.springframework.security.test.web.servlet.setup", - "org.springframework.security.test.web.support" - ], - "org.springframework.security:spring-security-web": [ - "org.springframework.security.web", - "org.springframework.security.web.access", - "org.springframework.security.web.access.expression", - "org.springframework.security.web.access.intercept", - "org.springframework.security.web.aot.hint", - "org.springframework.security.web.authentication", - "org.springframework.security.web.authentication.logout", - "org.springframework.security.web.authentication.ott", - "org.springframework.security.web.authentication.password", - "org.springframework.security.web.authentication.preauth", - "org.springframework.security.web.authentication.preauth.j2ee", - "org.springframework.security.web.authentication.preauth.websphere", - "org.springframework.security.web.authentication.preauth.x509", - "org.springframework.security.web.authentication.rememberme", - "org.springframework.security.web.authentication.session", - "org.springframework.security.web.authentication.switchuser", - "org.springframework.security.web.authentication.ui", - "org.springframework.security.web.authentication.www", - "org.springframework.security.web.bind", - "org.springframework.security.web.bind.annotation", - "org.springframework.security.web.bind.support", - "org.springframework.security.web.context", - "org.springframework.security.web.context.request.async", - "org.springframework.security.web.context.support", - "org.springframework.security.web.csrf", - "org.springframework.security.web.debug", - "org.springframework.security.web.firewall", - "org.springframework.security.web.header", - "org.springframework.security.web.header.writers", - "org.springframework.security.web.header.writers.frameoptions", - "org.springframework.security.web.http", - "org.springframework.security.web.jaasapi", - "org.springframework.security.web.jackson", - "org.springframework.security.web.jackson2", - "org.springframework.security.web.method.annotation", - "org.springframework.security.web.reactive.result.method.annotation", - "org.springframework.security.web.reactive.result.view", - "org.springframework.security.web.savedrequest", - "org.springframework.security.web.server", - "org.springframework.security.web.server.authentication", - "org.springframework.security.web.server.authentication.logout", - "org.springframework.security.web.server.authentication.ott", - "org.springframework.security.web.server.authorization", - "org.springframework.security.web.server.context", - "org.springframework.security.web.server.csrf", - "org.springframework.security.web.server.firewall", - "org.springframework.security.web.server.header", - "org.springframework.security.web.server.jackson", - "org.springframework.security.web.server.jackson2", - "org.springframework.security.web.server.savedrequest", - "org.springframework.security.web.server.transport", - "org.springframework.security.web.server.ui", - "org.springframework.security.web.server.util.matcher", - "org.springframework.security.web.servlet.support.csrf", - "org.springframework.security.web.servlet.util.matcher", - "org.springframework.security.web.servletapi", - "org.springframework.security.web.session", - "org.springframework.security.web.transport", - "org.springframework.security.web.util", - "org.springframework.security.web.util.matcher" - ], - "org.springframework:spring-aop": [ - "org.aopalliance", - "org.aopalliance.aop", - "org.aopalliance.intercept", - "org.springframework.aop", - "org.springframework.aop.aspectj", - "org.springframework.aop.aspectj.annotation", - "org.springframework.aop.aspectj.autoproxy", - "org.springframework.aop.config", - "org.springframework.aop.framework", - "org.springframework.aop.framework.adapter", - "org.springframework.aop.framework.autoproxy", - "org.springframework.aop.framework.autoproxy.target", - "org.springframework.aop.interceptor", - "org.springframework.aop.scope", - "org.springframework.aop.support", - "org.springframework.aop.support.annotation", - "org.springframework.aop.target", - "org.springframework.aop.target.dynamic" - ], - "org.springframework:spring-beans": [ - "org.springframework.beans", - "org.springframework.beans.factory", - "org.springframework.beans.factory.annotation", - "org.springframework.beans.factory.aot", - "org.springframework.beans.factory.config", - "org.springframework.beans.factory.groovy", - "org.springframework.beans.factory.parsing", - "org.springframework.beans.factory.serviceloader", - "org.springframework.beans.factory.support", - "org.springframework.beans.factory.wiring", - "org.springframework.beans.factory.xml", - "org.springframework.beans.propertyeditors", - "org.springframework.beans.support" - ], - "org.springframework:spring-context": [ - "org.springframework.cache", - "org.springframework.cache.annotation", - "org.springframework.cache.concurrent", - "org.springframework.cache.config", - "org.springframework.cache.interceptor", - "org.springframework.cache.support", - "org.springframework.context", - "org.springframework.context.annotation", - "org.springframework.context.aot", - "org.springframework.context.config", - "org.springframework.context.event", - "org.springframework.context.expression", - "org.springframework.context.i18n", - "org.springframework.context.index", - "org.springframework.context.support", - "org.springframework.context.weaving", - "org.springframework.ejb.config", - "org.springframework.format", - "org.springframework.format.annotation", - "org.springframework.format.datetime", - "org.springframework.format.datetime.standard", - "org.springframework.format.number", - "org.springframework.format.number.money", - "org.springframework.format.support", - "org.springframework.instrument.classloading", - "org.springframework.instrument.classloading.glassfish", - "org.springframework.instrument.classloading.jboss", - "org.springframework.instrument.classloading.tomcat", - "org.springframework.jmx", - "org.springframework.jmx.access", - "org.springframework.jmx.export", - "org.springframework.jmx.export.annotation", - "org.springframework.jmx.export.assembler", - "org.springframework.jmx.export.metadata", - "org.springframework.jmx.export.naming", - "org.springframework.jmx.export.notification", - "org.springframework.jmx.support", - "org.springframework.jndi", - "org.springframework.jndi.support", - "org.springframework.resilience", - "org.springframework.resilience.annotation", - "org.springframework.resilience.retry", - "org.springframework.scheduling", - "org.springframework.scheduling.annotation", - "org.springframework.scheduling.concurrent", - "org.springframework.scheduling.config", - "org.springframework.scheduling.support", - "org.springframework.scripting", - "org.springframework.scripting.bsh", - "org.springframework.scripting.config", - "org.springframework.scripting.groovy", - "org.springframework.scripting.support", - "org.springframework.stereotype", - "org.springframework.ui", - "org.springframework.validation", - "org.springframework.validation.annotation", - "org.springframework.validation.beanvalidation", - "org.springframework.validation.method", - "org.springframework.validation.support" - ], - "org.springframework:spring-core": [ - "org.springframework.aot", - "org.springframework.aot.generate", - "org.springframework.aot.hint", - "org.springframework.aot.hint.annotation", - "org.springframework.aot.hint.predicate", - "org.springframework.aot.hint.support", - "org.springframework.aot.nativex", - "org.springframework.aot.nativex.feature", - "org.springframework.asm", - "org.springframework.cglib", - "org.springframework.cglib.beans", - "org.springframework.cglib.core", - "org.springframework.cglib.core.internal", - "org.springframework.cglib.proxy", - "org.springframework.cglib.reflect", - "org.springframework.cglib.transform", - "org.springframework.cglib.transform.impl", - "org.springframework.cglib.util", - "org.springframework.core", - "org.springframework.core.annotation", - "org.springframework.core.codec", - "org.springframework.core.convert", - "org.springframework.core.convert.converter", - "org.springframework.core.convert.support", - "org.springframework.core.env", - "org.springframework.core.io", - "org.springframework.core.io.buffer", - "org.springframework.core.io.support", - "org.springframework.core.log", - "org.springframework.core.metrics", - "org.springframework.core.metrics.jfr", - "org.springframework.core.retry", - "org.springframework.core.retry.support", - "org.springframework.core.serializer", - "org.springframework.core.serializer.support", - "org.springframework.core.style", - "org.springframework.core.task", - "org.springframework.core.task.support", - "org.springframework.core.type", - "org.springframework.core.type.classreading", - "org.springframework.core.type.filter", - "org.springframework.javapoet", - "org.springframework.lang", - "org.springframework.objenesis", - "org.springframework.objenesis.instantiator", - "org.springframework.objenesis.instantiator.android", - "org.springframework.objenesis.instantiator.annotations", - "org.springframework.objenesis.instantiator.basic", - "org.springframework.objenesis.instantiator.gcj", - "org.springframework.objenesis.instantiator.perc", - "org.springframework.objenesis.instantiator.sun", - "org.springframework.objenesis.instantiator.util", - "org.springframework.objenesis.strategy", - "org.springframework.util", - "org.springframework.util.backoff", - "org.springframework.util.comparator", - "org.springframework.util.concurrent", - "org.springframework.util.function", - "org.springframework.util.unit", - "org.springframework.util.xml" - ], - "org.springframework:spring-expression": [ - "org.springframework.expression", - "org.springframework.expression.common", - "org.springframework.expression.spel", - "org.springframework.expression.spel.ast", - "org.springframework.expression.spel.standard", - "org.springframework.expression.spel.support" - ], - "org.springframework:spring-test": [ - "org.springframework.mock.env", - "org.springframework.mock.http", - "org.springframework.mock.http.client", - "org.springframework.mock.http.client.reactive", - "org.springframework.mock.http.server.reactive", - "org.springframework.mock.web", - "org.springframework.mock.web.reactive.function.server", - "org.springframework.mock.web.server", - "org.springframework.test.annotation", - "org.springframework.test.context", - "org.springframework.test.context.aot", - "org.springframework.test.context.bean.override", - "org.springframework.test.context.bean.override.convention", - "org.springframework.test.context.bean.override.mockito", - "org.springframework.test.context.cache", - "org.springframework.test.context.event", - "org.springframework.test.context.event.annotation", - "org.springframework.test.context.hint", - "org.springframework.test.context.jdbc", - "org.springframework.test.context.junit.jupiter", - "org.springframework.test.context.junit.jupiter.web", - "org.springframework.test.context.junit4", - "org.springframework.test.context.junit4.rules", - "org.springframework.test.context.junit4.statements", - "org.springframework.test.context.observation", - "org.springframework.test.context.support", - "org.springframework.test.context.testng", - "org.springframework.test.context.transaction", - "org.springframework.test.context.util", - "org.springframework.test.context.web", - "org.springframework.test.context.web.socket", - "org.springframework.test.http", - "org.springframework.test.jdbc", - "org.springframework.test.json", - "org.springframework.test.util", - "org.springframework.test.validation", - "org.springframework.test.web", - "org.springframework.test.web.client", - "org.springframework.test.web.client.match", - "org.springframework.test.web.client.response", - "org.springframework.test.web.reactive.server", - "org.springframework.test.web.reactive.server.assertj", - "org.springframework.test.web.servlet", - "org.springframework.test.web.servlet.assertj", - "org.springframework.test.web.servlet.client", - "org.springframework.test.web.servlet.client.assertj", - "org.springframework.test.web.servlet.htmlunit", - "org.springframework.test.web.servlet.htmlunit.webdriver", - "org.springframework.test.web.servlet.request", - "org.springframework.test.web.servlet.result", - "org.springframework.test.web.servlet.setup", - "org.springframework.test.web.support" - ], - "org.springframework:spring-tx": [ - "org.springframework.dao", - "org.springframework.dao.annotation", - "org.springframework.dao.support", - "org.springframework.jca.endpoint", - "org.springframework.jca.support", - "org.springframework.transaction", - "org.springframework.transaction.annotation", - "org.springframework.transaction.config", - "org.springframework.transaction.event", - "org.springframework.transaction.interceptor", - "org.springframework.transaction.jta", - "org.springframework.transaction.reactive", - "org.springframework.transaction.support" - ], - "org.springframework:spring-web": [ - "org.springframework.http", - "org.springframework.http.client", - "org.springframework.http.client.observation", - "org.springframework.http.client.reactive", - "org.springframework.http.client.support", - "org.springframework.http.codec", - "org.springframework.http.codec.cbor", - "org.springframework.http.codec.json", - "org.springframework.http.codec.multipart", - "org.springframework.http.codec.protobuf", - "org.springframework.http.codec.smile", - "org.springframework.http.codec.support", - "org.springframework.http.codec.xml", - "org.springframework.http.converter", - "org.springframework.http.converter.cbor", - "org.springframework.http.converter.feed", - "org.springframework.http.converter.json", - "org.springframework.http.converter.protobuf", - "org.springframework.http.converter.smile", - "org.springframework.http.converter.support", - "org.springframework.http.converter.xml", - "org.springframework.http.converter.yaml", - "org.springframework.http.server", - "org.springframework.http.server.observation", - "org.springframework.http.server.reactive", - "org.springframework.http.server.reactive.observation", - "org.springframework.http.support", - "org.springframework.web", - "org.springframework.web.accept", - "org.springframework.web.bind", - "org.springframework.web.bind.annotation", - "org.springframework.web.bind.support", - "org.springframework.web.client", - "org.springframework.web.client.support", - "org.springframework.web.context", - "org.springframework.web.context.annotation", - "org.springframework.web.context.request", - "org.springframework.web.context.request.async", - "org.springframework.web.context.support", - "org.springframework.web.cors", - "org.springframework.web.cors.reactive", - "org.springframework.web.filter", - "org.springframework.web.filter.reactive", - "org.springframework.web.jsf", - "org.springframework.web.jsf.el", - "org.springframework.web.method", - "org.springframework.web.method.annotation", - "org.springframework.web.method.support", - "org.springframework.web.multipart", - "org.springframework.web.multipart.support", - "org.springframework.web.server", - "org.springframework.web.server.adapter", - "org.springframework.web.server.handler", - "org.springframework.web.server.i18n", - "org.springframework.web.server.session", - "org.springframework.web.service", - "org.springframework.web.service.annotation", - "org.springframework.web.service.invoker", - "org.springframework.web.service.registry", - "org.springframework.web.util", - "org.springframework.web.util.pattern" - ], - "org.springframework:spring-webflux": [ - "org.springframework.web.reactive", - "org.springframework.web.reactive.accept", - "org.springframework.web.reactive.config", - "org.springframework.web.reactive.function", - "org.springframework.web.reactive.function.client", - "org.springframework.web.reactive.function.client.support", - "org.springframework.web.reactive.function.server", - "org.springframework.web.reactive.function.server.support", - "org.springframework.web.reactive.handler", - "org.springframework.web.reactive.resource", - "org.springframework.web.reactive.result", - "org.springframework.web.reactive.result.condition", - "org.springframework.web.reactive.result.method", - "org.springframework.web.reactive.result.method.annotation", - "org.springframework.web.reactive.result.view", - "org.springframework.web.reactive.result.view.freemarker", - "org.springframework.web.reactive.result.view.script", - "org.springframework.web.reactive.socket", - "org.springframework.web.reactive.socket.adapter", - "org.springframework.web.reactive.socket.client", - "org.springframework.web.reactive.socket.server", - "org.springframework.web.reactive.socket.server.support", - "org.springframework.web.reactive.socket.server.upgrade" - ], - "org.springframework:spring-webmvc": [ - "org.springframework.web.servlet", - "org.springframework.web.servlet.config", - "org.springframework.web.servlet.config.annotation", - "org.springframework.web.servlet.function", - "org.springframework.web.servlet.function.support", - "org.springframework.web.servlet.handler", - "org.springframework.web.servlet.i18n", - "org.springframework.web.servlet.mvc", - "org.springframework.web.servlet.mvc.annotation", - "org.springframework.web.servlet.mvc.condition", - "org.springframework.web.servlet.mvc.method", - "org.springframework.web.servlet.mvc.method.annotation", - "org.springframework.web.servlet.mvc.support", - "org.springframework.web.servlet.resource", - "org.springframework.web.servlet.support", - "org.springframework.web.servlet.tags", - "org.springframework.web.servlet.tags.form", - "org.springframework.web.servlet.view", - "org.springframework.web.servlet.view.document", - "org.springframework.web.servlet.view.feed", - "org.springframework.web.servlet.view.freemarker", - "org.springframework.web.servlet.view.groovy", - "org.springframework.web.servlet.view.json", - "org.springframework.web.servlet.view.script", - "org.springframework.web.servlet.view.xml", - "org.springframework.web.servlet.view.xslt" - ], - "org.testcontainers:testcontainers": [ - "org.testcontainers", - "org.testcontainers.containers", - "org.testcontainers.containers.output", - "org.testcontainers.containers.startupcheck", - "org.testcontainers.containers.traits", - "org.testcontainers.containers.wait.internal", - "org.testcontainers.containers.wait.strategy", - "org.testcontainers.core", - "org.testcontainers.dockerclient", - "org.testcontainers.images", - "org.testcontainers.images.builder", - "org.testcontainers.images.builder.dockerfile", - "org.testcontainers.images.builder.dockerfile.statement", - "org.testcontainers.images.builder.dockerfile.traits", - "org.testcontainers.images.builder.traits", - "org.testcontainers.jib", - "org.testcontainers.lifecycle", - "org.testcontainers.shaded.com.fasterxml.jackson.core", - "org.testcontainers.shaded.com.fasterxml.jackson.core.async", - "org.testcontainers.shaded.com.fasterxml.jackson.core.base", - "org.testcontainers.shaded.com.fasterxml.jackson.core.exc", - "org.testcontainers.shaded.com.fasterxml.jackson.core.filter", - "org.testcontainers.shaded.com.fasterxml.jackson.core.format", - "org.testcontainers.shaded.com.fasterxml.jackson.core.internal.shaded.fdp.v2_18_4", - "org.testcontainers.shaded.com.fasterxml.jackson.core.io", - "org.testcontainers.shaded.com.fasterxml.jackson.core.io.schubfach", - "org.testcontainers.shaded.com.fasterxml.jackson.core.json", - "org.testcontainers.shaded.com.fasterxml.jackson.core.json.async", - "org.testcontainers.shaded.com.fasterxml.jackson.core.sym", - "org.testcontainers.shaded.com.fasterxml.jackson.core.type", - "org.testcontainers.shaded.com.fasterxml.jackson.core.util", - "org.testcontainers.shaded.com.fasterxml.jackson.databind", - "org.testcontainers.shaded.com.fasterxml.jackson.databind.annotation", - "org.testcontainers.shaded.com.fasterxml.jackson.databind.cfg", - "org.testcontainers.shaded.com.fasterxml.jackson.databind.deser", - "org.testcontainers.shaded.com.fasterxml.jackson.databind.deser.impl", - "org.testcontainers.shaded.com.fasterxml.jackson.databind.deser.std", - "org.testcontainers.shaded.com.fasterxml.jackson.databind.exc", - "org.testcontainers.shaded.com.fasterxml.jackson.databind.ext", - "org.testcontainers.shaded.com.fasterxml.jackson.databind.introspect", - "org.testcontainers.shaded.com.fasterxml.jackson.databind.jdk14", - "org.testcontainers.shaded.com.fasterxml.jackson.databind.json", - "org.testcontainers.shaded.com.fasterxml.jackson.databind.jsonFormatVisitors", - "org.testcontainers.shaded.com.fasterxml.jackson.databind.jsonschema", - "org.testcontainers.shaded.com.fasterxml.jackson.databind.jsontype", - "org.testcontainers.shaded.com.fasterxml.jackson.databind.jsontype.impl", - "org.testcontainers.shaded.com.fasterxml.jackson.databind.module", - "org.testcontainers.shaded.com.fasterxml.jackson.databind.node", - "org.testcontainers.shaded.com.fasterxml.jackson.databind.ser", - "org.testcontainers.shaded.com.fasterxml.jackson.databind.ser.impl", - "org.testcontainers.shaded.com.fasterxml.jackson.databind.ser.std", - "org.testcontainers.shaded.com.fasterxml.jackson.databind.type", - "org.testcontainers.shaded.com.fasterxml.jackson.databind.util", - "org.testcontainers.shaded.com.fasterxml.jackson.databind.util.internal", - "org.testcontainers.shaded.com.github.dockerjava.core", - "org.testcontainers.shaded.com.github.dockerjava.core.async", - "org.testcontainers.shaded.com.github.dockerjava.core.command", - "org.testcontainers.shaded.com.github.dockerjava.core.dockerfile", - "org.testcontainers.shaded.com.github.dockerjava.core.exception", - "org.testcontainers.shaded.com.github.dockerjava.core.exec", - "org.testcontainers.shaded.com.github.dockerjava.core.util", - "org.testcontainers.shaded.com.google.common.annotations", - "org.testcontainers.shaded.com.google.common.base", - "org.testcontainers.shaded.com.google.common.base.internal", - "org.testcontainers.shaded.com.google.common.cache", - "org.testcontainers.shaded.com.google.common.collect", - "org.testcontainers.shaded.com.google.common.escape", - "org.testcontainers.shaded.com.google.common.eventbus", - "org.testcontainers.shaded.com.google.common.graph", - "org.testcontainers.shaded.com.google.common.hash", - "org.testcontainers.shaded.com.google.common.html", - "org.testcontainers.shaded.com.google.common.io", - "org.testcontainers.shaded.com.google.common.math", - "org.testcontainers.shaded.com.google.common.net", - "org.testcontainers.shaded.com.google.common.primitives", - "org.testcontainers.shaded.com.google.common.reflect", - "org.testcontainers.shaded.com.google.common.util.concurrent", - "org.testcontainers.shaded.com.google.common.util.concurrent.internal", - "org.testcontainers.shaded.com.google.common.xml", - "org.testcontainers.shaded.com.google.errorprone.annotations", - "org.testcontainers.shaded.com.google.errorprone.annotations.concurrent", - "org.testcontainers.shaded.com.google.thirdparty.publicsuffix", - "org.testcontainers.shaded.com.trilead.ssh2", - "org.testcontainers.shaded.com.trilead.ssh2.auth", - "org.testcontainers.shaded.com.trilead.ssh2.channel", - "org.testcontainers.shaded.com.trilead.ssh2.crypto", - "org.testcontainers.shaded.com.trilead.ssh2.crypto.cipher", - "org.testcontainers.shaded.com.trilead.ssh2.crypto.dh", - "org.testcontainers.shaded.com.trilead.ssh2.crypto.digest", - "org.testcontainers.shaded.com.trilead.ssh2.log", - "org.testcontainers.shaded.com.trilead.ssh2.packets", - "org.testcontainers.shaded.com.trilead.ssh2.sftp", - "org.testcontainers.shaded.com.trilead.ssh2.signature", - "org.testcontainers.shaded.com.trilead.ssh2.transport", - "org.testcontainers.shaded.com.trilead.ssh2.util", - "org.testcontainers.shaded.org.awaitility", - "org.testcontainers.shaded.org.awaitility.classpath", - "org.testcontainers.shaded.org.awaitility.constraint", - "org.testcontainers.shaded.org.awaitility.core", - "org.testcontainers.shaded.org.awaitility.pollinterval", - "org.testcontainers.shaded.org.awaitility.reflect", - "org.testcontainers.shaded.org.awaitility.reflect.exception", - "org.testcontainers.shaded.org.awaitility.spi", - "org.testcontainers.shaded.org.bouncycastle", - "org.testcontainers.shaded.org.bouncycastle.asn1", - "org.testcontainers.shaded.org.bouncycastle.asn1.anssi", - "org.testcontainers.shaded.org.bouncycastle.asn1.bc", - "org.testcontainers.shaded.org.bouncycastle.asn1.bsi", - "org.testcontainers.shaded.org.bouncycastle.asn1.cmc", - "org.testcontainers.shaded.org.bouncycastle.asn1.cmp", - "org.testcontainers.shaded.org.bouncycastle.asn1.cms", - "org.testcontainers.shaded.org.bouncycastle.asn1.cms.ecc", - "org.testcontainers.shaded.org.bouncycastle.asn1.crmf", - "org.testcontainers.shaded.org.bouncycastle.asn1.cryptlib", - "org.testcontainers.shaded.org.bouncycastle.asn1.cryptopro", - "org.testcontainers.shaded.org.bouncycastle.asn1.dvcs", - "org.testcontainers.shaded.org.bouncycastle.asn1.eac", - "org.testcontainers.shaded.org.bouncycastle.asn1.edec", - "org.testcontainers.shaded.org.bouncycastle.asn1.esf", - "org.testcontainers.shaded.org.bouncycastle.asn1.ess", - "org.testcontainers.shaded.org.bouncycastle.asn1.est", - "org.testcontainers.shaded.org.bouncycastle.asn1.gm", - "org.testcontainers.shaded.org.bouncycastle.asn1.gnu", - "org.testcontainers.shaded.org.bouncycastle.asn1.iana", - "org.testcontainers.shaded.org.bouncycastle.asn1.icao", - "org.testcontainers.shaded.org.bouncycastle.asn1.isara", - "org.testcontainers.shaded.org.bouncycastle.asn1.isismtt", - "org.testcontainers.shaded.org.bouncycastle.asn1.isismtt.ocsp", - "org.testcontainers.shaded.org.bouncycastle.asn1.isismtt.x509", - "org.testcontainers.shaded.org.bouncycastle.asn1.iso", - "org.testcontainers.shaded.org.bouncycastle.asn1.kisa", - "org.testcontainers.shaded.org.bouncycastle.asn1.microsoft", - "org.testcontainers.shaded.org.bouncycastle.asn1.misc", - "org.testcontainers.shaded.org.bouncycastle.asn1.mod", - "org.testcontainers.shaded.org.bouncycastle.asn1.mozilla", - "org.testcontainers.shaded.org.bouncycastle.asn1.nist", - "org.testcontainers.shaded.org.bouncycastle.asn1.nsri", - "org.testcontainers.shaded.org.bouncycastle.asn1.ntt", - "org.testcontainers.shaded.org.bouncycastle.asn1.ocsp", - "org.testcontainers.shaded.org.bouncycastle.asn1.oiw", - "org.testcontainers.shaded.org.bouncycastle.asn1.pkcs", - "org.testcontainers.shaded.org.bouncycastle.asn1.rosstandart", - "org.testcontainers.shaded.org.bouncycastle.asn1.sec", - "org.testcontainers.shaded.org.bouncycastle.asn1.smime", - "org.testcontainers.shaded.org.bouncycastle.asn1.teletrust", - "org.testcontainers.shaded.org.bouncycastle.asn1.tsp", - "org.testcontainers.shaded.org.bouncycastle.asn1.ua", - "org.testcontainers.shaded.org.bouncycastle.asn1.util", - "org.testcontainers.shaded.org.bouncycastle.asn1.x500", - "org.testcontainers.shaded.org.bouncycastle.asn1.x500.style", - "org.testcontainers.shaded.org.bouncycastle.asn1.x509", - "org.testcontainers.shaded.org.bouncycastle.asn1.x509.qualified", - "org.testcontainers.shaded.org.bouncycastle.asn1.x509.sigi", - "org.testcontainers.shaded.org.bouncycastle.asn1.x9", - "org.testcontainers.shaded.org.bouncycastle.cert", - "org.testcontainers.shaded.org.bouncycastle.cert.bc", - "org.testcontainers.shaded.org.bouncycastle.cert.cmp", - "org.testcontainers.shaded.org.bouncycastle.cert.crmf", - "org.testcontainers.shaded.org.bouncycastle.cert.crmf.bc", - "org.testcontainers.shaded.org.bouncycastle.cert.crmf.jcajce", - "org.testcontainers.shaded.org.bouncycastle.cert.dane", - "org.testcontainers.shaded.org.bouncycastle.cert.dane.fetcher", - "org.testcontainers.shaded.org.bouncycastle.cert.jcajce", - "org.testcontainers.shaded.org.bouncycastle.cert.ocsp", - "org.testcontainers.shaded.org.bouncycastle.cert.ocsp.jcajce", - "org.testcontainers.shaded.org.bouncycastle.cert.path", - "org.testcontainers.shaded.org.bouncycastle.cert.path.validations", - "org.testcontainers.shaded.org.bouncycastle.cert.selector", - "org.testcontainers.shaded.org.bouncycastle.cert.selector.jcajce", - "org.testcontainers.shaded.org.bouncycastle.cmc", - "org.testcontainers.shaded.org.bouncycastle.cms", - "org.testcontainers.shaded.org.bouncycastle.cms.bc", - "org.testcontainers.shaded.org.bouncycastle.cms.jcajce", - "org.testcontainers.shaded.org.bouncycastle.crypto", - "org.testcontainers.shaded.org.bouncycastle.crypto.agreement", - "org.testcontainers.shaded.org.bouncycastle.crypto.agreement.ecjpake", - "org.testcontainers.shaded.org.bouncycastle.crypto.agreement.jpake", - "org.testcontainers.shaded.org.bouncycastle.crypto.agreement.kdf", - "org.testcontainers.shaded.org.bouncycastle.crypto.agreement.srp", - "org.testcontainers.shaded.org.bouncycastle.crypto.commitments", - "org.testcontainers.shaded.org.bouncycastle.crypto.constraints", - "org.testcontainers.shaded.org.bouncycastle.crypto.digests", - "org.testcontainers.shaded.org.bouncycastle.crypto.ec", - "org.testcontainers.shaded.org.bouncycastle.crypto.encodings", - "org.testcontainers.shaded.org.bouncycastle.crypto.engines", - "org.testcontainers.shaded.org.bouncycastle.crypto.examples", - "org.testcontainers.shaded.org.bouncycastle.crypto.fpe", - "org.testcontainers.shaded.org.bouncycastle.crypto.generators", - "org.testcontainers.shaded.org.bouncycastle.crypto.hpke", - "org.testcontainers.shaded.org.bouncycastle.crypto.io", - "org.testcontainers.shaded.org.bouncycastle.crypto.kems", - "org.testcontainers.shaded.org.bouncycastle.crypto.macs", - "org.testcontainers.shaded.org.bouncycastle.crypto.modes", - "org.testcontainers.shaded.org.bouncycastle.crypto.modes.gcm", - "org.testcontainers.shaded.org.bouncycastle.crypto.modes.kgcm", - "org.testcontainers.shaded.org.bouncycastle.crypto.paddings", - "org.testcontainers.shaded.org.bouncycastle.crypto.params", - "org.testcontainers.shaded.org.bouncycastle.crypto.parsers", - "org.testcontainers.shaded.org.bouncycastle.crypto.prng", - "org.testcontainers.shaded.org.bouncycastle.crypto.prng.drbg", - "org.testcontainers.shaded.org.bouncycastle.crypto.signers", - "org.testcontainers.shaded.org.bouncycastle.crypto.threshold", - "org.testcontainers.shaded.org.bouncycastle.crypto.tls", - "org.testcontainers.shaded.org.bouncycastle.crypto.util", - "org.testcontainers.shaded.org.bouncycastle.dvcs", - "org.testcontainers.shaded.org.bouncycastle.eac", - "org.testcontainers.shaded.org.bouncycastle.eac.jcajce", - "org.testcontainers.shaded.org.bouncycastle.eac.operator", - "org.testcontainers.shaded.org.bouncycastle.eac.operator.jcajce", - "org.testcontainers.shaded.org.bouncycastle.est", - "org.testcontainers.shaded.org.bouncycastle.est.jcajce", - "org.testcontainers.shaded.org.bouncycastle.i18n", - "org.testcontainers.shaded.org.bouncycastle.i18n.filter", - "org.testcontainers.shaded.org.bouncycastle.iana", - "org.testcontainers.shaded.org.bouncycastle.internal.asn1.bsi", - "org.testcontainers.shaded.org.bouncycastle.internal.asn1.cms", - "org.testcontainers.shaded.org.bouncycastle.internal.asn1.cryptlib", - "org.testcontainers.shaded.org.bouncycastle.internal.asn1.eac", - "org.testcontainers.shaded.org.bouncycastle.internal.asn1.edec", - "org.testcontainers.shaded.org.bouncycastle.internal.asn1.gnu", - "org.testcontainers.shaded.org.bouncycastle.internal.asn1.iana", - "org.testcontainers.shaded.org.bouncycastle.internal.asn1.isara", - "org.testcontainers.shaded.org.bouncycastle.internal.asn1.isismtt", - "org.testcontainers.shaded.org.bouncycastle.internal.asn1.iso", - "org.testcontainers.shaded.org.bouncycastle.internal.asn1.kisa", - "org.testcontainers.shaded.org.bouncycastle.internal.asn1.microsoft", - "org.testcontainers.shaded.org.bouncycastle.internal.asn1.misc", - "org.testcontainers.shaded.org.bouncycastle.internal.asn1.nsri", - "org.testcontainers.shaded.org.bouncycastle.internal.asn1.ntt", - "org.testcontainers.shaded.org.bouncycastle.internal.asn1.oiw", - "org.testcontainers.shaded.org.bouncycastle.internal.asn1.rosstandart", - "org.testcontainers.shaded.org.bouncycastle.its", - "org.testcontainers.shaded.org.bouncycastle.its.bc", - "org.testcontainers.shaded.org.bouncycastle.its.jcajce", - "org.testcontainers.shaded.org.bouncycastle.its.operator", - "org.testcontainers.shaded.org.bouncycastle.jcajce", - "org.testcontainers.shaded.org.bouncycastle.jcajce.interfaces", - "org.testcontainers.shaded.org.bouncycastle.jcajce.io", - "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.asymmetric", - "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.asymmetric.compositesignatures", - "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.asymmetric.dh", - "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.asymmetric.dsa", - "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.asymmetric.dstu", - "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.asymmetric.ec", - "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.asymmetric.ecgost", - "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.asymmetric.ecgost12", - "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.asymmetric.edec", - "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.asymmetric.elgamal", - "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.asymmetric.gost", - "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.asymmetric.ies", - "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.asymmetric.mldsa", - "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.asymmetric.mlkem", - "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.asymmetric.rsa", - "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.asymmetric.slhdsa", - "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.asymmetric.util", - "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.asymmetric.x509", - "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.config", - "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.digest", - "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.drbg", - "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.keystore", - "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.keystore.bc", - "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.keystore.bcfks", - "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.keystore.pkcs12", - "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.keystore.util", - "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.symmetric", - "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.symmetric.util", - "org.testcontainers.shaded.org.bouncycastle.jcajce.provider.util", - "org.testcontainers.shaded.org.bouncycastle.jcajce.spec", - "org.testcontainers.shaded.org.bouncycastle.jcajce.util", - "org.testcontainers.shaded.org.bouncycastle.jce", - "org.testcontainers.shaded.org.bouncycastle.jce.exception", - "org.testcontainers.shaded.org.bouncycastle.jce.interfaces", - "org.testcontainers.shaded.org.bouncycastle.jce.netscape", - "org.testcontainers.shaded.org.bouncycastle.jce.provider", - "org.testcontainers.shaded.org.bouncycastle.jce.spec", - "org.testcontainers.shaded.org.bouncycastle.math", - "org.testcontainers.shaded.org.bouncycastle.math.ec", - "org.testcontainers.shaded.org.bouncycastle.math.ec.custom.djb", - "org.testcontainers.shaded.org.bouncycastle.math.ec.custom.gm", - "org.testcontainers.shaded.org.bouncycastle.math.ec.custom.sec", - "org.testcontainers.shaded.org.bouncycastle.math.ec.endo", - "org.testcontainers.shaded.org.bouncycastle.math.ec.rfc7748", - "org.testcontainers.shaded.org.bouncycastle.math.ec.rfc8032", - "org.testcontainers.shaded.org.bouncycastle.math.ec.tools", - "org.testcontainers.shaded.org.bouncycastle.math.field", - "org.testcontainers.shaded.org.bouncycastle.math.raw", - "org.testcontainers.shaded.org.bouncycastle.mime", - "org.testcontainers.shaded.org.bouncycastle.mime.encoding", - "org.testcontainers.shaded.org.bouncycastle.mime.smime", - "org.testcontainers.shaded.org.bouncycastle.mozilla", - "org.testcontainers.shaded.org.bouncycastle.mozilla.jcajce", - "org.testcontainers.shaded.org.bouncycastle.oer", - "org.testcontainers.shaded.org.bouncycastle.oer.its", - "org.testcontainers.shaded.org.bouncycastle.oer.its.etsi102941", - "org.testcontainers.shaded.org.bouncycastle.oer.its.etsi102941.basetypes", - "org.testcontainers.shaded.org.bouncycastle.oer.its.etsi103097", - "org.testcontainers.shaded.org.bouncycastle.oer.its.etsi103097.extension", - "org.testcontainers.shaded.org.bouncycastle.oer.its.ieee1609dot2", - "org.testcontainers.shaded.org.bouncycastle.oer.its.ieee1609dot2.basetypes", - "org.testcontainers.shaded.org.bouncycastle.oer.its.ieee1609dot2dot1", - "org.testcontainers.shaded.org.bouncycastle.oer.its.template.etsi102941", - "org.testcontainers.shaded.org.bouncycastle.oer.its.template.etsi102941.basetypes", - "org.testcontainers.shaded.org.bouncycastle.oer.its.template.etsi103097", - "org.testcontainers.shaded.org.bouncycastle.oer.its.template.etsi103097.extension", - "org.testcontainers.shaded.org.bouncycastle.oer.its.template.ieee1609dot2", - "org.testcontainers.shaded.org.bouncycastle.oer.its.template.ieee1609dot2.basetypes", - "org.testcontainers.shaded.org.bouncycastle.oer.its.template.ieee1609dot2dot1", - "org.testcontainers.shaded.org.bouncycastle.openssl", - "org.testcontainers.shaded.org.bouncycastle.openssl.bc", - "org.testcontainers.shaded.org.bouncycastle.openssl.jcajce", - "org.testcontainers.shaded.org.bouncycastle.operator", - "org.testcontainers.shaded.org.bouncycastle.operator.bc", - "org.testcontainers.shaded.org.bouncycastle.operator.jcajce", - "org.testcontainers.shaded.org.bouncycastle.pkcs", - "org.testcontainers.shaded.org.bouncycastle.pkcs.bc", - "org.testcontainers.shaded.org.bouncycastle.pkcs.jcajce", - "org.testcontainers.shaded.org.bouncycastle.pkix", - "org.testcontainers.shaded.org.bouncycastle.pkix.jcajce", - "org.testcontainers.shaded.org.bouncycastle.pkix.util", - "org.testcontainers.shaded.org.bouncycastle.pkix.util.filter", - "org.testcontainers.shaded.org.bouncycastle.pqc.asn1", - "org.testcontainers.shaded.org.bouncycastle.pqc.crypto", - "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.bike", - "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.cmce", - "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.crystals.dilithium", - "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.falcon", - "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.frodo", - "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.hqc", - "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.lms", - "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.mayo", - "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.mldsa", - "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.mlkem", - "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.newhope", - "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.ntru", - "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.ntruprime", - "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.picnic", - "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.rainbow", - "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.saber", - "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.slhdsa", - "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.snova", - "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.sphincs", - "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.sphincsplus", - "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.util", - "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.xmss", - "org.testcontainers.shaded.org.bouncycastle.pqc.crypto.xwing", - "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.interfaces", - "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider", - "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider.bike", - "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider.cmce", - "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider.dilithium", - "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider.falcon", - "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider.frodo", - "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider.hqc", - "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider.kyber", - "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider.lms", - "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider.mayo", - "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider.newhope", - "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider.ntru", - "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider.ntruprime", - "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider.picnic", - "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider.saber", - "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider.snova", - "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider.sphincs", - "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider.sphincsplus", - "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider.util", - "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.provider.xmss", - "org.testcontainers.shaded.org.bouncycastle.pqc.jcajce.spec", - "org.testcontainers.shaded.org.bouncycastle.pqc.math.ntru", - "org.testcontainers.shaded.org.bouncycastle.pqc.math.ntru.parameters", - "org.testcontainers.shaded.org.bouncycastle.tsp", - "org.testcontainers.shaded.org.bouncycastle.tsp.cms", - "org.testcontainers.shaded.org.bouncycastle.tsp.ers", - "org.testcontainers.shaded.org.bouncycastle.util", - "org.testcontainers.shaded.org.bouncycastle.util.encoders", - "org.testcontainers.shaded.org.bouncycastle.util.io", - "org.testcontainers.shaded.org.bouncycastle.util.io.pem", - "org.testcontainers.shaded.org.bouncycastle.util.test", - "org.testcontainers.shaded.org.bouncycastle.voms", - "org.testcontainers.shaded.org.bouncycastle.x509", - "org.testcontainers.shaded.org.bouncycastle.x509.extension", - "org.testcontainers.shaded.org.bouncycastle.x509.util", - "org.testcontainers.shaded.org.checkerframework.checker.builder.qual", - "org.testcontainers.shaded.org.checkerframework.checker.calledmethods.qual", - "org.testcontainers.shaded.org.checkerframework.checker.compilermsgs.qual", - "org.testcontainers.shaded.org.checkerframework.checker.fenum.qual", - "org.testcontainers.shaded.org.checkerframework.checker.formatter.qual", - "org.testcontainers.shaded.org.checkerframework.checker.guieffect.qual", - "org.testcontainers.shaded.org.checkerframework.checker.i18n.qual", - "org.testcontainers.shaded.org.checkerframework.checker.i18nformatter.qual", - "org.testcontainers.shaded.org.checkerframework.checker.index.qual", - "org.testcontainers.shaded.org.checkerframework.checker.initialization.qual", - "org.testcontainers.shaded.org.checkerframework.checker.interning.qual", - "org.testcontainers.shaded.org.checkerframework.checker.lock.qual", - "org.testcontainers.shaded.org.checkerframework.checker.mustcall.qual", - "org.testcontainers.shaded.org.checkerframework.checker.nullness.qual", - "org.testcontainers.shaded.org.checkerframework.checker.optional.qual", - "org.testcontainers.shaded.org.checkerframework.checker.propkey.qual", - "org.testcontainers.shaded.org.checkerframework.checker.regex.qual", - "org.testcontainers.shaded.org.checkerframework.checker.signature.qual", - "org.testcontainers.shaded.org.checkerframework.checker.signedness.qual", - "org.testcontainers.shaded.org.checkerframework.checker.tainting.qual", - "org.testcontainers.shaded.org.checkerframework.checker.units.qual", - "org.testcontainers.shaded.org.checkerframework.common.aliasing.qual", - "org.testcontainers.shaded.org.checkerframework.common.initializedfields.qual", - "org.testcontainers.shaded.org.checkerframework.common.reflection.qual", - "org.testcontainers.shaded.org.checkerframework.common.returnsreceiver.qual", - "org.testcontainers.shaded.org.checkerframework.common.subtyping.qual", - "org.testcontainers.shaded.org.checkerframework.common.util.count.report.qual", - "org.testcontainers.shaded.org.checkerframework.common.value.qual", - "org.testcontainers.shaded.org.checkerframework.dataflow.qual", - "org.testcontainers.shaded.org.checkerframework.framework.qual", - "org.testcontainers.shaded.org.hamcrest", - "org.testcontainers.shaded.org.hamcrest.beans", - "org.testcontainers.shaded.org.hamcrest.collection", - "org.testcontainers.shaded.org.hamcrest.comparator", - "org.testcontainers.shaded.org.hamcrest.core", - "org.testcontainers.shaded.org.hamcrest.internal", - "org.testcontainers.shaded.org.hamcrest.io", - "org.testcontainers.shaded.org.hamcrest.number", - "org.testcontainers.shaded.org.hamcrest.object", - "org.testcontainers.shaded.org.hamcrest.text", - "org.testcontainers.shaded.org.hamcrest.xml", - "org.testcontainers.shaded.org.yaml.snakeyaml", - "org.testcontainers.shaded.org.yaml.snakeyaml.comments", - "org.testcontainers.shaded.org.yaml.snakeyaml.composer", - "org.testcontainers.shaded.org.yaml.snakeyaml.constructor", - "org.testcontainers.shaded.org.yaml.snakeyaml.emitter", - "org.testcontainers.shaded.org.yaml.snakeyaml.env", - "org.testcontainers.shaded.org.yaml.snakeyaml.error", - "org.testcontainers.shaded.org.yaml.snakeyaml.events", - "org.testcontainers.shaded.org.yaml.snakeyaml.extensions.compactnotation", - "org.testcontainers.shaded.org.yaml.snakeyaml.external.com.google.gdata.util.common.base", - "org.testcontainers.shaded.org.yaml.snakeyaml.inspector", - "org.testcontainers.shaded.org.yaml.snakeyaml.internal", - "org.testcontainers.shaded.org.yaml.snakeyaml.introspector", - "org.testcontainers.shaded.org.yaml.snakeyaml.nodes", - "org.testcontainers.shaded.org.yaml.snakeyaml.parser", - "org.testcontainers.shaded.org.yaml.snakeyaml.reader", - "org.testcontainers.shaded.org.yaml.snakeyaml.representer", - "org.testcontainers.shaded.org.yaml.snakeyaml.resolver", - "org.testcontainers.shaded.org.yaml.snakeyaml.scanner", - "org.testcontainers.shaded.org.yaml.snakeyaml.serializer", - "org.testcontainers.shaded.org.yaml.snakeyaml.tokens", - "org.testcontainers.shaded.org.yaml.snakeyaml.util", - "org.testcontainers.shaded.org.zeroturnaround.exec", - "org.testcontainers.shaded.org.zeroturnaround.exec.close", - "org.testcontainers.shaded.org.zeroturnaround.exec.listener", - "org.testcontainers.shaded.org.zeroturnaround.exec.stop", - "org.testcontainers.shaded.org.zeroturnaround.exec.stream", - "org.testcontainers.shaded.org.zeroturnaround.exec.stream.slf4j", - "org.testcontainers.utility" - ], - "org.testcontainers:testcontainers-cassandra": [ - "org.testcontainers.cassandra", - "org.testcontainers.containers", - "org.testcontainers.containers.delegate", - "org.testcontainers.containers.wait" - ], - "org.testcontainers:testcontainers-database-commons": [ - "org.testcontainers.delegate", - "org.testcontainers.exception", - "org.testcontainers.ext" - ], - "org.testcontainers:testcontainers-junit-jupiter": [ - "org.testcontainers.junit.jupiter" - ], - "org.wiremock:wiremock-standalone": [ - "com.github.tomakehurst.wiremock", - "com.github.tomakehurst.wiremock.admin", - "com.github.tomakehurst.wiremock.admin.model", - "com.github.tomakehurst.wiremock.admin.tasks", - "com.github.tomakehurst.wiremock.client", - "com.github.tomakehurst.wiremock.common", - "com.github.tomakehurst.wiremock.common.filemaker", - "com.github.tomakehurst.wiremock.common.ssl", - "com.github.tomakehurst.wiremock.common.url", - "com.github.tomakehurst.wiremock.common.xml", - "com.github.tomakehurst.wiremock.core", - "com.github.tomakehurst.wiremock.direct", - "com.github.tomakehurst.wiremock.extension", - "com.github.tomakehurst.wiremock.extension.requestfilter", - "com.github.tomakehurst.wiremock.extension.responsetemplating", - "com.github.tomakehurst.wiremock.extension.responsetemplating.helpers", - "com.github.tomakehurst.wiremock.global", - "com.github.tomakehurst.wiremock.http", - "com.github.tomakehurst.wiremock.http.client", - "com.github.tomakehurst.wiremock.http.multipart", - "com.github.tomakehurst.wiremock.http.ssl", - "com.github.tomakehurst.wiremock.http.trafficlistener", - "com.github.tomakehurst.wiremock.jetty", - "com.github.tomakehurst.wiremock.jetty11", - "com.github.tomakehurst.wiremock.junit", - "com.github.tomakehurst.wiremock.junit5", - "com.github.tomakehurst.wiremock.matching", - "com.github.tomakehurst.wiremock.recording", - "com.github.tomakehurst.wiremock.security", - "com.github.tomakehurst.wiremock.servlet", - "com.github.tomakehurst.wiremock.standalone", - "com.github.tomakehurst.wiremock.store", - "com.github.tomakehurst.wiremock.store.files", - "com.github.tomakehurst.wiremock.stubbing", - "com.github.tomakehurst.wiremock.verification", - "com.github.tomakehurst.wiremock.verification.diff", - "com.github.tomakehurst.wiremock.verification.notmatched", - "org.jspecify.annotations", - "org.wiremock.annotations", - "org.wiremock.webhooks", - "wiremock", - "wiremock.com.ethlo.time", - "wiremock.com.ethlo.time.internal", - "wiremock.com.ethlo.time.internal.fixed", - "wiremock.com.ethlo.time.internal.token", - "wiremock.com.ethlo.time.internal.util", - "wiremock.com.ethlo.time.token", - "wiremock.com.fasterxml.jackson.annotation", - "wiremock.com.fasterxml.jackson.core", - "wiremock.com.fasterxml.jackson.core.async", - "wiremock.com.fasterxml.jackson.core.base", - "wiremock.com.fasterxml.jackson.core.exc", - "wiremock.com.fasterxml.jackson.core.filter", - "wiremock.com.fasterxml.jackson.core.format", - "wiremock.com.fasterxml.jackson.core.internal.shaded.fdp.v2_20_1", - "wiremock.com.fasterxml.jackson.core.internal.shaded.fdp.v2_20_1.bte", - "wiremock.com.fasterxml.jackson.core.internal.shaded.fdp.v2_20_1.chr", - "wiremock.com.fasterxml.jackson.core.io", - "wiremock.com.fasterxml.jackson.core.io.schubfach", - "wiremock.com.fasterxml.jackson.core.json", - "wiremock.com.fasterxml.jackson.core.json.async", - "wiremock.com.fasterxml.jackson.core.sym", - "wiremock.com.fasterxml.jackson.core.type", - "wiremock.com.fasterxml.jackson.core.util", - "wiremock.com.fasterxml.jackson.databind", - "wiremock.com.fasterxml.jackson.databind.annotation", - "wiremock.com.fasterxml.jackson.databind.cfg", - "wiremock.com.fasterxml.jackson.databind.deser", - "wiremock.com.fasterxml.jackson.databind.deser.impl", - "wiremock.com.fasterxml.jackson.databind.deser.std", - "wiremock.com.fasterxml.jackson.databind.exc", - "wiremock.com.fasterxml.jackson.databind.ext", - "wiremock.com.fasterxml.jackson.databind.introspect", - "wiremock.com.fasterxml.jackson.databind.jdk14", - "wiremock.com.fasterxml.jackson.databind.json", - "wiremock.com.fasterxml.jackson.databind.jsonFormatVisitors", - "wiremock.com.fasterxml.jackson.databind.jsonschema", - "wiremock.com.fasterxml.jackson.databind.jsontype", - "wiremock.com.fasterxml.jackson.databind.jsontype.impl", - "wiremock.com.fasterxml.jackson.databind.module", - "wiremock.com.fasterxml.jackson.databind.node", - "wiremock.com.fasterxml.jackson.databind.ser", - "wiremock.com.fasterxml.jackson.databind.ser.impl", - "wiremock.com.fasterxml.jackson.databind.ser.std", - "wiremock.com.fasterxml.jackson.databind.type", - "wiremock.com.fasterxml.jackson.databind.util", - "wiremock.com.fasterxml.jackson.databind.util.internal", - "wiremock.com.fasterxml.jackson.dataformat.yaml", - "wiremock.com.fasterxml.jackson.dataformat.yaml.snakeyaml.error", - "wiremock.com.fasterxml.jackson.dataformat.yaml.util", - "wiremock.com.fasterxml.jackson.datatype.jsr310", - "wiremock.com.fasterxml.jackson.datatype.jsr310.deser", - "wiremock.com.fasterxml.jackson.datatype.jsr310.deser.key", - "wiremock.com.fasterxml.jackson.datatype.jsr310.ser", - "wiremock.com.fasterxml.jackson.datatype.jsr310.ser.key", - "wiremock.com.fasterxml.jackson.datatype.jsr310.util", - "wiremock.com.github.jknack.handlebars", - "wiremock.com.github.jknack.handlebars.cache", - "wiremock.com.github.jknack.handlebars.context", - "wiremock.com.github.jknack.handlebars.helper", - "wiremock.com.github.jknack.handlebars.internal", - "wiremock.com.github.jknack.handlebars.internal.antlr", - "wiremock.com.github.jknack.handlebars.internal.antlr.atn", - "wiremock.com.github.jknack.handlebars.internal.antlr.dfa", - "wiremock.com.github.jknack.handlebars.internal.antlr.misc", - "wiremock.com.github.jknack.handlebars.internal.antlr.tree", - "wiremock.com.github.jknack.handlebars.internal.antlr.tree.pattern", - "wiremock.com.github.jknack.handlebars.internal.antlr.tree.xpath", - "wiremock.com.github.jknack.handlebars.internal.lang3", - "wiremock.com.github.jknack.handlebars.internal.lang3.builder", - "wiremock.com.github.jknack.handlebars.internal.lang3.exception", - "wiremock.com.github.jknack.handlebars.internal.lang3.function", - "wiremock.com.github.jknack.handlebars.internal.lang3.math", - "wiremock.com.github.jknack.handlebars.internal.lang3.mutable", - "wiremock.com.github.jknack.handlebars.internal.lang3.text", - "wiremock.com.github.jknack.handlebars.internal.lang3.text.translate", - "wiremock.com.github.jknack.handlebars.internal.lang3.time", - "wiremock.com.github.jknack.handlebars.internal.lang3.tuple", - "wiremock.com.github.jknack.handlebars.internal.path", - "wiremock.com.github.jknack.handlebars.internal.text", - "wiremock.com.github.jknack.handlebars.internal.text.diff", - "wiremock.com.github.jknack.handlebars.internal.text.io", - "wiremock.com.github.jknack.handlebars.internal.text.lookup", - "wiremock.com.github.jknack.handlebars.internal.text.matcher", - "wiremock.com.github.jknack.handlebars.internal.text.numbers", - "wiremock.com.github.jknack.handlebars.internal.text.similarity", - "wiremock.com.github.jknack.handlebars.internal.text.translate", - "wiremock.com.github.jknack.handlebars.io", - "wiremock.com.google.common.annotations", - "wiremock.com.google.common.base", - "wiremock.com.google.common.base.internal", - "wiremock.com.google.common.cache", - "wiremock.com.google.common.collect", - "wiremock.com.google.common.escape", - "wiremock.com.google.common.eventbus", - "wiremock.com.google.common.graph", - "wiremock.com.google.common.hash", - "wiremock.com.google.common.html", - "wiremock.com.google.common.io", - "wiremock.com.google.common.math", - "wiremock.com.google.common.net", - "wiremock.com.google.common.primitives", - "wiremock.com.google.common.reflect", - "wiremock.com.google.common.util.concurrent", - "wiremock.com.google.common.util.concurrent.internal", - "wiremock.com.google.common.xml", - "wiremock.com.google.errorprone.annotations", - "wiremock.com.google.errorprone.annotations.concurrent", - "wiremock.com.google.j2objc.annotations", - "wiremock.com.google.thirdparty.publicsuffix", - "wiremock.com.jayway.jsonpath", - "wiremock.com.jayway.jsonpath.internal", - "wiremock.com.jayway.jsonpath.internal.filter", - "wiremock.com.jayway.jsonpath.internal.function", - "wiremock.com.jayway.jsonpath.internal.function.json", - "wiremock.com.jayway.jsonpath.internal.function.latebinding", - "wiremock.com.jayway.jsonpath.internal.function.numeric", - "wiremock.com.jayway.jsonpath.internal.function.sequence", - "wiremock.com.jayway.jsonpath.internal.function.text", - "wiremock.com.jayway.jsonpath.internal.path", - "wiremock.com.jayway.jsonpath.spi.cache", - "wiremock.com.jayway.jsonpath.spi.json", - "wiremock.com.jayway.jsonpath.spi.mapper", - "wiremock.com.networknt.org.apache.commons.validator.routines", - "wiremock.com.networknt.schema", - "wiremock.com.networknt.schema.annotation", - "wiremock.com.networknt.schema.format", - "wiremock.com.networknt.schema.i18n", - "wiremock.com.networknt.schema.oas", - "wiremock.com.networknt.schema.output", - "wiremock.com.networknt.schema.regex", - "wiremock.com.networknt.schema.resource", - "wiremock.com.networknt.schema.result", - "wiremock.com.networknt.schema.serialization", - "wiremock.com.networknt.schema.serialization.node", - "wiremock.com.networknt.schema.utils", - "wiremock.com.networknt.schema.walk", - "wiremock.jakarta.servlet", - "wiremock.jakarta.servlet.annotation", - "wiremock.jakarta.servlet.descriptor", - "wiremock.jakarta.servlet.http", - "wiremock.joptsimple", - "wiremock.joptsimple.internal", - "wiremock.joptsimple.util", - "wiremock.net.javacrumbs.jsonunit.core", - "wiremock.net.javacrumbs.jsonunit.core.internal", - "wiremock.net.javacrumbs.jsonunit.core.internal.matchers", - "wiremock.net.javacrumbs.jsonunit.core.listener", - "wiremock.net.javacrumbs.jsonunit.core.util", - "wiremock.net.javacrumbs.jsonunit.providers", - "wiremock.net.minidev.asm", - "wiremock.net.minidev.asm.ex", - "wiremock.net.minidev.json", - "wiremock.net.minidev.json.annotate", - "wiremock.net.minidev.json.parser", - "wiremock.net.minidev.json.reader", - "wiremock.net.minidev.json.writer", - "wiremock.org.apache.commons.fileupload", - "wiremock.org.apache.commons.fileupload.disk", - "wiremock.org.apache.commons.fileupload.portlet", - "wiremock.org.apache.commons.fileupload.servlet", - "wiremock.org.apache.commons.fileupload.util", - "wiremock.org.apache.commons.fileupload.util.mime", - "wiremock.org.apache.commons.io", - "wiremock.org.apache.commons.io.build", - "wiremock.org.apache.commons.io.channels", - "wiremock.org.apache.commons.io.charset", - "wiremock.org.apache.commons.io.comparator", - "wiremock.org.apache.commons.io.file", - "wiremock.org.apache.commons.io.file.attribute", - "wiremock.org.apache.commons.io.file.spi", - "wiremock.org.apache.commons.io.filefilter", - "wiremock.org.apache.commons.io.function", - "wiremock.org.apache.commons.io.input", - "wiremock.org.apache.commons.io.input.buffer", - "wiremock.org.apache.commons.io.monitor", - "wiremock.org.apache.commons.io.output", - "wiremock.org.apache.commons.io.serialization", - "wiremock.org.apache.hc.client5.http", - "wiremock.org.apache.hc.client5.http.async", - "wiremock.org.apache.hc.client5.http.async.methods", - "wiremock.org.apache.hc.client5.http.auth", - "wiremock.org.apache.hc.client5.http.classic", - "wiremock.org.apache.hc.client5.http.classic.methods", - "wiremock.org.apache.hc.client5.http.config", - "wiremock.org.apache.hc.client5.http.cookie", - "wiremock.org.apache.hc.client5.http.entity", - "wiremock.org.apache.hc.client5.http.entity.mime", - "wiremock.org.apache.hc.client5.http.impl", - "wiremock.org.apache.hc.client5.http.impl.async", - "wiremock.org.apache.hc.client5.http.impl.auth", - "wiremock.org.apache.hc.client5.http.impl.classic", - "wiremock.org.apache.hc.client5.http.impl.compat", - "wiremock.org.apache.hc.client5.http.impl.cookie", - "wiremock.org.apache.hc.client5.http.impl.io", - "wiremock.org.apache.hc.client5.http.impl.nio", - "wiremock.org.apache.hc.client5.http.impl.routing", - "wiremock.org.apache.hc.client5.http.io", - "wiremock.org.apache.hc.client5.http.nio", - "wiremock.org.apache.hc.client5.http.protocol", - "wiremock.org.apache.hc.client5.http.psl", - "wiremock.org.apache.hc.client5.http.routing", - "wiremock.org.apache.hc.client5.http.socket", - "wiremock.org.apache.hc.client5.http.ssl", - "wiremock.org.apache.hc.client5.http.utils", - "wiremock.org.apache.hc.client5.http.validator", - "wiremock.org.apache.hc.core5.annotation", - "wiremock.org.apache.hc.core5.concurrent", - "wiremock.org.apache.hc.core5.function", - "wiremock.org.apache.hc.core5.http", - "wiremock.org.apache.hc.core5.http.config", - "wiremock.org.apache.hc.core5.http.impl", - "wiremock.org.apache.hc.core5.http.impl.bootstrap", - "wiremock.org.apache.hc.core5.http.impl.io", - "wiremock.org.apache.hc.core5.http.impl.nio", - "wiremock.org.apache.hc.core5.http.impl.routing", - "wiremock.org.apache.hc.core5.http.io", - "wiremock.org.apache.hc.core5.http.io.entity", - "wiremock.org.apache.hc.core5.http.io.ssl", - "wiremock.org.apache.hc.core5.http.io.support", - "wiremock.org.apache.hc.core5.http.message", - "wiremock.org.apache.hc.core5.http.nio", - "wiremock.org.apache.hc.core5.http.nio.command", - "wiremock.org.apache.hc.core5.http.nio.entity", - "wiremock.org.apache.hc.core5.http.nio.ssl", - "wiremock.org.apache.hc.core5.http.nio.support", - "wiremock.org.apache.hc.core5.http.nio.support.classic", - "wiremock.org.apache.hc.core5.http.protocol", - "wiremock.org.apache.hc.core5.http.ssl", - "wiremock.org.apache.hc.core5.http.support", - "wiremock.org.apache.hc.core5.http2", - "wiremock.org.apache.hc.core5.http2.config", - "wiremock.org.apache.hc.core5.http2.frame", - "wiremock.org.apache.hc.core5.http2.hpack", - "wiremock.org.apache.hc.core5.http2.impl", - "wiremock.org.apache.hc.core5.http2.impl.io", - "wiremock.org.apache.hc.core5.http2.impl.nio", - "wiremock.org.apache.hc.core5.http2.impl.nio.bootstrap", - "wiremock.org.apache.hc.core5.http2.nio", - "wiremock.org.apache.hc.core5.http2.nio.command", - "wiremock.org.apache.hc.core5.http2.nio.pool", - "wiremock.org.apache.hc.core5.http2.nio.support", - "wiremock.org.apache.hc.core5.http2.protocol", - "wiremock.org.apache.hc.core5.http2.ssl", - "wiremock.org.apache.hc.core5.io", - "wiremock.org.apache.hc.core5.net", - "wiremock.org.apache.hc.core5.pool", - "wiremock.org.apache.hc.core5.reactor", - "wiremock.org.apache.hc.core5.reactor.ssl", - "wiremock.org.apache.hc.core5.ssl", - "wiremock.org.apache.hc.core5.util", - "wiremock.org.custommonkey.xmlunit", - "wiremock.org.custommonkey.xmlunit.examples", - "wiremock.org.custommonkey.xmlunit.exceptions", - "wiremock.org.custommonkey.xmlunit.jaxp13", - "wiremock.org.custommonkey.xmlunit.util", - "wiremock.org.eclipse.jetty.alpn.client", - "wiremock.org.eclipse.jetty.alpn.java.client", - "wiremock.org.eclipse.jetty.alpn.java.server", - "wiremock.org.eclipse.jetty.alpn.server", - "wiremock.org.eclipse.jetty.client", - "wiremock.org.eclipse.jetty.client.api", - "wiremock.org.eclipse.jetty.client.dynamic", - "wiremock.org.eclipse.jetty.client.http", - "wiremock.org.eclipse.jetty.client.internal", - "wiremock.org.eclipse.jetty.client.jmx", - "wiremock.org.eclipse.jetty.client.util", - "wiremock.org.eclipse.jetty.http", - "wiremock.org.eclipse.jetty.http.compression", - "wiremock.org.eclipse.jetty.http.pathmap", - "wiremock.org.eclipse.jetty.http2", - "wiremock.org.eclipse.jetty.http2.api", - "wiremock.org.eclipse.jetty.http2.api.server", - "wiremock.org.eclipse.jetty.http2.frames", - "wiremock.org.eclipse.jetty.http2.generator", - "wiremock.org.eclipse.jetty.http2.hpack", - "wiremock.org.eclipse.jetty.http2.parser", - "wiremock.org.eclipse.jetty.http2.server", - "wiremock.org.eclipse.jetty.io", - "wiremock.org.eclipse.jetty.io.jmx", - "wiremock.org.eclipse.jetty.io.ssl", - "wiremock.org.eclipse.jetty.proxy", - "wiremock.org.eclipse.jetty.security", - "wiremock.org.eclipse.jetty.security.authentication", - "wiremock.org.eclipse.jetty.server", - "wiremock.org.eclipse.jetty.server.handler", - "wiremock.org.eclipse.jetty.server.handler.gzip", - "wiremock.org.eclipse.jetty.server.handler.jmx", - "wiremock.org.eclipse.jetty.server.jmx", - "wiremock.org.eclipse.jetty.server.resource", - "wiremock.org.eclipse.jetty.server.session", - "wiremock.org.eclipse.jetty.servlet", - "wiremock.org.eclipse.jetty.servlet.jmx", - "wiremock.org.eclipse.jetty.servlet.listener", - "wiremock.org.eclipse.jetty.servlets", - "wiremock.org.eclipse.jetty.util", - "wiremock.org.eclipse.jetty.util.annotation", - "wiremock.org.eclipse.jetty.util.component", - "wiremock.org.eclipse.jetty.util.compression", - "wiremock.org.eclipse.jetty.util.log", - "wiremock.org.eclipse.jetty.util.preventers", - "wiremock.org.eclipse.jetty.util.resource", - "wiremock.org.eclipse.jetty.util.security", - "wiremock.org.eclipse.jetty.util.ssl", - "wiremock.org.eclipse.jetty.util.statistic", - "wiremock.org.eclipse.jetty.util.thread", - "wiremock.org.eclipse.jetty.util.thread.strategy", - "wiremock.org.eclipse.jetty.webapp", - "wiremock.org.eclipse.jetty.xml", - "wiremock.org.hamcrest", - "wiremock.org.hamcrest.beans", - "wiremock.org.hamcrest.collection", - "wiremock.org.hamcrest.comparator", - "wiremock.org.hamcrest.core", - "wiremock.org.hamcrest.core.deprecated", - "wiremock.org.hamcrest.internal", - "wiremock.org.hamcrest.io", - "wiremock.org.hamcrest.number", - "wiremock.org.hamcrest.object", - "wiremock.org.hamcrest.text", - "wiremock.org.hamcrest.xml", - "wiremock.org.slf4j", - "wiremock.org.slf4j.event", - "wiremock.org.slf4j.helpers", - "wiremock.org.slf4j.spi", - "wiremock.org.xmlunit", - "wiremock.org.xmlunit.builder", - "wiremock.org.xmlunit.builder.javax_jaxb", - "wiremock.org.xmlunit.diff", - "wiremock.org.xmlunit.input", - "wiremock.org.xmlunit.placeholder", - "wiremock.org.xmlunit.transform", - "wiremock.org.xmlunit.util", - "wiremock.org.xmlunit.validation", - "wiremock.org.xmlunit.xpath", - "wiremock.org.yaml.snakeyaml", - "wiremock.org.yaml.snakeyaml.comments", - "wiremock.org.yaml.snakeyaml.composer", - "wiremock.org.yaml.snakeyaml.constructor", - "wiremock.org.yaml.snakeyaml.emitter", - "wiremock.org.yaml.snakeyaml.env", - "wiremock.org.yaml.snakeyaml.error", - "wiremock.org.yaml.snakeyaml.events", - "wiremock.org.yaml.snakeyaml.extensions.compactnotation", - "wiremock.org.yaml.snakeyaml.external.com.google.gdata.util.common.base", - "wiremock.org.yaml.snakeyaml.inspector", - "wiremock.org.yaml.snakeyaml.internal", - "wiremock.org.yaml.snakeyaml.introspector", - "wiremock.org.yaml.snakeyaml.nodes", - "wiremock.org.yaml.snakeyaml.parser", - "wiremock.org.yaml.snakeyaml.reader", - "wiremock.org.yaml.snakeyaml.representer", - "wiremock.org.yaml.snakeyaml.resolver", - "wiremock.org.yaml.snakeyaml.scanner", - "wiremock.org.yaml.snakeyaml.serializer", - "wiremock.org.yaml.snakeyaml.tokens", - "wiremock.org.yaml.snakeyaml.util" - ], - "org.xmlunit:xmlunit-core": [ - "org.xmlunit", - "org.xmlunit.builder", - "org.xmlunit.builder.javax_jaxb", - "org.xmlunit.diff", - "org.xmlunit.input", - "org.xmlunit.transform", - "org.xmlunit.util", - "org.xmlunit.validation", - "org.xmlunit.xpath" - ], - "org.yaml:snakeyaml": [ - "org.yaml.snakeyaml", - "org.yaml.snakeyaml.comments", - "org.yaml.snakeyaml.composer", - "org.yaml.snakeyaml.constructor", - "org.yaml.snakeyaml.emitter", - "org.yaml.snakeyaml.env", - "org.yaml.snakeyaml.error", - "org.yaml.snakeyaml.events", - "org.yaml.snakeyaml.extensions.compactnotation", - "org.yaml.snakeyaml.external.com.google.gdata.util.common.base", - "org.yaml.snakeyaml.inspector", - "org.yaml.snakeyaml.internal", - "org.yaml.snakeyaml.introspector", - "org.yaml.snakeyaml.nodes", - "org.yaml.snakeyaml.parser", - "org.yaml.snakeyaml.reader", - "org.yaml.snakeyaml.representer", - "org.yaml.snakeyaml.resolver", - "org.yaml.snakeyaml.scanner", - "org.yaml.snakeyaml.serializer", - "org.yaml.snakeyaml.tokens", - "org.yaml.snakeyaml.util" - ], - "software.amazon.awssdk:annotations": [ - "software.amazon.awssdk.annotations" - ], - "software.amazon.awssdk:checksums": [ - "software.amazon.awssdk.checksums", - "software.amazon.awssdk.checksums.internal" - ], - "software.amazon.awssdk:checksums-spi": [ - "software.amazon.awssdk.checksums.spi" - ], - "software.amazon.awssdk:endpoints-spi": [ - "software.amazon.awssdk.endpoints" - ], - "software.amazon.awssdk:http-auth-aws": [ - "software.amazon.awssdk.http.auth.aws.crt.internal.io", - "software.amazon.awssdk.http.auth.aws.crt.internal.signer", - "software.amazon.awssdk.http.auth.aws.crt.internal.util", - "software.amazon.awssdk.http.auth.aws.eventstream.internal.io", - "software.amazon.awssdk.http.auth.aws.eventstream.internal.signer", - "software.amazon.awssdk.http.auth.aws.internal.scheme", - "software.amazon.awssdk.http.auth.aws.internal.signer", - "software.amazon.awssdk.http.auth.aws.internal.signer.checksums", - "software.amazon.awssdk.http.auth.aws.internal.signer.chunkedencoding", - "software.amazon.awssdk.http.auth.aws.internal.signer.io", - "software.amazon.awssdk.http.auth.aws.internal.signer.util", - "software.amazon.awssdk.http.auth.aws.scheme", - "software.amazon.awssdk.http.auth.aws.signer" - ], - "software.amazon.awssdk:http-auth-spi": [ - "software.amazon.awssdk.http.auth.spi.internal.scheme", - "software.amazon.awssdk.http.auth.spi.internal.signer", - "software.amazon.awssdk.http.auth.spi.scheme", - "software.amazon.awssdk.http.auth.spi.signer" - ], - "software.amazon.awssdk:http-client-spi": [ - "software.amazon.awssdk.http", - "software.amazon.awssdk.http.async", - "software.amazon.awssdk.internal.http" - ], - "software.amazon.awssdk:identity-spi": [ - "software.amazon.awssdk.identity.spi", - "software.amazon.awssdk.identity.spi.internal" - ], - "software.amazon.awssdk:json-utils": [ - "software.amazon.awssdk.protocols.jsoncore", - "software.amazon.awssdk.protocols.jsoncore.internal" - ], - "software.amazon.awssdk:metrics-spi": [ - "software.amazon.awssdk.metrics", - "software.amazon.awssdk.metrics.internal" - ], - "software.amazon.awssdk:profiles": [ - "software.amazon.awssdk.profiles", - "software.amazon.awssdk.profiles.internal" - ], - "software.amazon.awssdk:regions": [ - "software.amazon.awssdk.regions", - "software.amazon.awssdk.regions.internal", - "software.amazon.awssdk.regions.internal.util", - "software.amazon.awssdk.regions.partitionmetadata", - "software.amazon.awssdk.regions.providers", - "software.amazon.awssdk.regions.regionmetadata", - "software.amazon.awssdk.regions.servicemetadata", - "software.amazon.awssdk.regions.util" - ], - "software.amazon.awssdk:retries": [ - "software.amazon.awssdk.retries", - "software.amazon.awssdk.retries.internal", - "software.amazon.awssdk.retries.internal.circuitbreaker", - "software.amazon.awssdk.retries.internal.ratelimiter" - ], - "software.amazon.awssdk:retries-spi": [ - "software.amazon.awssdk.retries.api", - "software.amazon.awssdk.retries.api.internal", - "software.amazon.awssdk.retries.api.internal.backoff" - ], - "software.amazon.awssdk:sdk-core": [ - "software.amazon.awssdk.core", - "software.amazon.awssdk.core.adapter", - "software.amazon.awssdk.core.async", - "software.amazon.awssdk.core.async.listener", - "software.amazon.awssdk.core.checksums", - "software.amazon.awssdk.core.client.builder", - "software.amazon.awssdk.core.client.config", - "software.amazon.awssdk.core.client.handler", - "software.amazon.awssdk.core.document", - "software.amazon.awssdk.core.document.internal", - "software.amazon.awssdk.core.endpointdiscovery", - "software.amazon.awssdk.core.endpointdiscovery.providers", - "software.amazon.awssdk.core.exception", - "software.amazon.awssdk.core.http", - "software.amazon.awssdk.core.identity", - "software.amazon.awssdk.core.interceptor", - "software.amazon.awssdk.core.interceptor.trait", - "software.amazon.awssdk.core.internal", - "software.amazon.awssdk.core.internal.async", - "software.amazon.awssdk.core.internal.capacity", - "software.amazon.awssdk.core.internal.checksums", - "software.amazon.awssdk.core.internal.chunked", - "software.amazon.awssdk.core.internal.compression", - "software.amazon.awssdk.core.internal.handler", - "software.amazon.awssdk.core.internal.http", - "software.amazon.awssdk.core.internal.http.async", - "software.amazon.awssdk.core.internal.http.loader", - "software.amazon.awssdk.core.internal.http.pipeline", - "software.amazon.awssdk.core.internal.http.pipeline.stages", - "software.amazon.awssdk.core.internal.http.pipeline.stages.utils", - "software.amazon.awssdk.core.internal.http.timers", - "software.amazon.awssdk.core.internal.interceptor", - "software.amazon.awssdk.core.internal.interceptor.trait", - "software.amazon.awssdk.core.internal.io", - "software.amazon.awssdk.core.internal.metrics", - "software.amazon.awssdk.core.internal.pagination.async", - "software.amazon.awssdk.core.internal.retry", - "software.amazon.awssdk.core.internal.signer", - "software.amazon.awssdk.core.internal.sync", - "software.amazon.awssdk.core.internal.transform", - "software.amazon.awssdk.core.internal.useragent", - "software.amazon.awssdk.core.internal.util", - "software.amazon.awssdk.core.internal.waiters", - "software.amazon.awssdk.core.io", - "software.amazon.awssdk.core.metrics", - "software.amazon.awssdk.core.pagination.async", - "software.amazon.awssdk.core.pagination.sync", - "software.amazon.awssdk.core.protocol", - "software.amazon.awssdk.core.retry", - "software.amazon.awssdk.core.retry.backoff", - "software.amazon.awssdk.core.retry.conditions", - "software.amazon.awssdk.core.runtime", - "software.amazon.awssdk.core.runtime.transform", - "software.amazon.awssdk.core.signer", - "software.amazon.awssdk.core.sync", - "software.amazon.awssdk.core.traits", - "software.amazon.awssdk.core.useragent", - "software.amazon.awssdk.core.util", - "software.amazon.awssdk.core.waiters" - ], - "software.amazon.awssdk:third-party-jackson-core": [ - "software.amazon.awssdk.thirdparty.jackson.core", - "software.amazon.awssdk.thirdparty.jackson.core.async", - "software.amazon.awssdk.thirdparty.jackson.core.base", - "software.amazon.awssdk.thirdparty.jackson.core.exc", - "software.amazon.awssdk.thirdparty.jackson.core.filter", - "software.amazon.awssdk.thirdparty.jackson.core.format", - "software.amazon.awssdk.thirdparty.jackson.core.internal.shaded.fdp.v2_19_4", - "software.amazon.awssdk.thirdparty.jackson.core.io", - "software.amazon.awssdk.thirdparty.jackson.core.io.schubfach", - "software.amazon.awssdk.thirdparty.jackson.core.json", - "software.amazon.awssdk.thirdparty.jackson.core.json.async", - "software.amazon.awssdk.thirdparty.jackson.core.sym", - "software.amazon.awssdk.thirdparty.jackson.core.type", - "software.amazon.awssdk.thirdparty.jackson.core.util" - ], - "software.amazon.awssdk:utils": [ - "software.amazon.awssdk.utils", - "software.amazon.awssdk.utils.async", - "software.amazon.awssdk.utils.builder", - "software.amazon.awssdk.utils.cache", - "software.amazon.awssdk.utils.cache.bounded", - "software.amazon.awssdk.utils.cache.lru", - "software.amazon.awssdk.utils.http", - "software.amazon.awssdk.utils.internal", - "software.amazon.awssdk.utils.internal.async", - "software.amazon.awssdk.utils.internal.proxy", - "software.amazon.awssdk.utils.io", - "software.amazon.awssdk.utils.uri", - "software.amazon.awssdk.utils.uri.internal" - ], - "tools.jackson.core:jackson-core": [ - "tools.jackson.core", - "tools.jackson.core.async", - "tools.jackson.core.base", - "tools.jackson.core.exc", - "tools.jackson.core.filter", - "tools.jackson.core.internal.shaded.fdp", - "tools.jackson.core.internal.shaded.fdp.bte", - "tools.jackson.core.internal.shaded.fdp.chr", - "tools.jackson.core.io", - "tools.jackson.core.io.schubfach", - "tools.jackson.core.json", - "tools.jackson.core.json.async", - "tools.jackson.core.sym", - "tools.jackson.core.tree", - "tools.jackson.core.type", - "tools.jackson.core.util" - ], - "tools.jackson.core:jackson-databind": [ - "tools.jackson.databind", - "tools.jackson.databind.annotation", - "tools.jackson.databind.cfg", - "tools.jackson.databind.deser", - "tools.jackson.databind.deser.bean", - "tools.jackson.databind.deser.impl", - "tools.jackson.databind.deser.jackson", - "tools.jackson.databind.deser.jdk", - "tools.jackson.databind.deser.std", - "tools.jackson.databind.exc", - "tools.jackson.databind.ext", - "tools.jackson.databind.ext.beans", - "tools.jackson.databind.ext.javatime", - "tools.jackson.databind.ext.javatime.deser", - "tools.jackson.databind.ext.javatime.deser.key", - "tools.jackson.databind.ext.javatime.ser", - "tools.jackson.databind.ext.javatime.ser.key", - "tools.jackson.databind.ext.javatime.util", - "tools.jackson.databind.ext.jdk8", - "tools.jackson.databind.ext.sql", - "tools.jackson.databind.introspect", - "tools.jackson.databind.json", - "tools.jackson.databind.jsonFormatVisitors", - "tools.jackson.databind.jsontype", - "tools.jackson.databind.jsontype.impl", - "tools.jackson.databind.module", - "tools.jackson.databind.node", - "tools.jackson.databind.ser", - "tools.jackson.databind.ser.bean", - "tools.jackson.databind.ser.impl", - "tools.jackson.databind.ser.jackson", - "tools.jackson.databind.ser.jdk", - "tools.jackson.databind.ser.std", - "tools.jackson.databind.type", - "tools.jackson.databind.util", - "tools.jackson.databind.util.internal" - ], - "tools.jackson.module:jackson-module-blackbird": [ - "tools.jackson.module.blackbird", - "tools.jackson.module.blackbird.deser", - "tools.jackson.module.blackbird.ser", - "tools.jackson.module.blackbird.util" - ] - }, - "repositories": { - "https://maven-central.storage-download.googleapis.com/maven2/": [ - "aopalliance:aopalliance", - "aopalliance:aopalliance:jar:sources", - "args4j:args4j", - "args4j:args4j:jar:sources", - "at.yawk.lz4:lz4-java", - "at.yawk.lz4:lz4-java:jar:sources", - "ch.qos.logback:logback-classic", - "ch.qos.logback:logback-classic:jar:sources", - "ch.qos.logback:logback-core", - "ch.qos.logback:logback-core:jar:sources", - "com.datastax.cassandra:cassandra-driver-core", - "com.datastax.cassandra:cassandra-driver-core:jar:sources", - "com.datastax.oss:native-protocol", - "com.datastax.oss:native-protocol:jar:sources", - "com.fasterxml.jackson.core:jackson-annotations", - "com.fasterxml.jackson.core:jackson-annotations:jar:sources", - "com.fasterxml.jackson.core:jackson-core", - "com.fasterxml.jackson.core:jackson-core:jar:sources", - "com.fasterxml.jackson.core:jackson-databind", - "com.fasterxml.jackson.core:jackson-databind:jar:sources", - "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml", - "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:jar:sources", - "com.fasterxml.jackson.datatype:jackson-datatype-jsr310", - "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:jar:sources", - "com.fasterxml:classmate", - "com.fasterxml:classmate:jar:sources", - "com.github.ben-manes.caffeine:caffeine", - "com.github.ben-manes.caffeine:caffeine:jar:sources", - "com.github.ben-manes.caffeine:guava", - "com.github.ben-manes.caffeine:guava:jar:sources", - "com.github.docker-java:docker-java-api", - "com.github.docker-java:docker-java-api:jar:sources", - "com.github.docker-java:docker-java-transport", - "com.github.docker-java:docker-java-transport-zerodep", - "com.github.docker-java:docker-java-transport-zerodep:jar:sources", - "com.github.docker-java:docker-java-transport:jar:sources", - "com.github.java-json-tools:btf", - "com.github.java-json-tools:btf:jar:sources", - "com.github.java-json-tools:jackson-coreutils", - "com.github.java-json-tools:jackson-coreutils:jar:sources", - "com.github.java-json-tools:json-patch", - "com.github.java-json-tools:json-patch:jar:sources", - "com.github.java-json-tools:msg-simple", - "com.github.java-json-tools:msg-simple:jar:sources", - "com.github.jnr:jffi", - "com.github.jnr:jffi:jar:native", - "com.github.jnr:jffi:jar:sources", - "com.github.jnr:jnr-constants", - "com.github.jnr:jnr-constants:jar:sources", - "com.github.jnr:jnr-ffi", - "com.github.jnr:jnr-ffi:jar:sources", - "com.github.jnr:jnr-posix", - "com.github.jnr:jnr-posix:jar:sources", - "com.github.jnr:jnr-x86asm", - "com.github.jnr:jnr-x86asm:jar:sources", - "com.github.stephenc.jcip:jcip-annotations", - "com.github.stephenc.jcip:jcip-annotations:jar:sources", - "com.google.code.findbugs:jsr305", - "com.google.errorprone:error_prone_annotations", - "com.google.errorprone:error_prone_annotations:jar:sources", - "com.google.guava:failureaccess", - "com.google.guava:failureaccess:jar:sources", - "com.google.guava:guava", - "com.google.guava:guava:jar:sources", - "com.google.guava:listenablefuture", - "com.google.j2objc:j2objc-annotations", - "com.google.j2objc:j2objc-annotations:jar:sources", - "com.jayway.jsonpath:json-path", - "com.jayway.jsonpath:json-path:jar:sources", - "com.nimbusds:content-type", - "com.nimbusds:content-type:jar:sources", - "com.nimbusds:lang-tag", - "com.nimbusds:lang-tag:jar:sources", - "com.nimbusds:nimbus-jose-jwt", - "com.nimbusds:nimbus-jose-jwt:jar:sources", - "com.nimbusds:oauth2-oidc-sdk", - "com.nimbusds:oauth2-oidc-sdk:jar:sources", - "com.squareup.okhttp3:okhttp-jvm", - "com.squareup.okhttp3:okhttp-jvm:jar:sources", - "com.squareup.okio:okio-jvm", - "com.squareup.okio:okio-jvm:jar:sources", - "com.typesafe:config", - "com.typesafe:config:jar:sources", - "com.vaadin.external.google:android-json", - "com.vaadin.external.google:android-json:jar:sources", - "commons-codec:commons-codec", - "commons-codec:commons-codec:jar:sources", - "commons-io:commons-io", - "commons-io:commons-io:jar:sources", - "commons-logging:commons-logging", - "commons-logging:commons-logging:jar:sources", - "io.cloudevents:cloudevents-api", - "io.cloudevents:cloudevents-api:jar:sources", - "io.cloudevents:cloudevents-core", - "io.cloudevents:cloudevents-core:jar:sources", - "io.cloudevents:cloudevents-json-jackson", - "io.cloudevents:cloudevents-json-jackson:jar:sources", - "io.dropwizard.metrics:metrics-core", - "io.dropwizard.metrics:metrics-core:jar:sources", - "io.micrometer:context-propagation", - "io.micrometer:context-propagation:jar:sources", - "io.micrometer:micrometer-commons", - "io.micrometer:micrometer-commons:jar:sources", - "io.micrometer:micrometer-core", - "io.micrometer:micrometer-core:jar:sources", - "io.micrometer:micrometer-jakarta9", - "io.micrometer:micrometer-jakarta9:jar:sources", - "io.micrometer:micrometer-observation", - "io.micrometer:micrometer-observation-test", - "io.micrometer:micrometer-observation-test:jar:sources", - "io.micrometer:micrometer-observation:jar:sources", - "io.micrometer:micrometer-tracing", - "io.micrometer:micrometer-tracing-bridge-otel", - "io.micrometer:micrometer-tracing-bridge-otel:jar:sources", - "io.micrometer:micrometer-tracing:jar:sources", - "io.nats:jnats", - "io.nats:jnats:jar:sources", - "io.netty:netty-buffer", - "io.netty:netty-buffer:jar:sources", - "io.netty:netty-codec-base", - "io.netty:netty-codec-base:jar:sources", - "io.netty:netty-codec-classes-quic", - "io.netty:netty-codec-classes-quic:jar:sources", - "io.netty:netty-codec-compression", - "io.netty:netty-codec-compression:jar:sources", - "io.netty:netty-codec-dns", - "io.netty:netty-codec-dns:jar:sources", - "io.netty:netty-codec-http", - "io.netty:netty-codec-http2", - "io.netty:netty-codec-http2:jar:sources", - "io.netty:netty-codec-http3", - "io.netty:netty-codec-http3:jar:sources", - "io.netty:netty-codec-http:jar:sources", - "io.netty:netty-codec-native-quic:jar:linux-aarch_64", - "io.netty:netty-codec-native-quic:jar:linux-x86_64", - "io.netty:netty-codec-native-quic:jar:osx-aarch_64", - "io.netty:netty-codec-native-quic:jar:osx-x86_64", - "io.netty:netty-codec-native-quic:jar:sources", - "io.netty:netty-codec-native-quic:jar:windows-x86_64", - "io.netty:netty-codec-socks", - "io.netty:netty-codec-socks:jar:sources", - "io.netty:netty-common", - "io.netty:netty-common:jar:sources", - "io.netty:netty-handler", - "io.netty:netty-handler-proxy", - "io.netty:netty-handler-proxy:jar:sources", - "io.netty:netty-handler:jar:sources", - "io.netty:netty-resolver", - "io.netty:netty-resolver-dns", - "io.netty:netty-resolver-dns-classes-macos", - "io.netty:netty-resolver-dns-classes-macos:jar:sources", - "io.netty:netty-resolver-dns-native-macos:jar:osx-x86_64", - "io.netty:netty-resolver-dns-native-macos:jar:sources", - "io.netty:netty-resolver-dns:jar:sources", - "io.netty:netty-resolver:jar:sources", - "io.netty:netty-transport", - "io.netty:netty-transport-classes-epoll", - "io.netty:netty-transport-classes-epoll:jar:sources", - "io.netty:netty-transport-native-epoll:jar:linux-x86_64", - "io.netty:netty-transport-native-epoll:jar:sources", - "io.netty:netty-transport-native-unix-common", - "io.netty:netty-transport-native-unix-common:jar:sources", - "io.netty:netty-transport:jar:sources", - "io.opentelemetry.semconv:opentelemetry-semconv", - "io.opentelemetry.semconv:opentelemetry-semconv:jar:sources", - "io.opentelemetry:opentelemetry-api", - "io.opentelemetry:opentelemetry-api:jar:sources", - "io.opentelemetry:opentelemetry-common", - "io.opentelemetry:opentelemetry-common:jar:sources", - "io.opentelemetry:opentelemetry-context", - "io.opentelemetry:opentelemetry-context:jar:sources", - "io.opentelemetry:opentelemetry-exporter-common", - "io.opentelemetry:opentelemetry-exporter-common:jar:sources", - "io.opentelemetry:opentelemetry-exporter-otlp", - "io.opentelemetry:opentelemetry-exporter-otlp-common", - "io.opentelemetry:opentelemetry-exporter-otlp-common:jar:sources", - "io.opentelemetry:opentelemetry-exporter-otlp:jar:sources", - "io.opentelemetry:opentelemetry-exporter-sender-okhttp", - "io.opentelemetry:opentelemetry-exporter-sender-okhttp:jar:sources", - "io.opentelemetry:opentelemetry-extension-trace-propagators", - "io.opentelemetry:opentelemetry-extension-trace-propagators:jar:sources", - "io.opentelemetry:opentelemetry-sdk", - "io.opentelemetry:opentelemetry-sdk-common", - "io.opentelemetry:opentelemetry-sdk-common:jar:sources", - "io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi", - "io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi:jar:sources", - "io.opentelemetry:opentelemetry-sdk-logs", - "io.opentelemetry:opentelemetry-sdk-logs:jar:sources", - "io.opentelemetry:opentelemetry-sdk-metrics", - "io.opentelemetry:opentelemetry-sdk-metrics:jar:sources", - "io.opentelemetry:opentelemetry-sdk-testing", - "io.opentelemetry:opentelemetry-sdk-testing:jar:sources", - "io.opentelemetry:opentelemetry-sdk-trace", - "io.opentelemetry:opentelemetry-sdk-trace:jar:sources", - "io.opentelemetry:opentelemetry-sdk:jar:sources", - "io.projectreactor.netty:reactor-netty-core", - "io.projectreactor.netty:reactor-netty-core:jar:sources", - "io.projectreactor.netty:reactor-netty-http", - "io.projectreactor.netty:reactor-netty-http:jar:sources", - "io.projectreactor:reactor-core", - "io.projectreactor:reactor-core:jar:sources", - "io.projectreactor:reactor-test", - "io.projectreactor:reactor-test:jar:sources", - "io.swagger.core.v3:swagger-annotations-jakarta", - "io.swagger.core.v3:swagger-annotations-jakarta:jar:sources", - "io.swagger.core.v3:swagger-core-jakarta", - "io.swagger.core.v3:swagger-core-jakarta:jar:sources", - "io.swagger.core.v3:swagger-models-jakarta", - "io.swagger.core.v3:swagger-models-jakarta:jar:sources", - "jakarta.activation:jakarta.activation-api", - "jakarta.activation:jakarta.activation-api:jar:sources", - "jakarta.annotation:jakarta.annotation-api", - "jakarta.annotation:jakarta.annotation-api:jar:sources", - "jakarta.servlet:jakarta.servlet-api", - "jakarta.servlet:jakarta.servlet-api:jar:sources", - "jakarta.validation:jakarta.validation-api", - "jakarta.validation:jakarta.validation-api:jar:sources", - "jakarta.xml.bind:jakarta.xml.bind-api", - "jakarta.xml.bind:jakarta.xml.bind-api:jar:sources", - "net.bytebuddy:byte-buddy", - "net.bytebuddy:byte-buddy-agent", - "net.bytebuddy:byte-buddy-agent:jar:sources", - "net.bytebuddy:byte-buddy:jar:sources", - "net.java.dev.jna:jna", - "net.java.dev.jna:jna:jar:sources", - "net.minidev:accessors-smart", - "net.minidev:accessors-smart:jar:sources", - "net.minidev:json-smart", - "net.minidev:json-smart:jar:sources", - "org.apache.cassandra:java-driver-core", - "org.apache.cassandra:java-driver-core:jar:sources", - "org.apache.cassandra:java-driver-guava-shaded", - "org.apache.cassandra:java-driver-guava-shaded:jar:sources", - "org.apache.cassandra:java-driver-metrics-micrometer", - "org.apache.cassandra:java-driver-metrics-micrometer:jar:sources", - "org.apache.cassandra:java-driver-query-builder", - "org.apache.cassandra:java-driver-query-builder:jar:sources", - "org.apache.commons:commons-compress", - "org.apache.commons:commons-compress:jar:sources", - "org.apache.commons:commons-lang3", - "org.apache.commons:commons-lang3:jar:sources", - "org.apache.logging.log4j:log4j-api", - "org.apache.logging.log4j:log4j-api:jar:sources", - "org.apache.logging.log4j:log4j-to-slf4j", - "org.apache.logging.log4j:log4j-to-slf4j:jar:sources", - "org.apache.tomcat.embed:tomcat-embed-core", - "org.apache.tomcat.embed:tomcat-embed-core:jar:sources", - "org.apache.tomcat.embed:tomcat-embed-el", - "org.apache.tomcat.embed:tomcat-embed-el:jar:sources", - "org.apache.tomcat.embed:tomcat-embed-websocket", - "org.apache.tomcat.embed:tomcat-embed-websocket:jar:sources", - "org.apiguardian:apiguardian-api", - "org.apiguardian:apiguardian-api:jar:sources", - "org.assertj:assertj-core", - "org.assertj:assertj-core:jar:sources", - "org.awaitility:awaitility", - "org.awaitility:awaitility:jar:sources", - "org.bouncycastle:bcprov-jdk18on", - "org.bouncycastle:bcprov-jdk18on:jar:sources", - "org.bouncycastle:bcprov-lts8on", - "org.bouncycastle:bcprov-lts8on:jar:sources", - "org.hamcrest:hamcrest", - "org.hamcrest:hamcrest:jar:sources", - "org.hdrhistogram:HdrHistogram", - "org.hdrhistogram:HdrHistogram:jar:sources", - "org.hibernate.validator:hibernate-validator", - "org.hibernate.validator:hibernate-validator:jar:sources", - "org.jacoco:org.jacoco.agent:jar:runtime", - "org.jacoco:org.jacoco.agent:jar:sources", - "org.jacoco:org.jacoco.cli", - "org.jacoco:org.jacoco.cli:jar:sources", - "org.jacoco:org.jacoco.core", - "org.jacoco:org.jacoco.core:jar:sources", - "org.jacoco:org.jacoco.report", - "org.jacoco:org.jacoco.report:jar:sources", - "org.jboss.logging:jboss-logging", - "org.jboss.logging:jboss-logging:jar:sources", - "org.jetbrains.kotlin:kotlin-stdlib", - "org.jetbrains.kotlin:kotlin-stdlib:jar:sources", - "org.jetbrains:annotations", - "org.jetbrains:annotations:jar:sources", - "org.jspecify:jspecify", - "org.jspecify:jspecify:jar:sources", - "org.junit.jupiter:junit-jupiter", - "org.junit.jupiter:junit-jupiter-api", - "org.junit.jupiter:junit-jupiter-api:jar:sources", - "org.junit.jupiter:junit-jupiter-engine", - "org.junit.jupiter:junit-jupiter-engine:jar:sources", - "org.junit.jupiter:junit-jupiter-params", - "org.junit.jupiter:junit-jupiter-params:jar:sources", - "org.junit.jupiter:junit-jupiter:jar:sources", - "org.junit.platform:junit-platform-commons", - "org.junit.platform:junit-platform-commons:jar:sources", - "org.junit.platform:junit-platform-console-standalone", - "org.junit.platform:junit-platform-console-standalone:jar:sources", - "org.junit.platform:junit-platform-engine", - "org.junit.platform:junit-platform-engine:jar:sources", - "org.latencyutils:LatencyUtils", - "org.latencyutils:LatencyUtils:jar:sources", - "org.mockito:mockito-core", - "org.mockito:mockito-core:jar:sources", - "org.mockito:mockito-junit-jupiter", - "org.mockito:mockito-junit-jupiter:jar:sources", - "org.objenesis:objenesis", - "org.objenesis:objenesis:jar:sources", - "org.opentest4j:opentest4j", - "org.opentest4j:opentest4j:jar:sources", - "org.ow2.asm:asm", - "org.ow2.asm:asm-analysis", - "org.ow2.asm:asm-analysis:jar:sources", - "org.ow2.asm:asm-commons", - "org.ow2.asm:asm-commons:jar:sources", - "org.ow2.asm:asm-tree", - "org.ow2.asm:asm-tree:jar:sources", - "org.ow2.asm:asm-util", - "org.ow2.asm:asm-util:jar:sources", - "org.ow2.asm:asm:jar:sources", - "org.projectlombok:lombok", - "org.projectlombok:lombok:jar:sources", - "org.reactivestreams:reactive-streams", - "org.reactivestreams:reactive-streams:jar:sources", - "org.rnorth.duct-tape:duct-tape", - "org.rnorth.duct-tape:duct-tape:jar:sources", - "org.skyscreamer:jsonassert", - "org.skyscreamer:jsonassert:jar:sources", - "org.slf4j:jul-to-slf4j", - "org.slf4j:jul-to-slf4j:jar:sources", - "org.slf4j:slf4j-api", - "org.slf4j:slf4j-api:jar:sources", - "org.springdoc:springdoc-openapi-starter-common", - "org.springdoc:springdoc-openapi-starter-common:jar:sources", - "org.springdoc:springdoc-openapi-starter-webflux-api", - "org.springdoc:springdoc-openapi-starter-webflux-api:jar:sources", - "org.springdoc:springdoc-openapi-starter-webmvc-api", - "org.springdoc:springdoc-openapi-starter-webmvc-api:jar:sources", - "org.springframework.boot:spring-boot", - "org.springframework.boot:spring-boot-actuator", - "org.springframework.boot:spring-boot-actuator-autoconfigure", - "org.springframework.boot:spring-boot-actuator-autoconfigure:jar:sources", - "org.springframework.boot:spring-boot-actuator:jar:sources", - "org.springframework.boot:spring-boot-autoconfigure", - "org.springframework.boot:spring-boot-autoconfigure:jar:sources", - "org.springframework.boot:spring-boot-cassandra", - "org.springframework.boot:spring-boot-cassandra:jar:sources", - "org.springframework.boot:spring-boot-data-cassandra", - "org.springframework.boot:spring-boot-data-cassandra-test", - "org.springframework.boot:spring-boot-data-cassandra-test:jar:sources", - "org.springframework.boot:spring-boot-data-cassandra:jar:sources", - "org.springframework.boot:spring-boot-data-commons", - "org.springframework.boot:spring-boot-data-commons:jar:sources", - "org.springframework.boot:spring-boot-health", - "org.springframework.boot:spring-boot-health:jar:sources", - "org.springframework.boot:spring-boot-http-client", - "org.springframework.boot:spring-boot-http-client:jar:sources", - "org.springframework.boot:spring-boot-http-codec", - "org.springframework.boot:spring-boot-http-codec:jar:sources", - "org.springframework.boot:spring-boot-http-converter", - "org.springframework.boot:spring-boot-http-converter:jar:sources", - "org.springframework.boot:spring-boot-jackson", - "org.springframework.boot:spring-boot-jackson:jar:sources", - "org.springframework.boot:spring-boot-micrometer-metrics", - "org.springframework.boot:spring-boot-micrometer-metrics-test", - "org.springframework.boot:spring-boot-micrometer-metrics-test:jar:sources", - "org.springframework.boot:spring-boot-micrometer-metrics:jar:sources", - "org.springframework.boot:spring-boot-micrometer-observation", - "org.springframework.boot:spring-boot-micrometer-observation:jar:sources", - "org.springframework.boot:spring-boot-micrometer-tracing", - "org.springframework.boot:spring-boot-micrometer-tracing-opentelemetry", - "org.springframework.boot:spring-boot-micrometer-tracing-opentelemetry:jar:sources", - "org.springframework.boot:spring-boot-micrometer-tracing:jar:sources", - "org.springframework.boot:spring-boot-netty", - "org.springframework.boot:spring-boot-netty:jar:sources", - "org.springframework.boot:spring-boot-opentelemetry", - "org.springframework.boot:spring-boot-opentelemetry:jar:sources", - "org.springframework.boot:spring-boot-persistence", - "org.springframework.boot:spring-boot-persistence:jar:sources", - "org.springframework.boot:spring-boot-reactor", - "org.springframework.boot:spring-boot-reactor-netty", - "org.springframework.boot:spring-boot-reactor-netty:jar:sources", - "org.springframework.boot:spring-boot-reactor:jar:sources", - "org.springframework.boot:spring-boot-restclient", - "org.springframework.boot:spring-boot-restclient:jar:sources", - "org.springframework.boot:spring-boot-resttestclient", - "org.springframework.boot:spring-boot-resttestclient:jar:sources", - "org.springframework.boot:spring-boot-security", - "org.springframework.boot:spring-boot-security-oauth2-client", - "org.springframework.boot:spring-boot-security-oauth2-client:jar:sources", - "org.springframework.boot:spring-boot-security-oauth2-resource-server", - "org.springframework.boot:spring-boot-security-oauth2-resource-server:jar:sources", - "org.springframework.boot:spring-boot-security-test", - "org.springframework.boot:spring-boot-security-test:jar:sources", - "org.springframework.boot:spring-boot-security:jar:sources", - "org.springframework.boot:spring-boot-servlet", - "org.springframework.boot:spring-boot-servlet:jar:sources", - "org.springframework.boot:spring-boot-starter", - "org.springframework.boot:spring-boot-starter-actuator", - "org.springframework.boot:spring-boot-starter-actuator-test", - "org.springframework.boot:spring-boot-starter-actuator-test:jar:sources", - "org.springframework.boot:spring-boot-starter-actuator:jar:sources", - "org.springframework.boot:spring-boot-starter-data-cassandra", - "org.springframework.boot:spring-boot-starter-data-cassandra-test", - "org.springframework.boot:spring-boot-starter-data-cassandra-test:jar:sources", - "org.springframework.boot:spring-boot-starter-data-cassandra:jar:sources", - "org.springframework.boot:spring-boot-starter-jackson", - "org.springframework.boot:spring-boot-starter-jackson-test", - "org.springframework.boot:spring-boot-starter-jackson-test:jar:sources", - "org.springframework.boot:spring-boot-starter-jackson:jar:sources", - "org.springframework.boot:spring-boot-starter-logging", - "org.springframework.boot:spring-boot-starter-logging:jar:sources", - "org.springframework.boot:spring-boot-starter-micrometer-metrics", - "org.springframework.boot:spring-boot-starter-micrometer-metrics-test", - "org.springframework.boot:spring-boot-starter-micrometer-metrics-test:jar:sources", - "org.springframework.boot:spring-boot-starter-micrometer-metrics:jar:sources", - "org.springframework.boot:spring-boot-starter-reactor-netty", - "org.springframework.boot:spring-boot-starter-reactor-netty:jar:sources", - "org.springframework.boot:spring-boot-starter-security", - "org.springframework.boot:spring-boot-starter-security-oauth2-client", - "org.springframework.boot:spring-boot-starter-security-oauth2-client:jar:sources", - "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server", - "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server-test", - "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server-test:jar:sources", - "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server:jar:sources", - "org.springframework.boot:spring-boot-starter-security-test", - "org.springframework.boot:spring-boot-starter-security-test:jar:sources", - "org.springframework.boot:spring-boot-starter-security:jar:sources", - "org.springframework.boot:spring-boot-starter-test", - "org.springframework.boot:spring-boot-starter-test:jar:sources", - "org.springframework.boot:spring-boot-starter-tomcat", - "org.springframework.boot:spring-boot-starter-tomcat-runtime", - "org.springframework.boot:spring-boot-starter-tomcat-runtime:jar:sources", - "org.springframework.boot:spring-boot-starter-tomcat:jar:sources", - "org.springframework.boot:spring-boot-starter-validation", - "org.springframework.boot:spring-boot-starter-validation:jar:sources", - "org.springframework.boot:spring-boot-starter-webflux", - "org.springframework.boot:spring-boot-starter-webflux-test", - "org.springframework.boot:spring-boot-starter-webflux-test:jar:sources", - "org.springframework.boot:spring-boot-starter-webflux:jar:sources", - "org.springframework.boot:spring-boot-starter-webmvc", - "org.springframework.boot:spring-boot-starter-webmvc-test", - "org.springframework.boot:spring-boot-starter-webmvc-test:jar:sources", - "org.springframework.boot:spring-boot-starter-webmvc:jar:sources", - "org.springframework.boot:spring-boot-starter:jar:sources", - "org.springframework.boot:spring-boot-test", - "org.springframework.boot:spring-boot-test-autoconfigure", - "org.springframework.boot:spring-boot-test-autoconfigure:jar:sources", - "org.springframework.boot:spring-boot-test:jar:sources", - "org.springframework.boot:spring-boot-tomcat", - "org.springframework.boot:spring-boot-tomcat:jar:sources", - "org.springframework.boot:spring-boot-validation", - "org.springframework.boot:spring-boot-validation:jar:sources", - "org.springframework.boot:spring-boot-web-server", - "org.springframework.boot:spring-boot-web-server:jar:sources", - "org.springframework.boot:spring-boot-webclient", - "org.springframework.boot:spring-boot-webclient:jar:sources", - "org.springframework.boot:spring-boot-webflux", - "org.springframework.boot:spring-boot-webflux-test", - "org.springframework.boot:spring-boot-webflux-test:jar:sources", - "org.springframework.boot:spring-boot-webflux:jar:sources", - "org.springframework.boot:spring-boot-webmvc", - "org.springframework.boot:spring-boot-webmvc-test", - "org.springframework.boot:spring-boot-webmvc-test:jar:sources", - "org.springframework.boot:spring-boot-webmvc:jar:sources", - "org.springframework.boot:spring-boot-webtestclient", - "org.springframework.boot:spring-boot-webtestclient:jar:sources", - "org.springframework.boot:spring-boot:jar:sources", - "org.springframework.cloud:spring-cloud-commons", - "org.springframework.cloud:spring-cloud-commons:jar:sources", - "org.springframework.cloud:spring-cloud-context", - "org.springframework.cloud:spring-cloud-context:jar:sources", - "org.springframework.cloud:spring-cloud-starter", - "org.springframework.cloud:spring-cloud-starter-bootstrap", - "org.springframework.cloud:spring-cloud-starter-bootstrap:jar:sources", - "org.springframework.data:spring-data-cassandra", - "org.springframework.data:spring-data-cassandra:jar:sources", - "org.springframework.data:spring-data-commons", - "org.springframework.data:spring-data-commons:jar:sources", - "org.springframework.security:spring-security-config", - "org.springframework.security:spring-security-config:jar:sources", - "org.springframework.security:spring-security-core", - "org.springframework.security:spring-security-core:jar:sources", - "org.springframework.security:spring-security-crypto", - "org.springframework.security:spring-security-crypto:jar:sources", - "org.springframework.security:spring-security-oauth2-client", - "org.springframework.security:spring-security-oauth2-client:jar:sources", - "org.springframework.security:spring-security-oauth2-core", - "org.springframework.security:spring-security-oauth2-core:jar:sources", - "org.springframework.security:spring-security-oauth2-jose", - "org.springframework.security:spring-security-oauth2-jose:jar:sources", - "org.springframework.security:spring-security-oauth2-resource-server", - "org.springframework.security:spring-security-oauth2-resource-server:jar:sources", - "org.springframework.security:spring-security-test", - "org.springframework.security:spring-security-test:jar:sources", - "org.springframework.security:spring-security-web", - "org.springframework.security:spring-security-web:jar:sources", - "org.springframework:spring-aop", - "org.springframework:spring-aop:jar:sources", - "org.springframework:spring-beans", - "org.springframework:spring-beans:jar:sources", - "org.springframework:spring-context", - "org.springframework:spring-context:jar:sources", - "org.springframework:spring-core", - "org.springframework:spring-core:jar:sources", - "org.springframework:spring-expression", - "org.springframework:spring-expression:jar:sources", - "org.springframework:spring-test", - "org.springframework:spring-test:jar:sources", - "org.springframework:spring-tx", - "org.springframework:spring-tx:jar:sources", - "org.springframework:spring-web", - "org.springframework:spring-web:jar:sources", - "org.springframework:spring-webflux", - "org.springframework:spring-webflux:jar:sources", - "org.springframework:spring-webmvc", - "org.springframework:spring-webmvc:jar:sources", - "org.testcontainers:testcontainers", - "org.testcontainers:testcontainers-cassandra", - "org.testcontainers:testcontainers-cassandra:jar:sources", - "org.testcontainers:testcontainers-database-commons", - "org.testcontainers:testcontainers-database-commons:jar:sources", - "org.testcontainers:testcontainers-junit-jupiter", - "org.testcontainers:testcontainers-junit-jupiter:jar:sources", - "org.testcontainers:testcontainers:jar:sources", - "org.wiremock:wiremock-standalone", - "org.wiremock:wiremock-standalone:jar:sources", - "org.xmlunit:xmlunit-core", - "org.xmlunit:xmlunit-core:jar:sources", - "org.yaml:snakeyaml", - "org.yaml:snakeyaml:jar:sources", - "software.amazon.awssdk:annotations", - "software.amazon.awssdk:annotations:jar:sources", - "software.amazon.awssdk:checksums", - "software.amazon.awssdk:checksums-spi", - "software.amazon.awssdk:checksums-spi:jar:sources", - "software.amazon.awssdk:checksums:jar:sources", - "software.amazon.awssdk:endpoints-spi", - "software.amazon.awssdk:endpoints-spi:jar:sources", - "software.amazon.awssdk:http-auth-aws", - "software.amazon.awssdk:http-auth-aws:jar:sources", - "software.amazon.awssdk:http-auth-spi", - "software.amazon.awssdk:http-auth-spi:jar:sources", - "software.amazon.awssdk:http-client-spi", - "software.amazon.awssdk:http-client-spi:jar:sources", - "software.amazon.awssdk:identity-spi", - "software.amazon.awssdk:identity-spi:jar:sources", - "software.amazon.awssdk:json-utils", - "software.amazon.awssdk:json-utils:jar:sources", - "software.amazon.awssdk:metrics-spi", - "software.amazon.awssdk:metrics-spi:jar:sources", - "software.amazon.awssdk:profiles", - "software.amazon.awssdk:profiles:jar:sources", - "software.amazon.awssdk:regions", - "software.amazon.awssdk:regions:jar:sources", - "software.amazon.awssdk:retries", - "software.amazon.awssdk:retries-spi", - "software.amazon.awssdk:retries-spi:jar:sources", - "software.amazon.awssdk:retries:jar:sources", - "software.amazon.awssdk:sdk-core", - "software.amazon.awssdk:sdk-core:jar:sources", - "software.amazon.awssdk:third-party-jackson-core", - "software.amazon.awssdk:third-party-jackson-core:jar:sources", - "software.amazon.awssdk:utils", - "software.amazon.awssdk:utils:jar:sources", - "tools.jackson.core:jackson-core", - "tools.jackson.core:jackson-core:jar:sources", - "tools.jackson.core:jackson-databind", - "tools.jackson.core:jackson-databind:jar:sources", - "tools.jackson.module:jackson-module-blackbird", - "tools.jackson.module:jackson-module-blackbird:jar:sources" - ], - "https://repo.maven.apache.org/maven2/": [ - "aopalliance:aopalliance", - "aopalliance:aopalliance:jar:sources", - "args4j:args4j", - "args4j:args4j:jar:sources", - "at.yawk.lz4:lz4-java", - "at.yawk.lz4:lz4-java:jar:sources", - "ch.qos.logback:logback-classic", - "ch.qos.logback:logback-classic:jar:sources", - "ch.qos.logback:logback-core", - "ch.qos.logback:logback-core:jar:sources", - "com.datastax.cassandra:cassandra-driver-core", - "com.datastax.cassandra:cassandra-driver-core:jar:sources", - "com.datastax.oss:native-protocol", - "com.datastax.oss:native-protocol:jar:sources", - "com.fasterxml.jackson.core:jackson-annotations", - "com.fasterxml.jackson.core:jackson-annotations:jar:sources", - "com.fasterxml.jackson.core:jackson-core", - "com.fasterxml.jackson.core:jackson-core:jar:sources", - "com.fasterxml.jackson.core:jackson-databind", - "com.fasterxml.jackson.core:jackson-databind:jar:sources", - "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml", - "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:jar:sources", - "com.fasterxml.jackson.datatype:jackson-datatype-jsr310", - "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:jar:sources", - "com.fasterxml:classmate", - "com.fasterxml:classmate:jar:sources", - "com.github.ben-manes.caffeine:caffeine", - "com.github.ben-manes.caffeine:caffeine:jar:sources", - "com.github.ben-manes.caffeine:guava", - "com.github.ben-manes.caffeine:guava:jar:sources", - "com.github.docker-java:docker-java-api", - "com.github.docker-java:docker-java-api:jar:sources", - "com.github.docker-java:docker-java-transport", - "com.github.docker-java:docker-java-transport-zerodep", - "com.github.docker-java:docker-java-transport-zerodep:jar:sources", - "com.github.docker-java:docker-java-transport:jar:sources", - "com.github.java-json-tools:btf", - "com.github.java-json-tools:btf:jar:sources", - "com.github.java-json-tools:jackson-coreutils", - "com.github.java-json-tools:jackson-coreutils:jar:sources", - "com.github.java-json-tools:json-patch", - "com.github.java-json-tools:json-patch:jar:sources", - "com.github.java-json-tools:msg-simple", - "com.github.java-json-tools:msg-simple:jar:sources", - "com.github.jnr:jffi", - "com.github.jnr:jffi:jar:native", - "com.github.jnr:jffi:jar:sources", - "com.github.jnr:jnr-constants", - "com.github.jnr:jnr-constants:jar:sources", - "com.github.jnr:jnr-ffi", - "com.github.jnr:jnr-ffi:jar:sources", - "com.github.jnr:jnr-posix", - "com.github.jnr:jnr-posix:jar:sources", - "com.github.jnr:jnr-x86asm", - "com.github.jnr:jnr-x86asm:jar:sources", - "com.github.stephenc.jcip:jcip-annotations", - "com.github.stephenc.jcip:jcip-annotations:jar:sources", - "com.google.code.findbugs:jsr305", - "com.google.errorprone:error_prone_annotations", - "com.google.errorprone:error_prone_annotations:jar:sources", - "com.google.guava:failureaccess", - "com.google.guava:failureaccess:jar:sources", - "com.google.guava:guava", - "com.google.guava:guava:jar:sources", - "com.google.guava:listenablefuture", - "com.google.j2objc:j2objc-annotations", - "com.google.j2objc:j2objc-annotations:jar:sources", - "com.jayway.jsonpath:json-path", - "com.jayway.jsonpath:json-path:jar:sources", - "com.nimbusds:content-type", - "com.nimbusds:content-type:jar:sources", - "com.nimbusds:lang-tag", - "com.nimbusds:lang-tag:jar:sources", - "com.nimbusds:nimbus-jose-jwt", - "com.nimbusds:nimbus-jose-jwt:jar:sources", - "com.nimbusds:oauth2-oidc-sdk", - "com.nimbusds:oauth2-oidc-sdk:jar:sources", - "com.squareup.okhttp3:okhttp-jvm", - "com.squareup.okhttp3:okhttp-jvm:jar:sources", - "com.squareup.okio:okio-jvm", - "com.squareup.okio:okio-jvm:jar:sources", - "com.typesafe:config", - "com.typesafe:config:jar:sources", - "com.vaadin.external.google:android-json", - "com.vaadin.external.google:android-json:jar:sources", - "commons-codec:commons-codec", - "commons-codec:commons-codec:jar:sources", - "commons-io:commons-io", - "commons-io:commons-io:jar:sources", - "commons-logging:commons-logging", - "commons-logging:commons-logging:jar:sources", - "io.cloudevents:cloudevents-api", - "io.cloudevents:cloudevents-api:jar:sources", - "io.cloudevents:cloudevents-core", - "io.cloudevents:cloudevents-core:jar:sources", - "io.cloudevents:cloudevents-json-jackson", - "io.cloudevents:cloudevents-json-jackson:jar:sources", - "io.dropwizard.metrics:metrics-core", - "io.dropwizard.metrics:metrics-core:jar:sources", - "io.micrometer:context-propagation", - "io.micrometer:context-propagation:jar:sources", - "io.micrometer:micrometer-commons", - "io.micrometer:micrometer-commons:jar:sources", - "io.micrometer:micrometer-core", - "io.micrometer:micrometer-core:jar:sources", - "io.micrometer:micrometer-jakarta9", - "io.micrometer:micrometer-jakarta9:jar:sources", - "io.micrometer:micrometer-observation", - "io.micrometer:micrometer-observation-test", - "io.micrometer:micrometer-observation-test:jar:sources", - "io.micrometer:micrometer-observation:jar:sources", - "io.micrometer:micrometer-tracing", - "io.micrometer:micrometer-tracing-bridge-otel", - "io.micrometer:micrometer-tracing-bridge-otel:jar:sources", - "io.micrometer:micrometer-tracing:jar:sources", - "io.nats:jnats", - "io.nats:jnats:jar:sources", - "io.netty:netty-buffer", - "io.netty:netty-buffer:jar:sources", - "io.netty:netty-codec-base", - "io.netty:netty-codec-base:jar:sources", - "io.netty:netty-codec-classes-quic", - "io.netty:netty-codec-classes-quic:jar:sources", - "io.netty:netty-codec-compression", - "io.netty:netty-codec-compression:jar:sources", - "io.netty:netty-codec-dns", - "io.netty:netty-codec-dns:jar:sources", - "io.netty:netty-codec-http", - "io.netty:netty-codec-http2", - "io.netty:netty-codec-http2:jar:sources", - "io.netty:netty-codec-http3", - "io.netty:netty-codec-http3:jar:sources", - "io.netty:netty-codec-http:jar:sources", - "io.netty:netty-codec-native-quic:jar:linux-aarch_64", - "io.netty:netty-codec-native-quic:jar:linux-x86_64", - "io.netty:netty-codec-native-quic:jar:osx-aarch_64", - "io.netty:netty-codec-native-quic:jar:osx-x86_64", - "io.netty:netty-codec-native-quic:jar:sources", - "io.netty:netty-codec-native-quic:jar:windows-x86_64", - "io.netty:netty-codec-socks", - "io.netty:netty-codec-socks:jar:sources", - "io.netty:netty-common", - "io.netty:netty-common:jar:sources", - "io.netty:netty-handler", - "io.netty:netty-handler-proxy", - "io.netty:netty-handler-proxy:jar:sources", - "io.netty:netty-handler:jar:sources", - "io.netty:netty-resolver", - "io.netty:netty-resolver-dns", - "io.netty:netty-resolver-dns-classes-macos", - "io.netty:netty-resolver-dns-classes-macos:jar:sources", - "io.netty:netty-resolver-dns-native-macos:jar:osx-x86_64", - "io.netty:netty-resolver-dns-native-macos:jar:sources", - "io.netty:netty-resolver-dns:jar:sources", - "io.netty:netty-resolver:jar:sources", - "io.netty:netty-transport", - "io.netty:netty-transport-classes-epoll", - "io.netty:netty-transport-classes-epoll:jar:sources", - "io.netty:netty-transport-native-epoll:jar:linux-x86_64", - "io.netty:netty-transport-native-epoll:jar:sources", - "io.netty:netty-transport-native-unix-common", - "io.netty:netty-transport-native-unix-common:jar:sources", - "io.netty:netty-transport:jar:sources", - "io.opentelemetry.semconv:opentelemetry-semconv", - "io.opentelemetry.semconv:opentelemetry-semconv:jar:sources", - "io.opentelemetry:opentelemetry-api", - "io.opentelemetry:opentelemetry-api:jar:sources", - "io.opentelemetry:opentelemetry-common", - "io.opentelemetry:opentelemetry-common:jar:sources", - "io.opentelemetry:opentelemetry-context", - "io.opentelemetry:opentelemetry-context:jar:sources", - "io.opentelemetry:opentelemetry-exporter-common", - "io.opentelemetry:opentelemetry-exporter-common:jar:sources", - "io.opentelemetry:opentelemetry-exporter-otlp", - "io.opentelemetry:opentelemetry-exporter-otlp-common", - "io.opentelemetry:opentelemetry-exporter-otlp-common:jar:sources", - "io.opentelemetry:opentelemetry-exporter-otlp:jar:sources", - "io.opentelemetry:opentelemetry-exporter-sender-okhttp", - "io.opentelemetry:opentelemetry-exporter-sender-okhttp:jar:sources", - "io.opentelemetry:opentelemetry-extension-trace-propagators", - "io.opentelemetry:opentelemetry-extension-trace-propagators:jar:sources", - "io.opentelemetry:opentelemetry-sdk", - "io.opentelemetry:opentelemetry-sdk-common", - "io.opentelemetry:opentelemetry-sdk-common:jar:sources", - "io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi", - "io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi:jar:sources", - "io.opentelemetry:opentelemetry-sdk-logs", - "io.opentelemetry:opentelemetry-sdk-logs:jar:sources", - "io.opentelemetry:opentelemetry-sdk-metrics", - "io.opentelemetry:opentelemetry-sdk-metrics:jar:sources", - "io.opentelemetry:opentelemetry-sdk-testing", - "io.opentelemetry:opentelemetry-sdk-testing:jar:sources", - "io.opentelemetry:opentelemetry-sdk-trace", - "io.opentelemetry:opentelemetry-sdk-trace:jar:sources", - "io.opentelemetry:opentelemetry-sdk:jar:sources", - "io.projectreactor.netty:reactor-netty-core", - "io.projectreactor.netty:reactor-netty-core:jar:sources", - "io.projectreactor.netty:reactor-netty-http", - "io.projectreactor.netty:reactor-netty-http:jar:sources", - "io.projectreactor:reactor-core", - "io.projectreactor:reactor-core:jar:sources", - "io.projectreactor:reactor-test", - "io.projectreactor:reactor-test:jar:sources", - "io.swagger.core.v3:swagger-annotations-jakarta", - "io.swagger.core.v3:swagger-annotations-jakarta:jar:sources", - "io.swagger.core.v3:swagger-core-jakarta", - "io.swagger.core.v3:swagger-core-jakarta:jar:sources", - "io.swagger.core.v3:swagger-models-jakarta", - "io.swagger.core.v3:swagger-models-jakarta:jar:sources", - "jakarta.activation:jakarta.activation-api", - "jakarta.activation:jakarta.activation-api:jar:sources", - "jakarta.annotation:jakarta.annotation-api", - "jakarta.annotation:jakarta.annotation-api:jar:sources", - "jakarta.servlet:jakarta.servlet-api", - "jakarta.servlet:jakarta.servlet-api:jar:sources", - "jakarta.validation:jakarta.validation-api", - "jakarta.validation:jakarta.validation-api:jar:sources", - "jakarta.xml.bind:jakarta.xml.bind-api", - "jakarta.xml.bind:jakarta.xml.bind-api:jar:sources", - "net.bytebuddy:byte-buddy", - "net.bytebuddy:byte-buddy-agent", - "net.bytebuddy:byte-buddy-agent:jar:sources", - "net.bytebuddy:byte-buddy:jar:sources", - "net.java.dev.jna:jna", - "net.java.dev.jna:jna:jar:sources", - "net.minidev:accessors-smart", - "net.minidev:accessors-smart:jar:sources", - "net.minidev:json-smart", - "net.minidev:json-smart:jar:sources", - "org.apache.cassandra:java-driver-core", - "org.apache.cassandra:java-driver-core:jar:sources", - "org.apache.cassandra:java-driver-guava-shaded", - "org.apache.cassandra:java-driver-guava-shaded:jar:sources", - "org.apache.cassandra:java-driver-metrics-micrometer", - "org.apache.cassandra:java-driver-metrics-micrometer:jar:sources", - "org.apache.cassandra:java-driver-query-builder", - "org.apache.cassandra:java-driver-query-builder:jar:sources", - "org.apache.commons:commons-compress", - "org.apache.commons:commons-compress:jar:sources", - "org.apache.commons:commons-lang3", - "org.apache.commons:commons-lang3:jar:sources", - "org.apache.logging.log4j:log4j-api", - "org.apache.logging.log4j:log4j-api:jar:sources", - "org.apache.logging.log4j:log4j-to-slf4j", - "org.apache.logging.log4j:log4j-to-slf4j:jar:sources", - "org.apache.tomcat.embed:tomcat-embed-core", - "org.apache.tomcat.embed:tomcat-embed-core:jar:sources", - "org.apache.tomcat.embed:tomcat-embed-el", - "org.apache.tomcat.embed:tomcat-embed-el:jar:sources", - "org.apache.tomcat.embed:tomcat-embed-websocket", - "org.apache.tomcat.embed:tomcat-embed-websocket:jar:sources", - "org.apiguardian:apiguardian-api", - "org.apiguardian:apiguardian-api:jar:sources", - "org.assertj:assertj-core", - "org.assertj:assertj-core:jar:sources", - "org.awaitility:awaitility", - "org.awaitility:awaitility:jar:sources", - "org.bouncycastle:bcprov-jdk18on", - "org.bouncycastle:bcprov-jdk18on:jar:sources", - "org.bouncycastle:bcprov-lts8on", - "org.bouncycastle:bcprov-lts8on:jar:sources", - "org.hamcrest:hamcrest", - "org.hamcrest:hamcrest:jar:sources", - "org.hdrhistogram:HdrHistogram", - "org.hdrhistogram:HdrHistogram:jar:sources", - "org.hibernate.validator:hibernate-validator", - "org.hibernate.validator:hibernate-validator:jar:sources", - "org.jacoco:org.jacoco.agent:jar:runtime", - "org.jacoco:org.jacoco.agent:jar:sources", - "org.jacoco:org.jacoco.cli", - "org.jacoco:org.jacoco.cli:jar:sources", - "org.jacoco:org.jacoco.core", - "org.jacoco:org.jacoco.core:jar:sources", - "org.jacoco:org.jacoco.report", - "org.jacoco:org.jacoco.report:jar:sources", - "org.jboss.logging:jboss-logging", - "org.jboss.logging:jboss-logging:jar:sources", - "org.jetbrains.kotlin:kotlin-stdlib", - "org.jetbrains.kotlin:kotlin-stdlib:jar:sources", - "org.jetbrains:annotations", - "org.jetbrains:annotations:jar:sources", - "org.jspecify:jspecify", - "org.jspecify:jspecify:jar:sources", - "org.junit.jupiter:junit-jupiter", - "org.junit.jupiter:junit-jupiter-api", - "org.junit.jupiter:junit-jupiter-api:jar:sources", - "org.junit.jupiter:junit-jupiter-engine", - "org.junit.jupiter:junit-jupiter-engine:jar:sources", - "org.junit.jupiter:junit-jupiter-params", - "org.junit.jupiter:junit-jupiter-params:jar:sources", - "org.junit.jupiter:junit-jupiter:jar:sources", - "org.junit.platform:junit-platform-commons", - "org.junit.platform:junit-platform-commons:jar:sources", - "org.junit.platform:junit-platform-console-standalone", - "org.junit.platform:junit-platform-console-standalone:jar:sources", - "org.junit.platform:junit-platform-engine", - "org.junit.platform:junit-platform-engine:jar:sources", - "org.latencyutils:LatencyUtils", - "org.latencyutils:LatencyUtils:jar:sources", - "org.mockito:mockito-core", - "org.mockito:mockito-core:jar:sources", - "org.mockito:mockito-junit-jupiter", - "org.mockito:mockito-junit-jupiter:jar:sources", - "org.objenesis:objenesis", - "org.objenesis:objenesis:jar:sources", - "org.opentest4j:opentest4j", - "org.opentest4j:opentest4j:jar:sources", - "org.ow2.asm:asm", - "org.ow2.asm:asm-analysis", - "org.ow2.asm:asm-analysis:jar:sources", - "org.ow2.asm:asm-commons", - "org.ow2.asm:asm-commons:jar:sources", - "org.ow2.asm:asm-tree", - "org.ow2.asm:asm-tree:jar:sources", - "org.ow2.asm:asm-util", - "org.ow2.asm:asm-util:jar:sources", - "org.ow2.asm:asm:jar:sources", - "org.projectlombok:lombok", - "org.projectlombok:lombok:jar:sources", - "org.reactivestreams:reactive-streams", - "org.reactivestreams:reactive-streams:jar:sources", - "org.rnorth.duct-tape:duct-tape", - "org.rnorth.duct-tape:duct-tape:jar:sources", - "org.skyscreamer:jsonassert", - "org.skyscreamer:jsonassert:jar:sources", - "org.slf4j:jul-to-slf4j", - "org.slf4j:jul-to-slf4j:jar:sources", - "org.slf4j:slf4j-api", - "org.slf4j:slf4j-api:jar:sources", - "org.springdoc:springdoc-openapi-starter-common", - "org.springdoc:springdoc-openapi-starter-common:jar:sources", - "org.springdoc:springdoc-openapi-starter-webflux-api", - "org.springdoc:springdoc-openapi-starter-webflux-api:jar:sources", - "org.springdoc:springdoc-openapi-starter-webmvc-api", - "org.springdoc:springdoc-openapi-starter-webmvc-api:jar:sources", - "org.springframework.boot:spring-boot", - "org.springframework.boot:spring-boot-actuator", - "org.springframework.boot:spring-boot-actuator-autoconfigure", - "org.springframework.boot:spring-boot-actuator-autoconfigure:jar:sources", - "org.springframework.boot:spring-boot-actuator:jar:sources", - "org.springframework.boot:spring-boot-autoconfigure", - "org.springframework.boot:spring-boot-autoconfigure:jar:sources", - "org.springframework.boot:spring-boot-cassandra", - "org.springframework.boot:spring-boot-cassandra:jar:sources", - "org.springframework.boot:spring-boot-data-cassandra", - "org.springframework.boot:spring-boot-data-cassandra-test", - "org.springframework.boot:spring-boot-data-cassandra-test:jar:sources", - "org.springframework.boot:spring-boot-data-cassandra:jar:sources", - "org.springframework.boot:spring-boot-data-commons", - "org.springframework.boot:spring-boot-data-commons:jar:sources", - "org.springframework.boot:spring-boot-health", - "org.springframework.boot:spring-boot-health:jar:sources", - "org.springframework.boot:spring-boot-http-client", - "org.springframework.boot:spring-boot-http-client:jar:sources", - "org.springframework.boot:spring-boot-http-codec", - "org.springframework.boot:spring-boot-http-codec:jar:sources", - "org.springframework.boot:spring-boot-http-converter", - "org.springframework.boot:spring-boot-http-converter:jar:sources", - "org.springframework.boot:spring-boot-jackson", - "org.springframework.boot:spring-boot-jackson:jar:sources", - "org.springframework.boot:spring-boot-micrometer-metrics", - "org.springframework.boot:spring-boot-micrometer-metrics-test", - "org.springframework.boot:spring-boot-micrometer-metrics-test:jar:sources", - "org.springframework.boot:spring-boot-micrometer-metrics:jar:sources", - "org.springframework.boot:spring-boot-micrometer-observation", - "org.springframework.boot:spring-boot-micrometer-observation:jar:sources", - "org.springframework.boot:spring-boot-micrometer-tracing", - "org.springframework.boot:spring-boot-micrometer-tracing-opentelemetry", - "org.springframework.boot:spring-boot-micrometer-tracing-opentelemetry:jar:sources", - "org.springframework.boot:spring-boot-micrometer-tracing:jar:sources", - "org.springframework.boot:spring-boot-netty", - "org.springframework.boot:spring-boot-netty:jar:sources", - "org.springframework.boot:spring-boot-opentelemetry", - "org.springframework.boot:spring-boot-opentelemetry:jar:sources", - "org.springframework.boot:spring-boot-persistence", - "org.springframework.boot:spring-boot-persistence:jar:sources", - "org.springframework.boot:spring-boot-reactor", - "org.springframework.boot:spring-boot-reactor-netty", - "org.springframework.boot:spring-boot-reactor-netty:jar:sources", - "org.springframework.boot:spring-boot-reactor:jar:sources", - "org.springframework.boot:spring-boot-restclient", - "org.springframework.boot:spring-boot-restclient:jar:sources", - "org.springframework.boot:spring-boot-resttestclient", - "org.springframework.boot:spring-boot-resttestclient:jar:sources", - "org.springframework.boot:spring-boot-security", - "org.springframework.boot:spring-boot-security-oauth2-client", - "org.springframework.boot:spring-boot-security-oauth2-client:jar:sources", - "org.springframework.boot:spring-boot-security-oauth2-resource-server", - "org.springframework.boot:spring-boot-security-oauth2-resource-server:jar:sources", - "org.springframework.boot:spring-boot-security-test", - "org.springframework.boot:spring-boot-security-test:jar:sources", - "org.springframework.boot:spring-boot-security:jar:sources", - "org.springframework.boot:spring-boot-servlet", - "org.springframework.boot:spring-boot-servlet:jar:sources", - "org.springframework.boot:spring-boot-starter", - "org.springframework.boot:spring-boot-starter-actuator", - "org.springframework.boot:spring-boot-starter-actuator-test", - "org.springframework.boot:spring-boot-starter-actuator-test:jar:sources", - "org.springframework.boot:spring-boot-starter-actuator:jar:sources", - "org.springframework.boot:spring-boot-starter-data-cassandra", - "org.springframework.boot:spring-boot-starter-data-cassandra-test", - "org.springframework.boot:spring-boot-starter-data-cassandra-test:jar:sources", - "org.springframework.boot:spring-boot-starter-data-cassandra:jar:sources", - "org.springframework.boot:spring-boot-starter-jackson", - "org.springframework.boot:spring-boot-starter-jackson-test", - "org.springframework.boot:spring-boot-starter-jackson-test:jar:sources", - "org.springframework.boot:spring-boot-starter-jackson:jar:sources", - "org.springframework.boot:spring-boot-starter-logging", - "org.springframework.boot:spring-boot-starter-logging:jar:sources", - "org.springframework.boot:spring-boot-starter-micrometer-metrics", - "org.springframework.boot:spring-boot-starter-micrometer-metrics-test", - "org.springframework.boot:spring-boot-starter-micrometer-metrics-test:jar:sources", - "org.springframework.boot:spring-boot-starter-micrometer-metrics:jar:sources", - "org.springframework.boot:spring-boot-starter-reactor-netty", - "org.springframework.boot:spring-boot-starter-reactor-netty:jar:sources", - "org.springframework.boot:spring-boot-starter-security", - "org.springframework.boot:spring-boot-starter-security-oauth2-client", - "org.springframework.boot:spring-boot-starter-security-oauth2-client:jar:sources", - "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server", - "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server-test", - "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server-test:jar:sources", - "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server:jar:sources", - "org.springframework.boot:spring-boot-starter-security-test", - "org.springframework.boot:spring-boot-starter-security-test:jar:sources", - "org.springframework.boot:spring-boot-starter-security:jar:sources", - "org.springframework.boot:spring-boot-starter-test", - "org.springframework.boot:spring-boot-starter-test:jar:sources", - "org.springframework.boot:spring-boot-starter-tomcat", - "org.springframework.boot:spring-boot-starter-tomcat-runtime", - "org.springframework.boot:spring-boot-starter-tomcat-runtime:jar:sources", - "org.springframework.boot:spring-boot-starter-tomcat:jar:sources", - "org.springframework.boot:spring-boot-starter-validation", - "org.springframework.boot:spring-boot-starter-validation:jar:sources", - "org.springframework.boot:spring-boot-starter-webflux", - "org.springframework.boot:spring-boot-starter-webflux-test", - "org.springframework.boot:spring-boot-starter-webflux-test:jar:sources", - "org.springframework.boot:spring-boot-starter-webflux:jar:sources", - "org.springframework.boot:spring-boot-starter-webmvc", - "org.springframework.boot:spring-boot-starter-webmvc-test", - "org.springframework.boot:spring-boot-starter-webmvc-test:jar:sources", - "org.springframework.boot:spring-boot-starter-webmvc:jar:sources", - "org.springframework.boot:spring-boot-starter:jar:sources", - "org.springframework.boot:spring-boot-test", - "org.springframework.boot:spring-boot-test-autoconfigure", - "org.springframework.boot:spring-boot-test-autoconfigure:jar:sources", - "org.springframework.boot:spring-boot-test:jar:sources", - "org.springframework.boot:spring-boot-tomcat", - "org.springframework.boot:spring-boot-tomcat:jar:sources", - "org.springframework.boot:spring-boot-validation", - "org.springframework.boot:spring-boot-validation:jar:sources", - "org.springframework.boot:spring-boot-web-server", - "org.springframework.boot:spring-boot-web-server:jar:sources", - "org.springframework.boot:spring-boot-webclient", - "org.springframework.boot:spring-boot-webclient:jar:sources", - "org.springframework.boot:spring-boot-webflux", - "org.springframework.boot:spring-boot-webflux-test", - "org.springframework.boot:spring-boot-webflux-test:jar:sources", - "org.springframework.boot:spring-boot-webflux:jar:sources", - "org.springframework.boot:spring-boot-webmvc", - "org.springframework.boot:spring-boot-webmvc-test", - "org.springframework.boot:spring-boot-webmvc-test:jar:sources", - "org.springframework.boot:spring-boot-webmvc:jar:sources", - "org.springframework.boot:spring-boot-webtestclient", - "org.springframework.boot:spring-boot-webtestclient:jar:sources", - "org.springframework.boot:spring-boot:jar:sources", - "org.springframework.cloud:spring-cloud-commons", - "org.springframework.cloud:spring-cloud-commons:jar:sources", - "org.springframework.cloud:spring-cloud-context", - "org.springframework.cloud:spring-cloud-context:jar:sources", - "org.springframework.cloud:spring-cloud-starter", - "org.springframework.cloud:spring-cloud-starter-bootstrap", - "org.springframework.cloud:spring-cloud-starter-bootstrap:jar:sources", - "org.springframework.data:spring-data-cassandra", - "org.springframework.data:spring-data-cassandra:jar:sources", - "org.springframework.data:spring-data-commons", - "org.springframework.data:spring-data-commons:jar:sources", - "org.springframework.security:spring-security-config", - "org.springframework.security:spring-security-config:jar:sources", - "org.springframework.security:spring-security-core", - "org.springframework.security:spring-security-core:jar:sources", - "org.springframework.security:spring-security-crypto", - "org.springframework.security:spring-security-crypto:jar:sources", - "org.springframework.security:spring-security-oauth2-client", - "org.springframework.security:spring-security-oauth2-client:jar:sources", - "org.springframework.security:spring-security-oauth2-core", - "org.springframework.security:spring-security-oauth2-core:jar:sources", - "org.springframework.security:spring-security-oauth2-jose", - "org.springframework.security:spring-security-oauth2-jose:jar:sources", - "org.springframework.security:spring-security-oauth2-resource-server", - "org.springframework.security:spring-security-oauth2-resource-server:jar:sources", - "org.springframework.security:spring-security-test", - "org.springframework.security:spring-security-test:jar:sources", - "org.springframework.security:spring-security-web", - "org.springframework.security:spring-security-web:jar:sources", - "org.springframework:spring-aop", - "org.springframework:spring-aop:jar:sources", - "org.springframework:spring-beans", - "org.springframework:spring-beans:jar:sources", - "org.springframework:spring-context", - "org.springframework:spring-context:jar:sources", - "org.springframework:spring-core", - "org.springframework:spring-core:jar:sources", - "org.springframework:spring-expression", - "org.springframework:spring-expression:jar:sources", - "org.springframework:spring-test", - "org.springframework:spring-test:jar:sources", - "org.springframework:spring-tx", - "org.springframework:spring-tx:jar:sources", - "org.springframework:spring-web", - "org.springframework:spring-web:jar:sources", - "org.springframework:spring-webflux", - "org.springframework:spring-webflux:jar:sources", - "org.springframework:spring-webmvc", - "org.springframework:spring-webmvc:jar:sources", - "org.testcontainers:testcontainers", - "org.testcontainers:testcontainers-cassandra", - "org.testcontainers:testcontainers-cassandra:jar:sources", - "org.testcontainers:testcontainers-database-commons", - "org.testcontainers:testcontainers-database-commons:jar:sources", - "org.testcontainers:testcontainers-junit-jupiter", - "org.testcontainers:testcontainers-junit-jupiter:jar:sources", - "org.testcontainers:testcontainers:jar:sources", - "org.wiremock:wiremock-standalone", - "org.wiremock:wiremock-standalone:jar:sources", - "org.xmlunit:xmlunit-core", - "org.xmlunit:xmlunit-core:jar:sources", - "org.yaml:snakeyaml", - "org.yaml:snakeyaml:jar:sources", - "software.amazon.awssdk:annotations", - "software.amazon.awssdk:annotations:jar:sources", - "software.amazon.awssdk:checksums", - "software.amazon.awssdk:checksums-spi", - "software.amazon.awssdk:checksums-spi:jar:sources", - "software.amazon.awssdk:checksums:jar:sources", - "software.amazon.awssdk:endpoints-spi", - "software.amazon.awssdk:endpoints-spi:jar:sources", - "software.amazon.awssdk:http-auth-aws", - "software.amazon.awssdk:http-auth-aws:jar:sources", - "software.amazon.awssdk:http-auth-spi", - "software.amazon.awssdk:http-auth-spi:jar:sources", - "software.amazon.awssdk:http-client-spi", - "software.amazon.awssdk:http-client-spi:jar:sources", - "software.amazon.awssdk:identity-spi", - "software.amazon.awssdk:identity-spi:jar:sources", - "software.amazon.awssdk:json-utils", - "software.amazon.awssdk:json-utils:jar:sources", - "software.amazon.awssdk:metrics-spi", - "software.amazon.awssdk:metrics-spi:jar:sources", - "software.amazon.awssdk:profiles", - "software.amazon.awssdk:profiles:jar:sources", - "software.amazon.awssdk:regions", - "software.amazon.awssdk:regions:jar:sources", - "software.amazon.awssdk:retries", - "software.amazon.awssdk:retries-spi", - "software.amazon.awssdk:retries-spi:jar:sources", - "software.amazon.awssdk:retries:jar:sources", - "software.amazon.awssdk:sdk-core", - "software.amazon.awssdk:sdk-core:jar:sources", - "software.amazon.awssdk:third-party-jackson-core", - "software.amazon.awssdk:third-party-jackson-core:jar:sources", - "software.amazon.awssdk:utils", - "software.amazon.awssdk:utils:jar:sources", - "tools.jackson.core:jackson-core", - "tools.jackson.core:jackson-core:jar:sources", - "tools.jackson.core:jackson-databind", - "tools.jackson.core:jackson-databind:jar:sources", - "tools.jackson.module:jackson-module-blackbird", - "tools.jackson.module:jackson-module-blackbird:jar:sources" - ] - }, - "services": { - "ch.qos.logback:logback-classic": { - "jakarta.servlet.ServletContainerInitializer": [ - "ch.qos.logback.classic.servlet.LogbackServletContainerInitializer" - ], - "org.slf4j.spi.SLF4JServiceProvider": [ - "ch.qos.logback.classic.spi.LogbackServiceProvider" - ] - }, - "com.fasterxml.jackson.core:jackson-core": { - "com.fasterxml.jackson.core.JsonFactory": [ - "com.fasterxml.jackson.core.JsonFactory" - ] - }, - "com.fasterxml.jackson.core:jackson-databind": { - "com.fasterxml.jackson.core.ObjectCodec": [ - "com.fasterxml.jackson.databind.ObjectMapper" - ] - }, - "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml": { - "com.fasterxml.jackson.core.JsonFactory": [ - "com.fasterxml.jackson.dataformat.yaml.YAMLFactory" - ], - "com.fasterxml.jackson.core.ObjectCodec": [ - "com.fasterxml.jackson.dataformat.yaml.YAMLMapper" - ] - }, - "com.fasterxml.jackson.datatype:jackson-datatype-jsr310": { - "com.fasterxml.jackson.databind.Module": [ - "com.fasterxml.jackson.datatype.jsr310.JavaTimeModule" - ] - }, - "io.cloudevents:cloudevents-json-jackson": { - "io.cloudevents.core.format.EventFormat": [ - "io.cloudevents.jackson.JsonFormat" - ] - }, - "io.micrometer:micrometer-observation": { - "io.micrometer.context.ThreadLocalAccessor": [ - "io.micrometer.observation.contextpropagation.ObservationThreadLocalAccessor" - ] - }, - "io.netty:netty-common": { - "reactor.blockhound.integration.BlockHoundIntegration": [ - "io.netty.util.internal.Hidden$NettyBlockHoundIntegration" - ] - }, - "io.opentelemetry:opentelemetry-exporter-otlp": { - "io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider": [ - "io.opentelemetry.exporter.otlp.internal.OtlpGrpcLogRecordExporterComponentProvider", - "io.opentelemetry.exporter.otlp.internal.OtlpGrpcMetricExporterComponentProvider", - "io.opentelemetry.exporter.otlp.internal.OtlpGrpcSpanExporterComponentProvider", - "io.opentelemetry.exporter.otlp.internal.OtlpHttpLogRecordExporterComponentProvider", - "io.opentelemetry.exporter.otlp.internal.OtlpHttpMetricExporterComponentProvider", - "io.opentelemetry.exporter.otlp.internal.OtlpHttpSpanExporterComponentProvider" - ], - "io.opentelemetry.sdk.autoconfigure.spi.logs.ConfigurableLogRecordExporterProvider": [ - "io.opentelemetry.exporter.otlp.internal.OtlpLogRecordExporterProvider" - ], - "io.opentelemetry.sdk.autoconfigure.spi.metrics.ConfigurableMetricExporterProvider": [ - "io.opentelemetry.exporter.otlp.internal.OtlpMetricExporterProvider" - ], - "io.opentelemetry.sdk.autoconfigure.spi.traces.ConfigurableSpanExporterProvider": [ - "io.opentelemetry.exporter.otlp.internal.OtlpSpanExporterProvider" - ] - }, - "io.opentelemetry:opentelemetry-exporter-sender-okhttp": { - "io.opentelemetry.exporter.internal.grpc.GrpcSenderProvider": [ - "io.opentelemetry.exporter.sender.okhttp.internal.OkHttpGrpcSenderProvider" - ], - "io.opentelemetry.exporter.internal.http.HttpSenderProvider": [ - "io.opentelemetry.exporter.sender.okhttp.internal.OkHttpHttpSenderProvider" - ] - }, - "io.opentelemetry:opentelemetry-extension-trace-propagators": { - "io.opentelemetry.sdk.autoconfigure.spi.ConfigurablePropagatorProvider": [ - "io.opentelemetry.extension.trace.propagation.B3ConfigurablePropagator", - "io.opentelemetry.extension.trace.propagation.B3MultiConfigurablePropagator", - "io.opentelemetry.extension.trace.propagation.JaegerConfigurablePropagator", - "io.opentelemetry.extension.trace.propagation.OtTraceConfigurablePropagator" - ], - "io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider": [ - "io.opentelemetry.extension.trace.propagation.internal.B3ComponentProvider", - "io.opentelemetry.extension.trace.propagation.internal.B3MultiComponentProvider", - "io.opentelemetry.extension.trace.propagation.internal.JaegerComponentProvider", - "io.opentelemetry.extension.trace.propagation.internal.OtTraceComponentProvider" - ] - }, - "io.opentelemetry:opentelemetry-sdk-testing": { - "io.opentelemetry.context.ContextStorageProvider": [ - "io.opentelemetry.sdk.testing.context.SettableContextStorageProvider" - ] - }, - "io.projectreactor.netty:reactor-netty-core": { - "io.micrometer.context.ContextAccessor": [ - "reactor.netty.contextpropagation.ChannelContextAccessor" - ] - }, - "io.projectreactor:reactor-core": { - "io.micrometer.context.ContextAccessor": [ - "reactor.util.context.ReactorContextAccessor" - ], - "reactor.blockhound.integration.BlockHoundIntegration": [ - "reactor.core.scheduler.ReactorBlockHoundIntegration" - ] - }, - "org.apache.cassandra:java-driver-core": { - "reactor.blockhound.integration.BlockHoundIntegration": [ - "com.datastax.oss.driver.internal.core.util.concurrent.DriverBlockHoundIntegration" - ] - }, - "org.apache.logging.log4j:log4j-api": { - "org.apache.logging.log4j.util.PropertySource": [ - "org.apache.logging.log4j.util.EnvironmentPropertySource", - "org.apache.logging.log4j.util.SystemPropertiesPropertySource" - ] - }, - "org.apache.logging.log4j:log4j-to-slf4j": { - "org.apache.logging.log4j.spi.Provider": [ - "org.apache.logging.slf4j.SLF4JProvider" - ] - }, - "org.apache.tomcat.embed:tomcat-embed-el": { - "jakarta.el.ExpressionFactory": [ - "org.apache.el.ExpressionFactoryImpl" - ] - }, - "org.apache.tomcat.embed:tomcat-embed-websocket": { - "jakarta.servlet.ServletContainerInitializer": [ - "org.apache.tomcat.websocket.server.WsSci" - ], - "jakarta.websocket.ContainerProvider": [ - "org.apache.tomcat.websocket.WsContainerProvider" - ], - "jakarta.websocket.server.ServerEndpointConfig$Configurator": [ - "org.apache.tomcat.websocket.server.DefaultServerEndpointConfigurator" - ] - }, - "org.bouncycastle:bcprov-jdk18on": { - "java.security.Provider": [ - "org.bouncycastle.jce.provider.BouncyCastleProvider", - "org.bouncycastle.pqc.jcajce.provider.BouncyCastlePQCProvider" - ] - }, - "org.bouncycastle:bcprov-lts8on": { - "java.security.Provider": [ - "org.bouncycastle.jce.provider.BouncyCastleProvider", - "org.bouncycastle.pqc.jcajce.provider.BouncyCastlePQCProvider" - ] - }, - "org.hibernate.validator:hibernate-validator": { - "jakarta.validation.spi.ValidationProvider": [ - "org.hibernate.validator.HibernateValidator" - ] - }, - "org.junit.jupiter:junit-jupiter-engine": { - "org.junit.platform.engine.TestEngine": [ - "org.junit.jupiter.engine.JupiterTestEngine" - ] - }, - "org.junit.platform:junit-platform-console-standalone": { - "java.util.spi.ToolProvider": [ - "org.junit.platform.console.ConsoleLauncherToolProvider" - ], - "org.junit.platform.engine.TestEngine": [ - "org.junit.jupiter.engine.JupiterTestEngine", - "org.junit.platform.suite.engine.SuiteTestEngine", - "org.junit.vintage.engine.VintageTestEngine" - ], - "org.junit.platform.engine.discovery.DiscoverySelectorIdentifierParser": [ - "org.junit.platform.engine.discovery.ClassSelector$IdentifierParser", - "org.junit.platform.engine.discovery.ClasspathResourceSelector$IdentifierParser", - "org.junit.platform.engine.discovery.ClasspathRootSelector$IdentifierParser", - "org.junit.platform.engine.discovery.DirectorySelector$IdentifierParser", - "org.junit.platform.engine.discovery.FileSelector$IdentifierParser", - "org.junit.platform.engine.discovery.IterationSelector$IdentifierParser", - "org.junit.platform.engine.discovery.MethodSelector$IdentifierParser", - "org.junit.platform.engine.discovery.ModuleSelector$IdentifierParser", - "org.junit.platform.engine.discovery.NestedClassSelector$IdentifierParser", - "org.junit.platform.engine.discovery.NestedMethodSelector$IdentifierParser", - "org.junit.platform.engine.discovery.PackageSelector$IdentifierParser", - "org.junit.platform.engine.discovery.UniqueIdSelector$IdentifierParser", - "org.junit.platform.engine.discovery.UriSelector$IdentifierParser" - ], - "org.junit.platform.launcher.TestExecutionListener": [ - "org.junit.platform.launcher.listeners.UniqueIdTrackingListener", - "org.junit.platform.reporting.open.xml.OpenTestReportGeneratingListener" - ], - "org.opentest4j.reporting.tooling.spi.htmlreport.Contributor": [ - "org.junit.platform.reporting.open.xml.JUnitContributor" - ] - }, - "org.junit.platform:junit-platform-engine": { - "org.junit.platform.engine.discovery.DiscoverySelectorIdentifierParser": [ - "org.junit.platform.engine.discovery.ClassSelector$IdentifierParser", - "org.junit.platform.engine.discovery.ClasspathResourceSelector$IdentifierParser", - "org.junit.platform.engine.discovery.ClasspathRootSelector$IdentifierParser", - "org.junit.platform.engine.discovery.DirectorySelector$IdentifierParser", - "org.junit.platform.engine.discovery.FileSelector$IdentifierParser", - "org.junit.platform.engine.discovery.IterationSelector$IdentifierParser", - "org.junit.platform.engine.discovery.MethodSelector$IdentifierParser", - "org.junit.platform.engine.discovery.ModuleSelector$IdentifierParser", - "org.junit.platform.engine.discovery.NestedClassSelector$IdentifierParser", - "org.junit.platform.engine.discovery.NestedMethodSelector$IdentifierParser", - "org.junit.platform.engine.discovery.PackageSelector$IdentifierParser", - "org.junit.platform.engine.discovery.UniqueIdSelector$IdentifierParser", - "org.junit.platform.engine.discovery.UriSelector$IdentifierParser" - ] - }, - "org.projectlombok:lombok": { - "javax.annotation.processing.Processor": [ - "lombok.launch.AnnotationProcessorHider$AnnotationProcessor", - "lombok.launch.AnnotationProcessorHider$ClaimingProcessor" - ], - "lombok.core.LombokApp": [ - "lombok.bytecode.PoolConstantsApp", - "lombok.bytecode.PostCompilerApp", - "lombok.core.Main$LicenseApp", - "lombok.core.Main$VersionApp", - "lombok.core.PublicApiCreatorApp", - "lombok.core.configuration.ConfigurationApp", - "lombok.core.runtimeDependencies.CreateLombokRuntimeApp", - "lombok.delombok.DelombokApp", - "lombok.eclipse.agent.MavenEcjBootstrapApp", - "lombok.installer.Installer$CommandLineInstallerApp", - "lombok.installer.Installer$CommandLineUninstallerApp", - "lombok.installer.Installer$GraphicalInstallerApp" - ], - "lombok.core.PostCompilerTransformation": [ - "lombok.bytecode.PreventNullAnalysisRemover", - "lombok.bytecode.SneakyThrowsRemover" - ], - "lombok.core.runtimeDependencies.RuntimeDependencyInfo": [ - "lombok.core.handlers.SneakyThrowsAndCleanupDependencyInfo" - ], - "lombok.eclipse.EclipseASTVisitor": [ - "lombok.eclipse.handlers.HandleFieldDefaults", - "lombok.eclipse.handlers.HandleVal" - ], - "lombok.eclipse.EclipseAnnotationHandler": [ - "lombok.eclipse.handlers.HandleAccessors", - "lombok.eclipse.handlers.HandleBuilder", - "lombok.eclipse.handlers.HandleBuilderDefault", - "lombok.eclipse.handlers.HandleCleanup", - "lombok.eclipse.handlers.HandleConstructor$HandleAllArgsConstructor", - "lombok.eclipse.handlers.HandleConstructor$HandleNoArgsConstructor", - "lombok.eclipse.handlers.HandleConstructor$HandleRequiredArgsConstructor", - "lombok.eclipse.handlers.HandleData", - "lombok.eclipse.handlers.HandleDelegate", - "lombok.eclipse.handlers.HandleEqualsAndHashCode", - "lombok.eclipse.handlers.HandleExtensionMethod", - "lombok.eclipse.handlers.HandleFieldNameConstants", - "lombok.eclipse.handlers.HandleGetter", - "lombok.eclipse.handlers.HandleHelper", - "lombok.eclipse.handlers.HandleJacksonized", - "lombok.eclipse.handlers.HandleLocked", - "lombok.eclipse.handlers.HandleLockedRead", - "lombok.eclipse.handlers.HandleLockedWrite", - "lombok.eclipse.handlers.HandleLog$HandleCommonsLog", - "lombok.eclipse.handlers.HandleLog$HandleCustomLog", - "lombok.eclipse.handlers.HandleLog$HandleFloggerLog", - "lombok.eclipse.handlers.HandleLog$HandleJBossLog", - "lombok.eclipse.handlers.HandleLog$HandleJulLog", - "lombok.eclipse.handlers.HandleLog$HandleLog4j2Log", - "lombok.eclipse.handlers.HandleLog$HandleLog4jLog", - "lombok.eclipse.handlers.HandleLog$HandleSlf4jLog", - "lombok.eclipse.handlers.HandleLog$HandleXSlf4jLog", - "lombok.eclipse.handlers.HandleNonNull", - "lombok.eclipse.handlers.HandlePrintAST", - "lombok.eclipse.handlers.HandleSetter", - "lombok.eclipse.handlers.HandleSneakyThrows", - "lombok.eclipse.handlers.HandleStandardException", - "lombok.eclipse.handlers.HandleSuperBuilder", - "lombok.eclipse.handlers.HandleSynchronized", - "lombok.eclipse.handlers.HandleToString", - "lombok.eclipse.handlers.HandleUtilityClass", - "lombok.eclipse.handlers.HandleValue", - "lombok.eclipse.handlers.HandleWith", - "lombok.eclipse.handlers.HandleWithBy" - ], - "lombok.eclipse.handlers.EclipseSingularsRecipes$EclipseSingularizer": [ - "lombok.eclipse.handlers.singulars.EclipseGuavaMapSingularizer", - "lombok.eclipse.handlers.singulars.EclipseGuavaSetListSingularizer", - "lombok.eclipse.handlers.singulars.EclipseGuavaTableSingularizer", - "lombok.eclipse.handlers.singulars.EclipseJavaUtilListSingularizer", - "lombok.eclipse.handlers.singulars.EclipseJavaUtilMapSingularizer", - "lombok.eclipse.handlers.singulars.EclipseJavaUtilSetSingularizer" - ], - "lombok.installer.IdeLocationProvider": [ - "lombok.installer.eclipse.AngularIDELocationProvider", - "lombok.installer.eclipse.EclipseLocationProvider", - "lombok.installer.eclipse.JbdsLocationProvider", - "lombok.installer.eclipse.MyEclipseLocationProvider", - "lombok.installer.eclipse.RhcrLocationProvider", - "lombok.installer.eclipse.RhdsLocationProvider", - "lombok.installer.eclipse.STS4LocationProvider", - "lombok.installer.eclipse.STS5LocationProvider", - "lombok.installer.eclipse.STSLocationProvider" - ], - "lombok.javac.JavacASTVisitor": [ - "lombok.javac.handlers.HandleFieldDefaults", - "lombok.javac.handlers.HandleVal" - ], - "lombok.javac.JavacAnnotationHandler": [ - "lombok.javac.handlers.HandleAccessors", - "lombok.javac.handlers.HandleBuilder", - "lombok.javac.handlers.HandleBuilderDefault", - "lombok.javac.handlers.HandleBuilderDefaultRemove", - "lombok.javac.handlers.HandleBuilderRemove", - "lombok.javac.handlers.HandleCleanup", - "lombok.javac.handlers.HandleConstructor$HandleAllArgsConstructor", - "lombok.javac.handlers.HandleConstructor$HandleNoArgsConstructor", - "lombok.javac.handlers.HandleConstructor$HandleRequiredArgsConstructor", - "lombok.javac.handlers.HandleData", - "lombok.javac.handlers.HandleDelegate", - "lombok.javac.handlers.HandleEqualsAndHashCode", - "lombok.javac.handlers.HandleExtensionMethod", - "lombok.javac.handlers.HandleFieldNameConstants", - "lombok.javac.handlers.HandleGetter", - "lombok.javac.handlers.HandleHelper", - "lombok.javac.handlers.HandleJacksonized", - "lombok.javac.handlers.HandleLocked", - "lombok.javac.handlers.HandleLockedRead", - "lombok.javac.handlers.HandleLockedWrite", - "lombok.javac.handlers.HandleLog$HandleCommonsLog", - "lombok.javac.handlers.HandleLog$HandleCustomLog", - "lombok.javac.handlers.HandleLog$HandleFloggerLog", - "lombok.javac.handlers.HandleLog$HandleJBossLog", - "lombok.javac.handlers.HandleLog$HandleJulLog", - "lombok.javac.handlers.HandleLog$HandleLog4j2Log", - "lombok.javac.handlers.HandleLog$HandleLog4jLog", - "lombok.javac.handlers.HandleLog$HandleSlf4jLog", - "lombok.javac.handlers.HandleLog$HandleXSlf4jLog", - "lombok.javac.handlers.HandleNonNull", - "lombok.javac.handlers.HandlePrintAST", - "lombok.javac.handlers.HandleSetter", - "lombok.javac.handlers.HandleSingularRemove", - "lombok.javac.handlers.HandleSneakyThrows", - "lombok.javac.handlers.HandleStandardException", - "lombok.javac.handlers.HandleSuperBuilder", - "lombok.javac.handlers.HandleSuperBuilderRemove", - "lombok.javac.handlers.HandleSynchronized", - "lombok.javac.handlers.HandleToString", - "lombok.javac.handlers.HandleUtilityClass", - "lombok.javac.handlers.HandleValue", - "lombok.javac.handlers.HandleWith", - "lombok.javac.handlers.HandleWithBy" - ], - "lombok.javac.handlers.JavacSingularsRecipes$JavacSingularizer": [ - "lombok.javac.handlers.singulars.JavacGuavaMapSingularizer", - "lombok.javac.handlers.singulars.JavacGuavaSetListSingularizer", - "lombok.javac.handlers.singulars.JavacGuavaTableSingularizer", - "lombok.javac.handlers.singulars.JavacJavaUtilListSingularizer", - "lombok.javac.handlers.singulars.JavacJavaUtilMapSingularizer", - "lombok.javac.handlers.singulars.JavacJavaUtilSetSingularizer" - ] - }, - "org.springframework.boot:spring-boot": { - "ch.qos.logback.classic.spi.Configurator": [ - "org.springframework.boot.logging.logback.RootLogLevelConfigurator" - ], - "org.apache.logging.log4j.util.PropertySource": [ - "org.springframework.boot.logging.log4j2.SpringBootPropertySource" - ] - }, - "org.springframework.boot:spring-boot-micrometer-tracing-opentelemetry": { - "org.junit.platform.launcher.TestExecutionListener": [ - "org.springframework.boot.micrometer.tracing.opentelemetry.autoconfigure.OpenTelemetryEventPublisherBeansTestExecutionListener" - ] - }, - "org.springframework.data:spring-data-cassandra": { - "jakarta.enterprise.inject.spi.Extension": [ - "org.springframework.data.cassandra.repository.cdi.CassandraRepositoryExtension" - ] - }, - "org.springframework.security:spring-security-core": { - "io.micrometer.context.ThreadLocalAccessor": [ - "org.springframework.security.core.context.ReactiveSecurityContextHolderThreadLocalAccessor", - "org.springframework.security.core.context.SecurityContextHolderThreadLocalAccessor" - ] - }, - "org.springframework.security:spring-security-web": { - "io.micrometer.context.ThreadLocalAccessor": [ - "org.springframework.security.web.server.ServerWebExchangeThreadLocalAccessor" - ] - }, - "org.springframework:spring-core": { - "reactor.blockhound.integration.BlockHoundIntegration": [ - "org.springframework.core.ReactiveAdapterRegistry$SpringCoreBlockHoundIntegration" - ] - }, - "org.springframework:spring-web": { - "jakarta.servlet.ServletContainerInitializer": [ - "org.springframework.web.SpringServletContainerInitializer" - ], - "reactor.blockhound.integration.BlockHoundIntegration": [ - "org.springframework.web.server.adapter.WebHttpHandlerBuilder$SpringWebBlockHoundIntegration" - ] - }, - "org.testcontainers:testcontainers": { - "org.testcontainers.dockerclient.DockerClientProviderStrategy": [ - "org.testcontainers.dockerclient.DockerDesktopClientProviderStrategy", - "org.testcontainers.dockerclient.DockerMachineClientProviderStrategy", - "org.testcontainers.dockerclient.EnvironmentAndSystemPropertyClientProviderStrategy", - "org.testcontainers.dockerclient.NpipeSocketClientProviderStrategy", - "org.testcontainers.dockerclient.RootlessDockerClientProviderStrategy", - "org.testcontainers.dockerclient.TestcontainersHostPropertyClientProviderStrategy", - "org.testcontainers.dockerclient.UnixSocketClientProviderStrategy" - ], - "org.testcontainers.shaded.com.fasterxml.jackson.core.JsonFactory": [ - "org.testcontainers.shaded.com.fasterxml.jackson.core.JsonFactory" - ], - "org.testcontainers.shaded.com.fasterxml.jackson.core.ObjectCodec": [ - "org.testcontainers.shaded.com.fasterxml.jackson.databind.ObjectMapper" - ] - }, - "org.wiremock:wiremock-standalone": { - "wiremock.com.fasterxml.jackson.core.JsonFactory": [ - "wiremock.com.fasterxml.jackson.core.JsonFactory", - "wiremock.com.fasterxml.jackson.dataformat.yaml.YAMLFactory" - ], - "wiremock.com.fasterxml.jackson.core.ObjectCodec": [ - "wiremock.com.fasterxml.jackson.databind.ObjectMapper", - "wiremock.com.fasterxml.jackson.dataformat.yaml.YAMLMapper" - ], - "wiremock.com.fasterxml.jackson.databind.Module": [ - "wiremock.com.fasterxml.jackson.datatype.jsr310.JavaTimeModule" - ], - "wiremock.org.eclipse.jetty.http.HttpFieldPreEncoder": [ - "wiremock.org.eclipse.jetty.http.Http1FieldPreEncoder", - "wiremock.org.eclipse.jetty.http2.hpack.HpackFieldPreEncoder" - ], - "wiremock.org.eclipse.jetty.io.ssl.ALPNProcessor$Client": [ - "wiremock.org.eclipse.jetty.alpn.java.client.JDK9ClientALPNProcessor" - ], - "wiremock.org.eclipse.jetty.io.ssl.ALPNProcessor$Server": [ - "wiremock.org.eclipse.jetty.alpn.java.server.JDK9ServerALPNProcessor" - ], - "wiremock.org.eclipse.jetty.webapp.Configuration": [ - "wiremock.org.eclipse.jetty.webapp.FragmentConfiguration", - "wiremock.org.eclipse.jetty.webapp.JaasConfiguration", - "wiremock.org.eclipse.jetty.webapp.JaspiConfiguration", - "wiremock.org.eclipse.jetty.webapp.JettyWebXmlConfiguration", - "wiremock.org.eclipse.jetty.webapp.JmxConfiguration", - "wiremock.org.eclipse.jetty.webapp.JndiConfiguration", - "wiremock.org.eclipse.jetty.webapp.JspConfiguration", - "wiremock.org.eclipse.jetty.webapp.MetaInfConfiguration", - "wiremock.org.eclipse.jetty.webapp.ServletsConfiguration", - "wiremock.org.eclipse.jetty.webapp.WebAppConfiguration", - "wiremock.org.eclipse.jetty.webapp.WebInfConfiguration", - "wiremock.org.eclipse.jetty.webapp.WebXmlConfiguration" - ], - "wiremock.org.slf4j.spi.SLF4JServiceProvider": [ - "wiremock.org.slf4j.helpers.NOP_FallbackServiceProvider" - ], - "wiremock.org.xmlunit.placeholder.PlaceholderHandler": [ - "wiremock.org.xmlunit.placeholder.IgnorePlaceholderHandler", - "wiremock.org.xmlunit.placeholder.IsDateTimePlaceholderHandler", - "wiremock.org.xmlunit.placeholder.IsNumberPlaceholderHandler", - "wiremock.org.xmlunit.placeholder.MatchesRegexPlaceholderHandler" - ] - }, - "software.amazon.awssdk:third-party-jackson-core": { - "software.amazon.awssdk.thirdparty.jackson.core.JsonFactory": [ - "software.amazon.awssdk.thirdparty.jackson.core.JsonFactory" - ] - }, - "tools.jackson.core:jackson-core": { - "tools.jackson.core.TokenStreamFactory": [ - "tools.jackson.core.json.JsonFactory" - ] - }, - "tools.jackson.core:jackson-databind": { - "tools.jackson.databind.ObjectMapper": [ - "tools.jackson.databind.json.JsonMapper" - ] - }, - "tools.jackson.module:jackson-module-blackbird": { - "tools.jackson.databind.JacksonModule": [ - "tools.jackson.module.blackbird.BlackbirdModule" - ] - } - }, - "skipped": [], - "version": "3" -} diff --git a/src/libraries/java/nv-boot-parent/tools/bazel/notice_metadata.json b/src/libraries/java/nv-boot-parent/notice_metadata.json similarity index 100% rename from src/libraries/java/nv-boot-parent/tools/bazel/notice_metadata.json rename to src/libraries/java/nv-boot-parent/notice_metadata.json diff --git a/src/libraries/java/nv-boot-parent/tools/bazel/notice_roots.json b/src/libraries/java/nv-boot-parent/notice_roots.json similarity index 100% rename from src/libraries/java/nv-boot-parent/tools/bazel/notice_roots.json rename to src/libraries/java/nv-boot-parent/notice_roots.json diff --git a/src/libraries/java/nv-boot-parent/nv-boot-mock-servers-test/BUILD.bazel b/src/libraries/java/nv-boot-parent/nv-boot-mock-servers-test/BUILD.bazel index acb3366a0..23692d227 100644 --- a/src/libraries/java/nv-boot-parent/nv-boot-mock-servers-test/BUILD.bazel +++ b/src/libraries/java/nv-boot-parent/nv-boot-mock-servers-test/BUILD.bazel @@ -1,4 +1,4 @@ -load("//tools/bazel:java.bzl", "nv_boot_library", "nv_boot_library_test") +load("//rules/java:defs.bzl", "nv_boot_library", "nv_boot_library_test") MOCK_SERVERS_COMPILE_DEPS = [ "@nv_third_party_deps//:com_fasterxml_jackson_core_jackson_annotations", diff --git a/src/libraries/java/nv-boot-parent/nv-boot-starter-audit/BUILD.bazel b/src/libraries/java/nv-boot-parent/nv-boot-starter-audit/BUILD.bazel index fe0b483ff..63ef3407f 100644 --- a/src/libraries/java/nv-boot-parent/nv-boot-starter-audit/BUILD.bazel +++ b/src/libraries/java/nv-boot-parent/nv-boot-starter-audit/BUILD.bazel @@ -1,5 +1,5 @@ load("@rules_java//java:defs.bzl", "java_library") -load("//tools/bazel:java.bzl", "nv_boot_library", "nv_boot_library_test", "nv_boot_runtime_classpath_test") +load("//rules/java:defs.bzl", "nv_boot_library", "nv_boot_library_test", "nv_boot_runtime_classpath_test") AUDIT_REQUIRED_DEPS = [ "@nv_third_party_deps//:com_fasterxml_jackson_core_jackson_annotations", @@ -40,7 +40,7 @@ java_library( nv_boot_library( name = "nv_boot_starter_audit", srcs = glob(["src/main/java/**/*.java"]), - resource_strip_prefix = "nv-boot-starter-audit/src/main/resources", + resource_strip_prefix = "src/libraries/java/nv-boot-parent/nv-boot-starter-audit/src/main/resources", resources = glob(["src/main/resources/**"]), visibility = ["//visibility:public"], deps = AUDIT_REQUIRED_DEPS + [":optional_compile_deps"], diff --git a/src/libraries/java/nv-boot-parent/nv-boot-starter-cassandra/BUILD.bazel b/src/libraries/java/nv-boot-parent/nv-boot-starter-cassandra/BUILD.bazel index ea64f0995..95c7d07cb 100644 --- a/src/libraries/java/nv-boot-parent/nv-boot-starter-cassandra/BUILD.bazel +++ b/src/libraries/java/nv-boot-parent/nv-boot-starter-cassandra/BUILD.bazel @@ -1,4 +1,4 @@ -load("//tools/bazel:java.bzl", "nv_boot_library", "nv_boot_library_test") +load("//rules/java:defs.bzl", "nv_boot_library", "nv_boot_library_test") CASSANDRA_COMPILE_DEPS = [ "@nv_third_party_deps//:at_yawk_lz4_lz4_java", @@ -47,7 +47,7 @@ CASSANDRA_TEST_DEPS = [ nv_boot_library( name = "nv_boot_starter_cassandra", srcs = glob(["src/main/java/**/*.java"]), - resource_strip_prefix = "nv-boot-starter-cassandra/src/main/resources", + resource_strip_prefix = "src/libraries/java/nv-boot-parent/nv-boot-starter-cassandra/src/main/resources", resources = glob(["src/main/resources/**"]), visibility = ["//visibility:public"], deps = CASSANDRA_COMPILE_DEPS, @@ -57,7 +57,7 @@ nv_boot_library_test( name = "tests", srcs = glob(["src/test/java/**/*.java"]), coverage_library = ":nv_boot_starter_cassandra", - resource_strip_prefix = "nv-boot-starter-cassandra/src/test/resources", + resource_strip_prefix = "src/libraries/java/nv-boot-parent/nv-boot-starter-cassandra/src/test/resources", resources = glob(["src/test/resources/**"]), deps = CASSANDRA_TEST_DEPS, size = "large", diff --git a/src/libraries/java/nv-boot-parent/nv-boot-starter-core/BUILD.bazel b/src/libraries/java/nv-boot-parent/nv-boot-starter-core/BUILD.bazel index 2ca8c9ab4..bb65cc339 100644 --- a/src/libraries/java/nv-boot-parent/nv-boot-starter-core/BUILD.bazel +++ b/src/libraries/java/nv-boot-parent/nv-boot-starter-core/BUILD.bazel @@ -1,5 +1,5 @@ load("@rules_java//java:defs.bzl", "java_library") -load("//tools/bazel:java.bzl", "nv_boot_library", "nv_boot_library_test", "nv_boot_runtime_classpath_test") +load("//rules/java:defs.bzl", "nv_boot_library", "nv_boot_library_test", "nv_boot_runtime_classpath_test") CORE_REQUIRED_DEPS = [ "@nv_third_party_deps//:com_github_ben_manes_caffeine_guava", @@ -41,7 +41,7 @@ java_library( nv_boot_library( name = "nv_boot_starter_core", srcs = glob(["src/main/java/**/*.java"]), - resource_strip_prefix = "nv-boot-starter-core/src/main/resources", + resource_strip_prefix = "src/libraries/java/nv-boot-parent/nv-boot-starter-core/src/main/resources", resources = glob(["src/main/resources/**"]), visibility = ["//visibility:public"], deps = CORE_REQUIRED_DEPS + [":optional_compile_deps"], @@ -65,7 +65,7 @@ nv_boot_library_test( name = "tests", srcs = glob(["src/test/java/**/*.java"]), coverage_library = ":nv_boot_starter_core", - resource_strip_prefix = "nv-boot-starter-core/src/test/resources", + resource_strip_prefix = "src/libraries/java/nv-boot-parent/nv-boot-starter-core/src/test/resources", resources = glob(["src/test/resources/**"]), deps = [ ":nv_boot_starter_core", diff --git a/src/libraries/java/nv-boot-parent/nv-boot-starter-data-migration-notification/BUILD.bazel b/src/libraries/java/nv-boot-parent/nv-boot-starter-data-migration-notification/BUILD.bazel index 0d0d3bee7..bfc64bdbc 100644 --- a/src/libraries/java/nv-boot-parent/nv-boot-starter-data-migration-notification/BUILD.bazel +++ b/src/libraries/java/nv-boot-parent/nv-boot-starter-data-migration-notification/BUILD.bazel @@ -1,4 +1,4 @@ -load("//tools/bazel:java.bzl", "nv_boot_library", "nv_boot_library_test") +load("//rules/java:defs.bzl", "nv_boot_library", "nv_boot_library_test") DATA_MIGRATION_NOTIFICATION_COMPILE_DEPS = [ "@nv_third_party_deps//:io_cloudevents_cloudevents_api", @@ -24,7 +24,7 @@ DATA_MIGRATION_NOTIFICATION_COMPILE_DEPS = [ nv_boot_library( name = "nv_boot_starter_data_migration_notification", srcs = glob(["src/main/java/**/*.java"]), - resource_strip_prefix = "nv-boot-starter-data-migration-notification/src/main/resources", + resource_strip_prefix = "src/libraries/java/nv-boot-parent/nv-boot-starter-data-migration-notification/src/main/resources", resources = glob(["src/main/resources/**"]), visibility = ["//visibility:public"], deps = DATA_MIGRATION_NOTIFICATION_COMPILE_DEPS, diff --git a/src/libraries/java/nv-boot-parent/nv-boot-starter-exceptions/BUILD.bazel b/src/libraries/java/nv-boot-parent/nv-boot-starter-exceptions/BUILD.bazel index 3171512e5..9fb7fabc1 100644 --- a/src/libraries/java/nv-boot-parent/nv-boot-starter-exceptions/BUILD.bazel +++ b/src/libraries/java/nv-boot-parent/nv-boot-starter-exceptions/BUILD.bazel @@ -1,5 +1,5 @@ load("@rules_java//java:defs.bzl", "java_library") -load("//tools/bazel:java.bzl", "nv_boot_library", "nv_boot_library_test", "nv_boot_runtime_classpath_test") +load("//rules/java:defs.bzl", "nv_boot_library", "nv_boot_library_test", "nv_boot_runtime_classpath_test") EXCEPTIONS_REQUIRED_DEPS = [ "@nv_third_party_deps//:jakarta_annotation_jakarta_annotation_api", @@ -32,7 +32,7 @@ java_library( nv_boot_library( name = "nv_boot_starter_exceptions", srcs = glob(["src/main/java/**/*.java"]), - resource_strip_prefix = "nv-boot-starter-exceptions/src/main/resources", + resource_strip_prefix = "src/libraries/java/nv-boot-parent/nv-boot-starter-exceptions/src/main/resources", resources = glob(["src/main/resources/**"]), visibility = ["//visibility:public"], deps = EXCEPTIONS_REQUIRED_DEPS + [":optional_compile_deps"], @@ -55,7 +55,7 @@ nv_boot_library_test( name = "tests", srcs = glob(["src/test/java/**/*.java"]), coverage_library = ":nv_boot_starter_exceptions", - resource_strip_prefix = "nv-boot-starter-exceptions/src/test/resources", + resource_strip_prefix = "src/libraries/java/nv-boot-parent/nv-boot-starter-exceptions/src/test/resources", resources = glob(["src/test/resources/**"]), deps = [ ":nv_boot_starter_exceptions", diff --git a/src/libraries/java/nv-boot-parent/nv-boot-starter-jwt/BUILD.bazel b/src/libraries/java/nv-boot-parent/nv-boot-starter-jwt/BUILD.bazel index dda0b65df..1f246808c 100644 --- a/src/libraries/java/nv-boot-parent/nv-boot-starter-jwt/BUILD.bazel +++ b/src/libraries/java/nv-boot-parent/nv-boot-starter-jwt/BUILD.bazel @@ -1,4 +1,4 @@ -load("//tools/bazel:java.bzl", "nv_boot_library", "nv_boot_library_test") +load("//rules/java:defs.bzl", "nv_boot_library", "nv_boot_library_test") JWT_COMPILE_DEPS = [ "@nv_third_party_deps//:com_fasterxml_jackson_core_jackson_annotations", @@ -29,7 +29,7 @@ JWT_COMPILE_DEPS = [ nv_boot_library( name = "nv_boot_starter_jwt", srcs = glob(["src/main/java/**/*.java"]), - resource_strip_prefix = "nv-boot-starter-jwt/src/main/resources", + resource_strip_prefix = "src/libraries/java/nv-boot-parent/nv-boot-starter-jwt/src/main/resources", resources = glob(["src/main/resources/**"]), visibility = ["//visibility:public"], deps = JWT_COMPILE_DEPS, @@ -39,7 +39,7 @@ nv_boot_library_test( name = "tests", srcs = glob(["src/test/java/**/*.java"]), coverage_library = ":nv_boot_starter_jwt", - resource_strip_prefix = "nv-boot-starter-jwt/src/test/resources", + resource_strip_prefix = "src/libraries/java/nv-boot-parent/nv-boot-starter-jwt/src/test/resources", resources = glob(["src/test/resources/**"]), deps = [ ":nv_boot_starter_jwt", diff --git a/src/libraries/java/nv-boot-parent/nv-boot-starter-observability/BUILD.bazel b/src/libraries/java/nv-boot-parent/nv-boot-starter-observability/BUILD.bazel index fd238f454..a78a84da5 100644 --- a/src/libraries/java/nv-boot-parent/nv-boot-starter-observability/BUILD.bazel +++ b/src/libraries/java/nv-boot-parent/nv-boot-starter-observability/BUILD.bazel @@ -1,5 +1,5 @@ load("@rules_java//java:defs.bzl", "java_library") -load("//tools/bazel:java.bzl", "nv_boot_library", "nv_boot_library_test", "nv_boot_runtime_classpath_test") +load("//rules/java:defs.bzl", "nv_boot_library", "nv_boot_library_test", "nv_boot_runtime_classpath_test") OBSERVABILITY_REQUIRED_DEPS = [ "@nv_third_party_deps//:ch_qos_logback_logback_classic", @@ -59,7 +59,7 @@ java_library( nv_boot_library( name = "nv_boot_starter_observability", srcs = glob(["src/main/java/**/*.java"]), - resource_strip_prefix = "nv-boot-starter-observability/src/main/resources", + resource_strip_prefix = "src/libraries/java/nv-boot-parent/nv-boot-starter-observability/src/main/resources", resources = glob(["src/main/resources/**"]), visibility = ["//visibility:public"], deps = OBSERVABILITY_REQUIRED_DEPS + [":optional_compile_deps"], @@ -84,7 +84,7 @@ nv_boot_library_test( name = "tests", srcs = glob(["src/test/java/**/*.java"]), coverage_library = ":nv_boot_starter_observability", - resource_strip_prefix = "nv-boot-starter-observability/src/test/resources", + resource_strip_prefix = "src/libraries/java/nv-boot-parent/nv-boot-starter-observability/src/test/resources", resources = glob(["src/test/resources/**"]), deps = [ ":nv_boot_starter_observability", diff --git a/src/libraries/java/nv-boot-parent/nv-boot-starter-registries/BUILD.bazel b/src/libraries/java/nv-boot-parent/nv-boot-starter-registries/BUILD.bazel index 2fcfb9745..5074efaa2 100644 --- a/src/libraries/java/nv-boot-parent/nv-boot-starter-registries/BUILD.bazel +++ b/src/libraries/java/nv-boot-parent/nv-boot-starter-registries/BUILD.bazel @@ -1,7 +1,7 @@ -load("//tools/bazel:java.bzl", "nv_boot_library", "nv_boot_library_test") +load("//rules/java:defs.bzl", "nv_boot_library", "nv_boot_library_test") REGISTRIES_COMPILE_DEPS = [ - "//nv-boot-starter-exceptions:nv_boot_starter_exceptions", + "//src/libraries/java/nv-boot-parent/nv-boot-starter-exceptions:nv_boot_starter_exceptions", "@nv_third_party_deps//:com_fasterxml_jackson_core_jackson_annotations", "@nv_third_party_deps//:com_github_ben_manes_caffeine_caffeine", "@nv_third_party_deps//:com_github_ben_manes_caffeine_guava", @@ -48,7 +48,7 @@ REGISTRIES_COMPILE_DEPS = [ nv_boot_library( name = "nv_boot_starter_registries", srcs = glob(["src/main/java/**/*.java"]), - resource_strip_prefix = "nv-boot-starter-registries/src/main/resources", + resource_strip_prefix = "src/libraries/java/nv-boot-parent/nv-boot-starter-registries/src/main/resources", resources = glob(["src/main/resources/**"]), visibility = ["//visibility:public"], deps = REGISTRIES_COMPILE_DEPS, @@ -58,11 +58,11 @@ nv_boot_library_test( name = "tests", srcs = glob(["src/test/java/**/*.java"]), coverage_library = ":nv_boot_starter_registries", - resource_strip_prefix = "nv-boot-starter-registries/src/test/resources", + resource_strip_prefix = "src/libraries/java/nv-boot-parent/nv-boot-starter-registries/src/test/resources", resources = glob(["src/test/resources/**"]), deps = [ ":nv_boot_starter_registries", - "//nv-boot-mock-servers-test:nv_boot_mock_servers_test", + "//src/libraries/java/nv-boot-parent/nv-boot-mock-servers-test:nv_boot_mock_servers_test", "@nv_third_party_deps//:org_springframework_boot_spring_boot_starter_webflux_test", "@nv_third_party_deps//:org_wiremock_wiremock_standalone", ] + REGISTRIES_COMPILE_DEPS, diff --git a/src/libraries/java/nv-boot-parent/nv-boot-starter-reloadable-properties/BUILD.bazel b/src/libraries/java/nv-boot-parent/nv-boot-starter-reloadable-properties/BUILD.bazel index 2bb6601b2..51be2c950 100644 --- a/src/libraries/java/nv-boot-parent/nv-boot-starter-reloadable-properties/BUILD.bazel +++ b/src/libraries/java/nv-boot-parent/nv-boot-starter-reloadable-properties/BUILD.bazel @@ -1,4 +1,4 @@ -load("//tools/bazel:java.bzl", "nv_boot_library", "nv_boot_library_test", "nv_boot_workspace_runfiles") +load("//rules/java:defs.bzl", "nv_boot_library", "nv_boot_library_test", "nv_boot_workspace_runfiles") RELOADABLE_PROPERTIES_COMPILE_DEPS = [ "@nv_third_party_deps//:com_github_ben_manes_caffeine_guava", @@ -23,13 +23,13 @@ filegroup( nv_boot_workspace_runfiles( name = "reloadable_properties_test_resources", srcs = [":test_resource_files"], - strip_prefix = "nv-boot-starter-reloadable-properties/", + strip_prefix = "src/libraries/java/nv-boot-parent/nv-boot-starter-reloadable-properties/", ) nv_boot_library( name = "nv_boot_starter_reloadable_properties", srcs = glob(["src/main/java/**/*.java"]), - resource_strip_prefix = "nv-boot-starter-reloadable-properties/src/main/resources", + resource_strip_prefix = "src/libraries/java/nv-boot-parent/nv-boot-starter-reloadable-properties/src/main/resources", resources = glob(["src/main/resources/**"]), visibility = ["//visibility:public"], deps = RELOADABLE_PROPERTIES_COMPILE_DEPS, @@ -41,7 +41,7 @@ nv_boot_library_test( coverage_library = ":nv_boot_starter_reloadable_properties", data = [":reloadable_properties_test_resources"], junit_classpath = ["src/test/resources"], - resource_strip_prefix = "nv-boot-starter-reloadable-properties/src/test/resources", + resource_strip_prefix = "src/libraries/java/nv-boot-parent/nv-boot-starter-reloadable-properties/src/test/resources", resources = glob(["src/test/resources/**"]), deps = [ ":nv_boot_starter_reloadable_properties", diff --git a/src/libraries/java/nv-boot-parent/nv-boot-starter-telemetry/BUILD.bazel b/src/libraries/java/nv-boot-parent/nv-boot-starter-telemetry/BUILD.bazel index ef45217e6..d5a57b8aa 100644 --- a/src/libraries/java/nv-boot-parent/nv-boot-starter-telemetry/BUILD.bazel +++ b/src/libraries/java/nv-boot-parent/nv-boot-starter-telemetry/BUILD.bazel @@ -1,4 +1,4 @@ -load("//tools/bazel:java.bzl", "nv_boot_library", "nv_boot_library_test") +load("//rules/java:defs.bzl", "nv_boot_library", "nv_boot_library_test") TELEMETRY_COMPILE_DEPS = [ "@nv_third_party_deps//:io_cloudevents_cloudevents_api", @@ -30,7 +30,7 @@ TELEMETRY_COMPILE_DEPS = [ nv_boot_library( name = "nv_boot_starter_telemetry", srcs = glob(["src/main/java/**/*.java"]), - resource_strip_prefix = "nv-boot-starter-telemetry/src/main/resources", + resource_strip_prefix = "src/libraries/java/nv-boot-parent/nv-boot-starter-telemetry/src/main/resources", resources = glob(["src/main/resources/**"]), visibility = ["//visibility:public"], deps = TELEMETRY_COMPILE_DEPS, diff --git a/src/libraries/java/nv-boot-parent/tools/bazel/BUILD.bazel b/src/libraries/java/nv-boot-parent/tools/bazel/BUILD.bazel deleted file mode 100644 index b8494a40f..000000000 --- a/src/libraries/java/nv-boot-parent/tools/bazel/BUILD.bazel +++ /dev/null @@ -1,58 +0,0 @@ -load("@rules_java//java:defs.bzl", "java_binary", "java_library", "java_plugin") -load("@rules_python//python:defs.bzl", "py_binary") -load("@rules_shell//shell:sh_test.bzl", "sh_test") - -package(default_visibility = ["//visibility:public"]) - -exports_files([ - "jacoco_test_runner.sh", - "lcov_to_sonar_generic.py", - "lcov_to_sonar_generic_test.sh", - "notice_metadata.json", - "notice_roots.json", -]) - -py_binary( - name = "generate_notice_tool", - srcs = ["generate_notice.py"], - main = "generate_notice.py", - python_version = "3.11", -) - -sh_test( - name = "lcov_to_sonar_generic_test", - srcs = ["lcov_to_sonar_generic_test.sh"], - data = [":lcov_to_sonar_generic.py"], -) - -sh_test( - name = "notice_check_test", - srcs = ["notice_check_test.sh"], - data = [ - ":generate_notice.py", - ":notice_metadata.json", - "//:MODULE.bazel", - "//:NOTICE", - "//:maven_install.json", - ":notice_roots.json", - ], -) - -java_plugin( - name = "lombok_plugin", - generates_api = True, - processor_class = "lombok.launch.AnnotationProcessorHider$AnnotationProcessor", - deps = ["@nv_third_party_deps//:org_projectlombok_lombok"], -) - -java_binary( - name = "jacoco_cli", - main_class = "org.jacoco.cli.internal.Main", - runtime_deps = ["@nv_third_party_deps//:org_jacoco_org_jacoco_cli"], -) - -java_library( - name = "lombok_annotations", - exports = ["@nv_third_party_deps//:org_projectlombok_lombok"], - neverlink = True, -) diff --git a/src/libraries/java/nv-boot-parent/tools/bazel/jacoco_test_runner.sh b/src/libraries/java/nv-boot-parent/tools/bazel/jacoco_test_runner.sh deleted file mode 100755 index 7033aeebb..000000000 --- a/src/libraries/java/nv-boot-parent/tools/bazel/jacoco_test_runner.sh +++ /dev/null @@ -1,77 +0,0 @@ -#!/usr/bin/env bash -# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 - -set -euo pipefail - -if [ "$#" -lt 5 ]; then - echo "Usage: $0 <junit-runner> <classfiles> <source-root> <title> <jacoco-cli> [junit-args...]" >&2 - exit 2 -fi - -absolute_path() { - case "$1" in - /*) printf '%s\n' "$1" ;; - *) printf '%s/%s\n' "${PWD}" "$1" ;; - esac -} - -junit_runner="$(absolute_path "$1")" -classfiles="$(absolute_path "$2")" -source_root="$3" -report_title="$4" -jacoco_cli="$(absolute_path "$5")" -shift 5 - -report_dir="${TEST_UNDECLARED_OUTPUTS_DIR:?TEST_UNDECLARED_OUTPUTS_DIR is required}" -junit_report_dir="${report_dir}/junit" -junit_xml="${junit_report_dir}/TEST-junit-jupiter.xml" -exec_file="${PWD}/jacoco.exec" -sourcefiles="" -if [ -n "${source_root}" ]; then - sourcefiles="${TEST_SRCDIR:?TEST_SRCDIR is required}/${TEST_WORKSPACE:?TEST_WORKSPACE is required}/${source_root}" -fi - -mkdir -p "${report_dir}" "${junit_report_dir}" -rm -f "${exec_file}" - -set +e -"${junit_runner}" "$@" --reports-dir="${junit_report_dir}" -junit_status=$? -set -e - -report_status=0 -if [ ! -s "${junit_xml}" ]; then - echo "ERROR: JUnit did not create ${junit_xml}" >&2 - report_status=1 -fi - -if [ ! -s "${exec_file}" ]; then - echo "ERROR: JaCoCo did not create ${exec_file}" >&2 - report_status=1 -else - cp "${exec_file}" "${report_dir}/jacoco.exec" - report_args=( - report "${report_dir}/jacoco.exec" - --classfiles "${classfiles}" - --html "${report_dir}" - --xml "${report_dir}/jacoco.xml" - --name "${report_title}" - ) - if [ -n "${sourcefiles}" ]; then - report_args+=(--sourcefiles "${sourcefiles}") - fi - - set +e - "${jacoco_cli}" "${report_args[@]}" - jacoco_status=$? - set -e - if [ "${jacoco_status}" -ne 0 ]; then - report_status="${jacoco_status}" - fi -fi - -if [ "${junit_status}" -ne 0 ]; then - exit "${junit_status}" -fi -exit "${report_status}" diff --git a/src/libraries/java/nv-boot-parent/tools/bazel/java.bzl b/src/libraries/java/nv-boot-parent/tools/bazel/java.bzl deleted file mode 100644 index 80ff0cd80..000000000 --- a/src/libraries/java/nv-boot-parent/tools/bazel/java.bzl +++ /dev/null @@ -1,210 +0,0 @@ -load("@rules_java//java:defs.bzl", _java_binary = "java_binary", _java_library = "java_library") -load("@rules_java//java/common:java_info.bzl", "JavaInfo") -load("@rules_shell//shell:sh_test.bzl", _sh_test = "sh_test") - -NV_JAVA_JAVACOPTS = [ - "-Xlint:deprecation", -] - -NV_LOMBOK_COMPILE_DEPS = [ - "//tools/bazel:lombok_annotations", -] - -NV_LOMBOK_PLUGINS = [ - "//tools/bazel:lombok_plugin", -] - -NV_JUNIT5_ARGS = [ - "execute", - "--details=flat", - "--disable-ansi-colors", - "--details-theme=ascii", - "--include-classname=.*(Test|IntegrationTest)", - "--fail-if-no-tests", -] - -NV_JUNIT5_RUNTIME_DEPS = [ - "@nv_third_party_deps//:org_junit_platform_junit_platform_console_standalone", -] - -NV_JUNIT5_COMPILE_DEPS = [ - "@nv_third_party_deps//:org_assertj_assertj_core", - "@nv_third_party_deps//:org_junit_jupiter_junit_jupiter_api", - "@nv_third_party_deps//:org_junit_jupiter_junit_jupiter_params", - "@nv_third_party_deps//:org_mockito_mockito_core", - "@nv_third_party_deps//:org_mockito_mockito_junit_jupiter", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_test", - "@nv_third_party_deps//:org_springframework_boot_spring_boot_test_autoconfigure", - "@nv_third_party_deps//:org_springframework_spring_test", -] - -NV_MOCKITO_CORE = "@nv_third_party_deps//:org_mockito_mockito_core" - -NV_MOCKITO_AGENT_DATA = [ - NV_MOCKITO_CORE, -] - -NV_MOCKITO_AGENT_JVM_FLAGS = [ - "-javaagent:$(location %s)" % NV_MOCKITO_CORE, -] - -NV_JACOCO_AGENT = "@nv_third_party_deps//:org_jacoco_org_jacoco_agent_runtime" - -NV_JACOCO_AGENT_DATA = [ - NV_JACOCO_AGENT, -] - -NV_JACOCO_AGENT_JVM_FLAGS = [ - ( - "-javaagent:$(location %s)=destfile=jacoco.exec,append=false," - + "dumponexit=true,includes=com.nvidia.*" - ) % NV_JACOCO_AGENT, -] - -def _nv_boot_runtime_classpath_test_impl(ctx): - runtime_jars = ctx.attr.target[JavaInfo].transitive_runtime_jars.to_list() - leaked = [] - - for jar in runtime_jars: - for artifact in ctx.attr.forbidden_artifacts: - if artifact in jar.basename: - leaked.append(jar.short_path) - break - - if leaked: - fail( - "%s exports Maven-optional/provided runtime jars:\n%s" % ( - ctx.attr.target.label, - "\n".join(sorted(leaked)), - ), - ) - - executable = ctx.actions.declare_file(ctx.label.name + ".sh") - ctx.actions.write( - output = executable, - content = "#!/bin/sh\nexit 0\n", - is_executable = True, - ) - return [DefaultInfo(executable = executable)] - -nv_boot_runtime_classpath_test = rule( - implementation = _nv_boot_runtime_classpath_test_impl, - attrs = { - "forbidden_artifacts": attr.string_list(mandatory = True), - "target": attr.label(mandatory = True, providers = [JavaInfo]), - }, - test = True, -) - -def _nv_boot_workspace_runfiles_impl(ctx): - symlinks = {} - strip_prefix = ctx.attr.strip_prefix - - for src in ctx.files.srcs: - runfiles_path = src.short_path - if strip_prefix: - if not runfiles_path.startswith(strip_prefix): - fail("Expected %s to start with strip_prefix %s" % (runfiles_path, strip_prefix)) - runfiles_path = runfiles_path[len(strip_prefix):] - - if runfiles_path in symlinks: - fail("Duplicate runfiles path: %s" % runfiles_path) - symlinks[runfiles_path] = src - - return [DefaultInfo(runfiles = ctx.runfiles(symlinks = symlinks))] - -nv_boot_workspace_runfiles = rule( - implementation = _nv_boot_workspace_runfiles_impl, - attrs = { - "srcs": attr.label_list(allow_files = True), - "strip_prefix": attr.string(), - }, -) - -def nv_boot_library( - name, - srcs, - deps = [], - resources = [], - runtime_deps = [], - visibility = None, - resource_strip_prefix = ""): - _java_library( - name = name, - srcs = srcs, - deps = deps + NV_LOMBOK_COMPILE_DEPS, - javacopts = NV_JAVA_JAVACOPTS, - plugins = NV_LOMBOK_PLUGINS, - resources = resources, - resource_strip_prefix = resource_strip_prefix, - runtime_deps = runtime_deps, - visibility = visibility, - ) - -def nv_boot_library_test( - name, - srcs, - deps, - coverage_library, - data = [], - junit_classpath = [], - jvm_flags = [], - resources = [], - runtime_deps = [], - size = "small", - tags = [], - timeout = "short", - resource_strip_prefix = ""): - if type(coverage_library) != "string" or not coverage_library.startswith(":"): - fail( - "coverage_library must be the module library target as a local " - + "label starting with ':'", - ) - - coverage_sourcefiles = native.glob(["src/main/java/**/*.java"]) - coverage_source_root = native.package_name() + "/src/main/java" - junit_runner = name + "_junit_runner" - - _java_binary( - name = junit_runner, - srcs = srcs, - data = data + NV_MOCKITO_AGENT_DATA + NV_JACOCO_AGENT_DATA, - deps = deps + NV_LOMBOK_COMPILE_DEPS + NV_JUNIT5_COMPILE_DEPS, - javacopts = NV_JAVA_JAVACOPTS, - jvm_flags = NV_JACOCO_AGENT_JVM_FLAGS + NV_MOCKITO_AGENT_JVM_FLAGS + jvm_flags, - main_class = "org.junit.platform.console.ConsoleLauncher", - plugins = NV_LOMBOK_PLUGINS, - resources = resources, - resource_strip_prefix = resource_strip_prefix, - runtime_deps = runtime_deps + NV_JUNIT5_RUNTIME_DEPS, - tags = ["manual"], - testonly = True, - visibility = ["//visibility:private"], - ) - - _sh_test( - name = name, - srcs = ["//tools/bazel:jacoco_test_runner.sh"], - args = [ - "$(location :%s)" % junit_runner, - "$(location %s)" % coverage_library, - coverage_source_root if coverage_sourcefiles else "", - native.package_name(), - "$(location //tools/bazel:jacoco_cli)", - ] + NV_JUNIT5_ARGS + [ - "--class-path=$(location :%s.jar)" % junit_runner, - "--scan-classpath=$(location :%s.jar)" % junit_runner, - ] + [ - "--class-path=%s" % path - for path in junit_classpath - ], - data = [ - ":" + junit_runner, - ":%s.jar" % junit_runner, - coverage_library, - "//tools/bazel:jacoco_cli", - ] + coverage_sourcefiles, - size = size, - tags = tags, - timeout = timeout, - ) diff --git a/src/libraries/java/nv-boot-parent/tools/bazel/notice_check_test.sh b/src/libraries/java/nv-boot-parent/tools/bazel/notice_check_test.sh deleted file mode 100755 index 13033e0b0..000000000 --- a/src/libraries/java/nv-boot-parent/tools/bazel/notice_check_test.sh +++ /dev/null @@ -1,104 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -find_workspace_above() { - local candidate="$1" - while [[ "${candidate}" != "/" ]]; do - if [[ -f "${candidate}/MODULE.bazel" ]]; then - printf '%s\n' "${candidate}" - return - fi - candidate="$(dirname "${candidate}")" - done - return 1 -} - -find_workspace() { - if [[ -n "${BUILD_WORKSPACE_DIRECTORY:-}" && -f "${BUILD_WORKSPACE_DIRECTORY}/MODULE.bazel" ]]; then - printf '%s\n' "${BUILD_WORKSPACE_DIRECTORY}" - return - fi - - local candidate - for runfiles_root in "${TEST_SRCDIR:-}" "${RUNFILES_DIR:-}"; do - if [[ -z "${runfiles_root}" ]]; then - continue - fi - for candidate in "${runfiles_root}/_main" "${runfiles_root}/nv_boot_parent"; do - if [[ -f "${candidate}/MODULE.bazel" ]]; then - printf '%s\n' "${candidate}" - return - fi - done - done - - local script_dir - script_dir="$(cd "$(dirname "$0")" && pwd)" - - local workspace - if workspace="$(find_workspace_above "${script_dir}")"; then - printf '%s\n' "${workspace}" - return - fi - - printf 'Could not find MODULE.bazel in test runfiles\n' >&2 - exit 1 -} - -workspace="$(find_workspace)" - -PYTHONPATH="${workspace}/tools/bazel" python3 - <<'PY' -import pathlib -import tempfile -import zipfile - -from generate_notice import dependency_closure, parse_pom_xml, runtime_jar_coordinates - -parse_pom_xml("<project><name>safe</name></project>") -for unsafe_xml in ( - '<!DOCTYPE project SYSTEM "https://example.invalid/pom.dtd"><project/>', - '<!DOCTYPE project [<!ENTITY name "unsafe">]><project>&name;</project>', -): - try: - parse_pom_xml(unsafe_xml) - except ValueError: - continue - raise AssertionError("POM parser accepted a DTD or entity declaration") - -try: - dependency_closure( - ["example:missing:1.0"], - {"artifacts": {}, "dependencies": {}}, - (), - ) -except ValueError: - pass -else: - raise AssertionError("NOTICE closure silently accepted a missing dependency root") - -with tempfile.TemporaryDirectory() as directory: - app_jar = pathlib.Path(directory, "app.jar") - with zipfile.ZipFile(app_jar, "w") as archive: - archive.writestr( - "BOOT-INF/lib/external/rules_jvm_external++maven+nv_third_party_deps/" - "com/example/demo/1.0/demo-1.0.jar", - b"", - ) - try: - runtime_jar_coordinates( - [app_jar], - {"artifacts": {"com.example:demo": {"version": "2.0"}}}, - (), - ) - except ValueError: - pass - else: - raise AssertionError("Runtime NOTICE accepted a stale lockfile version") -PY - -exec python3 "${workspace}/tools/bazel/generate_notice.py" \ - --maven-install "${workspace}/maven_install.json" \ - --metadata "${workspace}/tools/bazel/notice_metadata.json" \ - --notice "${workspace}/NOTICE" \ - --root-manifest "${workspace}/tools/bazel/notice_roots.json" \ - --check diff --git a/src/control-plane-services/cloud-tasks/tools/bazel/BUILD.bazel b/tools/bazel/java/BUILD.bazel similarity index 61% rename from src/control-plane-services/cloud-tasks/tools/bazel/BUILD.bazel rename to tools/bazel/java/BUILD.bazel index 1f2e00f6f..ca8514eb4 100644 --- a/src/control-plane-services/cloud-tasks/tools/bazel/BUILD.bazel +++ b/tools/bazel/java/BUILD.bazel @@ -1,39 +1,19 @@ load("@rules_java//java:defs.bzl", "java_binary", "java_library", "java_plugin") load("@rules_proto_grpc//:defs.bzl", "proto_plugin") +load("@rules_python//python:defs.bzl", "py_binary") load("@rules_shell//shell:sh_test.bzl", "sh_test") +# Root-owned executable helpers and shared build targets for Java subtrees. +# Reusable Starlark macros live under //rules/java and reference these targets. package(default_visibility = ["//visibility:public"]) exports_files([ - "generate_notice.sh", + "generate_notice.py", "jacoco_test_runner.sh", - "notice_metadata.json", + "lcov_to_sonar_generic.py", ]) -proto_plugin( - name = "grpc_java_1_63_plugin", - out = "{name}_grpc.jar", - tool = select({ - "@rules_proto_grpc//platforms:darwin_arm64": "@grpc_java_plugin_osx_aarch_64//file:protoc-gen-grpc-java.exe", - "@rules_proto_grpc//platforms:darwin_x86_64": "@grpc_java_plugin_osx_x86_64//file:protoc-gen-grpc-java.exe", - "@rules_proto_grpc//platforms:linux_aarch64": "@grpc_java_plugin_linux_aarch_64//file:protoc-gen-grpc-java.exe", - "@rules_proto_grpc//platforms:linux_x86_64": "@grpc_java_plugin_linux_x86_64//file:protoc-gen-grpc-java.exe", - "@rules_proto_grpc//platforms:windows_x86_64": "@grpc_java_plugin_windows_x86_64//file:protoc-gen-grpc-java.exe", - }), -) - -sh_test( - name = "notice_check_test", - srcs = ["notice_check_test.sh"], - data = [ - ":notice_metadata.json", - "//:NOTICE", - "//:maven_install.json", - "//nvct-service:app", - "@nv_boot_parent//tools/bazel:generate_notice.py", - ], -) - +# Lombok annotation processing (shared by both Java compile profiles). java_plugin( name = "lombok_plugin", generates_api = True, @@ -41,14 +21,44 @@ java_plugin( deps = ["@nv_third_party_deps//:org_projectlombok_lombok"], ) +java_library( + name = "lombok_annotations", + exports = ["@nv_third_party_deps//:org_projectlombok_lombok"], + neverlink = True, +) + +# JaCoCo CLI used by the shared coverage test runner. java_binary( name = "jacoco_cli", main_class = "org.jacoco.cli.internal.Main", runtime_deps = ["@nv_third_party_deps//:org_jacoco_org_jacoco_cli"], ) -java_library( - name = "lombok_annotations", - exports = ["@nv_third_party_deps//:org_projectlombok_lombok"], - neverlink = True, +# NOTICE generator (root-owned). Service NOTICE metadata stays service-local; +# this tool only implements the generation/drift algorithm. +py_binary( + name = "generate_notice_tool", + srcs = ["generate_notice.py"], + main = "generate_notice.py", + python_version = "3.11", +) + +# gRPC-Java codegen plugin (pinned native binary, version tracks GRPC_VERSION +# in the root MODULE.bazel). Consumed by //rules/java:proto.bzl. +proto_plugin( + name = "grpc_java_1_63_plugin", + out = "{name}_grpc.jar", + tool = select({ + "@rules_proto_grpc//platforms:darwin_arm64": "@grpc_java_plugin_osx_aarch_64//file:protoc-gen-grpc-java.exe", + "@rules_proto_grpc//platforms:darwin_x86_64": "@grpc_java_plugin_osx_x86_64//file:protoc-gen-grpc-java.exe", + "@rules_proto_grpc//platforms:linux_aarch64": "@grpc_java_plugin_linux_aarch_64//file:protoc-gen-grpc-java.exe", + "@rules_proto_grpc//platforms:linux_x86_64": "@grpc_java_plugin_linux_x86_64//file:protoc-gen-grpc-java.exe", + "@rules_proto_grpc//platforms:windows_x86_64": "@grpc_java_plugin_windows_x86_64//file:protoc-gen-grpc-java.exe", + }), +) + +sh_test( + name = "lcov_to_sonar_generic_test", + srcs = ["lcov_to_sonar_generic_test.sh"], + data = [":lcov_to_sonar_generic.py"], ) diff --git a/src/libraries/java/nv-boot-parent/tools/bazel/generate_notice.py b/tools/bazel/java/generate_notice.py similarity index 100% rename from src/libraries/java/nv-boot-parent/tools/bazel/generate_notice.py rename to tools/bazel/java/generate_notice.py diff --git a/src/control-plane-services/cloud-tasks/tools/bazel/jacoco_test_runner.sh b/tools/bazel/java/jacoco_test_runner.sh similarity index 100% rename from src/control-plane-services/cloud-tasks/tools/bazel/jacoco_test_runner.sh rename to tools/bazel/java/jacoco_test_runner.sh diff --git a/src/libraries/java/nv-boot-parent/tools/bazel/lcov_to_sonar_generic.py b/tools/bazel/java/lcov_to_sonar_generic.py similarity index 100% rename from src/libraries/java/nv-boot-parent/tools/bazel/lcov_to_sonar_generic.py rename to tools/bazel/java/lcov_to_sonar_generic.py diff --git a/src/libraries/java/nv-boot-parent/tools/bazel/lcov_to_sonar_generic_test.sh b/tools/bazel/java/lcov_to_sonar_generic_test.sh similarity index 100% rename from src/libraries/java/nv-boot-parent/tools/bazel/lcov_to_sonar_generic_test.sh rename to tools/bazel/java/lcov_to_sonar_generic_test.sh diff --git a/tools/workspace_status.sh b/tools/workspace_status.sh index 1393379f0..562aecdd8 100755 --- a/tools/workspace_status.sh +++ b/tools/workspace_status.sh @@ -44,6 +44,18 @@ echo "STABLE_BUILD_USER ${BUILD_USER}" echo "STABLE_GO_VERSION ${GO_VERSION}" echo "STABLE_OCI_TAG ${VERSION}-${COMMIT}${DIRTY}" +# Java build metadata. The Spring Boot packaging macro (//rules/java:spring.bzl) +# stamps git.properties / maven.properties from these keys. Empty values are +# handled gracefully by the packaging rule. +FULL_COMMIT=$(git rev-parse HEAD 2>/dev/null || echo "unknown") +GIT_TAGS=$(git tag --points-at HEAD 2>/dev/null | paste -sd, - || true) +CLOSEST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || true) +echo "STABLE_GIT_COMMIT_ID_FULL ${FULL_COMMIT}" +echo "STABLE_GIT_COMMIT_ID_ABBREV ${COMMIT}" +echo "STABLE_GIT_TAGS ${GIT_TAGS}" +echo "STABLE_GIT_CLOSEST_TAG_NAME ${CLOSEST_TAG}" +echo "STABLE_BUILD_VERSION ${NEXT_VERSION:-${VERSION}}" + # Stack OCI refs for the nvcf-cli ldflag stamping. Set by CI at release # build time; empty string is the correct default for dev builds (users # must pass --control-plane-stack / --compute-plane-stack explicitly). From 60b5516c65fbaf5c193d28a37ae9a698094ab2c2 Mon Sep 17 00:00:00 2001 From: Balaji Ganesan <bganesan@nvidia.com> Date: Thu, 23 Jul 2026 12:09:38 -0700 Subject: [PATCH 16/29] ci(bazel): add root-scoped lane mode; give Java its own matrix rows After the Java fold into the single root module, the nv-boot-parent and cloud-tasks rows can't cd into a nested module. Add a root-scoped lane mode (optional 4th ROWS field `root`): such a row runs bazel from the repo root and builds/tests only //<path>/... , keeping a dedicated check per Java service without a nested MODULE.bazel. Existing per-module rows are unchanged (workdir=path, scope=//...). New Java services are a one-line row with `root`. Co-authored-by: Balaji Ganesan <bganesan@nvidia.com> --- .github/workflows/bazel.yml | 45 ++++++++++++++++++++++--------------- 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/.github/workflows/bazel.yml b/.github/workflows/bazel.yml index b64314627..2497c274b 100644 --- a/.github/workflows/bazel.yml +++ b/.github/workflows/bazel.yml @@ -115,15 +115,14 @@ jobs: function-autoscaler|src/control-plane-services/function-autoscaler|false helm-reval|src/control-plane-services/helm-reval|false stargate|src/libraries/rust/stargate|false - nv-boot-parent|src/libraries/java/nv-boot-parent|false - cloud-tasks|src/control-plane-services/cloud-tasks|false' - # Standalone Java modules. Each has its own MODULE.bazel and its own - # nv_third_party_deps hub, so it builds+tests in its own module dir. - # Like every non-root row they do NOT set --config=remote; the - # build/test steps below inject --remote_cache/--tls_certificate/ - # --remote_header from the EC2 Buildbarn secrets, so these rows warm - # from and hit that shared cache rather than cold-building (see - # NVIDIA/nvcf#372). + nv-boot-parent|src/libraries/java/nv-boot-parent|false|root + cloud-tasks|src/control-plane-services/cloud-tasks|false|root' + # Root-scoped Java lanes (optional 4th field `root`). The Java tree is + # folded into the single root `nvcf` module -- no nested MODULE.bazel -- + # so these rows do NOT cd into a module dir. They run bazel from the + # repo root and build/test only their own targets (//<path>/...), which + # gives each Java service its own check lane without a nested module. + # Add a new Java service as one line here with the `root` marker. # Paths that affect the root-module workspace build (native root # subtrees plus the shared Bazel scaffold). Java and stargate no longer # ride the root row: nv-boot-parent, cloud-tasks, and stargate are @@ -156,8 +155,14 @@ jobs: fi include="[]" - while IFS='|' read -r id path tests_skip; do + while IFS='|' read -r id path tests_skip scoped; do id="$(echo "$id" | xargs)"; [ -z "$id" ] && continue + scoped="$(echo "$scoped" | xargs)" + # Root-scoped lane (scoped=root): the subtree lives inside the single + # root module, so it runs bazel from the repo root and builds only + # //<path>/... . Every other row keeps per-module behavior + # (workdir=path, scope=//...). + if [ "$scoped" = "root" ]; then workdir="."; scope="//${path}/..."; else workdir="$path"; scope="//..."; fi hit=false if [ "$run_all" = "true" ]; then hit=true @@ -183,7 +188,7 @@ jobs: if printf '%s\n' "$changed" | grep -q "^${path}/"; then hit=true; fi fi if [ "$hit" = "true" ]; then - include=$(printf '%s' "$include" | jq -c --arg id "$id" --arg path "$path" --argjson ts "$tests_skip" '. + [{id:$id, path:$path, tests_skip:$ts}]') + include=$(printf '%s' "$include" | jq -c --arg id "$id" --arg path "$path" --argjson ts "$tests_skip" --arg wd "$workdir" --arg sc "$scope" --arg sm "$scoped" '. + [{id:$id, path:$path, tests_skip:$ts, workdir:$wd, scope:$sc, scoped:$sm}]') fi done <<< "$ROWS" @@ -231,7 +236,7 @@ jobs: - name: Skip if subtree has no MODULE.bazel yet id: precheck run: | - if [ ! -f "${{ matrix.subtree.path }}/MODULE.bazel" ]; then + if [ "${{ matrix.subtree.scoped }}" != "root" ] && [ ! -f "${{ matrix.subtree.path }}/MODULE.bazel" ]; then echo "no MODULE.bazel at ${{ matrix.subtree.path }} -- skipping" echo "skip=true" >> "$GITHUB_OUTPUT" else @@ -241,7 +246,7 @@ jobs: # bazelisk is preinstalled in the bazel-ci image as `bazel`. - name: bazel version if: steps.precheck.outputs.skip == 'false' - working-directory: ${{ matrix.subtree.path }} + working-directory: ${{ matrix.subtree.workdir }} run: bazel version - name: Cache Bazel repository + disk caches @@ -251,7 +256,7 @@ jobs: path: | ~/.cache/bazel/_bazel_${{ env.USER || 'root' }}/install ~/.cache/bazel/_bazel_${{ env.USER || 'root' }}/cache - key: bazel-${{ matrix.subtree.id }}-${{ hashFiles(format('{0}/MODULE.bazel.lock', matrix.subtree.path), format('{0}/.bazelversion', matrix.subtree.path)) }} + key: bazel-${{ matrix.subtree.id }}-${{ hashFiles(format('{0}/MODULE.bazel.lock', matrix.subtree.workdir), format('{0}/.bazelversion', matrix.subtree.workdir)) }} restore-keys: | bazel-${{ matrix.subtree.id }}- @@ -313,15 +318,19 @@ jobs: - name: Determine build targets id: targets if: steps.precheck.outputs.skip == 'false' - working-directory: ${{ matrix.subtree.path }} + working-directory: ${{ matrix.subtree.workdir }} env: EVENT: ${{ github.event_name }} BASE_SHA: ${{ github.event.pull_request.base.sha }} SUBTREE_PATH: ${{ matrix.subtree.path }} + SCOPE: ${{ matrix.subtree.scope }} run: | set -uo pipefail tfile="$RUNNER_TEMP/targets.txt" - full() { printf '//...\n' > "$tfile"; echo "targets: //... (full build)"; } + # SCOPE is //... for the root row and per-module rows, and //<path>/... + # for a root-scoped lane so it builds only its own targets out of the + # shared root module. + full() { printf '%s\n' "$SCOPE" > "$tfile"; echo "targets: $SCOPE (full build)"; } # Only the root row on a pull_request is a narrowing candidate. Every # other trigger (main push warms + uploads the whole closure; dispatch @@ -383,7 +392,7 @@ jobs: - name: bazel build if: steps.precheck.outputs.skip == 'false' - working-directory: ${{ matrix.subtree.path }} + working-directory: ${{ matrix.subtree.workdir }} run: | if [ ! -s "$RUNNER_TEMP/targets.txt" ]; then echo "no targets to build; skipping"; exit 0 @@ -431,7 +440,7 @@ jobs: # but tests fail with an environment delta from GitLab CI (per the # documented build-only policy). Default is to run tests. if: steps.precheck.outputs.skip == 'false' && !matrix.subtree.tests_skip - working-directory: ${{ matrix.subtree.path }} + working-directory: ${{ matrix.subtree.workdir }} run: | if [ ! -s "$RUNNER_TEMP/targets.txt" ]; then echo "no targets to test; skipping"; exit 0 From 5ceb1e458aee59f8c9f209dfc771bae0b3e5937a Mon Sep 17 00:00:00 2001 From: Balaji Ganesan <bganesan@nvidia.com> Date: Thu, 23 Jul 2026 12:35:37 -0700 Subject: [PATCH 17/29] ci(bazel): give the integration lane a JDK 25 for local_jdk After folding Java into the root module, `bazel integration (docker)` (which runs root //... requires-docker) now picks up the Java Testcontainers suites (nv-boot-starter-cassandra, cloud-tasks). That lane runs on a bare runner without the bazel-ci image's Temurin 25, so local_jdk had no JDK to resolve and the Java targets failed to build. Add actions/setup-java (Temurin 25) so JAVA_HOME points at a JDK 25 there. Co-authored-by: Balaji Ganesan <bganesan@nvidia.com> --- .github/workflows/bazel.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/workflows/bazel.yml b/.github/workflows/bazel.yml index 2497c274b..0f90f077b 100644 --- a/.github/workflows/bazel.yml +++ b/.github/workflows/bazel.yml @@ -530,6 +530,15 @@ jobs: - uses: actions/checkout@v4 with: fetch-depth: 0 + # The Java tree builds with local_jdk (root .bazelrc). This lane runs on a + # bare runner (not the bazel-ci image, which ships Temurin 25), so provide + # a JDK 25 at JAVA_HOME for local_jdk to resolve; otherwise the Java + # requires-docker tests (nv-boot / cloud-tasks Testcontainers suites) that + # now live in the root module fail to build here. + - uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: '25' - name: Install bazelisk run: | sudo curl -fsSLo /usr/local/bin/bazel \ From 5ec0a38c8587edd0bb21b167235c10dcffedb35a Mon Sep 17 00:00:00 2001 From: Balaji Ganesan <bganesan@nvidia.com> Date: Thu, 23 Jul 2026 13:29:04 -0700 Subject: [PATCH 18/29] fix(ci): resolve cloud-tasks test failures in the GHA bazel lanes Two monorepo-fold bugs surfaced once cloud-tasks tests started running in the public GHA bazel matrix: - Integration lane: the tests read local_env paths (local_env/vault/secrets.json) relative to the runfiles workspace root, but integration_local_env had no strip_prefix, so the files landed at their nested package path and the JVM saw FileNotFoundException. In the standalone repo this package was the repo root so no strip was needed; add strip_prefix for the nested monorepo path. - Unit lane: when a narrowed scope's only tests are requires-docker (cloud-tasks), naming them explicitly and running `bazel test --test_tag_filters=-requires-docker` fails with "No test targets were found, yet testing was requested" (exit 4). Exclude requires-docker tests in the resolving query so the scope resolves to empty and skips cleanly, matching the tag filter applied to the run. Co-authored-by: Balaji Ganesan <bganesan@nvidia.com> --- .github/workflows/bazel.yml | 10 +++++++++- src/control-plane-services/cloud-tasks/BUILD.bazel | 5 +++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/.github/workflows/bazel.yml b/.github/workflows/bazel.yml index 0f90f077b..09bf08b3b 100644 --- a/.github/workflows/bazel.yml +++ b/.github/workflows/bazel.yml @@ -455,7 +455,15 @@ jobs: cp "$RUNNER_TEMP/targets.txt" "$ttfile" else patterns=$(tr '\n' ' ' < "$RUNNER_TEMP/targets.txt") - tests=$(bazel query --noshow_progress --output=label "tests(set($patterns))" 2>/dev/null) || tests="__QFAIL__" + # Exclude requires-docker tests from the resolved set: they run in the + # bazel-integration lane, not here. Naming them explicitly and then + # running `bazel test --test_tag_filters=-requires-docker` fails with + # "No test targets were found, yet testing was requested" (exit 4) when + # a scope's only tests are requires-docker (e.g. cloud-tasks). Filtering + # them in the query lets such a scope resolve to empty and skip cleanly, + # matching the tag filter applied to the run below. + tests=$(bazel query --noshow_progress --output=label \ + "tests(set($patterns)) except attr(tags, 'requires-docker', set($patterns))" 2>/dev/null) || tests="__QFAIL__" if [ "$tests" = "__QFAIL__" ]; then echo "tests() query failed; falling back to full test set" printf '//...\n' > "$ttfile" diff --git a/src/control-plane-services/cloud-tasks/BUILD.bazel b/src/control-plane-services/cloud-tasks/BUILD.bazel index d9ade0221..c3e04bac2 100644 --- a/src/control-plane-services/cloud-tasks/BUILD.bazel +++ b/src/control-plane-services/cloud-tasks/BUILD.bazel @@ -22,9 +22,14 @@ filegroup( ]), ) +# The tests read local_env paths (e.g. local_env/vault/secrets.json) relative +# to the runfiles workspace root, the JVM working directory under `bazel test`. +# Strip the package prefix so these files land root-relative in runfiles; in the +# standalone repo this package was the repo root, so no strip was needed. nvct_workspace_runfiles( name = "integration_local_env", srcs = [":integration_local_env_files"], + strip_prefix = "src/control-plane-services/cloud-tasks/", ) genrule( From b449d03d69cdbcdb4ce4fdf292edbb8ae823e63b Mon Sep 17 00:00:00 2001 From: Balaji Ganesan <bganesan@nvidia.com> Date: Thu, 23 Jul 2026 13:44:34 -0700 Subject: [PATCH 19/29] ci(bazel): validate nv-boot-parent consumers on framework changes The change detector selected a subtree row only when a file under that row's own path changed, so a nv-boot-parent-only change scheduled just the nv-boot-parent row. Because cloud-tasks consumes nv-boot-parent, an incompatible framework change could merge without building its consumer's targets or running its Docker-backed tests through the fast matrix. Add an explicit reverse-dependency edge: when nv-boot-parent changes, also schedule its consumers (currently cloud-tasks) so their build lane runs and the integration lane exercises their requires-docker tests. Listed explicitly for now; a root-level nv-boot consumer suite can replace it as more Java services land. Addresses review feedback from Sanjay Saxena on PR #343. Co-authored-by: Balaji Ganesan <bganesan@nvidia.com> --- .github/workflows/bazel.yml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/.github/workflows/bazel.yml b/.github/workflows/bazel.yml index 09bf08b3b..eb7244edb 100644 --- a/.github/workflows/bazel.yml +++ b/.github/workflows/bazel.yml @@ -154,6 +154,21 @@ jobs: run_all=true fi + # Reverse-dependency edges. A change to a framework subtree must also + # validate its consumers: the consumer's build and tests are what prove + # the framework change is compatible, so an incompatible nv-boot-parent + # change cannot merge without building its consumers and running their + # (requires-docker) tests. nv-boot-parent is consumed by the Java + # services; list each consumer id here as it enters the monorepo. When + # more Java services land, a root-level nv-boot consumer suite can + # replace this explicit list. + NV_BOOT_PATH="src/libraries/java/nv-boot-parent" + NV_BOOT_CONSUMERS=" cloud-tasks " + nv_boot_changed=false + if [ "$run_all" != "true" ] && printf '%s\n' "$changed" | grep -q "^${NV_BOOT_PATH}/"; then + nv_boot_changed=true + fi + include="[]" while IFS='|' read -r id path tests_skip scoped; do id="$(echo "$id" | xargs)"; [ -z "$id" ] && continue @@ -187,6 +202,12 @@ jobs: else if printf '%s\n' "$changed" | grep -q "^${path}/"; then hit=true; fi fi + # Framework consumer edge: when nv-boot-parent changed, also schedule + # its consumers (see NV_BOOT_CONSUMERS above) so a framework change is + # validated against them, not just built in isolation. + if [ "$hit" != "true" ] && [ "$nv_boot_changed" = "true" ]; then + case "$NV_BOOT_CONSUMERS" in *" $id "*) hit=true ;; esac + fi if [ "$hit" = "true" ]; then include=$(printf '%s' "$include" | jq -c --arg id "$id" --arg path "$path" --argjson ts "$tests_skip" --arg wd "$workdir" --arg sc "$scope" --arg sm "$scoped" '. + [{id:$id, path:$path, tests_skip:$ts, workdir:$wd, scope:$sc, scoped:$sm}]') fi From 32b34c6664dec1ff07cb25b7f39bc934b65f586f Mon Sep 17 00:00:00 2001 From: Balaji Ganesan <bganesan@nvidia.com> Date: Thu, 23 Jul 2026 14:26:55 -0700 Subject: [PATCH 20/29] ci(bazel): run the full test matrix on every PR (no change-aware skipping) Force the change detector to select the full matrix on every PR and push, so no subtree's tests are skipped because an unrelated path changed. Regression safety over queue latency; the remote cache keeps unaffected targets to cache hits, and the requires-docker (Testcontainers) tests already ran every PR via the integration lane. The change-aware detection and the nv-boot-parent consumer edges are retained but inert behind a single override line, so change-aware scheduling can be restored by deleting that line. Also clarify the unit-lane "no tests" log: a scope whose only tests are requires-docker (e.g. cloud-tasks) is covered by the integration lane, not skipped. Co-authored-by: Balaji Ganesan <bganesan@nvidia.com> --- .github/workflows/bazel.yml | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/.github/workflows/bazel.yml b/.github/workflows/bazel.yml index eb7244edb..ece10098a 100644 --- a/.github/workflows/bazel.yml +++ b/.github/workflows/bazel.yml @@ -149,6 +149,13 @@ jobs: fi ;; esac + # Policy: run the full test matrix on every PR and push so no subtree's + # tests are skipped because an unrelated path changed (regression safety + # over queue latency; the remote cache keeps unaffected targets to cache + # hits). The change-aware detection above and the reverse-dependency + # edges below are retained but inert while this is set; delete the next + # line to restore change-aware scheduling. + run_all=true # A change to this workflow itself revalidates everything. if printf '%s\n' "$changed" | grep -q '^\.github/workflows/bazel\.yml$'; then run_all=true @@ -489,7 +496,11 @@ jobs: echo "tests() query failed; falling back to full test set" printf '//...\n' > "$ttfile" elif [ -z "$tests" ]; then - echo "no affected test targets; skipping tests"; exit 0 + # Not a coverage gap: requires-docker tests are excluded here (the + # container has no Docker daemon) and run in the bazel-integration + # lane instead. A scope whose only tests are requires-docker (e.g. + # cloud-tasks) resolves empty here and is covered there. + echo "no non-docker test targets in scope; requires-docker tests run in the integration lane"; exit 0 else printf '%s\n' "$tests" > "$ttfile" echo "tests: $(grep -c . "$ttfile") affected test target(s)" From 934158afafe23e9dcbc8eaa5a055520d182818cb Mon Sep 17 00:00:00 2001 From: Balaji Ganesan <bganesan@nvidia.com> Date: Thu, 23 Jul 2026 14:55:28 -0700 Subject: [PATCH 21/29] ci(bazel): per-service Docker lanes so no subtree lane runs zero tests The cloud-tasks fast lane produced no `bazel test` output: all its tests are requires-docker, the containerized fast matrix filters those out (no Docker daemon), and they ran only in a pooled `//...` integration lane. A service lane that runs none of its own tests undermines confidence that a green PR caught bugs. Restructure so every subtree that owns requires-docker tests runs its FULL suite (unit + Testcontainers) in its own visibly-named `bazel docker (<id>)` lane, on a bare ubuntu-latest runner with host Docker, with no tag filter: - detect emits a second matrix (matrix_docker) for docker-owning subtrees (cloud-tasks, nv-boot-parent); they are excluded from the container matrix, so they never produce a zero-test lane. - New bazel-docker matrix job builds + tests each such subtree's scope with no `-requires-docker` filter, so all its tests run and are attributed to it. - Retire the pooled integration lane (it only ever ran these Java tests). - bazel-verification gates on bazel-docker. grpc-proxy also owns a requires-docker test but is a nested Rust module whose test has never run in CI; wiring+validating it is tracked in NVIDIA/nvcf#396 to keep this change scoped to the Java subtrees. Co-authored-by: Balaji Ganesan <bganesan@nvidia.com> --- .github/workflows/bazel.yml | 92 ++++++++++++++++++++++++------------- 1 file changed, 59 insertions(+), 33 deletions(-) diff --git a/.github/workflows/bazel.yml b/.github/workflows/bazel.yml index ece10098a..241a2282d 100644 --- a/.github/workflows/bazel.yml +++ b/.github/workflows/bazel.yml @@ -64,6 +64,7 @@ jobs: runs-on: ubuntu-latest outputs: matrix: ${{ steps.detect.outputs.matrix }} + matrix_docker: ${{ steps.detect.outputs.matrix_docker }} any: ${{ steps.detect.outputs.any }} steps: - uses: actions/checkout@v4 @@ -176,7 +177,20 @@ jobs: nv_boot_changed=true fi + # Subtrees that own requires-docker (Testcontainers) tests. They run in + # the bazel-docker matrix on a Docker-capable runner, executing their + # FULL suite (unit + Testcontainers) with no tag filter, so every test a + # subtree owns runs in its own visible lane -- nothing is filtered out or + # deferred. A subtree here is NOT also placed in the container matrix, so + # it never produces a lane that runs no tests. + # NOTE: grpc-proxy also owns a requires-docker test but is a nested Rust + # module whose test has never run in CI; wiring+validating it is tracked + # separately (NVIDIA/nvcf#396) to keep this change scoped to the Java + # subtrees. It stays in the container matrix for now (build coverage). + DOCKER_SUBTREES=" cloud-tasks nv-boot-parent " + include="[]" + include_docker="[]" while IFS='|' read -r id path tests_skip scoped; do id="$(echo "$id" | xargs)"; [ -z "$id" ] && continue scoped="$(echo "$scoped" | xargs)" @@ -216,14 +230,21 @@ jobs: case "$NV_BOOT_CONSUMERS" in *" $id "*) hit=true ;; esac fi if [ "$hit" = "true" ]; then - include=$(printf '%s' "$include" | jq -c --arg id "$id" --arg path "$path" --argjson ts "$tests_skip" --arg wd "$workdir" --arg sc "$scope" --arg sm "$scoped" '. + [{id:$id, path:$path, tests_skip:$ts, workdir:$wd, scope:$sc, scoped:$sm}]') + entry=$(jq -cn --arg id "$id" --arg path "$path" --argjson ts "$tests_skip" --arg wd "$workdir" --arg sc "$scope" --arg sm "$scoped" '{id:$id, path:$path, tests_skip:$ts, workdir:$wd, scope:$sc, scoped:$sm}') + case "$DOCKER_SUBTREES" in + *" $id "*) include_docker=$(printf '%s' "$include_docker" | jq -c --argjson e "$entry" '. + [$e]') ;; + *) include=$(printf '%s' "$include" | jq -c --argjson e "$entry" '. + [$e]') ;; + esac fi done <<< "$ROWS" count=$(printf '%s' "$include" | jq 'length') - echo "selected ${count} subtree(s): $(printf '%s' "$include" | jq -r '[.[].id] | join(", ")')" + count_docker=$(printf '%s' "$include_docker" | jq 'length') + total=$((count + count_docker)) + echo "selected ${total} subtree(s): container=[$(printf '%s' "$include" | jq -r '[.[].id] | join(", ")')] docker=[$(printf '%s' "$include_docker" | jq -r '[.[].id] | join(", ")')]" echo "matrix=${include}" >> "$GITHUB_OUTPUT" - if [ "$count" -gt 0 ]; then echo "any=true" >> "$GITHUB_OUTPUT"; else echo "any=false" >> "$GITHUB_OUTPUT"; fi + echo "matrix_docker=${include_docker}" >> "$GITHUB_OUTPUT" + if [ "$total" -gt 0 ]; then echo "any=true" >> "$GITHUB_OUTPUT"; else echo "any=false" >> "$GITHUB_OUTPUT"; fi bazel: name: bazel (${{ matrix.subtree.id }}) @@ -553,28 +574,31 @@ jobs: bazel test "${COMMON[@]}" --remote_cache= "${TARGETS[@]}" fi - # Docker integration lane. Runs only the "requires-docker"-tagged tests - # (Testcontainers suites) that the containerized fast matrix cannot run - # because it has no Docker daemon. This is how integration tests stay ENABLED - # instead of being skipped. Runs on the bare runner (not the bazel-ci - # container) because ubuntu-latest ships Docker running, so Testcontainers - # uses the host daemon directly -- no DinD, no host-override networking, and it - # avoids the container+service checkout fragility. bazelisk reads - # .bazelversion for the pinned Bazel. - bazel-integration: - name: bazel integration (docker) + # Per-service Docker lane. Each subtree that owns requires-docker + # (Testcontainers) tests runs its FULL suite (unit + Testcontainers) here, in + # its own visibly-named lane, with no tag filter -- so no test a subtree owns + # is filtered out or deferred, and a green lane means that service's tests ran. + # Runs on the bare ubuntu-latest runner (not the bazel-ci container) because + # that runner ships a running Docker daemon, so Testcontainers uses the host + # daemon directly -- no DinD, no host-override networking. These subtrees are + # excluded from the container matrix, so they never produce a zero-test lane. + # bazelisk reads .bazelversion for the pinned Bazel. + bazel-docker: + name: bazel docker (${{ matrix.subtree.id }}) needs: detect - if: needs.detect.outputs.any == 'true' + if: needs.detect.outputs.matrix_docker != '[]' runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + subtree: ${{ fromJson(needs.detect.outputs.matrix_docker) }} steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - # The Java tree builds with local_jdk (root .bazelrc). This lane runs on a - # bare runner (not the bazel-ci image, which ships Temurin 25), so provide - # a JDK 25 at JAVA_HOME for local_jdk to resolve; otherwise the Java - # requires-docker tests (nv-boot / cloud-tasks Testcontainers suites) that - # now live in the root module fail to build here. + # The Java tree builds with local_jdk (root .bazelrc). This bare runner is + # not the bazel-ci image (which ships Temurin 25), so provide JDK 25 at + # JAVA_HOME for local_jdk to resolve. - uses: actions/setup-java@v4 with: distribution: temurin @@ -585,29 +609,31 @@ jobs: https://github.com/bazelbuild/bazelisk/releases/download/v1.20.0/bazelisk-linux-amd64 sudo chmod +x /usr/local/bin/bazel bazel version - - name: bazel integration tests (requires-docker) + - name: bazel build (${{ matrix.subtree.id }}) + working-directory: ${{ matrix.subtree.workdir }} + run: bazel build ${{ matrix.subtree.scope }} + - name: bazel test (${{ matrix.subtree.id }}) + working-directory: ${{ matrix.subtree.workdir }} + # Full suite, NO tag filter: runs the subtree's unit AND requires-docker + # (Testcontainers) tests against the host Docker daemon. A subtree whose + # only tests are requires-docker (cloud-tasks) still runs them all here. + # bazel exit 4 (no test targets in scope) is treated as success. run: | - # Run only the Testcontainers suites across the root workspace against - # the host Docker. If a change touches none, bazel exits 4 (no tests - # matched) which we treat as success. Nested-module subtrees are - # handled in a later fan-out. set +e - bazel test //... \ - --build_tests_only \ - --test_tag_filters=requires-docker \ + bazel test ${{ matrix.subtree.scope }} \ --test_output=errors \ --flaky_test_attempts=2 rc=$? set -e if [ "$rc" -eq 4 ]; then - echo "no requires-docker tests matched; nothing to run" + echo "::warning::${{ matrix.subtree.id }}: no test targets in scope" exit 0 fi exit "$rc" bazel-verification: name: bazel verification - needs: [detect, bazel, bazel-integration] + needs: [detect, bazel, bazel-docker] if: ${{ always() }} runs-on: ubuntu-latest steps: @@ -615,7 +641,7 @@ jobs: env: DETECT_RESULT: ${{ needs.detect.result }} BAZEL_RESULT: ${{ needs.bazel.result }} - INTEGRATION_RESULT: ${{ needs.bazel-integration.result }} + DOCKER_RESULT: ${{ needs.bazel-docker.result }} BAZEL_ANY: ${{ needs.detect.outputs.any }} run: | set -euo pipefail @@ -639,8 +665,8 @@ jobs: exit 1 fi - echo "integration result: ${INTEGRATION_RESULT}" - if [ "${INTEGRATION_RESULT}" != "success" ] && [ "${INTEGRATION_RESULT}" != "skipped" ]; then - echo "the bazel integration (docker) lane failed or was cancelled" + echo "bazel-docker result: ${DOCKER_RESULT}" + if [ "${DOCKER_RESULT}" != "success" ] && [ "${DOCKER_RESULT}" != "skipped" ]; then + echo "one or more bazel docker (per-service Testcontainers) lanes failed or were cancelled" exit 1 fi From dacf0154791f4dc87558a4ea8a81297a8d62538a Mon Sep 17 00:00:00 2001 From: Balaji Ganesan <bganesan@nvidia.com> Date: Thu, 23 Jul 2026 15:19:17 -0700 Subject: [PATCH 22/29] ci(bazel): rename per-service Docker lanes to bazel (<id>) Each service now has exactly one lane (docker-owning subtrees were removed from the container matrix), so the "docker" qualifier was redundant and read like "docker" was the unit under test. Name them bazel (<id>) for parity with every other service lane. Also correct the container.image comment: java/javac come from the GitLab-built bazel-ci image (Temurin JDK 25 + Maven), skopeo-mirrored to ghcr -- not from this repo's stale ci/Dockerfile.bazel (being removed separately). Co-authored-by: Balaji Ganesan <bganesan@nvidia.com> --- .github/workflows/bazel.yml | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/.github/workflows/bazel.yml b/.github/workflows/bazel.yml index 241a2282d..595b737a2 100644 --- a/.github/workflows/bazel.yml +++ b/.github/workflows/bazel.yml @@ -258,12 +258,13 @@ jobs: CACHE_TOKEN: ${{ secrets.BAZEL_REMOTE_CACHE_TOKEN }} CACHE_ENDPOINT: ${{ vars.BAZEL_REMOTE_CACHE_ENDPOINT }} container: - # Staged bump: ci/Dockerfile.bazel + bazel-ci-image.yml move to 0.13.0 - # (adds the remotejdk_25 / Bazel 9.1.1 pre-warm the Java module rows use). - # 0.13.0 publishes only on merge to main, so this consumer ref stays at - # 0.12.0 until then to keep the matrix from pinning an unpublished image; - # a fast-follow bumps it to 0.13.0. The Java rows still work on 0.12.0 (they - # cold-fetch the JDK once, then reuse it via actions/cache). See #372. + # Built in GitLab nvcf/bazel-ci-templates (bazel-ci/Dockerfile: Temurin + # JDK 25 + Maven + prewarmed Bazel and Go SDKs -- that is where java/javac + # come from) and skopeo-mirrored to the public ghcr tag below. This repo + # does NOT build the image (the old ci/Dockerfile.bazel + bazel-ci-image.yml + # were a stale, Java-less copy and have been removed). Bump this ref in + # lockstep after a new tag is mirrored. Kept a string literal on purpose + # (see the container.image evaluation note above). image: ghcr.io/nvidia/nvcf/bazel-ci:0.12.0 credentials: username: ${{ github.actor }} @@ -584,7 +585,7 @@ jobs: # excluded from the container matrix, so they never produce a zero-test lane. # bazelisk reads .bazelversion for the pinned Bazel. bazel-docker: - name: bazel docker (${{ matrix.subtree.id }}) + name: bazel (${{ matrix.subtree.id }}) needs: detect if: needs.detect.outputs.matrix_docker != '[]' runs-on: ubuntu-latest From 833220bae17c3ce1f8a4d38186c10a6c4f471a09 Mon Sep 17 00:00:00 2001 From: Sanjay Saxena <sasaxena@nvidia.com> Date: Thu, 23 Jul 2026 15:50:21 -0700 Subject: [PATCH 23/29] build(bazel): enforce root Java module ownership --- .bazelrc | 7 +- .github/workflows/bazel.yml | 32 ++++---- BAZEL.md | 75 ++++++++++++++---- BUILD.bazel | 14 ++-- MODULE.bazel | 4 +- .../cloud-tasks/AGENTS.md | 70 +++++++++-------- src/libraries/java/nv-boot-parent/AGENTS.md | 77 +++++++++---------- tools/ci/check-java-import-boundaries | 56 ++++++++++++++ 8 files changed, 223 insertions(+), 112 deletions(-) create mode 100755 tools/ci/check-java-import-boundaries diff --git a/.bazelrc b/.bazelrc index d5842697c..9a11339d3 100644 --- a/.bazelrc +++ b/.bazelrc @@ -69,9 +69,10 @@ build --workspace_status_command=./tools/workspace_status.sh build --nostamp # Java baseline: Java 25 for the whole monorepo (nv-boot-parent and the Java -# control-plane services). local_jdk is the approved runtime here: the folded -# Java subtrees were validated against a locally provisioned JDK 25, so both the -# build and tool runtimes resolve to local_jdk rather than a hermetic remotejdk. +# control-plane services). local_jdk is the approved runtime. The pinned +# bazel-ci image supplies Temurin 25 through JAVA_HOME; the bare +# Docker-integration lane supplies it through actions/setup-java. The Java +# build and test jobs prove that both environments satisfy this contract. # Full javac (header compilation off) is required because Lombok-generated APIs # in the imported projects are not compatible with Bazel's Turbine header # compiler. diff --git a/.github/workflows/bazel.yml b/.github/workflows/bazel.yml index 595b737a2..ba18cc2e0 100644 --- a/.github/workflows/bazel.yml +++ b/.github/workflows/bazel.yml @@ -18,8 +18,8 @@ # # Image push targets, internal NGC registry pulls, and the nvcfbarn # remote cache are all internal-only; this workflow runs build + test -# only. It pulls the same bazel-ci toolchain image the GitLab pipeline -# uses, mirrored to ghcr.io by the bazel-ci-image workflow. +# only. The bazel-ci image is built by the internal nvcf/bazel-ci-templates +# project and mirrored to GHCR for this public workflow. name: bazel @@ -71,6 +71,9 @@ jobs: with: fetch-depth: 0 + - name: Check Java import boundaries + run: bash tools/ci/check-java-import-boundaries + - name: Compute changed subtrees id: detect env: @@ -127,7 +130,7 @@ jobs: # Paths that affect the root-module workspace build (native root # subtrees plus the shared Bazel scaffold). Java and stargate no longer # ride the root row: nv-boot-parent, cloud-tasks, and stargate are - # their own module rows, so src/libraries/ is narrowed to + # their own scoped rows, so src/libraries/ is narrowed to # src/libraries/go/ and cloud-tasks is dropped here. ROOT_GLOBS=(MODULE.bazel .bazelrc .bazelversion BUILD.bazel WORKSPACE WORKSPACE.bazel go.work go.work.bazel rules/ platforms/ tools/ ci/ src/clis/ src/libraries/go/ .github/bazel-root-test-quarantine.txt) @@ -258,13 +261,11 @@ jobs: CACHE_TOKEN: ${{ secrets.BAZEL_REMOTE_CACHE_TOKEN }} CACHE_ENDPOINT: ${{ vars.BAZEL_REMOTE_CACHE_ENDPOINT }} container: - # Built in GitLab nvcf/bazel-ci-templates (bazel-ci/Dockerfile: Temurin - # JDK 25 + Maven + prewarmed Bazel and Go SDKs -- that is where java/javac - # come from) and skopeo-mirrored to the public ghcr tag below. This repo - # does NOT build the image (the old ci/Dockerfile.bazel + bazel-ci-image.yml - # were a stale, Java-less copy and have been removed). Bump this ref in - # lockstep after a new tag is mirrored. Kept a string literal on purpose - # (see the container.image evaluation note above). + # This pinned image is built in the internal nvcf/bazel-ci-templates + # project and mirrored to GHCR. It supplies Temurin 25 at JAVA_HOME; + # Bazelisk then selects the root .bazelversion release. Update this tag + # only after the corresponding internal image has been published and + # mirrored. image: ghcr.io/nvidia/nvcf/bazel-ci:0.12.0 credentials: username: ${{ github.actor }} @@ -377,7 +378,7 @@ jobs: run: | set -uo pipefail tfile="$RUNNER_TEMP/targets.txt" - # SCOPE is //... for the root row and per-module rows, and //<path>/... + # SCOPE is //... for standalone-module rows, and //<path>/... # for a root-scoped lane so it builds only its own targets out of the # shared root module. full() { printf '%s\n' "$SCOPE" > "$tfile"; echo "targets: $SCOPE (full build)"; } @@ -597,9 +598,9 @@ jobs: - uses: actions/checkout@v4 with: fetch-depth: 0 - # The Java tree builds with local_jdk (root .bazelrc). This bare runner is - # not the bazel-ci image (which ships Temurin 25), so provide JDK 25 at - # JAVA_HOME for local_jdk to resolve. + # The Java tree builds with local_jdk (root .bazelrc). Unlike the fast + # matrix, this lane runs on a bare runner rather than the bazel-ci image, + # so provide JDK 25 explicitly for the Java requires-docker tests. - uses: actions/setup-java@v4 with: distribution: temurin @@ -620,6 +621,9 @@ jobs: # only tests are requires-docker (cloud-tasks) still runs them all here. # bazel exit 4 (no test targets in scope) is treated as success. run: | + # Run only the Testcontainers suites across the root workspace against + # the host Docker. If a change touches none, bazel exits 4 (no tests + # matched) which we treat as success. set +e bazel test ${{ matrix.subtree.scope }} \ --test_output=errors \ diff --git a/BAZEL.md b/BAZEL.md index 56b564b55..b8e1cf7c0 100644 --- a/BAZEL.md +++ b/BAZEL.md @@ -11,11 +11,13 @@ Bazel currently builds, tests, and packages: - `src/clis/nvcf-cli` (Go binary + multi-platform release matrix + OCI image) - `src/libraries/go/lib` (Go library, 92 targets) +- `src/libraries/java/nv-boot-parent` (Java framework libraries and tests) +- `src/control-plane-services/cloud-tasks` (Java libraries, tests, and Spring + Boot application) -Subtrees listed in `imports.yaml` with `authoritative_source: upstream` are -intentionally excluded via -`.bazelignore` and `# gazelle:exclude` directives in the root `BUILD.bazel`. -They will be onboarded one at a time as Phase B in separate MRs. +Other upstream-owned subtrees remain excluded until they are onboarded one at +a time. nv-boot-parent and Cloud Tasks are folded into the root Bazel module +and are not nested Bazel workspaces. ## One-time setup @@ -62,10 +64,34 @@ the cross-toolchain on first use. ### Common environment -The repo expects Bazel 8.6.0 (pinned in `.bazelversion`). Bazelisk handles +The repo expects Bazel 9.1.1 (pinned in `.bazelversion`). Bazelisk handles the download automatically; do not install Bazel via apt or brew directly, as that pins a different version. +Java targets use Java 25 with the root `.bazelrc` setting +`--java_runtime_version=local_jdk`. The pinned containerized CI image supplies +Temurin 25 through `JAVA_HOME`. The bare Docker-integration lane downloads and +configures Temurin 25 through the workflow's `actions/setup-java@v4` step. + +`bazel info java-home` reports the Java runtime used to run the Bazel server. +That directory is not guaranteed to contain command-line tools such as +`javac`, so it is not the right way to inspect the Java toolchains selected for +build actions. Query those toolchains directly: + +```bash +bazel cquery @bazel_tools//tools/jdk:current_java_runtime \ + --output=starlark \ + --starlark:expr='str(providers(target)["ToolchainInfo"].java_runtime.version)' + +bazel cquery @bazel_tools//tools/jdk:current_host_java_runtime \ + --output=starlark \ + --starlark:expr='str(providers(target)["ToolchainInfo"].java_runtime.version)' +``` + +Both commands must print `25`. The normal Java build then proves that the +compiler toolchain works; a separate `javac` command under +`bazel info java-home` is neither required nor expected. + ## Day-to-day commands ### Build @@ -282,12 +308,31 @@ build). ## CI -Two Bazel-aware jobs in the root `.gitlab-ci.yml`: +The public GitHub Bazel matrix in `.github/workflows/bazel.yml` consumes +`ghcr.io/nvidia/nvcf/bazel-ci:0.12.0`. That image is built in the internal +[`nvcf/bazel-ci-templates`](https://gitlab-master.nvidia.com/nvcf/bazel-ci-templates) +project, stamped with a version, and mirrored to GHCR. The mirror is currently +manual; automation is planned. To change the image's Bazel, Java, or operating +system tooling, update the internal template first, publish and mirror a new +tag, and only then update the pinned `container.image` here. + +The root `ci/Dockerfile.bazel` and +`.github/workflows/bazel-ci-image.yml` are legacy files and are not the +authoritative producer for the image used by the matrix. Do not use them to +reason about the contents of `bazel-ci:0.12.0`. + +The detect job also enforces the single-module import boundary: + +```bash +bash tools/ci/check-java-import-boundaries +``` + +Run this after refreshing nv-boot-parent or Cloud Tasks source. It fails when +a standalone Bazel root file, lockfile, workspace file, or migration directory +is reintroduced under either subtree. + +The existing internal Bazel jobs include: -- `bazel-ci-image`: rebuilds `ci/Dockerfile.bazel` via buildah and pushes - to `${CI_REGISTRY_IMAGE}/bazel-ci:<ref-slug>`. Triggers only when - `ci/Dockerfile.bazel` or `.bazelversion` changes (or when a web pipeline - is run with `$REBUILD_BAZEL_IMAGE` set). - `bazel-smoke`: pulls the image, runs `bazel info release`, then `bazel build --config=remote //src/libraries/go/lib/... //src/clis/nvcf-cli:image_index` and `bazel mod graph`. It does not @@ -339,9 +384,13 @@ For native subtrees outside Phase 1 scope today: 5. Run `bazel run //:gazelle` then `bazel mod tidy`. 6. `bazel build //path/to/subtree/...` to validate. -For upstream-owned subtrees (`authoritative_source: upstream` in -`imports.yaml`), Bazel files belong upstream so they survive the next commit-pin -refresh. +The public checkout does not contain the internal source-mirroring +configuration. For an upstream-owned subtree, distinguish between source files +that continue to mirror from the standalone repository and monorepo-native +Bazel overlays. The import process must exclude standalone `MODULE.bazel`, +lockfiles, `.bazelrc`, `.bazelversion`, downloader config, dependency hub, +and `bazel-enablement` content. Root-module BUILD adaptations and monorepo +agent/documentation overlays must be preserved during refreshes. ## Per-service publish cadence diff --git a/BUILD.bazel b/BUILD.bazel index 3f8365df4..1cd9bf97b 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -35,14 +35,14 @@ exports_files( ], ) -# Phase 1 scope: only the native Go subtrees listed in go.work.bazel are -# managed by Bazel. -# Everything else is excluded so Gazelle does not descend into vendored -# directories of upstream-owned subtrees. Their source is owned upstream, and -# local-only changes would be clobbered by the next commit-pin refresh. +# Gazelle manages only the native Go subtrees listed in go.work.bazel. +# nv-boot-parent and Cloud Tasks are also owned by the root Bazel module, but +# their checked-in Java BUILD files are maintained manually and remain outside +# Gazelle's scope. Other upstream-owned subtrees stay excluded so Gazelle does +# not descend into vendored directories. # -# When promoting an upstream to native (Phase B), remove the corresponding -# exclude line below and add a per-subtree BUILD.bazel with the right prefix. +# When onboarding another subtree, remove only the exclusions needed by its +# language-specific build integration. # gazelle:exclude .bazel-cache # gazelle:exclude .worktrees # gazelle:exclude .cursor diff --git a/MODULE.bazel b/MODULE.bazel index f89e90136..61deaccb4 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -300,10 +300,10 @@ maven.install( "org.junit.jupiter:junit-jupiter-engine", "org.junit.platform:junit-platform-launcher", "org.junit.platform:junit-platform-reporting", - # cloud-tasks service closure. Version-less coordinates are managed by + # Cloud Tasks service closure. Version-less coordinates are managed by # the BOMs above (spring-boot 4.0.7 / spring-cloud 2025.1.2 / # testcontainers 2.0.5 / shedlock 7.7.0). Explicit versions match the - # cloud-tasks standalone module; io.grpc pins track GRPC_VERSION. + # validated Cloud Tasks baseline; io.grpc pins track GRPC_VERSION. "com.bucket4j:bucket4j_jdk17-core:8.19.0", "com.github.ben-manes.caffeine:caffeine", "com.google.protobuf:protobuf-java:4.33.4", diff --git a/src/control-plane-services/cloud-tasks/AGENTS.md b/src/control-plane-services/cloud-tasks/AGENTS.md index d73f49e14..4fa074bab 100644 --- a/src/control-plane-services/cloud-tasks/AGENTS.md +++ b/src/control-plane-services/cloud-tasks/AGENTS.md @@ -1,45 +1,51 @@ -# AGENTS.md - cloud_tasks +# AGENTS.md - Cloud Tasks -The NVCF cloud-tasks Java (Spring Boot) service, as a standalone Bazel module -(`module(name = "cloud_tasks")`). Depends on `nv_boot_parent` (the Spring -platform starters) via `bazel_dep` plus `local_path_override`. Maven and Bazel -coexist; Maven stays the default build during coexistence. +Cloud Tasks is an OSS/self-hosted Java service folded into the root `nvcf` +Bazel module. It is not a nested Bazel module and does not own a +`MODULE.bazel`, lockfile, `.bazelrc`, `.bazelversion`, downloader config, or +third-party dependency hub. -## Build and test (from this directory) +Maven POMs remain during coexistence, but Bazel uses source targets throughout +the monorepo. Do not generate or publish Maven-shaped project artifacts from +Bazel. -``` -cd src/control-plane-services/cloud-tasks -export BAZEL_OUTPUT_USER_ROOT="${TMPDIR:-/tmp}/cloud-tasks-bazel-cache" -bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" build //... -bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" test //... --test_tag_filters=-requires-docker -``` +## Build And Test -The module builds on its own with no reference to the repo root. The Spring plus -Testcontainers integration tests are tagged `requires-docker` and run in the -dedicated Docker integration lane, not the default fast matrix. +Run Bazel from the monorepo root: -## Dependency hub +```bash +export BAZEL_OUTPUT_USER_ROOT="${TMPDIR:-/tmp}/nvcf-bazel-cache" -Third-party dependencies resolve through one shared hub named -`nv_third_party_deps` (never `@maven`). `maven.install` lists `nv_boot_parent` -in `known_contributing_modules`, so this service and the nv-boot starters -resolve a single merged third-party graph. This root owns and re-pins the merged -`maven_install.json`: +bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ + build //src/control-plane-services/cloud-tasks/... +bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ + test //src/control-plane-services/cloud-tasks/... \ + --test_tag_filters=-requires-docker ``` -REPIN=1 bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" run @nv_third_party_deps//:pin + +The Testcontainers suites are tagged `requires-docker` and run in the +dedicated Docker integration lane. + +## Dependencies + +The root `MODULE.bazel` owns the single `nv_third_party_deps` hub and the root +`maven_install.json` and `MODULE.bazel.lock`. BUILD targets here declare only +the direct labels they compile or run against. A coordinate being available in +the root hub does not put it on this service's runtime classpath. + +Use direct monorepo labels for nv-boot libraries, for example: + +```text +//src/libraries/java/nv-boot-parent/nv-boot-starter-core:nv_boot_starter_core ``` -Both `maven_install.json` and `MODULE.bazel.lock` are committed. Lombok needs -`build --java_header_compilation=false` (via `--nojava_header_compilation` in -this module's `.bazelrc`). +Do not introduce `@nv_boot_parent`, `@cloud_tasks`, `@maven`, +`local_path_override`, or `git_override` for code already in this repository. ## Layout -- `nvct-core/` - service library plus the gRPC `nvct.proto` codegen (driven by - the `protoc-gen-grpc-java` native plugins declared in `MODULE.bazel` and the - macros in `tools/bazel/proto.bzl`). -- `nvct-service/` - the `@SpringBootApplication` entry point and the Spring Boot - executable app jar (`tools/bazel/spring_boot.bzl`). -- `tools/bazel/` - the `nv_boot_library` macros (`java.bzl`), Lombok wiring, the - gRPC plugin, the JaCoCo runner, and the NOTICE generator. +- `nvct-core/`: service library and gRPC code generation. +- `nvct-service/`: Spring Boot application and executable `app.jar`. +- `//rules/java`: shared Java, test, protobuf, and Spring Boot rules. +- `//tools/bazel/java`: shared executable helper implementations. diff --git a/src/libraries/java/nv-boot-parent/AGENTS.md b/src/libraries/java/nv-boot-parent/AGENTS.md index 2d6e77416..ec383edaa 100644 --- a/src/libraries/java/nv-boot-parent/AGENTS.md +++ b/src/libraries/java/nv-boot-parent/AGENTS.md @@ -1,55 +1,50 @@ -# AGENTS.md - nv_boot_parent +# AGENTS.md - nv-boot-parent -The NVCF Spring Boot platform library, as a standalone Bazel module -(`module(name = "nv_boot_parent")`). Owns the shared Spring BOM set and the -`nv-boot-*` starter `java_library` targets that every NVCF Java service depends -on. Maven and Bazel coexist here; Maven stays authoritative for Maven consumers. +nv-boot-parent provides the NVCF Spring Boot platform libraries inside the root +`nvcf` Bazel module. It is not a nested Bazel module and does not own a +`MODULE.bazel`, lockfile, `.bazelrc`, `.bazelversion`, downloader config, or +third-party dependency hub. -## Build and test (from this directory) +Maven POMs remain during coexistence for Maven consumers. Bazel consumers use +the public starter source targets directly; Bazel does not generate or publish +Maven-shaped nv-boot artifacts. -``` -cd src/libraries/java/nv-boot-parent -export BAZEL_OUTPUT_USER_ROOT="${TMPDIR:-/tmp}/nv-boot-parent-bazel-cache" -bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" build //... -bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" test //... -``` +## Build And Test -The module builds on its own with no reference to the repo root. Docker -integration tests are tagged `requires-docker` and run in the dedicated -integration lane, not the default `bazel test //...`. +Run Bazel from the monorepo root: -## Dependency hub +```bash +export BAZEL_OUTPUT_USER_ROOT="${TMPDIR:-/tmp}/nvcf-bazel-cache" -Third-party dependencies resolve through one shared hub named -`nv_third_party_deps` (never `@maven`). Downstream services contribute to the -same hub and list this module in `known_contributing_modules`, so the final -application resolves a single third-party graph. Public BUILD labels look like -`@nv_third_party_deps//:org_springframework_boot_spring_boot`. +bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ + build //src/libraries/java/nv-boot-parent/... -`MODULE.bazel` is the edited source of truth for BOM-managed roots and explicit -pins. After editing `maven.install`, re-pin and commit the lockfile: - -``` -REPIN=1 bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" run @nv_third_party_deps//:pin +bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ + test //src/libraries/java/nv-boot-parent/... \ + --test_tag_filters=-requires-docker ``` -Both `maven_install.json` and `MODULE.bazel.lock` are committed and never -hand-edited. +Tests tagged `requires-docker` run in the dedicated Docker integration lane. -## Layout +## Dependencies + +The root `MODULE.bazel` owns the one `nv_third_party_deps` hub and the root +`maven_install.json` and `MODULE.bazel.lock`. Starter BUILD targets declare +their own direct compile/runtime edges. Optional APIs use private `neverlink` +compile helpers plus runtime-classpath tests so frameworks such as Cassandra +are not added to unrelated consumers. -- `nv-boot-starter-*/` - the platform starters, each a public `nv_boot_library`. -- `tools/bazel/` - `nv_boot_library` / `nv_boot_library_test` macros - (`java.bzl`), Lombok wiring, JUnit 5 + JaCoCo runners, and the NOTICE - generator (`generate_notice.py`). -- `NOTICE` - generated from this module's own `maven_install.json`. +Do not introduce `@nv_boot_parent`, `@cloud_tasks`, `@maven`, +`local_path_override`, or `git_override` for code already in this repository. -Lombok needs `build --java_header_compilation=false`; that flag lives in this -module's `.bazelrc` and must also be set in every downstream consuming root, -because `.bazelrc` is not transitive through Bzlmod. +## Layout -## Consuming this module +- `nv-boot-starter-*/`: public nv-boot starter source targets. +- `//rules/java`: shared Java, test, runtime-scope, protobuf, and Spring Boot + rules. +- `//tools/bazel/java`: shared executable helper implementations. +- `NOTICE`, `notice_roots.json`, and `notice_metadata.json`: nv-boot's + monorepo NOTICE inputs and generated output. -In-tree, a service module uses `bazel_dep(name = "nv_boot_parent", version = -"0.0.0")` plus `local_path_override`. See -`src/control-plane-services/cloud-tasks/MODULE.bazel` for the reference wiring. +The root `.bazelrc` owns Java 25 and +`build --java_header_compilation=false`. diff --git a/tools/ci/check-java-import-boundaries b/tools/ci/check-java-import-boundaries new file mode 100755 index 000000000..a133c06d5 --- /dev/null +++ b/tools/ci/check-java-import-boundaries @@ -0,0 +1,56 @@ +#!/usr/bin/env bash +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +set -euo pipefail + +repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" + +import_roots=( + "src/libraries/java/nv-boot-parent" + "src/control-plane-services/cloud-tasks" +) + +root_owned_files=( + ".bazel_downloader_config" + ".bazelignore" + ".bazelrc" + ".bazelversion" + "MODULE.bazel" + "MODULE.bazel.lock" + "WORKSPACE" + "WORKSPACE.bazel" + "maven_install.json" +) + +failed=false + +for import_root in "${import_roots[@]}"; do + for root_owned_file in "${root_owned_files[@]}"; do + path="${repo_root}/${import_root}/${root_owned_file}" + if [[ -e "${path}" ]]; then + echo "ERROR: root-owned Bazel file reintroduced: ${import_root}/${root_owned_file}" >&2 + failed=true + fi + done + + while IFS= read -r migration_dir; do + [[ -z "${migration_dir}" ]] && continue + echo "ERROR: standalone migration directory reintroduced: ${migration_dir#${repo_root}/}" >&2 + failed=true + done < <( + find "${repo_root}/${import_root}" -type d \ + \( -name bazel-enablement -o -name bazel-migration \) -print + ) +done + +if [[ "${failed}" == true ]]; then + cat >&2 <<'EOF' +nv-boot-parent and Cloud Tasks are packages in the root nvcf Bazel module. +Keep Bazel root configuration and dependency locks at the repository root, and +keep standalone migration records out of imported source trees. +EOF + exit 1 +fi + +echo "Java import boundaries: PASS" From 36911cd4353c4cf1a8bb990cb3dac8b3016a1edb Mon Sep 17 00:00:00 2001 From: Sanjay Saxena <sasaxena@nvidia.com> Date: Thu, 23 Jul 2026 16:39:08 -0700 Subject: [PATCH 24/29] Complete Cloud Tasks Bazel parity validation --- .github/workflows/bazel.yml | 3 - .../cloud-tasks/BAZEL.md | 387 ++++++------------ .../cloud-tasks/nvct-service/Dockerfile | 29 ++ src/libraries/java/nv-boot-parent/BAZEL.md | 342 +++++----------- 4 files changed, 267 insertions(+), 494 deletions(-) create mode 100644 src/control-plane-services/cloud-tasks/nvct-service/Dockerfile diff --git a/.github/workflows/bazel.yml b/.github/workflows/bazel.yml index ba18cc2e0..66fe7c457 100644 --- a/.github/workflows/bazel.yml +++ b/.github/workflows/bazel.yml @@ -621,9 +621,6 @@ jobs: # only tests are requires-docker (cloud-tasks) still runs them all here. # bazel exit 4 (no test targets in scope) is treated as success. run: | - # Run only the Testcontainers suites across the root workspace against - # the host Docker. If a change touches none, bazel exits 4 (no tests - # matched) which we treat as success. set +e bazel test ${{ matrix.subtree.scope }} \ --test_output=errors \ diff --git a/src/control-plane-services/cloud-tasks/BAZEL.md b/src/control-plane-services/cloud-tasks/BAZEL.md index b3992a08a..e80f1c62d 100644 --- a/src/control-plane-services/cloud-tasks/BAZEL.md +++ b/src/control-plane-services/cloud-tasks/BAZEL.md @@ -1,23 +1,25 @@ # Bazel -This project is migrating from Maven to Bazel while both build systems coexist. -Maven remains available during the migration. +Cloud Tasks lives inside the `NVIDIA/nvcf` monorepo. Run every command in this +document from the monorepo root, not from this subtree. Maven remains available +during coexistence, but Bazel configuration and dependency locks are owned by +the monorepo root. -For the Bazel path, consume `nv-boot-parent` directly as Bazel source targets -instead of consuming Bazel-produced Maven-shaped `com.nvidia.boot:*` artifacts -from URM. +For the Bazel path, Cloud Tasks consumes nv-boot through direct first-party +labels such as: -Hard rule for this migration: do not publish Maven-shaped jars from the Bazel -toolchain. Maven consumers should continue to use the Maven build/publish path -during coexistence. Bazel consumers should depend on Bazel targets. We initially -took a wrong turn by treating Maven artifact publication as required for Bazel -coexistence; after clarifying that Bazel apps can consume source targets -directly, we are correcting that path. +```text +//src/libraries/java/nv-boot-parent/nv-boot-starter-core:nv_boot_starter_core +``` + +Bazel does not publish Maven-shaped Cloud Tasks or nv-boot jars. Maven +consumers continue to use the Maven build/publish path during coexistence; +Bazel consumers use source targets in this checkout. Set one OS-neutral Bazel output root when opening a shell in this repository: ```bash -export BAZEL_OUTPUT_USER_ROOT="${TMPDIR:-/tmp}/cloud-tasks-bazel-cache" +export BAZEL_OUTPUT_USER_ROOT="${TMPDIR:-/tmp}/nvcf-bazel-cache" ``` The commands below reuse this variable. It resolves under the operating @@ -26,25 +28,24 @@ system's temporary directory instead of assuming the macOS-specific ## Understanding the Dependency Files -Bazel uses three top-level files for dependency declarations and locking. A +Bazel uses three root files for dependency declarations and locking. A simple way to remember their responsibilities is: ```text -MODULE.bazel = what this repository wants +MODULE.bazel = what the whole monorepo wants maven_install.json = exact third-party Java artifacts that were resolved MODULE.bazel.lock = exact Bazel modules and module extensions that were resolved ``` ### `MODULE.bazel` -Developers edit this file. It declares the repository as a Bazel module and -contains inputs such as: +Developers edit the root `MODULE.bazel`. Cloud Tasks does not have a nested +module file. The root file declares inputs such as: - `bazel_dep` entries for Bazel rules and tooling; -- the pinned `git_override` for the nv-boot-parent source module; - Maven-compatible BOMs and third-party Java dependency roots supplied to `rules_jvm_external`; -- the shared `nv_third_party_deps` hub configuration. +- the shared `nv_third_party_deps` hub configuration; and - checksum-pinned repositories for native build tools that are not Java dependencies. @@ -71,7 +72,7 @@ drift. Negative numbers there are normal. They are not artifact checksums; artifact integrity is recorded separately as hexadecimal SHA-256 values under each artifact's `shasums` entry. -After changing BOMs, third-party roots, or versions in `MODULE.bazel`, +After changing BOMs, third-party roots, or versions in the root `MODULE.bazel`, regenerate it with: ```bash @@ -103,8 +104,9 @@ them, commit those changes together. The normal workflow is: ## Prerequisites -- Bazel 9.1.1, preferably through Bazelisk honoring `.bazelversion`. -- Java 25. `.bazelrc` pins Bazel Java compilation and runtime to Java 25. +- Bazel 9.1.1 through Bazelisk honoring the root `.bazelversion`. +- Java 25. The root `.bazelrc` selects the local Java 25 JDK for compilation + and runtime. - Docker is required for the current `nvct-core` and `nvct-service` integration tests. @@ -114,15 +116,9 @@ only to build and commands that inherit build options. The `rules_spring` external Java-rule compatibility option is therefore under `common`, while the Lombok header-compilation setting remains under `build`. -Current Bazel-path nv-boot source dependency: - -```text -nv_boot_parent git_override commit bfd1db74fa6588cda53df364bfbbb14457221099 -``` - -The Bazel path consumes `nv-boot-parent` source targets directly and does not -list `com.nvidia.boot:nv-boot-bom` or `com.nvidia.boot:*` artifacts in -`MODULE.bazel`. +The root `.bazel_downloader_config` maps external downloads to approved +mirrors. Bazel applies it automatically through `.bazelrc`; Cloud Tasks should +not define a subtree-specific downloader configuration. ## Dependency Updates @@ -134,7 +130,7 @@ Jackson, gRPC, and Guava. `rules_jvm_external` currently obtains those jars from Maven-compatible repositories, but that is an implementation detail of dependency resolution, not the meaning of the hub name. -Both `nv-boot-parent` and Cloud Tasks intentionally use: +The monorepo root defines exactly one install: ```python maven.install( @@ -144,15 +140,14 @@ maven.install( use_repo(maven, "nv_third_party_deps") ``` -The same name is deliberate. In simple terms: +In simple terms: -1. `nv-boot-parent` contributes the third-party dependencies needed by its - libraries. -2. Cloud Tasks contributes the additional dependencies needed by the app. -3. Bzlmod and `rules_jvm_external` merge those contributions into one - `@nv_third_party_deps` repository. -4. The merged hub resolves one selected version of each third-party artifact - for the complete application. +1. The root `MODULE.bazel` lists the third-party roots needed across Java + libraries and applications. +2. `rules_jvm_external` resolves them as one graph. +3. BUILD files use labels from the generated `@nv_third_party_deps` + repository. +4. The root `maven_install.json` locks the selected artifacts and checksums. The name `nv_third_party_deps` is intentionally agnostic about build tool, resolver, and runtime. The hub contains only third-party dependency targets. @@ -161,71 +156,23 @@ consumed and built as first-party Bazel source targets. It also does not imply that Bazel creates or publishes Maven-shaped project artifacts. `maven.install.name` names the generated hub. `use_repo` makes that generated -repository visible to BUILD files as `@nv_third_party_deps`. Cloud Tasks also -lists `nv_boot_parent` in `known_contributing_modules` to state that the -upstream module is expected to contribute third-party dependencies to this -hub. - -Using different names would create two independent dependency graphs. A final -Spring Boot app could then contain two versions of the same library or an -incompatible mixture from one dependency family. We observed exactly that: -the two-hub app was 218 MB, while the merged-hub app was 142 MB and closely -matched Maven's 142 MB app. The split graph also mixed gRPC 1.63 and 1.74, -causing missing-class failures at runtime. - -Therefore, do not add a second `maven.install` or rename the Cloud Tasks hub to -something project-specific. Add required roots to the existing -`nv_third_party_deps` install and repin it. - -### Local nv-boot-parent Override - -The shared hub itself is not locally overridden. The command-line override -replaces the first-party `nv_boot_parent` module, and that local module then -contributes its third-party dependency roots to `nv_third_party_deps`. - -A local override is appropriate only while developing unpushed -`nv-boot-parent` changes and validating them in Cloud Tasks. Supply an absolute -path to the local checkout: - -```bash -bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ - build \ - --override_module=nv_boot_parent=/absolute/path/to/nv-boot-parent \ - //... +repository visible to BUILD files as `@nv_third_party_deps`. -bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ - test \ - --override_module=nv_boot_parent=/absolute/path/to/nv-boot-parent \ - //... \ - --cache_test_results=no \ - --test_output=errors -``` - -If the local nv-boot-parent change modifies third-party dependency roots or -versions, repin against that same local checkout: - -```bash -REPIN=1 bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ - run \ - --override_module=nv_boot_parent=/absolute/path/to/nv-boot-parent \ - @nv_third_party_deps//:pin -``` +Do not add a second hub in a service subtree. Multiple hubs can select +different versions of the same library and create an incompatible runtime. +A coordinate's presence in the root hub only makes its Bazel target available; +it reaches Cloud Tasks compilation or runtime only when a BUILD dependency +edge selects it. -Do not put a workstation path in `MODULE.bazel`, CI configuration, or shared -scripts. CI and final validation must omit `--override_module` and use the -committed `git_override` hash. - -An accidental or stale local override causes Bazel to ignore the committed -nv-boot-parent Git hash for that invocation. The build may then use dirty, -unpushed, or outdated source and a different contribution to the shared hub. -It can fail with a pin-signature error, or it can pass locally while producing -a result that CI cannot reproduce. Removing `--override_module` restores the -committed Git dependency. Before committing Cloud Tasks, always repin, build, -and test once without the override. +Therefore, add required roots to the existing root install and repin it. Do +not use `git_override`, `local_path_override`, or `--override_module` between +nv-boot and Cloud Tasks: both are ordinary directories in the same Bazel +module. ### Updating Dependencies -After changing third-party roots or versions in `MODULE.bazel`, repin with: +After changing third-party roots or versions in the root `MODULE.bazel`, +repin with: ```bash REPIN=1 bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ @@ -236,9 +183,9 @@ Then run the normal build and tests. Commit `MODULE.bazel` and `maven_install.json` together. Commit `MODULE.bazel.lock` too if Bzlmod changes it. -The project intentionally pins gRPC runtime and code generation to 1.63.0. +Cloud Tasks intentionally pins gRPC runtime and code generation to 1.63.0. `rules_proto_grpc_java` 5.8.0 bundles a newer 1.74 generator, so -`tools/bazel/proto.bzl` keeps the upstream compile implementation but selects +`//rules/java:proto.bzl` keeps the upstream compile implementation but selects the matching 1.63 executable fetched by checksum-pinned `http_file` repositories. These native executables intentionally stay outside `nv_third_party_deps`, which has `fetch_sources = True` for Java @@ -256,11 +203,11 @@ outside the checkout: ## Build Everything -Build all current Bazel targets: +Build all Cloud Tasks targets: ```bash bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ - build //... \ + build //src/control-plane-services/cloud-tasks/... \ --verbose_failures ``` @@ -273,28 +220,28 @@ Build the main `nvct-core` library: ```bash bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ - build //nvct-core:nvct_core \ + build //src/control-plane-services/cloud-tasks/nvct-core:nvct_core \ --verbose_failures ``` The current Bazel library jar is: ```text -bazel-bin/nvct-core/libnvct_core.jar +bazel-bin/src/control-plane-services/cloud-tasks/nvct-core/libnvct_core.jar ``` Build the `nvct-core` test-fixtures target consumed by `nvct-service` tests: ```bash bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ - build //nvct-core:nvct_core_test_fixtures \ + build //src/control-plane-services/cloud-tasks/nvct-core:nvct_core_test_fixtures \ --verbose_failures ``` The current Bazel test-fixtures jar is: ```text -bazel-bin/nvct-core/libnvct_core_test_fixtures.jar +bazel-bin/src/control-plane-services/cloud-tasks/nvct-core/libnvct_core_test_fixtures.jar ``` This is a Bazel-native library target, not a Maven `tests` classifier artifact. @@ -307,7 +254,7 @@ feedback: ```bash bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ - build //nvct-service:app_classes \ + build //src/control-plane-services/cloud-tasks/nvct-service:app_classes \ --verbose_failures ``` @@ -318,17 +265,17 @@ Build the Bazel-native Spring Boot executable jar: ```bash bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ - build //nvct-service:app \ + build //src/control-plane-services/cloud-tasks/nvct-service:app \ --verbose_failures ``` The app jar is: ```text -bazel-bin/nvct-service/app.jar +bazel-bin/src/control-plane-services/cloud-tasks/nvct-service/app.jar ``` -The jar is produced by `tools/bazel/spring_boot.bzl`, which delegates Spring +The jar is produced by `//rules/java:spring.bzl`, which delegates Spring Boot executable packaging to `rules_spring` and then injects the small set of metadata files that Maven plugins used to contribute: @@ -361,7 +308,7 @@ git.tags Quick local launch smoke: ```bash -java -jar bazel-bin/nvct-service/app.jar \ +java -jar bazel-bin/src/control-plane-services/cloud-tasks/nvct-service/app.jar \ --spring.main.web-application-type=none \ --spring.main.banner-mode=off \ --logging.level.root=OFF \ @@ -374,13 +321,13 @@ Spring Boot launcher, app classes, and runtime dependencies. ## Build and Run the Docker Image -Run these commands from the cloud-tasks repository root. +Run these commands from the monorepo root. First, build the Spring Boot executable jar: ```bash bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ - build //nvct-service:app \ + build //src/control-plane-services/cloud-tasks/nvct-service:app \ --verbose_failures ``` @@ -393,10 +340,10 @@ BAZEL_BIN_DIR="$( )" docker build \ - -f nvct-service/Dockerfile \ + -f src/control-plane-services/cloud-tasks/nvct-service/Dockerfile \ --build-arg APP_JAR=app.jar \ - -t nvct-service:bazel \ - "${BAZEL_BIN_DIR}/nvct-service" + -t cloud-tasks-nvct-service:bazel \ + "${BAZEL_BIN_DIR}/src/control-plane-services/cloud-tasks/nvct-service" ``` Using the resolved output directory is necessary because the workspace @@ -406,7 +353,9 @@ Docker cannot follow that symlink through a repository-root build context. Start the local Cassandra dependency: ```bash -docker compose -f local_env/docker-compose.yml up -d +docker compose \ + -f src/control-plane-services/cloud-tasks/local_env/docker-compose.yml \ + up -d ``` Run the application container with the `local` Spring profile: @@ -414,13 +363,13 @@ Run the application container with the `local` Spring profile: ```bash docker run --rm \ --name nvct-service \ - --mount "type=bind,source=$(pwd),target=/home/app,readonly" \ + --mount "type=bind,source=$(pwd)/src/control-plane-services/cloud-tasks,target=/home/app,readonly" \ -e SPRING_PROFILES_ACTIVE=local \ -e SPRING_CASSANDRA_CONTACT_POINTS=host.docker.internal \ -p 8080:8080 \ -p 9090:9090 \ -p 8181:8181 \ - nvct-service:bazel + cloud-tasks-nvct-service:bazel ``` The repository bind mount makes `local_env/vault/secrets.json` available at @@ -431,7 +380,9 @@ container refers to the application container itself. After stopping the application, stop the local Cassandra dependency: ```bash -docker compose -f local_env/docker-compose.yml down +docker compose \ + -f src/control-plane-services/cloud-tasks/local_env/docker-compose.yml \ + down ``` Omitting the Docker build argument keeps the Dockerfile's Maven-build default, @@ -443,7 +394,7 @@ Run all current Bazel test targets without using cached test results: ```bash bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ - test //... \ + test //src/control-plane-services/cloud-tasks/... \ --cache_test_results=no \ --test_output=errors \ --test_env=DOCKER_HOST \ @@ -456,12 +407,12 @@ bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ Current Bazel test targets are: ```text -//nvct-core:tests -//nvct-service:tests +//src/control-plane-services/cloud-tasks/nvct-core:tests +//src/control-plane-services/cloud-tasks/nvct-service:tests ``` Both are tagged `exclusive` because they use the same fixed-port local -integration environment. Without that, `bazel test //...` can run them in +integration environment. Without that, a scoped wildcard test can run them in parallel and collide on ports such as WireMock `9092`. ## Test `nvct-core` @@ -470,7 +421,7 @@ Run the full `nvct-core` test target: ```bash bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ - test //nvct-core:tests \ + test //src/control-plane-services/cloud-tasks/nvct-core:tests \ --cache_test_results=no \ --test_output=errors \ --test_env=DOCKER_HOST \ @@ -489,7 +440,7 @@ Run the `nvct-service` Spring Boot smoke/integration test target: ```bash bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ - test //nvct-service:tests \ + test //src/control-plane-services/cloud-tasks/nvct-service:tests \ --cache_test_results=no \ --test_output=errors \ --test_env=DOCKER_HOST \ @@ -509,7 +460,7 @@ Convert the test source path to its fully qualified class name. Example: ```text -nvct-core/src/test/java/com/nvidia/nvct/service/apikeys/ApiKeyValidationResultTest.java +src/control-plane-services/cloud-tasks/nvct-core/src/test/java/com/nvidia/nvct/service/apikeys/ApiKeyValidationResultTest.java ``` becomes: @@ -522,7 +473,7 @@ Run only that test class: ```bash bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ - test //nvct-core:tests \ + test //src/control-plane-services/cloud-tasks/nvct-core:tests \ --cache_test_results=no \ --test_output=errors \ --test_env=DOCKER_HOST \ @@ -542,7 +493,7 @@ Run one test method by combining a class filter with a method-name filter: ```bash bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ - test //nvct-core:tests \ + test //src/control-plane-services/cloud-tasks/nvct-core:tests \ --cache_test_results=no \ --test_output=errors \ --test_env=DOCKER_HOST \ @@ -561,7 +512,7 @@ Example: ```bash bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ - test //nvct-core:tests \ + test //src/control-plane-services/cloud-tasks/nvct-core:tests \ --cache_test_results=no \ --test_output=errors \ --test_arg=--exclude-classname='^(?!com\.nvidia\.nvct\.service\.apikeys\.ApiKeyValidationResultTest$).*$' \ @@ -574,20 +525,20 @@ bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ Bazel writes test logs under: ```text -bazel-testlogs/<module>/tests/ +bazel-testlogs/src/control-plane-services/cloud-tasks/<module>/tests/ ``` Useful files: ```text -bazel-testlogs/nvct-core/tests/test.log -bazel-testlogs/nvct-core/tests/test.outputs/junit/TEST-junit-jupiter.xml -bazel-testlogs/nvct-service/tests/test.log -bazel-testlogs/nvct-service/tests/test.outputs/junit/TEST-junit-jupiter.xml +bazel-testlogs/src/control-plane-services/cloud-tasks/nvct-core/tests/test.log +bazel-testlogs/src/control-plane-services/cloud-tasks/nvct-core/tests/test.outputs/junit/TEST-junit-jupiter.xml +bazel-testlogs/src/control-plane-services/cloud-tasks/nvct-service/tests/test.log +bazel-testlogs/src/control-plane-services/cloud-tasks/nvct-service/tests/test.outputs/junit/TEST-junit-jupiter.xml ``` The Jupiter XML files contain the real Java testcases and are the reports -published by GitLab. The nearby `tests/test.xml` files describe Bazel's single +published by GitHub Actions. The nearby `tests/test.xml` files describe Bazel's single outer `sh_test` wrapper and must not be used as JUnit reports. Use `--cache_test_results=no` when you want to force the tests to run again. @@ -597,7 +548,7 @@ watch test output live: ```bash bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ - test //nvct-core:tests \ + test //src/control-plane-services/cloud-tasks/nvct-core:tests \ --cache_test_results=no \ --test_output=streamed \ --test_env=DOCKER_HOST \ @@ -608,17 +559,19 @@ bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ ## Coverage And Sonar XML -Coverage generation is part of `//nvct-core:tests` and -`//nvct-service:tests`; no separate coverage command is required. Running a +Coverage generation is part of +`//src/control-plane-services/cloud-tasks/nvct-core:tests` and +`//src/control-plane-services/cloud-tasks/nvct-service:tests`; no separate +coverage command is required. Running a test with `--cache_test_results=no` refreshes these outputs: ```text -bazel-testlogs/nvct-core/tests/test.outputs/index.html -bazel-testlogs/nvct-core/tests/test.outputs/jacoco.xml -bazel-testlogs/nvct-core/tests/test.outputs/jacoco.exec -bazel-testlogs/nvct-service/tests/test.outputs/index.html -bazel-testlogs/nvct-service/tests/test.outputs/jacoco.xml -bazel-testlogs/nvct-service/tests/test.outputs/jacoco.exec +bazel-testlogs/src/control-plane-services/cloud-tasks/nvct-core/tests/test.outputs/index.html +bazel-testlogs/src/control-plane-services/cloud-tasks/nvct-core/tests/test.outputs/jacoco.xml +bazel-testlogs/src/control-plane-services/cloud-tasks/nvct-core/tests/test.outputs/jacoco.exec +bazel-testlogs/src/control-plane-services/cloud-tasks/nvct-service/tests/test.outputs/index.html +bazel-testlogs/src/control-plane-services/cloud-tasks/nvct-service/tests/test.outputs/jacoco.xml +bazel-testlogs/src/control-plane-services/cloud-tasks/nvct-service/tests/test.outputs/jacoco.exec ``` The test JVM runs the JaCoCo agent with `dumponexit=true`. After JUnit exits, @@ -630,7 +583,7 @@ Open `index.html` for the JaCoCo HTML report. Sonar consumes the corresponding `jacoco.xml`, for example: ```text --Dsonar.coverage.jacoco.xmlReportPaths=bazel-testlogs/nvct-core/tests/test.outputs/jacoco.xml,bazel-testlogs/nvct-service/tests/test.outputs/jacoco.xml +-Dsonar.coverage.jacoco.xmlReportPaths=bazel-testlogs/src/control-plane-services/cloud-tasks/nvct-core/tests/test.outputs/jacoco.xml,bazel-testlogs/src/control-plane-services/cloud-tasks/nvct-service/tests/test.outputs/jacoco.xml ``` Class and method filters also produce reports, but those reports describe only @@ -638,132 +591,48 @@ the selected test execution. ## License/NOTICE Generation -This is the Bazel-native replacement for the aggregate third-party inventory -previously produced through `license-maven-plugin`. It covers third-party -runtime dependency names, versions, declared licenses, and project URLs. It is -separate from source-file license-header enforcement. - -The canonical root `NOTICE` is derived from the third-party jars actually -nested in `//nvct-service:app`. This makes the executable application, rather -than a manually maintained dependency list, the source of truth. The generator -does not read project POM files and does not invoke Maven. - -License metadata is checked into -`tools/bazel/notice_metadata.json`. Keeping this metadata in the repository -makes normal NOTICE checks deterministic and allows CI to fail when the runtime -graph changes without a corresponding NOTICE update. - -### Regenerate NOTICE - -Regenerate `NOTICE` and fetch metadata for newly encountered runtime -coordinates: - -```bash -bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ - run //:generate_notice -- --update-metadata --write -``` - -This command builds `//nvct-service:app` automatically, inspects its -`BOOT-INF/lib` jars, refreshes missing license metadata, and writes: +NOTICE generation is the Bazel-native replacement for the aggregate +third-party inventory previously produced through `license-maven-plugin`. It +must derive the shipped coordinates from the jars nested in: ```text -NOTICE -tools/bazel/notice_metadata.json -``` - -Run it whenever `MODULE.bazel`, `maven_install.json`, or an application runtime -dependency changes. Commit both generated files when both change. - -### Check Committed NOTICE - -Check that the committed NOTICE and metadata match the current app runtime: - -```bash -bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ - test //tools/bazel:notice_check_test \ - --cache_test_results=no \ - --test_output=errors -``` - -For an interactive check through the generator entrypoint: - -```bash -bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ - run //:generate_notice -- --check +//src/control-plane-services/cloud-tasks/nvct-service:app ``` -`//tools/bazel:notice_check_test` is also part of `bazel test //...` and the -opt-in Bazel CI job. - -### Build A NOTICE Artifact +The root owns the generator under `//tools/bazel/java`; Cloud Tasks owns its +checked-in `NOTICE` and service-specific `notice_metadata.json`. The generator +does not read project POM files and does not invoke Maven. -Build a generated NOTICE artifact without modifying the checkout: +The final layered NOTICE integration is Phase 4 work. The current diagnostic +target is intentionally tagged `manual` and exposes the metadata gap: ```bash bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ - build //:third_party_notice + build //src/control-plane-services/cloud-tasks:third_party_notice ``` -The output is `bazel-bin/THIRD_PARTY_NOTICE`. It is useful for packaging or -inspection; the checked-in root `NOTICE` remains the reviewable canonical copy. - -## Opt-In CI - -Maven remains the default CI path. To add the Bazel build/test job to a -pipeline, set this GitLab CI/CD variable when starting the pipeline or in an MR -pipeline configuration: - -```yaml -ENABLE_BAZEL_BUILD: "true" -``` - -The `bazel-build-test` job uses Bazelisk with `.bazelversion`, Java 25, and a -Docker-in-Docker service. It runs all Bazel tests without cached test results, -builds all targets, checks NOTICE, and retains `app.jar`, JUnit XML, JaCoCo -HTML/XML, and other Bazel outputs for seven days. It also writes -`bazel-sonar.properties` with the discovered JaCoCo XML paths. - -CI intentionally sets `BAZEL_OUTPUT_USER_ROOT` under `/builds`, outside -`CI_PROJECT_DIR`. With the Kubernetes executor, `/builds` is shared by the job -container and Docker-in-Docker service, while each container has its own -`/tmp`. Testcontainers Compose bind mounts originate inside Bazel's test -sandbox, so a `/tmp` output root makes those files invisible to the Docker -daemon and causes file-versus-directory mount errors. - -There is intentionally no Bazel publish/deploy job. During coexistence, Maven -continues to own Maven artifact publication; the Bazel application consumes -`nv-boot-parent` source targets and produces the container input app jar. - -### Opt-In Bazel Docker Publication - -To prove container publication from the Bazel-built application, set: - -```yaml -ENABLE_BAZEL_DOCKER_PUBLISH: "true" -``` +At the end of Phase 3 this reports missing service/shared metadata, beginning +with `aopalliance:aopalliance:1.0`. Do not treat the current target or +checked-in NOTICE as the completed CI contract. Phase 4 will add deterministic +regenerate, check, complete-runtime NOTICE, and license-grouped OSRB-delta +commands here. -This flag also enables `bazel-build-test`, so `ENABLE_BAZEL_BUILD` does not -need to be set separately. It does not replace or disable the default Maven -jobs. The isolated proof path is: +## GitHub CI -1. `compute-next-release-version` supplies `NEXT_VERSION`. -2. `bazel-build-test` embeds that value in `maven.properties` and - `pom.properties`, archives `app.jar`, and records its SHA-256. -3. `bazel-docker-build` downloads that artifact, builds and pushes - `nvct-service-oss-bazel-validation` to the GitLab registry, pulls it back, - extracts `/usr/share/app.jar`, and compares its checksum and metadata with - the archived Bazel jar. -4. `bazel-pulse-scan` scans the isolated validation image. -5. `bazel-docker-push-ngc` is a manual job that reuses the existing NGC - publication path. +The monorepo uses `.github/workflows/bazel.yml`. There are no GitLab +`ENABLE_BAZEL_*` variables for this subtree. -An MR image tag remains `mr.<iid>-<commit-short-sha>`; a non-MR image uses -`NEXT_VERSION`. The separate validation image name prevents this proof from -overwriting the Maven-produced `nvct-service-oss` image. Verification evidence -is retained under the `bazel-docker-build` job artifacts. +The workflow detects Cloud Tasks or shared Java changes and selects the +appropriate service lane. The containerized fast lane excludes +`requires-docker` tests at query time. The per-service `bazel-docker` lane +receives Java 25 through `actions/setup-java`, uses the host Docker daemon, and +runs the complete Cloud Tasks test scope, including unit and Testcontainers +tests. Changes to nv-boot or shared Java tooling must also select Cloud Tasks +as a reverse-dependency validation target. -This publishes a container application product, not Maven-shaped jars or POMs. -There remains no Bazel Maven artifact publication path. +GitHub CI currently proves build and test behavior. Container publication and +layered NOTICE enforcement are later phases. Bazel never publishes +Maven-shaped project artifacts. ## Clean diff --git a/src/control-plane-services/cloud-tasks/nvct-service/Dockerfile b/src/control-plane-services/cloud-tasks/nvct-service/Dockerfile new file mode 100644 index 000000000..1c67e5514 --- /dev/null +++ b/src/control-plane-services/cloud-tasks/nvct-service/Dockerfile @@ -0,0 +1,29 @@ +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +# +# 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. +# Pull base image. +FROM nvcr.io/nvidia/distroless/java:25-jdk-v4.0.8 + +# Add the service jar +ARG APP_JAR=nvct-service/target/app.jar +COPY ${APP_JAR} /usr/share/app.jar + +# enable setting the ulimit to max on boot +ENV ULIMIT_FLAG=1 + +# use this instead of JAVA_OPTS +ENV JDK_JAVA_OPTIONS="-XX:MaxRAMPercentage=40.0 -XX:+EnableDynamicAgentLoading -Dreactor.netty.pool.maxIdleTime=30000 -Dreactor.netty.pool.maxConnections=500" + +WORKDIR /home/app +CMD ["java", "-jar", "/usr/share/app.jar"] diff --git a/src/libraries/java/nv-boot-parent/BAZEL.md b/src/libraries/java/nv-boot-parent/BAZEL.md index 0db1a11d5..051001e22 100644 --- a/src/libraries/java/nv-boot-parent/BAZEL.md +++ b/src/libraries/java/nv-boot-parent/BAZEL.md @@ -1,44 +1,45 @@ # Bazel Developer Guide -This repository supports Bazel alongside Maven during migration. Maven remains -the canonical build and publish path until the team explicitly cuts over. +nv-boot lives inside the `NVIDIA/nvcf` monorepo. Run every command in this +guide from the monorepo root. Maven remains available during coexistence, but +Bazel configuration, dependencies, locks, and CI are owned by the monorepo +root. ## Tooling -- Bazel: 9.1.1, via `.bazelversion` +- Bazel: 9.1.1 through Bazelisk honoring the root `.bazelversion` - Dependency mode: Bzlmod with `rules_jvm_external` - Java: 25 - Python: 3.11 through `rules_python` for Bazel NOTICE actions - Docker: required for Testcontainers-backed tests such as Cassandra tests -The Bazel build/test path uses Bazel-managed Java tooling for compilation and -tests. The CI image does not need `java` or `jar` on `PATH` for the opt-in -Bazel build/test job. +The root `.bazelrc` selects the local Java 25 JDK. The GitHub matrix image +provides Temurin 25 through `JAVA_HOME`; the Docker-capable lane uses +`actions/setup-java`. Local command examples use one portable cache location. Set it once per shell: ```bash -export BAZEL_OUTPUT_USER_ROOT="${TMPDIR:-/tmp}/nv-boot-parent-bazel-cache" +export BAZEL_OUTPUT_USER_ROOT="${TMPDIR:-/tmp}/nvcf-bazel-cache" ``` ## Understanding the Dependency Files -Bazel uses three top-level files for dependency declarations and locking. A +Bazel uses three monorepo-root files for dependency declarations and locking. A simple way to remember their responsibilities is: ```text -MODULE.bazel = what this repository wants +MODULE.bazel = what the whole monorepo wants maven_install.json = exact third-party Java artifacts that were resolved MODULE.bazel.lock = exact Bazel modules and module extensions that were resolved ``` ### `MODULE.bazel` -Developers edit this file. It declares the repository as a Bazel module and -contains inputs such as: +Developers edit the root `MODULE.bazel`. nv-boot does not have a nested module +file. The root file contains inputs such as: - `bazel_dep` entries for Bazel rules and tooling; -- overrides for Bazel source modules when needed; - Maven-compatible BOMs and third-party Java dependency roots supplied to `rules_jvm_external`; - the shared `nv_third_party_deps` hub configuration. @@ -65,7 +66,7 @@ Maven build, publish nv-boot artifacts, or make the Bazel outputs Maven-shaped. Maven does not normally have a direct checked-in equivalent to this dependency lockfile. -After changing BOMs, third-party roots, or versions in `MODULE.bazel`, +After changing BOMs, third-party roots, or versions in the root `MODULE.bazel`, regenerate it with: ```bash @@ -101,24 +102,22 @@ uses `asm-analysis` and `asm-util`. Those two unmanaged modules are explicitly aligned to 9.9 in `MODULE.bazel` so the shared hub does not contain a partially upgraded ASM runtime. -The commands below reuse `BAZEL_OUTPUT_USER_ROOT` so local builds do not fight -with other workspaces. `${TMPDIR:-/tmp}` works on macOS and Linux; the stable -project-specific suffix prevents cache collisions with other repositories. +The root `.bazel_downloader_config` maps external downloads to approved +mirrors. Bazel applies it through `.bazelrc`; nv-boot does not define a +subtree-specific downloader configuration. ## Shared Neutral Dependency Hub -`nv-boot-parent` exposes public Bazel source targets whose third-party labels -refer to one shared dependency repository: +nv-boot exposes Bazel source targets whose third-party labels refer to the +monorepo's one shared dependency repository: ```text @nv_third_party_deps ``` -The exact configured name is `nv_third_party_deps`, with underscores. Every -Bazel application that consumes nv-boot targets must use this same name for its -`rules_jvm_external` install. A different name, including -`nv-third-party-deps`, creates a different repository and does not satisfy the -labels exposed by nv-boot. +The exact configured name is `nv_third_party_deps`, with underscores. The root +`MODULE.bazel` defines it once. No library or application subtree defines +another `maven.install`. The name is intentionally neutral: @@ -127,38 +126,16 @@ The name is intentionally neutral: - it does not contain nv-boot libraries or application-owned libraries; - nv-boot and application code remain first-party Bazel source targets. -A downstream application's `MODULE.bazel` should follow this shape: - -```python -maven = use_extension("@rules_jvm_external//:extensions.bzl", "maven") -maven.install( - name = "nv_third_party_deps", - artifacts = [ - # Application-owned third-party roots only. - ], - boms = [ - # Application-owned BOMs, including the Spring Boot BOM as needed. - ], - known_contributing_modules = [ - "nv_boot_parent", - # Other Bazel modules that contribute to this same hub. - ], - lock_file = "//:maven_install.json", - ... -) -use_repo(maven, "nv_third_party_deps") -``` - -Bzlmod and `rules_jvm_external` then merge the upstream and application -contributions into one resolved graph. If an application creates a second hub, -its executable jar can contain duplicate or version-skewed libraries. Cloud -Tasks demonstrated this failure mode with an incompatible gRPC mix and a -218 MB two-hub app; the single shared hub produced the expected 142 MB app. +`rules_jvm_external` resolves the root Java dependency graph and exposes jar +targets through this hub. A coordinate in the hub is merely available; only a +BUILD dependency edge places it on a library or application's compile/runtime +classpath. This is how unrelated service dependencies stay out of nv-boot +targets even though the root lock contains all Java services. After changing third-party roots or versions, repin the shared hub: ```bash -REPIN=1 bazel --output_user_root="${TMPDIR:-/tmp}/<application>-bazel-cache" \ +REPIN=1 bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ run @nv_third_party_deps//:pin ``` @@ -173,30 +150,31 @@ whole cache. ## Build -Build the entire repository: +Build the entire nv-boot subtree: ```bash -bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" build //... +bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ + build //src/libraries/java/nv-boot-parent/... ``` Build one module: ```bash bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ - build //nv-boot-starter-core:all + build //src/libraries/java/nv-boot-parent/nv-boot-starter-core:all ``` Build one module's Bazel-native Java library target: ```bash bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ - build //nv-boot-starter-core:nv_boot_starter_core + build //src/libraries/java/nv-boot-parent/nv-boot-starter-core:nv_boot_starter_core ``` The compiled library jar is written under `bazel-bin/<module>/`, for example: ```text -bazel-bin/nv-boot-starter-core/libnv_boot_starter_core.jar +bazel-bin/src/libraries/java/nv-boot-parent/nv-boot-starter-core/libnv_boot_starter_core.jar ``` The Bazel path does not generate POMs, Maven-named jars, sources jars for Maven @@ -208,7 +186,7 @@ Run all tests without reusing cached test results: ```bash bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ - test //... \ + test //src/libraries/java/nv-boot-parent/... \ --cache_test_results=no \ --test_output=errors ``` @@ -217,7 +195,7 @@ Run all tests and stream logs to the terminal: ```bash bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ - test //... \ + test //src/libraries/java/nv-boot-parent/... \ --cache_test_results=no \ --test_output=streamed ``` @@ -226,7 +204,7 @@ Run one module's tests: ```bash bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ - test //nv-boot-starter-core:tests \ + test //src/libraries/java/nv-boot-parent/nv-boot-starter-core:tests \ --cache_test_results=no \ --test_output=errors ``` @@ -235,7 +213,7 @@ Run one test class: ```bash bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ - test //nv-boot-starter-core:tests \ + test //src/libraries/java/nv-boot-parent/nv-boot-starter-core:tests \ --cache_test_results=no \ --test_output=streamed \ --test_arg='--exclude-classname=^(?!com\.nvidia\.boot\.core\.env\.BootCoreEnvironmentPostProcessorTest$).*' @@ -245,7 +223,7 @@ Run one test method: ```bash bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ - test //nv-boot-starter-core:tests \ + test //src/libraries/java/nv-boot-parent/nv-boot-starter-core:tests \ --cache_test_results=no \ --test_output=streamed \ --test_arg='--exclude-classname=^(?!com\.nvidia\.boot\.core\.env\.BootCoreEnvironmentPostProcessorTest$).*' \ @@ -261,13 +239,15 @@ test macro runs JUnit ConsoleLauncher directly. Test logs are under: ```text -bazel-testlogs/<module>/tests/test.log -bazel-testlogs/<module>/tests/test.outputs/junit/TEST-junit-jupiter.xml +bazel-testlogs/src/libraries/java/nv-boot-parent/<module>/tests/test.log +bazel-testlogs/src/libraries/java/nv-boot-parent/<module>/tests/test.outputs/junit/TEST-junit-jupiter.xml ``` The Jupiter XML contains the real Java testcases and is the report published by -GitLab. The nearby `bazel-testlogs/<module>/tests/test.xml` describes Bazel's -single outer `sh_test` wrapper and must not be used as the JUnit report. +GitHub Actions. The nearby +`bazel-testlogs/src/libraries/java/nv-boot-parent/<module>/tests/test.xml` +describes Bazel's single outer `sh_test` wrapper and must not be used as the +JUnit report. ## Coverage @@ -280,7 +260,7 @@ Run one module's tests and generate its JaCoCo report: ```bash bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ - test //nv-boot-starter-core:tests \ + test //src/libraries/java/nv-boot-parent/nv-boot-starter-core:tests \ --cache_test_results=no \ --test_output=errors ``` @@ -288,21 +268,21 @@ bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ Open the generated HTML report: ```text -bazel-testlogs/nv-boot-starter-core/tests/test.outputs/index.html +bazel-testlogs/src/libraries/java/nv-boot-parent/nv-boot-starter-core/tests/test.outputs/index.html ``` The same test output directory also contains: ```text -bazel-testlogs/nv-boot-starter-core/tests/test.outputs/jacoco.xml -bazel-testlogs/nv-boot-starter-core/tests/test.outputs/jacoco.exec +bazel-testlogs/src/libraries/java/nv-boot-parent/nv-boot-starter-core/tests/test.outputs/jacoco.xml +bazel-testlogs/src/libraries/java/nv-boot-parent/nv-boot-starter-core/tests/test.outputs/jacoco.exec ``` Run all module tests and generate one JaCoCo report per test target: ```bash bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ - test //... \ + test //src/libraries/java/nv-boot-parent/... \ --cache_test_results=no \ --test_output=errors ``` @@ -310,10 +290,10 @@ bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ Per-module reports are written under each test target's output directory: ```text -bazel-testlogs/<module>/tests/test.outputs/junit/TEST-junit-jupiter.xml -bazel-testlogs/<module>/tests/test.outputs/index.html -bazel-testlogs/<module>/tests/test.outputs/jacoco.xml -bazel-testlogs/<module>/tests/test.outputs/jacoco.exec +bazel-testlogs/src/libraries/java/nv-boot-parent/<module>/tests/test.outputs/junit/TEST-junit-jupiter.xml +bazel-testlogs/src/libraries/java/nv-boot-parent/<module>/tests/test.outputs/index.html +bazel-testlogs/src/libraries/java/nv-boot-parent/<module>/tests/test.outputs/jacoco.xml +bazel-testlogs/src/libraries/java/nv-boot-parent/<module>/tests/test.outputs/jacoco.exec ``` For CI/Sonar Java coverage, publish the generated `jacoco.xml` files and pass @@ -333,11 +313,11 @@ standard Bazel `java_test` targets. In that case, run: ```bash bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ - coverage //... \ + coverage //src/libraries/java/nv-boot-parent/... \ --cache_test_results=no \ --test_output=errors \ --combined_report=lcov \ - --instrumentation_filter=//nv-boot + --instrumentation_filter=//src/libraries/java/nv-boot-parent ``` For standard `java_test` targets, the combined LCOV report is written to: @@ -349,7 +329,7 @@ bazel-out/_coverage/_coverage_report.dat Convert the combined LCOV report to SonarQube generic coverage XML: ```bash -python3 tools/bazel/lcov_to_sonar_generic.py \ +python3 tools/bazel/java/lcov_to_sonar_generic.py \ --input bazel-out/_coverage/_coverage_report.dat \ --output "${TMPDIR:-/tmp}/nv-boot-parent-sonar-coverage.xml" ``` @@ -363,100 +343,41 @@ sonar.coverageReportPaths=<path-to-sonar-generic-coverage.xml> ## License And Notice -During Maven/Bazel coexistence, the root `NOTICE` file remains the canonical -third-party notice artifact. It is generated by Bazel-native tooling from: - -- explicit production dependency roots in `tools/bazel/notice_roots.json`; -- the resolved dependency graph in `maven_install.json`; -- checked-in upstream artifact metadata in - `tools/bazel/notice_metadata.json`. - -The root list intentionally excludes test-only and provided dependencies. The -generator excludes first-party `com.nvidia.boot` artifacts and does not call -Maven, `license-maven-plugin`, or read project `pom.xml` files. - -Bazel invokes the generator through the `//tools/bazel:generate_notice_tool` -`py_binary`, so build actions use the Bazel-declared Python runtime instead of -looking up host `python3`. Explicit roots missing from `maven_install.json` are -errors. Application runtime scans also reject a packaged jar when its path -version differs from the lockfile version. - -Refresh `NOTICE` and the checked-in artifact metadata after dependency changes: - -```bash -bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ - run //:generate_notice -- --update-metadata --write -``` - -The `--update-metadata` path reads upstream artifact POMs from the local Maven -cache first, then from the repositories configured in `maven_install.json` when -needed. Commit both `NOTICE` and `tools/bazel/notice_metadata.json` after a -refresh. +The root owns the generator under `//tools/bazel/java`; nv-boot owns its +checked-in `NOTICE`, `notice_roots.json`, and `notice_metadata.json` under: -Run a developer check without changing files: - -```bash -bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ - run //:generate_notice -- --check -``` - -Validate the checked-in `NOTICE` file: - -```bash -bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ - test //tools/bazel:notice_check_test \ - --cache_test_results=no \ - --test_output=errors +```text +//src/libraries/java/nv-boot-parent ``` -Build a Bazel output copy for CI artifact collection: +The generator is Bazel-native: it does not run Maven, invoke +`license-maven-plugin`, or read project POMs. The final layered NOTICE and +OSRB integration is Phase 4 work. The current diagnostic target is: ```bash bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ - build //:third_party_notice + run //src/libraries/java/nv-boot-parent:generate_notice -- --check ``` -The generated copy is written to: +At the end of Phase 3 the checked-in nv-boot NOTICE is stale for +`com.google.code.findbugs:jsr305` (`2.0.1` versus resolved `3.0.2`). Phase 4 +will finish deterministic regenerate/check targets, shared metadata reuse by +services, and license-grouped OSRB delta output. Do not describe NOTICE as a +required passing CI gate until that work is complete. -```text -bazel-bin/THIRD_PARTY_NOTICE -``` +## GitHub CI -This is not a `rules_license` integration. The build and test path is stable -because the human-readable license/name/homepage metadata is checked in, while -the explicit refresh command updates that metadata from upstream Maven artifact -POMs when dependencies change. +The monorepo uses `.github/workflows/bazel.yml`; there is no GitLab +`ENABLE_BAZEL_BUILD` variable for this subtree. The workflow detects nv-boot, +shared Java tooling, root dependency, or consumer changes and selects: -## CI Opt-In +- the containerized fast lane for tests that do not require Docker; +- the per-service Docker lane for complete Testcontainers scopes; and +- reverse-dependency consumer validation, including Cloud Tasks when nv-boot + changes. -Maven remains the default CI build and publish path during coexistence. Bazel CI -is opt-in with: - -```yaml -variables: - ENABLE_BAZEL_BUILD: "true" -``` - -The CI handoff and GitLab job shape are documented in -`bazel-enablement/ci-bazel-handoff.md`. This branch also has a project-local -`.gitlab-ci.yml` trial job named `bazel-build-test` guarded by that flag. -Bazel CI builds and tests the Bazel target graph; it does not publish -Maven-shaped artifacts to URM/Artifactory. - -For CI jobs that run Testcontainers-backed tests, pass Docker environment -variables into Bazel's restricted test environment: - -```bash -bazel --output_user_root=/tmp/nv-boot-parent-bazel-cache \ - test \ - --cache_test_results=no \ - --test_output=errors \ - --test_env=DOCKER_HOST \ - --test_env=DOCKER_TLS_VERIFY \ - --test_env=DOCKER_TLS_CERTDIR \ - --test_env=DOCKER_CERT_PATH \ - //... -``` +GitHub CI builds and tests Bazel source targets. It does not publish +Maven-shaped nv-boot artifacts. ## Build And Test Like `mvn clean install` @@ -466,17 +387,16 @@ For a Maven-like local validation loop: bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" clean bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ - test //... \ + test //src/libraries/java/nv-boot-parent/... \ --cache_test_results=no \ --test_output=errors bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ - build //... + build //src/libraries/java/nv-boot-parent/... ``` -`bazel test //...` runs tests and builds what those tests need. Run -`bazel build //...` when you also want all non-test Bazel outputs, including -the module library jars and generated third-party NOTICE. +`bazel test` builds what the tests need. Run the scoped `bazel build` when you +also want non-test library outputs. ## Maven Coexistence @@ -488,8 +408,8 @@ During coexistence: - Maven remains the canonical remote publish path for Maven consumers. - Bazel build/test remains the canonical path for Bazel consumers. -- Downstream Bazel applications should consume `nv-boot-parent` through Bzlmod - source dependencies, such as `git_override`, not through URM Maven artifacts. +- Applications in this monorepo consume nv-boot through direct labels under + `//src/libraries/java/nv-boot-parent/...`. - Bazel does not generate, install, or publish Maven-shaped project artifacts. ## Dependency Updates @@ -498,11 +418,12 @@ When a module needs a new external dependency: 1. Add the dependency close to the module that uses it, in that module's `BUILD.bazel`. -2. Add the coordinate to `MODULE.bazel` if Bazel does not already resolve it. +2. Add the coordinate to the root `MODULE.bazel` if Bazel does not already + resolve it. 3. Prefer versionless coordinates when a BOM manages the version. 4. Add an explicit version only for intentional pins or CVE overrides. -5. If the dependency is shipped by a starter, add its direct production root - to `tools/bazel/notice_roots.json`. +5. If the dependency is shipped by a starter, update the nv-boot NOTICE roots + during the Phase 4 NOTICE workflow. 6. Repin and validate: ```bash @@ -510,7 +431,7 @@ REPIN=1 bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ run @nv_third_party_deps//:pin bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ - test //tools/bazel:notice_check_test \ + test //src/libraries/java/nv-boot-parent/... \ --cache_test_results=no \ --test_output=errors ``` @@ -523,75 +444,36 @@ unrelated transitive path. For a new nv-boot module during coexistence: -1. Add the Maven module to root `pom.xml`. +1. Add the Maven module to + `src/libraries/java/nv-boot-parent/pom.xml`. 2. Add the module's Maven `pom.xml`. 3. Add the module to `nv-boot-bom/pom.xml` if downstream apps should get its version through the BOM. -4. Add `new-module/BUILD.bazel`. +4. Add + `src/libraries/java/nv-boot-parent/new-module/BUILD.bazel`. 5. Add `nv_boot_library(...)`. 6. Add `nv_boot_library_test(...)` if the module has tests, with `coverage_library` set to the module's `nv_boot_library(...)` target. -7. Add any new shipped third-party roots to - `tools/bazel/notice_roots.json`. -8. Update migration docs or release docs if they list modules explicitly. +7. Update the nv-boot NOTICE roots during the Phase 4 NOTICE workflow. +8. Update architecture or release docs if they list modules explicitly. For an internal-only Maven module, skip the Maven BOM entry. Its Bazel target is still an ordinary source library target. ## Reusable Bazel Enablement Skills -The reusable Codex Bazel enablement skills are versioned in this repo at: - -```text -bazel-enablement/skills/maven-parent-bazel-enablement -bazel-enablement/skills/spring-boot-app-bazel-enablement -``` - -Keep these repo-owned copies centralized in `nv-boot-parent`. Application -repositories should reference the appropriate skill in their handoff docs, -but should not duplicate the skill directory. - -Use `maven-parent-bazel-enablement` for parent/aggregator and shared-library -repositories such as nv-boot-parent or nv-boot-managed-parent. Use -`spring-boot-app-bazel-enablement` for application reactors such as Cloud Tasks -or cloud-functions that must build/test libraries, package an executable app, -generate runtime NOTICE, and validate Docker/CI. - -Codex loads the installed runtime copy from: +The imported monorepo subtree deliberately does not contain +`bazel-enablement` history or skill files. The authoritative skill source +remains in the standalone nv-boot repository, with installed copies at: ```text $HOME/.codex/skills/maven-parent-bazel-enablement $HOME/.codex/skills/spring-boot-app-bazel-enablement ``` -Treat the repo copy as the source of truth. After updating and committing the -repo copy, sync it into the installed skill location: - -```bash -rsync -a --delete \ - bazel-enablement/skills/maven-parent-bazel-enablement/ \ - "${HOME}/.codex/skills/maven-parent-bazel-enablement/" - -rsync -a --delete \ - bazel-enablement/skills/spring-boot-app-bazel-enablement/ \ - "${HOME}/.codex/skills/spring-boot-app-bazel-enablement/" -``` - -Verify the two copies are aligned: - -```bash -diff -ru \ - bazel-enablement/skills/maven-parent-bazel-enablement \ - "${HOME}/.codex/skills/maven-parent-bazel-enablement" - -diff -ru \ - bazel-enablement/skills/spring-boot-app-bazel-enablement \ - "${HOME}/.codex/skills/spring-boot-app-bazel-enablement" -``` - -Until this is automated, periodically sync repo to installed copy after skill -changes so future Bazel enablement work, such as `nv-boot-managed-parent`, uses -the latest validated workflow. +Use `spring-boot-app-bazel-enablement` with its GitHub monorepo profile for +other OSS/self-hosted Spring Boot subtrees. Do not recreate skill directories +inside this monorepo. ## Bazel-Native Status @@ -605,9 +487,8 @@ Most of the migration work is Bazel-native: - build and test use Bazel Java targets and `nv_boot_library_test`, not `maven-surefire-plugin`; - coverage is generated by the Bazel test wrapper, not `jacoco-maven-plugin`; -- License/NOTICE generation uses `tools/bazel/notice_roots.json`, - `maven_install.json`, and `tools/bazel/notice_metadata.json`, not - `license-maven-plugin`; +- NOTICE generation is Bazel-native and is being completed as the layered + monorepo Phase 4 workflow, not through `license-maven-plugin`; - module library jars are ordinary Bazel Java outputs; - POM generation, Maven-shaped artifact creation, local Maven installation, and remote Maven deployment are absent from the Bazel toolchain. @@ -627,7 +508,7 @@ toolchain code: - the Bazel test wrapper preserves the JUnit exit status and then invokes the JaCoCo CLI to generate HTML and XML reports; - reports remain under - `bazel-testlogs/<module>/tests/test.outputs`; + `bazel-testlogs/src/libraries/java/nv-boot-parent/<module>/tests/test.outputs`; - focused test selection and ordinary console logging continue to use the JUnit Platform Console Launcher. @@ -647,17 +528,14 @@ separate cutover decision. Do not recreate it inside Bazel. ## Current Gaps - Maven remains the canonical publishing path during coexistence. -- Downstream Maven consumption from URM has been validated with `cloud-tasks` - using version `15665e3b`. - The Bazel remote publish/deploy bridge was removed after validation because the target Bazel-native model is source-target consumption, not URM Maven artifact consumption. - Parent/BOM POM artifacts still come from the Maven build and checked-in `pom.xml` files during coexistence. -- A project-local opt-in Bazel CI job is available; the shared CI template has - not been updated yet. -- License/NOTICE is covered by Bazel-native generation and checks from - `maven_install.json`, explicit production roots, and checked-in artifact - metadata. A formal `rules_license` integration is not implemented. +- GitHub CI build/test selection is integrated; layered NOTICE enforcement and + license-grouped OSRB delta output remain Phase 4. +- The root dependency graph currently warns that protobuf expected + `libprotoc 33.4` but selected `33.0`. - Downstream Spring Boot executable app packaging belongs to downstream app migration, not to `nv-boot-parent`. From 8b33aeccb12f2ce70d73f99060c1c98cefe745f2 Mon Sep 17 00:00:00 2001 From: Sanjay Saxena <sasaxena@nvidia.com> Date: Thu, 23 Jul 2026 17:25:10 -0700 Subject: [PATCH 25/29] feat(bazel): formalize layered Java NOTICE generation --- rules/java/BUILD.bazel | 3 +- rules/java/notice.bzl | 203 +++ .../cloud-tasks/BAZEL.md | 95 +- .../cloud-tasks/BUILD.bazel | 45 +- src/control-plane-services/cloud-tasks/NOTICE | 2 +- .../cloud-tasks/generate_notice.sh | 21 - .../cloud-tasks/notice_metadata.json | 1491 +---------------- src/libraries/java/nv-boot-parent/BAZEL.md | 95 +- src/libraries/java/nv-boot-parent/BUILD.bazel | 53 +- src/libraries/java/nv-boot-parent/NOTICE | 2 +- .../java/nv-boot-parent/notice_metadata.json | 2 +- tools/bazel/java/BUILD.bazel | 19 +- tools/bazel/java/generate_notice.py | 271 ++- tools/bazel/java/generate_notice_test.py | 86 + tools/bazel/java/license_aliases.json | 23 + tools/bazel/java/notice_diff_test.sh | 10 + 16 files changed, 865 insertions(+), 1556 deletions(-) create mode 100644 rules/java/notice.bzl delete mode 100755 src/control-plane-services/cloud-tasks/generate_notice.sh create mode 100644 tools/bazel/java/generate_notice_test.py create mode 100644 tools/bazel/java/license_aliases.json create mode 100755 tools/bazel/java/notice_diff_test.sh diff --git a/rules/java/BUILD.bazel b/rules/java/BUILD.bazel index 65778e0d4..b77e2d446 100644 --- a/rules/java/BUILD.bazel +++ b/rules/java/BUILD.bazel @@ -1,2 +1,3 @@ -# Root-owned reusable Java Starlark APIs. See defs.bzl, spring.bzl, proto.bzl. +# Root-owned reusable Java Starlark APIs. See defs.bzl, notice.bzl, proto.bzl, +# and spring.bzl. package(default_visibility = ["//visibility:public"]) diff --git a/rules/java/notice.bzl b/rules/java/notice.bzl new file mode 100644 index 000000000..f2cebb706 --- /dev/null +++ b/rules/java/notice.bzl @@ -0,0 +1,203 @@ +"""Shared NOTICE generation rules for Java components in the NVCF monorepo.""" + +load("@rules_shell//shell:sh_test.bzl", _sh_test = "sh_test") + +_DIFF_TEST = "//tools/bazel/java:notice_diff_test.sh" +_GENERATOR = "//tools/bazel/java:generate_notice_tool" +_LICENSE_ALIASES = "//tools/bazel/java:license_aliases.json" +_MAVEN_INSTALL = "//:maven_install.json" + + +def _workspace_path(label): + if label.startswith(":"): + return native.package_name() + "/" + label[1:] + if label.startswith("//"): + package_and_name = label[2:].split(":") + if len(package_and_name) != 2: + fail("Expected an explicit //package:file label, got %s" % label) + return package_and_name[0] + "/" + package_and_name[1] + fail("Expected a local or absolute source-file label, got %s" % label) + + +def _action_arguments( + metadata, + shared_metadata, + root_manifests, + runtime_target, + first_party_groups): + arguments = [ + '--maven-install "$(location %s)"' % _MAVEN_INSTALL, + '--metadata "$(location %s)"' % metadata, + '--license-aliases "$(location %s)"' % _LICENSE_ALIASES, + ] + for label in shared_metadata: + arguments.append('--shared-metadata "$(location %s)"' % label) + for label in root_manifests: + arguments.append('--root-manifest "$(location %s)"' % label) + if runtime_target: + arguments.append('--runtime-jar "$(location %s)"' % runtime_target) + for group in first_party_groups: + arguments.append("--first-party-group %s" % group) + return arguments + + +def _update_arguments( + checked_notice, + metadata, + shared_metadata, + root_manifests, + runtime_target, + first_party_groups): + arguments = [ + '--maven-install "$${workspace}/maven_install.json"', + '--metadata "$${workspace}/%s"' % _workspace_path(metadata), + '--notice "$${workspace}/%s"' % _workspace_path(checked_notice), + '--license-aliases "$${workspace}/tools/bazel/java/license_aliases.json"', + ] + for label in shared_metadata: + arguments.append( + '--shared-metadata "$${workspace}/%s"' % _workspace_path(label) + ) + for label in root_manifests: + arguments.append( + '--root-manifest "$${workspace}/%s"' % _workspace_path(label) + ) + if runtime_target: + arguments.append('--runtime-jar "$(location %s)"' % runtime_target) + for group in first_party_groups: + arguments.append("--first-party-group %s" % group) + return arguments + + +def nvcf_notice( + checked_notice, + metadata, + shared_metadata = [], + root_manifests = [], + runtime_target = None, + first_party_groups = [], + name = "third_party_notice", + inventory_name = "runtime_inventory"): + """Generates and checks one component's complete third-party NOTICE.""" + if bool(root_manifests) == bool(runtime_target): + fail("Set exactly one of root_manifests or runtime_target") + + srcs = [ + _LICENSE_ALIASES, + _MAVEN_INSTALL, + checked_notice, + metadata, + ] + shared_metadata + root_manifests + if runtime_target: + srcs.append(runtime_target) + + action_arguments = _action_arguments( + metadata, + shared_metadata, + root_manifests, + runtime_target, + first_party_groups, + ) + native.genrule( + name = name, + srcs = srcs, + outs = [ + "THIRD_PARTY_NOTICE", + "runtime_inventory.json", + ], + cmd = """ +set -eu +"$(execpath {generator})" \ + {arguments} \ + --output "$(@D)/THIRD_PARTY_NOTICE" \ + --inventory-output "$(@D)/runtime_inventory.json" \ + --write +""".format( + arguments = " \\\n ".join(action_arguments), + generator = _GENERATOR, + ), + tools = [_GENERATOR], + ) + + native.filegroup( + name = inventory_name, + srcs = [":runtime_inventory.json"], + ) + + _sh_test( + name = "notice_check_test", + srcs = [_DIFF_TEST], + args = [ + "$(location :THIRD_PARTY_NOTICE)", + "$(location %s)" % checked_notice, + ], + data = [ + ":THIRD_PARTY_NOTICE", + checked_notice, + ], + size = "small", + ) + + update_arguments = _update_arguments( + checked_notice, + metadata, + shared_metadata, + root_manifests, + runtime_target, + first_party_groups, + ) + native.genrule( + name = "generate_notice", + srcs = srcs, + outs = ["generate_notice.sh"], + cmd = """ +cat > "$@" <<'EOF' +#!/usr/bin/env bash +set -euo pipefail + +workspace="$${{BUILD_WORKSPACE_DIRECTORY:?Run this command through bazel run}}" +exec "$(execpath {generator})" \ + {arguments} \ + "$$@" +EOF +chmod +x "$@" +""".format( + arguments = " \\\n ".join(update_arguments), + generator = _GENERATOR, + ), + executable = True, + tools = [_GENERATOR], + ) + + +def nvcf_notice_delta( + inventory, + baseline_inventories, + name = "osrb_dependency_delta"): + """Generates machine-readable and license-grouped OSRB dependency deltas.""" + baseline_arguments = [ + '--baseline-inventory "$(location %s)"' % label + for label in baseline_inventories + ] + native.genrule( + name = name, + srcs = [inventory] + baseline_inventories, + outs = [ + name + ".json", + name + ".md", + ], + cmd = """ +set -eu +"$(execpath {generator})" \ + --delta-inventory "$(location {inventory})" \ + {baselines} \ + --delta-json-output "$(@D)/{name}.json" \ + --delta-markdown-output "$(@D)/{name}.md" +""".format( + baselines = " \\\n ".join(baseline_arguments), + generator = _GENERATOR, + inventory = inventory, + name = name, + ), + tools = [_GENERATOR], + ) diff --git a/src/control-plane-services/cloud-tasks/BAZEL.md b/src/control-plane-services/cloud-tasks/BAZEL.md index e80f1c62d..c4f7398ee 100644 --- a/src/control-plane-services/cloud-tasks/BAZEL.md +++ b/src/control-plane-services/cloud-tasks/BAZEL.md @@ -591,31 +591,98 @@ the selected test execution. ## License/NOTICE Generation -NOTICE generation is the Bazel-native replacement for the aggregate -third-party inventory previously produced through `license-maven-plugin`. It -must derive the shipped coordinates from the jars nested in: +The monorepo has two NOTICE levels: + +1. Cloud Tasks' Bazel target generates and checks the complete third-party + NOTICE for the application. +2. The existing root `tools/scripts/collect-notices` process records the Cloud + Tasks NOTICE path in the monorepo's top-level `NOTICE`. + +Cloud Tasks derives its actual shipped coordinates from the jars nested in: ```text //src/control-plane-services/cloud-tasks/nvct-service:app ``` -The root owns the generator under `//tools/bazel/java`; Cloud Tasks owns its -checked-in `NOTICE` and service-specific `notice_metadata.json`. The generator -does not read project POM files and does not invoke Maven. +The root owns the shared rule and generator under `//rules/java` and +`//tools/bazel/java`. Cloud Tasks owns: + +```text +src/control-plane-services/cloud-tasks/NOTICE +src/control-plane-services/cloud-tasks/notice_metadata.json +``` + +Cloud Tasks does not need `notice_roots.json`: the executable `app.jar` is the +authoritative runtime closure. Its metadata file contains only dependencies +additional to nv-boot. The shared rule reads common metadata from: + +```text +//src/libraries/java/nv-boot-parent:notice_metadata.json +``` -The final layered NOTICE integration is Phase 4 work. The current diagnostic -target is intentionally tagged `manual` and exposes the metadata gap: +It selects only shared entries actually present in `app.jar`, merges the +service-owned entries, and fails on missing, conflicting, or duplicated +metadata. The generated Cloud Tasks NOTICE is complete and standalone; it is +not a concatenation of or link to nv-boot's NOTICE. + +Regenerate the checked-in NOTICE: + +```bash +bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ + run //src/control-plane-services/cloud-tasks:generate_notice -- --write +``` + +When a new service runtime dependency lacks metadata, refresh only the +service-owned metadata and NOTICE: ```bash bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ - build //src/control-plane-services/cloud-tasks:third_party_notice + run //src/control-plane-services/cloud-tasks:generate_notice -- \ + --update-metadata --write +``` + +The metadata-update mode may read an upstream dependency POM from the local +Maven cache or configured artifact repository to obtain its published name, +URL, and license declaration. That is metadata discovery only; it does not run +a Maven project build. + +Check NOTICE drift exactly as CI does: + +```bash +bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ + test //src/control-plane-services/cloud-tasks:notice_check_test \ + --cache_test_results=no \ + --test_output=errors +``` + +Build the complete runtime inventory and NVBug-ready dependency delta: + +```bash +bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ + build \ + //src/control-plane-services/cloud-tasks:cloud_tasks_runtime_inventory \ + //src/control-plane-services/cloud-tasks:osrb_dependency_delta + +cat bazel-bin/src/control-plane-services/cloud-tasks/runtime_inventory.json +cat bazel-bin/src/control-plane-services/cloud-tasks/osrb_dependency_delta.json +cat bazel-bin/src/control-plane-services/cloud-tasks/osrb_dependency_delta.md +``` + +The delta compares exact versioned Cloud Tasks runtime coordinates with the +nv-boot runtime inventory and groups only the additional dependencies by +normalized license. Use that Markdown as the dependency portion of the NVBug +6040004 approval comment. Ambiguous and custom license expressions remain +explicit for OSRB review. + +After component NOTICE files are updated, validate the existing monorepo root +rollup: + +```bash +./tools/ci/check-license ``` -At the end of Phase 3 this reports missing service/shared metadata, beginning -with `aopalliance:aopalliance:1.0`. Do not treat the current target or -checked-in NOTICE as the completed CI contract. Phase 4 will add deterministic -regenerate, check, complete-runtime NOTICE, and license-grouped OSRB-delta -commands here. +`check-license` requires Bash 4 or newer. To intentionally refresh the +top-level path rollup, run `./tools/scripts/update-license`. ## GitHub CI diff --git a/src/control-plane-services/cloud-tasks/BUILD.bazel b/src/control-plane-services/cloud-tasks/BUILD.bazel index c3e04bac2..707c00733 100644 --- a/src/control-plane-services/cloud-tasks/BUILD.bazel +++ b/src/control-plane-services/cloud-tasks/BUILD.bazel @@ -1,5 +1,5 @@ -load("@rules_shell//shell:sh_binary.bzl", "sh_binary") load("//rules/java:defs.bzl", "nvct_workspace_runfiles") +load("//rules/java:notice.bzl", "nvcf_notice", "nvcf_notice_delta") package(default_visibility = ["//visibility:public"]) @@ -9,7 +9,6 @@ package(default_visibility = ["//visibility:public"]) exports_files([ "NOTICE", "notice_metadata.json", - "generate_notice.sh", ]) filegroup( @@ -32,38 +31,20 @@ nvct_workspace_runfiles( strip_prefix = "src/control-plane-services/cloud-tasks/", ) -genrule( - name = "third_party_notice", - srcs = [ - "//:maven_install.json", - "//src/control-plane-services/cloud-tasks/nvct-service:app", - ":notice_metadata.json", - "//tools/bazel/java:generate_notice.py", +nvcf_notice( + checked_notice = ":NOTICE", + first_party_groups = ["com.nvidia.nvct"], + inventory_name = "cloud_tasks_runtime_inventory", + metadata = ":notice_metadata.json", + runtime_target = "//src/control-plane-services/cloud-tasks/nvct-service:app", + shared_metadata = [ + "//src/libraries/java/nv-boot-parent:notice_metadata.json", ], - outs = ["THIRD_PARTY_NOTICE"], - # Excluded from wildcard builds: the service NOTICE metadata does not yet - # cover every transitive resolved through the single merged root hub (for - # example aopalliance:aopalliance:1.0). Reconciling service NOTICE metadata - # against the merged root closure is the layered-NOTICE work deferred to the - # shared-tooling pilot in the monorepo Java architecture. Run explicitly - # with `bazel build //src/control-plane-services/cloud-tasks:third_party_notice`. - tags = ["manual"], - cmd = """ -python3 "$(location //tools/bazel/java:generate_notice.py)" \ - --maven-install "$(location //:maven_install.json)" \ - --metadata "$(location :notice_metadata.json)" \ - --runtime-jar "$(location //src/control-plane-services/cloud-tasks/nvct-service:app)" \ - --first-party-group com.nvidia.nvct \ - --output "$@" \ - --write -""", ) -sh_binary( - name = "generate_notice", - srcs = [":generate_notice.sh"], - data = [ - "//src/control-plane-services/cloud-tasks/nvct-service:app", - "//tools/bazel/java:generate_notice.py", +nvcf_notice_delta( + baseline_inventories = [ + "//src/libraries/java/nv-boot-parent:runtime_inventory.json", ], + inventory = ":runtime_inventory.json", ) diff --git a/src/control-plane-services/cloud-tasks/NOTICE b/src/control-plane-services/cloud-tasks/NOTICE index 4989aae6f..f667592de 100644 --- a/src/control-plane-services/cloud-tasks/NOTICE +++ b/src/control-plane-services/cloud-tasks/NOTICE @@ -1,5 +1,6 @@ Lists of 258 third-party dependencies. + (Public Domain) AOP alliance (aopalliance:aopalliance:1.0 - http://aopalliance.sourceforge.net) (Apache License, Version 2.0) LZ4 Java Compression (at.yawk.lz4:lz4-java:1.10.3 - https://github.com/yawkat/lz4-java) (EPL-2.0) (LGPL-2.1-only) Logback Classic Module (ch.qos.logback:logback-classic:1.5.34 - http://logback.qos.ch) (EPL-2.0) (LGPL-2.1-only) Logback Core Module (ch.qos.logback:logback-core:1.5.34 - http://logback.qos.ch) @@ -47,7 +48,6 @@ Lists of 258 third-party dependencies. (Apache-2.0) Apache Commons Codec (commons-codec:commons-codec:1.19.0 - https://commons.apache.org/proper/commons-codec/) (Apache-2.0) Apache Commons IO (commons-io:commons-io:2.20.0 - https://commons.apache.org/proper/commons-io/) (Apache-2.0) Apache Commons Logging (commons-logging:commons-logging:1.3.6 - https://commons.apache.org/proper/commons-logging/) - (Apache License 2.0) Metrics Core (io.dropwizard.metrics:metrics-core:4.1.18 - https://metrics.dropwizard.io) (Apache 2.0) io.grpc:grpc-api (io.grpc:grpc-api:1.63.0 - https://github.com/grpc/grpc-java) (Apache 2.0) io.grpc:grpc-context (io.grpc:grpc-context:1.63.0 - https://github.com/grpc/grpc-java) (Apache 2.0) io.grpc:grpc-core (io.grpc:grpc-core:1.63.0 - https://github.com/grpc/grpc-java) diff --git a/src/control-plane-services/cloud-tasks/generate_notice.sh b/src/control-plane-services/cloud-tasks/generate_notice.sh deleted file mode 100755 index d8a90dd43..000000000 --- a/src/control-plane-services/cloud-tasks/generate_notice.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/env bash -set -euo pipefail - -workspace="${BUILD_WORKSPACE_DIRECTORY:?Run this command through bazel run}" -runfiles_root="${RUNFILES_DIR:-${0}.runfiles}" - -generator="$(find "${runfiles_root}" -path '*/tools/bazel/generate_notice.py' -print -quit)" -runtime_jar="$(find "${runfiles_root}" -path '*/nvct-service/app.jar' -print -quit)" - -if [[ -z "${generator}" || -z "${runtime_jar}" ]]; then - printf 'Could not locate NOTICE generator or app.jar in runfiles\n' >&2 - exit 1 -fi - -exec python3 "${generator}" \ - --maven-install "${workspace}/maven_install.json" \ - --metadata "${workspace}/src/control-plane-services/cloud-tasks/notice_metadata.json" \ - --notice "${workspace}/src/control-plane-services/cloud-tasks/NOTICE" \ - --runtime-jar "${runtime_jar}" \ - --first-party-group com.nvidia.nvct \ - "$@" diff --git a/src/control-plane-services/cloud-tasks/notice_metadata.json b/src/control-plane-services/cloud-tasks/notice_metadata.json index 6901a7e48..75cdbe18e 100644 --- a/src/control-plane-services/cloud-tasks/notice_metadata.json +++ b/src/control-plane-services/cloud-tasks/notice_metadata.json @@ -1,28 +1,5 @@ { "artifacts": { - "at.yawk.lz4:lz4-java:1.10.3": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "LZ4 Java Compression", - "url": "https://github.com/yawkat/lz4-java" - }, - "ch.qos.logback:logback-classic:1.5.34": { - "licenses": [ - "EPL-2.0", - "LGPL-2.1-only" - ], - "name": "Logback Classic Module", - "url": "http://logback.qos.ch" - }, - "ch.qos.logback:logback-core:1.5.34": { - "licenses": [ - "EPL-2.0", - "LGPL-2.1-only" - ], - "name": "Logback Core Module", - "url": "http://logback.qos.ch" - }, "com.bucket4j:bucket4j-core:8.10.1": { "licenses": [ "The Apache Software License, Version 2.0" @@ -37,145 +14,6 @@ "name": "bucket4j_jdk17-core", "url": "http://github.com/bucket4j/bucket4j/bucket4j_jdk17-core" }, - "com.datastax.oss:native-protocol:1.5.2": { - "licenses": [ - "Apache 2" - ], - "name": "An implementation of the Apache Cassandra\u00ae native protocol", - "url": "https://github.com/datastax/native-protocol" - }, - "com.fasterxml.jackson.core:jackson-annotations:2.21": { - "licenses": [ - "The Apache Software License, Version 2.0" - ], - "name": "Jackson-annotations", - "url": "https://github.com/FasterXML/jackson" - }, - "com.fasterxml.jackson.core:jackson-core:2.21.4": { - "licenses": [ - "The Apache Software License, Version 2.0" - ], - "name": "Jackson-core", - "url": "https://github.com/FasterXML/jackson-core" - }, - "com.fasterxml.jackson.core:jackson-databind:2.21.4": { - "licenses": [ - "The Apache Software License, Version 2.0" - ], - "name": "jackson-databind", - "url": "https://github.com/FasterXML/jackson" - }, - "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.21.4": { - "licenses": [ - "The Apache Software License, Version 2.0" - ], - "name": "Jackson-dataformat-YAML", - "url": "https://github.com/FasterXML/jackson-dataformats-text" - }, - "com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.21.4": { - "licenses": [ - "The Apache Software License, Version 2.0" - ], - "name": "Jackson datatype: JSR310", - "url": "https://github.com/FasterXML/jackson-modules-java8" - }, - "com.fasterxml:classmate:1.7.3": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "ClassMate", - "url": "https://github.com/FasterXML/java-classmate" - }, - "com.github.ben-manes.caffeine:caffeine:3.2.4": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "Caffeine cache", - "url": "https://github.com/ben-manes/caffeine" - }, - "com.github.ben-manes.caffeine:guava:3.2.4": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "Caffeine cache", - "url": "https://github.com/ben-manes/caffeine" - }, - "com.github.java-json-tools:btf:1.3": { - "licenses": [ - "Lesser General Public License, version 3 or greater", - "Apache Software License, version 2.0" - ], - "name": "btf", - "url": "https://github.com/java-json-tools/btf" - }, - "com.github.java-json-tools:jackson-coreutils:2.0": { - "licenses": [ - "Lesser General Public License, version 3 or greater", - "Apache Software License, version 2.0" - ], - "name": "jackson-coreutils", - "url": "https://github.com/java-json-tools/jackson-coreutils" - }, - "com.github.java-json-tools:json-patch:1.13": { - "licenses": [ - "Lesser General Public License, version 3 or greater", - "Apache Software License, version 2.0" - ], - "name": "json-patch", - "url": "https://github.com/java-json-tools/json-patch" - }, - "com.github.java-json-tools:msg-simple:1.2": { - "licenses": [ - "Lesser General Public License, version 3 or greater", - "Apache Software License, version 2.0" - ], - "name": "msg-simple", - "url": "https://github.com/java-json-tools/msg-simple" - }, - "com.github.jnr:jffi:1.2.16": { - "licenses": [ - "The Apache Software License, Version 2.0" - ], - "name": "jffi", - "url": "http://github.com/jnr/jffi" - }, - "com.github.jnr:jnr-constants:0.10.3": { - "licenses": [ - "The Apache Software License, Version 2.0" - ], - "name": "jnr-constants", - "url": "http://github.com/jnr/jnr-constants" - }, - "com.github.jnr:jnr-ffi:2.1.7": { - "licenses": [ - "The Apache Software License, Version 2.0" - ], - "name": "jnr-ffi", - "url": "http://github.com/jnr/jnr-ffi" - }, - "com.github.jnr:jnr-posix:3.1.15": { - "licenses": [ - "Eclipse Public License - v 2.0", - "GNU General Public License Version 2", - "GNU Lesser General Public License Version 2.1" - ], - "name": "jnr-posix", - "url": "http://nexus.sonatype.org/oss-repository-hosting.html" - }, - "com.github.jnr:jnr-x86asm:1.0.2": { - "licenses": [ - "MIT License" - ], - "name": "jnr-x86asm", - "url": "http://github.com/jnr/jnr-x86asm" - }, - "com.github.stephenc.jcip:jcip-annotations:1.0-1": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "JCIP Annotations under Apache License", - "url": "http://stephenc.github.com/jcip-annotations" - }, "com.google.android:annotations:4.1.1.4": { "licenses": [ "Apache 2.0" @@ -197,13 +35,6 @@ "name": "proto-google-common-protos", "url": "https://github.com/googleapis/sdk-platform-java" }, - "com.google.code.findbugs:jsr305:3.0.2": { - "licenses": [ - "The Apache Software License, Version 2.0" - ], - "name": "FindBugs-jsr305", - "url": "http://findbugs.sourceforge.net/" - }, "com.google.code.gson:gson:2.13.2": { "licenses": [ "Apache-2.0" @@ -211,41 +42,6 @@ "name": "Gson", "url": "https://github.com/google/gson" }, - "com.google.errorprone:error_prone_annotations:2.49.0": { - "licenses": [ - "Apache 2.0" - ], - "name": "error-prone annotations", - "url": "https://errorprone.info" - }, - "com.google.guava:failureaccess:1.0.3": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "Guava InternalFutureFailureAccess and InternalFutures", - "url": "https://github.com/google/guava" - }, - "com.google.guava:guava:33.6.0-jre": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "Guava: Google Core Libraries for Java", - "url": "https://github.com/google/guava" - }, - "com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava": { - "licenses": [ - "The Apache Software License, Version 2.0" - ], - "name": "Guava ListenableFuture only", - "url": "https://github.com/google/guava" - }, - "com.google.j2objc:j2objc-annotations:3.1": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "J2ObjC Annotations", - "url": "https://github.com/google/j2objc/" - }, "com.google.protobuf:protobuf-java-util:4.33.4": { "licenses": [ "BSD-3-Clause" @@ -260,34 +56,6 @@ "name": "Protocol Buffers [Core]", "url": "https://developers.google.com/protocol-buffers/" }, - "com.nimbusds:content-type:2.3": { - "licenses": [ - "The Apache Software License, Version 2.0" - ], - "name": "Nimbus Content Type", - "url": "https://bitbucket.org/connect2id/nimbus-content-type" - }, - "com.nimbusds:lang-tag:1.7": { - "licenses": [ - "The Apache Software License, Version 2.0" - ], - "name": "Nimbus LangTag", - "url": "https://bitbucket.org/connect2id/nimbus-language-tags" - }, - "com.nimbusds:nimbus-jose-jwt:10.4": { - "licenses": [ - "The Apache Software License, Version 2.0" - ], - "name": "Nimbus JOSE+JWT", - "url": "https://bitbucket.org/connect2id/nimbus-jose-jwt" - }, - "com.nimbusds:oauth2-oidc-sdk:11.26.1": { - "licenses": [ - "Apache License, version 2.0" - ], - "name": "OAuth 2.0 SDK with OpenID Connect extensions", - "url": "https://bitbucket.org/connect2id/oauth-2.0-sdk-with-openid-connect-extensions" - }, "com.squareup.okhttp3:logging-interceptor:4.12.0": { "licenses": [ "The Apache Software License, Version 2.0" @@ -302,13 +70,6 @@ "name": "okhttp", "url": "https://square.github.io/okhttp/" }, - "com.squareup.okio:okio-jvm:3.16.1": { - "licenses": [ - "The Apache Software License, Version 2.0" - ], - "name": "okio", - "url": "https://github.com/square/okio/" - }, "com.squareup.okio:okio:3.6.0": { "licenses": [ "The Apache Software License, Version 2.0" @@ -316,20 +77,6 @@ "name": "okio", "url": "https://github.com/square/okio/" }, - "com.typesafe:config:1.4.1": { - "licenses": [ - "Apache-2.0" - ], - "name": "config", - "url": "https://github.com/lightbend/config" - }, - "commons-codec:commons-codec:1.19.0": { - "licenses": [ - "Apache-2.0" - ], - "name": "Apache Commons Codec", - "url": "https://commons.apache.org/proper/commons-codec/" - }, "commons-io:commons-io:2.20.0": { "licenses": [ "Apache-2.0" @@ -337,13 +84,6 @@ "name": "Apache Commons IO", "url": "https://commons.apache.org/proper/commons-io/" }, - "commons-logging:commons-logging:1.3.6": { - "licenses": [ - "Apache-2.0" - ], - "name": "Apache Commons Logging", - "url": "https://commons.apache.org/proper/commons-logging/" - }, "io.dropwizard.metrics:metrics-core:4.1.18": { "licenses": [ "Apache License 2.0" @@ -491,41 +231,6 @@ "name": "client-java", "url": "https://github.com/kubernetes-client/java" }, - "io.micrometer:context-propagation:1.2.1": { - "licenses": [ - "The Apache Software License, Version 2.0" - ], - "name": "context-propagation", - "url": "https://github.com/micrometer-metrics/context-propagation" - }, - "io.micrometer:micrometer-commons:1.16.6": { - "licenses": [ - "The Apache Software License, Version 2.0" - ], - "name": "micrometer-commons", - "url": "https://github.com/micrometer-metrics/micrometer" - }, - "io.micrometer:micrometer-core:1.16.6": { - "licenses": [ - "The Apache Software License, Version 2.0" - ], - "name": "micrometer-core", - "url": "https://github.com/micrometer-metrics/micrometer" - }, - "io.micrometer:micrometer-jakarta9:1.16.6": { - "licenses": [ - "The Apache Software License, Version 2.0" - ], - "name": "micrometer-jakarta9", - "url": "https://github.com/micrometer-metrics/micrometer" - }, - "io.micrometer:micrometer-observation:1.16.6": { - "licenses": [ - "The Apache Software License, Version 2.0" - ], - "name": "micrometer-observation", - "url": "https://github.com/micrometer-metrics/micrometer" - }, "io.micrometer:micrometer-registry-prometheus:1.16.6": { "licenses": [ "The Apache Software License, Version 2.0" @@ -533,389 +238,122 @@ "name": "micrometer-registry-prometheus", "url": "https://github.com/micrometer-metrics/micrometer" }, - "io.micrometer:micrometer-tracing-bridge-otel:1.6.6": { - "licenses": [ - "The Apache Software License, Version 2.0" - ], - "name": "micrometer-tracing-bridge-otel", - "url": "https://github.com/micrometer-metrics/tracing" - }, - "io.micrometer:micrometer-tracing:1.6.6": { - "licenses": [ - "The Apache Software License, Version 2.0" - ], - "name": "micrometer-tracing", - "url": "https://github.com/micrometer-metrics/tracing" - }, - "io.netty:netty-buffer:4.2.15.Final": { + "io.netty:netty-codec-native-quic:4.2.15.Final": { "licenses": [ "Apache License, Version 2.0" ], - "name": "Netty/Buffer", + "name": "Netty/Codec/Native/Quic", "url": "https://netty.io/" }, - "io.netty:netty-codec-base:4.2.15.Final": { + "io.netty:netty-resolver-dns-classes-macos:4.2.15.Final": { "licenses": [ "Apache License, Version 2.0" ], - "name": "Netty/Codec/Base", + "name": "Netty/Resolver/DNS/Classes/MacOS", "url": "https://netty.io/" }, - "io.netty:netty-codec-classes-quic:4.2.15.Final": { + "io.netty:netty-resolver-dns-native-macos:4.2.15.Final": { "licenses": [ "Apache License, Version 2.0" ], - "name": "Netty/Codec/Classes/Quic", + "name": "Netty/Resolver/DNS/Native/MacOS", "url": "https://netty.io/" }, - "io.netty:netty-codec-compression:4.2.15.Final": { + "io.netty:netty-transport-classes-epoll:4.2.15.Final": { "licenses": [ "Apache License, Version 2.0" ], - "name": "Netty/Codec/Compression", + "name": "Netty/Transport/Classes/Epoll", "url": "https://netty.io/" }, - "io.netty:netty-codec-dns:4.2.15.Final": { + "io.netty:netty-transport-native-epoll:4.2.15.Final": { "licenses": [ "Apache License, Version 2.0" ], - "name": "Netty/Codec/DNS", + "name": "Netty/Transport/Native/Epoll", "url": "https://netty.io/" }, - "io.netty:netty-codec-http2:4.2.15.Final": { + "io.perfmark:perfmark-api:0.26.0": { "licenses": [ - "Apache License, Version 2.0" + "Apache 2.0" ], - "name": "Netty/Codec/HTTP2", - "url": "https://netty.io/" + "name": "perfmark:perfmark-api", + "url": "https://github.com/perfmark/perfmark" }, - "io.netty:netty-codec-http3:4.2.15.Final": { + "io.prometheus:prometheus-metrics-config:1.4.3": { "licenses": [ - "Apache License, Version 2.0" + "The Apache Software License, Version 2.0" ], - "name": "Netty/Codec/Http3", - "url": "https://netty.io/netty-codec-http3/" + "name": "Prometheus Metrics Config", + "url": "http://github.com/prometheus/client_java" }, - "io.netty:netty-codec-http:4.2.15.Final": { + "io.prometheus:prometheus-metrics-core:1.4.3": { "licenses": [ - "Apache License, Version 2.0" + "The Apache Software License, Version 2.0" ], - "name": "Netty/Codec/HTTP", - "url": "https://netty.io/" + "name": "Prometheus Metrics Core", + "url": "http://github.com/prometheus/client_java" }, - "io.netty:netty-codec-native-quic:4.2.15.Final": { + "io.prometheus:prometheus-metrics-exposition-formats:1.4.3": { "licenses": [ - "Apache License, Version 2.0" + "The Apache Software License, Version 2.0" ], - "name": "Netty/Codec/Native/Quic", - "url": "https://netty.io/" + "name": "Prometheus Metrics Exposition Formats", + "url": "http://github.com/prometheus/client_java" }, - "io.netty:netty-codec-socks:4.2.15.Final": { + "io.prometheus:prometheus-metrics-exposition-textformats:1.4.3": { "licenses": [ - "Apache License, Version 2.0" + "The Apache Software License, Version 2.0" ], - "name": "Netty/Codec/Socks", - "url": "https://netty.io/" + "name": "Prometheus Metrics Exposition Text Formats", + "url": "http://github.com/prometheus/client_java" }, - "io.netty:netty-common:4.2.15.Final": { + "io.prometheus:prometheus-metrics-model:1.4.3": { "licenses": [ - "Apache License, Version 2.0" + "The Apache Software License, Version 2.0" ], - "name": "Netty/Common", - "url": "https://netty.io/" + "name": "Prometheus Metrics Model", + "url": "http://github.com/prometheus/client_java" }, - "io.netty:netty-handler-proxy:4.2.15.Final": { + "io.prometheus:prometheus-metrics-tracer-common:1.4.3": { "licenses": [ - "Apache License, Version 2.0" + "The Apache Software License, Version 2.0" ], - "name": "Netty/Handler/Proxy", - "url": "https://netty.io/" + "name": "Prometheus Metrics Tracer Common", + "url": "http://github.com/prometheus/client_java" }, - "io.netty:netty-handler:4.2.15.Final": { + "io.swagger:swagger-annotations:1.6.16": { "licenses": [ - "Apache License, Version 2.0" + "Apache License 2.0" ], - "name": "Netty/Handler", - "url": "https://netty.io/" + "name": "swagger-annotations", + "url": "https://github.com/swagger-api/swagger-core" }, - "io.netty:netty-resolver-dns-classes-macos:4.2.15.Final": { + "jakarta.servlet:jakarta.servlet-api:6.1.0": { "licenses": [ - "Apache License, Version 2.0" + "EPL 2.0", + "GPL2 w/ CPE" ], - "name": "Netty/Resolver/DNS/Classes/MacOS", - "url": "https://netty.io/" + "name": "Jakarta Servlet", + "url": "https://projects.eclipse.org/projects/ee4j.servlet" }, - "io.netty:netty-resolver-dns-native-macos:4.2.15.Final": { + "javax.annotation:javax.annotation-api:1.3.2": { "licenses": [ - "Apache License, Version 2.0" + "CDDL + GPLv2 with classpath exception" ], - "name": "Netty/Resolver/DNS/Native/MacOS", - "url": "https://netty.io/" + "name": "javax.annotation API", + "url": "http://jcp.org/en/jsr/detail?id=250" }, - "io.netty:netty-resolver-dns:4.2.15.Final": { + "net.devh:grpc-common-spring-boot:3.1.0.RELEASE": { "licenses": [ - "Apache License, Version 2.0" + "Apache 2.0" ], - "name": "Netty/Resolver/DNS", - "url": "https://netty.io/" + "name": "gRPC Spring Boot Starter", + "url": "https://github.com/yidongnan/grpc-spring-boot-starter" }, - "io.netty:netty-resolver:4.2.15.Final": { + "net.devh:grpc-server-spring-boot-starter:3.1.0.RELEASE": { "licenses": [ - "Apache License, Version 2.0" - ], - "name": "Netty/Resolver", - "url": "https://netty.io/" - }, - "io.netty:netty-transport-classes-epoll:4.2.15.Final": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "Netty/Transport/Classes/Epoll", - "url": "https://netty.io/" - }, - "io.netty:netty-transport-native-epoll:4.2.15.Final": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "Netty/Transport/Native/Epoll", - "url": "https://netty.io/" - }, - "io.netty:netty-transport-native-unix-common:4.2.15.Final": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "Netty/Transport/Native/Unix/Common", - "url": "https://netty.io/" - }, - "io.netty:netty-transport:4.2.15.Final": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "Netty/Transport", - "url": "https://netty.io/" - }, - "io.opentelemetry.semconv:opentelemetry-semconv:1.37.0": { - "licenses": [ - "The Apache License, Version 2.0" - ], - "name": "OpenTelemetry Semantic Conventions Java", - "url": "https://github.com/open-telemetry/semantic-conventions-java" - }, - "io.opentelemetry:opentelemetry-api:1.55.0": { - "licenses": [ - "The Apache License, Version 2.0" - ], - "name": "OpenTelemetry Java", - "url": "https://github.com/open-telemetry/opentelemetry-java" - }, - "io.opentelemetry:opentelemetry-common:1.55.0": { - "licenses": [ - "The Apache License, Version 2.0" - ], - "name": "OpenTelemetry Java", - "url": "https://github.com/open-telemetry/opentelemetry-java" - }, - "io.opentelemetry:opentelemetry-context:1.55.0": { - "licenses": [ - "The Apache License, Version 2.0" - ], - "name": "OpenTelemetry Java", - "url": "https://github.com/open-telemetry/opentelemetry-java" - }, - "io.opentelemetry:opentelemetry-extension-trace-propagators:1.55.0": { - "licenses": [ - "The Apache License, Version 2.0" - ], - "name": "OpenTelemetry Java", - "url": "https://github.com/open-telemetry/opentelemetry-java" - }, - "io.opentelemetry:opentelemetry-sdk-common:1.55.0": { - "licenses": [ - "The Apache License, Version 2.0" - ], - "name": "OpenTelemetry Java", - "url": "https://github.com/open-telemetry/opentelemetry-java" - }, - "io.opentelemetry:opentelemetry-sdk-logs:1.55.0": { - "licenses": [ - "The Apache License, Version 2.0" - ], - "name": "OpenTelemetry Java", - "url": "https://github.com/open-telemetry/opentelemetry-java" - }, - "io.opentelemetry:opentelemetry-sdk-metrics:1.55.0": { - "licenses": [ - "The Apache License, Version 2.0" - ], - "name": "OpenTelemetry Java", - "url": "https://github.com/open-telemetry/opentelemetry-java" - }, - "io.opentelemetry:opentelemetry-sdk-trace:1.55.0": { - "licenses": [ - "The Apache License, Version 2.0" - ], - "name": "OpenTelemetry Java", - "url": "https://github.com/open-telemetry/opentelemetry-java" - }, - "io.opentelemetry:opentelemetry-sdk:1.55.0": { - "licenses": [ - "The Apache License, Version 2.0" - ], - "name": "OpenTelemetry Java", - "url": "https://github.com/open-telemetry/opentelemetry-java" - }, - "io.perfmark:perfmark-api:0.26.0": { - "licenses": [ - "Apache 2.0" - ], - "name": "perfmark:perfmark-api", - "url": "https://github.com/perfmark/perfmark" - }, - "io.projectreactor.netty:reactor-netty-core:1.3.6": { - "licenses": [ - "The Apache Software License, Version 2.0" - ], - "name": "Core functionality for the Reactor Netty library", - "url": "https://github.com/reactor/reactor-netty" - }, - "io.projectreactor.netty:reactor-netty-http:1.3.6": { - "licenses": [ - "The Apache Software License, Version 2.0" - ], - "name": "HTTP functionality for the Reactor Netty library", - "url": "https://github.com/reactor/reactor-netty" - }, - "io.projectreactor:reactor-core:3.8.6": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "Non-Blocking Reactive Foundation for the JVM", - "url": "https://github.com/reactor/reactor-core" - }, - "io.prometheus:prometheus-metrics-config:1.4.3": { - "licenses": [ - "The Apache Software License, Version 2.0" - ], - "name": "Prometheus Metrics Config", - "url": "http://github.com/prometheus/client_java" - }, - "io.prometheus:prometheus-metrics-core:1.4.3": { - "licenses": [ - "The Apache Software License, Version 2.0" - ], - "name": "Prometheus Metrics Core", - "url": "http://github.com/prometheus/client_java" - }, - "io.prometheus:prometheus-metrics-exposition-formats:1.4.3": { - "licenses": [ - "The Apache Software License, Version 2.0" - ], - "name": "Prometheus Metrics Exposition Formats", - "url": "http://github.com/prometheus/client_java" - }, - "io.prometheus:prometheus-metrics-exposition-textformats:1.4.3": { - "licenses": [ - "The Apache Software License, Version 2.0" - ], - "name": "Prometheus Metrics Exposition Text Formats", - "url": "http://github.com/prometheus/client_java" - }, - "io.prometheus:prometheus-metrics-model:1.4.3": { - "licenses": [ - "The Apache Software License, Version 2.0" - ], - "name": "Prometheus Metrics Model", - "url": "http://github.com/prometheus/client_java" - }, - "io.prometheus:prometheus-metrics-tracer-common:1.4.3": { - "licenses": [ - "The Apache Software License, Version 2.0" - ], - "name": "Prometheus Metrics Tracer Common", - "url": "http://github.com/prometheus/client_java" - }, - "io.swagger.core.v3:swagger-annotations-jakarta:2.2.47": { - "licenses": [ - "Apache License 2.0" - ], - "name": "swagger-annotations-jakarta", - "url": "https://github.com/swagger-api/swagger-core" - }, - "io.swagger.core.v3:swagger-core-jakarta:2.2.47": { - "licenses": [ - "Apache License 2.0" - ], - "name": "swagger-core-jakarta", - "url": "https://github.com/swagger-api/swagger-core" - }, - "io.swagger.core.v3:swagger-models-jakarta:2.2.47": { - "licenses": [ - "Apache License 2.0" - ], - "name": "swagger-models-jakarta", - "url": "https://github.com/swagger-api/swagger-core" - }, - "io.swagger:swagger-annotations:1.6.16": { - "licenses": [ - "Apache License 2.0" - ], - "name": "swagger-annotations", - "url": "https://github.com/swagger-api/swagger-core" - }, - "jakarta.activation:jakarta.activation-api:2.1.4": { - "licenses": [ - "EDL 1.0" - ], - "name": "Jakarta Activation API", - "url": "https://github.com/jakartaee/jaf-api" - }, - "jakarta.annotation:jakarta.annotation-api:3.0.0": { - "licenses": [ - "EPL 2.0", - "GPL2 w/ CPE" - ], - "name": "Jakarta Annotations API", - "url": "https://projects.eclipse.org/projects/ee4j.ca" - }, - "jakarta.servlet:jakarta.servlet-api:6.1.0": { - "licenses": [ - "EPL 2.0", - "GPL2 w/ CPE" - ], - "name": "Jakarta Servlet", - "url": "https://projects.eclipse.org/projects/ee4j.servlet" - }, - "jakarta.validation:jakarta.validation-api:3.1.1": { - "licenses": [ - "Apache License 2.0" - ], - "name": "Jakarta Validation API", - "url": "https://beanvalidation.org" - }, - "jakarta.xml.bind:jakarta.xml.bind-api:4.0.5": { - "licenses": [ - "Eclipse Distribution License - v 1.0" - ], - "name": "Jakarta XML Binding API", - "url": "https://github.com/jakartaee/jaxb-api" - }, - "javax.annotation:javax.annotation-api:1.3.2": { - "licenses": [ - "CDDL + GPLv2 with classpath exception" - ], - "name": "javax.annotation API", - "url": "http://jcp.org/en/jsr/detail?id=250" - }, - "net.devh:grpc-common-spring-boot:3.1.0.RELEASE": { - "licenses": [ - "Apache 2.0" - ], - "name": "gRPC Spring Boot Starter", - "url": "https://github.com/yidongnan/grpc-spring-boot-starter" - }, - "net.devh:grpc-server-spring-boot-starter:3.1.0.RELEASE": { - "licenses": [ - "Apache 2.0" + "Apache 2.0" ], "name": "gRPC Spring Boot Starter", "url": "https://github.com/yidongnan/grpc-spring-boot-starter" @@ -941,48 +379,6 @@ "name": "net.javacrumbs.shedlock:shedlock-spring", "url": "http://nexus.sonatype.org/oss-repository-hosting.html" }, - "net.minidev:accessors-smart:2.6.0": { - "licenses": [ - "The Apache Software License, Version 2.0" - ], - "name": "ASM based accessors helper used by json-smart", - "url": "https://urielch.github.io/" - }, - "net.minidev:json-smart:2.6.0": { - "licenses": [ - "The Apache Software License, Version 2.0" - ], - "name": "JSON Small and Fast Parser", - "url": "https://urielch.github.io/" - }, - "org.apache.cassandra:java-driver-core:4.19.3": { - "licenses": [ - "Apache 2" - ], - "name": "Apache Cassandra Java Driver - core", - "url": "https://github.com/datastax/java-driver" - }, - "org.apache.cassandra:java-driver-guava-shaded:4.19.3": { - "licenses": [ - "Apache 2" - ], - "name": "Apache Cassandra Java Driver - guava shaded dep", - "url": "https://github.com/datastax/java-driver" - }, - "org.apache.cassandra:java-driver-metrics-micrometer:4.19.3": { - "licenses": [ - "Apache 2" - ], - "name": "Apache Cassandra Java Driver - Metrics - Micrometer", - "url": "https://github.com/datastax/java-driver" - }, - "org.apache.cassandra:java-driver-query-builder:4.19.3": { - "licenses": [ - "Apache 2" - ], - "name": "Apache Cassandra Java Driver - query builder", - "url": "https://github.com/datastax/java-driver" - }, "org.apache.commons:commons-collections4:4.5.0": { "licenses": [ "Apache-2.0" @@ -997,27 +393,6 @@ "name": "Apache Commons Compress", "url": "https://commons.apache.org/proper/commons-compress/" }, - "org.apache.commons:commons-lang3:3.20.0": { - "licenses": [ - "Apache-2.0" - ], - "name": "Apache Commons Lang", - "url": "https://commons.apache.org/proper/commons-lang/" - }, - "org.apache.logging.log4j:log4j-api:2.25.4": { - "licenses": [ - "Apache-2.0" - ], - "name": "Apache Log4j API", - "url": "https://logging.apache.org/log4j/2.x/" - }, - "org.apache.logging.log4j:log4j-to-slf4j:2.25.4": { - "licenses": [ - "Apache-2.0" - ], - "name": "Log4j API to SLF4J Adapter", - "url": "https://logging.apache.org/log4j/2.x/" - }, "org.apache.tomcat.embed:tomcat-embed-core:11.0.22": { "licenses": [ "Apache License, Version 2.0" @@ -1025,13 +400,6 @@ "name": "tomcat-embed-core", "url": "https://tomcat.apache.org/" }, - "org.apache.tomcat.embed:tomcat-embed-el:11.0.22": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "tomcat-embed-el", - "url": "https://tomcat.apache.org/" - }, "org.apache.tomcat.embed:tomcat-embed-websocket:11.0.22": { "licenses": [ "Apache License, Version 2.0" @@ -1060,13 +428,6 @@ "name": "Bouncy Castle PKIX, CMS, EAC, TSP, PKCS, OCSP, CMP, and CRMF APIs", "url": "https://www.bouncycastle.org/download/bouncy-castle-java/" }, - "org.bouncycastle:bcprov-jdk18on:1.84": { - "licenses": [ - "Bouncy Castle Licence" - ], - "name": "Bouncy Castle Provider", - "url": "https://www.bouncycastle.org/download/bouncy-castle-java/" - }, "org.bouncycastle:bcutil-jdk18on:1.80.2": { "licenses": [ "Bouncy Castle Licence" @@ -1088,28 +449,6 @@ "name": "Animal Sniffer Annotations", "url": "https://www.mojohaus.org/animal-sniffer" }, - "org.hdrhistogram:HdrHistogram:2.2.2": { - "licenses": [ - "Public Domain, per Creative Commons CC0", - "BSD-2-Clause" - ], - "name": "HdrHistogram", - "url": "http://hdrhistogram.github.io/HdrHistogram/" - }, - "org.hibernate.validator:hibernate-validator:9.0.1.Final": { - "licenses": [ - "Apache License 2.0" - ], - "name": "Hibernate Validator Engine", - "url": "https://hibernate.org/validator" - }, - "org.jboss.logging:jboss-logging:3.6.3.Final": { - "licenses": [ - "Apache License 2.0" - ], - "name": "JBoss Logging 3", - "url": "https://www.jboss.org" - }, "org.jetbrains.kotlin:kotlin-stdlib-jdk7:2.2.21": { "licenses": [ "Apache-2.0" @@ -1124,420 +463,42 @@ "name": "Kotlin Stdlib Jdk8", "url": "https://kotlinlang.org/" }, - "org.jetbrains.kotlin:kotlin-stdlib:2.2.21": { + "org.springframework.boot:spring-boot-starter-aspectj:4.0.7": { "licenses": [ - "Apache-2.0" + "Apache License, Version 2.0" ], - "name": "Kotlin Stdlib", - "url": "https://kotlinlang.org/" + "name": "spring-boot-starter-aspectj", + "url": "https://spring.io/projects/spring-boot" }, - "org.jetbrains:annotations:17.0.0": { + "org.springframework.boot:spring-boot-starter-tomcat-runtime:4.0.7": { "licenses": [ - "The Apache Software License, Version 2.0" + "Apache License, Version 2.0" ], - "name": "JetBrains Java Annotations", - "url": "https://github.com/JetBrains/java-annotations" + "name": "spring-boot-starter-tomcat-runtime", + "url": "https://spring.io/projects/spring-boot" }, - "org.jspecify:jspecify:1.0.0": { + "org.springframework.boot:spring-boot-starter-tomcat:4.0.7": { "licenses": [ - "The Apache License, Version 2.0" + "Apache License, Version 2.0" ], - "name": "JSpecify annotations", - "url": "http://jspecify.org/" + "name": "spring-boot-starter-tomcat", + "url": "https://spring.io/projects/spring-boot" }, - "org.latencyutils:LatencyUtils:2.0.3": { + "org.springframework.boot:spring-boot-starter-webmvc:4.0.7": { "licenses": [ - "Public Domain, per Creative Commons CC0" + "Apache License, Version 2.0" ], - "name": "LatencyUtils", - "url": "http://latencyutils.github.io/LatencyUtils/" + "name": "spring-boot-starter-webmvc", + "url": "https://spring.io/projects/spring-boot" }, - "org.ow2.asm:asm-analysis:9.9": { + "org.springframework.boot:spring-boot-tomcat:4.0.7": { "licenses": [ - "BSD-3-Clause" + "Apache License, Version 2.0" ], - "name": "asm-analysis", - "url": "http://asm.ow2.io/" + "name": "spring-boot-tomcat", + "url": "https://spring.io/projects/spring-boot" }, - "org.ow2.asm:asm-commons:9.9": { - "licenses": [ - "BSD-3-Clause" - ], - "name": "asm-commons", - "url": "http://asm.ow2.io/" - }, - "org.ow2.asm:asm-tree:9.9": { - "licenses": [ - "BSD-3-Clause" - ], - "name": "asm-tree", - "url": "http://asm.ow2.io/" - }, - "org.ow2.asm:asm-util:9.9": { - "licenses": [ - "BSD-3-Clause" - ], - "name": "asm-util", - "url": "http://asm.ow2.io/" - }, - "org.ow2.asm:asm:9.9": { - "licenses": [ - "BSD-3-Clause" - ], - "name": "asm", - "url": "http://asm.ow2.io/" - }, - "org.reactivestreams:reactive-streams:1.0.4": { - "licenses": [ - "MIT-0" - ], - "name": "reactive-streams", - "url": "http://www.reactive-streams.org/" - }, - "org.slf4j:jul-to-slf4j:2.0.18": { - "licenses": [ - "MIT" - ], - "name": "JUL to SLF4J bridge", - "url": "http://www.slf4j.org" - }, - "org.slf4j:slf4j-api:2.0.18": { - "licenses": [ - "MIT" - ], - "name": "SLF4J API Module", - "url": "http://www.slf4j.org" - }, - "org.springdoc:springdoc-openapi-starter-common:3.0.3": { - "licenses": [ - "The Apache License, Version 2.0" - ], - "name": "springdoc-openapi-starter-common", - "url": "https://springdoc.org/" - }, - "org.springdoc:springdoc-openapi-starter-webflux-api:3.0.3": { - "licenses": [ - "The Apache License, Version 2.0" - ], - "name": "springdoc-openapi-starter-webflux-api", - "url": "https://springdoc.org/" - }, - "org.springdoc:springdoc-openapi-starter-webmvc-api:3.0.3": { - "licenses": [ - "The Apache License, Version 2.0" - ], - "name": "springdoc-openapi-starter-webmvc-api", - "url": "https://springdoc.org/" - }, - "org.springframework.boot:spring-boot-actuator-autoconfigure:4.0.7": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "spring-boot-actuator-autoconfigure", - "url": "https://spring.io/projects/spring-boot" - }, - "org.springframework.boot:spring-boot-actuator:4.0.7": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "spring-boot-actuator", - "url": "https://spring.io/projects/spring-boot" - }, - "org.springframework.boot:spring-boot-autoconfigure:4.0.7": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "spring-boot-autoconfigure", - "url": "https://spring.io/projects/spring-boot" - }, - "org.springframework.boot:spring-boot-cassandra:4.0.7": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "spring-boot-cassandra", - "url": "https://spring.io/projects/spring-boot" - }, - "org.springframework.boot:spring-boot-data-cassandra:4.0.7": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "spring-boot-data-cassandra", - "url": "https://spring.io/projects/spring-boot" - }, - "org.springframework.boot:spring-boot-data-commons:4.0.7": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "spring-boot-data-commons", - "url": "https://spring.io/projects/spring-boot" - }, - "org.springframework.boot:spring-boot-health:4.0.7": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "spring-boot-health", - "url": "https://spring.io/projects/spring-boot" - }, - "org.springframework.boot:spring-boot-http-client:4.0.7": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "spring-boot-http-client", - "url": "https://spring.io/projects/spring-boot" - }, - "org.springframework.boot:spring-boot-http-codec:4.0.7": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "spring-boot-http-codec", - "url": "https://spring.io/projects/spring-boot" - }, - "org.springframework.boot:spring-boot-http-converter:4.0.7": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "spring-boot-http-converter", - "url": "https://spring.io/projects/spring-boot" - }, - "org.springframework.boot:spring-boot-jackson:4.0.7": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "spring-boot-jackson", - "url": "https://spring.io/projects/spring-boot" - }, - "org.springframework.boot:spring-boot-micrometer-metrics:4.0.7": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "spring-boot-micrometer-metrics", - "url": "https://spring.io/projects/spring-boot" - }, - "org.springframework.boot:spring-boot-micrometer-observation:4.0.7": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "spring-boot-micrometer-observation", - "url": "https://spring.io/projects/spring-boot" - }, - "org.springframework.boot:spring-boot-micrometer-tracing-opentelemetry:4.0.7": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "spring-boot-micrometer-tracing-opentelemetry", - "url": "https://spring.io/projects/spring-boot" - }, - "org.springframework.boot:spring-boot-micrometer-tracing:4.0.7": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "spring-boot-micrometer-tracing", - "url": "https://spring.io/projects/spring-boot" - }, - "org.springframework.boot:spring-boot-opentelemetry:4.0.7": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "spring-boot-opentelemetry", - "url": "https://spring.io/projects/spring-boot" - }, - "org.springframework.boot:spring-boot-persistence:4.0.7": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "spring-boot-persistence", - "url": "https://spring.io/projects/spring-boot" - }, - "org.springframework.boot:spring-boot-security-oauth2-client:4.0.7": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "spring-boot-security-oauth2-client", - "url": "https://spring.io/projects/spring-boot" - }, - "org.springframework.boot:spring-boot-security-oauth2-resource-server:4.0.7": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "spring-boot-security-oauth2-resource-server", - "url": "https://spring.io/projects/spring-boot" - }, - "org.springframework.boot:spring-boot-security:4.0.7": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "spring-boot-security", - "url": "https://spring.io/projects/spring-boot" - }, - "org.springframework.boot:spring-boot-servlet:4.0.7": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "spring-boot-servlet", - "url": "https://spring.io/projects/spring-boot" - }, - "org.springframework.boot:spring-boot-starter-actuator:4.0.7": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "spring-boot-starter-actuator", - "url": "https://spring.io/projects/spring-boot" - }, - "org.springframework.boot:spring-boot-starter-aspectj:4.0.7": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "spring-boot-starter-aspectj", - "url": "https://spring.io/projects/spring-boot" - }, - "org.springframework.boot:spring-boot-starter-data-cassandra:4.0.7": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "spring-boot-starter-data-cassandra", - "url": "https://spring.io/projects/spring-boot" - }, - "org.springframework.boot:spring-boot-starter-jackson:4.0.7": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "spring-boot-starter-jackson", - "url": "https://spring.io/projects/spring-boot" - }, - "org.springframework.boot:spring-boot-starter-logging:4.0.7": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "spring-boot-starter-logging", - "url": "https://spring.io/projects/spring-boot" - }, - "org.springframework.boot:spring-boot-starter-micrometer-metrics:4.0.7": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "spring-boot-starter-micrometer-metrics", - "url": "https://spring.io/projects/spring-boot" - }, - "org.springframework.boot:spring-boot-starter-security-oauth2-client:4.0.7": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "spring-boot-starter-security-oauth2-client", - "url": "https://spring.io/projects/spring-boot" - }, - "org.springframework.boot:spring-boot-starter-security-oauth2-resource-server:4.0.7": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "spring-boot-starter-security-oauth2-resource-server", - "url": "https://spring.io/projects/spring-boot" - }, - "org.springframework.boot:spring-boot-starter-security:4.0.7": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "spring-boot-starter-security", - "url": "https://spring.io/projects/spring-boot" - }, - "org.springframework.boot:spring-boot-starter-tomcat-runtime:4.0.7": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "spring-boot-starter-tomcat-runtime", - "url": "https://spring.io/projects/spring-boot" - }, - "org.springframework.boot:spring-boot-starter-tomcat:4.0.7": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "spring-boot-starter-tomcat", - "url": "https://spring.io/projects/spring-boot" - }, - "org.springframework.boot:spring-boot-starter-validation:4.0.7": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "spring-boot-starter-validation", - "url": "https://spring.io/projects/spring-boot" - }, - "org.springframework.boot:spring-boot-starter-webmvc:4.0.7": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "spring-boot-starter-webmvc", - "url": "https://spring.io/projects/spring-boot" - }, - "org.springframework.boot:spring-boot-starter:4.0.7": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "spring-boot-starter", - "url": "https://spring.io/projects/spring-boot" - }, - "org.springframework.boot:spring-boot-tomcat:4.0.7": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "spring-boot-tomcat", - "url": "https://spring.io/projects/spring-boot" - }, - "org.springframework.boot:spring-boot-validation:4.0.7": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "spring-boot-validation", - "url": "https://spring.io/projects/spring-boot" - }, - "org.springframework.boot:spring-boot-web-server:4.0.7": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "spring-boot-web-server", - "url": "https://spring.io/projects/spring-boot" - }, - "org.springframework.boot:spring-boot-webclient:4.0.7": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "spring-boot-webclient", - "url": "https://spring.io/projects/spring-boot" - }, - "org.springframework.boot:spring-boot-webflux:4.0.7": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "spring-boot-webflux", - "url": "https://spring.io/projects/spring-boot" - }, - "org.springframework.boot:spring-boot-webmvc:4.0.7": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "spring-boot-webmvc", - "url": "https://spring.io/projects/spring-boot" - }, - "org.springframework.boot:spring-boot:4.0.7": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "spring-boot", - "url": "https://spring.io/projects/spring-boot" - }, - "org.springframework.cloud:spring-cloud-commons:5.0.2": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "Spring Cloud Commons", - "url": "https://projects.spring.io/spring-cloud/spring-cloud-commons/" - }, - "org.springframework.cloud:spring-cloud-context:5.0.2": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "Spring Cloud Context", - "url": "https://projects.spring.io/spring-cloud/spring-cloud-context/" - }, - "org.springframework.cloud:spring-cloud-kubernetes-client-autoconfig:5.0.2": { + "org.springframework.cloud:spring-cloud-kubernetes-client-autoconfig:5.0.2": { "licenses": [ "Apache License, Version 2.0" ], @@ -1558,13 +519,6 @@ "name": "spring-cloud-kubernetes-commons", "url": "https://cloud.spring.io/spring-cloud-kubernetes-commons" }, - "org.springframework.cloud:spring-cloud-starter-bootstrap:5.0.2": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "spring-cloud-starter-bootstrap", - "url": "https://projects.spring.io/spring-cloud" - }, "org.springframework.cloud:spring-cloud-starter-kubernetes-client-config:5.0.2": { "licenses": [ "Apache License, Version 2.0" @@ -1572,27 +526,6 @@ "name": "Spring Cloud Kubernetes :: Kubernetes Native Starter :: Config", "url": "https://cloud.spring.io/spring-cloud-starter-kubernetes-client-config" }, - "org.springframework.cloud:spring-cloud-starter:5.0.2": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "spring-cloud-starter", - "url": "https://projects.spring.io/spring-cloud" - }, - "org.springframework.data:spring-data-cassandra:5.0.6": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "Spring Data for Apache Cassandra Core", - "url": "https://projects.spring.io/spring-data-cassandra/" - }, - "org.springframework.data:spring-data-commons:4.0.6": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "Spring Data Core", - "url": "https://spring.io/projects/spring-data" - }, "org.springframework.retry:spring-retry:2.0.13": { "licenses": [ "Apache 2.0" @@ -1600,279 +533,13 @@ "name": "Spring Retry", "url": "https://github.com/spring-projects/spring-retry" }, - "org.springframework.security:spring-security-config:7.0.6": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "spring-security-config", - "url": "https://spring.io/projects/spring-security" - }, - "org.springframework.security:spring-security-core:7.0.6": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "spring-security-core", - "url": "https://spring.io/projects/spring-security" - }, - "org.springframework.security:spring-security-crypto:7.0.6": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "spring-security-crypto", - "url": "https://spring.io/projects/spring-security" - }, - "org.springframework.security:spring-security-oauth2-client:7.0.6": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "spring-security-oauth2-client", - "url": "https://spring.io/projects/spring-security" - }, - "org.springframework.security:spring-security-oauth2-core:7.0.6": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "spring-security-oauth2-core", - "url": "https://spring.io/projects/spring-security" - }, - "org.springframework.security:spring-security-oauth2-jose:7.0.6": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "spring-security-oauth2-jose", - "url": "https://spring.io/projects/spring-security" - }, - "org.springframework.security:spring-security-oauth2-resource-server:7.0.6": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "spring-security-oauth2-resource-server", - "url": "https://spring.io/projects/spring-security" - }, - "org.springframework.security:spring-security-web:7.0.6": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "spring-security-web", - "url": "https://spring.io/projects/spring-security" - }, - "org.springframework:spring-aop:7.0.8": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "Spring AOP", - "url": "https://github.com/spring-projects/spring-framework" - }, - "org.springframework:spring-beans:7.0.8": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "Spring Beans", - "url": "https://github.com/spring-projects/spring-framework" - }, "org.springframework:spring-context-support:7.0.8": { "licenses": [ "Apache License, Version 2.0" ], "name": "Spring Context Support", "url": "https://github.com/spring-projects/spring-framework" - }, - "org.springframework:spring-context:7.0.8": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "Spring Context", - "url": "https://github.com/spring-projects/spring-framework" - }, - "org.springframework:spring-core:7.0.8": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "Spring Core", - "url": "https://github.com/spring-projects/spring-framework" - }, - "org.springframework:spring-expression:7.0.8": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "Spring Expression Language (SpEL)", - "url": "https://github.com/spring-projects/spring-framework" - }, - "org.springframework:spring-tx:7.0.8": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "Spring Transaction", - "url": "https://github.com/spring-projects/spring-framework" - }, - "org.springframework:spring-web:7.0.8": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "Spring Web", - "url": "https://github.com/spring-projects/spring-framework" - }, - "org.springframework:spring-webflux:7.0.8": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "Spring WebFlux", - "url": "https://github.com/spring-projects/spring-framework" - }, - "org.springframework:spring-webmvc:7.0.8": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "Spring Web MVC", - "url": "https://github.com/spring-projects/spring-framework" - }, - "org.yaml:snakeyaml:2.5": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "SnakeYAML", - "url": "https://bitbucket.org/snakeyaml/snakeyaml" - }, - "software.amazon.awssdk:annotations:2.40.1": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "AWS Java SDK :: Annotations", - "url": "https://aws.amazon.com/sdkforjava" - }, - "software.amazon.awssdk:checksums-spi:2.40.1": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "AWS Java SDK :: Checksums SPI", - "url": "https://aws.amazon.com/sdkforjava" - }, - "software.amazon.awssdk:checksums:2.40.1": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "AWS Java SDK :: Checksums", - "url": "https://aws.amazon.com/sdkforjava" - }, - "software.amazon.awssdk:endpoints-spi:2.40.1": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "AWS Java SDK :: Endpoints SPI", - "url": "https://aws.amazon.com/sdkforjava" - }, - "software.amazon.awssdk:http-auth-aws:2.40.1": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "AWS Java SDK :: HTTP Auth AWS", - "url": "https://aws.amazon.com/sdkforjava" - }, - "software.amazon.awssdk:http-auth-spi:2.40.1": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "AWS Java SDK :: HTTP Auth SPI", - "url": "https://aws.amazon.com/sdkforjava" - }, - "software.amazon.awssdk:http-client-spi:2.40.1": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "AWS Java SDK :: HTTP Client Interface", - "url": "https://aws.amazon.com/sdkforjava" - }, - "software.amazon.awssdk:identity-spi:2.40.1": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "AWS Java SDK :: Identity SPI", - "url": "https://aws.amazon.com/sdkforjava" - }, - "software.amazon.awssdk:json-utils:2.40.1": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "AWS Java SDK :: Core :: Protocols :: Json Utils", - "url": "https://aws.amazon.com/sdkforjava" - }, - "software.amazon.awssdk:metrics-spi:2.40.1": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "AWS Java SDK :: Metrics SPI", - "url": "https://aws.amazon.com/sdkforjava" - }, - "software.amazon.awssdk:profiles:2.40.1": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "AWS Java SDK :: Profiles", - "url": "https://aws.amazon.com/sdkforjava" - }, - "software.amazon.awssdk:regions:2.40.1": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "AWS Java SDK :: Regions", - "url": "https://aws.amazon.com/sdkforjava" - }, - "software.amazon.awssdk:retries-spi:2.40.1": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "AWS Java SDK :: Retries API", - "url": "https://aws.amazon.com/sdkforjava" - }, - "software.amazon.awssdk:retries:2.40.1": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "AWS Java SDK :: Retries", - "url": "https://aws.amazon.com/sdkforjava" - }, - "software.amazon.awssdk:sdk-core:2.40.1": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "AWS Java SDK :: SDK Core", - "url": "https://aws.amazon.com/sdkforjava" - }, - "software.amazon.awssdk:third-party-jackson-core:2.40.1": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "AWS Java SDK :: Third Party :: Jackson-core", - "url": "https://aws.amazon.com/sdkforjava" - }, - "software.amazon.awssdk:utils:2.40.1": { - "licenses": [ - "Apache License, Version 2.0" - ], - "name": "AWS Java SDK :: Utilities", - "url": "https://aws.amazon.com/sdkforjava" - }, - "tools.jackson.core:jackson-core:3.1.4": { - "licenses": [ - "The Apache Software License, Version 2.0" - ], - "name": "Jackson-core", - "url": "https://github.com/FasterXML/jackson-core" - }, - "tools.jackson.core:jackson-databind:3.1.4": { - "licenses": [ - "The Apache Software License, Version 2.0" - ], - "name": "jackson-databind", - "url": "https://github.com/FasterXML/jackson" - }, - "tools.jackson.module:jackson-module-blackbird:3.1.4": { - "licenses": [ - "The Apache Software License, Version 2.0" - ], - "name": "Jackson module: Blackbird", - "url": "https://github.com/FasterXML/jackson-modules-base" } }, - "generated_by": "tools/bazel/generate_notice.py --update-metadata" + "generated_by": "tools/bazel/java/generate_notice.py --update-metadata" } diff --git a/src/libraries/java/nv-boot-parent/BAZEL.md b/src/libraries/java/nv-boot-parent/BAZEL.md index 051001e22..4f2565440 100644 --- a/src/libraries/java/nv-boot-parent/BAZEL.md +++ b/src/libraries/java/nv-boot-parent/BAZEL.md @@ -343,27 +343,98 @@ sonar.coverageReportPaths=<path-to-sonar-generic-coverage.xml> ## License And Notice -The root owns the generator under `//tools/bazel/java`; nv-boot owns its -checked-in `NOTICE`, `notice_roots.json`, and `notice_metadata.json` under: +The monorepo has two NOTICE levels: + +1. nv-boot's Bazel target generates and checks the complete third-party NOTICE + for the nv-boot libraries. +2. The existing root `tools/scripts/collect-notices` process records the + nv-boot NOTICE path in the monorepo's top-level `NOTICE`. + +The root owns the shared implementation: ```text -//src/libraries/java/nv-boot-parent +//rules/java:notice.bzl +//tools/bazel/java:generate_notice_tool ``` -The generator is Bazel-native: it does not run Maven, invoke -`license-maven-plugin`, or read project POMs. The final layered NOTICE and -OSRB integration is Phase 4 work. The current diagnostic target is: +nv-boot owns three component files: + +```text +src/libraries/java/nv-boot-parent/NOTICE +src/libraries/java/nv-boot-parent/notice_roots.json +src/libraries/java/nv-boot-parent/notice_metadata.json +``` + +Their roles are deliberately different: + +- `NOTICE` is the complete, human-readable generated result checked into Git. +- `notice_roots.json` lists the production dependency entry points for the + nv-boot library collection. It is required because nv-boot has no single + executable jar whose contents represent every public starter. +- `notice_metadata.json` contains the reusable name, URL, and license metadata + for nv-boot's third-party runtime dependencies. OSS services reuse this + shared metadata instead of copying it. + +The generator is Bazel-native. Normal generation reads the root +`maven_install.json`, not project POM files, and does not run Maven or +`license-maven-plugin`. + +Regenerate the checked-in nv-boot NOTICE: ```bash bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ - run //src/libraries/java/nv-boot-parent:generate_notice -- --check + run //src/libraries/java/nv-boot-parent:generate_notice -- --write +``` + +When a new runtime dependency lacks metadata, refresh the component-owned +metadata and NOTICE together: + +```bash +bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ + run //src/libraries/java/nv-boot-parent:generate_notice -- \ + --update-metadata --write +``` + +The metadata-update mode may read an upstream dependency POM from the local +Maven cache or configured artifact repository to obtain its published name, +URL, and license declaration. That is metadata discovery only; it does not run +a Maven project build. + +Check for drift exactly as CI does: + +```bash +bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ + test //src/libraries/java/nv-boot-parent:notice_check_test \ + --cache_test_results=no \ + --test_output=errors +``` + +Build the machine-readable nv-boot runtime inventory: + +```bash +bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ + build //src/libraries/java/nv-boot-parent:nv_boot_runtime_inventory + +cat bazel-bin/src/libraries/java/nv-boot-parent/runtime_inventory.json +``` + +The nv-boot inventory is the input for its OSRB comparison. An +`nv_boot_osrb_dependency_delta` target is intentionally not defined yet +because the monorepo does not have a checked-in approved-baseline inventory to +subtract. Do not compare nv-boot with an empty baseline and describe every +dependency as newly introduced. Once OSRB establishes the approved public +baseline, add that inventory as the explicit baseline and generate nv-boot's +license-grouped delta from the exact versioned-coordinate difference. + +After component NOTICE files are updated, validate the existing monorepo root +rollup: + +```bash +./tools/ci/check-license ``` -At the end of Phase 3 the checked-in nv-boot NOTICE is stale for -`com.google.code.findbugs:jsr305` (`2.0.1` versus resolved `3.0.2`). Phase 4 -will finish deterministic regenerate/check targets, shared metadata reuse by -services, and license-grouped OSRB delta output. Do not describe NOTICE as a -required passing CI gate until that work is complete. +`check-license` requires Bash 4 or newer. To intentionally refresh the +top-level path rollup, run `./tools/scripts/update-license`. ## GitHub CI diff --git a/src/libraries/java/nv-boot-parent/BUILD.bazel b/src/libraries/java/nv-boot-parent/BUILD.bazel index 17f61bf3c..a70870dd9 100644 --- a/src/libraries/java/nv-boot-parent/BUILD.bazel +++ b/src/libraries/java/nv-boot-parent/BUILD.bazel @@ -1,3 +1,5 @@ +load("//rules/java:notice.bzl", "nvcf_notice") + package(default_visibility = ["//visibility:public"]) # NOTICE and its generator inputs are owned by this subtree. The third-party @@ -9,50 +11,9 @@ exports_files([ "notice_roots.json", ]) -genrule( - name = "third_party_notice", - srcs = [ - "//:maven_install.json", - ":notice_metadata.json", - ":notice_roots.json", - ], - tools = ["//tools/bazel/java:generate_notice_tool"], - outs = ["THIRD_PARTY_NOTICE"], - cmd = """ -set -eu -"$(execpath //tools/bazel/java:generate_notice_tool)" \ - --maven-install "$(location //:maven_install.json)" \ - --metadata "$(location :notice_metadata.json)" \ - --root-manifest "$(location :notice_roots.json)" \ - --output "$@" \ - --write -""", -) - -genrule( - name = "generate_notice", - srcs = [ - "//:maven_install.json", - ":notice_metadata.json", - ":notice_roots.json", - ], - tools = ["//tools/bazel/java:generate_notice_tool"], - outs = ["generate_notice.sh"], - cmd = """ -cat > "$@" <<'EOF' -#!/usr/bin/env bash -set -euo pipefail - -workspace="$${BUILD_WORKSPACE_DIRECTORY:-$$(pwd)}" -service="$${workspace}/src/libraries/java/nv-boot-parent" -exec "$(execpath //tools/bazel/java:generate_notice_tool)" \ - --maven-install "$${workspace}/maven_install.json" \ - --metadata "$${service}/notice_metadata.json" \ - --notice "$${service}/NOTICE" \ - --root-manifest "$${service}/notice_roots.json" \ - "$$@" -EOF -chmod +x "$@" -""", - executable = True, +nvcf_notice( + checked_notice = ":NOTICE", + inventory_name = "nv_boot_runtime_inventory", + metadata = ":notice_metadata.json", + root_manifests = [":notice_roots.json"], ) diff --git a/src/libraries/java/nv-boot-parent/NOTICE b/src/libraries/java/nv-boot-parent/NOTICE index ca15f90d3..400531af2 100644 --- a/src/libraries/java/nv-boot-parent/NOTICE +++ b/src/libraries/java/nv-boot-parent/NOTICE @@ -23,7 +23,7 @@ Lists of 208 third-party dependencies. (Eclipse Public License - v 2.0) (GNU General Public License Version 2) (GNU Lesser General Public License Version 2.1) jnr-posix (com.github.jnr:jnr-posix:3.1.15 - http://nexus.sonatype.org/oss-repository-hosting.html) (MIT License) jnr-x86asm (com.github.jnr:jnr-x86asm:1.0.2 - http://github.com/jnr/jnr-x86asm) (Apache License, Version 2.0) JCIP Annotations under Apache License (com.github.stephenc.jcip:jcip-annotations:1.0-1 - http://stephenc.github.com/jcip-annotations) - (The Apache Software License, Version 2.0) FindBugs-jsr305 (com.google.code.findbugs:jsr305:2.0.1 - http://findbugs.sourceforge.net/) + (The Apache Software License, Version 2.0) FindBugs-jsr305 (com.google.code.findbugs:jsr305:3.0.2 - http://findbugs.sourceforge.net/) (Apache 2.0) error-prone annotations (com.google.errorprone:error_prone_annotations:2.49.0 - https://errorprone.info) (Apache License, Version 2.0) Guava InternalFutureFailureAccess and InternalFutures (com.google.guava:failureaccess:1.0.3 - https://github.com/google/guava) (Apache License, Version 2.0) Guava: Google Core Libraries for Java (com.google.guava:guava:33.6.0-jre - https://github.com/google/guava) diff --git a/src/libraries/java/nv-boot-parent/notice_metadata.json b/src/libraries/java/nv-boot-parent/notice_metadata.json index a6261780e..a84cb5b29 100644 --- a/src/libraries/java/nv-boot-parent/notice_metadata.json +++ b/src/libraries/java/nv-boot-parent/notice_metadata.json @@ -1509,5 +1509,5 @@ "url": "https://github.com/FasterXML/jackson-modules-base" } }, - "generated_by": "tools/bazel/generate_notice.py --update-metadata" + "generated_by": "tools/bazel/java/generate_notice.py --update-metadata" } diff --git a/tools/bazel/java/BUILD.bazel b/tools/bazel/java/BUILD.bazel index ca8514eb4..6d45cff13 100644 --- a/tools/bazel/java/BUILD.bazel +++ b/tools/bazel/java/BUILD.bazel @@ -1,6 +1,6 @@ load("@rules_java//java:defs.bzl", "java_binary", "java_library", "java_plugin") load("@rules_proto_grpc//:defs.bzl", "proto_plugin") -load("@rules_python//python:defs.bzl", "py_binary") +load("@rules_python//python:defs.bzl", "py_binary", "py_library", "py_test") load("@rules_shell//shell:sh_test.bzl", "sh_test") # Root-owned executable helpers and shared build targets for Java subtrees. @@ -10,7 +10,9 @@ package(default_visibility = ["//visibility:public"]) exports_files([ "generate_notice.py", "jacoco_test_runner.sh", + "license_aliases.json", "lcov_to_sonar_generic.py", + "notice_diff_test.sh", ]) # Lombok annotation processing (shared by both Java compile profiles). @@ -43,6 +45,21 @@ py_binary( python_version = "3.11", ) +py_library( + name = "generate_notice_lib", + srcs = ["generate_notice.py"], + imports = ["."], +) + +py_test( + name = "generate_notice_test", + srcs = ["generate_notice_test.py"], + deps = [":generate_notice_lib"], + main = "generate_notice_test.py", + python_version = "3.11", + size = "small", +) + # gRPC-Java codegen plugin (pinned native binary, version tracks GRPC_VERSION # in the root MODULE.bazel). Consumed by //rules/java:proto.bzl. proto_plugin( diff --git a/tools/bazel/java/generate_notice.py b/tools/bazel/java/generate_notice.py index bb9e5f3e6..0268bae56 100644 --- a/tools/bazel/java/generate_notice.py +++ b/tools/bazel/java/generate_notice.py @@ -1,10 +1,10 @@ #!/usr/bin/env python3 """Generates the third-party NOTICE file from Bazel dependency metadata. -The build/test path is hermetic: it reads checked-in root manifests, -`maven_install.json`, and generated upstream POM metadata. The update path can -refresh the metadata from local Maven POM cache files or remote Maven -repositories, similar to repinning `maven_install.json`. +The build/test path is hermetic: it reads `maven_install.json`, checked-in +component metadata, and either declared library roots or a packaged runtime +jar. Only the explicit metadata-update path reads dependency POMs from a local +Maven cache or remote Maven-compatible repository. """ import argparse @@ -67,6 +67,70 @@ def load_json(path): return json.loads(path.read_text()) +def metadata_artifacts(metadata): + return metadata.get("artifacts", {}) + + +def merge_metadata(shared_documents, primary_document, reject_primary_overlap=True): + """Merges shared metadata with component-owned metadata.""" + merged = {} + for source, document in shared_documents: + for coordinate, entry in metadata_artifacts(document).items(): + existing = merged.get(coordinate) + if existing is not None and existing != entry: + raise ValueError( + f"Conflicting shared NOTICE metadata for {coordinate}: {source}" + ) + merged[coordinate] = entry + + for coordinate, entry in metadata_artifacts(primary_document).items(): + existing = merged.get(coordinate) + if existing is not None: + if existing != entry: + raise ValueError( + f"Component NOTICE metadata conflicts with shared metadata for {coordinate}" + ) + if reject_primary_overlap: + raise ValueError( + f"Component NOTICE metadata duplicates shared metadata for {coordinate}" + ) + merged[coordinate] = entry + + return {"artifacts": merged} + + +def prune_shared_metadata(primary_document, shared_documents): + """Removes exact shared entries from component-owned metadata.""" + shared = merge_metadata(shared_documents, {"artifacts": {}}, False) + artifacts = {} + for coordinate, entry in metadata_artifacts(primary_document).items(): + shared_entry = metadata_artifacts(shared).get(coordinate) + if shared_entry is not None: + if shared_entry != entry: + raise ValueError( + f"Component NOTICE metadata conflicts with shared metadata for {coordinate}" + ) + continue + artifacts[coordinate] = entry + return { + "generated_by": primary_document.get( + "generated_by", + "tools/bazel/java/generate_notice.py", + ), + "artifacts": {key: artifacts[key] for key in sorted(artifacts)}, + } + + +def load_license_aliases(path): + if not path: + return {} + return load_json(path).get("aliases", {}) + + +def normalized_licenses(licenses, aliases): + return sorted({aliases.get(license_name, license_name) for license_name in licenses}) + + def load_root_manifests(paths): roots = [] for path in paths: @@ -199,18 +263,107 @@ def generated_notice(coordinates, maven_install, metadata): raise ValueError( "Missing NOTICE metadata for:\n" + "\n".join(f" {coordinate}" for coordinate in missing) - + "\nRun: python3 tools/bazel/generate_notice.py --update-metadata --write" + + "\nRun the component's Bazel generate_notice target with " + "--update-metadata --write" ) if incomplete: raise ValueError( "Incomplete NOTICE metadata for:\n" + "\n".join(f" {coordinate}" for coordinate in incomplete) - + "\nFix tools/bazel/notice_metadata.json or rerun metadata generation after POM metadata is available." + + "\nFix the component notice_metadata.json or rerun metadata " + "generation after POM metadata is available." ) lines.append("") return "\n".join(lines) +def generated_inventory(coordinates, maven_install, metadata, aliases): + dependencies = [] + for key in coordinates: + artifact = maven_install["artifacts"].get(key) + if not artifact: + continue + group_id, artifact_id = key.split(":", 1) + coordinate = versioned_coordinate( + group_id, + artifact_id, + artifact["version"], + ) + entry = metadata_artifacts(metadata).get(coordinate) + if not entry: + raise ValueError(f"Missing NOTICE metadata for {coordinate}") + dependencies.append( + { + "coordinate": coordinate, + "licenses": normalized_licenses(entry.get("licenses", []), aliases), + "name": entry.get("name") or artifact_id, + "url": entry.get("url") or "", + } + ) + return { + "generated_by": "tools/bazel/java/generate_notice.py", + "dependencies": dependencies, + } + + +def inventory_coordinates(inventory): + return { + dependency["coordinate"] + for dependency in inventory.get("dependencies", []) + } + + +def generated_delta(inventory, baseline_inventories): + baseline_coordinates = set() + for baseline in baseline_inventories: + baseline_coordinates.update(inventory_coordinates(baseline)) + + dependencies = [ + dependency + for dependency in inventory.get("dependencies", []) + if dependency["coordinate"] not in baseline_coordinates + ] + dependencies.sort(key=lambda dependency: dependency["coordinate"]) + + groups = {} + for dependency in dependencies: + licenses = dependency.get("licenses") or ["UNKNOWN"] + group = " / ".join(sorted(licenses)) + groups.setdefault(group, []).append(dependency) + + return { + "generated_by": "tools/bazel/java/generate_notice.py", + "dependencies": dependencies, + "groups": {key: groups[key] for key in sorted(groups)}, + } + + +def generated_delta_markdown(delta): + dependencies = delta["dependencies"] + lines = [ + "# OSRB Dependency Delta", + "", + ( + f"{len(dependencies)} new or additional third-party " + "dependencies require review." + ), + "", + ] + if not dependencies: + lines.extend(["No new or additional dependencies were found.", ""]) + return "\n".join(lines) + + for license_group, entries in delta["groups"].items(): + lines.extend([f"## {license_group}", ""]) + for entry in entries: + suffix = f" - {entry['url']}" if entry.get("url") else "" + lines.append( + f"- `{entry['coordinate']}` - {entry['name']}{suffix}" + ) + lines.append("") + return "\n".join(lines) + + def compare_or_write(expected, notice_path, write): if write: notice_path.write_text(expected) @@ -381,9 +534,15 @@ def resolve(self, group_id, artifact_id, version): return result -def update_metadata(coordinates, maven_install, existing_metadata): +def update_metadata( + coordinates, + maven_install, + existing_metadata, + shared_metadata=None, +): resolver = PomMetadataResolver(maven_install) artifacts = dict(existing_metadata.get("artifacts", {})) + shared_artifacts = metadata_artifacts(shared_metadata or {}) for key in coordinates: artifact = maven_install["artifacts"].get(key) if not artifact: @@ -391,6 +550,8 @@ def update_metadata(coordinates, maven_install, existing_metadata): group_id, artifact_id = key.split(":", 1) version = artifact["version"] versioned = versioned_coordinate(group_id, artifact_id, version) + if versioned in shared_artifacts: + continue resolved = resolver.resolve(group_id, artifact_id, version) artifacts[versioned] = { "licenses": resolved["licenses"], @@ -398,7 +559,7 @@ def update_metadata(coordinates, maven_install, existing_metadata): "url": resolved["url"], } return { - "generated_by": "tools/bazel/generate_notice.py --update-metadata", + "generated_by": "tools/bazel/java/generate_notice.py --update-metadata", "artifacts": {key: artifacts[key] for key in sorted(artifacts)}, } @@ -417,22 +578,81 @@ def current_notice_coordinates(path): def main(): parser = argparse.ArgumentParser() parser.add_argument("--maven-install", default="maven_install.json") - parser.add_argument("--metadata", default="tools/bazel/notice_metadata.json") + parser.add_argument("--metadata") + parser.add_argument("--shared-metadata", action="append", default=[]) parser.add_argument("--notice", default="NOTICE") parser.add_argument("--root-manifest", action="append", default=[]) parser.add_argument("--runtime-jar", action="append", default=[]) parser.add_argument("--first-party-group", action="append", default=[]) + parser.add_argument("--license-aliases") parser.add_argument("--output") + parser.add_argument("--inventory-output") + parser.add_argument("--delta-inventory") + parser.add_argument("--baseline-inventory", action="append", default=[]) + parser.add_argument("--delta-json-output") + parser.add_argument("--delta-markdown-output") parser.add_argument("--check", action="store_true") parser.add_argument("--write", action="store_true") parser.add_argument("--update-metadata", action="store_true") + parser.add_argument("--prune-shared-metadata", action="store_true") args = parser.parse_args() + if args.delta_inventory: + if not args.delta_json_output or not args.delta_markdown_output: + parser.error( + "--delta-inventory requires --delta-json-output and " + "--delta-markdown-output" + ) + inventory = load_json(pathlib.Path(args.delta_inventory)) + baselines = [ + load_json(pathlib.Path(path)) + for path in args.baseline_inventory + ] + delta = generated_delta(inventory, baselines) + pathlib.Path(args.delta_json_output).write_text( + json.dumps(delta, indent=2, sort_keys=True) + "\n" + ) + pathlib.Path(args.delta_markdown_output).write_text( + generated_delta_markdown(delta) + ) + print( + f"OSRB delta generated for {len(delta['dependencies'])} " + "new or additional dependencies" + ) + return 0 + + if not args.metadata: + parser.error("--metadata is required for NOTICE generation") + maven_install_path = pathlib.Path(args.maven_install) metadata_path = pathlib.Path(args.metadata) notice_path = pathlib.Path(args.notice) maven_install = load_json(maven_install_path) - metadata = load_json(metadata_path) if metadata_path.exists() else {"artifacts": {}} + primary_metadata = ( + load_json(metadata_path) + if metadata_path.exists() + else {"artifacts": {}} + ) + shared_documents = [ + (path, load_json(pathlib.Path(path))) + for path in args.shared_metadata + ] + + if args.prune_shared_metadata: + primary_metadata = prune_shared_metadata( + primary_metadata, + shared_documents, + ) + metadata_path.write_text( + json.dumps(primary_metadata, indent=2, sort_keys=True) + "\n" + ) + + shared_metadata = merge_metadata( + shared_documents, + {"artifacts": {}}, + False, + ) + metadata = merge_metadata(shared_documents, primary_metadata) first_party_groups = tuple(FIRST_PARTY_GROUPS) + tuple(args.first_party_group) roots = load_root_manifests([pathlib.Path(path) for path in args.root_manifest]) @@ -448,8 +668,16 @@ def main(): raise ValueError("At least one --root-manifest or --runtime-jar is required") if args.update_metadata: - metadata = update_metadata(coordinates, maven_install, metadata) - metadata_path.write_text(json.dumps(metadata, indent=2, sort_keys=True) + "\n") + primary_metadata = update_metadata( + coordinates, + maven_install, + primary_metadata, + shared_metadata, + ) + metadata_path.write_text( + json.dumps(primary_metadata, indent=2, sort_keys=True) + "\n" + ) + metadata = merge_metadata(shared_documents, primary_metadata) notice = generated_notice(coordinates, maven_install, metadata) output_path = pathlib.Path(args.output) if args.output else notice_path @@ -457,11 +685,26 @@ def main(): if diff: sys.stderr.write(diff) sys.stderr.write( - "\nRun: python3 tools/bazel/generate_notice.py --update-metadata --write " - "with the same --root-manifest or --runtime-jar inputs\n" + "\nRun the component's Bazel generate_notice target with --write " + "(and --update-metadata when dependency metadata changed)\n" ) return 1 + if args.inventory_output: + inventory = generated_inventory( + coordinates, + maven_install, + metadata, + load_license_aliases( + pathlib.Path(args.license_aliases) + if args.license_aliases + else None + ), + ) + pathlib.Path(args.inventory_output).write_text( + json.dumps(inventory, indent=2, sort_keys=True) + "\n" + ) + if args.check: generated_coordinates = set() for key in coordinates: diff --git a/tools/bazel/java/generate_notice_test.py b/tools/bazel/java/generate_notice_test.py new file mode 100644 index 000000000..203d1aa85 --- /dev/null +++ b/tools/bazel/java/generate_notice_test.py @@ -0,0 +1,86 @@ +import unittest + +import generate_notice + + +class NoticeMetadataTest(unittest.TestCase): + def test_merge_rejects_component_duplicate(self): + entry = {"licenses": ["MIT"], "name": "Example", "url": ""} + shared = [("shared.json", {"artifacts": {"g:a:1": entry}})] + + with self.assertRaisesRegex(ValueError, "duplicates shared metadata"): + generate_notice.merge_metadata( + shared, + {"artifacts": {"g:a:1": entry}}, + ) + + def test_prune_removes_exact_shared_entries(self): + shared_entry = {"licenses": ["MIT"], "name": "Shared", "url": ""} + local_entry = {"licenses": ["Apache-2.0"], "name": "Local", "url": ""} + result = generate_notice.prune_shared_metadata( + {"artifacts": {"g:a:1": shared_entry, "g:b:2": local_entry}}, + [("shared.json", {"artifacts": {"g:a:1": shared_entry}})], + ) + + self.assertEqual({"g:b:2": local_entry}, result["artifacts"]) + + def test_inventory_normalizes_unambiguous_license_aliases(self): + inventory = generate_notice.generated_inventory( + ["g:a"], + {"artifacts": {"g:a": {"version": "1"}}}, + { + "artifacts": { + "g:a:1": { + "licenses": ["Apache License, Version 2.0"], + "name": "Example", + "url": "https://example.invalid", + } + } + }, + {"Apache License, Version 2.0": "Apache-2.0"}, + ) + + self.assertEqual( + ["Apache-2.0"], + inventory["dependencies"][0]["licenses"], + ) + + def test_delta_uses_exact_versioned_coordinates(self): + current = { + "dependencies": [ + { + "coordinate": "g:a:2", + "licenses": ["MIT"], + "name": "A", + "url": "", + }, + { + "coordinate": "g:b:1", + "licenses": ["Apache-2.0"], + "name": "B", + "url": "", + }, + ] + } + baseline = { + "dependencies": [ + { + "coordinate": "g:a:1", + "licenses": ["MIT"], + "name": "A", + "url": "", + } + ] + } + + delta = generate_notice.generated_delta(current, [baseline]) + + self.assertEqual( + ["g:a:2", "g:b:1"], + [entry["coordinate"] for entry in delta["dependencies"]], + ) + self.assertIn("## MIT", generate_notice.generated_delta_markdown(delta)) + + +if __name__ == "__main__": + unittest.main() diff --git a/tools/bazel/java/license_aliases.json b/tools/bazel/java/license_aliases.json new file mode 100644 index 000000000..81e47f869 --- /dev/null +++ b/tools/bazel/java/license_aliases.json @@ -0,0 +1,23 @@ +{ + "aliases": { + "Apache 2": "Apache-2.0", + "Apache 2.0": "Apache-2.0", + "Apache License 2.0": "Apache-2.0", + "Apache License, Version 2.0": "Apache-2.0", + "Apache License, version 2.0": "Apache-2.0", + "Apache Software License, version 2.0": "Apache-2.0", + "EPL 2.0": "EPL-2.0", + "Eclipse Distribution License - v 1.0": "EDL-1.0", + "Eclipse Public License - v 2.0": "EPL-2.0", + "GNU General Public License Version 2": "GPL-2.0-only", + "GNU Lesser General Public License Version 2.1": "LGPL-2.1-only", + "GPL2 w/ CPE": "GPL-2.0-only WITH Classpath-exception-2.0", + "Lesser General Public License, version 3 or greater": "LGPL-3.0-or-later", + "MIT License": "MIT", + "MIT license": "MIT", + "Public Domain, per Creative Commons CC0": "CC0-1.0", + "The Apache License, Version 2.0": "Apache-2.0", + "The Apache Software License, Version 2.0": "Apache-2.0", + "The MIT License": "MIT" + } +} diff --git a/tools/bazel/java/notice_diff_test.sh b/tools/bazel/java/notice_diff_test.sh new file mode 100755 index 000000000..4fc035622 --- /dev/null +++ b/tools/bazel/java/notice_diff_test.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash +set -euo pipefail + +generated="$1" +checked_in="$2" + +if ! diff -u "${checked_in}" "${generated}"; then + printf '\nNOTICE is stale. Run the package generate_notice target with --write.\n' >&2 + exit 1 +fi From c8caf29592ba07e9a2047b603bc6c59c154d4d7c Mon Sep 17 00:00:00 2001 From: Sanjay Saxena <sasaxena@nvidia.com> Date: Thu, 23 Jul 2026 18:15:00 -0700 Subject: [PATCH 26/29] Automate Java Bazel CI registration and artifacts --- .github/workflows/bazel.yml | 202 ++++++++++++------ .../cloud-tasks/BAZEL.md | 101 ++++++++- .../cloud-tasks/bazel-java-ci.json | 6 + src/libraries/java/nv-boot-parent/BAZEL.md | 84 +++++++- .../java/nv-boot-parent/bazel-java-ci.json | 6 + tools/ci/stage-bazel-java-artifacts | 36 ++++ 6 files changed, 359 insertions(+), 76 deletions(-) create mode 100644 src/control-plane-services/cloud-tasks/bazel-java-ci.json create mode 100644 src/libraries/java/nv-boot-parent/bazel-java-ci.json create mode 100755 tools/ci/stage-bazel-java-artifacts diff --git a/.github/workflows/bazel.yml b/.github/workflows/bazel.yml index 66fe7c457..c02503e32 100644 --- a/.github/workflows/bazel.yml +++ b/.github/workflows/bazel.yml @@ -12,9 +12,9 @@ # # Matrix entries reference subtrees that have their Bazel scaffold # mirrored to GitHub (each subtree's upstream .oss-allowlist controls -# whether BUILD.bazel files reach this mirror). Add a row to the ROWS -# table in the detect job when a new subtree's OSS-flip MR merges -# upstream. +# whether BUILD.bazel files reach this mirror). Add a static ROWS entry when a +# non-Java subtree's OSS-flip MR merges upstream. Java components are +# discovered from component-local bazel-java-ci.json files. # # Image push targets, internal NGC registry pulls, and the nvcfbarn # remote cache are all internal-only; this workflow runs build + test @@ -100,6 +100,9 @@ jobs: # its own private agent image (not publicly pullable), so it is not # externally buildable and is built only by its own internal CI. # Excluded from the public build pending a public base (NVIDIA/nvcf#39). + # Row fields: + # id|path|tests_skip|component_kind|ci_lane + # Static non-Java rows use only the first three fields. ROWS='root|.|false grpc-proxy|src/invocation-plane-services/grpc-proxy|false nats-auth-callout|src/control-plane-services/nats-auth-callout|false @@ -118,20 +121,34 @@ jobs: worker-utils|src/compute-plane-services/worker-utils|false function-autoscaler|src/control-plane-services/function-autoscaler|false helm-reval|src/control-plane-services/helm-reval|false - stargate|src/libraries/rust/stargate|false - nv-boot-parent|src/libraries/java/nv-boot-parent|false|root - cloud-tasks|src/control-plane-services/cloud-tasks|false|root' - # Root-scoped Java lanes (optional 4th field `root`). The Java tree is - # folded into the single root `nvcf` module -- no nested MODULE.bazel -- - # so these rows do NOT cd into a module dir. They run bazel from the - # repo root and build/test only their own targets (//<path>/...), which - # gives each Java service its own check lane without a nested module. - # Add a new Java service as one line here with the `root` marker. + stargate|src/libraries/rust/stargate|false' + + # Java rows are discovered from component-local bazel-java-ci.json + # descriptors. The descriptor's parent directory is the component + # path, so adding a Java service never requires editing this workflow. + # jq validates every field before the row reaches matrix generation. + while IFS= read -r manifest; do + path="${manifest%/bazel-java-ci.json}" + id="$(jq -er '.id | select(test("^[a-z0-9][a-z0-9-]*$"))' "$manifest")" + tests_skip="$(jq -er '.tests_skip | if type == "boolean" then tostring else error("tests_skip must be boolean") end' "$manifest")" + component_kind="$(jq -er '.component_kind | select(. == "java-framework" or . == "java-service")' "$manifest")" + ci_lane="$(jq -er '.ci_lane | select(. == "build-container" or . == "docker-host")' "$manifest")" + ROWS="${ROWS} + ${id}|${path}|${tests_skip}|${component_kind}|${ci_lane}" + done < <(find src -name bazel-java-ci.json -type f -print | LC_ALL=C sort) + + # Every discovered Java component belongs to the root `nvcf` Bazel + # module; it does not own a nested MODULE.bazel. Its lane therefore + # invokes Bazel from the repository root and scopes work to + # //<component-path>/... . Descriptor component_kind and ci_lane + # fields derive shared triggers, framework-consumer validation, + # execution-environment routing, and artifact upload; do not maintain + # separate component-name lists for those behaviors. # Paths that affect the root-module workspace build (native root # subtrees plus the shared Bazel scaffold). Java and stargate no longer - # ride the root row: nv-boot-parent, cloud-tasks, and stargate are + # ride the root row: discovered Java components and stargate have # their own scoped rows, so src/libraries/ is narrowed to - # src/libraries/go/ and cloud-tasks is dropped here. + # src/libraries/go/. ROOT_GLOBS=(MODULE.bazel .bazelrc .bazelversion BUILD.bazel WORKSPACE WORKSPACE.bazel go.work go.work.bazel rules/ platforms/ tools/ ci/ src/clis/ src/libraries/go/ .github/bazel-root-test-quarantine.txt) run_all=false @@ -165,43 +182,66 @@ jobs: run_all=true fi - # Reverse-dependency edges. A change to a framework subtree must also - # validate its consumers: the consumer's build and tests are what prove - # the framework change is compatible, so an incompatible nv-boot-parent - # change cannot merge without building its consumers and running their - # (requires-docker) tests. nv-boot-parent is consumed by the Java - # services; list each consumer id here as it enters the monorepo. When - # more Java services land, a root-level nv-boot consumer suite can - # replace this explicit list. - NV_BOOT_PATH="src/libraries/java/nv-boot-parent" - NV_BOOT_CONSUMERS=" cloud-tasks " - nv_boot_changed=false - if [ "$run_all" != "true" ] && printf '%s\n' "$changed" | grep -q "^${NV_BOOT_PATH}/"; then - nv_boot_changed=true + # Reverse-dependency edge. A discovered Java framework change + # validates every discovered java-service row. + java_framework_changed=false + if [ "$run_all" != "true" ]; then + while IFS='|' read -r _id path _tests_skip component_kind _ci_lane; do + component_kind="$(echo "$component_kind" | xargs)" + if [ "$component_kind" = "java-framework" ] && printf '%s\n' "$changed" | grep -q "^${path}/"; then + java_framework_changed=true + break + fi + done <<< "$ROWS" fi - # Subtrees that own requires-docker (Testcontainers) tests. They run in - # the bazel-docker matrix on a Docker-capable runner, executing their - # FULL suite (unit + Testcontainers) with no tag filter, so every test a - # subtree owns runs in its own visible lane -- nothing is filtered out or - # deferred. A subtree here is NOT also placed in the container matrix, so - # it never produces a lane that runs no tests. + # Root-owned Java dependencies and reusable Java rules/tools affect + # every root-scoped Java component even though the changed path is + # outside that component's subtree. Keep these explicit edges correct + # while run_all=true; they become active automatically if change-aware + # scheduling is restored. + JAVA_SHARED_GLOBS=( + MODULE.bazel + MODULE.bazel.lock + maven_install.json + .bazelrc + .bazelversion + .bazel_downloader_config + rules/java/ + tools/bazel/java/ + tools/ci/stage-bazel-java-artifacts + ) + java_shared_changed=false + if [ "$run_all" != "true" ]; then + for g in "${JAVA_SHARED_GLOBS[@]}"; do + if printf '%s\n' "$changed" | awk -v p="$g" 'index($0, p) == 1 { f = 1 } END { exit !f }'; then + java_shared_changed=true + break + fi + done + fi + + # Rows with ci_lane=docker-host own requires-docker (Testcontainers) + # tests. They run directly on the GitHub host where a Docker daemon is + # available, executing their FULL suite with no tag filter. Such a row + # is not also placed in the build-container matrix. # NOTE: grpc-proxy also owns a requires-docker test but is a nested Rust # module whose test has never run in CI; wiring+validating it is tracked # separately (NVIDIA/nvcf#396) to keep this change scoped to the Java - # subtrees. It stays in the container matrix for now (build coverage). - DOCKER_SUBTREES=" cloud-tasks nv-boot-parent " - + # subtrees. It stays in the build-container matrix for now (build + # coverage). include="[]" include_docker="[]" - while IFS='|' read -r id path tests_skip scoped; do + while IFS='|' read -r id path tests_skip component_kind ci_lane; do id="$(echo "$id" | xargs)"; [ -z "$id" ] && continue - scoped="$(echo "$scoped" | xargs)" - # Root-scoped lane (scoped=root): the subtree lives inside the single - # root module, so it runs bazel from the repo root and builds only - # //<path>/... . Every other row keeps per-module behavior - # (workdir=path, scope=//...). - if [ "$scoped" = "root" ]; then workdir="."; scope="//${path}/..."; else workdir="$path"; scope="//..."; fi + component_kind="$(echo "$component_kind" | xargs)" + ci_lane="$(echo "$ci_lane" | xargs)" + # Discovered Java rows belong to the root module. Existing static + # non-Java rows retain their module-local behavior. + case "$component_kind" in + java-*) workdir="."; scope="//${path}/..."; scoped="root" ;; + *) workdir="$path"; scope="//..."; scoped="" ;; + esac hit=false if [ "$run_all" = "true" ]; then hit=true @@ -226,17 +266,20 @@ jobs: else if printf '%s\n' "$changed" | grep -q "^${path}/"; then hit=true; fi fi - # Framework consumer edge: when nv-boot-parent changed, also schedule - # its consumers (see NV_BOOT_CONSUMERS above) so a framework change is - # validated against them, not just built in isolation. - if [ "$hit" != "true" ] && [ "$nv_boot_changed" = "true" ]; then - case "$NV_BOOT_CONSUMERS" in *" $id "*) hit=true ;; esac + # A framework change schedules every registered Java service. + if [ "$hit" != "true" ] && [ "$java_framework_changed" = "true" ] && [ "$component_kind" = "java-service" ]; then + hit=true + fi + # Shared Java configuration, dependency locks, rules, and tools + # schedule every Java row, not merely the root row. + if [ "$hit" != "true" ] && [ "$java_shared_changed" = "true" ]; then + case "$component_kind" in java-*) hit=true ;; esac fi if [ "$hit" = "true" ]; then - entry=$(jq -cn --arg id "$id" --arg path "$path" --argjson ts "$tests_skip" --arg wd "$workdir" --arg sc "$scope" --arg sm "$scoped" '{id:$id, path:$path, tests_skip:$ts, workdir:$wd, scope:$sc, scoped:$sm}') - case "$DOCKER_SUBTREES" in - *" $id "*) include_docker=$(printf '%s' "$include_docker" | jq -c --argjson e "$entry" '. + [$e]') ;; - *) include=$(printf '%s' "$include" | jq -c --argjson e "$entry" '. + [$e]') ;; + entry=$(jq -cn --arg id "$id" --arg path "$path" --argjson ts "$tests_skip" --arg wd "$workdir" --arg sc "$scope" --arg sm "$scoped" --arg ck "$component_kind" --arg cl "$ci_lane" '{id:$id, path:$path, tests_skip:$ts, workdir:$wd, scope:$sc, scoped:$sm, component_kind:$ck, ci_lane:$cl}') + case "$ci_lane" in + docker-host) include_docker=$(printf '%s' "$include_docker" | jq -c --argjson e "$entry" '. + [$e]') ;; + *) include=$(printf '%s' "$include" | jq -c --argjson e "$entry" '. + [$e]') ;; esac fi done <<< "$ROWS" @@ -244,7 +287,7 @@ jobs: count=$(printf '%s' "$include" | jq 'length') count_docker=$(printf '%s' "$include_docker" | jq 'length') total=$((count + count_docker)) - echo "selected ${total} subtree(s): container=[$(printf '%s' "$include" | jq -r '[.[].id] | join(", ")')] docker=[$(printf '%s' "$include_docker" | jq -r '[.[].id] | join(", ")')]" + echo "selected ${total} subtree(s): build-container=[$(printf '%s' "$include" | jq -r '[.[].id] | join(", ")')] docker-host=[$(printf '%s' "$include_docker" | jq -r '[.[].id] | join(", ")')]" echo "matrix=${include}" >> "$GITHUB_OUTPUT" echo "matrix_docker=${include_docker}" >> "$GITHUB_OUTPUT" if [ "$total" -gt 0 ]; then echo "any=true" >> "$GITHUB_OUTPUT"; else echo "any=false" >> "$GITHUB_OUTPUT"; fi @@ -507,10 +550,10 @@ jobs: else patterns=$(tr '\n' ' ' < "$RUNNER_TEMP/targets.txt") # Exclude requires-docker tests from the resolved set: they run in the - # bazel-integration lane, not here. Naming them explicitly and then + # Docker-host lane, not here. Naming them explicitly and then # running `bazel test --test_tag_filters=-requires-docker` fails with # "No test targets were found, yet testing was requested" (exit 4) when - # a scope's only tests are requires-docker (e.g. cloud-tasks). Filtering + # a scope's only tests are requires-docker. Filtering # them in the query lets such a scope resolve to empty and skip cleanly, # matching the tag filter applied to the run below. tests=$(bazel query --noshow_progress --output=label \ @@ -521,9 +564,9 @@ jobs: elif [ -z "$tests" ]; then # Not a coverage gap: requires-docker tests are excluded here (the # container has no Docker daemon) and run in the bazel-integration - # lane instead. A scope whose only tests are requires-docker (e.g. - # cloud-tasks) resolves empty here and is covered there. - echo "no non-docker test targets in scope; requires-docker tests run in the integration lane"; exit 0 + # lane instead. A scope whose only tests are requires-docker + # resolves empty here and is covered there. + echo "no non-docker test targets in scope; requires-docker tests run in the Docker-host lane"; exit 0 else printf '%s\n' "$tests" > "$ttfile" echo "tests: $(grep -c . "$ttfile") affected test target(s)" @@ -542,7 +585,7 @@ jobs: echo "quarantine: subtracted ${n:-0} pattern(s) from the root test set" fi # requires-docker tests (Testcontainers/DinD) run in the dedicated - # bazel-integration lane, not here; this matrix has no Docker daemon. + # Docker-host lane, not here; this matrix has no Docker daemon. # They still compile in the build step; only their execution is # deferred to that lane (see the bazel-integration job). COMMON=(--flaky_test_attempts=3 --test_tag_filters=-requires-docker) @@ -576,14 +619,32 @@ jobs: bazel test "${COMMON[@]}" --remote_cache= "${TARGETS[@]}" fi - # Per-service Docker lane. Each subtree that owns requires-docker + - name: Stage Java verification artifacts + if: ${{ always() && startsWith(matrix.subtree.component_kind, 'java-') }} + working-directory: ${{ matrix.subtree.workdir }} + run: | + bash tools/ci/stage-bazel-java-artifacts \ + "${{ matrix.subtree.id }}" \ + "${{ matrix.subtree.path }}" + + - name: Upload Java verification artifacts + if: ${{ always() && startsWith(matrix.subtree.component_kind, 'java-') }} + uses: actions/upload-artifact@v4 + with: + name: bazel-${{ matrix.subtree.id }}-verification-${{ github.run_attempt }} + path: ${{ runner.temp }}/bazel-java-verification/${{ matrix.subtree.id }} + if-no-files-found: error + retention-days: 14 + + # Docker-host lane. Each subtree that owns requires-docker # (Testcontainers) tests runs its FULL suite (unit + Testcontainers) here, in # its own visibly-named lane, with no tag filter -- so no test a subtree owns # is filtered out or deferred, and a green lane means that service's tests ran. # Runs on the bare ubuntu-latest runner (not the bazel-ci container) because # that runner ships a running Docker daemon, so Testcontainers uses the host # daemon directly -- no DinD, no host-override networking. These subtrees are - # excluded from the container matrix, so they never produce a zero-test lane. + # excluded from the build-container matrix, so they never produce a + # zero-test lane. # bazelisk reads .bazelversion for the pinned Bazel. bazel-docker: name: bazel (${{ matrix.subtree.id }}) @@ -618,7 +679,7 @@ jobs: working-directory: ${{ matrix.subtree.workdir }} # Full suite, NO tag filter: runs the subtree's unit AND requires-docker # (Testcontainers) tests against the host Docker daemon. A subtree whose - # only tests are requires-docker (cloud-tasks) still runs them all here. + # only tests are requires-docker still runs them all here. # bazel exit 4 (no test targets in scope) is treated as success. run: | set +e @@ -633,6 +694,23 @@ jobs: fi exit "$rc" + - name: Stage Java verification artifacts + if: ${{ always() && startsWith(matrix.subtree.component_kind, 'java-') }} + working-directory: ${{ matrix.subtree.workdir }} + run: | + bash tools/ci/stage-bazel-java-artifacts \ + "${{ matrix.subtree.id }}" \ + "${{ matrix.subtree.path }}" + + - name: Upload Java verification artifacts + if: ${{ always() && startsWith(matrix.subtree.component_kind, 'java-') }} + uses: actions/upload-artifact@v4 + with: + name: bazel-${{ matrix.subtree.id }}-verification-${{ github.run_attempt }} + path: ${{ runner.temp }}/bazel-java-verification/${{ matrix.subtree.id }} + if-no-files-found: error + retention-days: 14 + bazel-verification: name: bazel verification needs: [detect, bazel, bazel-docker] diff --git a/src/control-plane-services/cloud-tasks/BAZEL.md b/src/control-plane-services/cloud-tasks/BAZEL.md index c4f7398ee..c63600b5c 100644 --- a/src/control-plane-services/cloud-tasks/BAZEL.md +++ b/src/control-plane-services/cloud-tasks/BAZEL.md @@ -690,16 +690,97 @@ The monorepo uses `.github/workflows/bazel.yml`. There are no GitLab `ENABLE_BAZEL_*` variables for this subtree. The workflow detects Cloud Tasks or shared Java changes and selects the -appropriate service lane. The containerized fast lane excludes -`requires-docker` tests at query time. The per-service `bazel-docker` lane -receives Java 25 through `actions/setup-java`, uses the host Docker daemon, and -runs the complete Cloud Tasks test scope, including unit and Testcontainers -tests. Changes to nv-boot or shared Java tooling must also select Cloud Tasks -as a reverse-dependency validation target. - -GitHub CI currently proves build and test behavior. Container publication and -layered NOTICE enforcement are later phases. Bazel never publishes -Maven-shaped project artifacts. +appropriate service lane. The build-container lane excludes `requires-docker` +tests at query time. The Docker-host lane receives Java 25 through +`actions/setup-java`, uses the host Docker daemon, and runs the complete Cloud +Tasks test scope, including unit and Testcontainers tests. Changes to nv-boot +or shared Java tooling must also select Cloud Tasks as a reverse-dependency +validation target. + +GitHub CI proves build, test, coverage, and layered NOTICE behavior. Public +container publication remains a separate release-policy decision. Bazel never +publishes Maven-shaped project artifacts. + +The component-local `bazel-java-ci.json` registers Cloud Tasks with the root +workflow. The detector infers the component path from that file. A future Java +service adds its own descriptor with: + +```json +{ + "ci_lane": "docker-host", + "component_kind": "java-service", + "id": "service-id", + "tests_skip": false +} +``` + +That one descriptor supplies shared Java triggers, nv-boot reverse-dependency +validation, CI execution-environment routing, and report upload. Do not add the +service name to parallel lists in `.github/workflows/bazel.yml`. + +### CI Execution Environments + +The `ci_lane` descriptor field has two supported values: + +- `build-container`: GitHub Actions runs the job inside the pinned + `ghcr.io/nvidia/nvcf/bazel-ci` image. Its build tools are preinstalled, but + it does not expose the host Docker daemon. Use it only when the component's + complete test scope does not require Testcontainers or Docker commands. +- `docker-host`: GitHub Actions runs directly on the `ubuntu-latest` virtual + machine. The workflow installs Java and Bazelisk, and Docker is available. + Cloud Tasks uses this lane because its tests start Cassandra containers. + +This distinction belongs to the GitHub CI environment, not to Bazel itself. +On a developer machine, Maven and Bazel both use Docker Desktop when their +tests require containers. Under the current one-lane-per-component policy, a +component with even one `requires-docker` test uses `docker-host` for its +complete suite. A Java component with no Docker-dependent tests may use +`build-container`. + +### Bazel Scope + +Cloud Tasks is part of the monorepo root Bazel module. CI invokes Bazel from +the repository root with: + +```text +//src/control-plane-services/cloud-tasks/... +``` + +The descriptor no longer contains `scope_mode`. Earlier, +`scope_mode: root` stated that CI must run from the monorepo root instead of +entering Cloud Tasks and expecting a nested `MODULE.bazel`. All Java components +now use that root scope implicitly. Some existing non-Java components remain +independent nested Bazel modules, but that is not a supported option for Java +components integrated into this monorepo. + +### Downloading CI Reports + +Open the completed GitHub Actions workflow run and download: + +```text +bazel-cloud-tasks-verification-<run-attempt> +``` + +The artifact is retained for 14 days and contains: + +```text +generated/THIRD_PARTY_NOTICE +generated/runtime_inventory.json +generated/osrb_dependency_delta.json +generated/osrb_dependency_delta.md +testlogs/nvct-core/tests/test.log +testlogs/nvct-core/tests/test.outputs/junit/TEST-junit-jupiter.xml +testlogs/nvct-core/tests/test.outputs/jacoco.exec +testlogs/nvct-core/tests/test.outputs/jacoco.xml +testlogs/nvct-core/tests/test.outputs/index.html +testlogs/nvct-service/tests/test.outputs/... +``` + +Use the XML under `test.outputs/junit`; Bazel's outer `test.xml` describes the +shell test wrapper rather than the individual JUnit tests. The root-owned +`tools/ci/stage-bazel-java-artifacts` helper copies through Bazel's `bazel-bin` +and `bazel-testlogs` symlinks so the download contains real files after the CI +runner is destroyed. ## Clean diff --git a/src/control-plane-services/cloud-tasks/bazel-java-ci.json b/src/control-plane-services/cloud-tasks/bazel-java-ci.json new file mode 100644 index 000000000..cd805f6fa --- /dev/null +++ b/src/control-plane-services/cloud-tasks/bazel-java-ci.json @@ -0,0 +1,6 @@ +{ + "ci_lane": "docker-host", + "component_kind": "java-service", + "id": "cloud-tasks", + "tests_skip": false +} diff --git a/src/libraries/java/nv-boot-parent/BAZEL.md b/src/libraries/java/nv-boot-parent/BAZEL.md index 4f2565440..a978277ad 100644 --- a/src/libraries/java/nv-boot-parent/BAZEL.md +++ b/src/libraries/java/nv-boot-parent/BAZEL.md @@ -13,8 +13,8 @@ root. - Python: 3.11 through `rules_python` for Bazel NOTICE actions - Docker: required for Testcontainers-backed tests such as Cassandra tests -The root `.bazelrc` selects the local Java 25 JDK. The GitHub matrix image -provides Temurin 25 through `JAVA_HOME`; the Docker-capable lane uses +The root `.bazelrc` selects the local Java 25 JDK. The GitHub build-container +lane gets Temurin 25 from its pinned CI image; the Docker-host lane uses `actions/setup-java`. Local command examples use one portable cache location. Set it once per shell: @@ -442,14 +442,90 @@ The monorepo uses `.github/workflows/bazel.yml`; there is no GitLab `ENABLE_BAZEL_BUILD` variable for this subtree. The workflow detects nv-boot, shared Java tooling, root dependency, or consumer changes and selects: -- the containerized fast lane for tests that do not require Docker; -- the per-service Docker lane for complete Testcontainers scopes; and +- the build-container lane for tests that do not require a Docker daemon; +- the Docker-host lane for complete Testcontainers scopes; and - reverse-dependency consumer validation, including Cloud Tasks when nv-boot changes. GitHub CI builds and tests Bazel source targets. It does not publish Maven-shaped nv-boot artifacts. +The component-local `bazel-java-ci.json` registers nv-boot with the root +workflow. The detector infers the component path from that file and reads: + +```text +id +ci_lane +component_kind +tests_skip +``` + +`component_kind: java-framework` makes framework changes select every +discovered `java-service`. Shared root Java configuration, rules, and tools +select every discovered Java component. Do not add parallel component-name +lists to `.github/workflows/bazel.yml`. + +### CI Execution Environments + +The `ci_lane` descriptor field chooses where GitHub Actions executes Bazel: + +- `build-container`: the job runs inside the pinned + `ghcr.io/nvidia/nvcf/bazel-ci` image. Java, Bazelisk, and other build tools + are already installed. The host Docker daemon is not exposed there, so this + lane cannot run Testcontainers tests or build Docker images. +- `docker-host`: the job runs directly on GitHub's `ubuntu-latest` virtual + machine. The workflow installs Java and Bazelisk, and the host Docker daemon + is available to Testcontainers and Docker commands. + +This is CI routing, not a Maven-versus-Bazel difference. Local Maven and Bazel +commands both use Docker Desktop when their tests need containers. nv-boot uses +`docker-host` because its complete test scope includes Testcontainers tests. A +future Java component without such tests may use `build-container`. Under the +current one-lane-per-component policy, even one `requires-docker` test routes +the component's complete suite to `docker-host`. + +### Bazel Scope + +Every discovered Java component is part of the monorepo root Bazel module. +The workflow runs Bazel from the repository root and uses a scoped target such +as: + +```text +//src/libraries/java/nv-boot-parent/... +``` + +The first version of the descriptor called this `scope_mode: root`. The field +was removed because there is no supported alternative for Java components. +Some existing non-Java components are independent nested Bazel modules and run +from their own directories with `//...`, but imported Java frameworks and +services must not create nested `MODULE.bazel` files. + +### Downloading CI Reports + +Open the completed GitHub Actions workflow run and download: + +```text +bazel-nv-boot-parent-verification-<run-attempt> +``` + +The artifact is retained for 14 days and contains: + +```text +generated/THIRD_PARTY_NOTICE +generated/runtime_inventory.json +testlogs/<module>/tests/test.log +testlogs/<module>/tests/test.outputs/junit/TEST-junit-jupiter.xml +testlogs/<module>/tests/test.outputs/jacoco.exec +testlogs/<module>/tests/test.outputs/jacoco.xml +testlogs/<module>/tests/test.outputs/index.html +``` + +Use the XML under `test.outputs/junit`; Bazel's outer `test.xml` describes the +shell test wrapper rather than the individual JUnit tests. The root-owned +`tools/ci/stage-bazel-java-artifacts` helper copies through Bazel's `bazel-bin` +and `bazel-testlogs` symlinks so the download contains real files after the CI +runner is destroyed. + ## Build And Test Like `mvn clean install` For a Maven-like local validation loop: diff --git a/src/libraries/java/nv-boot-parent/bazel-java-ci.json b/src/libraries/java/nv-boot-parent/bazel-java-ci.json new file mode 100644 index 000000000..114fde1ae --- /dev/null +++ b/src/libraries/java/nv-boot-parent/bazel-java-ci.json @@ -0,0 +1,6 @@ +{ + "ci_lane": "docker-host", + "component_kind": "java-framework", + "id": "nv-boot-parent", + "tests_skip": false +} diff --git a/tools/ci/stage-bazel-java-artifacts b/tools/ci/stage-bazel-java-artifacts new file mode 100755 index 000000000..72723d178 --- /dev/null +++ b/tools/ci/stage-bazel-java-artifacts @@ -0,0 +1,36 @@ +#!/usr/bin/env bash +# SPDX-FileCopyrightText: Copyright (c) NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +set -euo pipefail + +subtree_id="${1:?usage: stage-bazel-java-artifacts SUBTREE_ID SUBTREE_PATH}" +subtree_path="${2:?usage: stage-bazel-java-artifacts SUBTREE_ID SUBTREE_PATH}" +artifact_root="${RUNNER_TEMP:?RUNNER_TEMP is required}/bazel-java-verification/${subtree_id}" +generated_root="${artifact_root}/generated" +testlogs_root="${artifact_root}/testlogs" + +mkdir -p "${generated_root}" "${testlogs_root}" + +source_testlogs="bazel-testlogs/${subtree_path}" +if [[ -d "${source_testlogs}" ]]; then + cp -R -L "${source_testlogs}/." "${testlogs_root}/" +fi + +source_outputs="bazel-bin/${subtree_path}" +for filename in \ + THIRD_PARTY_NOTICE \ + runtime_inventory.json \ + osrb_dependency_delta.json \ + osrb_dependency_delta.md; do + if [[ -f "${source_outputs}/${filename}" ]]; then + cp -L "${source_outputs}/${filename}" "${generated_root}/${filename}" + fi +done + +file_count="$(find "${artifact_root}" -type f | wc -l | tr -d ' ')" +junit_count="$(find "${testlogs_root}" -name 'TEST-junit-jupiter.xml' -type f | wc -l | tr -d ' ')" +jacoco_count="$(find "${testlogs_root}" -name 'jacoco.xml' -type f | wc -l | tr -d ' ')" + +echo "Staged ${file_count} files: ${junit_count} JUnit reports, ${jacoco_count} JaCoCo XML reports" +find "${generated_root}" -type f -print | LC_ALL=C sort From 3a0dcbaf6a56b224f3ef3663bb7a7a02cc83fde8 Mon Sep 17 00:00:00 2001 From: Sanjay Saxena <sasaxena@nvidia.com> Date: Thu, 23 Jul 2026 19:03:40 -0700 Subject: [PATCH 27/29] docs(bazel): complete monorepo Java guidance --- .github/workflows/bazel.yml | 12 +- BAZEL.md | 155 ++++++++++++++++-- .../cloud-tasks/BAZEL.md | 27 ++- src/libraries/java/nv-boot-parent/BAZEL.md | 31 +++- 4 files changed, 191 insertions(+), 34 deletions(-) diff --git a/.github/workflows/bazel.yml b/.github/workflows/bazel.yml index c02503e32..b3564fbb4 100644 --- a/.github/workflows/bazel.yml +++ b/.github/workflows/bazel.yml @@ -3,12 +3,12 @@ # # Bazel build + test on the public NVIDIA/nvcf mirror. # -# Change-aware: a cheap detect job diffs the push/PR and expands the -# build matrix to only the subtrees whose files changed. A docs-only -# mirror sync spawns zero build jobs instead of twelve, keeping the -# org-shared hosted-runner queue clear. workflow_dispatch, changes to -# this workflow file, and any diff that cannot be computed safely fall -# back to the full matrix. +# The detect job computes dependency-aware subtree selection, including shared +# Java triggers and framework-to-service reverse dependencies. Current policy +# deliberately forces the full matrix on every PR and push for regression +# safety; the change-aware result remains implemented and locally validated so +# that policy can be restored later by removing the documented run_all=true +# override. workflow_dispatch and unsafe/unknown diffs also use the full matrix. # # Matrix entries reference subtrees that have their Bazel scaffold # mirrored to GitHub (each subtree's upstream .oss-allowlist controls diff --git a/BAZEL.md b/BAZEL.md index b8e1cf7c0..f7cd23bec 100644 --- a/BAZEL.md +++ b/BAZEL.md @@ -1,11 +1,11 @@ # Bazel in the NVCF monorepo This file is the contributor-facing guide for the Bazel build path in the -NVCF umbrella repo. Bazel is the build engine for the native subtrees in -Phase 1; upstream-owned subtrees keep their existing build paths until they go -native. +NVCF umbrella repository. Bazel is the build engine for onboarded subtrees; +upstream-owned subtrees keep their existing build paths until they are +explicitly integrated. -## Phase 1 scope +## Current Scope Bazel currently builds, tests, and packages: @@ -16,8 +16,8 @@ Bazel currently builds, tests, and packages: Boot application) Other upstream-owned subtrees remain excluded until they are onboarded one at -a time. nv-boot-parent and Cloud Tasks are folded into the root Bazel module -and are not nested Bazel workspaces. +a time. `nv-boot-parent` and onboarded Java service directories are folded +into the root Bazel module and are not nested Bazel workspaces. ## One-time setup @@ -70,8 +70,21 @@ as that pins a different version. Java targets use Java 25 with the root `.bazelrc` setting `--java_runtime_version=local_jdk`. The pinned containerized CI image supplies -Temurin 25 through `JAVA_HOME`. The bare Docker-integration lane downloads and -configures Temurin 25 through the workflow's `actions/setup-java@v4` step. +Temurin 25 through `JAVA_HOME`. The Docker-host lane downloads and configures +Temurin 25 through the workflow's `actions/setup-java@v4` step. + +For local Java work, install an organization-approved full JDK 25 and point +`JAVA_HOME` at it: + +```bash +export JAVA_HOME="<path-to-jdk-25>" +export PATH="${JAVA_HOME}/bin:${PATH}" +java --version +``` + +Java services with Testcontainers tests and the nv-boot Cassandra tests also +require a running Docker daemon. Use Docker Desktop on macOS or Docker Engine +on Linux. `bazel info java-home` reports the Java runtime used to run the Bazel server. That directory is not guaranteed to contain command-line tools such as @@ -92,6 +105,114 @@ Both commands must print `25`. The normal Java build then proves that the compiler toolchain works; a separate `javac` command under `bazel info java-home` is neither required nor expected. +## Java In The Root Module + +`nv-boot-parent` and onboarded Java services are ordinary source directories +inside the single root `nvcf` Bazel module. They do not have nested +`MODULE.bazel`, `.bazelrc`, `.bazelversion`, downloader configuration, or +dependency lockfiles. Run their Bazel commands from this repository root. + +For someone familiar with Maven, these root files divide responsibilities that +often live in a parent POM, Maven settings, and the local repository: + +| Root file | Purpose | +|---|---| +| `.bazelversion` | Tells Bazelisk which Bazel release to run. | +| `.bazelrc` | Supplies shared Bazel flags, Java 25 toolchain settings, and downloader configuration. | +| `.bazel_downloader_config` | Redirects supported external downloads through approved mirrors. It does not declare dependencies. | +| `MODULE.bazel` | Declares Bazel rule modules, BOM imports, and the roots of the shared third-party Java graph. | +| `maven_install.json` | Locks resolved third-party Java artifacts, relationships, repositories, and checksums. Its name describes Maven-compatible coordinates; it does not run Maven. | +| `MODULE.bazel.lock` | Locks Bzlmod modules and module-extension evaluation. It is separate from the Java artifact lock. | + +Commit changes to these files together when one dependency update affects more +than one of them. Do not edit either lockfile manually. + +All Java components use the root-owned `@nv_third_party_deps` hub for external +jars. The hub contains third-party artifacts only. `nv-boot-parent` and each +service remain first-party source targets referenced with direct labels such +as: + +```text +//src/libraries/java/nv-boot-parent/nv-boot-starter-core:nv_boot_starter_core +//src/control-plane-services/<service-directory>/<module>:<target> +``` + +Set a portable output root once per local shell: + +```bash +export BAZEL_OUTPUT_USER_ROOT="${TMPDIR:-/tmp}/nvcf-bazel-cache" +export JAVA_SERVICE_DIR="src/control-plane-services/<service-directory>" +export JAVA_APP_MODULE="<spring-boot-app-module>" +``` + +Replace the angle-bracket placeholders with the service directory and its +Spring Boot application module. The component's own `BAZEL.md` supplies its +exact values and targets. + +Build or test the complete framework or one Java service: + +```bash +bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ + build //src/libraries/java/nv-boot-parent/... + +bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ + test //src/libraries/java/nv-boot-parent/... \ + --cache_test_results=no \ + --test_output=errors + +bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ + build "//${JAVA_SERVICE_DIR}/..." + +bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ + test "//${JAVA_SERVICE_DIR}/..." \ + --cache_test_results=no \ + --test_output=errors +``` + +When the selected scope includes Testcontainers tests, the complete suite +requires a running Docker daemon. `bazel test` automatically builds the code +needed by the selected tests; a separate build is useful for compile-only +feedback and for non-test products such as the Spring Boot app jar. + +Build the selected service's executable app jar with: + +```bash +bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ + build "//${JAVA_SERVICE_DIR}/${JAVA_APP_MODULE}:app" +``` + +Its output is: + +```text +bazel-bin/src/control-plane-services/<service-directory>/<spring-boot-app-module>/app.jar +``` + +Real Java test, JUnit, and JaCoCo outputs are under each target's +`bazel-testlogs/<component>/<module>/tests/test.outputs` directory. The +component guides provide commands for one module, class, or method and for +NOTICE, OSRB, Docker, and Maven coexistence: + +```text +src/libraries/java/nv-boot-parent/BAZEL.md +src/control-plane-services/<service-directory>/BAZEL.md +``` + +When the shared third-party Java graph changes, repin it from the root: + +```bash +REPIN=1 bazel --output_user_root="${BAZEL_OUTPUT_USER_ROOT}" \ + run @nv_third_party_deps//:pin +``` + +Java CI registration is component-local. Each component owns one +`bazel-java-ci.json`; `.github/workflows/bazel.yml` discovers those files and +derives shared-Java triggers, framework-to-service validation, CI execution +environment, and artifact upload. Use `ci_lane: docker-host` when any component +test requires Docker and `ci_lane: build-container` otherwise. Java root scope +is implicit and is not a descriptor option. The detector supports +dependency-aware selection, but current policy deliberately runs the full +matrix on every PR and push for regression safety. + ## Day-to-day commands ### Build @@ -161,7 +282,7 @@ bazel run //:gazelle bazel mod tidy ``` -Gazelle is configured to skip everything outside Phase 1 scope, so it will +Gazelle is configured to skip everything outside the current native scope, so it will not touch upstream-owned subtrees or vendored directories. #### Rust equivalent @@ -327,9 +448,9 @@ The detect job also enforces the single-module import boundary: bash tools/ci/check-java-import-boundaries ``` -Run this after refreshing nv-boot-parent or Cloud Tasks source. It fails when -a standalone Bazel root file, lockfile, workspace file, or migration directory -is reintroduced under either subtree. +Run this after refreshing `nv-boot-parent` or an onboarded Java service. It +fails when a standalone Bazel root file, lockfile, workspace file, or migration +directory is reintroduced under an imported subtree. The existing internal Bazel jobs include: @@ -373,7 +494,7 @@ build). ## Adding a new Go module -For native subtrees outside Phase 1 scope today: +For native subtrees outside the current scope: 1. Add the module path to `go.work.bazel` under `use (...)`. 2. Add or update its `go.mod`. @@ -463,7 +584,7 @@ maintainers; centralising it would couple unrelated release decisions. - `bazel info release` blocks for >30 s on first run: it is downloading the pinned Bazel binary. One-time cost. -## Phase B status +## Additional Subtree Rollout Per-service rollout state for upstream-owned subtrees is tracked in an internal plan that references upstream GitLab URLs and per-service rollout state that @@ -471,7 +592,7 @@ does not belong in the public mirror, including which upstream MRs are open, which are merged, and which umbrella `imports.yaml` bumps have landed. Update that internal plan as each service moves through the playbook. -## Out of scope (Phase B and later) +## Out of scope (Later Phase) - Wiring upstream-owned subtrees listed in `imports.yaml`. One MR per upstream owner. See the tracker. @@ -479,7 +600,7 @@ that internal plan as each service moves through the playbook. (archive/package/publish/ngc-push) onto Bazel-native equivalents (e.g. `pkg_tar`, `oci_push`, custom rules for NGC). Today the artifact contracts are preserved via copy-from-bazel-bin shims in CI. -- Coverage report generation in CI. `bazel coverage` works locally; CI - parsing of coverage output is deferred. +- Go coverage report publication in CI. Java JUnit and JaCoCo reports are + already generated and uploaded by their component lanes. - Lint integration. `golangci-lint` still runs as a separate job and is not yet wrapped into a Bazel rule. diff --git a/src/control-plane-services/cloud-tasks/BAZEL.md b/src/control-plane-services/cloud-tasks/BAZEL.md index c63600b5c..05df6a451 100644 --- a/src/control-plane-services/cloud-tasks/BAZEL.md +++ b/src/control-plane-services/cloud-tasks/BAZEL.md @@ -689,9 +689,11 @@ top-level path rollup, run `./tools/scripts/update-license`. The monorepo uses `.github/workflows/bazel.yml`. There are no GitLab `ENABLE_BAZEL_*` variables for this subtree. -The workflow detects Cloud Tasks or shared Java changes and selects the -appropriate service lane. The build-container lane excludes `requires-docker` -tests at query time. The Docker-host lane receives Java 25 through +The detector models Cloud Tasks, nv-boot, and shared Java changes, but current +policy deliberately runs the full matrix on every PR and push. If change-aware +scheduling is restored later, those relationships select the appropriate +service lane. The build-container lane excludes `requires-docker` tests at +query time. The Docker-host lane receives Java 25 through `actions/setup-java`, uses the host Docker daemon, and runs the complete Cloud Tasks test scope, including unit and Testcontainers tests. Changes to nv-boot or shared Java tooling must also select Cloud Tasks as a reverse-dependency @@ -782,6 +784,25 @@ shell test wrapper rather than the individual JUnit tests. The root-owned and `bazel-testlogs` symlinks so the download contains real files after the CI runner is destroyed. +## Maven Coexistence + +Maven and Bazel remain independent during coexistence. Maven consumers use the +Maven build and its published artifacts. Bazel consumers use source targets +from the monorepo and do not consume Maven-shaped project artifacts generated +by Bazel. + +Run the Maven reactor from the Cloud Tasks subtree: + +```bash +( + cd src/control-plane-services/cloud-tasks + mvn clean install +) +``` + +Maven writes under the modules' `target` directories. It does not consume +`bazel-bin`, and the Bazel build does not consume Maven `target` outputs. + ## Clean Clean Bazel outputs for this workspace: diff --git a/src/libraries/java/nv-boot-parent/BAZEL.md b/src/libraries/java/nv-boot-parent/BAZEL.md index a978277ad..ad11523ef 100644 --- a/src/libraries/java/nv-boot-parent/BAZEL.md +++ b/src/libraries/java/nv-boot-parent/BAZEL.md @@ -439,8 +439,10 @@ top-level path rollup, run `./tools/scripts/update-license`. ## GitHub CI The monorepo uses `.github/workflows/bazel.yml`; there is no GitLab -`ENABLE_BAZEL_BUILD` variable for this subtree. The workflow detects nv-boot, -shared Java tooling, root dependency, or consumer changes and selects: +`ENABLE_BAZEL_BUILD` variable for this subtree. Its detector models nv-boot, +shared Java tooling, root dependency, and consumer relationships. Current +policy deliberately runs the full matrix on every PR and push. If +change-aware scheduling is restored later, the detector selects: - the build-container lane for tests that do not require a Docker daemon; - the Docker-host lane for complete Testcontainers scopes; and @@ -559,6 +561,18 @@ During coexistence: `//src/libraries/java/nv-boot-parent/...`. - Bazel does not generate, install, or publish Maven-shaped project artifacts. +Run the independent Maven reactor from the nv-boot subtree: + +```bash +( + cd src/libraries/java/nv-boot-parent + mvn clean install +) +``` + +Maven writes under the subtree's `target` directories. It does not consume +`bazel-bin`, and the Bazel build does not consume Maven `target` outputs. + ## Dependency Updates When a module needs a new external dependency: @@ -570,7 +584,7 @@ When a module needs a new external dependency: 3. Prefer versionless coordinates when a BOM manages the version. 4. Add an explicit version only for intentional pins or CVE overrides. 5. If the dependency is shipped by a starter, update the nv-boot NOTICE roots - during the Phase 4 NOTICE workflow. + and metadata as part of the same change. 6. Repin and validate: ```bash @@ -601,7 +615,7 @@ For a new nv-boot module during coexistence: 5. Add `nv_boot_library(...)`. 6. Add `nv_boot_library_test(...)` if the module has tests, with `coverage_library` set to the module's `nv_boot_library(...)` target. -7. Update the nv-boot NOTICE roots during the Phase 4 NOTICE workflow. +7. Update the nv-boot NOTICE roots and metadata. 8. Update architecture or release docs if they list modules explicitly. For an internal-only Maven module, skip the Maven BOM entry. Its Bazel target @@ -634,8 +648,8 @@ Most of the migration work is Bazel-native: - build and test use Bazel Java targets and `nv_boot_library_test`, not `maven-surefire-plugin`; - coverage is generated by the Bazel test wrapper, not `jacoco-maven-plugin`; -- NOTICE generation is Bazel-native and is being completed as the layered - monorepo Phase 4 workflow, not through `license-maven-plugin`; +- NOTICE generation is Bazel-native and uses the layered monorepo workflow, + not `license-maven-plugin`; - module library jars are ordinary Bazel Java outputs; - POM generation, Maven-shaped artifact creation, local Maven installation, and remote Maven deployment are absent from the Bazel toolchain. @@ -680,8 +694,9 @@ separate cutover decision. Do not recreate it inside Bazel. artifact consumption. - Parent/BOM POM artifacts still come from the Maven build and checked-in `pom.xml` files during coexistence. -- GitHub CI build/test selection is integrated; layered NOTICE enforcement and - license-grouped OSRB delta output remain Phase 4. +- GitHub CI enforces nv-boot NOTICE drift and uploads its complete NOTICE and + runtime inventory. A license-grouped nv-boot OSRB delta still requires an + approved nv-boot baseline inventory. - The root dependency graph currently warns that protobuf expected `libprotoc 33.4` but selected `33.0`. - Downstream Spring Boot executable app packaging belongs to downstream app From 6934b8cce6b8c898e271d4ae27e761b07e03ffc5 Mon Sep 17 00:00:00 2001 From: Sanjay Saxena <sasaxena@nvidia.com> Date: Thu, 23 Jul 2026 21:51:02 -0700 Subject: [PATCH 28/29] build: make Zig toolchain root-only --- MODULE.bazel | 18 ++++++++++++++++-- tools/bazel/BUILD.bazel | 1 + tools/bazel/root_zig.bzl | 13 +++++++++++++ 3 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 tools/bazel/BUILD.bazel create mode 100644 tools/bazel/root_zig.bzl diff --git a/MODULE.bazel b/MODULE.bazel index 61deaccb4..ba2b262ee 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -39,7 +39,12 @@ bazel_dep(name = "platforms", version = "1.0.0") bazel_dep(name = "rules_oci", version = "2.2.7") bazel_dep(name = "rules_pkg", version = "1.2.0") bazel_dep(name = "aspect_bazel_lib", version = "2.19.3") -bazel_dep(name = "hermetic_cc_toolchain", version = "4.1.0") + +bazel_dep( + name = "hermetic_cc_toolchain", + version = "4.1.0", + dev_dependency = True, +) python = use_extension("@rules_python//python/extensions:python.bzl", "python") python.toolchain( @@ -98,11 +103,20 @@ use_repo(go_deps, "cat_dario_mergo", "com_github_aws_aws_sdk_go_v2", "com_github # C++ cross-compilation (multi-arch container builds). # Only register the cross toolchain; native arch uses host gcc. # ============================================================================ -zig = use_extension("@hermetic_cc_toolchain//toolchain:ext.bzl", "toolchains") +# The upstream extension only creates zig_sdk for the root module, which makes +# its use_repo declaration invalid when nvcf is consumed as a dependency. This +# root-owned adapter keeps the cross toolchain active here and drops the entire +# usage for external consumers. +zig = use_extension( + "//tools/bazel:root_zig.bzl", + "root_zig", + dev_dependency = True, +) use_repo(zig, "zig_sdk") register_toolchains( "@zig_sdk//toolchain:linux_arm64_gnu.2.38", + dev_dependency = True, ) # ============================================================================ diff --git a/tools/bazel/BUILD.bazel b/tools/bazel/BUILD.bazel new file mode 100644 index 000000000..9b655f630 --- /dev/null +++ b/tools/bazel/BUILD.bazel @@ -0,0 +1 @@ +exports_files(["root_zig.bzl"]) diff --git a/tools/bazel/root_zig.bzl b/tools/bazel/root_zig.bzl new file mode 100644 index 000000000..484e2534c --- /dev/null +++ b/tools/bazel/root_zig.bzl @@ -0,0 +1,13 @@ +"""Root-only Zig repository adapter for the NVCF monorepo.""" + +load("@hermetic_cc_toolchain//toolchain:defs.bzl", zig_toolchains = "toolchains") + +def _root_zig_impl(module_ctx): + repos = zig_toolchains() + return module_ctx.extension_metadata( + reproducible = True, + root_module_direct_dev_deps = list(repos.public), + root_module_direct_deps = [], + ) + +root_zig = module_extension(implementation = _root_zig_impl) From bfb3976f44f6caef4561e41171c33c2d178ecc72 Mon Sep 17 00:00:00 2001 From: Sanjay Saxena <sasaxena@nvidia.com> Date: Thu, 23 Jul 2026 23:09:08 -0700 Subject: [PATCH 29/29] Preserve nvct-core fixture resources for external consumers --- src/control-plane-services/cloud-tasks/BUILD.bazel | 1 + src/control-plane-services/cloud-tasks/nvct-core/BUILD.bazel | 3 +++ 2 files changed, 4 insertions(+) diff --git a/src/control-plane-services/cloud-tasks/BUILD.bazel b/src/control-plane-services/cloud-tasks/BUILD.bazel index 707c00733..3ad4e40c5 100644 --- a/src/control-plane-services/cloud-tasks/BUILD.bazel +++ b/src/control-plane-services/cloud-tasks/BUILD.bazel @@ -29,6 +29,7 @@ nvct_workspace_runfiles( name = "integration_local_env", srcs = [":integration_local_env_files"], strip_prefix = "src/control-plane-services/cloud-tasks/", + visibility = ["//src/control-plane-services/cloud-tasks:__subpackages__"], ) nvcf_notice( diff --git a/src/control-plane-services/cloud-tasks/nvct-core/BUILD.bazel b/src/control-plane-services/cloud-tasks/nvct-core/BUILD.bazel index dc9ca4be4..c45f7d57f 100644 --- a/src/control-plane-services/cloud-tasks/nvct-core/BUILD.bazel +++ b/src/control-plane-services/cloud-tasks/nvct-core/BUILD.bazel @@ -204,6 +204,9 @@ nvct_library( name = "nvct_core_test_fixtures", srcs = NVCT_CORE_TEST_SRCS, deps = NVCT_CORE_TEST_DEPS, + # Preserve the classpath layout of the standalone cloud-tasks fixture jar + # after moving its sources under this monorepo directory. + resource_strip_prefix = "src/control-plane-services/cloud-tasks", resources = NVCT_CORE_TEST_RESOURCES, )