From 9c9b4ebbe0849bde414464d2222356afbe1c1d11 Mon Sep 17 00:00:00 2001 From: Yuichi <913637919@qq.com> Date: Thu, 21 Nov 2024 09:22:38 +0000 Subject: [PATCH 01/48] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=83=A8=E5=88=86?= =?UTF-8?q?=E5=87=BD=E6=95=B0=E5=AE=9A=E4=B9=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.lock | 625 +++++++++++++++++++++++++++++++++++++++-- Cargo.toml | 1 + src/cores/apiserver.rs | 125 +++++++-- src/cores/handlers.rs | 372 +++++++++++++++++++++--- src/main.rs | 34 +-- 5 files changed, 1041 insertions(+), 116 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b797beb..e127116 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -30,7 +30,7 @@ dependencies = [ "actix-service", "actix-utils", "ahash", - "base64", + "base64 0.22.1", "bitflags", "brotli", "bytes", @@ -308,6 +308,35 @@ version = "1.0.91" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c042108f3ed77fd83760a5fd79b53be043192bb3b9dba91d8c574c0ada7850c8" +[[package]] +name = "async-nats" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23f02c8b692d7eea2cfcdf58b43031b163efd93aa99c01d2a9e796168d37dcf1" +dependencies = [ + "base64-url", + "bytes", + "futures", + "http 0.2.12", + "itoa", + "nkeys", + "nuid", + "once_cell", + "regex", + "rustls-pemfile", + "serde", + "serde_json", + "serde_nanos", + "serde_repr", + "subslice", + "time", + "tokio", + "tokio-rustls", + "tokio-util", + "url", + "webpki-roots", +] + [[package]] name = "async-trait" version = "0.1.83" @@ -340,12 +369,33 @@ dependencies = [ "windows-targets", ] +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + [[package]] name = "base64" version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +[[package]] +name = "base64-url" +version = "1.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67a99c239d0c7e77c85dddfa9cebce48704b3c49550fcd3b84dd637e4484899f" +dependencies = [ + "base64 0.13.1", +] + +[[package]] +name = "base64ct" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6b4d9b1225d28d360ec6a231d65af1fd99a2a095154c8040689617290569c5c" + [[package]] name = "bit-set" version = "0.5.3" @@ -367,6 +417,15 @@ version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array", +] + [[package]] name = "block-buffer" version = "0.10.4" @@ -468,12 +527,40 @@ dependencies = [ "windows-targets", ] +[[package]] +name = "chrono-tz" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29c39203181991a7dd4343b8005bd804e7a9a37afb8ac070e43771e8c820bbde" +dependencies = [ + "chrono", + "chrono-tz-build", + "phf", +] + +[[package]] +name = "chrono-tz-build" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f509c3a87b33437b05e2458750a0700e5bdd6956176773e6c7d6dd15a283a0c" +dependencies = [ + "parse-zoneinfo", + "phf", + "phf_codegen", +] + [[package]] name = "colorchoice" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" +[[package]] +name = "const-oid" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d6f2aa4d0537bcc1c74df8755072bd31c1ef1a3a1b85a68e8404a8c353b7b8b" + [[package]] name = "convert_case" version = "0.4.0" @@ -525,6 +612,19 @@ dependencies = [ "typenum", ] +[[package]] +name = "curve25519-dalek" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" +dependencies = [ + "byteorder", + "digest 0.9.0", + "rand_core 0.5.1", + "subtle", + "zeroize", +] + [[package]] name = "darling" version = "0.20.10" @@ -560,6 +660,21 @@ dependencies = [ "syn", ] +[[package]] +name = "data-encoding" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2" + +[[package]] +name = "der" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79b71cca7d95d7681a4b3b9cdf63c8dbc3730d0584c2c74e31416d64a90493f4" +dependencies = [ + "const-oid", +] + [[package]] name = "deranged" version = "0.3.11" @@ -567,6 +682,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" dependencies = [ "powerfmt", + "serde", ] [[package]] @@ -631,13 +747,22 @@ dependencies = [ "syn", ] +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + [[package]] name = "digest" version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "block-buffer", + "block-buffer 0.10.4", "crypto-common", ] @@ -678,6 +803,27 @@ version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" +[[package]] +name = "ed25519" +version = "1.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91cff35c70bba8a626e3185d8cd48cc11b5437e1a5bcd15b9b5fa3c64b6dfee7" +dependencies = [ + "signature", +] + +[[package]] +name = "ed25519-dalek" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" +dependencies = [ + "curve25519-dalek", + "ed25519", + "sha2", + "zeroize", +] + [[package]] name = "either" version = "1.13.0" @@ -742,6 +888,24 @@ dependencies = [ "regex-syntax", ] +[[package]] +name = "feventbus" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b44fa2d92d2434c95a5da95cca25861a437eb63fc3c164a07ea023481e255d0" +dependencies = [ + "async-nats", + "async-trait", + "bytes", + "chrono", + "chrono-tz", + "futures", + "serde", + "serde_json", + "thiserror", + "tokio", +] + [[package]] name = "flate2" version = "1.0.34" @@ -788,6 +952,21 @@ dependencies = [ "num", ] +[[package]] +name = "futures" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + [[package]] name = "futures-channel" version = "0.3.31" @@ -804,12 +983,34 @@ version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" +[[package]] +name = "futures-executor" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + [[package]] name = "futures-io" version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" +[[package]] +name = "futures-macro" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "futures-sink" version = "0.3.31" @@ -828,8 +1029,10 @@ version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ + "futures-channel", "futures-core", "futures-io", + "futures-macro", "futures-sink", "futures-task", "memchr", @@ -1232,7 +1435,7 @@ checksum = "bea85509e7320309cc8be62d8badb46f9525157bdc748bf2ec089cd4083a3f7e" dependencies = [ "ahash", "anyhow", - "base64", + "base64 0.22.1", "bytecount", "email_address", "fancy-regex", @@ -1257,7 +1460,7 @@ version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8847402328d8301354c94d605481f25a6bdc1ed65471fd96af8eca71141b13" dependencies = [ - "base64", + "base64 0.22.1", "chrono", "serde", "serde-value", @@ -1277,6 +1480,7 @@ dependencies = [ "diesel_migrations", "dotenv", "env_logger", + "feventbus", "jsonschema", "k8s-openapi", "once_cell", @@ -1409,6 +1613,31 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "nkeys" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e66a7cd1358277b2a6f77078e70aea7315ff2f20db969cc61153103ec162594" +dependencies = [ + "byteorder", + "data-encoding", + "ed25519-dalek", + "getrandom", + "log", + "rand", + "signatory", +] + +[[package]] +name = "nuid" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20c1bb65186718d348306bf1afdeb20d9ab45b2ab80fb793c0fdcf59ffbb4f38" +dependencies = [ + "lazy_static", + "rand", +] + [[package]] name = "num" version = "0.4.3" @@ -1509,6 +1738,12 @@ version = "1.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" +[[package]] +name = "opaque-debug" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" + [[package]] name = "ordered-float" version = "2.10.1" @@ -1547,18 +1782,75 @@ dependencies = [ "windows-targets", ] +[[package]] +name = "parse-zoneinfo" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f2a05b18d44e2957b88f96ba460715e295bc1d7510468a2f3d3b44535d26c24" +dependencies = [ + "regex", +] + [[package]] name = "paste" version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" +[[package]] +name = "pem-rfc7468" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84e93a3b1cc0510b03020f33f21e62acdde3dcaef432edc95bea377fbd4c2cd4" +dependencies = [ + "base64ct", +] + [[package]] name = "percent-encoding" version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +[[package]] +name = "phf" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" +dependencies = [ + "phf_shared", +] + +[[package]] +name = "phf_codegen" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8d39688d359e6b34654d328e262234662d16cc0f60ec8dcbe5e718709342a5a" +dependencies = [ + "phf_generator", + "phf_shared", +] + +[[package]] +name = "phf_generator" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" +dependencies = [ + "phf_shared", + "rand", +] + +[[package]] +name = "phf_shared" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" +dependencies = [ + "siphasher", + "uncased", +] + [[package]] name = "pin-project-lite" version = "0.2.14" @@ -1571,6 +1863,18 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "pkcs8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee3ef9b64d26bad0536099c816c6734379e45bbd5f14798def6809e5cc350447" +dependencies = [ + "der", + "pem-rfc7468", + "spki", + "zeroize", +] + [[package]] name = "pkg-config" version = "0.3.31" @@ -1603,9 +1907,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.87" +version = "1.0.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3e4daa0dcf6feba26f985457cdf104d4b4256fc5a09547140f3631bb076b19a" +checksum = "307e3004becf10f5a6e0d59d20f3cd28231b0e0827a96cd3e0ce6d14bc1e4bb3" dependencies = [ "unicode-ident", ] @@ -1638,7 +1942,7 @@ checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", "rand_chacha", - "rand_core", + "rand_core 0.6.4", ] [[package]] @@ -1648,9 +1952,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core", + "rand_core 0.6.4", ] +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" + [[package]] name = "rand_core" version = "0.6.4" @@ -1743,7 +2053,7 @@ version = "0.12.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a77c62af46e79de0a562e1a9849205ffcb7fc1238876e9bd743357570e04046f" dependencies = [ - "base64", + "base64 0.22.1", "bytes", "futures-channel", "futures-core", @@ -1773,6 +2083,36 @@ dependencies = [ "windows-registry", ] +[[package]] +name = "ring" +version = "0.16.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" +dependencies = [ + "cc", + "libc", + "once_cell", + "spin 0.5.2", + "untrusted 0.7.1", + "web-sys", + "winapi", +] + +[[package]] +name = "ring" +version = "0.17.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" +dependencies = [ + "cc", + "cfg-if", + "getrandom", + "libc", + "spin 0.9.8", + "untrusted 0.9.0", + "windows-sys", +] + [[package]] name = "rustc-demangle" version = "0.1.24" @@ -1788,6 +2128,27 @@ dependencies = [ "semver", ] +[[package]] +name = "rustls" +version = "0.20.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b80e3dec595989ea8510028f30c408a4630db12c9cbb8de34203b89d6577e99" +dependencies = [ + "log", + "ring 0.16.20", + "sct", + "webpki", +] + +[[package]] +name = "rustls-pemfile" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ee86d63972a7c661d1536fefe8c3c8407321c3df668891286de28abcd087360" +dependencies = [ + "base64 0.13.1", +] + [[package]] name = "ryu" version = "1.0.18" @@ -1833,6 +2194,16 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "sct" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" +dependencies = [ + "ring 0.17.8", + "untrusted 0.9.0", +] + [[package]] name = "semver" version = "1.0.23" @@ -1841,9 +2212,9 @@ checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "serde" -version = "1.0.210" +version = "1.0.215" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" +checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f" dependencies = [ "serde_derive", ] @@ -1860,9 +2231,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.210" +version = "1.0.215" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" +checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" dependencies = [ "proc-macro2", "quote", @@ -1882,9 +2253,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.128" +version = "1.0.133" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" +checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377" dependencies = [ "itoa", "memchr", @@ -1892,6 +2263,26 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_nanos" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a93142f0367a4cc53ae0fead1bcda39e85beccfad3dcd717656cacab94b12985" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_repr" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "serde_spanned" version = "0.6.8" @@ -1921,7 +2312,20 @@ checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" dependencies = [ "cfg-if", "cpufeatures", - "digest", + "digest 0.10.7", +] + +[[package]] +name = "sha2" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if", + "cpufeatures", + "digest 0.9.0", + "opaque-debug", ] [[package]] @@ -1939,6 +2343,30 @@ dependencies = [ "libc", ] +[[package]] +name = "signatory" +version = "0.23.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dfecc059e81632eef1dd9b79e22fc28b8fe69b30d3357512a77a0ad8ee3c782" +dependencies = [ + "pkcs8", + "rand_core 0.6.4", + "signature", + "zeroize", +] + +[[package]] +name = "signature" +version = "1.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" + +[[package]] +name = "siphasher" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" + [[package]] name = "slab" version = "0.4.9" @@ -1964,6 +2392,27 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + +[[package]] +name = "spki" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c01a0c15da1b0b0e1494112e7af814a678fec9bd157881b49beac661e9b6f32" +dependencies = [ + "der", +] + [[package]] name = "stable_deref_trait" version = "1.2.0" @@ -1976,11 +2425,26 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" +[[package]] +name = "subslice" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0a8e4809a3bb02de01f1f7faf1ba01a83af9e8eabcd4d31dd6e413d14d56aae" +dependencies = [ + "memchr", +] + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + [[package]] name = "syn" -version = "2.0.79" +version = "2.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" +checksum = "44d46482f1c1c87acd84dea20c1bf5ebff4c757009ed6bf19cfd36fb10e92c4e" dependencies = [ "proc-macro2", "quote", @@ -2007,6 +2471,26 @@ dependencies = [ "syn", ] +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "time" version = "0.3.36" @@ -2077,9 +2561,32 @@ dependencies = [ "pin-project-lite", "signal-hook-registry", "socket2", + "tokio-macros", "windows-sys", ] +[[package]] +name = "tokio-macros" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tokio-rustls" +version = "0.23.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59" +dependencies = [ + "rustls", + "tokio", + "webpki", +] + [[package]] name = "tokio-util" version = "0.7.12" @@ -2165,6 +2672,15 @@ version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" +[[package]] +name = "uncased" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1b88fcfe09e89d3866a5c11019378088af2d24c3fbd4f0543f96b479ec90697" +dependencies = [ + "version_check", +] + [[package]] name = "unicode-bidi" version = "0.3.17" @@ -2186,6 +2702,18 @@ dependencies = [ "tinyvec", ] +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + [[package]] name = "url" version = "2.5.2" @@ -2342,6 +2870,47 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "webpki" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed63aea5ce73d0ff405984102c42de94fc55a6b75765d621c65262469b3c9b53" +dependencies = [ + "ring 0.17.8", + "untrusted 0.9.0", +] + +[[package]] +name = "webpki-roots" +version = "0.22.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c71e40d7d2c34a5106301fb632274ca37242cd0c9d3e64dbece371a40a2d87" +dependencies = [ + "webpki", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + [[package]] name = "windows-core" version = "0.52.0" @@ -2541,6 +3110,26 @@ dependencies = [ "synstructure", ] +[[package]] +name = "zeroize" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "zerovec" version = "0.10.4" diff --git a/Cargo.toml b/Cargo.toml index 0e042eb..c2920a2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,6 +11,7 @@ repository = "https://gitee.com/iscas-system/apiserver" readme = "README.md" [dependencies] +feventbus = "0.2.0" r2d2 = "0.8.10" dotenv = "0.15.0" diesel = { version = "2.2.0", features = ["sqlite", "postgres", "r2d2"] } diff --git a/src/cores/apiserver.rs b/src/cores/apiserver.rs index ea18e79..599f757 100644 --- a/src/cores/apiserver.rs +++ b/src/cores/apiserver.rs @@ -11,6 +11,8 @@ use crate::cores::config::{Config, APIS_WITHOUT_NAMESPACE, APIS_WITH_NAMESPACE, use crate::cores::handlers::{Handler}; use std::sync::{Arc}; +use feventbus::impls::nats::nats::NatsCli; +use feventbus::traits::controller::EventBus; use crate::cores::db::{DbPool}; pub struct ApiServer @@ -33,6 +35,8 @@ impl ApiServer (self: Arc, addr: &str, handler: T, db_pool: Arc) -> Result<(), std::io::Error> { let handler = Arc::new(handler); + // 初始化 NatsCli 实例 + let nats_cli = Arc::new(NatsCli::new().await.unwrap()); let server = HttpServer::new(move || { @@ -40,6 +44,7 @@ impl ApiServer let handler = Arc::clone(&handler); let config = Arc::clone(&self.config); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); // URL是手动注册的,不会存在APIS_WITHOUT_NAMESPACE, APIS_WITH_NAMESPACE, // API_WITHOUT_NAMESPACE, API_WITH_NAMESPACE之外情况 @@ -47,16 +52,20 @@ impl ApiServer if route == API_WITHOUT_NAMESPACE { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + app = app.route(key, web::post().to( move |path, data| { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { Ok(mut conn) => { handler .default() - .create_api_without_namespace(path, data, &mut conn) + .create_api_without_namespace(path, data, &mut conn, nats_cli) .await }, Err(_) => Err(actix_web::error::ErrorInternalServerError( @@ -68,16 +77,20 @@ impl ApiServer } else if route == API_WITH_NAMESPACE { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + app = app.route(key, web::post().to( move |path, data| { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { Ok(mut conn) => { handler .default() - .create_api_with_namespace(path, data, &mut conn) + .create_api_with_namespace(path, data, &mut conn, nats_cli) .await }, Err(_) => Err(actix_web::error::ErrorInternalServerError( @@ -89,16 +102,20 @@ impl ApiServer } else if route == APIS_WITHOUT_NAMESPACE { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + app = app.route(key, web::post().to( move |path, data| { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { Ok(mut conn) => { handler .default() - .create_apis_without_namespace(path, data, &mut conn) + .create_apis_without_namespace(path, data, &mut conn, nats_cli) .await }, Err(_) => Err(actix_web::error::ErrorInternalServerError( @@ -110,16 +127,20 @@ impl ApiServer } else if route == APIS_WITH_NAMESPACE { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + app = app.route(key, web::post().to( move |path, data| { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { Ok(mut conn) => { handler .default() - .create_apis_with_namespace(path, data, &mut conn) + .create_apis_with_namespace(path, data, &mut conn, nats_cli) .await }, Err(_) => Err(actix_web::error::ErrorInternalServerError( @@ -137,16 +158,20 @@ impl ApiServer if route == API_WITHOUT_NAMESPACE { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + app = app.route(key, web::delete().to( move |path| { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { Ok(mut conn) => { handler .default() - .delete_api_without_namespace(path, &mut conn) + .delete_api_without_namespace(path, &mut conn, nats_cli) .await }, Err(_) => Err(actix_web::error::ErrorInternalServerError( @@ -158,16 +183,20 @@ impl ApiServer } else if route == API_WITH_NAMESPACE { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + app = app.route(key, web::delete().to( move |path| { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { Ok(mut conn) => { handler .default() - .delete_api_with_namespace(path, &mut conn) + .delete_api_with_namespace(path, &mut conn, nats_cli) .await }, Err(_) => Err(actix_web::error::ErrorInternalServerError( @@ -179,16 +208,20 @@ impl ApiServer } else if route == APIS_WITHOUT_NAMESPACE { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + app = app.route(key, web::delete().to( move |path| { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { Ok(mut conn) => { handler .default() - .delete_apis_without_namespace(path, &mut conn) + .delete_apis_without_namespace(path, &mut conn, nats_cli) .await }, Err(_) => Err(actix_web::error::ErrorInternalServerError( @@ -200,16 +233,20 @@ impl ApiServer } else if route == APIS_WITH_NAMESPACE { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + app = app.route(key, web::delete().to( move |path| { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { Ok(mut conn) => { handler .default() - .delete_apis_with_namespace(path, &mut conn) + .delete_apis_with_namespace(path, &mut conn, nats_cli) .await }, Err(_) => Err(actix_web::error::ErrorInternalServerError( @@ -227,16 +264,20 @@ impl ApiServer if route == API_WITHOUT_NAMESPACE { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + app = app.route(key, web::put().to( move |path, data| { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { Ok(mut conn) => { handler .default() - .update_api_without_namespace(path, data, &mut conn) + .update_api_without_namespace(path, data, &mut conn, nats_cli) .await }, Err(_) => Err(actix_web::error::ErrorInternalServerError( @@ -248,16 +289,20 @@ impl ApiServer } else if route == API_WITH_NAMESPACE { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + app = app.route(key, web::put().to( move |path, data| { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { Ok(mut conn) => { handler .default() - .update_api_with_namespace(path, data, &mut conn) + .update_api_with_namespace(path, data, &mut conn, nats_cli) .await }, Err(_) => Err(actix_web::error::ErrorInternalServerError( @@ -269,16 +314,20 @@ impl ApiServer } else if route == APIS_WITHOUT_NAMESPACE { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + app = app.route(key, web::put().to( move |path, data| { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { Ok(mut conn) => { handler .default() - .update_apis_without_namespace(path, data, &mut conn) + .update_apis_without_namespace(path, data, &mut conn, nats_cli) .await }, Err(_) => Err(actix_web::error::ErrorInternalServerError( @@ -290,16 +339,20 @@ impl ApiServer } else if route == APIS_WITH_NAMESPACE { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + app = app.route(key, web::put().to( move |path, data| { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { Ok(mut conn) => { handler .default() - .update_apis_with_namespace(path, data, &mut conn) + .update_apis_with_namespace(path, data, &mut conn, nats_cli) .await }, Err(_) => Err(actix_web::error::ErrorInternalServerError( @@ -317,16 +370,20 @@ impl ApiServer if route == API_WITHOUT_NAMESPACE { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + app = app.route(key, web::get().to( move |path, data| { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { Ok(mut conn) => { handler .default() - .getone_api_without_namespace(path, data, &mut conn) + .getone_api_without_namespace(path, data, &mut conn, nats_cli) .await }, Err(_) => Err(actix_web::error::ErrorInternalServerError( @@ -338,16 +395,20 @@ impl ApiServer } else if route == API_WITH_NAMESPACE { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + app = app.route(key, web::get().to( move |path, data| { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { Ok(mut conn) => { handler .default() - .getone_api_with_namespace(path, data, &mut conn) + .getone_api_with_namespace(path, data, &mut conn, nats_cli) .await }, Err(_) => Err(actix_web::error::ErrorInternalServerError( @@ -359,16 +420,20 @@ impl ApiServer } else if route == APIS_WITHOUT_NAMESPACE { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + app = app.route(key, web::get().to( move |path, data| { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { Ok(mut conn) => { handler .default() - .getone_apis_without_namespace(path, data, &mut conn) + .getone_apis_without_namespace(path, data, &mut conn, nats_cli) .await }, Err(_) => Err(actix_web::error::ErrorInternalServerError( @@ -380,16 +445,20 @@ impl ApiServer } else if route == APIS_WITH_NAMESPACE { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + app = app.route(key, web::get().to( move |path, data| { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { Ok(mut conn) => { handler .default() - .getone_apis_with_namespace(path, data, &mut conn) + .getone_apis_with_namespace(path, data, &mut conn, nats_cli) .await }, Err(_) => Err(actix_web::error::ErrorInternalServerError( @@ -408,16 +477,20 @@ impl ApiServer if route == API_WITHOUT_NAMESPACE { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + app = app.route(key, web::get().to( move |path, data| { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { Ok(mut conn) => { handler .default() - .listall_api_without_namespace(path, data, &mut conn) + .listall_api_without_namespace(path, data, &mut conn, nats_cli) .await }, Err(_) => Err(actix_web::error::ErrorInternalServerError( @@ -429,16 +502,20 @@ impl ApiServer } else if route == API_WITH_NAMESPACE { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + app = app.route(key, web::get().to( move |path, data| { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { Ok(mut conn) => { handler .default() - .listall_api_with_namespace(path, data, &mut conn) + .listall_api_with_namespace(path, data, &mut conn, nats_cli) .await }, Err(_) => Err(actix_web::error::ErrorInternalServerError( @@ -450,16 +527,20 @@ impl ApiServer } else if route == APIS_WITHOUT_NAMESPACE { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + app = app.route(key, web::get().to( move |path, data| { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { Ok(mut conn) => { handler .default() - .listall_apis_without_namespace(path, data, &mut conn) + .listall_apis_without_namespace(path, data, &mut conn, nats_cli) .await }, Err(_) => Err(actix_web::error::ErrorInternalServerError( @@ -471,16 +552,20 @@ impl ApiServer } else if route == APIS_WITH_NAMESPACE { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + app = app.route(key, web::get().to( move |path, data| { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { Ok(mut conn) => { handler .default() - .listall_apis_with_namespace(path, data, &mut conn) + .listall_apis_with_namespace(path, data, &mut conn, nats_cli) .await }, Err(_) => Err(actix_web::error::ErrorInternalServerError( diff --git a/src/cores/handlers.rs b/src/cores/handlers.rs index 9e73695..88c7f08 100644 --- a/src/cores/handlers.rs +++ b/src/cores/handlers.rs @@ -1,3 +1,4 @@ +use std::sync::Arc; /** * Copyright (2024, ) Institute of Software, Chinese Academy of Sciences * author: wuheng@iscas.ac.cn @@ -14,68 +15,226 @@ use serde_json::Value; use crate::cores::db::DbConnection; use diesel::sql_types::{Text}; use actix_web::error::ErrorInternalServerError; +use feventbus::impls::nats::nats::NatsCli; +use serde::{Deserialize, Serialize}; #[async_trait] pub trait Handler { // /api/{version}/{plural} - async fn create_api_without_namespace(&self, info: web::Path<(String, String)>, data: web::Json, db_connection: &mut DbConnection) -> Result; + async fn create_api_without_namespace( + &self, + info: web::Path<(String, String)>, + data: web::Json, + db_connection: &mut DbConnection, + nats_cli: Arc>, + ) -> Result + where + T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; // /api/{version}/namespaces/{namespace}/{plural} - async fn create_api_with_namespace(&self, info: web::Path<(String, String, String)>, data: web::Json, db_connection: &mut DbConnection) -> Result; + async fn create_api_with_namespace( + &self, + info: web::Path<(String, String, String)>, + data: web::Json, + db_connection: &mut DbConnection, + nats_cli: Arc>, + ) -> Result + where + T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; // /apis/{group}/{version}/{plural} - async fn create_apis_without_namespace(&self, info: web::Path<(String, String, String)>, data: web::Json, db_connection: &mut DbConnection) -> Result; + async fn create_apis_without_namespace( + &self, + info: web::Path<(String, String, String)>, + data: web::Json, + db_connection: &mut DbConnection, + nats_cli: Arc>, + ) -> Result + where + T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; // /apis/{group}/{version}/namespaces/{namespace}/{plural} - async fn create_apis_with_namespace(&self, info: web::Path<(String, String, String, String)>, data: web::Json, db_connection: &mut DbConnection) -> Result; + async fn create_apis_with_namespace( + &self, + info: web::Path<(String, String, String, String)>, + data: web::Json, + db_connection: &mut DbConnection, + nats_cli: Arc>, + ) -> Result + where + T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; // /api/{version}/{plural}/{name} - async fn delete_api_without_namespace(&self, info: web::Path<(String, String, String)>, db_connection: &mut DbConnection) -> Result; + async fn delete_api_without_namespace( + &self, + info: web::Path<(String, String, String)>, + db_connection: &mut DbConnection, + nats_cli: Arc>, + ) -> Result + where + T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; // /api/{version}/namespaces/{namespace}/{plural}/{name} - async fn delete_api_with_namespace(&self, info: web::Path<(String, String, String, String)>, db_connection: &mut DbConnection) -> Result; + async fn delete_api_with_namespace( + &self, + info: web::Path<(String, String, String, String)>, + db_connection: &mut DbConnection, + nats_cli: Arc>, + ) -> Result + where + T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; // /apis/{group}/{version}/{plural}/{name} - async fn delete_apis_without_namespace(&self, info: web::Path<(String, String, String, String)>, db_connection: &mut DbConnection) -> Result; + async fn delete_apis_without_namespace( + &self, + info: web::Path<(String, String, String, String)>, + db_connection: &mut DbConnection, + nats_cli: Arc>, + ) -> Result + where + T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; // /apis/{group}/{version}/namespaces/{namespace}/{plural}/{name} - async fn delete_apis_with_namespace(&self, info: web::Path<(String, String, String, String, String)>, db_connection: &mut DbConnection) -> Result; + async fn delete_apis_with_namespace( + &self, + info: web::Path<(String, String, String, String, String)>, + db_connection: &mut DbConnection, + nats_cli: Arc>, + ) -> Result + where + T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; // /api/{version}/{plural}/{name} - async fn update_api_without_namespace(&self, info: web::Path<(String, String, String)>, data: web::Json, db_connection: &mut DbConnection) -> Result; + async fn update_api_without_namespace( + &self, + info: web::Path<(String, String, String)>, + data: web::Json, + db_connection: &mut DbConnection, + nats_cli: Arc>, + ) -> Result + where + T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; // /api/{version}/namespaces/{namespace}/{plural}/{name} - async fn update_api_with_namespace(&self, info: web::Path<(String, String, String, String)>, data: web::Json, db_connection: &mut DbConnection) -> Result; + async fn update_api_with_namespace( + &self, + info: web::Path<(String, String, String, String)>, + data: web::Json, + db_connection: &mut DbConnection, + nats_cli: Arc>, + ) -> Result + where + T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; // /apis/{group}/{version}/{plural}/{name} - async fn update_apis_without_namespace(&self, info: web::Path<(String, String, String, String)>, data: web::Json, db_connection: &mut DbConnection) -> Result; + async fn update_apis_without_namespace( + &self, + info: web::Path<(String, String, String, String)>, + data: web::Json, + db_connection: &mut DbConnection, + nats_cli: Arc>, + ) -> Result + where + T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; // /apis/{group}/{version}/namespaces/{namespace}/{plural}/{name} - async fn update_apis_with_namespace(&self, info: web::Path<(String, String, String, String, String)>, data: web::Json, db_connection: &mut DbConnection) -> Result; + async fn update_apis_with_namespace( + &self, + info: web::Path<(String, String, String, String, String)>, + data: web::Json, + db_connection: &mut DbConnection, + nats_cli: Arc>, + ) -> Result + where + T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; // /api/{version}/{plural}/{name} - async fn getone_api_without_namespace(&self, info: web::Path<(String, String, String)>, data: web::Query, db_connection: &mut DbConnection) -> Result; + async fn getone_api_without_namespace( + &self, + info: web::Path<(String, String, String)>, + data: web::Query, + db_connection: &mut DbConnection, + nats_cli: Arc>, + ) -> Result + where + T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; // /api/{version}/namespaces/{namespace}/{plural}/{name} - async fn getone_api_with_namespace(&self, info: web::Path<(String, String, String, String)>, data: web::Query, db_connection: &mut DbConnection) -> Result; + async fn getone_api_with_namespace( + &self, + info: web::Path<(String, String, String, String)>, + data: web::Query, + db_connection: &mut DbConnection, + nats_cli: Arc>, + ) -> Result + where + T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; // /apis/{group}/{version}/{plural}/{name} - async fn getone_apis_without_namespace(&self, info: web::Path<(String, String, String, String)>, data: web::Query, db_connection: &mut DbConnection) -> Result; + async fn getone_apis_without_namespace( + &self, + info: web::Path<(String, String, String, String)>, + data: web::Query, + db_connection: &mut DbConnection, + nats_cli: Arc>, + ) -> Result + where + T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; // /apis/{group}/{version}/namespaces/{namespace}/{plural}/{name} - async fn getone_apis_with_namespace(&self, info: web::Path<(String, String, String, String, String)>, data: web::Query, db_connection: &mut DbConnection) -> Result; + async fn getone_apis_with_namespace( + &self, + info: web::Path<(String, String, String, String, String)>, + data: web::Query, + db_connection: &mut DbConnection, + nats_cli: Arc>, + ) -> Result + where + T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; // /api/{version}/{plural} - async fn listall_api_without_namespace(&self, info: web::Path<(String, String)>, data: web::Query, db_connection: &mut DbConnection) -> Result; + async fn listall_api_without_namespace( + &self, + info: web::Path<(String, String)>, + data: web::Query, + db_connection: &mut DbConnection, + nats_cli: Arc>, + ) -> Result + where + T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; // /api/{version}/namespaces/{namespace}/{plural} - async fn listall_api_with_namespace(&self, info: web::Path<(String, String, String)>, data: web::Query, db_connection: &mut DbConnection) -> Result; + async fn listall_api_with_namespace( + &self, + info: web::Path<(String, String, String)>, + data: web::Query, + db_connection: &mut DbConnection, + nats_cli: Arc>, + ) -> Result + where + T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; // /apis/{group}/{version}/{plural} - async fn listall_apis_without_namespace(&self, info: web::Path<(String, String, String)>, data: web::Query, db_connection: &mut DbConnection) -> Result; + async fn listall_apis_without_namespace( + &self, + info: web::Path<(String, String, String)>, + data: web::Query, + db_connection: &mut DbConnection, + nats_cli: Arc>, + ) -> Result + where + T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; // /apis/{group}/{version}/namespaces/{namespace}/{plural} - async fn listall_apis_with_namespace(&self, info: web::Path<(String, String, String, String)>, data: web::Query, db_connection: &mut DbConnection) -> Result; + async fn listall_apis_with_namespace( + &self, + info: web::Path<(String, String, String, String)>, + data: web::Query, + db_connection: &mut DbConnection, + nats_cli: Arc>, + ) -> Result + where + T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; // 不满足以上请求路径的处理 fn default(&self) -> DefaultHandler; @@ -492,11 +651,12 @@ async fn get_all_data_from_table( impl Handler for DefaultHandler { // /api/{version}/{plural} - async fn create_api_without_namespace( + async fn create_api_without_namespace( &self, info: web::Path<(String, String)>, data: web::Json, db_connection: &mut DbConnection, + nats_cli: Arc>, ) -> Result { let (version, plural) = info.into_inner(); @@ -541,7 +701,13 @@ impl Handler for DefaultHandler { } // /api/{version}/namespaces/{namespace}/{plural} - async fn create_api_with_namespace(&self, info: web::Path<(String, String, String)>, data: web::Json, db_connection: &mut DbConnection) -> Result { + async fn create_api_with_namespace( + &self, + info: web::Path<(String, String, String)>, + data: web::Json, + db_connection: &mut DbConnection, + nats_cli: Arc>, + ) -> Result { let (version, namespace, plural) = info.into_inner(); //判断是正常的插入函数还是 crd 资源的注册函数 @@ -585,7 +751,13 @@ impl Handler for DefaultHandler { } // /apis/{group}/{version}/{plural} - async fn create_apis_without_namespace(&self, info: web::Path<(String, String, String)>, data: web::Json, db_connection: &mut DbConnection) -> Result { + async fn create_apis_without_namespace( + &self, + info: web::Path<(String, String, String)>, + data: web::Json, + db_connection: &mut DbConnection, + nats_cli: Arc>, + ) -> Result { let (group, version, plural) = info.into_inner(); let ver = group + "/" + &*version; @@ -631,7 +803,13 @@ impl Handler for DefaultHandler { } // /apis/{group}/{version}/namespaces/{namespace}/{plural} - async fn create_apis_with_namespace(&self, info: web::Path<(String, String, String, String)>, data: web::Json, db_connection: &mut DbConnection) -> Result { + async fn create_apis_with_namespace( + &self, + info: web::Path<(String, String, String, String)>, + data: web::Json, + db_connection: &mut DbConnection, + nats_cli: Arc>, + ) -> Result { let (group, version, namespace, plural) = info.into_inner(); let ver = group + "/" + &*version; @@ -678,7 +856,12 @@ impl Handler for DefaultHandler { } // /api/{version}/{plural}/{name} - async fn delete_api_without_namespace(&self, info: web::Path<(String, String, String)>, db_connection: &mut DbConnection) -> Result { + async fn delete_api_without_namespace( + &self, + info: web::Path<(String, String, String)>, + db_connection: &mut DbConnection, + nats_cli: Arc>, + ) -> Result { let (version, plural, name) = info.into_inner(); // 检查 metadata 中是否存在该 plural 且不需要 namespace @@ -703,7 +886,12 @@ impl Handler for DefaultHandler { } // /api/{version}/namespaces/{namespace}/{plural}/{name} - async fn delete_api_with_namespace(&self, info: web::Path<(String, String, String, String)>, db_connection: &mut DbConnection) -> Result { + async fn delete_api_with_namespace( + &self, + info: web::Path<(String, String, String, String)>, + db_connection: &mut DbConnection, + nats_cli: Arc>, + ) -> Result { let (version, namespace, plural, name) = info.into_inner(); // 检查 metadata 中是否存在该 plural 且需要 namespace let metadata_exists = check_metadata(db_connection, &plural, &version, true) @@ -727,7 +915,12 @@ impl Handler for DefaultHandler { } // /apis/{group}/{version}/{plural}/{name} - async fn delete_apis_without_namespace(&self, info: web::Path<(String, String, String, String)>, db_connection: &mut DbConnection) -> Result { + async fn delete_apis_without_namespace( + &self, + info: web::Path<(String, String, String, String)>, + db_connection: &mut DbConnection, + nats_cli: Arc>, + ) -> Result { let (group, version, plural, name) = info.into_inner(); let ver = format!("{}/{}", group, version); @@ -751,7 +944,12 @@ impl Handler for DefaultHandler { } // /apis/{group}/{version}/namespaces/{namespace}/{plural}/{name} - async fn delete_apis_with_namespace(&self, info: web::Path<(String, String, String, String, String)>, db_connection: &mut DbConnection) -> Result { + async fn delete_apis_with_namespace( + &self, + info: web::Path<(String, String, String, String, String)>, + db_connection: &mut DbConnection, + nats_cli: Arc>, + ) -> Result { let (group, version, namespace, plural, name) = info.into_inner(); let ver = format!("{}/{}", group, version); @@ -775,7 +973,13 @@ impl Handler for DefaultHandler { } // /api/{version}/{plural}/{name} - async fn update_api_without_namespace(&self, info: web::Path<(String, String, String)>, data: web::Json, db_connection: &mut DbConnection) -> Result { + async fn update_api_without_namespace( + &self, + info: web::Path<(String, String, String)>, + data: web::Json, + db_connection: &mut DbConnection, + nats_cli: Arc>, + ) -> Result { let (version, plural, name) = info.into_inner(); let metadata_exists = check_metadata(db_connection, &plural, &version, false) @@ -799,7 +1003,13 @@ impl Handler for DefaultHandler { } // /api/{version}/namespaces/{namespace}/{plural}/{name} - async fn update_api_with_namespace(&self, info: web::Path<(String, String, String, String)>, data: web::Json, db_connection: &mut DbConnection) -> Result { + async fn update_api_with_namespace( + &self, + info: web::Path<(String, String, String, String)>, + data: web::Json, + db_connection: &mut DbConnection, + nats_cli: Arc>, + ) -> Result { let (version, namespace, plural, name) = info.into_inner(); // 检查 metadata 中是否存在 plural 且要求 namespace let metadata_exists = check_metadata(db_connection, &plural, &version, true) @@ -822,7 +1032,13 @@ impl Handler for DefaultHandler { } // /apis/{group}/{version}/{plural}/{name} - async fn update_apis_without_namespace(&self, info: web::Path<(String, String, String, String)>, data: web::Json, db_connection: &mut DbConnection) -> Result { + async fn update_apis_without_namespace( + &self, + info: web::Path<(String, String, String, String)>, + data: web::Json, + db_connection: &mut DbConnection, + nats_cli: Arc>, + ) -> Result { let (group, version, plural, name) = info.into_inner(); let ver = format!("{}/{}", group, version); @@ -846,7 +1062,13 @@ impl Handler for DefaultHandler { } // /apis/{group}/{version}/namespaces/{namespace}/{plural}/{name} - async fn update_apis_with_namespace(&self, info: web::Path<(String, String, String, String, String)>, data: web::Json, db_connection: &mut DbConnection) -> Result { + async fn update_apis_with_namespace( + &self, + info: web::Path<(String, String, String, String, String)>, + data: web::Json, + db_connection: &mut DbConnection, + nats_cli: Arc>, + ) -> Result { let (group, version, namespace, plural, name) = info.into_inner(); let ver = format!("{}/{}", group, version); @@ -870,7 +1092,13 @@ impl Handler for DefaultHandler { } // /api/{version}/{plural}/{name} - async fn getone_api_without_namespace(&self, info: web::Path<(String, String, String)>, _data: web::Query, db_connection: &mut DbConnection) -> Result { + async fn getone_api_without_namespace( + &self, + info: web::Path<(String, String, String)>, + _data: web::Query, + db_connection: &mut DbConnection, + nats_cli: Arc>, + ) -> Result { let (version, plural, name) = info.into_inner(); let metadata_exists = check_metadata(db_connection, &plural, &version, false) .await @@ -893,7 +1121,13 @@ impl Handler for DefaultHandler { } // /api/{version}/namespaces/{namespace}/{plural}/{name} - async fn getone_api_with_namespace(&self, info: web::Path<(String, String, String, String)>, _data: web::Query, db_connection: &mut DbConnection) -> Result { + async fn getone_api_with_namespace( + &self, + info: web::Path<(String, String, String, String)>, + _data: web::Query, + db_connection: &mut DbConnection, + nats_cli: Arc>, + ) -> Result { let (version, namespace, plural, name) = info.into_inner(); let metadata_exists = check_metadata(db_connection, &plural, &version, true) .await @@ -916,7 +1150,13 @@ impl Handler for DefaultHandler { } // /apis/{group}/{version}/{plural}/{name} - async fn getone_apis_without_namespace(&self, info: web::Path<(String, String, String, String)>, _data: web::Query, db_connection: &mut DbConnection) -> Result { + async fn getone_apis_without_namespace( + &self, + info: web::Path<(String, String, String, String)>, + _data: web::Query, + db_connection: &mut DbConnection, + nats_cli: Arc>, + ) -> Result { let (group, version, plural, name) = info.into_inner(); let ver = format!("{}/{}", group, version); @@ -941,7 +1181,13 @@ impl Handler for DefaultHandler { } // /apis/{group}/{version}/namespaces/{namespace}/{plural}/{name} - async fn getone_apis_with_namespace(&self, info: web::Path<(String, String, String, String, String)>, _data: web::Query, db_connection: &mut DbConnection) -> Result { + async fn getone_apis_with_namespace( + &self, + info: web::Path<(String, String, String, String, String)>, + _data: web::Query, + db_connection: &mut DbConnection, + nats_cli: Arc>, + ) -> Result { let (group, version, namespace, plural, name) = info.into_inner(); let ver = format!("{}/{}", group, version); @@ -966,7 +1212,13 @@ impl Handler for DefaultHandler { } // /api/{version}/{plural} - async fn listall_api_without_namespace(&self, info: web::Path<(String, String)>, _data: web::Query, db_connection: &mut DbConnection) -> Result { + async fn listall_api_without_namespace( + &self, + info: web::Path<(String, String)>, + _data: web::Query, + db_connection: &mut DbConnection, + nats_cli: Arc>, + ) -> Result { let (version, plural) = info.into_inner(); let metadata_exists = check_metadata(db_connection, &plural, &version, false) .await @@ -990,7 +1242,13 @@ impl Handler for DefaultHandler { } // /api/{version}/namespaces/{namespace}/{plural} - async fn listall_api_with_namespace(&self, info: web::Path<(String, String, String)>, _data: web::Query, db_connection: &mut DbConnection) -> Result { + async fn listall_api_with_namespace( + &self, + info: web::Path<(String, String, String)>, + _data: web::Query, + db_connection: &mut DbConnection, + nats_cli: Arc>, + ) -> Result { let (version, namespace, plural) = info.into_inner(); let metadata_exists = check_metadata(db_connection, &plural, &version, true) .await @@ -1014,7 +1272,13 @@ impl Handler for DefaultHandler { } // /apis/{group}/{version}/{plural} - async fn listall_apis_without_namespace(&self, info: web::Path<(String, String, String)>, _data: web::Query, db_connection: &mut DbConnection) -> Result { + async fn listall_apis_without_namespace( + &self, + info: web::Path<(String, String, String)>, + _data: web::Query, + db_connection: &mut DbConnection, + nats_cli: Arc>, + ) -> Result { let (group, version, plural) = info.into_inner(); let ver = format!("{}/{}", group, version); @@ -1040,7 +1304,13 @@ impl Handler for DefaultHandler { } // /apis/{group}/{version}/namespaces/{namespace}/{plural} - async fn listall_apis_with_namespace(&self, info: web::Path<(String, String, String, String)>, _data: web::Query, db_connection: &mut DbConnection) -> Result { + async fn listall_apis_with_namespace( + &self, + info: web::Path<(String, String, String, String)>, + _data: web::Query, + db_connection: &mut DbConnection, + nats_cli: Arc>, + ) -> Result { let (group, version, namespace, plural) = info.into_inner(); let ver = format!("{}/{}", group, version); @@ -1077,6 +1347,7 @@ mod tests { use serde_json::json; use crate::cores::db::DbPool; use std::sync::Arc; + use feventbus::traits::controller::EventBus; use once_cell::sync::Lazy; // 使用 Lazy 来初始化静态的共享资源 @@ -1090,6 +1361,7 @@ mod tests { #[actix_web::test] async fn test_api_with_namespace() { + let nats_cli = Arc::new(NatsCli::new().await.unwrap()); let app = test::init_service( App::new() @@ -1097,9 +1369,11 @@ mod tests { move |path, data| { let handler = HANDLER.clone(); let db_pool = DB_POOL.clone(); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { - Ok(mut conn) => handler.create_api_with_namespace(path, data, &mut conn).await, + Ok(mut conn) => handler.create_api_with_namespace(path, data, &mut conn, nats_cli).await, Err(_) => Err(ErrorInternalServerError("Failed to get database connection")), } } @@ -1109,9 +1383,11 @@ mod tests { move |path, data| { let handler = HANDLER.clone(); let db_pool = DB_POOL.clone(); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { - Ok(mut conn) => handler.update_api_with_namespace(path, data, &mut conn).await, + Ok(mut conn) => handler.update_api_with_namespace(path, data, &mut conn, nats_cli).await, Err(_) => Err(ErrorInternalServerError("Failed to get database connection")), } } @@ -1121,9 +1397,11 @@ mod tests { move |path| { let handler = HANDLER.clone(); let db_pool = DB_POOL.clone(); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { - Ok(mut conn) => handler.delete_api_with_namespace(path, &mut conn).await, + Ok(mut conn) => handler.delete_api_with_namespace(path, &mut conn, nats_cli).await, Err(_) => Err(ErrorInternalServerError("Failed to get database connection")), } } @@ -1133,9 +1411,11 @@ mod tests { move |path, data| { let handler = HANDLER.clone(); let db_pool = DB_POOL.clone(); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { - Ok(mut conn) => handler.getone_api_with_namespace(path, data, &mut conn).await, + Ok(mut conn) => handler.getone_api_with_namespace(path, data, &mut conn, nats_cli).await, Err(_) => Err(ErrorInternalServerError("Failed to get database connection")), } } @@ -1145,9 +1425,11 @@ mod tests { move |path, data| { let handler = HANDLER.clone(); let db_pool = DB_POOL.clone(); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { - Ok(mut conn) => handler.listall_api_with_namespace(path, data, &mut conn).await, + Ok(mut conn) => handler.listall_api_with_namespace(path, data, &mut conn, nats_cli).await, Err(_) => Err(ErrorInternalServerError("Failed to get database connection")), } } diff --git a/src/main.rs b/src/main.rs index b35adf0..a9aba48 100644 --- a/src/main.rs +++ b/src/main.rs @@ -36,36 +36,4 @@ async fn start(db_pool: Arc) { let handler: DefaultHandler = DefaultHandler::new(); let _ = Arc::new(server).start("0.0.0.0:8080", handler, db_pool).await; -} - -// fn validate() { -// let pod_json = r#" -// { -// "apiVersion": "v1", -// "kind": "Pod", -// "metadata": { -// "name": "example-pod" -// }, -// "spec": { -// "containers": [ -// { -// "name": "nginx", -// "image": "nginx:1.14.2", -// "ports": [ -// { -// "containerPort": 80 -// } -// ] -// } -// ] -// } -// } -// "#; -// -// // 使用 Pod 类型进行校验 -// match checker::validate_pod_json(pod_json) { -// Ok(true) => println!("Pod JSON validation passed!"), -// Ok(false) => println!("JSON validation failed, but no critical error."), -// Err(e) => println!("Pod JSON validation failed: {}", e), -// } -// } +} \ No newline at end of file -- Gitee From 96477eb5b895c864259cf92bf49dffbef8d1cddf Mon Sep 17 00:00:00 2001 From: Yuichi <913637919@qq.com> Date: Sun, 24 Nov 2024 17:22:37 +0800 Subject: [PATCH 02/48] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=83=A8=E5=88=86?= =?UTF-8?q?=E5=87=BD=E6=95=B0=E5=AE=9A=E4=B9=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/cores/apiserver.rs | 8 +- src/cores/handlers.rs | 556 +++++++++++++++++++++++++++-------------- 2 files changed, 369 insertions(+), 195 deletions(-) diff --git a/src/cores/apiserver.rs b/src/cores/apiserver.rs index 599f757..ee6750f 100644 --- a/src/cores/apiserver.rs +++ b/src/cores/apiserver.rs @@ -13,6 +13,7 @@ use crate::cores::handlers::{Handler}; use std::sync::{Arc}; use feventbus::impls::nats::nats::NatsCli; use feventbus::traits::controller::EventBus; +use serde::{Deserialize, Serialize}; use crate::cores::db::{DbPool}; pub struct ApiServer @@ -21,6 +22,11 @@ pub struct ApiServer config: Arc, } +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct ApiServerMessage { + pub content: String, +} + impl ApiServer { pub fn new (config: Box) -> Self { @@ -36,7 +42,7 @@ impl ApiServer let handler = Arc::new(handler); // 初始化 NatsCli 实例 - let nats_cli = Arc::new(NatsCli::new().await.unwrap()); + let nats_cli: Arc> = Arc::new(NatsCli::new().await.unwrap()); let server = HttpServer::new(move || { diff --git a/src/cores/handlers.rs b/src/cores/handlers.rs index 88c7f08..a335666 100644 --- a/src/cores/handlers.rs +++ b/src/cores/handlers.rs @@ -1,4 +1,6 @@ +use std::fmt::Debug; use std::sync::Arc; +use std::time; /** * Copyright (2024, ) Institute of Software, Chinese Academy of Sciences * author: wuheng@iscas.ac.cn @@ -16,225 +18,191 @@ use crate::cores::db::DbConnection; use diesel::sql_types::{Text}; use actix_web::error::ErrorInternalServerError; use feventbus::impls::nats::nats::NatsCli; +use feventbus::message::Message; +use feventbus::message; +use feventbus::traits::consumer::{Consumer, MessageHandler}; +use feventbus::traits::producer::Producer; use serde::{Deserialize, Serialize}; +use cores::apiserver::ApiServerMessage; +use crate::cores; #[async_trait] pub trait Handler { // /api/{version}/{plural} - async fn create_api_without_namespace( + async fn create_api_without_namespace( &self, info: web::Path<(String, String)>, data: web::Json, db_connection: &mut DbConnection, - nats_cli: Arc>, - ) -> Result - where - T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; + nats_cli: Arc>, + ) -> Result; // /api/{version}/namespaces/{namespace}/{plural} - async fn create_api_with_namespace( + async fn create_api_with_namespace( &self, info: web::Path<(String, String, String)>, data: web::Json, db_connection: &mut DbConnection, - nats_cli: Arc>, - ) -> Result - where - T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; + nats_cli: Arc>, + ) -> Result; // /apis/{group}/{version}/{plural} - async fn create_apis_without_namespace( + async fn create_apis_without_namespace( &self, info: web::Path<(String, String, String)>, data: web::Json, db_connection: &mut DbConnection, - nats_cli: Arc>, - ) -> Result - where - T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; + nats_cli: Arc>, + ) -> Result; // /apis/{group}/{version}/namespaces/{namespace}/{plural} - async fn create_apis_with_namespace( + async fn create_apis_with_namespace( &self, info: web::Path<(String, String, String, String)>, data: web::Json, db_connection: &mut DbConnection, - nats_cli: Arc>, - ) -> Result - where - T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; + nats_cli: Arc>, + ) -> Result; // /api/{version}/{plural}/{name} - async fn delete_api_without_namespace( + async fn delete_api_without_namespace( &self, info: web::Path<(String, String, String)>, db_connection: &mut DbConnection, - nats_cli: Arc>, - ) -> Result - where - T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; + nats_cli: Arc>, + ) -> Result; // /api/{version}/namespaces/{namespace}/{plural}/{name} - async fn delete_api_with_namespace( + async fn delete_api_with_namespace( &self, info: web::Path<(String, String, String, String)>, db_connection: &mut DbConnection, - nats_cli: Arc>, - ) -> Result - where - T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; + nats_cli: Arc>, + ) -> Result; // /apis/{group}/{version}/{plural}/{name} - async fn delete_apis_without_namespace( + async fn delete_apis_without_namespace( &self, info: web::Path<(String, String, String, String)>, db_connection: &mut DbConnection, - nats_cli: Arc>, - ) -> Result - where - T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; + nats_cli: Arc>, + ) -> Result; // /apis/{group}/{version}/namespaces/{namespace}/{plural}/{name} - async fn delete_apis_with_namespace( + async fn delete_apis_with_namespace( &self, info: web::Path<(String, String, String, String, String)>, db_connection: &mut DbConnection, - nats_cli: Arc>, - ) -> Result - where - T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; + nats_cli: Arc>, + ) -> Result; // /api/{version}/{plural}/{name} - async fn update_api_without_namespace( + async fn update_api_without_namespace( &self, info: web::Path<(String, String, String)>, data: web::Json, db_connection: &mut DbConnection, - nats_cli: Arc>, - ) -> Result - where - T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; + nats_cli: Arc>, + ) -> Result; // /api/{version}/namespaces/{namespace}/{plural}/{name} - async fn update_api_with_namespace( + async fn update_api_with_namespace( &self, info: web::Path<(String, String, String, String)>, data: web::Json, db_connection: &mut DbConnection, - nats_cli: Arc>, - ) -> Result - where - T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; + nats_cli: Arc>, + ) -> Result; // /apis/{group}/{version}/{plural}/{name} - async fn update_apis_without_namespace( + async fn update_apis_without_namespace( &self, info: web::Path<(String, String, String, String)>, data: web::Json, db_connection: &mut DbConnection, - nats_cli: Arc>, - ) -> Result - where - T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; + nats_cli: Arc>, + ) -> Result; // /apis/{group}/{version}/namespaces/{namespace}/{plural}/{name} - async fn update_apis_with_namespace( + async fn update_apis_with_namespace( &self, info: web::Path<(String, String, String, String, String)>, data: web::Json, db_connection: &mut DbConnection, - nats_cli: Arc>, - ) -> Result - where - T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; + nats_cli: Arc>, + ) -> Result; // /api/{version}/{plural}/{name} - async fn getone_api_without_namespace( + async fn getone_api_without_namespace( &self, info: web::Path<(String, String, String)>, data: web::Query, db_connection: &mut DbConnection, - nats_cli: Arc>, - ) -> Result - where - T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; + nats_cli: Arc>, + ) -> Result; // /api/{version}/namespaces/{namespace}/{plural}/{name} - async fn getone_api_with_namespace( + async fn getone_api_with_namespace( &self, info: web::Path<(String, String, String, String)>, data: web::Query, db_connection: &mut DbConnection, - nats_cli: Arc>, - ) -> Result - where - T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; + nats_cli: Arc>, + ) -> Result; // /apis/{group}/{version}/{plural}/{name} - async fn getone_apis_without_namespace( + async fn getone_apis_without_namespace( &self, info: web::Path<(String, String, String, String)>, data: web::Query, db_connection: &mut DbConnection, - nats_cli: Arc>, - ) -> Result - where - T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; + nats_cli: Arc>, + ) -> Result; // /apis/{group}/{version}/namespaces/{namespace}/{plural}/{name} - async fn getone_apis_with_namespace( + async fn getone_apis_with_namespace( &self, info: web::Path<(String, String, String, String, String)>, data: web::Query, db_connection: &mut DbConnection, - nats_cli: Arc>, - ) -> Result - where - T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; + nats_cli: Arc>, + ) -> Result; // /api/{version}/{plural} - async fn listall_api_without_namespace( + async fn listall_api_without_namespace( &self, info: web::Path<(String, String)>, data: web::Query, db_connection: &mut DbConnection, - nats_cli: Arc>, - ) -> Result - where - T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; + nats_cli: Arc>, + ) -> Result; // /api/{version}/namespaces/{namespace}/{plural} - async fn listall_api_with_namespace( + async fn listall_api_with_namespace( &self, info: web::Path<(String, String, String)>, data: web::Query, db_connection: &mut DbConnection, - nats_cli: Arc>, - ) -> Result - where - T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; + nats_cli: Arc>, + ) -> Result; // /apis/{group}/{version}/{plural} - async fn listall_apis_without_namespace( + async fn listall_apis_without_namespace( &self, info: web::Path<(String, String, String)>, data: web::Query, db_connection: &mut DbConnection, - nats_cli: Arc>, - ) -> Result - where - T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; + nats_cli: Arc>, + ) -> Result; // /apis/{group}/{version}/namespaces/{namespace}/{plural} - async fn listall_apis_with_namespace( + async fn listall_apis_with_namespace( &self, info: web::Path<(String, String, String, String)>, data: web::Query, db_connection: &mut DbConnection, - nats_cli: Arc>, - ) -> Result - where - T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; + nats_cli: Arc>, + ) -> Result; // 不满足以上请求路径的处理 fn default(&self) -> DefaultHandler; @@ -646,17 +614,55 @@ async fn get_all_data_from_table( } } +// 收到请求并等待响应 +async fn reply_to_topic( + topic: &str, + nats_cli: Arc>, + handler: MessageHandler, +) -> Result<(), Box> +where + T: Serialize + for<'de> Deserialize<'de> + Debug + Send + Clone + Sync + 'static, +{ + nats_cli + .reply(topic, handler) + .await + .map_err(|e| Box::new(e) as Box)?; + Ok(()) +} + +// 发送请求并等待响应 +async fn send_request(message: Message, nats_cli: Arc>) -> Result<(), Box> +where + T: Serialize + for<'de> Deserialize<'de> + Debug + Clone + Send + Sync + 'static, +{ + match nats_cli + .request(message, time::Duration::from_secs(100)) + .await + { + Ok(response) => { + println!( + "===============Received response: {:?}==================", + response + ); + Ok(()) + } + Err(e) => { + println!("Failed to get response: {:?}", e); + Err(Box::new(e) as Box) + } + } +} #[async_trait] impl Handler for DefaultHandler { // /api/{version}/{plural} - async fn create_api_without_namespace( + async fn create_api_without_namespace( &self, info: web::Path<(String, String)>, data: web::Json, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc>, ) -> Result { let (version, plural) = info.into_inner(); @@ -692,6 +698,18 @@ impl Handler for DefaultHandler { return Ok(HttpResponse::NotFound().json(json!({ "error": "该 plural 不存在,请重新注册或检查 plural 版本以及是否需要 namespace" }))); } + // request消息 + let request_message = Message::new( + "CREATE".to_string(), + message::NativeEventAction::Other, + None, + Some(ApiServerMessage { + content: data.to_string(), + }), + None, + ); + tokio::spawn(send_request(request_message, nats_cli)); + insert_into_table(db_connection, &plural, &data, &version, None) .await .map_err(ErrorInternalServerError)?; @@ -701,12 +719,12 @@ impl Handler for DefaultHandler { } // /api/{version}/namespaces/{namespace}/{plural} - async fn create_api_with_namespace( + async fn create_api_with_namespace( &self, info: web::Path<(String, String, String)>, data: web::Json, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc>, ) -> Result { let (version, namespace, plural) = info.into_inner(); @@ -742,6 +760,18 @@ impl Handler for DefaultHandler { return Ok(HttpResponse::NotFound().json(json!({ "error": "该 plural 不存在,请重新注册或检查 plural 版本以及是否需要 namespace" }))); } + // request消息 + let request_message = Message::new( + "CREATE".to_string(), + message::NativeEventAction::Other, + None, + Some(ApiServerMessage { + content: data.to_string(), + }), + None, + ); + tokio::spawn(send_request(request_message, nats_cli)); + insert_into_table(db_connection, &plural, &data, &version, Some(&namespace)) .await .map_err(ErrorInternalServerError)?; @@ -751,12 +781,12 @@ impl Handler for DefaultHandler { } // /apis/{group}/{version}/{plural} - async fn create_apis_without_namespace( + async fn create_apis_without_namespace( &self, info: web::Path<(String, String, String)>, data: web::Json, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc>, ) -> Result { let (group, version, plural) = info.into_inner(); let ver = group + "/" + &*version; @@ -794,6 +824,18 @@ impl Handler for DefaultHandler { return Ok(HttpResponse::NotFound().json(json!({ "error": "该 plural 不存在,请重新注册或检查 plural 版本以及是否需要 namespace" }))); } + // request消息 + let request_message = Message::new( + "CREATE".to_string(), + message::NativeEventAction::Other, + None, + Some(ApiServerMessage { + content: data.to_string(), + }), + None, + ); + tokio::spawn(send_request(request_message, nats_cli)); + insert_into_table(db_connection, &plural, &data, &ver, None) .await .map_err(ErrorInternalServerError)?; @@ -803,12 +845,12 @@ impl Handler for DefaultHandler { } // /apis/{group}/{version}/namespaces/{namespace}/{plural} - async fn create_apis_with_namespace( + async fn create_apis_with_namespace( &self, info: web::Path<(String, String, String, String)>, data: web::Json, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc>, ) -> Result { let (group, version, namespace, plural) = info.into_inner(); @@ -847,6 +889,18 @@ impl Handler for DefaultHandler { return Ok(HttpResponse::NotFound().json(json!({ "error": "该 plural 不存在,请重新注册或检查 plural 版本以及是否需要 namespace" }))); } + // request消息 + let request_message = Message::new( + "CREATE".to_string(), + message::NativeEventAction::Other, + None, + Some(ApiServerMessage { + content: data.to_string(), + }), + None, + ); + tokio::spawn(send_request(request_message, nats_cli)); + insert_into_table(db_connection, &plural, &data, &ver, Some(&namespace)) .await .map_err(ErrorInternalServerError)?; @@ -856,11 +910,11 @@ impl Handler for DefaultHandler { } // /api/{version}/{plural}/{name} - async fn delete_api_without_namespace( + async fn delete_api_without_namespace( &self, info: web::Path<(String, String, String)>, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc>, ) -> Result { let (version, plural, name) = info.into_inner(); @@ -873,6 +927,18 @@ impl Handler for DefaultHandler { return Ok(HttpResponse::NotFound().json(json!({ "error": "该 plural 不存在,请检查 plural 版本以及是否需要 namespace" }))); } + // request消息 + let request_message = Message::new( + "REMOVE".to_string(), + message::NativeEventAction::Other, + None, + Some(ApiServerMessage { + content: name.clone(), + }), + None, + ); + tokio::spawn(send_request(request_message, nats_cli)); + // 从 plural 表中删除指定的 name let deleted = delete_from_table(db_connection, &plural, &name, &version, None) .await @@ -886,11 +952,11 @@ impl Handler for DefaultHandler { } // /api/{version}/namespaces/{namespace}/{plural}/{name} - async fn delete_api_with_namespace( + async fn delete_api_with_namespace( &self, info: web::Path<(String, String, String, String)>, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc>, ) -> Result { let (version, namespace, plural, name) = info.into_inner(); // 检查 metadata 中是否存在该 plural 且需要 namespace @@ -902,6 +968,18 @@ impl Handler for DefaultHandler { return Ok(HttpResponse::NotFound().json(json!({ "error": "该 plural 不存在,请检查 plural 版本以及是否需要 namespace" }))); } + // request消息 + let request_message = Message::new( + "REMOVE".to_string(), + message::NativeEventAction::Other, + None, + Some(ApiServerMessage { + content: name.clone(), + }), + None, + ); + tokio::spawn(send_request(request_message, nats_cli)); + // 从 plural 表中删除指定的数据 let deleted = delete_from_table(db_connection, &plural, &name, &version, Some(&namespace)) .await @@ -915,11 +993,11 @@ impl Handler for DefaultHandler { } // /apis/{group}/{version}/{plural}/{name} - async fn delete_apis_without_namespace( + async fn delete_apis_without_namespace( &self, info: web::Path<(String, String, String, String)>, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc>, ) -> Result { let (group, version, plural, name) = info.into_inner(); let ver = format!("{}/{}", group, version); @@ -932,6 +1010,18 @@ impl Handler for DefaultHandler { return Ok(HttpResponse::NotFound().json(json!({ "error": "该 plural 不存在,请检查 plural 版本以及是否需要 namespace" }))); } + // request消息 + let request_message = Message::new( + "REMOVE".to_string(), + message::NativeEventAction::Other, + None, + Some(ApiServerMessage { + content: name.clone(), + }), + None, + ); + tokio::spawn(send_request(request_message, nats_cli)); + let deleted = delete_from_table(db_connection, &plural, &name, &ver, None) .await .map_err(ErrorInternalServerError)?; @@ -944,11 +1034,11 @@ impl Handler for DefaultHandler { } // /apis/{group}/{version}/namespaces/{namespace}/{plural}/{name} - async fn delete_apis_with_namespace( + async fn delete_apis_with_namespace( &self, info: web::Path<(String, String, String, String, String)>, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc>, ) -> Result { let (group, version, namespace, plural, name) = info.into_inner(); let ver = format!("{}/{}", group, version); @@ -961,6 +1051,18 @@ impl Handler for DefaultHandler { return Ok(HttpResponse::NotFound().json(json!({ "error": "该 plural 不存在,请检查 plural 版本以及是否需要 namespace" }))); } + // request消息 + let request_message = Message::new( + "REMOVE".to_string(), + message::NativeEventAction::Other, + None, + Some(ApiServerMessage { + content: name.clone(), + }), + None, + ); + tokio::spawn(send_request(request_message, nats_cli)); + let deleted = delete_from_table(db_connection, &plural, &name, &ver, Some(&namespace)) .await .map_err(ErrorInternalServerError)?; @@ -973,12 +1075,12 @@ impl Handler for DefaultHandler { } // /api/{version}/{plural}/{name} - async fn update_api_without_namespace( + async fn update_api_without_namespace( &self, info: web::Path<(String, String, String)>, data: web::Json, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc>, ) -> Result { let (version, plural, name) = info.into_inner(); @@ -1003,12 +1105,12 @@ impl Handler for DefaultHandler { } // /api/{version}/namespaces/{namespace}/{plural}/{name} - async fn update_api_with_namespace( + async fn update_api_with_namespace( &self, info: web::Path<(String, String, String, String)>, data: web::Json, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc>, ) -> Result { let (version, namespace, plural, name) = info.into_inner(); // 检查 metadata 中是否存在 plural 且要求 namespace @@ -1032,12 +1134,12 @@ impl Handler for DefaultHandler { } // /apis/{group}/{version}/{plural}/{name} - async fn update_apis_without_namespace( + async fn update_apis_without_namespace( &self, info: web::Path<(String, String, String, String)>, data: web::Json, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc>, ) -> Result { let (group, version, plural, name) = info.into_inner(); let ver = format!("{}/{}", group, version); @@ -1062,12 +1164,12 @@ impl Handler for DefaultHandler { } // /apis/{group}/{version}/namespaces/{namespace}/{plural}/{name} - async fn update_apis_with_namespace( + async fn update_apis_with_namespace( &self, info: web::Path<(String, String, String, String, String)>, data: web::Json, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc>, ) -> Result { let (group, version, namespace, plural, name) = info.into_inner(); let ver = format!("{}/{}", group, version); @@ -1092,12 +1194,12 @@ impl Handler for DefaultHandler { } // /api/{version}/{plural}/{name} - async fn getone_api_without_namespace( + async fn getone_api_without_namespace( &self, info: web::Path<(String, String, String)>, _data: web::Query, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc>, ) -> Result { let (version, plural, name) = info.into_inner(); let metadata_exists = check_metadata(db_connection, &plural, &version, false) @@ -1121,12 +1223,12 @@ impl Handler for DefaultHandler { } // /api/{version}/namespaces/{namespace}/{plural}/{name} - async fn getone_api_with_namespace( + async fn getone_api_with_namespace( &self, info: web::Path<(String, String, String, String)>, _data: web::Query, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc>, ) -> Result { let (version, namespace, plural, name) = info.into_inner(); let metadata_exists = check_metadata(db_connection, &plural, &version, true) @@ -1150,12 +1252,12 @@ impl Handler for DefaultHandler { } // /apis/{group}/{version}/{plural}/{name} - async fn getone_apis_without_namespace( + async fn getone_apis_without_namespace( &self, info: web::Path<(String, String, String, String)>, _data: web::Query, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc>, ) -> Result { let (group, version, plural, name) = info.into_inner(); let ver = format!("{}/{}", group, version); @@ -1181,12 +1283,12 @@ impl Handler for DefaultHandler { } // /apis/{group}/{version}/namespaces/{namespace}/{plural}/{name} - async fn getone_apis_with_namespace( + async fn getone_apis_with_namespace( &self, info: web::Path<(String, String, String, String, String)>, _data: web::Query, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc>, ) -> Result { let (group, version, namespace, plural, name) = info.into_inner(); let ver = format!("{}/{}", group, version); @@ -1212,12 +1314,12 @@ impl Handler for DefaultHandler { } // /api/{version}/{plural} - async fn listall_api_without_namespace( + async fn listall_api_without_namespace( &self, info: web::Path<(String, String)>, _data: web::Query, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc>, ) -> Result { let (version, plural) = info.into_inner(); let metadata_exists = check_metadata(db_connection, &plural, &version, false) @@ -1242,12 +1344,12 @@ impl Handler for DefaultHandler { } // /api/{version}/namespaces/{namespace}/{plural} - async fn listall_api_with_namespace( + async fn listall_api_with_namespace( &self, info: web::Path<(String, String, String)>, _data: web::Query, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc>, ) -> Result { let (version, namespace, plural) = info.into_inner(); let metadata_exists = check_metadata(db_connection, &plural, &version, true) @@ -1272,12 +1374,12 @@ impl Handler for DefaultHandler { } // /apis/{group}/{version}/{plural} - async fn listall_apis_without_namespace( + async fn listall_apis_without_namespace( &self, info: web::Path<(String, String, String)>, _data: web::Query, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc>, ) -> Result { let (group, version, plural) = info.into_inner(); let ver = format!("{}/{}", group, version); @@ -1304,12 +1406,12 @@ impl Handler for DefaultHandler { } // /apis/{group}/{version}/namespaces/{namespace}/{plural} - async fn listall_apis_with_namespace( + async fn listall_apis_with_namespace( &self, info: web::Path<(String, String, String, String)>, _data: web::Query, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc>, ) -> Result { let (group, version, namespace, plural) = info.into_inner(); let ver = format!("{}/{}", group, version); @@ -1365,7 +1467,8 @@ mod tests { let app = test::init_service( App::new() - .route("/api/{version}/namespaces/{namespace}/{plural}", web::post().to( + .route("/api/{version}/namespaces/{namespace}/{plural}", web::post().to({ + let nats_cli = Arc::clone(&nats_cli); move |path, data| { let handler = HANDLER.clone(); let db_pool = DB_POOL.clone(); @@ -1378,8 +1481,9 @@ mod tests { } } } - )) - .route("/api/{version}/namespaces/{namespace}/{plural}/{name}", web::put().to( + })) + .route("/api/{version}/namespaces/{namespace}/{plural}/{name}", web::put().to({ + let nats_cli = Arc::clone(&nats_cli); move |path, data| { let handler = HANDLER.clone(); let db_pool = DB_POOL.clone(); @@ -1392,8 +1496,9 @@ mod tests { } } } - )) - .route("/api/{version}/namespaces/{namespace}/{plural}/{name}", web::delete().to( + })) + .route("/api/{version}/namespaces/{namespace}/{plural}/{name}", web::delete().to({ + let nats_cli = Arc::clone(&nats_cli); move |path| { let handler = HANDLER.clone(); let db_pool = DB_POOL.clone(); @@ -1406,7 +1511,7 @@ mod tests { } } } - )) + })) .route("/api/{version}/namespaces/{namespace}/{plural}/{name}", web::get().to( move |path, data| { let handler = HANDLER.clone(); @@ -1421,7 +1526,8 @@ mod tests { } } )) - .route("/api/{version}/namespaces/{namespace}/{plural}", web::get().to( + .route("/api/{version}/namespaces/{namespace}/{plural}", web::get().to({ + let nats_cli = Arc::clone(&nats_cli); move |path, data| { let handler = HANDLER.clone(); let db_pool = DB_POOL.clone(); @@ -1434,7 +1540,7 @@ mod tests { } } } - )) + })) ).await; @@ -1700,73 +1806,93 @@ mod tests { #[actix_web::test] async fn test_api_without_namespace() { + let nats_cli = Arc::new(NatsCli::new().await.unwrap()); let app = test::init_service( App::new() - .route("/api/{version}/{plural}", web::post().to( + .route("/api/{version}/{plural}", web::post().to({ + let nats_cli = Arc::clone(&nats_cli); + move |path, data| { let handler = HANDLER.clone(); let db_pool = DB_POOL.clone(); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { - Ok(mut conn) => handler.create_api_without_namespace(path, data, &mut conn).await, + Ok(mut conn) => handler.create_api_without_namespace(path, data, &mut conn, nats_cli).await, Err(_) => Err(ErrorInternalServerError("Failed to get database connection")), } } } - )) - .route("/api/{version}/{plural}/{name}", web::put().to( + })) + .route("/api/{version}/{plural}/{name}", web::put().to({ + let nats_cli = Arc::clone(&nats_cli); + move |path, data| { let handler = HANDLER.clone(); let db_pool = DB_POOL.clone(); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { - Ok(mut conn) => handler.update_api_without_namespace(path, data, &mut conn).await, + Ok(mut conn) => handler.update_api_without_namespace(path, data, &mut conn, nats_cli).await, Err(_) => Err(ErrorInternalServerError("Failed to get database connection")), } } } - )) - .route("/api/{version}/{plural}/{name}", web::delete().to( + })) + .route("/api/{version}/{plural}/{name}", web::delete().to({ + let nats_cli = Arc::clone(&nats_cli); + move |path| { let handler = HANDLER.clone(); let db_pool = DB_POOL.clone(); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { - Ok(mut conn) => handler.delete_api_without_namespace(path, &mut conn).await, + Ok(mut conn) => handler.delete_api_without_namespace(path, &mut conn, nats_cli).await, Err(_) => Err(ErrorInternalServerError("Failed to get database connection")), } } } - )) - .route("/api/{version}/{plural}/{name}", web::get().to( + })) + .route("/api/{version}/{plural}/{name}", web::get().to({ + let nats_cli = Arc::clone(&nats_cli); + move |path, data| { let handler = HANDLER.clone(); let db_pool = DB_POOL.clone(); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { - Ok(mut conn) => handler.getone_api_without_namespace(path, data, &mut conn).await, + Ok(mut conn) => handler.getone_api_without_namespace(path, data, &mut conn, nats_cli).await, Err(_) => Err(ErrorInternalServerError("Failed to get database connection")), } } } - )) - .route("/api/{version}/{plural}", web::get().to( + })) + .route("/api/{version}/{plural}", web::get().to({ + let nats_cli = Arc::clone(&nats_cli); + move |path, data| { let handler = HANDLER.clone(); let db_pool = DB_POOL.clone(); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { - Ok(mut conn) => handler.listall_api_without_namespace(path, data, &mut conn).await, + Ok(mut conn) => handler.listall_api_without_namespace(path, data, &mut conn, nats_cli).await, Err(_) => Err(ErrorInternalServerError("Failed to get database connection")), } } } - )) + })) ).await; - let create_req_data = json!({ "apiVersion": "v1", "kind": "Node", @@ -1999,69 +2125,90 @@ mod tests { #[actix_web::test] async fn test_apis_with_namespace() { + let nats_cli = Arc::new(NatsCli::new().await.unwrap()); let app = test::init_service( App::new() - .route("/apis/{group}/{version}/namespaces/{namespace}/{plural}", web::post().to( + .route("/apis/{group}/{version}/namespaces/{namespace}/{plural}", web::post().to({ + let nats_cli = Arc::clone(&nats_cli); + move |path, data| { let handler = HANDLER.clone(); let db_pool = DB_POOL.clone(); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { - Ok(mut conn) => handler.create_apis_with_namespace(path, data, &mut conn).await, + Ok(mut conn) => handler.create_apis_with_namespace(path, data, &mut conn, nats_cli).await, Err(_) => Err(ErrorInternalServerError("Failed to get database connection")), } } } - )) - .route("/apis/{group}/{version}/namespaces/{namespace}/{plural}/{name}", web::put().to( + })) + .route("/apis/{group}/{version}/namespaces/{namespace}/{plural}/{name}", web::put().to({ + let nats_cli = Arc::clone(&nats_cli); + move |path, data| { let handler = HANDLER.clone(); let db_pool = DB_POOL.clone(); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { - Ok(mut conn) => handler.update_apis_with_namespace(path, data, &mut conn).await, + Ok(mut conn) => handler.update_apis_with_namespace(path, data, &mut conn, nats_cli).await, Err(_) => Err(ErrorInternalServerError("Failed to get database connection")), } } } - )) - .route("/apis/{group}/{version}/namespaces/{namespace}/{plural}/{name}", web::delete().to( + })) + .route("/apis/{group}/{version}/namespaces/{namespace}/{plural}/{name}", web::delete().to({ + let nats_cli = Arc::clone(&nats_cli); + move |path| { let handler = HANDLER.clone(); let db_pool = DB_POOL.clone(); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { - Ok(mut conn) => handler.delete_apis_with_namespace(path, &mut conn).await, + Ok(mut conn) => handler.delete_apis_with_namespace(path, &mut conn, nats_cli).await, Err(_) => Err(ErrorInternalServerError("Failed to get database connection")), } } } - )) - .route("/apis/{group}/{version}/namespaces/{namespace}/{plural}/{name}", web::get().to( + })) + .route("/apis/{group}/{version}/namespaces/{namespace}/{plural}/{name}", web::get().to({ + let nats_cli = Arc::clone(&nats_cli); + move |path, data| { let handler = HANDLER.clone(); let db_pool = DB_POOL.clone(); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { - Ok(mut conn) => handler.getone_apis_with_namespace(path, data, &mut conn).await, + Ok(mut conn) => handler.getone_apis_with_namespace(path, data, &mut conn, nats_cli).await, Err(_) => Err(ErrorInternalServerError("Failed to get database connection")), } } } - )) - .route("/apis/{group}/{version}/namespaces/{namespace}/{plural}", web::get().to( + })) + .route("/apis/{group}/{version}/namespaces/{namespace}/{plural}", web::get().to({ + let nats_cli = Arc::clone(&nats_cli); + move |path, data| { let handler = HANDLER.clone(); let db_pool = DB_POOL.clone(); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { - Ok(mut conn) => handler.listall_apis_with_namespace(path, data, &mut conn).await, + Ok(mut conn) => handler.listall_apis_with_namespace(path, data, &mut conn, nats_cli).await, Err(_) => Err(ErrorInternalServerError("Failed to get database connection")), } } } - )) + })) ).await; @@ -2296,69 +2443,90 @@ mod tests { #[actix_web::test] async fn test_crd_and_apis_without_namespace() { + let nats_cli = Arc::new(NatsCli::new().await.unwarp()); let app = test::init_service( App::new() - .route("/apis/{group}/{version}/{plural}", web::post().to( + .route("/apis/{group}/{version}/{plural}", web::post().to({ + let nats_cli = Arc::clone(&nats_cli); + move |path, data| { let handler = HANDLER.clone(); let db_pool = DB_POOL.clone(); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { - Ok(mut conn) => handler.create_apis_without_namespace(path, data, &mut conn).await, + Ok(mut conn) => handler.create_apis_without_namespace(path, data, &mut conn, nats_cli).await, Err(_) => Err(ErrorInternalServerError("Failed to get database connection")), } } } - )) - .route("/apis/{group}/{version}/{plural}/{name}", web::put().to( + })) + .route("/apis/{group}/{version}/{plural}/{name}", web::put().to({ + let nats_cli = Arc::clone(&nats_cli); + move |path, data| { let handler = HANDLER.clone(); let db_pool = DB_POOL.clone(); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { - Ok(mut conn) => handler.update_apis_without_namespace(path, data, &mut conn).await, + Ok(mut conn) => handler.update_apis_without_namespace(path, data, &mut conn, nats_cli).await, Err(_) => Err(ErrorInternalServerError("Failed to get database connection")), } } } - )) - .route("/apis/{group}/{version}/{plural}/{name}", web::delete().to( + })) + .route("/apis/{group}/{version}/{plural}/{name}", web::delete().to({ + let nats_cli = Arc::clone(&nats_cli); + move |path| { let handler = HANDLER.clone(); let db_pool = DB_POOL.clone(); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { - Ok(mut conn) => handler.delete_apis_without_namespace(path, &mut conn).await, + Ok(mut conn) => handler.delete_apis_without_namespace(path, &mut conn, nats_cli).await, Err(_) => Err(ErrorInternalServerError("Failed to get database connection")), } } } - )) - .route("/apis/{group}/{version}/{plural}/{name}", web::get().to( + })) + .route("/apis/{group}/{version}/{plural}/{name}", web::get().to({ + let nats_cli = Arc::clone(&nats_cli); + move |path, data| { let handler = HANDLER.clone(); let db_pool = DB_POOL.clone(); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { - Ok(mut conn) => handler.getone_apis_without_namespace(path, data, &mut conn).await, + Ok(mut conn) => handler.getone_apis_without_namespace(path, data, &mut conn, nats_cli).await, Err(_) => Err(ErrorInternalServerError("Failed to get database connection")), } } } - )) - .route("/apis/{group}/{version}/{plural}", web::get().to( + })) + .route("/apis/{group}/{version}/{plural}", web::get().to({ + let nats_cli = Arc::clone(&nats_cli); + move |path, data| { let handler = HANDLER.clone(); let db_pool = DB_POOL.clone(); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { - Ok(mut conn) => handler.listall_apis_without_namespace(path, data, &mut conn).await, + Ok(mut conn) => handler.listall_apis_without_namespace(path, data, &mut conn, nats_cli).await, Err(_) => Err(ErrorInternalServerError("Failed to get database connection")), } } } - )) + })) ).await; -- Gitee From bd61408973f4adadd4c09df9475ae511eb397ef2 Mon Sep 17 00:00:00 2001 From: Yuichi <913637919@qq.com> Date: Mon, 25 Nov 2024 07:27:26 +0000 Subject: [PATCH 03/48] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=83=A8=E5=88=86?= =?UTF-8?q?=E5=87=BD=E6=95=B0=E5=AE=9A=E4=B9=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.lock | 49 ++++++------ Cargo.toml | 12 ++- src/cores/apiserver.rs | 7 -- src/cores/handlers.rs | 173 +++++++++++++++++++++++++++++------------ src/lib.rs | 33 +++++++- src/main.rs | 40 +++------- 6 files changed, 196 insertions(+), 118 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e127116..65008bb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -916,6 +916,31 @@ dependencies = [ "miniz_oxide", ] +[[package]] +name = "fleet_apiserver" +version = "0.1.0" +dependencies = [ + "actix-http", + "actix-service", + "actix-web", + "async-trait", + "chrono", + "diesel", + "diesel_migrations", + "dotenv", + "env_logger", + "feventbus", + "jsonschema", + "k8s-openapi", + "lazy_static", + "once_cell", + "r2d2", + "schemars", + "serde", + "serde_json", + "tokio", +] + [[package]] name = "fluent-uri" version = "0.3.2" @@ -1467,30 +1492,6 @@ dependencies = [ "serde_json", ] -[[package]] -name = "k8s_apiserver" -version = "0.1.5" -dependencies = [ - "actix-http", - "actix-service", - "actix-web", - "async-trait", - "chrono", - "diesel", - "diesel_migrations", - "dotenv", - "env_logger", - "feventbus", - "jsonschema", - "k8s-openapi", - "once_cell", - "r2d2", - "schemars", - "serde", - "serde_json", - "tokio", -] - [[package]] name = "language-tags" version = "0.3.2" diff --git a/Cargo.toml b/Cargo.toml index c2920a2..0a37ef1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,12 +1,12 @@ [package] -name = "k8s_apiserver" -version = "0.1.5" +name = "fleet_apiserver" +version = "0.1.0" license = "Apache-2.0" authors = ["wuheng ", "chenhongyu23@otcaix.iscas.ac.cn"] categories = ["api-bindings"] -description = "Kubernetes apiserver" +description = "Kubernetes apiserver for fleet" edition = "2021" -keywords = ["apiserver", "kubernetes", "k8s"] +keywords = ["apiserver", "kubernetes", "k8s", "fleet"] repository = "https://gitee.com/iscas-system/apiserver" readme = "README.md" @@ -24,11 +24,9 @@ env_logger = "0.11.5" serde = { version = "1.0.209", features = ["derive"] } serde_json = "1.0.127" tokio = "1.40.0" -#kube = { version = "0.96.0", features = ["runtime", "derive"] } k8s-openapi = { version = "0.23.0", features = ["latest"] } jsonschema = "0.23.0" schemars = "0.8.21" chrono = "0.4.38" once_cell = "1.20.2" -#log = "0.4" -#env_logger = { version = "0.11" } +lazy_static = "1.5.0" \ No newline at end of file diff --git a/src/cores/apiserver.rs b/src/cores/apiserver.rs index ee6750f..963d751 100644 --- a/src/cores/apiserver.rs +++ b/src/cores/apiserver.rs @@ -1,10 +1,3 @@ -/** - * Copyright (2024, ) Institute of Software, Chinese Academy of Sciences - * author: wuheng@iscas.ac.cn - * since: 0.1.2 - * -**/ - use actix_web::{HttpServer, App, web, HttpResponse}; use crate::cores::config::{Config, APIS_WITHOUT_NAMESPACE, APIS_WITH_NAMESPACE, API_WITHOUT_NAMESPACE, API_WITH_NAMESPACE}; diff --git a/src/cores/handlers.rs b/src/cores/handlers.rs index a335666..6cb9b01 100644 --- a/src/cores/handlers.rs +++ b/src/cores/handlers.rs @@ -1,13 +1,7 @@ +use std::collections::HashMap; use std::fmt::Debug; -use std::sync::Arc; +use std::sync::{Arc, LazyLock, Mutex}; use std::time; -/** - * Copyright (2024, ) Institute of Software, Chinese Academy of Sciences - * author: wuheng@iscas.ac.cn - * since: 0.1.0 - * -**/ - use async_trait::async_trait; use actix_web::{HttpResponse, Result, web}; use chrono::Utc; @@ -20,12 +14,33 @@ use actix_web::error::ErrorInternalServerError; use feventbus::impls::nats::nats::NatsCli; use feventbus::message::Message; use feventbus::message; -use feventbus::traits::consumer::{Consumer, MessageHandler}; +use feventbus::traits::consumer::{Consumer}; use feventbus::traits::producer::Producer; use serde::{Deserialize, Serialize}; use cores::apiserver::ApiServerMessage; use crate::cores; +// 定义全局哈希表来获取model名 +static GLOBAL_HASHMAP: LazyLock>> = LazyLock::new(|| { + let mut map = HashMap::new(); + map.insert("cargos".to_string(), "CARGO".to_string()); + map.insert("nodes".to_string(), "NODE".to_string()); + map.insert("jobs".to_string(), "JOB".to_string()); + Mutex::new(map) +}); + +// 添加键值对 +fn insert_key_value(key: &str, value: &str) { + let mut map = GLOBAL_HASHMAP.lock().unwrap(); + map.insert(key.to_string(), value.to_string()); +} + +// 获取键对应的值 +fn get_value(key: &str) -> Option { + let map = GLOBAL_HASHMAP.lock().unwrap(); + map.get(key).cloned() +} + #[async_trait] pub trait Handler { // /api/{version}/{plural} @@ -614,21 +629,6 @@ async fn get_all_data_from_table( } } -// 收到请求并等待响应 -async fn reply_to_topic( - topic: &str, - nats_cli: Arc>, - handler: MessageHandler, -) -> Result<(), Box> -where - T: Serialize + for<'de> Deserialize<'de> + Debug + Send + Clone + Sync + 'static, -{ - nats_cli - .reply(topic, handler) - .await - .map_err(|e| Box::new(e) as Box)?; - Ok(()) -} // 发送请求并等待响应 async fn send_request(message: Message, nats_cli: Arc>) -> Result<(), Box> @@ -639,11 +639,7 @@ where .request(message, time::Duration::from_secs(100)) .await { - Ok(response) => { - println!( - "===============Received response: {:?}==================", - response - ); + Ok(_) => { Ok(()) } Err(e) => { @@ -675,6 +671,13 @@ impl Handler for DefaultHandler { .and_then(|plural| plural.as_str()) .unwrap_or("error"); + let crd_kind = data + .get("spec") + .and_then(|spec| spec.get("names")) + .and_then(|names| names.get("kind")) + .and_then(|kind| kind.as_str()) + .unwrap_or("error"); + // 调用check_metadata函数 let metadata_exists = check_metadata(db_connection, table_name, &version,false).await.map_err(ErrorInternalServerError)?; @@ -682,7 +685,6 @@ impl Handler for DefaultHandler { return Ok(HttpResponse::NotFound().json(json!({ "error": "该 crd 资源已存在,无需重复注册" }))); } - create_table_if_not_exists(db_connection, table_name) .await .map_err(ErrorInternalServerError)?; @@ -690,6 +692,8 @@ impl Handler for DefaultHandler { insert_metadata(db_connection, table_name, &version, false, &data) .await .map_err(ErrorInternalServerError)?; + + insert_key_value(table_name, crd_kind); } else { // 调用check_metadata函数 let metadata_exists = check_metadata(db_connection, &plural, &version,false).await.map_err(ErrorInternalServerError)?; @@ -698,17 +702,23 @@ impl Handler for DefaultHandler { return Ok(HttpResponse::NotFound().json(json!({ "error": "该 plural 不存在,请重新注册或检查 plural 版本以及是否需要 namespace" }))); } + let mut model_map = HashMap::new(); + let kind = get_value(&*plural.clone()).unwrap(); + + model_map.insert("MODEL".to_string(), kind); + // request消息 let request_message = Message::new( "CREATE".to_string(), message::NativeEventAction::Other, - None, + Some(model_map), Some(ApiServerMessage { content: data.to_string(), }), None, ); - tokio::spawn(send_request(request_message, nats_cli)); + + send_request(request_message, nats_cli).await.map_err(ErrorInternalServerError)?; insert_into_table(db_connection, &plural, &data, &version, None) .await @@ -737,6 +747,13 @@ impl Handler for DefaultHandler { .and_then(|plural| plural.as_str()) .unwrap_or("error"); + let crd_kind = data + .get("spec") + .and_then(|spec| spec.get("names")) + .and_then(|names| names.get("kind")) + .and_then(|kind| kind.as_str()) + .unwrap_or("error"); + // 调用check_metadata函数 let metadata_exists = check_metadata(db_connection, table_name, &version, true).await.map_err(ErrorInternalServerError)?; @@ -752,6 +769,8 @@ impl Handler for DefaultHandler { insert_metadata(db_connection, table_name, &version, false, &data) .await .map_err(ErrorInternalServerError)?; + + insert_key_value(table_name, crd_kind); } else { // 调用check_metadata函数 let metadata_exists = check_metadata(db_connection, &plural, &version, true).await.map_err(ErrorInternalServerError)?; @@ -760,17 +779,23 @@ impl Handler for DefaultHandler { return Ok(HttpResponse::NotFound().json(json!({ "error": "该 plural 不存在,请重新注册或检查 plural 版本以及是否需要 namespace" }))); } + let mut model_map = HashMap::new(); + let kind = get_value(&*plural.clone()).unwrap(); + + model_map.insert("MODEL".to_string(), kind); + // request消息 let request_message = Message::new( "CREATE".to_string(), message::NativeEventAction::Other, - None, + Some(model_map), Some(ApiServerMessage { content: data.to_string(), }), None, ); - tokio::spawn(send_request(request_message, nats_cli)); + + send_request(request_message, nats_cli).await.map_err(ErrorInternalServerError)?; insert_into_table(db_connection, &plural, &data, &version, Some(&namespace)) .await @@ -801,6 +826,13 @@ impl Handler for DefaultHandler { .and_then(|plural| plural.as_str()) .unwrap_or("error"); + let crd_kind = data + .get("spec") + .and_then(|spec| spec.get("names")) + .and_then(|names| names.get("kind")) + .and_then(|kind| kind.as_str()) + .unwrap_or("error"); + // 调用check_metadata函数 let metadata_exists = check_metadata(db_connection, table_name, &ver, false).await.map_err(ErrorInternalServerError)?; @@ -816,6 +848,8 @@ impl Handler for DefaultHandler { insert_metadata(db_connection, table_name, &ver, false, &data) .await .map_err(ErrorInternalServerError)?; + + insert_key_value(table_name, crd_kind); } else { // 调用check_metadata函数 let metadata_exists = check_metadata(db_connection, &plural, &ver, false).await.map_err(ErrorInternalServerError)?; @@ -824,17 +858,23 @@ impl Handler for DefaultHandler { return Ok(HttpResponse::NotFound().json(json!({ "error": "该 plural 不存在,请重新注册或检查 plural 版本以及是否需要 namespace" }))); } + let mut model_map = HashMap::new(); + let kind = get_value(&*plural.clone()).unwrap(); + + model_map.insert("MODEL".to_string(), kind); + // request消息 let request_message = Message::new( "CREATE".to_string(), message::NativeEventAction::Other, - None, + Some(model_map), Some(ApiServerMessage { content: data.to_string(), }), None, ); - tokio::spawn(send_request(request_message, nats_cli)); + + send_request(request_message, nats_cli).await.map_err(ErrorInternalServerError)?; insert_into_table(db_connection, &plural, &data, &ver, None) .await @@ -866,6 +906,13 @@ impl Handler for DefaultHandler { .and_then(|plural| plural.as_str()) .unwrap_or("error"); + let crd_kind = data + .get("spec") + .and_then(|spec| spec.get("names")) + .and_then(|names| names.get("kind")) + .and_then(|kind| kind.as_str()) + .unwrap_or("error"); + // 调用 check_metadata 函数 let metadata_exists = check_metadata(db_connection, table_name, &ver, true).await.map_err(ErrorInternalServerError)?; @@ -881,6 +928,8 @@ impl Handler for DefaultHandler { insert_metadata(db_connection, table_name, &ver, false, &data) .await .map_err(ErrorInternalServerError)?; + + insert_key_value(table_name, crd_kind); } else { // 调用 check_metadata 函数 let metadata_exists = check_metadata(db_connection, &plural, &ver, true).await.map_err(ErrorInternalServerError)?; @@ -889,17 +938,23 @@ impl Handler for DefaultHandler { return Ok(HttpResponse::NotFound().json(json!({ "error": "该 plural 不存在,请重新注册或检查 plural 版本以及是否需要 namespace" }))); } + let mut model_map = HashMap::new(); + let kind = get_value(&*plural.clone()).unwrap(); + + model_map.insert("MODEL".to_string(), kind); + // request消息 let request_message = Message::new( "CREATE".to_string(), message::NativeEventAction::Other, - None, + Some(model_map), Some(ApiServerMessage { content: data.to_string(), }), None, ); - tokio::spawn(send_request(request_message, nats_cli)); + + send_request(request_message, nats_cli).await.map_err(ErrorInternalServerError)?; insert_into_table(db_connection, &plural, &data, &ver, Some(&namespace)) .await @@ -927,17 +982,23 @@ impl Handler for DefaultHandler { return Ok(HttpResponse::NotFound().json(json!({ "error": "该 plural 不存在,请检查 plural 版本以及是否需要 namespace" }))); } + let mut model_map = HashMap::new(); + let kind = get_value(&*plural.clone()).unwrap(); + + model_map.insert("MODEL".to_string(), kind); + // request消息 let request_message = Message::new( "REMOVE".to_string(), message::NativeEventAction::Other, - None, + Some(model_map), Some(ApiServerMessage { content: name.clone(), }), None, ); - tokio::spawn(send_request(request_message, nats_cli)); + + send_request(request_message, nats_cli).await.map_err(ErrorInternalServerError)?; // 从 plural 表中删除指定的 name let deleted = delete_from_table(db_connection, &plural, &name, &version, None) @@ -968,17 +1029,22 @@ impl Handler for DefaultHandler { return Ok(HttpResponse::NotFound().json(json!({ "error": "该 plural 不存在,请检查 plural 版本以及是否需要 namespace" }))); } + let mut model_map = HashMap::new(); + let kind = get_value(&*plural.clone()).unwrap(); + + model_map.insert("MODEL".to_string(), kind); + // request消息 let request_message = Message::new( "REMOVE".to_string(), message::NativeEventAction::Other, - None, + Some(model_map), Some(ApiServerMessage { content: name.clone(), }), None, ); - tokio::spawn(send_request(request_message, nats_cli)); + send_request(request_message, nats_cli).await.map_err(ErrorInternalServerError)?; // 从 plural 表中删除指定的数据 let deleted = delete_from_table(db_connection, &plural, &name, &version, Some(&namespace)) @@ -1010,17 +1076,22 @@ impl Handler for DefaultHandler { return Ok(HttpResponse::NotFound().json(json!({ "error": "该 plural 不存在,请检查 plural 版本以及是否需要 namespace" }))); } + let mut model_map = HashMap::new(); + let kind = get_value(&*plural.clone()).unwrap(); + + model_map.insert("MODEL".to_string(), kind); + // request消息 let request_message = Message::new( "REMOVE".to_string(), message::NativeEventAction::Other, - None, + Some(model_map), Some(ApiServerMessage { content: name.clone(), }), None, ); - tokio::spawn(send_request(request_message, nats_cli)); + send_request(request_message, nats_cli).await.map_err(ErrorInternalServerError)?; let deleted = delete_from_table(db_connection, &plural, &name, &ver, None) .await @@ -1051,17 +1122,22 @@ impl Handler for DefaultHandler { return Ok(HttpResponse::NotFound().json(json!({ "error": "该 plural 不存在,请检查 plural 版本以及是否需要 namespace" }))); } + let mut model_map = HashMap::new(); + let kind = get_value(&*plural.clone()).unwrap(); + + model_map.insert("MODEL".to_string(), kind); + // request消息 let request_message = Message::new( "REMOVE".to_string(), message::NativeEventAction::Other, - None, + Some(model_map), Some(ApiServerMessage { content: name.clone(), }), None, ); - tokio::spawn(send_request(request_message, nats_cli)); + send_request(request_message, nats_cli).await.map_err(ErrorInternalServerError)?; let deleted = delete_from_table(db_connection, &plural, &name, &ver, Some(&namespace)) .await @@ -1512,7 +1588,8 @@ mod tests { } } })) - .route("/api/{version}/namespaces/{namespace}/{plural}/{name}", web::get().to( + .route("/api/{version}/namespaces/{namespace}/{plural}/{name}", web::get().to({ + let nats_cli = Arc::clone(&nats_cli); move |path, data| { let handler = HANDLER.clone(); let db_pool = DB_POOL.clone(); @@ -1525,7 +1602,7 @@ mod tests { } } } - )) + })) .route("/api/{version}/namespaces/{namespace}/{plural}", web::get().to({ let nats_cli = Arc::clone(&nats_cli); move |path, data| { diff --git a/src/lib.rs b/src/lib.rs index 60932e1..c219ec4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,2 +1,33 @@ pub mod cores; -pub mod schema; \ No newline at end of file +pub mod schema; + +use cores::apiserver::ApiServer; +use cores::config::DefaultConfig; +use cores::handlers::DefaultHandler; +use cores::db::DbPool; +use std::sync::Arc; +use env_logger; + + +/// 启动 Web 服务器 +/// +/// # 参数 +/// - `database_url`: 数据库连接字符串 +/// - `address`: 服务监听地址(如 "0.0.0.0:8080") +/// +/// # 返回值 +/// - 异步运行结果 +pub async fn start_server(database_url: &str, address: &str) -> Result<(), Box> { + // 创建数据库连接池 + let db_pool = Arc::new(DbPool::new(database_url)?); + + // 初始化日志 + env_logger::init(); + + // 配置和启动服务器 + let config = Box::new(DefaultConfig::new()); + let server = ApiServer::new(config); + let handler: DefaultHandler = DefaultHandler::new(); + server.start(address, handler, db_pool).await?; + Ok(()) +} diff --git a/src/main.rs b/src/main.rs index a9aba48..1a6664d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,39 +1,17 @@ - -/** - * Copyright (2024, ) Institute of Software, Chinese Academy of Sciences - * author: wuheng@iscas.ac.cn - * since: 0.1.0 - * -**/ - -use k8s_apiserver::cores::apiserver::ApiServer; -use k8s_apiserver::cores::config::DefaultConfig; -use k8s_apiserver::cores::handlers::DefaultHandler; -use std::sync::{Arc}; -use env_logger; -use dotenv::dotenv; use std::env; -use k8s_apiserver::cores::db::DbPool; +use dotenv::dotenv; +use k8s_apiserver::start_server; #[actix_web::main] -async fn main() -{ +async fn main() { dotenv().ok(); + // 从环境变量读取配置 let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set"); - // 创建连接池 - let db_pool = Arc::new(DbPool::new(&database_url).expect("Failed to create database pool")); - - env_logger::init(); - - start(db_pool).await; + let address = "0.0.0.0:8080"; // 或者通过环境变量或配置文件读取 + // 启动服务 + if let Err(e) = start_server(&database_url, address).await { + eprintln!("Failed to start server: {}", e); + } } - -async fn start(db_pool: Arc) { - let config = Box::new(DefaultConfig::new()); - let server = ApiServer::new(config); - let handler: DefaultHandler = DefaultHandler::new(); - - let _ = Arc::new(server).start("0.0.0.0:8080", handler, db_pool).await; -} \ No newline at end of file -- Gitee From 043c7febdf3d19a22ed0c0bf2e9193b2c92aa403 Mon Sep 17 00:00:00 2001 From: Yuichi <913637919@qq.com> Date: Mon, 25 Nov 2024 07:30:24 +0000 Subject: [PATCH 04/48] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=83=A8=E5=88=86?= =?UTF-8?q?=E5=87=BD=E6=95=B0=E5=AE=9A=E4=B9=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.lock | 50 +++++++++++++++++++++++++------------------------- Cargo.toml | 2 +- src/lib.rs | 2 ++ 3 files changed, 28 insertions(+), 26 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 65008bb..eef6a1c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -916,31 +916,6 @@ dependencies = [ "miniz_oxide", ] -[[package]] -name = "fleet_apiserver" -version = "0.1.0" -dependencies = [ - "actix-http", - "actix-service", - "actix-web", - "async-trait", - "chrono", - "diesel", - "diesel_migrations", - "dotenv", - "env_logger", - "feventbus", - "jsonschema", - "k8s-openapi", - "lazy_static", - "once_cell", - "r2d2", - "schemars", - "serde", - "serde_json", - "tokio", -] - [[package]] name = "fluent-uri" version = "0.3.2" @@ -1492,6 +1467,31 @@ dependencies = [ "serde_json", ] +[[package]] +name = "k8s_apiserver" +version = "0.1.0" +dependencies = [ + "actix-http", + "actix-service", + "actix-web", + "async-trait", + "chrono", + "diesel", + "diesel_migrations", + "dotenv", + "env_logger", + "feventbus", + "jsonschema", + "k8s-openapi", + "lazy_static", + "once_cell", + "r2d2", + "schemars", + "serde", + "serde_json", + "tokio", +] + [[package]] name = "language-tags" version = "0.3.2" diff --git a/Cargo.toml b/Cargo.toml index 0a37ef1..38fb21c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "fleet_apiserver" +name = "k8s_apiserver" version = "0.1.0" license = "Apache-2.0" authors = ["wuheng ", "chenhongyu23@otcaix.iscas.ac.cn"] diff --git a/src/lib.rs b/src/lib.rs index c219ec4..d02e6db 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -31,3 +31,5 @@ pub async fn start_server(database_url: &str, address: &str) -> Result<(), Box Date: Mon, 25 Nov 2024 07:33:07 +0000 Subject: [PATCH 05/48] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=83=A8=E5=88=86?= =?UTF-8?q?=E5=87=BD=E6=95=B0=E5=AE=9A=E4=B9=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/lib.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index d02e6db..cdbf155 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -28,8 +28,7 @@ pub async fn start_server(database_url: &str, address: &str) -> Result<(), Box Date: Mon, 25 Nov 2024 07:36:15 +0000 Subject: [PATCH 06/48] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=A1=B9=E7=9B=AE?= =?UTF-8?q?=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.lock | 50 +++++++++++++++++++++++++------------------------- Cargo.toml | 2 +- src/main.rs | 2 +- 3 files changed, 27 insertions(+), 27 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index eef6a1c..65008bb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -916,6 +916,31 @@ dependencies = [ "miniz_oxide", ] +[[package]] +name = "fleet_apiserver" +version = "0.1.0" +dependencies = [ + "actix-http", + "actix-service", + "actix-web", + "async-trait", + "chrono", + "diesel", + "diesel_migrations", + "dotenv", + "env_logger", + "feventbus", + "jsonschema", + "k8s-openapi", + "lazy_static", + "once_cell", + "r2d2", + "schemars", + "serde", + "serde_json", + "tokio", +] + [[package]] name = "fluent-uri" version = "0.3.2" @@ -1467,31 +1492,6 @@ dependencies = [ "serde_json", ] -[[package]] -name = "k8s_apiserver" -version = "0.1.0" -dependencies = [ - "actix-http", - "actix-service", - "actix-web", - "async-trait", - "chrono", - "diesel", - "diesel_migrations", - "dotenv", - "env_logger", - "feventbus", - "jsonschema", - "k8s-openapi", - "lazy_static", - "once_cell", - "r2d2", - "schemars", - "serde", - "serde_json", - "tokio", -] - [[package]] name = "language-tags" version = "0.3.2" diff --git a/Cargo.toml b/Cargo.toml index 38fb21c..0a37ef1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "k8s_apiserver" +name = "fleet_apiserver" version = "0.1.0" license = "Apache-2.0" authors = ["wuheng ", "chenhongyu23@otcaix.iscas.ac.cn"] diff --git a/src/main.rs b/src/main.rs index 1a6664d..4ad7338 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,6 @@ use std::env; use dotenv::dotenv; -use k8s_apiserver::start_server; +use fleet_apiserver::start_server; #[actix_web::main] async fn main() { -- Gitee From 4278ae61aee8cdead456f327569e31f2c910085d Mon Sep 17 00:00:00 2001 From: Yuichi <913637919@qq.com> Date: Mon, 25 Nov 2024 07:47:35 +0000 Subject: [PATCH 07/48] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=83=A8=E5=88=86?= =?UTF-8?q?=E5=87=BD=E6=95=B0=E5=AE=9A=E4=B9=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/cores/handlers.rs | 8 ++++---- src/main.rs | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/cores/handlers.rs b/src/cores/handlers.rs index 6cb9b01..ce370a2 100644 --- a/src/cores/handlers.rs +++ b/src/cores/handlers.rs @@ -989,7 +989,7 @@ impl Handler for DefaultHandler { // request消息 let request_message = Message::new( - "REMOVE".to_string(), + "DELETE".to_string(), message::NativeEventAction::Other, Some(model_map), Some(ApiServerMessage { @@ -1036,7 +1036,7 @@ impl Handler for DefaultHandler { // request消息 let request_message = Message::new( - "REMOVE".to_string(), + "DELETE".to_string(), message::NativeEventAction::Other, Some(model_map), Some(ApiServerMessage { @@ -1083,7 +1083,7 @@ impl Handler for DefaultHandler { // request消息 let request_message = Message::new( - "REMOVE".to_string(), + "DELETE".to_string(), message::NativeEventAction::Other, Some(model_map), Some(ApiServerMessage { @@ -1129,7 +1129,7 @@ impl Handler for DefaultHandler { // request消息 let request_message = Message::new( - "REMOVE".to_string(), + "DELETE".to_string(), message::NativeEventAction::Other, Some(model_map), Some(ApiServerMessage { diff --git a/src/main.rs b/src/main.rs index 4ad7338..d20e3b9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,7 +8,7 @@ async fn main() { // 从环境变量读取配置 let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set"); - let address = "0.0.0.0:8080"; // 或者通过环境变量或配置文件读取 + let address = "0.0.0.0:8080"; // 启动服务 if let Err(e) = start_server(&database_url, address).await { -- Gitee From bf49c8d00dde452597433403c0b794e208eb9957 Mon Sep 17 00:00:00 2001 From: Yuichi <913637919@qq.com> Date: Mon, 25 Nov 2024 07:49:02 +0000 Subject: [PATCH 08/48] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 65008bb..616cd06 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -918,7 +918,7 @@ dependencies = [ [[package]] name = "fleet_apiserver" -version = "0.1.0" +version = "0.2.0" dependencies = [ "actix-http", "actix-service", diff --git a/Cargo.toml b/Cargo.toml index 0a37ef1..856e098 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "fleet_apiserver" -version = "0.1.0" +version = "0.2.0" license = "Apache-2.0" authors = ["wuheng ", "chenhongyu23@otcaix.iscas.ac.cn"] categories = ["api-bindings"] -- Gitee From 9dc865c7eeaffba303081a8d5a667bef41d716f3 Mon Sep 17 00:00:00 2001 From: Yuichi <913637919@qq.com> Date: Tue, 26 Nov 2024 08:13:22 +0000 Subject: [PATCH 09/48] =?UTF-8?q?=E6=89=80=E6=9C=89=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=AD=98=E5=82=A8=E5=88=B0kine=E8=A1=A8=E5=86=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../down.sql | 3 +- .../up.sql | 11 + src/cores/db.rs | 15 - src/cores/handlers.rs | 405 +++++++++++++----- src/schema.rs | 19 +- 5 files changed, 320 insertions(+), 133 deletions(-) diff --git a/migrations/2024-11-03-082237_create_metadata_table/down.sql b/migrations/2024-11-03-082237_create_metadata_table/down.sql index d3c389a..55d1278 100644 --- a/migrations/2024-11-03-082237_create_metadata_table/down.sql +++ b/migrations/2024-11-03-082237_create_metadata_table/down.sql @@ -1,2 +1,3 @@ -- This file should undo anything in `up.sql` -DROP TABLE IF EXISTS metadata; \ No newline at end of file +DROP TABLE IF EXISTS metadata; +DROP TABLE IF EXISTS kine; \ No newline at end of file diff --git a/migrations/2024-11-03-082237_create_metadata_table/up.sql b/migrations/2024-11-03-082237_create_metadata_table/up.sql index e89b705..5515cb3 100644 --- a/migrations/2024-11-03-082237_create_metadata_table/up.sql +++ b/migrations/2024-11-03-082237_create_metadata_table/up.sql @@ -7,4 +7,15 @@ CREATE TABLE IF NOT EXISTS metadata ( created_time VARCHAR(256), updated_time VARCHAR(256), PRIMARY KEY (name, namespace, apigroup) + ); + +CREATE TABLE IF NOT EXISTS kine ( + kind VARCHAR(256), + name VARCHAR(256), + namespace VARCHAR(256), + apigroup VARCHAR(256), + data TEXT, + created_time VARCHAR(256), + updated_time VARCHAR(256), + PRIMARY KEY (kind, name, namespace, apigroup) ); \ No newline at end of file diff --git a/src/cores/db.rs b/src/cores/db.rs index 33b5c67..1a888dd 100644 --- a/src/cores/db.rs +++ b/src/cores/db.rs @@ -116,19 +116,6 @@ impl DbPool { for (table_name, (supports_namespace, template)) in templates.iter() { - let create_table_query = format!( - "CREATE TABLE IF NOT EXISTS {} ( - name VARCHAR(256), - namespace VARCHAR(256), - apigroup VARCHAR(256), - data TEXT, - created_time VARCHAR(256), - updated_time VARCHAR(256), - PRIMARY KEY (name, namespace, apigroup) - );", - table_name - ); - // 从模板中提取 `apiVersion` 字段作为 `apigroup` let apigroup = template.get("apiVersion") .and_then(Value::as_str) @@ -147,11 +134,9 @@ impl DbPool { match conn { DbConnection::Pg(pg_conn) => { - sql_query(create_table_query).execute(pg_conn)?; sql_query(insert_metadata_query).execute(pg_conn)?; }, DbConnection::Sqlite(sqlite_conn) => { - sql_query(create_table_query).execute(sqlite_conn)?; sql_query(insert_metadata_query).execute(sqlite_conn)?; } } diff --git a/src/cores/handlers.rs b/src/cores/handlers.rs index ce370a2..3cf3524 100644 --- a/src/cores/handlers.rs +++ b/src/cores/handlers.rs @@ -14,7 +14,6 @@ use actix_web::error::ErrorInternalServerError; use feventbus::impls::nats::nats::NatsCli; use feventbus::message::Message; use feventbus::message; -use feventbus::traits::consumer::{Consumer}; use feventbus::traits::producer::Producer; use serde::{Deserialize, Serialize}; use cores::apiserver::ApiServerMessage; @@ -269,34 +268,60 @@ async fn check_metadata( } -// 创建新的数据表 -async fn create_table_if_not_exists(conn: &mut DbConnection, table_name: &str) -> QueryResult<()> { - - let create_query = format!( - "CREATE TABLE IF NOT EXISTS {} ( - name VARCHAR(256), - namespace VARCHAR(256), - apigroup VARCHAR(256), - data TEXT, - created_time VARCHAR(256), - updated_time VARCHAR(256), - PRIMARY KEY (name, namespace, apigroup) - )", - table_name - ); +// 查询 kine 表中指定的数据是否存在 +async fn check_kine( + conn: &mut DbConnection, + item_kind: &str, + item_name: &str, + item_version: &str, + item_namespace: Option<&str>, +) -> QueryResult { + use diesel::dsl::count_star; + use crate::schema::kine::dsl::*; + let count; match conn { DbConnection::Pg(pg_conn) => { - diesel::sql_query(create_query).execute(pg_conn)?; + if let Some(_) = item_namespace { + count = kine + .filter(kind.eq(item_kind)) + .filter(name.eq(item_name)) + .filter(apigroup.eq(item_version)) + .filter(namespace.eq(item_namespace)) + .select(count_star()) + .first::(pg_conn)?; + } else { + count = kine + .filter(kind.eq(item_kind)) + .filter(name.eq(item_name)) + .filter(apigroup.eq(item_version)) + .select(count_star()) + .first::(pg_conn)?; + } }, DbConnection::Sqlite(sqlite_conn) => { - diesel::sql_query(create_query).execute(sqlite_conn)?; + if let Some(_) = item_namespace { + count = kine + .filter(kind.eq(item_kind)) + .filter(name.eq(item_name)) + .filter(apigroup.eq(item_version)) + .filter(namespace.eq(item_namespace)) + .select(count_star()) + .first::(sqlite_conn)?; + } else { + count = kine + .filter(kind.eq(item_kind)) + .filter(name.eq(item_name)) + .filter(apigroup.eq(item_version)) + .select(count_star()) + .first::(sqlite_conn)?; + } } } - - Ok(()) + Ok(count > 0) } + // 在 metadata 表中插入新记录 async fn insert_metadata( conn: &mut DbConnection, @@ -340,26 +365,18 @@ async fn insert_metadata( // 插入数据到指定的表 async fn insert_into_table( conn: &mut DbConnection, - table_name: &str, + item_kind: &str, + item_name: &str, json_data: &Value, version: &str, namespace: Option<&str>, ) -> QueryResult<()> { match conn { DbConnection::Pg(pg_conn) => { - // 从 json_data 中提取 metadata.name - let name = json_data - .get("metadata") - .and_then(|metadata| metadata.get("name")) - .and_then(|name| name.as_str()) - .unwrap_or("error"); - - let insert_query = format!( - "INSERT INTO {} (name, namespace, apigroup, data, created_time, updated_time) VALUES ($1, $2, $3, $4, $5, $6)", - table_name - ); + let insert_query = "INSERT INTO kine (kind, name, namespace, apigroup, data, created_time, updated_time) VALUES ($1, $2, $3, $4, $5, $6, $7)".to_string(); diesel::sql_query(insert_query) - .bind::(name) + .bind::(item_kind) + .bind::(item_name) .bind::(namespace.unwrap_or("")) .bind::(version) .bind::(json_data.to_string()) // 将 JSON 数据存储为 TEXT @@ -368,19 +385,10 @@ async fn insert_into_table( .execute(pg_conn)?; }, DbConnection::Sqlite(sqlite_conn) => { - // 从 json_data 中提取 metadata.name - let name = json_data - .get("metadata") - .and_then(|metadata| metadata.get("name")) - .and_then(|name| name.as_str()) - .unwrap_or("error"); - - let insert_query = format!( - "INSERT INTO {} (name, namespace, apigroup, data, created_time, updated_time) VALUES (?, ?, ?, ?, ?, ?)", - table_name - ); + let insert_query = "INSERT INTO kine (kind, name, namespace, apigroup, data, created_time, updated_time) VALUES (?, ?, ?, ?, ?, ?)".to_string(); diesel::sql_query(insert_query) - .bind::(name) + .bind::(item_kind) + .bind::(item_name) .bind::(namespace.unwrap_or("")) .bind::(version) .bind::(json_data.to_string()) // 将 JSON 数据存储为 TEXT @@ -395,7 +403,7 @@ async fn insert_into_table( // 从 plural 表中删除特定 name 的记录 async fn delete_from_table( conn: &mut DbConnection, - table_name: &str, + item_kind: &str, item_name: &str, item_version: &str, item_namespace: Option<&str>, @@ -403,13 +411,13 @@ async fn delete_from_table( // 根据是否存在 namespace 动态构建删除查询 let delete_query = if let Some(_) = item_namespace { match conn { - DbConnection::Pg(_) => format!("DELETE FROM {} WHERE name = $1 AND namespace = $2 AND apigroup = $3", table_name), - DbConnection::Sqlite(_) => format!("DELETE FROM {} WHERE name = ? AND namespace = ? AND apigroup = ?", table_name), + DbConnection::Pg(_) => "DELETE FROM kine WHERE kind = $1 AND name = $2 AND namespace = $3 AND apigroup = $4".to_string(), + DbConnection::Sqlite(_) => "DELETE FROM kine WHERE kind = ? AND name = ? AND namespace = ? AND apigroup = ?".to_string(), } } else { match conn { - DbConnection::Pg(_) => format!("DELETE FROM {} WHERE name = $1 AND apigroup = $2", table_name), - DbConnection::Sqlite(_) => format!("DELETE FROM {} WHERE name = ? AND apigroup = ?", table_name), + DbConnection::Pg(_) => "DELETE FROM kine WHERE kind = $1 AND name = $2 AND apigroup = $3".to_string(), + DbConnection::Sqlite(_) => "DELETE FROM kine WHERE kind = ? AND name = ? AND apigroup = ?".to_string(), } }; @@ -418,12 +426,14 @@ async fn delete_from_table( DbConnection::Pg(pg_conn) => { if let Some(namespace) = item_namespace { diesel::sql_query(delete_query) + .bind::(item_kind) .bind::(item_name) .bind::(namespace) .bind::(item_version) .execute(pg_conn)? } else { diesel::sql_query(delete_query) + .bind::(item_kind) .bind::(item_name) .bind::(item_version) .execute(pg_conn)? @@ -432,12 +442,14 @@ async fn delete_from_table( DbConnection::Sqlite(sqlite_conn) => { if let Some(namespace) = item_namespace { diesel::sql_query(delete_query) + .bind::(item_kind) .bind::(item_name) .bind::(namespace) .bind::(item_version) .execute(sqlite_conn)? } else { diesel::sql_query(delete_query) + .bind::(item_kind) .bind::(item_name) .bind::(item_version) .execute(sqlite_conn)? @@ -450,7 +462,7 @@ async fn delete_from_table( async fn update_data_in_table( conn: &mut DbConnection, - table_name: &str, + item_kind: &str, item_name: &str, item_version: &str, item_namespace: Option<&str>, @@ -459,13 +471,13 @@ async fn update_data_in_table( let update_query = if let Some(_) = item_namespace { match conn { - DbConnection::Pg(_) => format!("UPDATE {} SET data = $1, updated_time = $2 WHERE name = $3 AND namespace = $4 AND apigroup = $5", table_name), - DbConnection::Sqlite(_) => format!("UPDATE {} SET data = ?, updated_time = ? WHERE name = ? AND namespace = ? AND apigroup = ?", table_name), + DbConnection::Pg(_) => "UPDATE kine SET data = $1, updated_time = $2 WHERE kind = $3 AND name = $4 AND namespace = $5 AND apigroup = $6".to_string(), + DbConnection::Sqlite(_) => "UPDATE kine SET data = ?, updated_time = ? WHERE kind = ? AND name = ? AND namespace = ? AND apigroup = ?".to_string(), } } else { match conn { - DbConnection::Pg(_) => format!("UPDATE {} SET data = $1, updated_time = $2 WHERE name = $3 AND apigroup = $4", table_name), - DbConnection::Sqlite(_) => format!("UPDATE {} SET data = ?, updated_time = ? WHERE name = ? AND apigroup = ?", table_name), + DbConnection::Pg(_) => "UPDATE kine SET data = $1, updated_time = $2 WHERE kind = $3 AND name = $4 AND apigroup = $5".to_string(), + DbConnection::Sqlite(_) => "UPDATE kine SET data = ?, updated_time = ? WHERE kind = ? AND name = ? AND apigroup = ?".to_string(), } }; @@ -475,6 +487,7 @@ async fn update_data_in_table( diesel::sql_query(update_query) .bind::(json_data.to_string()) .bind::(Utc::now().naive_utc().to_string()) + .bind::(item_kind) .bind::(item_name) .bind::(namespace) .bind::(item_version) @@ -483,6 +496,7 @@ async fn update_data_in_table( diesel::sql_query(update_query) .bind::(json_data.to_string()) .bind::(Utc::now().naive_utc().to_string()) + .bind::(item_kind) .bind::(item_name) .bind::(item_version) .execute(pg_conn)? @@ -493,6 +507,7 @@ async fn update_data_in_table( diesel::sql_query(update_query) .bind::(json_data.to_string()) .bind::(Utc::now().naive_utc().to_string()) + .bind::(item_kind) .bind::(item_name) .bind::(namespace) .bind::(item_version) @@ -501,6 +516,7 @@ async fn update_data_in_table( diesel::sql_query(update_query) .bind::(json_data.to_string()) .bind::(Utc::now().naive_utc().to_string()) + .bind::(item_kind) .bind::(item_name) .bind::(item_version) .execute(sqlite_conn)? @@ -520,20 +536,20 @@ struct DataResult { async fn get_data_from_table( conn: &mut DbConnection, - table_name: &str, + item_kind: &str, item_name: &str, item_version: &str, item_namespace: Option<&str>, ) -> QueryResult> { let select_query = if let Some(_) = item_namespace { match conn { - DbConnection::Pg(_) => format!("SELECT data FROM {} WHERE name = $1 AND namespace = $2 AND apigroup = $3", table_name), - DbConnection::Sqlite(_) => format!("SELECT data FROM {} WHERE name = ? AND namespace = ? AND apigroup = ?", table_name), + DbConnection::Pg(_) => "SELECT data FROM kine WHERE kind = $1 AND name = $2 AND namespace = $3 AND apigroup = $4".to_string(), + DbConnection::Sqlite(_) => "SELECT data FROM kine WHERE kind = ? AND name = ? AND namespace = ? AND apigroup = ?".to_string(), } } else { match conn { - DbConnection::Pg(_) => format!("SELECT data FROM {} WHERE name = $1 AND apigroup = $2", table_name), - DbConnection::Sqlite(_) => format!("SELECT data FROM {} WHERE name = ? AND apigroup = ?", table_name), + DbConnection::Pg(_) => "SELECT data FROM kine WHERE kind = $1 AND name = $2 AND apigroup = $3".to_string(), + DbConnection::Sqlite(_) => "SELECT data FROM kine WHERE kind = ? AND name = ? AND apigroup = ?".to_string(), } }; @@ -541,6 +557,7 @@ async fn get_data_from_table( DbConnection::Pg(pg_conn) => { if let Some(namespace) = item_namespace { diesel::sql_query(select_query) + .bind::(item_kind) .bind::(item_name) .bind::(namespace) .bind::(item_version) @@ -549,6 +566,7 @@ async fn get_data_from_table( .map(|res| res.map(|data_result| data_result.data)) } else { diesel::sql_query(select_query) + .bind::(item_kind) .bind::(item_name) .bind::(item_version) .get_result::(pg_conn) @@ -559,6 +577,7 @@ async fn get_data_from_table( DbConnection::Sqlite(sqlite_conn) => { if let Some(namespace) = item_namespace { diesel::sql_query(select_query) + .bind::(item_kind) .bind::(item_name) .bind::(namespace) .bind::(item_version) @@ -567,6 +586,7 @@ async fn get_data_from_table( .map(|res| res.map(|data_result| data_result.data)) } else { diesel::sql_query(select_query) + .bind::(item_kind) .bind::(item_name) .bind::(item_version) .get_result::(sqlite_conn) @@ -581,19 +601,19 @@ async fn get_data_from_table( // 辅助函数:从指定表中获取所有符合条件的数据的 `data` 字段 async fn get_all_data_from_table( conn: &mut DbConnection, - table_name: &str, + item_kind: &str, item_version: &str, item_namespace: Option<&str>, ) -> QueryResult> { let select_query = if let Some(_) = item_namespace { match conn { - DbConnection::Pg(_) => format!("SELECT data FROM {} WHERE namespace = $1 AND apigroup = $2", table_name), - DbConnection::Sqlite(_) => format!("SELECT data FROM {} WHERE namespace = ? AND apigroup = ?", table_name), + DbConnection::Pg(_) => "SELECT data FROM kine WHERE kind = $1 AND namespace = $2 AND apigroup = $3".to_string(), + DbConnection::Sqlite(_) => "SELECT data FROM kine WHERE kind = ? AND namespace = ? AND apigroup = ?".to_string(), } } else { match conn { - DbConnection::Pg(_) => format!("SELECT data FROM {} WHERE apigroup = $1", table_name), - DbConnection::Sqlite(_) => format!("SELECT data FROM {} WHERE apigroup = ?", table_name), + DbConnection::Pg(_) => "SELECT data FROM kine WHERE kind = $1 AND apigroup = $2".to_string(), + DbConnection::Sqlite(_) => "SELECT data FROM kine WHERE kind = ? AND apigroup = ?".to_string(), } }; @@ -601,12 +621,14 @@ async fn get_all_data_from_table( DbConnection::Pg(pg_conn) => { if let Some(namespace) = item_namespace { diesel::sql_query(select_query) + .bind::(item_kind) .bind::(namespace) .bind::(item_version) .load::(pg_conn) .map(|results| results.into_iter().map(|res| res.data).collect()) } else { diesel::sql_query(select_query) + .bind::(item_kind) .bind::(item_version) .load::(pg_conn) .map(|results| results.into_iter().map(|res| res.data).collect()) @@ -615,12 +637,14 @@ async fn get_all_data_from_table( DbConnection::Sqlite(sqlite_conn) => { if let Some(namespace) = item_namespace { diesel::sql_query(select_query) + .bind::(item_kind) .bind::(namespace) .bind::(item_version) .load::(sqlite_conn) .map(|results| results.into_iter().map(|res| res.data).collect()) } else { diesel::sql_query(select_query) + .bind::(item_kind) .bind::(item_version) .load::(sqlite_conn) .map(|results| results.into_iter().map(|res| res.data).collect()) @@ -664,14 +688,14 @@ impl Handler for DefaultHandler { //判断是正常的插入函数还是 crd 资源的注册函数 if plural == "crds" { - let table_name = data + let item_kind = data .get("spec") .and_then(|spec| spec.get("names")) .and_then(|names| names.get("plural")) .and_then(|plural| plural.as_str()) .unwrap_or("error"); - let crd_kind = data + let kind_upper = data .get("spec") .and_then(|spec| spec.get("names")) .and_then(|names| names.get("kind")) @@ -679,21 +703,17 @@ impl Handler for DefaultHandler { .unwrap_or("error"); // 调用check_metadata函数 - let metadata_exists = check_metadata(db_connection, table_name, &version,false).await.map_err(ErrorInternalServerError)?; + let metadata_exists = check_metadata(db_connection, item_kind, &version,false).await.map_err(ErrorInternalServerError)?; if metadata_exists { return Ok(HttpResponse::NotFound().json(json!({ "error": "该 crd 资源已存在,无需重复注册" }))); } - create_table_if_not_exists(db_connection, table_name) - .await - .map_err(ErrorInternalServerError)?; - - insert_metadata(db_connection, table_name, &version, false, &data) + insert_metadata(db_connection, item_kind, &version, false, &data) .await .map_err(ErrorInternalServerError)?; - insert_key_value(table_name, crd_kind); + insert_key_value(item_kind, kind_upper); } else { // 调用check_metadata函数 let metadata_exists = check_metadata(db_connection, &plural, &version,false).await.map_err(ErrorInternalServerError)?; @@ -702,6 +722,19 @@ impl Handler for DefaultHandler { return Ok(HttpResponse::NotFound().json(json!({ "error": "该 plural 不存在,请重新注册或检查 plural 版本以及是否需要 namespace" }))); } + // 从 json_data 中提取 metadata.name + let item_name = data + .get("metadata") + .and_then(|metadata| metadata.get("name")) + .and_then(|name| name.as_str()) + .unwrap_or("error"); + + let kine_exists = check_kine(db_connection, &plural, item_name, &version, None).await.map_err(ErrorInternalServerError)?; + + if kine_exists { + return Ok(HttpResponse::InternalServerError().json(json!({ "error": "该资源已存在,请勿重复创建" }))); + } + let mut model_map = HashMap::new(); let kind = get_value(&*plural.clone()).unwrap(); @@ -720,7 +753,7 @@ impl Handler for DefaultHandler { send_request(request_message, nats_cli).await.map_err(ErrorInternalServerError)?; - insert_into_table(db_connection, &plural, &data, &version, None) + insert_into_table(db_connection, &plural, item_name, &data, &version, None) .await .map_err(ErrorInternalServerError)?; } @@ -740,14 +773,14 @@ impl Handler for DefaultHandler { //判断是正常的插入函数还是 crd 资源的注册函数 if plural == "crds" { - let table_name = data + let item_kind = data .get("spec") .and_then(|spec| spec.get("names")) .and_then(|names| names.get("plural")) .and_then(|plural| plural.as_str()) .unwrap_or("error"); - let crd_kind = data + let kind_upper = data .get("spec") .and_then(|spec| spec.get("names")) .and_then(|names| names.get("kind")) @@ -755,22 +788,17 @@ impl Handler for DefaultHandler { .unwrap_or("error"); // 调用check_metadata函数 - let metadata_exists = check_metadata(db_connection, table_name, &version, true).await.map_err(ErrorInternalServerError)?; + let metadata_exists = check_metadata(db_connection, item_kind, &version, true).await.map_err(ErrorInternalServerError)?; if metadata_exists { return Ok(HttpResponse::NotFound().json(json!({ "error": "该 crd 资源已存在,无需重复注册" }))); } - - create_table_if_not_exists(db_connection, table_name) + insert_metadata(db_connection, item_kind, &version, false, &data) .await .map_err(ErrorInternalServerError)?; - insert_metadata(db_connection, table_name, &version, false, &data) - .await - .map_err(ErrorInternalServerError)?; - - insert_key_value(table_name, crd_kind); + insert_key_value(item_kind, kind_upper); } else { // 调用check_metadata函数 let metadata_exists = check_metadata(db_connection, &plural, &version, true).await.map_err(ErrorInternalServerError)?; @@ -779,6 +807,19 @@ impl Handler for DefaultHandler { return Ok(HttpResponse::NotFound().json(json!({ "error": "该 plural 不存在,请重新注册或检查 plural 版本以及是否需要 namespace" }))); } + // 从 json_data 中提取 metadata.name + let item_name = data + .get("metadata") + .and_then(|metadata| metadata.get("name")) + .and_then(|name| name.as_str()) + .unwrap_or("error"); + + let kine_exists = check_kine(db_connection, &plural, item_name, &version, Some(&namespace)).await.map_err(ErrorInternalServerError)?; + + if kine_exists { + return Ok(HttpResponse::InternalServerError().json(json!({ "error": "该资源已存在,请勿重复创建" }))); + } + let mut model_map = HashMap::new(); let kind = get_value(&*plural.clone()).unwrap(); @@ -797,7 +838,7 @@ impl Handler for DefaultHandler { send_request(request_message, nats_cli).await.map_err(ErrorInternalServerError)?; - insert_into_table(db_connection, &plural, &data, &version, Some(&namespace)) + insert_into_table(db_connection, &plural, item_name, &data, &version, Some(&namespace)) .await .map_err(ErrorInternalServerError)?; } @@ -819,14 +860,14 @@ impl Handler for DefaultHandler { //判断是正常的插入函数还是 crd 资源的注册函数 if plural == "crds" { - let table_name = data + let item_kind = data .get("spec") .and_then(|spec| spec.get("names")) .and_then(|names| names.get("plural")) .and_then(|plural| plural.as_str()) .unwrap_or("error"); - let crd_kind = data + let kind_upper = data .get("spec") .and_then(|spec| spec.get("names")) .and_then(|names| names.get("kind")) @@ -834,22 +875,17 @@ impl Handler for DefaultHandler { .unwrap_or("error"); // 调用check_metadata函数 - let metadata_exists = check_metadata(db_connection, table_name, &ver, false).await.map_err(ErrorInternalServerError)?; + let metadata_exists = check_metadata(db_connection, item_kind, &ver, false).await.map_err(ErrorInternalServerError)?; if metadata_exists { return Ok(HttpResponse::NotFound().json(json!({ "error": "该 crd 资源已存在,无需重复注册" }))); } - - create_table_if_not_exists(db_connection, table_name) - .await - .map_err(ErrorInternalServerError)?; - - insert_metadata(db_connection, table_name, &ver, false, &data) + insert_metadata(db_connection, item_kind, &ver, false, &data) .await .map_err(ErrorInternalServerError)?; - insert_key_value(table_name, crd_kind); + insert_key_value(item_kind, kind_upper); } else { // 调用check_metadata函数 let metadata_exists = check_metadata(db_connection, &plural, &ver, false).await.map_err(ErrorInternalServerError)?; @@ -858,6 +894,19 @@ impl Handler for DefaultHandler { return Ok(HttpResponse::NotFound().json(json!({ "error": "该 plural 不存在,请重新注册或检查 plural 版本以及是否需要 namespace" }))); } + // 从 json_data 中提取 metadata.name + let item_name = data + .get("metadata") + .and_then(|metadata| metadata.get("name")) + .and_then(|name| name.as_str()) + .unwrap_or("error"); + + let kine_exists = check_kine(db_connection, &plural, item_name, &ver, None).await.map_err(ErrorInternalServerError)?; + + if kine_exists { + return Ok(HttpResponse::InternalServerError().json(json!({ "error": "该资源已存在,请勿重复创建" }))); + } + let mut model_map = HashMap::new(); let kind = get_value(&*plural.clone()).unwrap(); @@ -876,7 +925,7 @@ impl Handler for DefaultHandler { send_request(request_message, nats_cli).await.map_err(ErrorInternalServerError)?; - insert_into_table(db_connection, &plural, &data, &ver, None) + insert_into_table(db_connection, &plural, item_name, &data, &ver, None) .await .map_err(ErrorInternalServerError)?; } @@ -899,14 +948,14 @@ impl Handler for DefaultHandler { //判断是正常的插入函数还是 crd 资源的注册函数 if plural == "crds" { - let table_name = data + let item_kind = data .get("spec") .and_then(|spec| spec.get("names")) .and_then(|names| names.get("plural")) .and_then(|plural| plural.as_str()) .unwrap_or("error"); - let crd_kind = data + let kind_upper = data .get("spec") .and_then(|spec| spec.get("names")) .and_then(|names| names.get("kind")) @@ -914,22 +963,17 @@ impl Handler for DefaultHandler { .unwrap_or("error"); // 调用 check_metadata 函数 - let metadata_exists = check_metadata(db_connection, table_name, &ver, true).await.map_err(ErrorInternalServerError)?; + let metadata_exists = check_metadata(db_connection, item_kind, &ver, true).await.map_err(ErrorInternalServerError)?; if metadata_exists { return Ok(HttpResponse::NotFound().json(json!({ "error": "该 crd 资源已存在,无需重复注册" }))); } - - create_table_if_not_exists(db_connection, table_name) + insert_metadata(db_connection, item_kind, &ver, false, &data) .await .map_err(ErrorInternalServerError)?; - insert_metadata(db_connection, table_name, &ver, false, &data) - .await - .map_err(ErrorInternalServerError)?; - - insert_key_value(table_name, crd_kind); + insert_key_value(item_kind, kind_upper); } else { // 调用 check_metadata 函数 let metadata_exists = check_metadata(db_connection, &plural, &ver, true).await.map_err(ErrorInternalServerError)?; @@ -938,6 +982,19 @@ impl Handler for DefaultHandler { return Ok(HttpResponse::NotFound().json(json!({ "error": "该 plural 不存在,请重新注册或检查 plural 版本以及是否需要 namespace" }))); } + // 从 json_data 中提取 metadata.name + let item_name = data + .get("metadata") + .and_then(|metadata| metadata.get("name")) + .and_then(|name| name.as_str()) + .unwrap_or("error"); + + let kine_exists = check_kine(db_connection, &plural, item_name, &ver, Some(&namespace)).await.map_err(ErrorInternalServerError)?; + + if kine_exists { + return Ok(HttpResponse::InternalServerError().json(json!({ "error": "该资源已存在,请勿重复创建" }))); + } + let mut model_map = HashMap::new(); let kind = get_value(&*plural.clone()).unwrap(); @@ -956,7 +1013,7 @@ impl Handler for DefaultHandler { send_request(request_message, nats_cli).await.map_err(ErrorInternalServerError)?; - insert_into_table(db_connection, &plural, &data, &ver, Some(&namespace)) + insert_into_table(db_connection, &plural, item_name, &data, &ver, Some(&namespace)) .await .map_err(ErrorInternalServerError)?; } @@ -982,6 +1039,12 @@ impl Handler for DefaultHandler { return Ok(HttpResponse::NotFound().json(json!({ "error": "该 plural 不存在,请检查 plural 版本以及是否需要 namespace" }))); } + let kine_exists = check_kine(db_connection, &plural, &name, &version, None).await.map_err(ErrorInternalServerError)?; + + if !kine_exists { + return Ok(HttpResponse::InternalServerError().json(json!({ "error": "指定数据不存在" }))); + } + let mut model_map = HashMap::new(); let kind = get_value(&*plural.clone()).unwrap(); @@ -1029,6 +1092,12 @@ impl Handler for DefaultHandler { return Ok(HttpResponse::NotFound().json(json!({ "error": "该 plural 不存在,请检查 plural 版本以及是否需要 namespace" }))); } + let kine_exists = check_kine(db_connection, &plural, &name, &version, Some(&namespace)).await.map_err(ErrorInternalServerError)?; + + if !kine_exists { + return Ok(HttpResponse::InternalServerError().json(json!({ "error": "指定数据不存在" }))); + } + let mut model_map = HashMap::new(); let kind = get_value(&*plural.clone()).unwrap(); @@ -1076,6 +1145,12 @@ impl Handler for DefaultHandler { return Ok(HttpResponse::NotFound().json(json!({ "error": "该 plural 不存在,请检查 plural 版本以及是否需要 namespace" }))); } + let kine_exists = check_kine(db_connection, &plural, &name, &ver, None).await.map_err(ErrorInternalServerError)?; + + if !kine_exists { + return Ok(HttpResponse::InternalServerError().json(json!({ "error": "指定数据不存在" }))); + } + let mut model_map = HashMap::new(); let kind = get_value(&*plural.clone()).unwrap(); @@ -1122,6 +1197,12 @@ impl Handler for DefaultHandler { return Ok(HttpResponse::NotFound().json(json!({ "error": "该 plural 不存在,请检查 plural 版本以及是否需要 namespace" }))); } + let kine_exists = check_kine(db_connection, &plural, &name, &ver, Some(&namespace)).await.map_err(ErrorInternalServerError)?; + + if !kine_exists { + return Ok(HttpResponse::InternalServerError().json(json!({ "error": "指定数据不存在" }))); + } + let mut model_map = HashMap::new(); let kind = get_value(&*plural.clone()).unwrap(); @@ -1168,6 +1249,29 @@ impl Handler for DefaultHandler { return Ok(HttpResponse::NotFound().json(json!({ "error": "该 plural 不存在,请检查 plural 版本以及是否需要 namespace" }))); } + let kine_exists = check_kine(db_connection, &plural, &name, &version, None).await.map_err(ErrorInternalServerError)?; + + if !kine_exists { + return Ok(HttpResponse::InternalServerError().json(json!({ "error": "指定数据不存在" }))); + } + + let mut model_map = HashMap::new(); + let kind = get_value(&*plural.clone()).unwrap(); + + model_map.insert("MODEL".to_string(), kind); + + // request消息 + let request_message = Message::new( + "UPDATE".to_string(), + message::NativeEventAction::Other, + Some(model_map), + Some(ApiServerMessage { + content: data.to_string(), + }), + None, + ); + send_request(request_message, nats_cli).await.map_err(ErrorInternalServerError)?; + // 查询 plural 表中是否存在 name 匹配的数据 let updated = update_data_in_table(db_connection, &plural, &name, &version, None, &data) .await @@ -1198,6 +1302,29 @@ impl Handler for DefaultHandler { return Ok(HttpResponse::NotFound().json(json!({ "error": "该 plural 不存在,请检查 plural 版本以及是否需要 namespace" }))); } + let kine_exists = check_kine(db_connection, &plural, &name, &version, Some(&namespace)).await.map_err(ErrorInternalServerError)?; + + if !kine_exists { + return Ok(HttpResponse::InternalServerError().json(json!({ "error": "指定数据不存在" }))); + } + + let mut model_map = HashMap::new(); + let kind = get_value(&*plural.clone()).unwrap(); + + model_map.insert("MODEL".to_string(), kind); + + // request消息 + let request_message = Message::new( + "UPDATE".to_string(), + message::NativeEventAction::Other, + Some(model_map), + Some(ApiServerMessage { + content: data.to_string(), + }), + None, + ); + send_request(request_message, nats_cli).await.map_err(ErrorInternalServerError)?; + let updated = update_data_in_table(db_connection, &plural, &name, &version, Some(&namespace), &data) .await .map_err(ErrorInternalServerError)?; @@ -1228,6 +1355,29 @@ impl Handler for DefaultHandler { return Ok(HttpResponse::NotFound().json(json!({ "error": "该 plural 不存在,请检查 plural 版本以及是否需要 namespace" }))); } + let kine_exists = check_kine(db_connection, &plural, &name, &ver, None).await.map_err(ErrorInternalServerError)?; + + if !kine_exists { + return Ok(HttpResponse::InternalServerError().json(json!({ "error": "指定数据不存在" }))); + } + + let mut model_map = HashMap::new(); + let kind = get_value(&*plural.clone()).unwrap(); + + model_map.insert("MODEL".to_string(), kind); + + // request消息 + let request_message = Message::new( + "UPDATE".to_string(), + message::NativeEventAction::Other, + Some(model_map), + Some(ApiServerMessage { + content: data.to_string(), + }), + None, + ); + send_request(request_message, nats_cli).await.map_err(ErrorInternalServerError)?; + let updated = update_data_in_table(db_connection, &plural, &name, &ver, None, &data) .await .map_err(ErrorInternalServerError)?; @@ -1258,6 +1408,29 @@ impl Handler for DefaultHandler { return Ok(HttpResponse::NotFound().json(json!({ "error": "该 plural 不存在,请检查 plural 版本以及是否需要 namespace" }))); } + let kine_exists = check_kine(db_connection, &plural, &name, &ver, Some(&namespace)).await.map_err(ErrorInternalServerError)?; + + if !kine_exists { + return Ok(HttpResponse::InternalServerError().json(json!({ "error": "指定数据不存在" }))); + } + + let mut model_map = HashMap::new(); + let kind = get_value(&*plural.clone()).unwrap(); + + model_map.insert("MODEL".to_string(), kind); + + // request消息 + let request_message = Message::new( + "UPDATE".to_string(), + message::NativeEventAction::Other, + Some(model_map), + Some(ApiServerMessage { + content: data.to_string(), + }), + None, + ); + send_request(request_message, nats_cli).await.map_err(ErrorInternalServerError)?; + let updated = update_data_in_table(db_connection, &plural, &name, &ver, Some(&namespace), &data) .await .map_err(ErrorInternalServerError)?; @@ -1275,7 +1448,7 @@ impl Handler for DefaultHandler { info: web::Path<(String, String, String)>, _data: web::Query, db_connection: &mut DbConnection, - nats_cli: Arc>, + _nats_cli: Arc>, ) -> Result { let (version, plural, name) = info.into_inner(); let metadata_exists = check_metadata(db_connection, &plural, &version, false) @@ -1304,7 +1477,7 @@ impl Handler for DefaultHandler { info: web::Path<(String, String, String, String)>, _data: web::Query, db_connection: &mut DbConnection, - nats_cli: Arc>, + _nats_cli: Arc>, ) -> Result { let (version, namespace, plural, name) = info.into_inner(); let metadata_exists = check_metadata(db_connection, &plural, &version, true) @@ -1333,7 +1506,7 @@ impl Handler for DefaultHandler { info: web::Path<(String, String, String, String)>, _data: web::Query, db_connection: &mut DbConnection, - nats_cli: Arc>, + _nats_cli: Arc>, ) -> Result { let (group, version, plural, name) = info.into_inner(); let ver = format!("{}/{}", group, version); @@ -1364,7 +1537,7 @@ impl Handler for DefaultHandler { info: web::Path<(String, String, String, String, String)>, _data: web::Query, db_connection: &mut DbConnection, - nats_cli: Arc>, + _nats_cli: Arc>, ) -> Result { let (group, version, namespace, plural, name) = info.into_inner(); let ver = format!("{}/{}", group, version); @@ -1395,7 +1568,7 @@ impl Handler for DefaultHandler { info: web::Path<(String, String)>, _data: web::Query, db_connection: &mut DbConnection, - nats_cli: Arc>, + _nats_cli: Arc>, ) -> Result { let (version, plural) = info.into_inner(); let metadata_exists = check_metadata(db_connection, &plural, &version, false) @@ -1425,7 +1598,7 @@ impl Handler for DefaultHandler { info: web::Path<(String, String, String)>, _data: web::Query, db_connection: &mut DbConnection, - nats_cli: Arc>, + _nats_cli: Arc>, ) -> Result { let (version, namespace, plural) = info.into_inner(); let metadata_exists = check_metadata(db_connection, &plural, &version, true) @@ -1455,7 +1628,7 @@ impl Handler for DefaultHandler { info: web::Path<(String, String, String)>, _data: web::Query, db_connection: &mut DbConnection, - nats_cli: Arc>, + _nats_cli: Arc>, ) -> Result { let (group, version, plural) = info.into_inner(); let ver = format!("{}/{}", group, version); @@ -1487,7 +1660,7 @@ impl Handler for DefaultHandler { info: web::Path<(String, String, String, String)>, _data: web::Query, db_connection: &mut DbConnection, - nats_cli: Arc>, + _nats_cli: Arc>, ) -> Result { let (group, version, namespace, plural) = info.into_inner(); let ver = format!("{}/{}", group, version); diff --git a/src/schema.rs b/src/schema.rs index 29ca975..687d79b 100644 --- a/src/schema.rs +++ b/src/schema.rs @@ -1,7 +1,19 @@ // @generated automatically by Diesel CLI. diesel::table! { - metadata (name) { + kine (kind, name, namespace, apigroup) { + kind -> Nullable, + name -> Nullable, + namespace -> Nullable, + apigroup -> Nullable, + data -> Nullable, + created_time -> Nullable, + updated_time -> Nullable, + } +} + +diesel::table! { + metadata (name, namespace, apigroup) { name -> Nullable, namespace -> Nullable, apigroup -> Nullable, @@ -10,3 +22,8 @@ diesel::table! { updated_time -> Nullable, } } + +diesel::allow_tables_to_appear_in_same_query!( + kine, + metadata, +); -- Gitee From 1c5428537e2952bac664dac84009b19b9de6b67d Mon Sep 17 00:00:00 2001 From: Yuichi <913637919@qq.com> Date: Tue, 26 Nov 2024 08:39:27 +0000 Subject: [PATCH 10/48] =?UTF-8?q?=E6=89=80=E6=9C=89=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=AD=98=E5=82=A8=E5=88=B0kine=E8=A1=A8=E5=86=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- database.sqlite | Bin 0 -> 28672 bytes src/cores/handlers.rs | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 database.sqlite diff --git a/database.sqlite b/database.sqlite new file mode 100644 index 0000000000000000000000000000000000000000..71aa76279a07eb61384b86c18b8cc0f393893d9c GIT binary patch literal 28672 zcmeI)?Qhyf90zbagoi{WG?gN>7f2^-(t<==%+nx!GlwvihLDapUE6804&zZejG663 zo4URT-T$z?-#@dreY@9ty%&46m-`*W4QX+s?!}~}-^0e|yR+}^V<(c&Hiuuf2EN6< zbzGbKtSH@-WLf%*F-el5G{00+UdZ(f34W?_` ztp*dRY;%=SplFXh)H?Mqw9aOsT*>C9$s=xCA<5pDn~U=Jc+hv9dx zJ2zd6`&Q5J2Ma4X9#i@7><69QeXaAD?KK{=P0{=u6Rn+nPaBtGL0huZ&SXD{#nSgS zWQht}KX~5{>DtTS$G$UNH-v_vitqU8Pmy>!laXKUP4#Tc=c4Vwa`}Q{ka{M0DcSbH zL93y)X9htF|5vTcobE2i()CQ3Q_x>S4Pw#LM{+!^Y4YUW)XOk>1Ix39hG#ytY;M?e zMsR=NjJ)uir3cRS?rE z^-E6uCDDWc0SG_<0uX=z1Rwwb2tWV=5P-n75Ll07S1t|-i2MJMWJXHeT-&Av0t6rc z0SG_<0uX=z1Rwx`4^v>GL=qb-nV02e^O@82y4*LP-aS#DEA-6#!`ZXn%9au&D>+5H z1VAbGoi42e&!#I|&y^wXT0@VrobEHr^eI<70Z;3m?+!+NjQ;GjhGj@9Q-JQ-kTTU6f&dH!>xw|{(siD0o zRf_Zp=}oCps;RY8TTXnmvOYO%HcfJL-rb$LDDp;s_-N$#vv&=sNtYk*Hx8cZ*fyV@ zMelL^7I&#!s}_s3MR)z_&{AflP@3NVkEC8nslQXNQh$D!f9B{l1Rwwb2tWV=5P$## zAOHafK;X&=+=|kOl{`OO6-h>Ed`3PSoLNdnX?$ZP7~Bx||LI5n5Fh{n2tWV=5P$## tAOHafKmY;|xW)qF{eN8lU*iLeu0a3-5P$##AOHafKmY;|fB*zY;9v0Y9$x?e literal 0 HcmV?d00001 diff --git a/src/cores/handlers.rs b/src/cores/handlers.rs index 3cf3524..a76d5e0 100644 --- a/src/cores/handlers.rs +++ b/src/cores/handlers.rs @@ -385,7 +385,7 @@ async fn insert_into_table( .execute(pg_conn)?; }, DbConnection::Sqlite(sqlite_conn) => { - let insert_query = "INSERT INTO kine (kind, name, namespace, apigroup, data, created_time, updated_time) VALUES (?, ?, ?, ?, ?, ?)".to_string(); + let insert_query = "INSERT INTO kine (kind, name, namespace, apigroup, data, created_time, updated_time) VALUES (?, ?, ?, ?, ?, ?, ?)".to_string(); diesel::sql_query(insert_query) .bind::(item_kind) .bind::(item_name) -- Gitee From 077be6c88695703b712ceb859418a02d4c435d85 Mon Sep 17 00:00:00 2001 From: Yuichi <913637919@qq.com> Date: Tue, 26 Nov 2024 08:39:47 +0000 Subject: [PATCH 11/48] =?UTF-8?q?=E6=89=80=E6=9C=89=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=AD=98=E5=82=A8=E5=88=B0kine=E8=A1=A8=E5=86=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- database.sqlite | Bin 28672 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 database.sqlite diff --git a/database.sqlite b/database.sqlite deleted file mode 100644 index 71aa76279a07eb61384b86c18b8cc0f393893d9c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 28672 zcmeI)?Qhyf90zbagoi{WG?gN>7f2^-(t<==%+nx!GlwvihLDapUE6804&zZejG663 zo4URT-T$z?-#@dreY@9ty%&46m-`*W4QX+s?!}~}-^0e|yR+}^V<(c&Hiuuf2EN6< zbzGbKtSH@-WLf%*F-el5G{00+UdZ(f34W?_` ztp*dRY;%=SplFXh)H?Mqw9aOsT*>C9$s=xCA<5pDn~U=Jc+hv9dx zJ2zd6`&Q5J2Ma4X9#i@7><69QeXaAD?KK{=P0{=u6Rn+nPaBtGL0huZ&SXD{#nSgS zWQht}KX~5{>DtTS$G$UNH-v_vitqU8Pmy>!laXKUP4#Tc=c4Vwa`}Q{ka{M0DcSbH zL93y)X9htF|5vTcobE2i()CQ3Q_x>S4Pw#LM{+!^Y4YUW)XOk>1Ix39hG#ytY;M?e zMsR=NjJ)uir3cRS?rE z^-E6uCDDWc0SG_<0uX=z1Rwwb2tWV=5P-n75Ll07S1t|-i2MJMWJXHeT-&Av0t6rc z0SG_<0uX=z1Rwx`4^v>GL=qb-nV02e^O@82y4*LP-aS#DEA-6#!`ZXn%9au&D>+5H z1VAbGoi42e&!#I|&y^wXT0@VrobEHr^eI<70Z;3m?+!+NjQ;GjhGj@9Q-JQ-kTTU6f&dH!>xw|{(siD0o zRf_Zp=}oCps;RY8TTXnmvOYO%HcfJL-rb$LDDp;s_-N$#vv&=sNtYk*Hx8cZ*fyV@ zMelL^7I&#!s}_s3MR)z_&{AflP@3NVkEC8nslQXNQh$D!f9B{l1Rwwb2tWV=5P$## zAOHafK;X&=+=|kOl{`OO6-h>Ed`3PSoLNdnX?$ZP7~Bx||LI5n5Fh{n2tWV=5P$## tAOHafKmY;|xW)qF{eN8lU*iLeu0a3-5P$##AOHafKmY;|fB*zY;9v0Y9$x?e -- Gitee From 1149bf5b95dc4cb2dd86e3092d676414918e0c24 Mon Sep 17 00:00:00 2001 From: Yuichi <913637919@qq.com> Date: Tue, 26 Nov 2024 08:48:19 +0000 Subject: [PATCH 12/48] =?UTF-8?q?=E4=BF=AE=E6=94=B9.gitignore?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index ff47c2d..5d594ea 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ Cargo.lock # These are backup files generated by rustfmt **/*.rs.bk +.idea/ \ No newline at end of file -- Gitee From 26d7d97434b8cbaec7ef7aff5750b1f2a7237245 Mon Sep 17 00:00:00 2001 From: Yuichi <913637919@qq.com> Date: Tue, 26 Nov 2024 08:49:42 +0000 Subject: [PATCH 13/48] =?UTF-8?q?=E4=BF=AE=E6=94=B9.gitignore?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 5d594ea..49f8c02 100644 --- a/.gitignore +++ b/.gitignore @@ -2,11 +2,10 @@ # will have compiled files and executables debug/ target/ - +.idea/ # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries # More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html Cargo.lock # These are backup files generated by rustfmt **/*.rs.bk -.idea/ \ No newline at end of file -- Gitee From 92126b6c8e513121440286fc11ae2c9cc6a5b3d2 Mon Sep 17 00:00:00 2001 From: Yuichi <913637919@qq.com> Date: Tue, 26 Nov 2024 08:51:49 +0000 Subject: [PATCH 14/48] =?UTF-8?q?=E4=BF=AE=E6=94=B9.gitignore?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/.gitignore | 8 -------- .idea/apiserver.iml | 11 ----------- .idea/dataSources.xml | 20 -------------------- .idea/modules.xml | 8 -------- .idea/vcs.xml | 6 ------ 5 files changed, 53 deletions(-) delete mode 100644 .idea/.gitignore delete mode 100644 .idea/apiserver.iml delete mode 100644 .idea/dataSources.xml delete mode 100644 .idea/modules.xml delete mode 100644 .idea/vcs.xml diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index 35410ca..0000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -# 默认忽略的文件 -/shelf/ -/workspace.xml -# 基于编辑器的 HTTP 客户端请求 -/httpRequests/ -# Datasource local storage ignored files -/dataSources/ -/dataSources.local.xml diff --git a/.idea/apiserver.iml b/.idea/apiserver.iml deleted file mode 100644 index cf84ae4..0000000 --- a/.idea/apiserver.iml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/dataSources.xml b/.idea/dataSources.xml deleted file mode 100644 index ad76524..0000000 --- a/.idea/dataSources.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - sqlite.xerial - true - org.sqlite.JDBC - jdbc:sqlite:$PROJECT_DIR$/database.sqlite - $ProjectFileDir$ - - - file://$APPLICATION_CONFIG_DIR$/jdbc-drivers/Xerial SQLiteJDBC/3.45.1/org/xerial/sqlite-jdbc/3.45.1.0/sqlite-jdbc-3.45.1.0.jar - - - file://$APPLICATION_CONFIG_DIR$/jdbc-drivers/Xerial SQLiteJDBC/3.45.1/org/slf4j/slf4j-api/1.7.36/slf4j-api-1.7.36.jar - - - - - \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index 3eff730..0000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 35eb1dd..0000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file -- Gitee From 2e28cb092ebb368acd5d559c03468d277f428eac Mon Sep 17 00:00:00 2001 From: Yuichi <913637919@qq.com> Date: Tue, 26 Nov 2024 09:01:06 +0000 Subject: [PATCH 15/48] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dcrd=E9=87=8D=E5=A4=8D?= =?UTF-8?q?=E6=B3=A8=E5=86=8C=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/cores/handlers.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/cores/handlers.rs b/src/cores/handlers.rs index a76d5e0..436fcc5 100644 --- a/src/cores/handlers.rs +++ b/src/cores/handlers.rs @@ -702,6 +702,7 @@ impl Handler for DefaultHandler { .and_then(|kind| kind.as_str()) .unwrap_or("error"); + // 调用check_metadata函数 let metadata_exists = check_metadata(db_connection, item_kind, &version,false).await.map_err(ErrorInternalServerError)?; @@ -794,7 +795,7 @@ impl Handler for DefaultHandler { return Ok(HttpResponse::NotFound().json(json!({ "error": "该 crd 资源已存在,无需重复注册" }))); } - insert_metadata(db_connection, item_kind, &version, false, &data) + insert_metadata(db_connection, item_kind, &version, true, &data) .await .map_err(ErrorInternalServerError)?; @@ -969,7 +970,7 @@ impl Handler for DefaultHandler { return Ok(HttpResponse::NotFound().json(json!({ "error": "该 crd 资源已存在,无需重复注册" }))); } - insert_metadata(db_connection, item_kind, &ver, false, &data) + insert_metadata(db_connection, item_kind, &ver, true, &data) .await .map_err(ErrorInternalServerError)?; -- Gitee From 8c3e99ef3fed521b44053b2d65a8de9185d52093 Mon Sep 17 00:00:00 2001 From: syswu Date: Tue, 26 Nov 2024 21:32:40 +0800 Subject: [PATCH 16/48] =?UTF-8?q?=E6=B7=BB=E5=8A=A0watchall=5Froutes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/cores/config.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/cores/config.rs b/src/cores/config.rs index 17e2a92..16e5786 100644 --- a/src/cores/config.rs +++ b/src/cores/config.rs @@ -103,6 +103,7 @@ pub struct DefaultConfig { update_routes: HashMap, getone_routes: HashMap, listall_routes: HashMap, + watchall_routes: HashMap, } impl DefaultConfig { @@ -162,6 +163,17 @@ impl DefaultConfig { map.insert("/apis/{group}/{version}/namespaces/{namespace}/{plural}".to_string(), APIS_WITH_NAMESPACE.to_string()); map.insert("/apis/{group}/{version}/{plural}".to_string(), APIS_WITHOUT_NAMESPACE.to_string()); map + }, + watchall_routes: { + let mut map: HashMap = HashMap::new(); + // watch some resources: GET + // - with namespace: /api(s)/{group}/{version}/watch/namespaces/{namespace}/{plural} + // - without namespace/api(s)/{group}/{version}/watch/namespaces/{plural} + map.insert("/api/{version}/watch/namespaces/{namespace}/{plural}".to_string(), API_WITH_NAMESPACE.to_string()); + map.insert("/api/{version}/watch/{plural}".to_string(), API_WITHOUT_NAMESPACE.to_string()); + map.insert("/apis/{group}/{version}/watch/namespaces/{namespace}/{plural}".to_string(), APIS_WITH_NAMESPACE.to_string()); + map.insert("/apis/{group}/{version}/watch/{plural}".to_string(), APIS_WITHOUT_NAMESPACE.to_string()); + map } } } -- Gitee From 1638355ce9b8cc9bdf044a0246fc6e6e80ee15d1 Mon Sep 17 00:00:00 2001 From: Yuichi <913637919@qq.com> Date: Wed, 27 Nov 2024 11:37:52 +0800 Subject: [PATCH 17/48] =?UTF-8?q?=E9=80=82=E9=85=8D0.3=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E7=9A=84feventbus?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.lock | 6 +-- Cargo.toml | 4 +- src/cores/apiserver.rs | 7 +-- src/cores/handlers.rs | 97 +++++++++++++++++++++++------------------- 4 files changed, 60 insertions(+), 54 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 616cd06..c48122b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -890,9 +890,9 @@ dependencies = [ [[package]] name = "feventbus" -version = "0.2.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b44fa2d92d2434c95a5da95cca25861a437eb63fc3c164a07ea023481e255d0" +checksum = "81b7cca7940f29e24592a89727028106825660bd8f9aae1d85283008fea92220" dependencies = [ "async-nats", "async-trait", @@ -918,7 +918,7 @@ dependencies = [ [[package]] name = "fleet_apiserver" -version = "0.2.0" +version = "0.3.0" dependencies = [ "actix-http", "actix-service", diff --git a/Cargo.toml b/Cargo.toml index 856e098..22083d1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "fleet_apiserver" -version = "0.2.0" +version = "0.3.0" license = "Apache-2.0" authors = ["wuheng ", "chenhongyu23@otcaix.iscas.ac.cn"] categories = ["api-bindings"] @@ -11,7 +11,7 @@ repository = "https://gitee.com/iscas-system/apiserver" readme = "README.md" [dependencies] -feventbus = "0.2.0" +feventbus = "0.3.0" r2d2 = "0.8.10" dotenv = "0.15.0" diesel = { version = "2.2.0", features = ["sqlite", "postgres", "r2d2"] } diff --git a/src/cores/apiserver.rs b/src/cores/apiserver.rs index 963d751..afaa16a 100644 --- a/src/cores/apiserver.rs +++ b/src/cores/apiserver.rs @@ -15,11 +15,6 @@ pub struct ApiServer config: Arc, } -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct ApiServerMessage { - pub content: String, -} - impl ApiServer { pub fn new (config: Box) -> Self { @@ -35,7 +30,7 @@ impl ApiServer let handler = Arc::new(handler); // 初始化 NatsCli 实例 - let nats_cli: Arc> = Arc::new(NatsCli::new().await.unwrap()); + let nats_cli = Arc::new(NatsCli::new().await.unwrap()); let server = HttpServer::new(move || { diff --git a/src/cores/handlers.rs b/src/cores/handlers.rs index 436fcc5..a79f7c1 100644 --- a/src/cores/handlers.rs +++ b/src/cores/handlers.rs @@ -16,7 +16,6 @@ use feventbus::message::Message; use feventbus::message; use feventbus::traits::producer::Producer; use serde::{Deserialize, Serialize}; -use cores::apiserver::ApiServerMessage; use crate::cores; // 定义全局哈希表来获取model名 @@ -48,7 +47,7 @@ pub trait Handler { info: web::Path<(String, String)>, data: web::Json, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc, ) -> Result; // /api/{version}/namespaces/{namespace}/{plural} @@ -57,7 +56,7 @@ pub trait Handler { info: web::Path<(String, String, String)>, data: web::Json, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc, ) -> Result; // /apis/{group}/{version}/{plural} @@ -66,7 +65,7 @@ pub trait Handler { info: web::Path<(String, String, String)>, data: web::Json, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc, ) -> Result; // /apis/{group}/{version}/namespaces/{namespace}/{plural} @@ -75,7 +74,7 @@ pub trait Handler { info: web::Path<(String, String, String, String)>, data: web::Json, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc, ) -> Result; // /api/{version}/{plural}/{name} @@ -83,7 +82,7 @@ pub trait Handler { &self, info: web::Path<(String, String, String)>, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc, ) -> Result; // /api/{version}/namespaces/{namespace}/{plural}/{name} @@ -91,7 +90,7 @@ pub trait Handler { &self, info: web::Path<(String, String, String, String)>, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc, ) -> Result; // /apis/{group}/{version}/{plural}/{name} @@ -99,7 +98,7 @@ pub trait Handler { &self, info: web::Path<(String, String, String, String)>, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc, ) -> Result; // /apis/{group}/{version}/namespaces/{namespace}/{plural}/{name} @@ -107,7 +106,7 @@ pub trait Handler { &self, info: web::Path<(String, String, String, String, String)>, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc, ) -> Result; // /api/{version}/{plural}/{name} @@ -116,7 +115,7 @@ pub trait Handler { info: web::Path<(String, String, String)>, data: web::Json, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc, ) -> Result; // /api/{version}/namespaces/{namespace}/{plural}/{name} @@ -125,7 +124,7 @@ pub trait Handler { info: web::Path<(String, String, String, String)>, data: web::Json, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc, ) -> Result; // /apis/{group}/{version}/{plural}/{name} @@ -134,7 +133,7 @@ pub trait Handler { info: web::Path<(String, String, String, String)>, data: web::Json, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc, ) -> Result; // /apis/{group}/{version}/namespaces/{namespace}/{plural}/{name} @@ -143,7 +142,7 @@ pub trait Handler { info: web::Path<(String, String, String, String, String)>, data: web::Json, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc, ) -> Result; // /api/{version}/{plural}/{name} @@ -152,7 +151,7 @@ pub trait Handler { info: web::Path<(String, String, String)>, data: web::Query, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc, ) -> Result; // /api/{version}/namespaces/{namespace}/{plural}/{name} @@ -161,7 +160,7 @@ pub trait Handler { info: web::Path<(String, String, String, String)>, data: web::Query, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc, ) -> Result; // /apis/{group}/{version}/{plural}/{name} @@ -170,7 +169,7 @@ pub trait Handler { info: web::Path<(String, String, String, String)>, data: web::Query, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc, ) -> Result; // /apis/{group}/{version}/namespaces/{namespace}/{plural}/{name} @@ -179,7 +178,7 @@ pub trait Handler { info: web::Path<(String, String, String, String, String)>, data: web::Query, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc, ) -> Result; // /api/{version}/{plural} @@ -188,7 +187,7 @@ pub trait Handler { info: web::Path<(String, String)>, data: web::Query, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc, ) -> Result; // /api/{version}/namespaces/{namespace}/{plural} @@ -197,7 +196,7 @@ pub trait Handler { info: web::Path<(String, String, String)>, data: web::Query, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc, ) -> Result; // /apis/{group}/{version}/{plural} @@ -206,7 +205,7 @@ pub trait Handler { info: web::Path<(String, String, String)>, data: web::Query, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc, ) -> Result; // /apis/{group}/{version}/namespaces/{namespace}/{plural} @@ -215,7 +214,7 @@ pub trait Handler { info: web::Path<(String, String, String, String)>, data: web::Query, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc, ) -> Result; // 不满足以上请求路径的处理 @@ -655,7 +654,10 @@ async fn get_all_data_from_table( // 发送请求并等待响应 -async fn send_request(message: Message, nats_cli: Arc>) -> Result<(), Box> +async fn send_request( + message: Message, + nats_cli: Arc, +) -> std::result::Result<(), Box> where T: Serialize + for<'de> Deserialize<'de> + Debug + Clone + Send + Sync + 'static, { @@ -663,7 +665,11 @@ where .request(message, time::Duration::from_secs(100)) .await { - Ok(_) => { + Ok(response) => { + println!( + "===============Received response: {:?}==================", + response + ); Ok(()) } Err(e) => { @@ -673,6 +679,11 @@ where } } +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct ApiServerMessage { + pub content: String, +} + #[async_trait] impl Handler for DefaultHandler { @@ -682,7 +693,7 @@ impl Handler for DefaultHandler { info: web::Path<(String, String)>, data: web::Json, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc, ) -> Result { let (version, plural) = info.into_inner(); @@ -768,7 +779,7 @@ impl Handler for DefaultHandler { info: web::Path<(String, String, String)>, data: web::Json, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc, ) -> Result { let (version, namespace, plural) = info.into_inner(); @@ -853,7 +864,7 @@ impl Handler for DefaultHandler { info: web::Path<(String, String, String)>, data: web::Json, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc, ) -> Result { let (group, version, plural) = info.into_inner(); let ver = group + "/" + &*version; @@ -940,7 +951,7 @@ impl Handler for DefaultHandler { info: web::Path<(String, String, String, String)>, data: web::Json, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc, ) -> Result { let (group, version, namespace, plural) = info.into_inner(); @@ -1027,7 +1038,7 @@ impl Handler for DefaultHandler { &self, info: web::Path<(String, String, String)>, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc, ) -> Result { let (version, plural, name) = info.into_inner(); @@ -1081,7 +1092,7 @@ impl Handler for DefaultHandler { &self, info: web::Path<(String, String, String, String)>, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc, ) -> Result { let (version, namespace, plural, name) = info.into_inner(); // 检查 metadata 中是否存在该 plural 且需要 namespace @@ -1133,7 +1144,7 @@ impl Handler for DefaultHandler { &self, info: web::Path<(String, String, String, String)>, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc, ) -> Result { let (group, version, plural, name) = info.into_inner(); let ver = format!("{}/{}", group, version); @@ -1185,7 +1196,7 @@ impl Handler for DefaultHandler { &self, info: web::Path<(String, String, String, String, String)>, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc, ) -> Result { let (group, version, namespace, plural, name) = info.into_inner(); let ver = format!("{}/{}", group, version); @@ -1238,7 +1249,7 @@ impl Handler for DefaultHandler { info: web::Path<(String, String, String)>, data: web::Json, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc, ) -> Result { let (version, plural, name) = info.into_inner(); @@ -1291,7 +1302,7 @@ impl Handler for DefaultHandler { info: web::Path<(String, String, String, String)>, data: web::Json, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc, ) -> Result { let (version, namespace, plural, name) = info.into_inner(); // 检查 metadata 中是否存在 plural 且要求 namespace @@ -1343,7 +1354,7 @@ impl Handler for DefaultHandler { info: web::Path<(String, String, String, String)>, data: web::Json, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc, ) -> Result { let (group, version, plural, name) = info.into_inner(); let ver = format!("{}/{}", group, version); @@ -1396,7 +1407,7 @@ impl Handler for DefaultHandler { info: web::Path<(String, String, String, String, String)>, data: web::Json, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc, ) -> Result { let (group, version, namespace, plural, name) = info.into_inner(); let ver = format!("{}/{}", group, version); @@ -1449,7 +1460,7 @@ impl Handler for DefaultHandler { info: web::Path<(String, String, String)>, _data: web::Query, db_connection: &mut DbConnection, - _nats_cli: Arc>, + _nats_cli: Arc, ) -> Result { let (version, plural, name) = info.into_inner(); let metadata_exists = check_metadata(db_connection, &plural, &version, false) @@ -1478,7 +1489,7 @@ impl Handler for DefaultHandler { info: web::Path<(String, String, String, String)>, _data: web::Query, db_connection: &mut DbConnection, - _nats_cli: Arc>, + _nats_cli: Arc, ) -> Result { let (version, namespace, plural, name) = info.into_inner(); let metadata_exists = check_metadata(db_connection, &plural, &version, true) @@ -1507,7 +1518,7 @@ impl Handler for DefaultHandler { info: web::Path<(String, String, String, String)>, _data: web::Query, db_connection: &mut DbConnection, - _nats_cli: Arc>, + _nats_cli: Arc, ) -> Result { let (group, version, plural, name) = info.into_inner(); let ver = format!("{}/{}", group, version); @@ -1538,7 +1549,7 @@ impl Handler for DefaultHandler { info: web::Path<(String, String, String, String, String)>, _data: web::Query, db_connection: &mut DbConnection, - _nats_cli: Arc>, + _nats_cli: Arc, ) -> Result { let (group, version, namespace, plural, name) = info.into_inner(); let ver = format!("{}/{}", group, version); @@ -1569,7 +1580,7 @@ impl Handler for DefaultHandler { info: web::Path<(String, String)>, _data: web::Query, db_connection: &mut DbConnection, - _nats_cli: Arc>, + _nats_cli: Arc, ) -> Result { let (version, plural) = info.into_inner(); let metadata_exists = check_metadata(db_connection, &plural, &version, false) @@ -1599,7 +1610,7 @@ impl Handler for DefaultHandler { info: web::Path<(String, String, String)>, _data: web::Query, db_connection: &mut DbConnection, - _nats_cli: Arc>, + _nats_cli: Arc, ) -> Result { let (version, namespace, plural) = info.into_inner(); let metadata_exists = check_metadata(db_connection, &plural, &version, true) @@ -1629,7 +1640,7 @@ impl Handler for DefaultHandler { info: web::Path<(String, String, String)>, _data: web::Query, db_connection: &mut DbConnection, - _nats_cli: Arc>, + _nats_cli: Arc, ) -> Result { let (group, version, plural) = info.into_inner(); let ver = format!("{}/{}", group, version); @@ -1661,7 +1672,7 @@ impl Handler for DefaultHandler { info: web::Path<(String, String, String, String)>, _data: web::Query, db_connection: &mut DbConnection, - _nats_cli: Arc>, + _nats_cli: Arc, ) -> Result { let (group, version, namespace, plural) = info.into_inner(); let ver = format!("{}/{}", group, version); -- Gitee From 9e96ceda454df70d5bf5aa17374cc5b8e6ca9367 Mon Sep 17 00:00:00 2001 From: Yuichi <913637919@qq.com> Date: Wed, 27 Nov 2024 14:24:09 +0800 Subject: [PATCH 18/48] =?UTF-8?q?=E5=88=A0=E9=99=A4envlogger?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.lock | 2 +- Cargo.toml | 2 +- src/cores/apiserver.rs | 1 - src/cores/handlers.rs | 1 - src/lib.rs | 5 +---- 5 files changed, 3 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c48122b..402550e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -918,7 +918,7 @@ dependencies = [ [[package]] name = "fleet_apiserver" -version = "0.3.0" +version = "0.3.1" dependencies = [ "actix-http", "actix-service", diff --git a/Cargo.toml b/Cargo.toml index 22083d1..c9599fe 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "fleet_apiserver" -version = "0.3.0" +version = "0.3.1" license = "Apache-2.0" authors = ["wuheng ", "chenhongyu23@otcaix.iscas.ac.cn"] categories = ["api-bindings"] diff --git a/src/cores/apiserver.rs b/src/cores/apiserver.rs index afaa16a..4cc38c0 100644 --- a/src/cores/apiserver.rs +++ b/src/cores/apiserver.rs @@ -6,7 +6,6 @@ use crate::cores::handlers::{Handler}; use std::sync::{Arc}; use feventbus::impls::nats::nats::NatsCli; use feventbus::traits::controller::EventBus; -use serde::{Deserialize, Serialize}; use crate::cores::db::{DbPool}; pub struct ApiServer diff --git a/src/cores/handlers.rs b/src/cores/handlers.rs index a79f7c1..a5c422d 100644 --- a/src/cores/handlers.rs +++ b/src/cores/handlers.rs @@ -16,7 +16,6 @@ use feventbus::message::Message; use feventbus::message; use feventbus::traits::producer::Producer; use serde::{Deserialize, Serialize}; -use crate::cores; // 定义全局哈希表来获取model名 static GLOBAL_HASHMAP: LazyLock>> = LazyLock::new(|| { diff --git a/src/lib.rs b/src/lib.rs index cdbf155..2f3e95c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,8 +6,6 @@ use cores::config::DefaultConfig; use cores::handlers::DefaultHandler; use cores::db::DbPool; use std::sync::Arc; -use env_logger; - /// 启动 Web 服务器 /// @@ -21,8 +19,7 @@ pub async fn start_server(database_url: &str, address: &str) -> Result<(), Box Date: Wed, 27 Nov 2024 16:00:11 +0800 Subject: [PATCH 19/48] =?UTF-8?q?request=E5=86=85=E5=AE=B9=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E4=B8=BAjson=E6=A0=BC=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.lock | 2 +- Cargo.toml | 2 +- src/cores/handlers.rs | 26 +++++++++++++------------- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 402550e..1f76641 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -918,7 +918,7 @@ dependencies = [ [[package]] name = "fleet_apiserver" -version = "0.3.1" +version = "0.3.2" dependencies = [ "actix-http", "actix-service", diff --git a/Cargo.toml b/Cargo.toml index c9599fe..484aa44 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "fleet_apiserver" -version = "0.3.1" +version = "0.3.2" license = "Apache-2.0" authors = ["wuheng ", "chenhongyu23@otcaix.iscas.ac.cn"] categories = ["api-bindings"] diff --git a/src/cores/handlers.rs b/src/cores/handlers.rs index a5c422d..71441a2 100644 --- a/src/cores/handlers.rs +++ b/src/cores/handlers.rs @@ -680,7 +680,7 @@ where #[derive(Serialize, Deserialize, Debug, Clone)] pub struct ApiServerMessage { - pub content: String, + pub content: Value, } #[async_trait] @@ -757,7 +757,7 @@ impl Handler for DefaultHandler { message::NativeEventAction::Other, Some(model_map), Some(ApiServerMessage { - content: data.to_string(), + content: data.clone(), }), None, ); @@ -842,7 +842,7 @@ impl Handler for DefaultHandler { message::NativeEventAction::Other, Some(model_map), Some(ApiServerMessage { - content: data.to_string(), + content: data.clone(), }), None, ); @@ -929,7 +929,7 @@ impl Handler for DefaultHandler { message::NativeEventAction::Other, Some(model_map), Some(ApiServerMessage { - content: data.to_string(), + content: data.clone(), }), None, ); @@ -1017,7 +1017,7 @@ impl Handler for DefaultHandler { message::NativeEventAction::Other, Some(model_map), Some(ApiServerMessage { - content: data.to_string(), + content: data.clone(), }), None, ); @@ -1067,7 +1067,7 @@ impl Handler for DefaultHandler { message::NativeEventAction::Other, Some(model_map), Some(ApiServerMessage { - content: name.clone(), + content: name.clone().parse()?, }), None, ); @@ -1120,7 +1120,7 @@ impl Handler for DefaultHandler { message::NativeEventAction::Other, Some(model_map), Some(ApiServerMessage { - content: name.clone(), + content: name.clone().parse()?, }), None, ); @@ -1173,7 +1173,7 @@ impl Handler for DefaultHandler { message::NativeEventAction::Other, Some(model_map), Some(ApiServerMessage { - content: name.clone(), + content: name.clone().parse()?, }), None, ); @@ -1225,7 +1225,7 @@ impl Handler for DefaultHandler { message::NativeEventAction::Other, Some(model_map), Some(ApiServerMessage { - content: name.clone(), + content: name.clone().parse()?, }), None, ); @@ -1277,7 +1277,7 @@ impl Handler for DefaultHandler { message::NativeEventAction::Other, Some(model_map), Some(ApiServerMessage { - content: data.to_string(), + content: data.clone(), }), None, ); @@ -1330,7 +1330,7 @@ impl Handler for DefaultHandler { message::NativeEventAction::Other, Some(model_map), Some(ApiServerMessage { - content: data.to_string(), + content: data.clone(), }), None, ); @@ -1383,7 +1383,7 @@ impl Handler for DefaultHandler { message::NativeEventAction::Other, Some(model_map), Some(ApiServerMessage { - content: data.to_string(), + content: data.clone(), }), None, ); @@ -1436,7 +1436,7 @@ impl Handler for DefaultHandler { message::NativeEventAction::Other, Some(model_map), Some(ApiServerMessage { - content: data.to_string(), + content: data.clone(), }), None, ); -- Gitee From c477e8ef362c546179743551baada369f010c5ce Mon Sep 17 00:00:00 2001 From: Yuichi <913637919@qq.com> Date: Wed, 27 Nov 2024 17:36:02 +0800 Subject: [PATCH 20/48] =?UTF-8?q?request=E5=86=85=E5=AE=B9=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E4=B8=BAjson=E6=A0=BC=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.lock | 2 +- Cargo.toml | 2 +- src/cores/handlers.rs | 28 ++++++++++++++++++---------- 3 files changed, 20 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1f76641..c291f84 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -918,7 +918,7 @@ dependencies = [ [[package]] name = "fleet_apiserver" -version = "0.3.2" +version = "0.3.3" dependencies = [ "actix-http", "actix-service", diff --git a/Cargo.toml b/Cargo.toml index 484aa44..91bde44 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "fleet_apiserver" -version = "0.3.2" +version = "0.3.3" license = "Apache-2.0" authors = ["wuheng ", "chenhongyu23@otcaix.iscas.ac.cn"] categories = ["api-bindings"] diff --git a/src/cores/handlers.rs b/src/cores/handlers.rs index 71441a2..8e3d13d 100644 --- a/src/cores/handlers.rs +++ b/src/cores/handlers.rs @@ -695,6 +695,7 @@ impl Handler for DefaultHandler { nats_cli: Arc, ) -> Result { let (version, plural) = info.into_inner(); + let data = data.into_inner(); //判断是正常的插入函数还是 crd 资源的注册函数 if plural == "crds" { @@ -751,6 +752,7 @@ impl Handler for DefaultHandler { model_map.insert("MODEL".to_string(), kind); + // request消息 let request_message = Message::new( "CREATE".to_string(), @@ -769,7 +771,7 @@ impl Handler for DefaultHandler { .map_err(ErrorInternalServerError)?; } - Ok(HttpResponse::Ok().json(data.into_inner())) + Ok(HttpResponse::Ok().json(data)) } // /api/{version}/namespaces/{namespace}/{plural} @@ -781,6 +783,7 @@ impl Handler for DefaultHandler { nats_cli: Arc, ) -> Result { let (version, namespace, plural) = info.into_inner(); + let data = data.into_inner(); //判断是正常的插入函数还是 crd 资源的注册函数 if plural == "crds" { @@ -854,7 +857,7 @@ impl Handler for DefaultHandler { .map_err(ErrorInternalServerError)?; } - Ok(HttpResponse::Ok().json(data.into_inner())) + Ok(HttpResponse::Ok().json(data)) } // /apis/{group}/{version}/{plural} @@ -867,7 +870,7 @@ impl Handler for DefaultHandler { ) -> Result { let (group, version, plural) = info.into_inner(); let ver = group + "/" + &*version; - + let data = data.into_inner(); //判断是正常的插入函数还是 crd 资源的注册函数 if plural == "crds" { @@ -941,7 +944,7 @@ impl Handler for DefaultHandler { .map_err(ErrorInternalServerError)?; } - Ok(HttpResponse::Ok().json(data.into_inner())) + Ok(HttpResponse::Ok().json(data)) } // /apis/{group}/{version}/namespaces/{namespace}/{plural} @@ -955,7 +958,7 @@ impl Handler for DefaultHandler { let (group, version, namespace, plural) = info.into_inner(); let ver = group + "/" + &*version; - + let data = data.into_inner(); //判断是正常的插入函数还是 crd 资源的注册函数 if plural == "crds" { @@ -1029,7 +1032,7 @@ impl Handler for DefaultHandler { .map_err(ErrorInternalServerError)?; } - Ok(HttpResponse::Ok().json(data.into_inner())) + Ok(HttpResponse::Ok().json(data)) } // /api/{version}/{plural}/{name} @@ -1251,6 +1254,7 @@ impl Handler for DefaultHandler { nats_cli: Arc, ) -> Result { let (version, plural, name) = info.into_inner(); + let data = data.into_inner(); let metadata_exists = check_metadata(db_connection, &plural, &version, false) .await @@ -1292,7 +1296,7 @@ impl Handler for DefaultHandler { return Ok(HttpResponse::NotFound().json(json!({ "error": "指定数据不存在" }))); } - Ok(HttpResponse::Ok().json(data.into_inner())) + Ok(HttpResponse::Ok().json(data)) } // /api/{version}/namespaces/{namespace}/{plural}/{name} @@ -1304,6 +1308,8 @@ impl Handler for DefaultHandler { nats_cli: Arc, ) -> Result { let (version, namespace, plural, name) = info.into_inner(); + let data = data.into_inner(); + // 检查 metadata 中是否存在 plural 且要求 namespace let metadata_exists = check_metadata(db_connection, &plural, &version, true) .await @@ -1344,7 +1350,7 @@ impl Handler for DefaultHandler { return Ok(HttpResponse::NotFound().json(json!({ "error": "指定数据不存在" }))); } - Ok(HttpResponse::Ok().json(data.into_inner())) + Ok(HttpResponse::Ok().json(data)) } // /apis/{group}/{version}/{plural}/{name} @@ -1357,6 +1363,7 @@ impl Handler for DefaultHandler { ) -> Result { let (group, version, plural, name) = info.into_inner(); let ver = format!("{}/{}", group, version); + let data = data.into_inner(); let metadata_exists = check_metadata(db_connection, &plural, &ver, false) .await @@ -1397,7 +1404,7 @@ impl Handler for DefaultHandler { return Ok(HttpResponse::NotFound().json(json!({ "error": "指定数据不存在" }))); } - Ok(HttpResponse::Ok().json(data.into_inner())) + Ok(HttpResponse::Ok().json(data)) } // /apis/{group}/{version}/namespaces/{namespace}/{plural}/{name} @@ -1410,6 +1417,7 @@ impl Handler for DefaultHandler { ) -> Result { let (group, version, namespace, plural, name) = info.into_inner(); let ver = format!("{}/{}", group, version); + let data = data.into_inner(); let metadata_exists = check_metadata(db_connection, &plural, &ver, true) .await @@ -1450,7 +1458,7 @@ impl Handler for DefaultHandler { return Ok(HttpResponse::NotFound().json(json!({ "error": "指定数据不存在" }))); } - Ok(HttpResponse::Ok().json(data.into_inner())) + Ok(HttpResponse::Ok().json(data)) } // /api/{version}/{plural}/{name} -- Gitee From 87ad2d42d7f9e72eec9e51b78195803661ec0efc Mon Sep 17 00:00:00 2001 From: Yuichi <913637919@qq.com> Date: Wed, 27 Nov 2024 20:09:06 +0800 Subject: [PATCH 21/48] =?UTF-8?q?=E6=B7=BB=E5=8A=A0watch=E6=A1=86=E6=9E=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/cores/apiserver.rs | 104 +++++++++++++++++++++++++++++++++++++++++ src/cores/config.rs | 4 ++ src/cores/handlers.rs | 44 +++++++++++++++++ 3 files changed, 152 insertions(+) diff --git a/src/cores/apiserver.rs b/src/cores/apiserver.rs index 4cc38c0..c8d2b31 100644 --- a/src/cores/apiserver.rs +++ b/src/cores/apiserver.rs @@ -570,6 +570,110 @@ impl ApiServer } } + for (key, route) in config.watchall_routes() { + if route == API_WITHOUT_NAMESPACE { + let handler = Arc::clone(&handler); + let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + + app = app.route(key, web::get().to( + move |path, data| { + let handler = Arc::clone(&handler); + let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + + async move { + match db_pool.get_connection() { + Ok(mut conn) => { + handler + .default() + .watch_api_without_namespace(path, data, &mut conn, nats_cli) + .await + }, + Err(_) => Err(actix_web::error::ErrorInternalServerError( + "Failed to get database connection", + )), + } + } + })); + } else if route == API_WITH_NAMESPACE { + let handler = Arc::clone(&handler); + let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + + app = app.route(key, web::get().to( + move |path, data| { + let handler = Arc::clone(&handler); + let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + + async move { + match db_pool.get_connection() { + Ok(mut conn) => { + handler + .default() + .watch_api_with_namespace(path, data, &mut conn, nats_cli) + .await + }, + Err(_) => Err(actix_web::error::ErrorInternalServerError( + "Failed to get database connection", + )), + } + } + })); + } else if route == APIS_WITHOUT_NAMESPACE { + let handler = Arc::clone(&handler); + let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + + app = app.route(key, web::get().to( + move |path, data| { + let handler = Arc::clone(&handler); + let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + + async move { + match db_pool.get_connection() { + Ok(mut conn) => { + handler + .default() + .watch_apis_without_namespace(path, data, &mut conn, nats_cli) + .await + }, + Err(_) => Err(actix_web::error::ErrorInternalServerError( + "Failed to get database connection", + )), + } + } + })); + } else if route == APIS_WITH_NAMESPACE { + let handler = Arc::clone(&handler); + let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + + app = app.route(key, web::get().to( + move |path, data| { + let handler = Arc::clone(&handler); + let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + + async move { + match db_pool.get_connection() { + Ok(mut conn) => { + handler + .default() + .watch_apis_with_namespace(path, data, &mut conn, nats_cli) + .await + }, + Err(_) => Err(actix_web::error::ErrorInternalServerError( + "Failed to get database connection", + )), + } + } + })); + } + } + // TODO 与Kubernetes的状态一致 app.default_service(web::to(move || async { Ok::( diff --git a/src/cores/config.rs b/src/cores/config.rs index 16e5786..1ddcf8b 100644 --- a/src/cores/config.rs +++ b/src/cores/config.rs @@ -91,6 +91,8 @@ pub trait Config: Sync + Send { // 获取指定类型(如Pod、Job的所有实例)的URL列表和Web服务器路由的映射关系 fn listall_routes(&self) -> &HashMap; + fn watchall_routes(&self) -> &HashMap; + // TODO WatchOne和WatchAll两个接口 } @@ -200,4 +202,6 @@ impl Config for DefaultConfig { } fn listall_routes(&self) -> &HashMap { &self.listall_routes } + + fn watchall_routes(&self) -> &HashMap { &self.watchall_routes } } diff --git a/src/cores/handlers.rs b/src/cores/handlers.rs index 8e3d13d..45ea7e0 100644 --- a/src/cores/handlers.rs +++ b/src/cores/handlers.rs @@ -216,6 +216,50 @@ pub trait Handler { nats_cli: Arc, ) -> Result; + async fn watch_api_without_namespace( + &self, + info: web::Path<(String, String)>, + data: web::Query, + db_connection: &mut DbConnection, + nats_cli: Arc, + ) -> Result { + // 实现逻辑 + Ok(HttpResponse::Ok().json("watch API without namespace")) + } + + async fn watch_api_with_namespace( + &self, + info: web::Path<(String, String, String)>, + data: web::Query, + db_connection: &mut DbConnection, + nats_cli: Arc, + ) -> Result { + // 实现逻辑 + Ok(HttpResponse::Ok().json("watch API with namespace")) + } + + async fn watch_apis_without_namespace( + &self, + info: web::Path<(String, String, String)>, + data: web::Query, + db_connection: &mut DbConnection, + nats_cli: Arc, + ) -> Result { + // 实现逻辑 + Ok(HttpResponse::Ok().json("watch APIS without namespace")) + } + + async fn watch_apis_with_namespace( + &self, + info: web::Path<(String, String, String, String)>, + data: web::Query, + db_connection: &mut DbConnection, + nats_cli: Arc, + ) -> Result { + // 实现逻辑 + Ok(HttpResponse::Ok().json("watch APIS with namespace")) + } + // 不满足以上请求路径的处理 fn default(&self) -> DefaultHandler; } -- Gitee From 59684dfb4868b7f087936d2b03509449b96efbcd Mon Sep 17 00:00:00 2001 From: Yuichi <913637919@qq.com> Date: Thu, 28 Nov 2024 15:22:35 +0800 Subject: [PATCH 22/48] =?UTF-8?q?=E4=BF=AE=E5=A4=8DUPDATE=20DELETE?= =?UTF-8?q?=E5=90=91Nats=E7=9A=84=E4=BC=A0=E5=80=BC=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.lock | 2 +- Cargo.toml | 2 +- src/cores/handlers.rs | 76 ++++++++++++++++++++++++++++++++++++++----- 3 files changed, 70 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c291f84..c1466fe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -918,7 +918,7 @@ dependencies = [ [[package]] name = "fleet_apiserver" -version = "0.3.3" +version = "0.3.4" dependencies = [ "actix-http", "actix-service", diff --git a/Cargo.toml b/Cargo.toml index 91bde44..d37a6f8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "fleet_apiserver" -version = "0.3.3" +version = "0.3.4" license = "Apache-2.0" authors = ["wuheng ", "chenhongyu23@otcaix.iscas.ac.cn"] categories = ["api-bindings"] diff --git a/src/cores/handlers.rs b/src/cores/handlers.rs index 45ea7e0..7fc4482 100644 --- a/src/cores/handlers.rs +++ b/src/cores/handlers.rs @@ -1108,13 +1108,20 @@ impl Handler for DefaultHandler { model_map.insert("MODEL".to_string(), kind); + let request_data = json!({ + "apiVersion": version.clone(), + "Namespaces": "", + "Plural": plural.clone(), + "Name": name.clone(), + }); + // request消息 let request_message = Message::new( "DELETE".to_string(), message::NativeEventAction::Other, Some(model_map), Some(ApiServerMessage { - content: name.clone().parse()?, + content: request_data, }), None, ); @@ -1161,13 +1168,20 @@ impl Handler for DefaultHandler { model_map.insert("MODEL".to_string(), kind); + let request_data = json!({ + "apiVersion": version.clone(), + "Namespaces": namespace.clone(), + "Plural": plural.clone(), + "Name": name.clone(), + }); + // request消息 let request_message = Message::new( "DELETE".to_string(), message::NativeEventAction::Other, Some(model_map), Some(ApiServerMessage { - content: name.clone().parse()?, + content: request_data, }), None, ); @@ -1214,13 +1228,20 @@ impl Handler for DefaultHandler { model_map.insert("MODEL".to_string(), kind); + let request_data = json!({ + "apiVersion": ver.clone(), + "Namespaces": "", + "Plural": plural.clone(), + "Name": name.clone(), + }); + // request消息 let request_message = Message::new( "DELETE".to_string(), message::NativeEventAction::Other, Some(model_map), Some(ApiServerMessage { - content: name.clone().parse()?, + content: request_data, }), None, ); @@ -1266,13 +1287,20 @@ impl Handler for DefaultHandler { model_map.insert("MODEL".to_string(), kind); + let request_data = json!({ + "apiVersion": ver.clone(), + "Namespaces": namespace.clone(), + "Plural": plural.clone(), + "Name": name.clone(), + }); + // request消息 let request_message = Message::new( "DELETE".to_string(), message::NativeEventAction::Other, Some(model_map), Some(ApiServerMessage { - content: name.clone().parse()?, + content: request_data, }), None, ); @@ -1319,13 +1347,21 @@ impl Handler for DefaultHandler { model_map.insert("MODEL".to_string(), kind); + let request_data = json!({ + "apiVersion": version.clone(), + "Namespaces": "", + "Plural": plural.clone(), + "Name": name.clone(), + "Data": data.clone() + }); + // request消息 let request_message = Message::new( "UPDATE".to_string(), message::NativeEventAction::Other, Some(model_map), Some(ApiServerMessage { - content: data.clone(), + content: request_data, }), None, ); @@ -1374,13 +1410,21 @@ impl Handler for DefaultHandler { model_map.insert("MODEL".to_string(), kind); + let request_data = json!({ + "apiVersion": version.clone(), + "Namespaces": namespace.clone(), + "Plural": plural.clone(), + "Name": name.clone(), + "Data": data.clone() + }); + // request消息 let request_message = Message::new( "UPDATE".to_string(), message::NativeEventAction::Other, Some(model_map), Some(ApiServerMessage { - content: data.clone(), + content: request_data, }), None, ); @@ -1428,13 +1472,21 @@ impl Handler for DefaultHandler { model_map.insert("MODEL".to_string(), kind); + let request_data = json!({ + "apiVersion": ver, + "Namespaces": "", + "Plural": plural.clone(), + "Name": name.clone(), + "Data": data.clone() + }); + // request消息 let request_message = Message::new( "UPDATE".to_string(), message::NativeEventAction::Other, Some(model_map), Some(ApiServerMessage { - content: data.clone(), + content: request_data, }), None, ); @@ -1482,13 +1534,21 @@ impl Handler for DefaultHandler { model_map.insert("MODEL".to_string(), kind); + let request_data = json!({ + "apiVersion": ver, + "Namespaces": namespace.clone(), + "Plural": plural.clone(), + "Name": name.clone(), + "Data": data.clone() + }); + // request消息 let request_message = Message::new( "UPDATE".to_string(), message::NativeEventAction::Other, Some(model_map), Some(ApiServerMessage { - content: data.clone(), + content: request_data, }), None, ); -- Gitee From 0c69fd2dff3d1a852face239592bad7ee6ed23e9 Mon Sep 17 00:00:00 2001 From: Yuichi <913637919@qq.com> Date: Thu, 28 Nov 2024 18:54:13 +0800 Subject: [PATCH 23/48] =?UTF-8?q?=E6=90=AD=E5=BB=BAwatchall=E5=88=9D?= =?UTF-8?q?=E6=AD=A5=E6=A1=86=E6=9E=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.lock | 23 +++++ Cargo.toml | 3 +- database.sqlite | Bin 0 -> 28672 bytes src/cores/apiserver.rs | 94 ++++++----------- src/cores/handlers.rs | 228 ++++++++++++++++++++++++++++++++++++----- 5 files changed, 260 insertions(+), 88 deletions(-) create mode 100644 database.sqlite diff --git a/Cargo.lock b/Cargo.lock index c1466fe..3e5ebe5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -337,6 +337,28 @@ dependencies = [ "webpki-roots", ] +[[package]] +name = "async-stream" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476" +dependencies = [ + "async-stream-impl", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-stream-impl" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "async-trait" version = "0.1.83" @@ -923,6 +945,7 @@ dependencies = [ "actix-http", "actix-service", "actix-web", + "async-stream", "async-trait", "chrono", "diesel", diff --git a/Cargo.toml b/Cargo.toml index d37a6f8..1e81aea 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,4 +29,5 @@ jsonschema = "0.23.0" schemars = "0.8.21" chrono = "0.4.38" once_cell = "1.20.2" -lazy_static = "1.5.0" \ No newline at end of file +lazy_static = "1.5.0" +async-stream = "0.3.6" \ No newline at end of file diff --git a/database.sqlite b/database.sqlite new file mode 100644 index 0000000000000000000000000000000000000000..a1b3c195131e86c810841e69f1bbcaf2ef949911 GIT binary patch literal 28672 zcmeI(OHboQ8~|`TfrKD}mz7Y&0m-#0Es^r@BQLU-hLEN#f!&6%-G^4z#4%YzVyCu~ zE~0w?_B*uqevJJBz3#P#o_gr1hn{-u-%bnxV$k+bE$rWlUo&HS=4U5T=0D!~wx-!C zyJwhPVzUx;kD_VnE0(1wDma(_A;TU?~yg>BO8s0W(v&Y^O>QfgG# zMro~9VVzWVWtN2rHe2k|Qoa05slFm+bMb_mtdp+llWg^fGAWPrw6(q9*bSsx&y}HER#>5|l zLa~R7GzEp#H`ezZ`0pi?zHPYsvZEmj&N6)bV=x?BUZzhsUA?Yq6Q}Opdg_9rmpYQX zk!xFqsoMi6+3FNmU)clMHkkQ587 zz!$S(QOeIkyJ+Sw3O+cY01BW03ZMWApa2S>01BW03ZMWA+zEk&U_5fMOTdZ$2cydr zb8mhPRyd&m3ZMWApa2S>01BW03ZTH}DR9CCXBH#Nr`c+C-)LG*Vk@uH1L25+G4oG{ zW52l~=OuFq&Upy{QXUyi*zv}ubHyXBLz-&Gf-IxCuPQd=IwRm=-?B|jZ*y-GoYhkm zr>L!VdmVV~z}dd;6k~@dhHevhYrupnyoB1BZRb+NG|3@cN$ZmK*rl#q`qf*QCWMAl znT#mrvUzb*+<2Iohv@S0W?&{Zvv9Idt?EWgwXXOKgmal~DDmHEdPb|fv0guCOK?5Y z7-%ik+*m(P^=pkF3i*t{Pi`t?uJWtmahIN1iY%P$RI3U&8rL_c>=e1w9-`}pJ$%;y zs&w=HzI5{xquV9!Q}hw{Z*r4(Nz6!DpY}p#VRcn<;{QSB1I7H!d|>|gJiq4HY7{^L z6hHwKKmim$0Te(16hHwKxOD>er=iD+9`CLSMyH{Fh8}g!1ftW>zY*~|H=Ou?VD3+9 z-i8HED1ZVefC4Ch0w{n2D1ZVea0diVBZ0`$gQbOciWk^*{{bZxVyQ`9Xm^Yz>0BGS zzA@Hpl@)Idlnx(2hdm(q;1uG&8s=7AHBw^hs5Eg{_{%AiB^Bm{op6)gA<(r5w+5ug+ur?PR~X-_GWEG1)Sd1Jz9R4%#WjXu)8E6x1oL zSDu*f@ntb%QYjmtxLRQIJxin91`Ha?bc>W`#oL zG(ul{2pm literal 0 HcmV?d00001 diff --git a/src/cores/apiserver.rs b/src/cores/apiserver.rs index c8d2b31..fc9c06e 100644 --- a/src/cores/apiserver.rs +++ b/src/cores/apiserver.rs @@ -1,7 +1,7 @@ use actix_web::{HttpServer, App, web, HttpResponse}; use crate::cores::config::{Config, APIS_WITHOUT_NAMESPACE, APIS_WITH_NAMESPACE, API_WITHOUT_NAMESPACE, API_WITH_NAMESPACE}; -use crate::cores::handlers::{Handler}; +use crate::cores::handlers::{EventManager, Handler}; use std::sync::{Arc}; use feventbus::impls::nats::nats::NatsCli; @@ -31,6 +31,9 @@ impl ApiServer // 初始化 NatsCli 实例 let nats_cli = Arc::new(NatsCli::new().await.unwrap()); + // 初始化事件管理器 + let event_manager = EventManager::new(); + let server = HttpServer::new(move || { let mut app = App::new(); @@ -38,6 +41,7 @@ impl ApiServer let config = Arc::clone(&self.config); let db_pool = Arc::clone(&db_pool); let nats_cli = Arc::clone(&nats_cli); + let event_manager = event_manager.clone(); // URL是手动注册的,不会存在APIS_WITHOUT_NAMESPACE, APIS_WITH_NAMESPACE, // API_WITHOUT_NAMESPACE, API_WITH_NAMESPACE之外情况 @@ -71,19 +75,21 @@ impl ApiServer let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); let nats_cli = Arc::clone(&nats_cli); + let event_manager = event_manager.clone(); app = app.route(key, web::post().to( move |path, data| { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); let nats_cli = Arc::clone(&nats_cli); + let event_manager = event_manager.clone(); async move { match db_pool.get_connection() { Ok(mut conn) => { handler .default() - .create_api_with_namespace(path, data, &mut conn, nats_cli) + .create_api_with_namespace(path, data, &mut conn, nats_cli, event_manager) .await }, Err(_) => Err(actix_web::error::ErrorInternalServerError( @@ -573,102 +579,66 @@ impl ApiServer for (key, route) in config.watchall_routes() { if route == API_WITHOUT_NAMESPACE { let handler = Arc::clone(&handler); - let db_pool = Arc::clone(&db_pool); - let nats_cli = Arc::clone(&nats_cli); + let event_manager = event_manager.clone(); app = app.route(key, web::get().to( move |path, data| { let handler = Arc::clone(&handler); - let db_pool = Arc::clone(&db_pool); - let nats_cli = Arc::clone(&nats_cli); + let event_manager = event_manager.clone(); async move { - match db_pool.get_connection() { - Ok(mut conn) => { - handler - .default() - .watch_api_without_namespace(path, data, &mut conn, nats_cli) - .await - }, - Err(_) => Err(actix_web::error::ErrorInternalServerError( - "Failed to get database connection", - )), - } + handler + .default() + .watch_api_without_namespace(path, data, event_manager) + .await } })); } else if route == API_WITH_NAMESPACE { let handler = Arc::clone(&handler); - let db_pool = Arc::clone(&db_pool); - let nats_cli = Arc::clone(&nats_cli); + let event_manager = event_manager.clone(); app = app.route(key, web::get().to( move |path, data| { let handler = Arc::clone(&handler); - let db_pool = Arc::clone(&db_pool); - let nats_cli = Arc::clone(&nats_cli); + let event_manager = event_manager.clone(); async move { - match db_pool.get_connection() { - Ok(mut conn) => { - handler - .default() - .watch_api_with_namespace(path, data, &mut conn, nats_cli) - .await - }, - Err(_) => Err(actix_web::error::ErrorInternalServerError( - "Failed to get database connection", - )), - } + handler + .default() + .watch_api_with_namespace(path, data, event_manager) + .await } })); } else if route == APIS_WITHOUT_NAMESPACE { let handler = Arc::clone(&handler); - let db_pool = Arc::clone(&db_pool); - let nats_cli = Arc::clone(&nats_cli); + let event_manager = event_manager.clone(); app = app.route(key, web::get().to( move |path, data| { let handler = Arc::clone(&handler); - let db_pool = Arc::clone(&db_pool); - let nats_cli = Arc::clone(&nats_cli); + let event_manager = event_manager.clone(); async move { - match db_pool.get_connection() { - Ok(mut conn) => { - handler - .default() - .watch_apis_without_namespace(path, data, &mut conn, nats_cli) - .await - }, - Err(_) => Err(actix_web::error::ErrorInternalServerError( - "Failed to get database connection", - )), - } + handler + .default() + .watch_apis_without_namespace(path, data, event_manager) + .await } })); } else if route == APIS_WITH_NAMESPACE { let handler = Arc::clone(&handler); - let db_pool = Arc::clone(&db_pool); - let nats_cli = Arc::clone(&nats_cli); + let event_manager = event_manager.clone(); app = app.route(key, web::get().to( move |path, data| { let handler = Arc::clone(&handler); - let db_pool = Arc::clone(&db_pool); - let nats_cli = Arc::clone(&nats_cli); + let event_manager = event_manager.clone(); async move { - match db_pool.get_connection() { - Ok(mut conn) => { - handler - .default() - .watch_apis_with_namespace(path, data, &mut conn, nats_cli) - .await - }, - Err(_) => Err(actix_web::error::ErrorInternalServerError( - "Failed to get database connection", - )), - } + handler + .default() + .watch_apis_with_namespace(path, data, event_manager) + .await } })); } diff --git a/src/cores/handlers.rs b/src/cores/handlers.rs index 7fc4482..4f002c2 100644 --- a/src/cores/handlers.rs +++ b/src/cores/handlers.rs @@ -3,7 +3,7 @@ use std::fmt::Debug; use std::sync::{Arc, LazyLock, Mutex}; use std::time; use async_trait::async_trait; -use actix_web::{HttpResponse, Result, web}; +use actix_web::{HttpResponse, Result, web, Error}; use chrono::Utc; use diesel::{QueryResult, RunQueryDsl, QueryDsl, ExpressionMethods, OptionalExtension, QueryableByName}; use serde_json::json; @@ -11,11 +11,14 @@ use serde_json::Value; use crate::cores::db::DbConnection; use diesel::sql_types::{Text}; use actix_web::error::ErrorInternalServerError; +use actix_web::web::{Path, Query}; use feventbus::impls::nats::nats::NatsCli; use feventbus::message::Message; use feventbus::message; use feventbus::traits::producer::Producer; use serde::{Deserialize, Serialize}; +use tokio::sync::broadcast; +use actix_web::web::Bytes; // 定义全局哈希表来获取model名 static GLOBAL_HASHMAP: LazyLock>> = LazyLock::new(|| { @@ -56,6 +59,7 @@ pub trait Handler { data: web::Json, db_connection: &mut DbConnection, nats_cli: Arc, + event_manager: EventManager ) -> Result; // /apis/{group}/{version}/{plural} @@ -220,45 +224,29 @@ pub trait Handler { &self, info: web::Path<(String, String)>, data: web::Query, - db_connection: &mut DbConnection, - nats_cli: Arc, - ) -> Result { - // 实现逻辑 - Ok(HttpResponse::Ok().json("watch API without namespace")) - } + event_manager: EventManager + ) -> Result; async fn watch_api_with_namespace( &self, info: web::Path<(String, String, String)>, data: web::Query, - db_connection: &mut DbConnection, - nats_cli: Arc, - ) -> Result { - // 实现逻辑 - Ok(HttpResponse::Ok().json("watch API with namespace")) - } + event_manager: EventManager + ) -> Result; async fn watch_apis_without_namespace( &self, info: web::Path<(String, String, String)>, data: web::Query, - db_connection: &mut DbConnection, - nats_cli: Arc, - ) -> Result { - // 实现逻辑 - Ok(HttpResponse::Ok().json("watch APIS without namespace")) - } + event_manager: EventManager + ) -> Result; async fn watch_apis_with_namespace( &self, info: web::Path<(String, String, String, String)>, data: web::Query, - db_connection: &mut DbConnection, - nats_cli: Arc, - ) -> Result { - // 实现逻辑 - Ok(HttpResponse::Ok().json("watch APIS with namespace")) - } + event_manager: EventManager + ) -> Result; // 不满足以上请求路径的处理 fn default(&self) -> DefaultHandler; @@ -727,6 +715,59 @@ pub struct ApiServerMessage { pub content: Value, } + +// watch的事件类型 +#[derive(Clone, Debug, Serialize)] +pub enum EventType { + Create, + Update, + Delete, +} + +// 事件结构,包含事件类型和相关信息 +#[derive(Clone, Debug, Serialize)] +pub struct Event { + pub event_type: EventType, + pub message: Value +} + +// 事件管理器,管理不同资源类型的事件频道 +#[derive(Clone)] +pub struct EventManager { + // 使用 HashMap 来管理不同资源类型的广播通道 + resource_channels: Arc>>>, +} + +impl EventManager { + pub fn new() -> Self { + EventManager { + resource_channels: Arc::new(Mutex::new(HashMap::new())), + } + } + + // 获取资源类型对应的广播通道 + fn get_channel(&self, resource_type: &str) -> broadcast::Sender { + let mut channels = self.resource_channels.lock().unwrap(); + // 如果不存在该资源类型的通道,创建一个新的 + channels.entry(resource_type.to_string()).or_insert_with(|| { + let (tx, _) = broadcast::channel(100); // 创建一个容量为 100 的广播通道 + tx + }).clone() + } + + // 向指定资源类型广播事件 + pub async fn send_event(&self, resource_type: &str, event_type: EventType, message: Value) { + let channel = self.get_channel(resource_type); + + // 创建一个事件并发送到广播通道 + let event = Event { + event_type, + message, + }; + let _ = channel.send(event); // 发送事件 + } +} + #[async_trait] impl Handler for DefaultHandler { @@ -825,6 +866,7 @@ impl Handler for DefaultHandler { data: web::Json, db_connection: &mut DbConnection, nats_cli: Arc, + event_manager: EventManager, ) -> Result { let (version, namespace, plural) = info.into_inner(); let data = data.into_inner(); @@ -896,6 +938,10 @@ impl Handler for DefaultHandler { send_request(request_message, nats_cli).await.map_err(ErrorInternalServerError)?; + let resource_type = format!("{}/{}/{}", version, namespace, plural); + + event_manager.send_event(&resource_type, EventType::Create, data.clone()).await; + insert_into_table(db_connection, &plural, item_name, &data, &version, Some(&namespace)) .await .map_err(ErrorInternalServerError)?; @@ -1809,6 +1855,138 @@ impl Handler for DefaultHandler { Ok(HttpResponse::Ok().json(json_array)) } + async fn watch_api_without_namespace( + &self, + info: Path<(String, String)>, + _data: Query, + event_manager: EventManager + ) -> Result { + let (version, plural) = info.into_inner(); + let resource_type = format!("{}/{}", version, plural); + + let channel = event_manager.get_channel(&resource_type); + let mut rx = channel.subscribe(); + + let stream = async_stream::stream! { + loop { + match rx.recv().await { + Ok(event) => { + let json_event = serde_json::to_string(&event).unwrap(); + println!("{}", json_event); + yield Ok::(Bytes::from(json_event)); + } + Err(_) => { + yield Err(actix_web::error::ErrorInternalServerError("Error occurred").into()); + } + } + } + }; + + Ok(HttpResponse::Ok() + .content_type("text/event-stream") + .streaming(stream)) + } + + async fn watch_api_with_namespace( + &self, + info: Path<(String, String, String)>, + _data: Query, + event_manager: EventManager + ) -> Result { + let (version, namespace, plural) = info.into_inner(); + let resource_type = format!("{}/{}/{}", version, namespace, plural); + + let channel = event_manager.get_channel(&resource_type); + let mut rx = channel.subscribe(); + + let stream = async_stream::stream! { + loop { + match rx.recv().await { + Ok(event) => { + let json_event = serde_json::to_string(&event).unwrap(); + println!("{}", json_event); + yield Ok::(Bytes::from(json_event)); + } + Err(_) => { + yield Err(actix_web::error::ErrorInternalServerError("Error occurred").into()); + } + } + } + }; + + Ok(HttpResponse::Ok() + .content_type("text/event-stream") + .streaming(stream)) + } + + async fn watch_apis_without_namespace( + &self, + info: Path<(String, String, String)>, + _data: Query, + event_manager: EventManager + ) -> Result { + let (group, version, plural) = info.into_inner(); + let ver = format!("{}/{}", group, version); + let resource_type = format!("{}/{}", ver, plural); + + let channel = event_manager.get_channel(&resource_type); + let mut rx = channel.subscribe(); + + let stream = async_stream::stream! { + loop { + match rx.recv().await { + Ok(event) => { + let json_event = serde_json::to_string(&event).unwrap(); + println!("{}", json_event); + yield Ok::(Bytes::from(json_event)); + } + Err(_) => { + yield Err(actix_web::error::ErrorInternalServerError("Error occurred").into()); + } + } + } + }; + + Ok(HttpResponse::Ok() + .content_type("text/event-stream") + .streaming(stream)) + } + + async fn watch_apis_with_namespace( + &self, + info: Path<(String, String, String, String)>, + _data: Query, + event_manager: EventManager + ) -> Result { + let (group, version, namespace, plural) = info.into_inner(); + let ver = format!("{}/{}", group, version); + + let resource_type = format!("{}/{}/{}", ver, namespace, plural); + + let channel = event_manager.get_channel(&resource_type); + let mut rx = channel.subscribe(); + + let stream = async_stream::stream! { + loop { + match rx.recv().await { + Ok(event) => { + let json_event = serde_json::to_string(&event).unwrap(); + println!("{}", json_event); + yield Ok::(Bytes::from(json_event)); + } + Err(_) => { + yield Err(actix_web::error::ErrorInternalServerError("Error occurred").into()); + } + } + } + }; + + Ok(HttpResponse::Ok() + .content_type("text/event-stream") + .streaming(stream)) + } + + fn default(&self) -> DefaultHandler { DefaultHandler {} } -- Gitee From 9b5a312eca52a382bf4928ba6aaef1e95812976e Mon Sep 17 00:00:00 2001 From: Yuichi <913637919@qq.com> Date: Thu, 21 Nov 2024 09:22:38 +0000 Subject: [PATCH 24/48] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=83=A8=E5=88=86?= =?UTF-8?q?=E5=87=BD=E6=95=B0=E5=AE=9A=E4=B9=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.lock | 625 +++++++++++++++++++++++++++++++++++++++-- Cargo.toml | 1 + src/cores/apiserver.rs | 125 +++++++-- src/cores/handlers.rs | 372 +++++++++++++++++++++--- src/main.rs | 34 +-- 5 files changed, 1041 insertions(+), 116 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b797beb..e127116 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -30,7 +30,7 @@ dependencies = [ "actix-service", "actix-utils", "ahash", - "base64", + "base64 0.22.1", "bitflags", "brotli", "bytes", @@ -308,6 +308,35 @@ version = "1.0.91" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c042108f3ed77fd83760a5fd79b53be043192bb3b9dba91d8c574c0ada7850c8" +[[package]] +name = "async-nats" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23f02c8b692d7eea2cfcdf58b43031b163efd93aa99c01d2a9e796168d37dcf1" +dependencies = [ + "base64-url", + "bytes", + "futures", + "http 0.2.12", + "itoa", + "nkeys", + "nuid", + "once_cell", + "regex", + "rustls-pemfile", + "serde", + "serde_json", + "serde_nanos", + "serde_repr", + "subslice", + "time", + "tokio", + "tokio-rustls", + "tokio-util", + "url", + "webpki-roots", +] + [[package]] name = "async-trait" version = "0.1.83" @@ -340,12 +369,33 @@ dependencies = [ "windows-targets", ] +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + [[package]] name = "base64" version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +[[package]] +name = "base64-url" +version = "1.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67a99c239d0c7e77c85dddfa9cebce48704b3c49550fcd3b84dd637e4484899f" +dependencies = [ + "base64 0.13.1", +] + +[[package]] +name = "base64ct" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6b4d9b1225d28d360ec6a231d65af1fd99a2a095154c8040689617290569c5c" + [[package]] name = "bit-set" version = "0.5.3" @@ -367,6 +417,15 @@ version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array", +] + [[package]] name = "block-buffer" version = "0.10.4" @@ -468,12 +527,40 @@ dependencies = [ "windows-targets", ] +[[package]] +name = "chrono-tz" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29c39203181991a7dd4343b8005bd804e7a9a37afb8ac070e43771e8c820bbde" +dependencies = [ + "chrono", + "chrono-tz-build", + "phf", +] + +[[package]] +name = "chrono-tz-build" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f509c3a87b33437b05e2458750a0700e5bdd6956176773e6c7d6dd15a283a0c" +dependencies = [ + "parse-zoneinfo", + "phf", + "phf_codegen", +] + [[package]] name = "colorchoice" version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" +[[package]] +name = "const-oid" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d6f2aa4d0537bcc1c74df8755072bd31c1ef1a3a1b85a68e8404a8c353b7b8b" + [[package]] name = "convert_case" version = "0.4.0" @@ -525,6 +612,19 @@ dependencies = [ "typenum", ] +[[package]] +name = "curve25519-dalek" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" +dependencies = [ + "byteorder", + "digest 0.9.0", + "rand_core 0.5.1", + "subtle", + "zeroize", +] + [[package]] name = "darling" version = "0.20.10" @@ -560,6 +660,21 @@ dependencies = [ "syn", ] +[[package]] +name = "data-encoding" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2" + +[[package]] +name = "der" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79b71cca7d95d7681a4b3b9cdf63c8dbc3730d0584c2c74e31416d64a90493f4" +dependencies = [ + "const-oid", +] + [[package]] name = "deranged" version = "0.3.11" @@ -567,6 +682,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" dependencies = [ "powerfmt", + "serde", ] [[package]] @@ -631,13 +747,22 @@ dependencies = [ "syn", ] +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + [[package]] name = "digest" version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "block-buffer", + "block-buffer 0.10.4", "crypto-common", ] @@ -678,6 +803,27 @@ version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" +[[package]] +name = "ed25519" +version = "1.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91cff35c70bba8a626e3185d8cd48cc11b5437e1a5bcd15b9b5fa3c64b6dfee7" +dependencies = [ + "signature", +] + +[[package]] +name = "ed25519-dalek" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" +dependencies = [ + "curve25519-dalek", + "ed25519", + "sha2", + "zeroize", +] + [[package]] name = "either" version = "1.13.0" @@ -742,6 +888,24 @@ dependencies = [ "regex-syntax", ] +[[package]] +name = "feventbus" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b44fa2d92d2434c95a5da95cca25861a437eb63fc3c164a07ea023481e255d0" +dependencies = [ + "async-nats", + "async-trait", + "bytes", + "chrono", + "chrono-tz", + "futures", + "serde", + "serde_json", + "thiserror", + "tokio", +] + [[package]] name = "flate2" version = "1.0.34" @@ -788,6 +952,21 @@ dependencies = [ "num", ] +[[package]] +name = "futures" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + [[package]] name = "futures-channel" version = "0.3.31" @@ -804,12 +983,34 @@ version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" +[[package]] +name = "futures-executor" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + [[package]] name = "futures-io" version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" +[[package]] +name = "futures-macro" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "futures-sink" version = "0.3.31" @@ -828,8 +1029,10 @@ version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ + "futures-channel", "futures-core", "futures-io", + "futures-macro", "futures-sink", "futures-task", "memchr", @@ -1232,7 +1435,7 @@ checksum = "bea85509e7320309cc8be62d8badb46f9525157bdc748bf2ec089cd4083a3f7e" dependencies = [ "ahash", "anyhow", - "base64", + "base64 0.22.1", "bytecount", "email_address", "fancy-regex", @@ -1257,7 +1460,7 @@ version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8847402328d8301354c94d605481f25a6bdc1ed65471fd96af8eca71141b13" dependencies = [ - "base64", + "base64 0.22.1", "chrono", "serde", "serde-value", @@ -1277,6 +1480,7 @@ dependencies = [ "diesel_migrations", "dotenv", "env_logger", + "feventbus", "jsonschema", "k8s-openapi", "once_cell", @@ -1409,6 +1613,31 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "nkeys" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e66a7cd1358277b2a6f77078e70aea7315ff2f20db969cc61153103ec162594" +dependencies = [ + "byteorder", + "data-encoding", + "ed25519-dalek", + "getrandom", + "log", + "rand", + "signatory", +] + +[[package]] +name = "nuid" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20c1bb65186718d348306bf1afdeb20d9ab45b2ab80fb793c0fdcf59ffbb4f38" +dependencies = [ + "lazy_static", + "rand", +] + [[package]] name = "num" version = "0.4.3" @@ -1509,6 +1738,12 @@ version = "1.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" +[[package]] +name = "opaque-debug" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" + [[package]] name = "ordered-float" version = "2.10.1" @@ -1547,18 +1782,75 @@ dependencies = [ "windows-targets", ] +[[package]] +name = "parse-zoneinfo" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f2a05b18d44e2957b88f96ba460715e295bc1d7510468a2f3d3b44535d26c24" +dependencies = [ + "regex", +] + [[package]] name = "paste" version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" +[[package]] +name = "pem-rfc7468" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84e93a3b1cc0510b03020f33f21e62acdde3dcaef432edc95bea377fbd4c2cd4" +dependencies = [ + "base64ct", +] + [[package]] name = "percent-encoding" version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +[[package]] +name = "phf" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" +dependencies = [ + "phf_shared", +] + +[[package]] +name = "phf_codegen" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8d39688d359e6b34654d328e262234662d16cc0f60ec8dcbe5e718709342a5a" +dependencies = [ + "phf_generator", + "phf_shared", +] + +[[package]] +name = "phf_generator" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" +dependencies = [ + "phf_shared", + "rand", +] + +[[package]] +name = "phf_shared" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" +dependencies = [ + "siphasher", + "uncased", +] + [[package]] name = "pin-project-lite" version = "0.2.14" @@ -1571,6 +1863,18 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "pkcs8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee3ef9b64d26bad0536099c816c6734379e45bbd5f14798def6809e5cc350447" +dependencies = [ + "der", + "pem-rfc7468", + "spki", + "zeroize", +] + [[package]] name = "pkg-config" version = "0.3.31" @@ -1603,9 +1907,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.87" +version = "1.0.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3e4daa0dcf6feba26f985457cdf104d4b4256fc5a09547140f3631bb076b19a" +checksum = "307e3004becf10f5a6e0d59d20f3cd28231b0e0827a96cd3e0ce6d14bc1e4bb3" dependencies = [ "unicode-ident", ] @@ -1638,7 +1942,7 @@ checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", "rand_chacha", - "rand_core", + "rand_core 0.6.4", ] [[package]] @@ -1648,9 +1952,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core", + "rand_core 0.6.4", ] +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" + [[package]] name = "rand_core" version = "0.6.4" @@ -1743,7 +2053,7 @@ version = "0.12.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a77c62af46e79de0a562e1a9849205ffcb7fc1238876e9bd743357570e04046f" dependencies = [ - "base64", + "base64 0.22.1", "bytes", "futures-channel", "futures-core", @@ -1773,6 +2083,36 @@ dependencies = [ "windows-registry", ] +[[package]] +name = "ring" +version = "0.16.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" +dependencies = [ + "cc", + "libc", + "once_cell", + "spin 0.5.2", + "untrusted 0.7.1", + "web-sys", + "winapi", +] + +[[package]] +name = "ring" +version = "0.17.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" +dependencies = [ + "cc", + "cfg-if", + "getrandom", + "libc", + "spin 0.9.8", + "untrusted 0.9.0", + "windows-sys", +] + [[package]] name = "rustc-demangle" version = "0.1.24" @@ -1788,6 +2128,27 @@ dependencies = [ "semver", ] +[[package]] +name = "rustls" +version = "0.20.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b80e3dec595989ea8510028f30c408a4630db12c9cbb8de34203b89d6577e99" +dependencies = [ + "log", + "ring 0.16.20", + "sct", + "webpki", +] + +[[package]] +name = "rustls-pemfile" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ee86d63972a7c661d1536fefe8c3c8407321c3df668891286de28abcd087360" +dependencies = [ + "base64 0.13.1", +] + [[package]] name = "ryu" version = "1.0.18" @@ -1833,6 +2194,16 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "sct" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" +dependencies = [ + "ring 0.17.8", + "untrusted 0.9.0", +] + [[package]] name = "semver" version = "1.0.23" @@ -1841,9 +2212,9 @@ checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "serde" -version = "1.0.210" +version = "1.0.215" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" +checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f" dependencies = [ "serde_derive", ] @@ -1860,9 +2231,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.210" +version = "1.0.215" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" +checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" dependencies = [ "proc-macro2", "quote", @@ -1882,9 +2253,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.128" +version = "1.0.133" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" +checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377" dependencies = [ "itoa", "memchr", @@ -1892,6 +2263,26 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_nanos" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a93142f0367a4cc53ae0fead1bcda39e85beccfad3dcd717656cacab94b12985" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_repr" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "serde_spanned" version = "0.6.8" @@ -1921,7 +2312,20 @@ checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" dependencies = [ "cfg-if", "cpufeatures", - "digest", + "digest 0.10.7", +] + +[[package]] +name = "sha2" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if", + "cpufeatures", + "digest 0.9.0", + "opaque-debug", ] [[package]] @@ -1939,6 +2343,30 @@ dependencies = [ "libc", ] +[[package]] +name = "signatory" +version = "0.23.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dfecc059e81632eef1dd9b79e22fc28b8fe69b30d3357512a77a0ad8ee3c782" +dependencies = [ + "pkcs8", + "rand_core 0.6.4", + "signature", + "zeroize", +] + +[[package]] +name = "signature" +version = "1.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" + +[[package]] +name = "siphasher" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" + [[package]] name = "slab" version = "0.4.9" @@ -1964,6 +2392,27 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + +[[package]] +name = "spki" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c01a0c15da1b0b0e1494112e7af814a678fec9bd157881b49beac661e9b6f32" +dependencies = [ + "der", +] + [[package]] name = "stable_deref_trait" version = "1.2.0" @@ -1976,11 +2425,26 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" +[[package]] +name = "subslice" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0a8e4809a3bb02de01f1f7faf1ba01a83af9e8eabcd4d31dd6e413d14d56aae" +dependencies = [ + "memchr", +] + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + [[package]] name = "syn" -version = "2.0.79" +version = "2.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" +checksum = "44d46482f1c1c87acd84dea20c1bf5ebff4c757009ed6bf19cfd36fb10e92c4e" dependencies = [ "proc-macro2", "quote", @@ -2007,6 +2471,26 @@ dependencies = [ "syn", ] +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "time" version = "0.3.36" @@ -2077,9 +2561,32 @@ dependencies = [ "pin-project-lite", "signal-hook-registry", "socket2", + "tokio-macros", "windows-sys", ] +[[package]] +name = "tokio-macros" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tokio-rustls" +version = "0.23.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59" +dependencies = [ + "rustls", + "tokio", + "webpki", +] + [[package]] name = "tokio-util" version = "0.7.12" @@ -2165,6 +2672,15 @@ version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" +[[package]] +name = "uncased" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1b88fcfe09e89d3866a5c11019378088af2d24c3fbd4f0543f96b479ec90697" +dependencies = [ + "version_check", +] + [[package]] name = "unicode-bidi" version = "0.3.17" @@ -2186,6 +2702,18 @@ dependencies = [ "tinyvec", ] +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + [[package]] name = "url" version = "2.5.2" @@ -2342,6 +2870,47 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "webpki" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed63aea5ce73d0ff405984102c42de94fc55a6b75765d621c65262469b3c9b53" +dependencies = [ + "ring 0.17.8", + "untrusted 0.9.0", +] + +[[package]] +name = "webpki-roots" +version = "0.22.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c71e40d7d2c34a5106301fb632274ca37242cd0c9d3e64dbece371a40a2d87" +dependencies = [ + "webpki", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + [[package]] name = "windows-core" version = "0.52.0" @@ -2541,6 +3110,26 @@ dependencies = [ "synstructure", ] +[[package]] +name = "zeroize" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "zerovec" version = "0.10.4" diff --git a/Cargo.toml b/Cargo.toml index 0e042eb..c2920a2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,6 +11,7 @@ repository = "https://gitee.com/iscas-system/apiserver" readme = "README.md" [dependencies] +feventbus = "0.2.0" r2d2 = "0.8.10" dotenv = "0.15.0" diesel = { version = "2.2.0", features = ["sqlite", "postgres", "r2d2"] } diff --git a/src/cores/apiserver.rs b/src/cores/apiserver.rs index ea18e79..599f757 100644 --- a/src/cores/apiserver.rs +++ b/src/cores/apiserver.rs @@ -11,6 +11,8 @@ use crate::cores::config::{Config, APIS_WITHOUT_NAMESPACE, APIS_WITH_NAMESPACE, use crate::cores::handlers::{Handler}; use std::sync::{Arc}; +use feventbus::impls::nats::nats::NatsCli; +use feventbus::traits::controller::EventBus; use crate::cores::db::{DbPool}; pub struct ApiServer @@ -33,6 +35,8 @@ impl ApiServer (self: Arc, addr: &str, handler: T, db_pool: Arc) -> Result<(), std::io::Error> { let handler = Arc::new(handler); + // 初始化 NatsCli 实例 + let nats_cli = Arc::new(NatsCli::new().await.unwrap()); let server = HttpServer::new(move || { @@ -40,6 +44,7 @@ impl ApiServer let handler = Arc::clone(&handler); let config = Arc::clone(&self.config); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); // URL是手动注册的,不会存在APIS_WITHOUT_NAMESPACE, APIS_WITH_NAMESPACE, // API_WITHOUT_NAMESPACE, API_WITH_NAMESPACE之外情况 @@ -47,16 +52,20 @@ impl ApiServer if route == API_WITHOUT_NAMESPACE { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + app = app.route(key, web::post().to( move |path, data| { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { Ok(mut conn) => { handler .default() - .create_api_without_namespace(path, data, &mut conn) + .create_api_without_namespace(path, data, &mut conn, nats_cli) .await }, Err(_) => Err(actix_web::error::ErrorInternalServerError( @@ -68,16 +77,20 @@ impl ApiServer } else if route == API_WITH_NAMESPACE { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + app = app.route(key, web::post().to( move |path, data| { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { Ok(mut conn) => { handler .default() - .create_api_with_namespace(path, data, &mut conn) + .create_api_with_namespace(path, data, &mut conn, nats_cli) .await }, Err(_) => Err(actix_web::error::ErrorInternalServerError( @@ -89,16 +102,20 @@ impl ApiServer } else if route == APIS_WITHOUT_NAMESPACE { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + app = app.route(key, web::post().to( move |path, data| { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { Ok(mut conn) => { handler .default() - .create_apis_without_namespace(path, data, &mut conn) + .create_apis_without_namespace(path, data, &mut conn, nats_cli) .await }, Err(_) => Err(actix_web::error::ErrorInternalServerError( @@ -110,16 +127,20 @@ impl ApiServer } else if route == APIS_WITH_NAMESPACE { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + app = app.route(key, web::post().to( move |path, data| { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { Ok(mut conn) => { handler .default() - .create_apis_with_namespace(path, data, &mut conn) + .create_apis_with_namespace(path, data, &mut conn, nats_cli) .await }, Err(_) => Err(actix_web::error::ErrorInternalServerError( @@ -137,16 +158,20 @@ impl ApiServer if route == API_WITHOUT_NAMESPACE { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + app = app.route(key, web::delete().to( move |path| { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { Ok(mut conn) => { handler .default() - .delete_api_without_namespace(path, &mut conn) + .delete_api_without_namespace(path, &mut conn, nats_cli) .await }, Err(_) => Err(actix_web::error::ErrorInternalServerError( @@ -158,16 +183,20 @@ impl ApiServer } else if route == API_WITH_NAMESPACE { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + app = app.route(key, web::delete().to( move |path| { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { Ok(mut conn) => { handler .default() - .delete_api_with_namespace(path, &mut conn) + .delete_api_with_namespace(path, &mut conn, nats_cli) .await }, Err(_) => Err(actix_web::error::ErrorInternalServerError( @@ -179,16 +208,20 @@ impl ApiServer } else if route == APIS_WITHOUT_NAMESPACE { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + app = app.route(key, web::delete().to( move |path| { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { Ok(mut conn) => { handler .default() - .delete_apis_without_namespace(path, &mut conn) + .delete_apis_without_namespace(path, &mut conn, nats_cli) .await }, Err(_) => Err(actix_web::error::ErrorInternalServerError( @@ -200,16 +233,20 @@ impl ApiServer } else if route == APIS_WITH_NAMESPACE { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + app = app.route(key, web::delete().to( move |path| { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { Ok(mut conn) => { handler .default() - .delete_apis_with_namespace(path, &mut conn) + .delete_apis_with_namespace(path, &mut conn, nats_cli) .await }, Err(_) => Err(actix_web::error::ErrorInternalServerError( @@ -227,16 +264,20 @@ impl ApiServer if route == API_WITHOUT_NAMESPACE { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + app = app.route(key, web::put().to( move |path, data| { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { Ok(mut conn) => { handler .default() - .update_api_without_namespace(path, data, &mut conn) + .update_api_without_namespace(path, data, &mut conn, nats_cli) .await }, Err(_) => Err(actix_web::error::ErrorInternalServerError( @@ -248,16 +289,20 @@ impl ApiServer } else if route == API_WITH_NAMESPACE { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + app = app.route(key, web::put().to( move |path, data| { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { Ok(mut conn) => { handler .default() - .update_api_with_namespace(path, data, &mut conn) + .update_api_with_namespace(path, data, &mut conn, nats_cli) .await }, Err(_) => Err(actix_web::error::ErrorInternalServerError( @@ -269,16 +314,20 @@ impl ApiServer } else if route == APIS_WITHOUT_NAMESPACE { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + app = app.route(key, web::put().to( move |path, data| { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { Ok(mut conn) => { handler .default() - .update_apis_without_namespace(path, data, &mut conn) + .update_apis_without_namespace(path, data, &mut conn, nats_cli) .await }, Err(_) => Err(actix_web::error::ErrorInternalServerError( @@ -290,16 +339,20 @@ impl ApiServer } else if route == APIS_WITH_NAMESPACE { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + app = app.route(key, web::put().to( move |path, data| { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { Ok(mut conn) => { handler .default() - .update_apis_with_namespace(path, data, &mut conn) + .update_apis_with_namespace(path, data, &mut conn, nats_cli) .await }, Err(_) => Err(actix_web::error::ErrorInternalServerError( @@ -317,16 +370,20 @@ impl ApiServer if route == API_WITHOUT_NAMESPACE { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + app = app.route(key, web::get().to( move |path, data| { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { Ok(mut conn) => { handler .default() - .getone_api_without_namespace(path, data, &mut conn) + .getone_api_without_namespace(path, data, &mut conn, nats_cli) .await }, Err(_) => Err(actix_web::error::ErrorInternalServerError( @@ -338,16 +395,20 @@ impl ApiServer } else if route == API_WITH_NAMESPACE { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + app = app.route(key, web::get().to( move |path, data| { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { Ok(mut conn) => { handler .default() - .getone_api_with_namespace(path, data, &mut conn) + .getone_api_with_namespace(path, data, &mut conn, nats_cli) .await }, Err(_) => Err(actix_web::error::ErrorInternalServerError( @@ -359,16 +420,20 @@ impl ApiServer } else if route == APIS_WITHOUT_NAMESPACE { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + app = app.route(key, web::get().to( move |path, data| { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { Ok(mut conn) => { handler .default() - .getone_apis_without_namespace(path, data, &mut conn) + .getone_apis_without_namespace(path, data, &mut conn, nats_cli) .await }, Err(_) => Err(actix_web::error::ErrorInternalServerError( @@ -380,16 +445,20 @@ impl ApiServer } else if route == APIS_WITH_NAMESPACE { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + app = app.route(key, web::get().to( move |path, data| { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { Ok(mut conn) => { handler .default() - .getone_apis_with_namespace(path, data, &mut conn) + .getone_apis_with_namespace(path, data, &mut conn, nats_cli) .await }, Err(_) => Err(actix_web::error::ErrorInternalServerError( @@ -408,16 +477,20 @@ impl ApiServer if route == API_WITHOUT_NAMESPACE { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + app = app.route(key, web::get().to( move |path, data| { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { Ok(mut conn) => { handler .default() - .listall_api_without_namespace(path, data, &mut conn) + .listall_api_without_namespace(path, data, &mut conn, nats_cli) .await }, Err(_) => Err(actix_web::error::ErrorInternalServerError( @@ -429,16 +502,20 @@ impl ApiServer } else if route == API_WITH_NAMESPACE { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + app = app.route(key, web::get().to( move |path, data| { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { Ok(mut conn) => { handler .default() - .listall_api_with_namespace(path, data, &mut conn) + .listall_api_with_namespace(path, data, &mut conn, nats_cli) .await }, Err(_) => Err(actix_web::error::ErrorInternalServerError( @@ -450,16 +527,20 @@ impl ApiServer } else if route == APIS_WITHOUT_NAMESPACE { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + app = app.route(key, web::get().to( move |path, data| { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { Ok(mut conn) => { handler .default() - .listall_apis_without_namespace(path, data, &mut conn) + .listall_apis_without_namespace(path, data, &mut conn, nats_cli) .await }, Err(_) => Err(actix_web::error::ErrorInternalServerError( @@ -471,16 +552,20 @@ impl ApiServer } else if route == APIS_WITH_NAMESPACE { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + app = app.route(key, web::get().to( move |path, data| { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { Ok(mut conn) => { handler .default() - .listall_apis_with_namespace(path, data, &mut conn) + .listall_apis_with_namespace(path, data, &mut conn, nats_cli) .await }, Err(_) => Err(actix_web::error::ErrorInternalServerError( diff --git a/src/cores/handlers.rs b/src/cores/handlers.rs index 9e73695..88c7f08 100644 --- a/src/cores/handlers.rs +++ b/src/cores/handlers.rs @@ -1,3 +1,4 @@ +use std::sync::Arc; /** * Copyright (2024, ) Institute of Software, Chinese Academy of Sciences * author: wuheng@iscas.ac.cn @@ -14,68 +15,226 @@ use serde_json::Value; use crate::cores::db::DbConnection; use diesel::sql_types::{Text}; use actix_web::error::ErrorInternalServerError; +use feventbus::impls::nats::nats::NatsCli; +use serde::{Deserialize, Serialize}; #[async_trait] pub trait Handler { // /api/{version}/{plural} - async fn create_api_without_namespace(&self, info: web::Path<(String, String)>, data: web::Json, db_connection: &mut DbConnection) -> Result; + async fn create_api_without_namespace( + &self, + info: web::Path<(String, String)>, + data: web::Json, + db_connection: &mut DbConnection, + nats_cli: Arc>, + ) -> Result + where + T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; // /api/{version}/namespaces/{namespace}/{plural} - async fn create_api_with_namespace(&self, info: web::Path<(String, String, String)>, data: web::Json, db_connection: &mut DbConnection) -> Result; + async fn create_api_with_namespace( + &self, + info: web::Path<(String, String, String)>, + data: web::Json, + db_connection: &mut DbConnection, + nats_cli: Arc>, + ) -> Result + where + T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; // /apis/{group}/{version}/{plural} - async fn create_apis_without_namespace(&self, info: web::Path<(String, String, String)>, data: web::Json, db_connection: &mut DbConnection) -> Result; + async fn create_apis_without_namespace( + &self, + info: web::Path<(String, String, String)>, + data: web::Json, + db_connection: &mut DbConnection, + nats_cli: Arc>, + ) -> Result + where + T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; // /apis/{group}/{version}/namespaces/{namespace}/{plural} - async fn create_apis_with_namespace(&self, info: web::Path<(String, String, String, String)>, data: web::Json, db_connection: &mut DbConnection) -> Result; + async fn create_apis_with_namespace( + &self, + info: web::Path<(String, String, String, String)>, + data: web::Json, + db_connection: &mut DbConnection, + nats_cli: Arc>, + ) -> Result + where + T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; // /api/{version}/{plural}/{name} - async fn delete_api_without_namespace(&self, info: web::Path<(String, String, String)>, db_connection: &mut DbConnection) -> Result; + async fn delete_api_without_namespace( + &self, + info: web::Path<(String, String, String)>, + db_connection: &mut DbConnection, + nats_cli: Arc>, + ) -> Result + where + T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; // /api/{version}/namespaces/{namespace}/{plural}/{name} - async fn delete_api_with_namespace(&self, info: web::Path<(String, String, String, String)>, db_connection: &mut DbConnection) -> Result; + async fn delete_api_with_namespace( + &self, + info: web::Path<(String, String, String, String)>, + db_connection: &mut DbConnection, + nats_cli: Arc>, + ) -> Result + where + T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; // /apis/{group}/{version}/{plural}/{name} - async fn delete_apis_without_namespace(&self, info: web::Path<(String, String, String, String)>, db_connection: &mut DbConnection) -> Result; + async fn delete_apis_without_namespace( + &self, + info: web::Path<(String, String, String, String)>, + db_connection: &mut DbConnection, + nats_cli: Arc>, + ) -> Result + where + T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; // /apis/{group}/{version}/namespaces/{namespace}/{plural}/{name} - async fn delete_apis_with_namespace(&self, info: web::Path<(String, String, String, String, String)>, db_connection: &mut DbConnection) -> Result; + async fn delete_apis_with_namespace( + &self, + info: web::Path<(String, String, String, String, String)>, + db_connection: &mut DbConnection, + nats_cli: Arc>, + ) -> Result + where + T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; // /api/{version}/{plural}/{name} - async fn update_api_without_namespace(&self, info: web::Path<(String, String, String)>, data: web::Json, db_connection: &mut DbConnection) -> Result; + async fn update_api_without_namespace( + &self, + info: web::Path<(String, String, String)>, + data: web::Json, + db_connection: &mut DbConnection, + nats_cli: Arc>, + ) -> Result + where + T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; // /api/{version}/namespaces/{namespace}/{plural}/{name} - async fn update_api_with_namespace(&self, info: web::Path<(String, String, String, String)>, data: web::Json, db_connection: &mut DbConnection) -> Result; + async fn update_api_with_namespace( + &self, + info: web::Path<(String, String, String, String)>, + data: web::Json, + db_connection: &mut DbConnection, + nats_cli: Arc>, + ) -> Result + where + T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; // /apis/{group}/{version}/{plural}/{name} - async fn update_apis_without_namespace(&self, info: web::Path<(String, String, String, String)>, data: web::Json, db_connection: &mut DbConnection) -> Result; + async fn update_apis_without_namespace( + &self, + info: web::Path<(String, String, String, String)>, + data: web::Json, + db_connection: &mut DbConnection, + nats_cli: Arc>, + ) -> Result + where + T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; // /apis/{group}/{version}/namespaces/{namespace}/{plural}/{name} - async fn update_apis_with_namespace(&self, info: web::Path<(String, String, String, String, String)>, data: web::Json, db_connection: &mut DbConnection) -> Result; + async fn update_apis_with_namespace( + &self, + info: web::Path<(String, String, String, String, String)>, + data: web::Json, + db_connection: &mut DbConnection, + nats_cli: Arc>, + ) -> Result + where + T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; // /api/{version}/{plural}/{name} - async fn getone_api_without_namespace(&self, info: web::Path<(String, String, String)>, data: web::Query, db_connection: &mut DbConnection) -> Result; + async fn getone_api_without_namespace( + &self, + info: web::Path<(String, String, String)>, + data: web::Query, + db_connection: &mut DbConnection, + nats_cli: Arc>, + ) -> Result + where + T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; // /api/{version}/namespaces/{namespace}/{plural}/{name} - async fn getone_api_with_namespace(&self, info: web::Path<(String, String, String, String)>, data: web::Query, db_connection: &mut DbConnection) -> Result; + async fn getone_api_with_namespace( + &self, + info: web::Path<(String, String, String, String)>, + data: web::Query, + db_connection: &mut DbConnection, + nats_cli: Arc>, + ) -> Result + where + T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; // /apis/{group}/{version}/{plural}/{name} - async fn getone_apis_without_namespace(&self, info: web::Path<(String, String, String, String)>, data: web::Query, db_connection: &mut DbConnection) -> Result; + async fn getone_apis_without_namespace( + &self, + info: web::Path<(String, String, String, String)>, + data: web::Query, + db_connection: &mut DbConnection, + nats_cli: Arc>, + ) -> Result + where + T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; // /apis/{group}/{version}/namespaces/{namespace}/{plural}/{name} - async fn getone_apis_with_namespace(&self, info: web::Path<(String, String, String, String, String)>, data: web::Query, db_connection: &mut DbConnection) -> Result; + async fn getone_apis_with_namespace( + &self, + info: web::Path<(String, String, String, String, String)>, + data: web::Query, + db_connection: &mut DbConnection, + nats_cli: Arc>, + ) -> Result + where + T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; // /api/{version}/{plural} - async fn listall_api_without_namespace(&self, info: web::Path<(String, String)>, data: web::Query, db_connection: &mut DbConnection) -> Result; + async fn listall_api_without_namespace( + &self, + info: web::Path<(String, String)>, + data: web::Query, + db_connection: &mut DbConnection, + nats_cli: Arc>, + ) -> Result + where + T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; // /api/{version}/namespaces/{namespace}/{plural} - async fn listall_api_with_namespace(&self, info: web::Path<(String, String, String)>, data: web::Query, db_connection: &mut DbConnection) -> Result; + async fn listall_api_with_namespace( + &self, + info: web::Path<(String, String, String)>, + data: web::Query, + db_connection: &mut DbConnection, + nats_cli: Arc>, + ) -> Result + where + T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; // /apis/{group}/{version}/{plural} - async fn listall_apis_without_namespace(&self, info: web::Path<(String, String, String)>, data: web::Query, db_connection: &mut DbConnection) -> Result; + async fn listall_apis_without_namespace( + &self, + info: web::Path<(String, String, String)>, + data: web::Query, + db_connection: &mut DbConnection, + nats_cli: Arc>, + ) -> Result + where + T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; // /apis/{group}/{version}/namespaces/{namespace}/{plural} - async fn listall_apis_with_namespace(&self, info: web::Path<(String, String, String, String)>, data: web::Query, db_connection: &mut DbConnection) -> Result; + async fn listall_apis_with_namespace( + &self, + info: web::Path<(String, String, String, String)>, + data: web::Query, + db_connection: &mut DbConnection, + nats_cli: Arc>, + ) -> Result + where + T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; // 不满足以上请求路径的处理 fn default(&self) -> DefaultHandler; @@ -492,11 +651,12 @@ async fn get_all_data_from_table( impl Handler for DefaultHandler { // /api/{version}/{plural} - async fn create_api_without_namespace( + async fn create_api_without_namespace( &self, info: web::Path<(String, String)>, data: web::Json, db_connection: &mut DbConnection, + nats_cli: Arc>, ) -> Result { let (version, plural) = info.into_inner(); @@ -541,7 +701,13 @@ impl Handler for DefaultHandler { } // /api/{version}/namespaces/{namespace}/{plural} - async fn create_api_with_namespace(&self, info: web::Path<(String, String, String)>, data: web::Json, db_connection: &mut DbConnection) -> Result { + async fn create_api_with_namespace( + &self, + info: web::Path<(String, String, String)>, + data: web::Json, + db_connection: &mut DbConnection, + nats_cli: Arc>, + ) -> Result { let (version, namespace, plural) = info.into_inner(); //判断是正常的插入函数还是 crd 资源的注册函数 @@ -585,7 +751,13 @@ impl Handler for DefaultHandler { } // /apis/{group}/{version}/{plural} - async fn create_apis_without_namespace(&self, info: web::Path<(String, String, String)>, data: web::Json, db_connection: &mut DbConnection) -> Result { + async fn create_apis_without_namespace( + &self, + info: web::Path<(String, String, String)>, + data: web::Json, + db_connection: &mut DbConnection, + nats_cli: Arc>, + ) -> Result { let (group, version, plural) = info.into_inner(); let ver = group + "/" + &*version; @@ -631,7 +803,13 @@ impl Handler for DefaultHandler { } // /apis/{group}/{version}/namespaces/{namespace}/{plural} - async fn create_apis_with_namespace(&self, info: web::Path<(String, String, String, String)>, data: web::Json, db_connection: &mut DbConnection) -> Result { + async fn create_apis_with_namespace( + &self, + info: web::Path<(String, String, String, String)>, + data: web::Json, + db_connection: &mut DbConnection, + nats_cli: Arc>, + ) -> Result { let (group, version, namespace, plural) = info.into_inner(); let ver = group + "/" + &*version; @@ -678,7 +856,12 @@ impl Handler for DefaultHandler { } // /api/{version}/{plural}/{name} - async fn delete_api_without_namespace(&self, info: web::Path<(String, String, String)>, db_connection: &mut DbConnection) -> Result { + async fn delete_api_without_namespace( + &self, + info: web::Path<(String, String, String)>, + db_connection: &mut DbConnection, + nats_cli: Arc>, + ) -> Result { let (version, plural, name) = info.into_inner(); // 检查 metadata 中是否存在该 plural 且不需要 namespace @@ -703,7 +886,12 @@ impl Handler for DefaultHandler { } // /api/{version}/namespaces/{namespace}/{plural}/{name} - async fn delete_api_with_namespace(&self, info: web::Path<(String, String, String, String)>, db_connection: &mut DbConnection) -> Result { + async fn delete_api_with_namespace( + &self, + info: web::Path<(String, String, String, String)>, + db_connection: &mut DbConnection, + nats_cli: Arc>, + ) -> Result { let (version, namespace, plural, name) = info.into_inner(); // 检查 metadata 中是否存在该 plural 且需要 namespace let metadata_exists = check_metadata(db_connection, &plural, &version, true) @@ -727,7 +915,12 @@ impl Handler for DefaultHandler { } // /apis/{group}/{version}/{plural}/{name} - async fn delete_apis_without_namespace(&self, info: web::Path<(String, String, String, String)>, db_connection: &mut DbConnection) -> Result { + async fn delete_apis_without_namespace( + &self, + info: web::Path<(String, String, String, String)>, + db_connection: &mut DbConnection, + nats_cli: Arc>, + ) -> Result { let (group, version, plural, name) = info.into_inner(); let ver = format!("{}/{}", group, version); @@ -751,7 +944,12 @@ impl Handler for DefaultHandler { } // /apis/{group}/{version}/namespaces/{namespace}/{plural}/{name} - async fn delete_apis_with_namespace(&self, info: web::Path<(String, String, String, String, String)>, db_connection: &mut DbConnection) -> Result { + async fn delete_apis_with_namespace( + &self, + info: web::Path<(String, String, String, String, String)>, + db_connection: &mut DbConnection, + nats_cli: Arc>, + ) -> Result { let (group, version, namespace, plural, name) = info.into_inner(); let ver = format!("{}/{}", group, version); @@ -775,7 +973,13 @@ impl Handler for DefaultHandler { } // /api/{version}/{plural}/{name} - async fn update_api_without_namespace(&self, info: web::Path<(String, String, String)>, data: web::Json, db_connection: &mut DbConnection) -> Result { + async fn update_api_without_namespace( + &self, + info: web::Path<(String, String, String)>, + data: web::Json, + db_connection: &mut DbConnection, + nats_cli: Arc>, + ) -> Result { let (version, plural, name) = info.into_inner(); let metadata_exists = check_metadata(db_connection, &plural, &version, false) @@ -799,7 +1003,13 @@ impl Handler for DefaultHandler { } // /api/{version}/namespaces/{namespace}/{plural}/{name} - async fn update_api_with_namespace(&self, info: web::Path<(String, String, String, String)>, data: web::Json, db_connection: &mut DbConnection) -> Result { + async fn update_api_with_namespace( + &self, + info: web::Path<(String, String, String, String)>, + data: web::Json, + db_connection: &mut DbConnection, + nats_cli: Arc>, + ) -> Result { let (version, namespace, plural, name) = info.into_inner(); // 检查 metadata 中是否存在 plural 且要求 namespace let metadata_exists = check_metadata(db_connection, &plural, &version, true) @@ -822,7 +1032,13 @@ impl Handler for DefaultHandler { } // /apis/{group}/{version}/{plural}/{name} - async fn update_apis_without_namespace(&self, info: web::Path<(String, String, String, String)>, data: web::Json, db_connection: &mut DbConnection) -> Result { + async fn update_apis_without_namespace( + &self, + info: web::Path<(String, String, String, String)>, + data: web::Json, + db_connection: &mut DbConnection, + nats_cli: Arc>, + ) -> Result { let (group, version, plural, name) = info.into_inner(); let ver = format!("{}/{}", group, version); @@ -846,7 +1062,13 @@ impl Handler for DefaultHandler { } // /apis/{group}/{version}/namespaces/{namespace}/{plural}/{name} - async fn update_apis_with_namespace(&self, info: web::Path<(String, String, String, String, String)>, data: web::Json, db_connection: &mut DbConnection) -> Result { + async fn update_apis_with_namespace( + &self, + info: web::Path<(String, String, String, String, String)>, + data: web::Json, + db_connection: &mut DbConnection, + nats_cli: Arc>, + ) -> Result { let (group, version, namespace, plural, name) = info.into_inner(); let ver = format!("{}/{}", group, version); @@ -870,7 +1092,13 @@ impl Handler for DefaultHandler { } // /api/{version}/{plural}/{name} - async fn getone_api_without_namespace(&self, info: web::Path<(String, String, String)>, _data: web::Query, db_connection: &mut DbConnection) -> Result { + async fn getone_api_without_namespace( + &self, + info: web::Path<(String, String, String)>, + _data: web::Query, + db_connection: &mut DbConnection, + nats_cli: Arc>, + ) -> Result { let (version, plural, name) = info.into_inner(); let metadata_exists = check_metadata(db_connection, &plural, &version, false) .await @@ -893,7 +1121,13 @@ impl Handler for DefaultHandler { } // /api/{version}/namespaces/{namespace}/{plural}/{name} - async fn getone_api_with_namespace(&self, info: web::Path<(String, String, String, String)>, _data: web::Query, db_connection: &mut DbConnection) -> Result { + async fn getone_api_with_namespace( + &self, + info: web::Path<(String, String, String, String)>, + _data: web::Query, + db_connection: &mut DbConnection, + nats_cli: Arc>, + ) -> Result { let (version, namespace, plural, name) = info.into_inner(); let metadata_exists = check_metadata(db_connection, &plural, &version, true) .await @@ -916,7 +1150,13 @@ impl Handler for DefaultHandler { } // /apis/{group}/{version}/{plural}/{name} - async fn getone_apis_without_namespace(&self, info: web::Path<(String, String, String, String)>, _data: web::Query, db_connection: &mut DbConnection) -> Result { + async fn getone_apis_without_namespace( + &self, + info: web::Path<(String, String, String, String)>, + _data: web::Query, + db_connection: &mut DbConnection, + nats_cli: Arc>, + ) -> Result { let (group, version, plural, name) = info.into_inner(); let ver = format!("{}/{}", group, version); @@ -941,7 +1181,13 @@ impl Handler for DefaultHandler { } // /apis/{group}/{version}/namespaces/{namespace}/{plural}/{name} - async fn getone_apis_with_namespace(&self, info: web::Path<(String, String, String, String, String)>, _data: web::Query, db_connection: &mut DbConnection) -> Result { + async fn getone_apis_with_namespace( + &self, + info: web::Path<(String, String, String, String, String)>, + _data: web::Query, + db_connection: &mut DbConnection, + nats_cli: Arc>, + ) -> Result { let (group, version, namespace, plural, name) = info.into_inner(); let ver = format!("{}/{}", group, version); @@ -966,7 +1212,13 @@ impl Handler for DefaultHandler { } // /api/{version}/{plural} - async fn listall_api_without_namespace(&self, info: web::Path<(String, String)>, _data: web::Query, db_connection: &mut DbConnection) -> Result { + async fn listall_api_without_namespace( + &self, + info: web::Path<(String, String)>, + _data: web::Query, + db_connection: &mut DbConnection, + nats_cli: Arc>, + ) -> Result { let (version, plural) = info.into_inner(); let metadata_exists = check_metadata(db_connection, &plural, &version, false) .await @@ -990,7 +1242,13 @@ impl Handler for DefaultHandler { } // /api/{version}/namespaces/{namespace}/{plural} - async fn listall_api_with_namespace(&self, info: web::Path<(String, String, String)>, _data: web::Query, db_connection: &mut DbConnection) -> Result { + async fn listall_api_with_namespace( + &self, + info: web::Path<(String, String, String)>, + _data: web::Query, + db_connection: &mut DbConnection, + nats_cli: Arc>, + ) -> Result { let (version, namespace, plural) = info.into_inner(); let metadata_exists = check_metadata(db_connection, &plural, &version, true) .await @@ -1014,7 +1272,13 @@ impl Handler for DefaultHandler { } // /apis/{group}/{version}/{plural} - async fn listall_apis_without_namespace(&self, info: web::Path<(String, String, String)>, _data: web::Query, db_connection: &mut DbConnection) -> Result { + async fn listall_apis_without_namespace( + &self, + info: web::Path<(String, String, String)>, + _data: web::Query, + db_connection: &mut DbConnection, + nats_cli: Arc>, + ) -> Result { let (group, version, plural) = info.into_inner(); let ver = format!("{}/{}", group, version); @@ -1040,7 +1304,13 @@ impl Handler for DefaultHandler { } // /apis/{group}/{version}/namespaces/{namespace}/{plural} - async fn listall_apis_with_namespace(&self, info: web::Path<(String, String, String, String)>, _data: web::Query, db_connection: &mut DbConnection) -> Result { + async fn listall_apis_with_namespace( + &self, + info: web::Path<(String, String, String, String)>, + _data: web::Query, + db_connection: &mut DbConnection, + nats_cli: Arc>, + ) -> Result { let (group, version, namespace, plural) = info.into_inner(); let ver = format!("{}/{}", group, version); @@ -1077,6 +1347,7 @@ mod tests { use serde_json::json; use crate::cores::db::DbPool; use std::sync::Arc; + use feventbus::traits::controller::EventBus; use once_cell::sync::Lazy; // 使用 Lazy 来初始化静态的共享资源 @@ -1090,6 +1361,7 @@ mod tests { #[actix_web::test] async fn test_api_with_namespace() { + let nats_cli = Arc::new(NatsCli::new().await.unwrap()); let app = test::init_service( App::new() @@ -1097,9 +1369,11 @@ mod tests { move |path, data| { let handler = HANDLER.clone(); let db_pool = DB_POOL.clone(); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { - Ok(mut conn) => handler.create_api_with_namespace(path, data, &mut conn).await, + Ok(mut conn) => handler.create_api_with_namespace(path, data, &mut conn, nats_cli).await, Err(_) => Err(ErrorInternalServerError("Failed to get database connection")), } } @@ -1109,9 +1383,11 @@ mod tests { move |path, data| { let handler = HANDLER.clone(); let db_pool = DB_POOL.clone(); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { - Ok(mut conn) => handler.update_api_with_namespace(path, data, &mut conn).await, + Ok(mut conn) => handler.update_api_with_namespace(path, data, &mut conn, nats_cli).await, Err(_) => Err(ErrorInternalServerError("Failed to get database connection")), } } @@ -1121,9 +1397,11 @@ mod tests { move |path| { let handler = HANDLER.clone(); let db_pool = DB_POOL.clone(); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { - Ok(mut conn) => handler.delete_api_with_namespace(path, &mut conn).await, + Ok(mut conn) => handler.delete_api_with_namespace(path, &mut conn, nats_cli).await, Err(_) => Err(ErrorInternalServerError("Failed to get database connection")), } } @@ -1133,9 +1411,11 @@ mod tests { move |path, data| { let handler = HANDLER.clone(); let db_pool = DB_POOL.clone(); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { - Ok(mut conn) => handler.getone_api_with_namespace(path, data, &mut conn).await, + Ok(mut conn) => handler.getone_api_with_namespace(path, data, &mut conn, nats_cli).await, Err(_) => Err(ErrorInternalServerError("Failed to get database connection")), } } @@ -1145,9 +1425,11 @@ mod tests { move |path, data| { let handler = HANDLER.clone(); let db_pool = DB_POOL.clone(); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { - Ok(mut conn) => handler.listall_api_with_namespace(path, data, &mut conn).await, + Ok(mut conn) => handler.listall_api_with_namespace(path, data, &mut conn, nats_cli).await, Err(_) => Err(ErrorInternalServerError("Failed to get database connection")), } } diff --git a/src/main.rs b/src/main.rs index b35adf0..a9aba48 100644 --- a/src/main.rs +++ b/src/main.rs @@ -36,36 +36,4 @@ async fn start(db_pool: Arc) { let handler: DefaultHandler = DefaultHandler::new(); let _ = Arc::new(server).start("0.0.0.0:8080", handler, db_pool).await; -} - -// fn validate() { -// let pod_json = r#" -// { -// "apiVersion": "v1", -// "kind": "Pod", -// "metadata": { -// "name": "example-pod" -// }, -// "spec": { -// "containers": [ -// { -// "name": "nginx", -// "image": "nginx:1.14.2", -// "ports": [ -// { -// "containerPort": 80 -// } -// ] -// } -// ] -// } -// } -// "#; -// -// // 使用 Pod 类型进行校验 -// match checker::validate_pod_json(pod_json) { -// Ok(true) => println!("Pod JSON validation passed!"), -// Ok(false) => println!("JSON validation failed, but no critical error."), -// Err(e) => println!("Pod JSON validation failed: {}", e), -// } -// } +} \ No newline at end of file -- Gitee From decffb77ed32d50f2bfa535b8186f25a66c93377 Mon Sep 17 00:00:00 2001 From: Yuichi <913637919@qq.com> Date: Sun, 24 Nov 2024 17:22:37 +0800 Subject: [PATCH 25/48] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=83=A8=E5=88=86?= =?UTF-8?q?=E5=87=BD=E6=95=B0=E5=AE=9A=E4=B9=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/cores/apiserver.rs | 8 +- src/cores/handlers.rs | 556 +++++++++++++++++++++++++++-------------- 2 files changed, 369 insertions(+), 195 deletions(-) diff --git a/src/cores/apiserver.rs b/src/cores/apiserver.rs index 599f757..ee6750f 100644 --- a/src/cores/apiserver.rs +++ b/src/cores/apiserver.rs @@ -13,6 +13,7 @@ use crate::cores::handlers::{Handler}; use std::sync::{Arc}; use feventbus::impls::nats::nats::NatsCli; use feventbus::traits::controller::EventBus; +use serde::{Deserialize, Serialize}; use crate::cores::db::{DbPool}; pub struct ApiServer @@ -21,6 +22,11 @@ pub struct ApiServer config: Arc, } +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct ApiServerMessage { + pub content: String, +} + impl ApiServer { pub fn new (config: Box) -> Self { @@ -36,7 +42,7 @@ impl ApiServer let handler = Arc::new(handler); // 初始化 NatsCli 实例 - let nats_cli = Arc::new(NatsCli::new().await.unwrap()); + let nats_cli: Arc> = Arc::new(NatsCli::new().await.unwrap()); let server = HttpServer::new(move || { diff --git a/src/cores/handlers.rs b/src/cores/handlers.rs index 88c7f08..a335666 100644 --- a/src/cores/handlers.rs +++ b/src/cores/handlers.rs @@ -1,4 +1,6 @@ +use std::fmt::Debug; use std::sync::Arc; +use std::time; /** * Copyright (2024, ) Institute of Software, Chinese Academy of Sciences * author: wuheng@iscas.ac.cn @@ -16,225 +18,191 @@ use crate::cores::db::DbConnection; use diesel::sql_types::{Text}; use actix_web::error::ErrorInternalServerError; use feventbus::impls::nats::nats::NatsCli; +use feventbus::message::Message; +use feventbus::message; +use feventbus::traits::consumer::{Consumer, MessageHandler}; +use feventbus::traits::producer::Producer; use serde::{Deserialize, Serialize}; +use cores::apiserver::ApiServerMessage; +use crate::cores; #[async_trait] pub trait Handler { // /api/{version}/{plural} - async fn create_api_without_namespace( + async fn create_api_without_namespace( &self, info: web::Path<(String, String)>, data: web::Json, db_connection: &mut DbConnection, - nats_cli: Arc>, - ) -> Result - where - T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; + nats_cli: Arc>, + ) -> Result; // /api/{version}/namespaces/{namespace}/{plural} - async fn create_api_with_namespace( + async fn create_api_with_namespace( &self, info: web::Path<(String, String, String)>, data: web::Json, db_connection: &mut DbConnection, - nats_cli: Arc>, - ) -> Result - where - T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; + nats_cli: Arc>, + ) -> Result; // /apis/{group}/{version}/{plural} - async fn create_apis_without_namespace( + async fn create_apis_without_namespace( &self, info: web::Path<(String, String, String)>, data: web::Json, db_connection: &mut DbConnection, - nats_cli: Arc>, - ) -> Result - where - T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; + nats_cli: Arc>, + ) -> Result; // /apis/{group}/{version}/namespaces/{namespace}/{plural} - async fn create_apis_with_namespace( + async fn create_apis_with_namespace( &self, info: web::Path<(String, String, String, String)>, data: web::Json, db_connection: &mut DbConnection, - nats_cli: Arc>, - ) -> Result - where - T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; + nats_cli: Arc>, + ) -> Result; // /api/{version}/{plural}/{name} - async fn delete_api_without_namespace( + async fn delete_api_without_namespace( &self, info: web::Path<(String, String, String)>, db_connection: &mut DbConnection, - nats_cli: Arc>, - ) -> Result - where - T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; + nats_cli: Arc>, + ) -> Result; // /api/{version}/namespaces/{namespace}/{plural}/{name} - async fn delete_api_with_namespace( + async fn delete_api_with_namespace( &self, info: web::Path<(String, String, String, String)>, db_connection: &mut DbConnection, - nats_cli: Arc>, - ) -> Result - where - T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; + nats_cli: Arc>, + ) -> Result; // /apis/{group}/{version}/{plural}/{name} - async fn delete_apis_without_namespace( + async fn delete_apis_without_namespace( &self, info: web::Path<(String, String, String, String)>, db_connection: &mut DbConnection, - nats_cli: Arc>, - ) -> Result - where - T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; + nats_cli: Arc>, + ) -> Result; // /apis/{group}/{version}/namespaces/{namespace}/{plural}/{name} - async fn delete_apis_with_namespace( + async fn delete_apis_with_namespace( &self, info: web::Path<(String, String, String, String, String)>, db_connection: &mut DbConnection, - nats_cli: Arc>, - ) -> Result - where - T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; + nats_cli: Arc>, + ) -> Result; // /api/{version}/{plural}/{name} - async fn update_api_without_namespace( + async fn update_api_without_namespace( &self, info: web::Path<(String, String, String)>, data: web::Json, db_connection: &mut DbConnection, - nats_cli: Arc>, - ) -> Result - where - T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; + nats_cli: Arc>, + ) -> Result; // /api/{version}/namespaces/{namespace}/{plural}/{name} - async fn update_api_with_namespace( + async fn update_api_with_namespace( &self, info: web::Path<(String, String, String, String)>, data: web::Json, db_connection: &mut DbConnection, - nats_cli: Arc>, - ) -> Result - where - T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; + nats_cli: Arc>, + ) -> Result; // /apis/{group}/{version}/{plural}/{name} - async fn update_apis_without_namespace( + async fn update_apis_without_namespace( &self, info: web::Path<(String, String, String, String)>, data: web::Json, db_connection: &mut DbConnection, - nats_cli: Arc>, - ) -> Result - where - T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; + nats_cli: Arc>, + ) -> Result; // /apis/{group}/{version}/namespaces/{namespace}/{plural}/{name} - async fn update_apis_with_namespace( + async fn update_apis_with_namespace( &self, info: web::Path<(String, String, String, String, String)>, data: web::Json, db_connection: &mut DbConnection, - nats_cli: Arc>, - ) -> Result - where - T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; + nats_cli: Arc>, + ) -> Result; // /api/{version}/{plural}/{name} - async fn getone_api_without_namespace( + async fn getone_api_without_namespace( &self, info: web::Path<(String, String, String)>, data: web::Query, db_connection: &mut DbConnection, - nats_cli: Arc>, - ) -> Result - where - T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; + nats_cli: Arc>, + ) -> Result; // /api/{version}/namespaces/{namespace}/{plural}/{name} - async fn getone_api_with_namespace( + async fn getone_api_with_namespace( &self, info: web::Path<(String, String, String, String)>, data: web::Query, db_connection: &mut DbConnection, - nats_cli: Arc>, - ) -> Result - where - T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; + nats_cli: Arc>, + ) -> Result; // /apis/{group}/{version}/{plural}/{name} - async fn getone_apis_without_namespace( + async fn getone_apis_without_namespace( &self, info: web::Path<(String, String, String, String)>, data: web::Query, db_connection: &mut DbConnection, - nats_cli: Arc>, - ) -> Result - where - T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; + nats_cli: Arc>, + ) -> Result; // /apis/{group}/{version}/namespaces/{namespace}/{plural}/{name} - async fn getone_apis_with_namespace( + async fn getone_apis_with_namespace( &self, info: web::Path<(String, String, String, String, String)>, data: web::Query, db_connection: &mut DbConnection, - nats_cli: Arc>, - ) -> Result - where - T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; + nats_cli: Arc>, + ) -> Result; // /api/{version}/{plural} - async fn listall_api_without_namespace( + async fn listall_api_without_namespace( &self, info: web::Path<(String, String)>, data: web::Query, db_connection: &mut DbConnection, - nats_cli: Arc>, - ) -> Result - where - T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; + nats_cli: Arc>, + ) -> Result; // /api/{version}/namespaces/{namespace}/{plural} - async fn listall_api_with_namespace( + async fn listall_api_with_namespace( &self, info: web::Path<(String, String, String)>, data: web::Query, db_connection: &mut DbConnection, - nats_cli: Arc>, - ) -> Result - where - T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; + nats_cli: Arc>, + ) -> Result; // /apis/{group}/{version}/{plural} - async fn listall_apis_without_namespace( + async fn listall_apis_without_namespace( &self, info: web::Path<(String, String, String)>, data: web::Query, db_connection: &mut DbConnection, - nats_cli: Arc>, - ) -> Result - where - T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; + nats_cli: Arc>, + ) -> Result; // /apis/{group}/{version}/namespaces/{namespace}/{plural} - async fn listall_apis_with_namespace( + async fn listall_apis_with_namespace( &self, info: web::Path<(String, String, String, String)>, data: web::Query, db_connection: &mut DbConnection, - nats_cli: Arc>, - ) -> Result - where - T: Serialize + for<'de> Deserialize<'de> + std::fmt::Debug + Clone + Send + Sync + 'static; + nats_cli: Arc>, + ) -> Result; // 不满足以上请求路径的处理 fn default(&self) -> DefaultHandler; @@ -646,17 +614,55 @@ async fn get_all_data_from_table( } } +// 收到请求并等待响应 +async fn reply_to_topic( + topic: &str, + nats_cli: Arc>, + handler: MessageHandler, +) -> Result<(), Box> +where + T: Serialize + for<'de> Deserialize<'de> + Debug + Send + Clone + Sync + 'static, +{ + nats_cli + .reply(topic, handler) + .await + .map_err(|e| Box::new(e) as Box)?; + Ok(()) +} + +// 发送请求并等待响应 +async fn send_request(message: Message, nats_cli: Arc>) -> Result<(), Box> +where + T: Serialize + for<'de> Deserialize<'de> + Debug + Clone + Send + Sync + 'static, +{ + match nats_cli + .request(message, time::Duration::from_secs(100)) + .await + { + Ok(response) => { + println!( + "===============Received response: {:?}==================", + response + ); + Ok(()) + } + Err(e) => { + println!("Failed to get response: {:?}", e); + Err(Box::new(e) as Box) + } + } +} #[async_trait] impl Handler for DefaultHandler { // /api/{version}/{plural} - async fn create_api_without_namespace( + async fn create_api_without_namespace( &self, info: web::Path<(String, String)>, data: web::Json, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc>, ) -> Result { let (version, plural) = info.into_inner(); @@ -692,6 +698,18 @@ impl Handler for DefaultHandler { return Ok(HttpResponse::NotFound().json(json!({ "error": "该 plural 不存在,请重新注册或检查 plural 版本以及是否需要 namespace" }))); } + // request消息 + let request_message = Message::new( + "CREATE".to_string(), + message::NativeEventAction::Other, + None, + Some(ApiServerMessage { + content: data.to_string(), + }), + None, + ); + tokio::spawn(send_request(request_message, nats_cli)); + insert_into_table(db_connection, &plural, &data, &version, None) .await .map_err(ErrorInternalServerError)?; @@ -701,12 +719,12 @@ impl Handler for DefaultHandler { } // /api/{version}/namespaces/{namespace}/{plural} - async fn create_api_with_namespace( + async fn create_api_with_namespace( &self, info: web::Path<(String, String, String)>, data: web::Json, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc>, ) -> Result { let (version, namespace, plural) = info.into_inner(); @@ -742,6 +760,18 @@ impl Handler for DefaultHandler { return Ok(HttpResponse::NotFound().json(json!({ "error": "该 plural 不存在,请重新注册或检查 plural 版本以及是否需要 namespace" }))); } + // request消息 + let request_message = Message::new( + "CREATE".to_string(), + message::NativeEventAction::Other, + None, + Some(ApiServerMessage { + content: data.to_string(), + }), + None, + ); + tokio::spawn(send_request(request_message, nats_cli)); + insert_into_table(db_connection, &plural, &data, &version, Some(&namespace)) .await .map_err(ErrorInternalServerError)?; @@ -751,12 +781,12 @@ impl Handler for DefaultHandler { } // /apis/{group}/{version}/{plural} - async fn create_apis_without_namespace( + async fn create_apis_without_namespace( &self, info: web::Path<(String, String, String)>, data: web::Json, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc>, ) -> Result { let (group, version, plural) = info.into_inner(); let ver = group + "/" + &*version; @@ -794,6 +824,18 @@ impl Handler for DefaultHandler { return Ok(HttpResponse::NotFound().json(json!({ "error": "该 plural 不存在,请重新注册或检查 plural 版本以及是否需要 namespace" }))); } + // request消息 + let request_message = Message::new( + "CREATE".to_string(), + message::NativeEventAction::Other, + None, + Some(ApiServerMessage { + content: data.to_string(), + }), + None, + ); + tokio::spawn(send_request(request_message, nats_cli)); + insert_into_table(db_connection, &plural, &data, &ver, None) .await .map_err(ErrorInternalServerError)?; @@ -803,12 +845,12 @@ impl Handler for DefaultHandler { } // /apis/{group}/{version}/namespaces/{namespace}/{plural} - async fn create_apis_with_namespace( + async fn create_apis_with_namespace( &self, info: web::Path<(String, String, String, String)>, data: web::Json, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc>, ) -> Result { let (group, version, namespace, plural) = info.into_inner(); @@ -847,6 +889,18 @@ impl Handler for DefaultHandler { return Ok(HttpResponse::NotFound().json(json!({ "error": "该 plural 不存在,请重新注册或检查 plural 版本以及是否需要 namespace" }))); } + // request消息 + let request_message = Message::new( + "CREATE".to_string(), + message::NativeEventAction::Other, + None, + Some(ApiServerMessage { + content: data.to_string(), + }), + None, + ); + tokio::spawn(send_request(request_message, nats_cli)); + insert_into_table(db_connection, &plural, &data, &ver, Some(&namespace)) .await .map_err(ErrorInternalServerError)?; @@ -856,11 +910,11 @@ impl Handler for DefaultHandler { } // /api/{version}/{plural}/{name} - async fn delete_api_without_namespace( + async fn delete_api_without_namespace( &self, info: web::Path<(String, String, String)>, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc>, ) -> Result { let (version, plural, name) = info.into_inner(); @@ -873,6 +927,18 @@ impl Handler for DefaultHandler { return Ok(HttpResponse::NotFound().json(json!({ "error": "该 plural 不存在,请检查 plural 版本以及是否需要 namespace" }))); } + // request消息 + let request_message = Message::new( + "REMOVE".to_string(), + message::NativeEventAction::Other, + None, + Some(ApiServerMessage { + content: name.clone(), + }), + None, + ); + tokio::spawn(send_request(request_message, nats_cli)); + // 从 plural 表中删除指定的 name let deleted = delete_from_table(db_connection, &plural, &name, &version, None) .await @@ -886,11 +952,11 @@ impl Handler for DefaultHandler { } // /api/{version}/namespaces/{namespace}/{plural}/{name} - async fn delete_api_with_namespace( + async fn delete_api_with_namespace( &self, info: web::Path<(String, String, String, String)>, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc>, ) -> Result { let (version, namespace, plural, name) = info.into_inner(); // 检查 metadata 中是否存在该 plural 且需要 namespace @@ -902,6 +968,18 @@ impl Handler for DefaultHandler { return Ok(HttpResponse::NotFound().json(json!({ "error": "该 plural 不存在,请检查 plural 版本以及是否需要 namespace" }))); } + // request消息 + let request_message = Message::new( + "REMOVE".to_string(), + message::NativeEventAction::Other, + None, + Some(ApiServerMessage { + content: name.clone(), + }), + None, + ); + tokio::spawn(send_request(request_message, nats_cli)); + // 从 plural 表中删除指定的数据 let deleted = delete_from_table(db_connection, &plural, &name, &version, Some(&namespace)) .await @@ -915,11 +993,11 @@ impl Handler for DefaultHandler { } // /apis/{group}/{version}/{plural}/{name} - async fn delete_apis_without_namespace( + async fn delete_apis_without_namespace( &self, info: web::Path<(String, String, String, String)>, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc>, ) -> Result { let (group, version, plural, name) = info.into_inner(); let ver = format!("{}/{}", group, version); @@ -932,6 +1010,18 @@ impl Handler for DefaultHandler { return Ok(HttpResponse::NotFound().json(json!({ "error": "该 plural 不存在,请检查 plural 版本以及是否需要 namespace" }))); } + // request消息 + let request_message = Message::new( + "REMOVE".to_string(), + message::NativeEventAction::Other, + None, + Some(ApiServerMessage { + content: name.clone(), + }), + None, + ); + tokio::spawn(send_request(request_message, nats_cli)); + let deleted = delete_from_table(db_connection, &plural, &name, &ver, None) .await .map_err(ErrorInternalServerError)?; @@ -944,11 +1034,11 @@ impl Handler for DefaultHandler { } // /apis/{group}/{version}/namespaces/{namespace}/{plural}/{name} - async fn delete_apis_with_namespace( + async fn delete_apis_with_namespace( &self, info: web::Path<(String, String, String, String, String)>, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc>, ) -> Result { let (group, version, namespace, plural, name) = info.into_inner(); let ver = format!("{}/{}", group, version); @@ -961,6 +1051,18 @@ impl Handler for DefaultHandler { return Ok(HttpResponse::NotFound().json(json!({ "error": "该 plural 不存在,请检查 plural 版本以及是否需要 namespace" }))); } + // request消息 + let request_message = Message::new( + "REMOVE".to_string(), + message::NativeEventAction::Other, + None, + Some(ApiServerMessage { + content: name.clone(), + }), + None, + ); + tokio::spawn(send_request(request_message, nats_cli)); + let deleted = delete_from_table(db_connection, &plural, &name, &ver, Some(&namespace)) .await .map_err(ErrorInternalServerError)?; @@ -973,12 +1075,12 @@ impl Handler for DefaultHandler { } // /api/{version}/{plural}/{name} - async fn update_api_without_namespace( + async fn update_api_without_namespace( &self, info: web::Path<(String, String, String)>, data: web::Json, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc>, ) -> Result { let (version, plural, name) = info.into_inner(); @@ -1003,12 +1105,12 @@ impl Handler for DefaultHandler { } // /api/{version}/namespaces/{namespace}/{plural}/{name} - async fn update_api_with_namespace( + async fn update_api_with_namespace( &self, info: web::Path<(String, String, String, String)>, data: web::Json, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc>, ) -> Result { let (version, namespace, plural, name) = info.into_inner(); // 检查 metadata 中是否存在 plural 且要求 namespace @@ -1032,12 +1134,12 @@ impl Handler for DefaultHandler { } // /apis/{group}/{version}/{plural}/{name} - async fn update_apis_without_namespace( + async fn update_apis_without_namespace( &self, info: web::Path<(String, String, String, String)>, data: web::Json, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc>, ) -> Result { let (group, version, plural, name) = info.into_inner(); let ver = format!("{}/{}", group, version); @@ -1062,12 +1164,12 @@ impl Handler for DefaultHandler { } // /apis/{group}/{version}/namespaces/{namespace}/{plural}/{name} - async fn update_apis_with_namespace( + async fn update_apis_with_namespace( &self, info: web::Path<(String, String, String, String, String)>, data: web::Json, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc>, ) -> Result { let (group, version, namespace, plural, name) = info.into_inner(); let ver = format!("{}/{}", group, version); @@ -1092,12 +1194,12 @@ impl Handler for DefaultHandler { } // /api/{version}/{plural}/{name} - async fn getone_api_without_namespace( + async fn getone_api_without_namespace( &self, info: web::Path<(String, String, String)>, _data: web::Query, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc>, ) -> Result { let (version, plural, name) = info.into_inner(); let metadata_exists = check_metadata(db_connection, &plural, &version, false) @@ -1121,12 +1223,12 @@ impl Handler for DefaultHandler { } // /api/{version}/namespaces/{namespace}/{plural}/{name} - async fn getone_api_with_namespace( + async fn getone_api_with_namespace( &self, info: web::Path<(String, String, String, String)>, _data: web::Query, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc>, ) -> Result { let (version, namespace, plural, name) = info.into_inner(); let metadata_exists = check_metadata(db_connection, &plural, &version, true) @@ -1150,12 +1252,12 @@ impl Handler for DefaultHandler { } // /apis/{group}/{version}/{plural}/{name} - async fn getone_apis_without_namespace( + async fn getone_apis_without_namespace( &self, info: web::Path<(String, String, String, String)>, _data: web::Query, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc>, ) -> Result { let (group, version, plural, name) = info.into_inner(); let ver = format!("{}/{}", group, version); @@ -1181,12 +1283,12 @@ impl Handler for DefaultHandler { } // /apis/{group}/{version}/namespaces/{namespace}/{plural}/{name} - async fn getone_apis_with_namespace( + async fn getone_apis_with_namespace( &self, info: web::Path<(String, String, String, String, String)>, _data: web::Query, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc>, ) -> Result { let (group, version, namespace, plural, name) = info.into_inner(); let ver = format!("{}/{}", group, version); @@ -1212,12 +1314,12 @@ impl Handler for DefaultHandler { } // /api/{version}/{plural} - async fn listall_api_without_namespace( + async fn listall_api_without_namespace( &self, info: web::Path<(String, String)>, _data: web::Query, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc>, ) -> Result { let (version, plural) = info.into_inner(); let metadata_exists = check_metadata(db_connection, &plural, &version, false) @@ -1242,12 +1344,12 @@ impl Handler for DefaultHandler { } // /api/{version}/namespaces/{namespace}/{plural} - async fn listall_api_with_namespace( + async fn listall_api_with_namespace( &self, info: web::Path<(String, String, String)>, _data: web::Query, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc>, ) -> Result { let (version, namespace, plural) = info.into_inner(); let metadata_exists = check_metadata(db_connection, &plural, &version, true) @@ -1272,12 +1374,12 @@ impl Handler for DefaultHandler { } // /apis/{group}/{version}/{plural} - async fn listall_apis_without_namespace( + async fn listall_apis_without_namespace( &self, info: web::Path<(String, String, String)>, _data: web::Query, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc>, ) -> Result { let (group, version, plural) = info.into_inner(); let ver = format!("{}/{}", group, version); @@ -1304,12 +1406,12 @@ impl Handler for DefaultHandler { } // /apis/{group}/{version}/namespaces/{namespace}/{plural} - async fn listall_apis_with_namespace( + async fn listall_apis_with_namespace( &self, info: web::Path<(String, String, String, String)>, _data: web::Query, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc>, ) -> Result { let (group, version, namespace, plural) = info.into_inner(); let ver = format!("{}/{}", group, version); @@ -1365,7 +1467,8 @@ mod tests { let app = test::init_service( App::new() - .route("/api/{version}/namespaces/{namespace}/{plural}", web::post().to( + .route("/api/{version}/namespaces/{namespace}/{plural}", web::post().to({ + let nats_cli = Arc::clone(&nats_cli); move |path, data| { let handler = HANDLER.clone(); let db_pool = DB_POOL.clone(); @@ -1378,8 +1481,9 @@ mod tests { } } } - )) - .route("/api/{version}/namespaces/{namespace}/{plural}/{name}", web::put().to( + })) + .route("/api/{version}/namespaces/{namespace}/{plural}/{name}", web::put().to({ + let nats_cli = Arc::clone(&nats_cli); move |path, data| { let handler = HANDLER.clone(); let db_pool = DB_POOL.clone(); @@ -1392,8 +1496,9 @@ mod tests { } } } - )) - .route("/api/{version}/namespaces/{namespace}/{plural}/{name}", web::delete().to( + })) + .route("/api/{version}/namespaces/{namespace}/{plural}/{name}", web::delete().to({ + let nats_cli = Arc::clone(&nats_cli); move |path| { let handler = HANDLER.clone(); let db_pool = DB_POOL.clone(); @@ -1406,7 +1511,7 @@ mod tests { } } } - )) + })) .route("/api/{version}/namespaces/{namespace}/{plural}/{name}", web::get().to( move |path, data| { let handler = HANDLER.clone(); @@ -1421,7 +1526,8 @@ mod tests { } } )) - .route("/api/{version}/namespaces/{namespace}/{plural}", web::get().to( + .route("/api/{version}/namespaces/{namespace}/{plural}", web::get().to({ + let nats_cli = Arc::clone(&nats_cli); move |path, data| { let handler = HANDLER.clone(); let db_pool = DB_POOL.clone(); @@ -1434,7 +1540,7 @@ mod tests { } } } - )) + })) ).await; @@ -1700,73 +1806,93 @@ mod tests { #[actix_web::test] async fn test_api_without_namespace() { + let nats_cli = Arc::new(NatsCli::new().await.unwrap()); let app = test::init_service( App::new() - .route("/api/{version}/{plural}", web::post().to( + .route("/api/{version}/{plural}", web::post().to({ + let nats_cli = Arc::clone(&nats_cli); + move |path, data| { let handler = HANDLER.clone(); let db_pool = DB_POOL.clone(); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { - Ok(mut conn) => handler.create_api_without_namespace(path, data, &mut conn).await, + Ok(mut conn) => handler.create_api_without_namespace(path, data, &mut conn, nats_cli).await, Err(_) => Err(ErrorInternalServerError("Failed to get database connection")), } } } - )) - .route("/api/{version}/{plural}/{name}", web::put().to( + })) + .route("/api/{version}/{plural}/{name}", web::put().to({ + let nats_cli = Arc::clone(&nats_cli); + move |path, data| { let handler = HANDLER.clone(); let db_pool = DB_POOL.clone(); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { - Ok(mut conn) => handler.update_api_without_namespace(path, data, &mut conn).await, + Ok(mut conn) => handler.update_api_without_namespace(path, data, &mut conn, nats_cli).await, Err(_) => Err(ErrorInternalServerError("Failed to get database connection")), } } } - )) - .route("/api/{version}/{plural}/{name}", web::delete().to( + })) + .route("/api/{version}/{plural}/{name}", web::delete().to({ + let nats_cli = Arc::clone(&nats_cli); + move |path| { let handler = HANDLER.clone(); let db_pool = DB_POOL.clone(); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { - Ok(mut conn) => handler.delete_api_without_namespace(path, &mut conn).await, + Ok(mut conn) => handler.delete_api_without_namespace(path, &mut conn, nats_cli).await, Err(_) => Err(ErrorInternalServerError("Failed to get database connection")), } } } - )) - .route("/api/{version}/{plural}/{name}", web::get().to( + })) + .route("/api/{version}/{plural}/{name}", web::get().to({ + let nats_cli = Arc::clone(&nats_cli); + move |path, data| { let handler = HANDLER.clone(); let db_pool = DB_POOL.clone(); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { - Ok(mut conn) => handler.getone_api_without_namespace(path, data, &mut conn).await, + Ok(mut conn) => handler.getone_api_without_namespace(path, data, &mut conn, nats_cli).await, Err(_) => Err(ErrorInternalServerError("Failed to get database connection")), } } } - )) - .route("/api/{version}/{plural}", web::get().to( + })) + .route("/api/{version}/{plural}", web::get().to({ + let nats_cli = Arc::clone(&nats_cli); + move |path, data| { let handler = HANDLER.clone(); let db_pool = DB_POOL.clone(); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { - Ok(mut conn) => handler.listall_api_without_namespace(path, data, &mut conn).await, + Ok(mut conn) => handler.listall_api_without_namespace(path, data, &mut conn, nats_cli).await, Err(_) => Err(ErrorInternalServerError("Failed to get database connection")), } } } - )) + })) ).await; - let create_req_data = json!({ "apiVersion": "v1", "kind": "Node", @@ -1999,69 +2125,90 @@ mod tests { #[actix_web::test] async fn test_apis_with_namespace() { + let nats_cli = Arc::new(NatsCli::new().await.unwrap()); let app = test::init_service( App::new() - .route("/apis/{group}/{version}/namespaces/{namespace}/{plural}", web::post().to( + .route("/apis/{group}/{version}/namespaces/{namespace}/{plural}", web::post().to({ + let nats_cli = Arc::clone(&nats_cli); + move |path, data| { let handler = HANDLER.clone(); let db_pool = DB_POOL.clone(); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { - Ok(mut conn) => handler.create_apis_with_namespace(path, data, &mut conn).await, + Ok(mut conn) => handler.create_apis_with_namespace(path, data, &mut conn, nats_cli).await, Err(_) => Err(ErrorInternalServerError("Failed to get database connection")), } } } - )) - .route("/apis/{group}/{version}/namespaces/{namespace}/{plural}/{name}", web::put().to( + })) + .route("/apis/{group}/{version}/namespaces/{namespace}/{plural}/{name}", web::put().to({ + let nats_cli = Arc::clone(&nats_cli); + move |path, data| { let handler = HANDLER.clone(); let db_pool = DB_POOL.clone(); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { - Ok(mut conn) => handler.update_apis_with_namespace(path, data, &mut conn).await, + Ok(mut conn) => handler.update_apis_with_namespace(path, data, &mut conn, nats_cli).await, Err(_) => Err(ErrorInternalServerError("Failed to get database connection")), } } } - )) - .route("/apis/{group}/{version}/namespaces/{namespace}/{plural}/{name}", web::delete().to( + })) + .route("/apis/{group}/{version}/namespaces/{namespace}/{plural}/{name}", web::delete().to({ + let nats_cli = Arc::clone(&nats_cli); + move |path| { let handler = HANDLER.clone(); let db_pool = DB_POOL.clone(); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { - Ok(mut conn) => handler.delete_apis_with_namespace(path, &mut conn).await, + Ok(mut conn) => handler.delete_apis_with_namespace(path, &mut conn, nats_cli).await, Err(_) => Err(ErrorInternalServerError("Failed to get database connection")), } } } - )) - .route("/apis/{group}/{version}/namespaces/{namespace}/{plural}/{name}", web::get().to( + })) + .route("/apis/{group}/{version}/namespaces/{namespace}/{plural}/{name}", web::get().to({ + let nats_cli = Arc::clone(&nats_cli); + move |path, data| { let handler = HANDLER.clone(); let db_pool = DB_POOL.clone(); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { - Ok(mut conn) => handler.getone_apis_with_namespace(path, data, &mut conn).await, + Ok(mut conn) => handler.getone_apis_with_namespace(path, data, &mut conn, nats_cli).await, Err(_) => Err(ErrorInternalServerError("Failed to get database connection")), } } } - )) - .route("/apis/{group}/{version}/namespaces/{namespace}/{plural}", web::get().to( + })) + .route("/apis/{group}/{version}/namespaces/{namespace}/{plural}", web::get().to({ + let nats_cli = Arc::clone(&nats_cli); + move |path, data| { let handler = HANDLER.clone(); let db_pool = DB_POOL.clone(); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { - Ok(mut conn) => handler.listall_apis_with_namespace(path, data, &mut conn).await, + Ok(mut conn) => handler.listall_apis_with_namespace(path, data, &mut conn, nats_cli).await, Err(_) => Err(ErrorInternalServerError("Failed to get database connection")), } } } - )) + })) ).await; @@ -2296,69 +2443,90 @@ mod tests { #[actix_web::test] async fn test_crd_and_apis_without_namespace() { + let nats_cli = Arc::new(NatsCli::new().await.unwarp()); let app = test::init_service( App::new() - .route("/apis/{group}/{version}/{plural}", web::post().to( + .route("/apis/{group}/{version}/{plural}", web::post().to({ + let nats_cli = Arc::clone(&nats_cli); + move |path, data| { let handler = HANDLER.clone(); let db_pool = DB_POOL.clone(); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { - Ok(mut conn) => handler.create_apis_without_namespace(path, data, &mut conn).await, + Ok(mut conn) => handler.create_apis_without_namespace(path, data, &mut conn, nats_cli).await, Err(_) => Err(ErrorInternalServerError("Failed to get database connection")), } } } - )) - .route("/apis/{group}/{version}/{plural}/{name}", web::put().to( + })) + .route("/apis/{group}/{version}/{plural}/{name}", web::put().to({ + let nats_cli = Arc::clone(&nats_cli); + move |path, data| { let handler = HANDLER.clone(); let db_pool = DB_POOL.clone(); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { - Ok(mut conn) => handler.update_apis_without_namespace(path, data, &mut conn).await, + Ok(mut conn) => handler.update_apis_without_namespace(path, data, &mut conn, nats_cli).await, Err(_) => Err(ErrorInternalServerError("Failed to get database connection")), } } } - )) - .route("/apis/{group}/{version}/{plural}/{name}", web::delete().to( + })) + .route("/apis/{group}/{version}/{plural}/{name}", web::delete().to({ + let nats_cli = Arc::clone(&nats_cli); + move |path| { let handler = HANDLER.clone(); let db_pool = DB_POOL.clone(); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { - Ok(mut conn) => handler.delete_apis_without_namespace(path, &mut conn).await, + Ok(mut conn) => handler.delete_apis_without_namespace(path, &mut conn, nats_cli).await, Err(_) => Err(ErrorInternalServerError("Failed to get database connection")), } } } - )) - .route("/apis/{group}/{version}/{plural}/{name}", web::get().to( + })) + .route("/apis/{group}/{version}/{plural}/{name}", web::get().to({ + let nats_cli = Arc::clone(&nats_cli); + move |path, data| { let handler = HANDLER.clone(); let db_pool = DB_POOL.clone(); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { - Ok(mut conn) => handler.getone_apis_without_namespace(path, data, &mut conn).await, + Ok(mut conn) => handler.getone_apis_without_namespace(path, data, &mut conn, nats_cli).await, Err(_) => Err(ErrorInternalServerError("Failed to get database connection")), } } } - )) - .route("/apis/{group}/{version}/{plural}", web::get().to( + })) + .route("/apis/{group}/{version}/{plural}", web::get().to({ + let nats_cli = Arc::clone(&nats_cli); + move |path, data| { let handler = HANDLER.clone(); let db_pool = DB_POOL.clone(); + let nats_cli = Arc::clone(&nats_cli); + async move { match db_pool.get_connection() { - Ok(mut conn) => handler.listall_apis_without_namespace(path, data, &mut conn).await, + Ok(mut conn) => handler.listall_apis_without_namespace(path, data, &mut conn, nats_cli).await, Err(_) => Err(ErrorInternalServerError("Failed to get database connection")), } } } - )) + })) ).await; -- Gitee From 8c9623bcead88c360783ab94528f04e92e8d014c Mon Sep 17 00:00:00 2001 From: Yuichi <913637919@qq.com> Date: Mon, 25 Nov 2024 07:27:26 +0000 Subject: [PATCH 26/48] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=83=A8=E5=88=86?= =?UTF-8?q?=E5=87=BD=E6=95=B0=E5=AE=9A=E4=B9=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.lock | 49 ++++++------ Cargo.toml | 12 ++- src/cores/apiserver.rs | 7 -- src/cores/handlers.rs | 173 +++++++++++++++++++++++++++++------------ src/lib.rs | 33 +++++++- src/main.rs | 40 +++------- 6 files changed, 196 insertions(+), 118 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e127116..65008bb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -916,6 +916,31 @@ dependencies = [ "miniz_oxide", ] +[[package]] +name = "fleet_apiserver" +version = "0.1.0" +dependencies = [ + "actix-http", + "actix-service", + "actix-web", + "async-trait", + "chrono", + "diesel", + "diesel_migrations", + "dotenv", + "env_logger", + "feventbus", + "jsonschema", + "k8s-openapi", + "lazy_static", + "once_cell", + "r2d2", + "schemars", + "serde", + "serde_json", + "tokio", +] + [[package]] name = "fluent-uri" version = "0.3.2" @@ -1467,30 +1492,6 @@ dependencies = [ "serde_json", ] -[[package]] -name = "k8s_apiserver" -version = "0.1.5" -dependencies = [ - "actix-http", - "actix-service", - "actix-web", - "async-trait", - "chrono", - "diesel", - "diesel_migrations", - "dotenv", - "env_logger", - "feventbus", - "jsonschema", - "k8s-openapi", - "once_cell", - "r2d2", - "schemars", - "serde", - "serde_json", - "tokio", -] - [[package]] name = "language-tags" version = "0.3.2" diff --git a/Cargo.toml b/Cargo.toml index c2920a2..0a37ef1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,12 +1,12 @@ [package] -name = "k8s_apiserver" -version = "0.1.5" +name = "fleet_apiserver" +version = "0.1.0" license = "Apache-2.0" authors = ["wuheng ", "chenhongyu23@otcaix.iscas.ac.cn"] categories = ["api-bindings"] -description = "Kubernetes apiserver" +description = "Kubernetes apiserver for fleet" edition = "2021" -keywords = ["apiserver", "kubernetes", "k8s"] +keywords = ["apiserver", "kubernetes", "k8s", "fleet"] repository = "https://gitee.com/iscas-system/apiserver" readme = "README.md" @@ -24,11 +24,9 @@ env_logger = "0.11.5" serde = { version = "1.0.209", features = ["derive"] } serde_json = "1.0.127" tokio = "1.40.0" -#kube = { version = "0.96.0", features = ["runtime", "derive"] } k8s-openapi = { version = "0.23.0", features = ["latest"] } jsonschema = "0.23.0" schemars = "0.8.21" chrono = "0.4.38" once_cell = "1.20.2" -#log = "0.4" -#env_logger = { version = "0.11" } +lazy_static = "1.5.0" \ No newline at end of file diff --git a/src/cores/apiserver.rs b/src/cores/apiserver.rs index ee6750f..963d751 100644 --- a/src/cores/apiserver.rs +++ b/src/cores/apiserver.rs @@ -1,10 +1,3 @@ -/** - * Copyright (2024, ) Institute of Software, Chinese Academy of Sciences - * author: wuheng@iscas.ac.cn - * since: 0.1.2 - * -**/ - use actix_web::{HttpServer, App, web, HttpResponse}; use crate::cores::config::{Config, APIS_WITHOUT_NAMESPACE, APIS_WITH_NAMESPACE, API_WITHOUT_NAMESPACE, API_WITH_NAMESPACE}; diff --git a/src/cores/handlers.rs b/src/cores/handlers.rs index a335666..6cb9b01 100644 --- a/src/cores/handlers.rs +++ b/src/cores/handlers.rs @@ -1,13 +1,7 @@ +use std::collections::HashMap; use std::fmt::Debug; -use std::sync::Arc; +use std::sync::{Arc, LazyLock, Mutex}; use std::time; -/** - * Copyright (2024, ) Institute of Software, Chinese Academy of Sciences - * author: wuheng@iscas.ac.cn - * since: 0.1.0 - * -**/ - use async_trait::async_trait; use actix_web::{HttpResponse, Result, web}; use chrono::Utc; @@ -20,12 +14,33 @@ use actix_web::error::ErrorInternalServerError; use feventbus::impls::nats::nats::NatsCli; use feventbus::message::Message; use feventbus::message; -use feventbus::traits::consumer::{Consumer, MessageHandler}; +use feventbus::traits::consumer::{Consumer}; use feventbus::traits::producer::Producer; use serde::{Deserialize, Serialize}; use cores::apiserver::ApiServerMessage; use crate::cores; +// 定义全局哈希表来获取model名 +static GLOBAL_HASHMAP: LazyLock>> = LazyLock::new(|| { + let mut map = HashMap::new(); + map.insert("cargos".to_string(), "CARGO".to_string()); + map.insert("nodes".to_string(), "NODE".to_string()); + map.insert("jobs".to_string(), "JOB".to_string()); + Mutex::new(map) +}); + +// 添加键值对 +fn insert_key_value(key: &str, value: &str) { + let mut map = GLOBAL_HASHMAP.lock().unwrap(); + map.insert(key.to_string(), value.to_string()); +} + +// 获取键对应的值 +fn get_value(key: &str) -> Option { + let map = GLOBAL_HASHMAP.lock().unwrap(); + map.get(key).cloned() +} + #[async_trait] pub trait Handler { // /api/{version}/{plural} @@ -614,21 +629,6 @@ async fn get_all_data_from_table( } } -// 收到请求并等待响应 -async fn reply_to_topic( - topic: &str, - nats_cli: Arc>, - handler: MessageHandler, -) -> Result<(), Box> -where - T: Serialize + for<'de> Deserialize<'de> + Debug + Send + Clone + Sync + 'static, -{ - nats_cli - .reply(topic, handler) - .await - .map_err(|e| Box::new(e) as Box)?; - Ok(()) -} // 发送请求并等待响应 async fn send_request(message: Message, nats_cli: Arc>) -> Result<(), Box> @@ -639,11 +639,7 @@ where .request(message, time::Duration::from_secs(100)) .await { - Ok(response) => { - println!( - "===============Received response: {:?}==================", - response - ); + Ok(_) => { Ok(()) } Err(e) => { @@ -675,6 +671,13 @@ impl Handler for DefaultHandler { .and_then(|plural| plural.as_str()) .unwrap_or("error"); + let crd_kind = data + .get("spec") + .and_then(|spec| spec.get("names")) + .and_then(|names| names.get("kind")) + .and_then(|kind| kind.as_str()) + .unwrap_or("error"); + // 调用check_metadata函数 let metadata_exists = check_metadata(db_connection, table_name, &version,false).await.map_err(ErrorInternalServerError)?; @@ -682,7 +685,6 @@ impl Handler for DefaultHandler { return Ok(HttpResponse::NotFound().json(json!({ "error": "该 crd 资源已存在,无需重复注册" }))); } - create_table_if_not_exists(db_connection, table_name) .await .map_err(ErrorInternalServerError)?; @@ -690,6 +692,8 @@ impl Handler for DefaultHandler { insert_metadata(db_connection, table_name, &version, false, &data) .await .map_err(ErrorInternalServerError)?; + + insert_key_value(table_name, crd_kind); } else { // 调用check_metadata函数 let metadata_exists = check_metadata(db_connection, &plural, &version,false).await.map_err(ErrorInternalServerError)?; @@ -698,17 +702,23 @@ impl Handler for DefaultHandler { return Ok(HttpResponse::NotFound().json(json!({ "error": "该 plural 不存在,请重新注册或检查 plural 版本以及是否需要 namespace" }))); } + let mut model_map = HashMap::new(); + let kind = get_value(&*plural.clone()).unwrap(); + + model_map.insert("MODEL".to_string(), kind); + // request消息 let request_message = Message::new( "CREATE".to_string(), message::NativeEventAction::Other, - None, + Some(model_map), Some(ApiServerMessage { content: data.to_string(), }), None, ); - tokio::spawn(send_request(request_message, nats_cli)); + + send_request(request_message, nats_cli).await.map_err(ErrorInternalServerError)?; insert_into_table(db_connection, &plural, &data, &version, None) .await @@ -737,6 +747,13 @@ impl Handler for DefaultHandler { .and_then(|plural| plural.as_str()) .unwrap_or("error"); + let crd_kind = data + .get("spec") + .and_then(|spec| spec.get("names")) + .and_then(|names| names.get("kind")) + .and_then(|kind| kind.as_str()) + .unwrap_or("error"); + // 调用check_metadata函数 let metadata_exists = check_metadata(db_connection, table_name, &version, true).await.map_err(ErrorInternalServerError)?; @@ -752,6 +769,8 @@ impl Handler for DefaultHandler { insert_metadata(db_connection, table_name, &version, false, &data) .await .map_err(ErrorInternalServerError)?; + + insert_key_value(table_name, crd_kind); } else { // 调用check_metadata函数 let metadata_exists = check_metadata(db_connection, &plural, &version, true).await.map_err(ErrorInternalServerError)?; @@ -760,17 +779,23 @@ impl Handler for DefaultHandler { return Ok(HttpResponse::NotFound().json(json!({ "error": "该 plural 不存在,请重新注册或检查 plural 版本以及是否需要 namespace" }))); } + let mut model_map = HashMap::new(); + let kind = get_value(&*plural.clone()).unwrap(); + + model_map.insert("MODEL".to_string(), kind); + // request消息 let request_message = Message::new( "CREATE".to_string(), message::NativeEventAction::Other, - None, + Some(model_map), Some(ApiServerMessage { content: data.to_string(), }), None, ); - tokio::spawn(send_request(request_message, nats_cli)); + + send_request(request_message, nats_cli).await.map_err(ErrorInternalServerError)?; insert_into_table(db_connection, &plural, &data, &version, Some(&namespace)) .await @@ -801,6 +826,13 @@ impl Handler for DefaultHandler { .and_then(|plural| plural.as_str()) .unwrap_or("error"); + let crd_kind = data + .get("spec") + .and_then(|spec| spec.get("names")) + .and_then(|names| names.get("kind")) + .and_then(|kind| kind.as_str()) + .unwrap_or("error"); + // 调用check_metadata函数 let metadata_exists = check_metadata(db_connection, table_name, &ver, false).await.map_err(ErrorInternalServerError)?; @@ -816,6 +848,8 @@ impl Handler for DefaultHandler { insert_metadata(db_connection, table_name, &ver, false, &data) .await .map_err(ErrorInternalServerError)?; + + insert_key_value(table_name, crd_kind); } else { // 调用check_metadata函数 let metadata_exists = check_metadata(db_connection, &plural, &ver, false).await.map_err(ErrorInternalServerError)?; @@ -824,17 +858,23 @@ impl Handler for DefaultHandler { return Ok(HttpResponse::NotFound().json(json!({ "error": "该 plural 不存在,请重新注册或检查 plural 版本以及是否需要 namespace" }))); } + let mut model_map = HashMap::new(); + let kind = get_value(&*plural.clone()).unwrap(); + + model_map.insert("MODEL".to_string(), kind); + // request消息 let request_message = Message::new( "CREATE".to_string(), message::NativeEventAction::Other, - None, + Some(model_map), Some(ApiServerMessage { content: data.to_string(), }), None, ); - tokio::spawn(send_request(request_message, nats_cli)); + + send_request(request_message, nats_cli).await.map_err(ErrorInternalServerError)?; insert_into_table(db_connection, &plural, &data, &ver, None) .await @@ -866,6 +906,13 @@ impl Handler for DefaultHandler { .and_then(|plural| plural.as_str()) .unwrap_or("error"); + let crd_kind = data + .get("spec") + .and_then(|spec| spec.get("names")) + .and_then(|names| names.get("kind")) + .and_then(|kind| kind.as_str()) + .unwrap_or("error"); + // 调用 check_metadata 函数 let metadata_exists = check_metadata(db_connection, table_name, &ver, true).await.map_err(ErrorInternalServerError)?; @@ -881,6 +928,8 @@ impl Handler for DefaultHandler { insert_metadata(db_connection, table_name, &ver, false, &data) .await .map_err(ErrorInternalServerError)?; + + insert_key_value(table_name, crd_kind); } else { // 调用 check_metadata 函数 let metadata_exists = check_metadata(db_connection, &plural, &ver, true).await.map_err(ErrorInternalServerError)?; @@ -889,17 +938,23 @@ impl Handler for DefaultHandler { return Ok(HttpResponse::NotFound().json(json!({ "error": "该 plural 不存在,请重新注册或检查 plural 版本以及是否需要 namespace" }))); } + let mut model_map = HashMap::new(); + let kind = get_value(&*plural.clone()).unwrap(); + + model_map.insert("MODEL".to_string(), kind); + // request消息 let request_message = Message::new( "CREATE".to_string(), message::NativeEventAction::Other, - None, + Some(model_map), Some(ApiServerMessage { content: data.to_string(), }), None, ); - tokio::spawn(send_request(request_message, nats_cli)); + + send_request(request_message, nats_cli).await.map_err(ErrorInternalServerError)?; insert_into_table(db_connection, &plural, &data, &ver, Some(&namespace)) .await @@ -927,17 +982,23 @@ impl Handler for DefaultHandler { return Ok(HttpResponse::NotFound().json(json!({ "error": "该 plural 不存在,请检查 plural 版本以及是否需要 namespace" }))); } + let mut model_map = HashMap::new(); + let kind = get_value(&*plural.clone()).unwrap(); + + model_map.insert("MODEL".to_string(), kind); + // request消息 let request_message = Message::new( "REMOVE".to_string(), message::NativeEventAction::Other, - None, + Some(model_map), Some(ApiServerMessage { content: name.clone(), }), None, ); - tokio::spawn(send_request(request_message, nats_cli)); + + send_request(request_message, nats_cli).await.map_err(ErrorInternalServerError)?; // 从 plural 表中删除指定的 name let deleted = delete_from_table(db_connection, &plural, &name, &version, None) @@ -968,17 +1029,22 @@ impl Handler for DefaultHandler { return Ok(HttpResponse::NotFound().json(json!({ "error": "该 plural 不存在,请检查 plural 版本以及是否需要 namespace" }))); } + let mut model_map = HashMap::new(); + let kind = get_value(&*plural.clone()).unwrap(); + + model_map.insert("MODEL".to_string(), kind); + // request消息 let request_message = Message::new( "REMOVE".to_string(), message::NativeEventAction::Other, - None, + Some(model_map), Some(ApiServerMessage { content: name.clone(), }), None, ); - tokio::spawn(send_request(request_message, nats_cli)); + send_request(request_message, nats_cli).await.map_err(ErrorInternalServerError)?; // 从 plural 表中删除指定的数据 let deleted = delete_from_table(db_connection, &plural, &name, &version, Some(&namespace)) @@ -1010,17 +1076,22 @@ impl Handler for DefaultHandler { return Ok(HttpResponse::NotFound().json(json!({ "error": "该 plural 不存在,请检查 plural 版本以及是否需要 namespace" }))); } + let mut model_map = HashMap::new(); + let kind = get_value(&*plural.clone()).unwrap(); + + model_map.insert("MODEL".to_string(), kind); + // request消息 let request_message = Message::new( "REMOVE".to_string(), message::NativeEventAction::Other, - None, + Some(model_map), Some(ApiServerMessage { content: name.clone(), }), None, ); - tokio::spawn(send_request(request_message, nats_cli)); + send_request(request_message, nats_cli).await.map_err(ErrorInternalServerError)?; let deleted = delete_from_table(db_connection, &plural, &name, &ver, None) .await @@ -1051,17 +1122,22 @@ impl Handler for DefaultHandler { return Ok(HttpResponse::NotFound().json(json!({ "error": "该 plural 不存在,请检查 plural 版本以及是否需要 namespace" }))); } + let mut model_map = HashMap::new(); + let kind = get_value(&*plural.clone()).unwrap(); + + model_map.insert("MODEL".to_string(), kind); + // request消息 let request_message = Message::new( "REMOVE".to_string(), message::NativeEventAction::Other, - None, + Some(model_map), Some(ApiServerMessage { content: name.clone(), }), None, ); - tokio::spawn(send_request(request_message, nats_cli)); + send_request(request_message, nats_cli).await.map_err(ErrorInternalServerError)?; let deleted = delete_from_table(db_connection, &plural, &name, &ver, Some(&namespace)) .await @@ -1512,7 +1588,8 @@ mod tests { } } })) - .route("/api/{version}/namespaces/{namespace}/{plural}/{name}", web::get().to( + .route("/api/{version}/namespaces/{namespace}/{plural}/{name}", web::get().to({ + let nats_cli = Arc::clone(&nats_cli); move |path, data| { let handler = HANDLER.clone(); let db_pool = DB_POOL.clone(); @@ -1525,7 +1602,7 @@ mod tests { } } } - )) + })) .route("/api/{version}/namespaces/{namespace}/{plural}", web::get().to({ let nats_cli = Arc::clone(&nats_cli); move |path, data| { diff --git a/src/lib.rs b/src/lib.rs index 60932e1..c219ec4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,2 +1,33 @@ pub mod cores; -pub mod schema; \ No newline at end of file +pub mod schema; + +use cores::apiserver::ApiServer; +use cores::config::DefaultConfig; +use cores::handlers::DefaultHandler; +use cores::db::DbPool; +use std::sync::Arc; +use env_logger; + + +/// 启动 Web 服务器 +/// +/// # 参数 +/// - `database_url`: 数据库连接字符串 +/// - `address`: 服务监听地址(如 "0.0.0.0:8080") +/// +/// # 返回值 +/// - 异步运行结果 +pub async fn start_server(database_url: &str, address: &str) -> Result<(), Box> { + // 创建数据库连接池 + let db_pool = Arc::new(DbPool::new(database_url)?); + + // 初始化日志 + env_logger::init(); + + // 配置和启动服务器 + let config = Box::new(DefaultConfig::new()); + let server = ApiServer::new(config); + let handler: DefaultHandler = DefaultHandler::new(); + server.start(address, handler, db_pool).await?; + Ok(()) +} diff --git a/src/main.rs b/src/main.rs index a9aba48..1a6664d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,39 +1,17 @@ - -/** - * Copyright (2024, ) Institute of Software, Chinese Academy of Sciences - * author: wuheng@iscas.ac.cn - * since: 0.1.0 - * -**/ - -use k8s_apiserver::cores::apiserver::ApiServer; -use k8s_apiserver::cores::config::DefaultConfig; -use k8s_apiserver::cores::handlers::DefaultHandler; -use std::sync::{Arc}; -use env_logger; -use dotenv::dotenv; use std::env; -use k8s_apiserver::cores::db::DbPool; +use dotenv::dotenv; +use k8s_apiserver::start_server; #[actix_web::main] -async fn main() -{ +async fn main() { dotenv().ok(); + // 从环境变量读取配置 let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set"); - // 创建连接池 - let db_pool = Arc::new(DbPool::new(&database_url).expect("Failed to create database pool")); - - env_logger::init(); - - start(db_pool).await; + let address = "0.0.0.0:8080"; // 或者通过环境变量或配置文件读取 + // 启动服务 + if let Err(e) = start_server(&database_url, address).await { + eprintln!("Failed to start server: {}", e); + } } - -async fn start(db_pool: Arc) { - let config = Box::new(DefaultConfig::new()); - let server = ApiServer::new(config); - let handler: DefaultHandler = DefaultHandler::new(); - - let _ = Arc::new(server).start("0.0.0.0:8080", handler, db_pool).await; -} \ No newline at end of file -- Gitee From 1e10a4e7dd9df47b7ed19c79c50f6c82075bdfa1 Mon Sep 17 00:00:00 2001 From: Yuichi <913637919@qq.com> Date: Mon, 25 Nov 2024 07:30:24 +0000 Subject: [PATCH 27/48] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=83=A8=E5=88=86?= =?UTF-8?q?=E5=87=BD=E6=95=B0=E5=AE=9A=E4=B9=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.lock | 50 +++++++++++++++++++++++++------------------------- Cargo.toml | 2 +- src/lib.rs | 2 ++ 3 files changed, 28 insertions(+), 26 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 65008bb..eef6a1c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -916,31 +916,6 @@ dependencies = [ "miniz_oxide", ] -[[package]] -name = "fleet_apiserver" -version = "0.1.0" -dependencies = [ - "actix-http", - "actix-service", - "actix-web", - "async-trait", - "chrono", - "diesel", - "diesel_migrations", - "dotenv", - "env_logger", - "feventbus", - "jsonschema", - "k8s-openapi", - "lazy_static", - "once_cell", - "r2d2", - "schemars", - "serde", - "serde_json", - "tokio", -] - [[package]] name = "fluent-uri" version = "0.3.2" @@ -1492,6 +1467,31 @@ dependencies = [ "serde_json", ] +[[package]] +name = "k8s_apiserver" +version = "0.1.0" +dependencies = [ + "actix-http", + "actix-service", + "actix-web", + "async-trait", + "chrono", + "diesel", + "diesel_migrations", + "dotenv", + "env_logger", + "feventbus", + "jsonschema", + "k8s-openapi", + "lazy_static", + "once_cell", + "r2d2", + "schemars", + "serde", + "serde_json", + "tokio", +] + [[package]] name = "language-tags" version = "0.3.2" diff --git a/Cargo.toml b/Cargo.toml index 0a37ef1..38fb21c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "fleet_apiserver" +name = "k8s_apiserver" version = "0.1.0" license = "Apache-2.0" authors = ["wuheng ", "chenhongyu23@otcaix.iscas.ac.cn"] diff --git a/src/lib.rs b/src/lib.rs index c219ec4..d02e6db 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -31,3 +31,5 @@ pub async fn start_server(database_url: &str, address: &str) -> Result<(), Box Date: Mon, 25 Nov 2024 07:33:07 +0000 Subject: [PATCH 28/48] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=83=A8=E5=88=86?= =?UTF-8?q?=E5=87=BD=E6=95=B0=E5=AE=9A=E4=B9=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/lib.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index d02e6db..cdbf155 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -28,8 +28,7 @@ pub async fn start_server(database_url: &str, address: &str) -> Result<(), Box Date: Mon, 25 Nov 2024 07:36:15 +0000 Subject: [PATCH 29/48] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=A1=B9=E7=9B=AE?= =?UTF-8?q?=E5=90=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.lock | 50 +++++++++++++++++++++++++------------------------- Cargo.toml | 2 +- src/main.rs | 2 +- 3 files changed, 27 insertions(+), 27 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index eef6a1c..65008bb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -916,6 +916,31 @@ dependencies = [ "miniz_oxide", ] +[[package]] +name = "fleet_apiserver" +version = "0.1.0" +dependencies = [ + "actix-http", + "actix-service", + "actix-web", + "async-trait", + "chrono", + "diesel", + "diesel_migrations", + "dotenv", + "env_logger", + "feventbus", + "jsonschema", + "k8s-openapi", + "lazy_static", + "once_cell", + "r2d2", + "schemars", + "serde", + "serde_json", + "tokio", +] + [[package]] name = "fluent-uri" version = "0.3.2" @@ -1467,31 +1492,6 @@ dependencies = [ "serde_json", ] -[[package]] -name = "k8s_apiserver" -version = "0.1.0" -dependencies = [ - "actix-http", - "actix-service", - "actix-web", - "async-trait", - "chrono", - "diesel", - "diesel_migrations", - "dotenv", - "env_logger", - "feventbus", - "jsonschema", - "k8s-openapi", - "lazy_static", - "once_cell", - "r2d2", - "schemars", - "serde", - "serde_json", - "tokio", -] - [[package]] name = "language-tags" version = "0.3.2" diff --git a/Cargo.toml b/Cargo.toml index 38fb21c..0a37ef1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "k8s_apiserver" +name = "fleet_apiserver" version = "0.1.0" license = "Apache-2.0" authors = ["wuheng ", "chenhongyu23@otcaix.iscas.ac.cn"] diff --git a/src/main.rs b/src/main.rs index 1a6664d..4ad7338 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,6 @@ use std::env; use dotenv::dotenv; -use k8s_apiserver::start_server; +use fleet_apiserver::start_server; #[actix_web::main] async fn main() { -- Gitee From d019ea611a2fa014d36ec4fbd27f7b28867e5f18 Mon Sep 17 00:00:00 2001 From: Yuichi <913637919@qq.com> Date: Mon, 25 Nov 2024 07:47:35 +0000 Subject: [PATCH 30/48] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=83=A8=E5=88=86?= =?UTF-8?q?=E5=87=BD=E6=95=B0=E5=AE=9A=E4=B9=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/cores/handlers.rs | 8 ++++---- src/main.rs | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/cores/handlers.rs b/src/cores/handlers.rs index 6cb9b01..ce370a2 100644 --- a/src/cores/handlers.rs +++ b/src/cores/handlers.rs @@ -989,7 +989,7 @@ impl Handler for DefaultHandler { // request消息 let request_message = Message::new( - "REMOVE".to_string(), + "DELETE".to_string(), message::NativeEventAction::Other, Some(model_map), Some(ApiServerMessage { @@ -1036,7 +1036,7 @@ impl Handler for DefaultHandler { // request消息 let request_message = Message::new( - "REMOVE".to_string(), + "DELETE".to_string(), message::NativeEventAction::Other, Some(model_map), Some(ApiServerMessage { @@ -1083,7 +1083,7 @@ impl Handler for DefaultHandler { // request消息 let request_message = Message::new( - "REMOVE".to_string(), + "DELETE".to_string(), message::NativeEventAction::Other, Some(model_map), Some(ApiServerMessage { @@ -1129,7 +1129,7 @@ impl Handler for DefaultHandler { // request消息 let request_message = Message::new( - "REMOVE".to_string(), + "DELETE".to_string(), message::NativeEventAction::Other, Some(model_map), Some(ApiServerMessage { diff --git a/src/main.rs b/src/main.rs index 4ad7338..d20e3b9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,7 +8,7 @@ async fn main() { // 从环境变量读取配置 let database_url = env::var("DATABASE_URL").expect("DATABASE_URL must be set"); - let address = "0.0.0.0:8080"; // 或者通过环境变量或配置文件读取 + let address = "0.0.0.0:8080"; // 启动服务 if let Err(e) = start_server(&database_url, address).await { -- Gitee From 5127cc881eb8570bb40d6f9ca1012e86c13af4ce Mon Sep 17 00:00:00 2001 From: Yuichi <913637919@qq.com> Date: Mon, 25 Nov 2024 07:49:02 +0000 Subject: [PATCH 31/48] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 65008bb..616cd06 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -918,7 +918,7 @@ dependencies = [ [[package]] name = "fleet_apiserver" -version = "0.1.0" +version = "0.2.0" dependencies = [ "actix-http", "actix-service", diff --git a/Cargo.toml b/Cargo.toml index 0a37ef1..856e098 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "fleet_apiserver" -version = "0.1.0" +version = "0.2.0" license = "Apache-2.0" authors = ["wuheng ", "chenhongyu23@otcaix.iscas.ac.cn"] categories = ["api-bindings"] -- Gitee From 1298ea0f66da29e5094ebc5a649cc705c741b860 Mon Sep 17 00:00:00 2001 From: Yuichi <913637919@qq.com> Date: Tue, 26 Nov 2024 08:13:22 +0000 Subject: [PATCH 32/48] =?UTF-8?q?=E6=89=80=E6=9C=89=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=AD=98=E5=82=A8=E5=88=B0kine=E8=A1=A8=E5=86=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../down.sql | 3 +- .../up.sql | 11 + src/cores/db.rs | 15 - src/cores/handlers.rs | 405 +++++++++++++----- src/schema.rs | 19 +- 5 files changed, 320 insertions(+), 133 deletions(-) diff --git a/migrations/2024-11-03-082237_create_metadata_table/down.sql b/migrations/2024-11-03-082237_create_metadata_table/down.sql index d3c389a..55d1278 100644 --- a/migrations/2024-11-03-082237_create_metadata_table/down.sql +++ b/migrations/2024-11-03-082237_create_metadata_table/down.sql @@ -1,2 +1,3 @@ -- This file should undo anything in `up.sql` -DROP TABLE IF EXISTS metadata; \ No newline at end of file +DROP TABLE IF EXISTS metadata; +DROP TABLE IF EXISTS kine; \ No newline at end of file diff --git a/migrations/2024-11-03-082237_create_metadata_table/up.sql b/migrations/2024-11-03-082237_create_metadata_table/up.sql index e89b705..5515cb3 100644 --- a/migrations/2024-11-03-082237_create_metadata_table/up.sql +++ b/migrations/2024-11-03-082237_create_metadata_table/up.sql @@ -7,4 +7,15 @@ CREATE TABLE IF NOT EXISTS metadata ( created_time VARCHAR(256), updated_time VARCHAR(256), PRIMARY KEY (name, namespace, apigroup) + ); + +CREATE TABLE IF NOT EXISTS kine ( + kind VARCHAR(256), + name VARCHAR(256), + namespace VARCHAR(256), + apigroup VARCHAR(256), + data TEXT, + created_time VARCHAR(256), + updated_time VARCHAR(256), + PRIMARY KEY (kind, name, namespace, apigroup) ); \ No newline at end of file diff --git a/src/cores/db.rs b/src/cores/db.rs index 33b5c67..1a888dd 100644 --- a/src/cores/db.rs +++ b/src/cores/db.rs @@ -116,19 +116,6 @@ impl DbPool { for (table_name, (supports_namespace, template)) in templates.iter() { - let create_table_query = format!( - "CREATE TABLE IF NOT EXISTS {} ( - name VARCHAR(256), - namespace VARCHAR(256), - apigroup VARCHAR(256), - data TEXT, - created_time VARCHAR(256), - updated_time VARCHAR(256), - PRIMARY KEY (name, namespace, apigroup) - );", - table_name - ); - // 从模板中提取 `apiVersion` 字段作为 `apigroup` let apigroup = template.get("apiVersion") .and_then(Value::as_str) @@ -147,11 +134,9 @@ impl DbPool { match conn { DbConnection::Pg(pg_conn) => { - sql_query(create_table_query).execute(pg_conn)?; sql_query(insert_metadata_query).execute(pg_conn)?; }, DbConnection::Sqlite(sqlite_conn) => { - sql_query(create_table_query).execute(sqlite_conn)?; sql_query(insert_metadata_query).execute(sqlite_conn)?; } } diff --git a/src/cores/handlers.rs b/src/cores/handlers.rs index ce370a2..3cf3524 100644 --- a/src/cores/handlers.rs +++ b/src/cores/handlers.rs @@ -14,7 +14,6 @@ use actix_web::error::ErrorInternalServerError; use feventbus::impls::nats::nats::NatsCli; use feventbus::message::Message; use feventbus::message; -use feventbus::traits::consumer::{Consumer}; use feventbus::traits::producer::Producer; use serde::{Deserialize, Serialize}; use cores::apiserver::ApiServerMessage; @@ -269,34 +268,60 @@ async fn check_metadata( } -// 创建新的数据表 -async fn create_table_if_not_exists(conn: &mut DbConnection, table_name: &str) -> QueryResult<()> { - - let create_query = format!( - "CREATE TABLE IF NOT EXISTS {} ( - name VARCHAR(256), - namespace VARCHAR(256), - apigroup VARCHAR(256), - data TEXT, - created_time VARCHAR(256), - updated_time VARCHAR(256), - PRIMARY KEY (name, namespace, apigroup) - )", - table_name - ); +// 查询 kine 表中指定的数据是否存在 +async fn check_kine( + conn: &mut DbConnection, + item_kind: &str, + item_name: &str, + item_version: &str, + item_namespace: Option<&str>, +) -> QueryResult { + use diesel::dsl::count_star; + use crate::schema::kine::dsl::*; + let count; match conn { DbConnection::Pg(pg_conn) => { - diesel::sql_query(create_query).execute(pg_conn)?; + if let Some(_) = item_namespace { + count = kine + .filter(kind.eq(item_kind)) + .filter(name.eq(item_name)) + .filter(apigroup.eq(item_version)) + .filter(namespace.eq(item_namespace)) + .select(count_star()) + .first::(pg_conn)?; + } else { + count = kine + .filter(kind.eq(item_kind)) + .filter(name.eq(item_name)) + .filter(apigroup.eq(item_version)) + .select(count_star()) + .first::(pg_conn)?; + } }, DbConnection::Sqlite(sqlite_conn) => { - diesel::sql_query(create_query).execute(sqlite_conn)?; + if let Some(_) = item_namespace { + count = kine + .filter(kind.eq(item_kind)) + .filter(name.eq(item_name)) + .filter(apigroup.eq(item_version)) + .filter(namespace.eq(item_namespace)) + .select(count_star()) + .first::(sqlite_conn)?; + } else { + count = kine + .filter(kind.eq(item_kind)) + .filter(name.eq(item_name)) + .filter(apigroup.eq(item_version)) + .select(count_star()) + .first::(sqlite_conn)?; + } } } - - Ok(()) + Ok(count > 0) } + // 在 metadata 表中插入新记录 async fn insert_metadata( conn: &mut DbConnection, @@ -340,26 +365,18 @@ async fn insert_metadata( // 插入数据到指定的表 async fn insert_into_table( conn: &mut DbConnection, - table_name: &str, + item_kind: &str, + item_name: &str, json_data: &Value, version: &str, namespace: Option<&str>, ) -> QueryResult<()> { match conn { DbConnection::Pg(pg_conn) => { - // 从 json_data 中提取 metadata.name - let name = json_data - .get("metadata") - .and_then(|metadata| metadata.get("name")) - .and_then(|name| name.as_str()) - .unwrap_or("error"); - - let insert_query = format!( - "INSERT INTO {} (name, namespace, apigroup, data, created_time, updated_time) VALUES ($1, $2, $3, $4, $5, $6)", - table_name - ); + let insert_query = "INSERT INTO kine (kind, name, namespace, apigroup, data, created_time, updated_time) VALUES ($1, $2, $3, $4, $5, $6, $7)".to_string(); diesel::sql_query(insert_query) - .bind::(name) + .bind::(item_kind) + .bind::(item_name) .bind::(namespace.unwrap_or("")) .bind::(version) .bind::(json_data.to_string()) // 将 JSON 数据存储为 TEXT @@ -368,19 +385,10 @@ async fn insert_into_table( .execute(pg_conn)?; }, DbConnection::Sqlite(sqlite_conn) => { - // 从 json_data 中提取 metadata.name - let name = json_data - .get("metadata") - .and_then(|metadata| metadata.get("name")) - .and_then(|name| name.as_str()) - .unwrap_or("error"); - - let insert_query = format!( - "INSERT INTO {} (name, namespace, apigroup, data, created_time, updated_time) VALUES (?, ?, ?, ?, ?, ?)", - table_name - ); + let insert_query = "INSERT INTO kine (kind, name, namespace, apigroup, data, created_time, updated_time) VALUES (?, ?, ?, ?, ?, ?)".to_string(); diesel::sql_query(insert_query) - .bind::(name) + .bind::(item_kind) + .bind::(item_name) .bind::(namespace.unwrap_or("")) .bind::(version) .bind::(json_data.to_string()) // 将 JSON 数据存储为 TEXT @@ -395,7 +403,7 @@ async fn insert_into_table( // 从 plural 表中删除特定 name 的记录 async fn delete_from_table( conn: &mut DbConnection, - table_name: &str, + item_kind: &str, item_name: &str, item_version: &str, item_namespace: Option<&str>, @@ -403,13 +411,13 @@ async fn delete_from_table( // 根据是否存在 namespace 动态构建删除查询 let delete_query = if let Some(_) = item_namespace { match conn { - DbConnection::Pg(_) => format!("DELETE FROM {} WHERE name = $1 AND namespace = $2 AND apigroup = $3", table_name), - DbConnection::Sqlite(_) => format!("DELETE FROM {} WHERE name = ? AND namespace = ? AND apigroup = ?", table_name), + DbConnection::Pg(_) => "DELETE FROM kine WHERE kind = $1 AND name = $2 AND namespace = $3 AND apigroup = $4".to_string(), + DbConnection::Sqlite(_) => "DELETE FROM kine WHERE kind = ? AND name = ? AND namespace = ? AND apigroup = ?".to_string(), } } else { match conn { - DbConnection::Pg(_) => format!("DELETE FROM {} WHERE name = $1 AND apigroup = $2", table_name), - DbConnection::Sqlite(_) => format!("DELETE FROM {} WHERE name = ? AND apigroup = ?", table_name), + DbConnection::Pg(_) => "DELETE FROM kine WHERE kind = $1 AND name = $2 AND apigroup = $3".to_string(), + DbConnection::Sqlite(_) => "DELETE FROM kine WHERE kind = ? AND name = ? AND apigroup = ?".to_string(), } }; @@ -418,12 +426,14 @@ async fn delete_from_table( DbConnection::Pg(pg_conn) => { if let Some(namespace) = item_namespace { diesel::sql_query(delete_query) + .bind::(item_kind) .bind::(item_name) .bind::(namespace) .bind::(item_version) .execute(pg_conn)? } else { diesel::sql_query(delete_query) + .bind::(item_kind) .bind::(item_name) .bind::(item_version) .execute(pg_conn)? @@ -432,12 +442,14 @@ async fn delete_from_table( DbConnection::Sqlite(sqlite_conn) => { if let Some(namespace) = item_namespace { diesel::sql_query(delete_query) + .bind::(item_kind) .bind::(item_name) .bind::(namespace) .bind::(item_version) .execute(sqlite_conn)? } else { diesel::sql_query(delete_query) + .bind::(item_kind) .bind::(item_name) .bind::(item_version) .execute(sqlite_conn)? @@ -450,7 +462,7 @@ async fn delete_from_table( async fn update_data_in_table( conn: &mut DbConnection, - table_name: &str, + item_kind: &str, item_name: &str, item_version: &str, item_namespace: Option<&str>, @@ -459,13 +471,13 @@ async fn update_data_in_table( let update_query = if let Some(_) = item_namespace { match conn { - DbConnection::Pg(_) => format!("UPDATE {} SET data = $1, updated_time = $2 WHERE name = $3 AND namespace = $4 AND apigroup = $5", table_name), - DbConnection::Sqlite(_) => format!("UPDATE {} SET data = ?, updated_time = ? WHERE name = ? AND namespace = ? AND apigroup = ?", table_name), + DbConnection::Pg(_) => "UPDATE kine SET data = $1, updated_time = $2 WHERE kind = $3 AND name = $4 AND namespace = $5 AND apigroup = $6".to_string(), + DbConnection::Sqlite(_) => "UPDATE kine SET data = ?, updated_time = ? WHERE kind = ? AND name = ? AND namespace = ? AND apigroup = ?".to_string(), } } else { match conn { - DbConnection::Pg(_) => format!("UPDATE {} SET data = $1, updated_time = $2 WHERE name = $3 AND apigroup = $4", table_name), - DbConnection::Sqlite(_) => format!("UPDATE {} SET data = ?, updated_time = ? WHERE name = ? AND apigroup = ?", table_name), + DbConnection::Pg(_) => "UPDATE kine SET data = $1, updated_time = $2 WHERE kind = $3 AND name = $4 AND apigroup = $5".to_string(), + DbConnection::Sqlite(_) => "UPDATE kine SET data = ?, updated_time = ? WHERE kind = ? AND name = ? AND apigroup = ?".to_string(), } }; @@ -475,6 +487,7 @@ async fn update_data_in_table( diesel::sql_query(update_query) .bind::(json_data.to_string()) .bind::(Utc::now().naive_utc().to_string()) + .bind::(item_kind) .bind::(item_name) .bind::(namespace) .bind::(item_version) @@ -483,6 +496,7 @@ async fn update_data_in_table( diesel::sql_query(update_query) .bind::(json_data.to_string()) .bind::(Utc::now().naive_utc().to_string()) + .bind::(item_kind) .bind::(item_name) .bind::(item_version) .execute(pg_conn)? @@ -493,6 +507,7 @@ async fn update_data_in_table( diesel::sql_query(update_query) .bind::(json_data.to_string()) .bind::(Utc::now().naive_utc().to_string()) + .bind::(item_kind) .bind::(item_name) .bind::(namespace) .bind::(item_version) @@ -501,6 +516,7 @@ async fn update_data_in_table( diesel::sql_query(update_query) .bind::(json_data.to_string()) .bind::(Utc::now().naive_utc().to_string()) + .bind::(item_kind) .bind::(item_name) .bind::(item_version) .execute(sqlite_conn)? @@ -520,20 +536,20 @@ struct DataResult { async fn get_data_from_table( conn: &mut DbConnection, - table_name: &str, + item_kind: &str, item_name: &str, item_version: &str, item_namespace: Option<&str>, ) -> QueryResult> { let select_query = if let Some(_) = item_namespace { match conn { - DbConnection::Pg(_) => format!("SELECT data FROM {} WHERE name = $1 AND namespace = $2 AND apigroup = $3", table_name), - DbConnection::Sqlite(_) => format!("SELECT data FROM {} WHERE name = ? AND namespace = ? AND apigroup = ?", table_name), + DbConnection::Pg(_) => "SELECT data FROM kine WHERE kind = $1 AND name = $2 AND namespace = $3 AND apigroup = $4".to_string(), + DbConnection::Sqlite(_) => "SELECT data FROM kine WHERE kind = ? AND name = ? AND namespace = ? AND apigroup = ?".to_string(), } } else { match conn { - DbConnection::Pg(_) => format!("SELECT data FROM {} WHERE name = $1 AND apigroup = $2", table_name), - DbConnection::Sqlite(_) => format!("SELECT data FROM {} WHERE name = ? AND apigroup = ?", table_name), + DbConnection::Pg(_) => "SELECT data FROM kine WHERE kind = $1 AND name = $2 AND apigroup = $3".to_string(), + DbConnection::Sqlite(_) => "SELECT data FROM kine WHERE kind = ? AND name = ? AND apigroup = ?".to_string(), } }; @@ -541,6 +557,7 @@ async fn get_data_from_table( DbConnection::Pg(pg_conn) => { if let Some(namespace) = item_namespace { diesel::sql_query(select_query) + .bind::(item_kind) .bind::(item_name) .bind::(namespace) .bind::(item_version) @@ -549,6 +566,7 @@ async fn get_data_from_table( .map(|res| res.map(|data_result| data_result.data)) } else { diesel::sql_query(select_query) + .bind::(item_kind) .bind::(item_name) .bind::(item_version) .get_result::(pg_conn) @@ -559,6 +577,7 @@ async fn get_data_from_table( DbConnection::Sqlite(sqlite_conn) => { if let Some(namespace) = item_namespace { diesel::sql_query(select_query) + .bind::(item_kind) .bind::(item_name) .bind::(namespace) .bind::(item_version) @@ -567,6 +586,7 @@ async fn get_data_from_table( .map(|res| res.map(|data_result| data_result.data)) } else { diesel::sql_query(select_query) + .bind::(item_kind) .bind::(item_name) .bind::(item_version) .get_result::(sqlite_conn) @@ -581,19 +601,19 @@ async fn get_data_from_table( // 辅助函数:从指定表中获取所有符合条件的数据的 `data` 字段 async fn get_all_data_from_table( conn: &mut DbConnection, - table_name: &str, + item_kind: &str, item_version: &str, item_namespace: Option<&str>, ) -> QueryResult> { let select_query = if let Some(_) = item_namespace { match conn { - DbConnection::Pg(_) => format!("SELECT data FROM {} WHERE namespace = $1 AND apigroup = $2", table_name), - DbConnection::Sqlite(_) => format!("SELECT data FROM {} WHERE namespace = ? AND apigroup = ?", table_name), + DbConnection::Pg(_) => "SELECT data FROM kine WHERE kind = $1 AND namespace = $2 AND apigroup = $3".to_string(), + DbConnection::Sqlite(_) => "SELECT data FROM kine WHERE kind = ? AND namespace = ? AND apigroup = ?".to_string(), } } else { match conn { - DbConnection::Pg(_) => format!("SELECT data FROM {} WHERE apigroup = $1", table_name), - DbConnection::Sqlite(_) => format!("SELECT data FROM {} WHERE apigroup = ?", table_name), + DbConnection::Pg(_) => "SELECT data FROM kine WHERE kind = $1 AND apigroup = $2".to_string(), + DbConnection::Sqlite(_) => "SELECT data FROM kine WHERE kind = ? AND apigroup = ?".to_string(), } }; @@ -601,12 +621,14 @@ async fn get_all_data_from_table( DbConnection::Pg(pg_conn) => { if let Some(namespace) = item_namespace { diesel::sql_query(select_query) + .bind::(item_kind) .bind::(namespace) .bind::(item_version) .load::(pg_conn) .map(|results| results.into_iter().map(|res| res.data).collect()) } else { diesel::sql_query(select_query) + .bind::(item_kind) .bind::(item_version) .load::(pg_conn) .map(|results| results.into_iter().map(|res| res.data).collect()) @@ -615,12 +637,14 @@ async fn get_all_data_from_table( DbConnection::Sqlite(sqlite_conn) => { if let Some(namespace) = item_namespace { diesel::sql_query(select_query) + .bind::(item_kind) .bind::(namespace) .bind::(item_version) .load::(sqlite_conn) .map(|results| results.into_iter().map(|res| res.data).collect()) } else { diesel::sql_query(select_query) + .bind::(item_kind) .bind::(item_version) .load::(sqlite_conn) .map(|results| results.into_iter().map(|res| res.data).collect()) @@ -664,14 +688,14 @@ impl Handler for DefaultHandler { //判断是正常的插入函数还是 crd 资源的注册函数 if plural == "crds" { - let table_name = data + let item_kind = data .get("spec") .and_then(|spec| spec.get("names")) .and_then(|names| names.get("plural")) .and_then(|plural| plural.as_str()) .unwrap_or("error"); - let crd_kind = data + let kind_upper = data .get("spec") .and_then(|spec| spec.get("names")) .and_then(|names| names.get("kind")) @@ -679,21 +703,17 @@ impl Handler for DefaultHandler { .unwrap_or("error"); // 调用check_metadata函数 - let metadata_exists = check_metadata(db_connection, table_name, &version,false).await.map_err(ErrorInternalServerError)?; + let metadata_exists = check_metadata(db_connection, item_kind, &version,false).await.map_err(ErrorInternalServerError)?; if metadata_exists { return Ok(HttpResponse::NotFound().json(json!({ "error": "该 crd 资源已存在,无需重复注册" }))); } - create_table_if_not_exists(db_connection, table_name) - .await - .map_err(ErrorInternalServerError)?; - - insert_metadata(db_connection, table_name, &version, false, &data) + insert_metadata(db_connection, item_kind, &version, false, &data) .await .map_err(ErrorInternalServerError)?; - insert_key_value(table_name, crd_kind); + insert_key_value(item_kind, kind_upper); } else { // 调用check_metadata函数 let metadata_exists = check_metadata(db_connection, &plural, &version,false).await.map_err(ErrorInternalServerError)?; @@ -702,6 +722,19 @@ impl Handler for DefaultHandler { return Ok(HttpResponse::NotFound().json(json!({ "error": "该 plural 不存在,请重新注册或检查 plural 版本以及是否需要 namespace" }))); } + // 从 json_data 中提取 metadata.name + let item_name = data + .get("metadata") + .and_then(|metadata| metadata.get("name")) + .and_then(|name| name.as_str()) + .unwrap_or("error"); + + let kine_exists = check_kine(db_connection, &plural, item_name, &version, None).await.map_err(ErrorInternalServerError)?; + + if kine_exists { + return Ok(HttpResponse::InternalServerError().json(json!({ "error": "该资源已存在,请勿重复创建" }))); + } + let mut model_map = HashMap::new(); let kind = get_value(&*plural.clone()).unwrap(); @@ -720,7 +753,7 @@ impl Handler for DefaultHandler { send_request(request_message, nats_cli).await.map_err(ErrorInternalServerError)?; - insert_into_table(db_connection, &plural, &data, &version, None) + insert_into_table(db_connection, &plural, item_name, &data, &version, None) .await .map_err(ErrorInternalServerError)?; } @@ -740,14 +773,14 @@ impl Handler for DefaultHandler { //判断是正常的插入函数还是 crd 资源的注册函数 if plural == "crds" { - let table_name = data + let item_kind = data .get("spec") .and_then(|spec| spec.get("names")) .and_then(|names| names.get("plural")) .and_then(|plural| plural.as_str()) .unwrap_or("error"); - let crd_kind = data + let kind_upper = data .get("spec") .and_then(|spec| spec.get("names")) .and_then(|names| names.get("kind")) @@ -755,22 +788,17 @@ impl Handler for DefaultHandler { .unwrap_or("error"); // 调用check_metadata函数 - let metadata_exists = check_metadata(db_connection, table_name, &version, true).await.map_err(ErrorInternalServerError)?; + let metadata_exists = check_metadata(db_connection, item_kind, &version, true).await.map_err(ErrorInternalServerError)?; if metadata_exists { return Ok(HttpResponse::NotFound().json(json!({ "error": "该 crd 资源已存在,无需重复注册" }))); } - - create_table_if_not_exists(db_connection, table_name) + insert_metadata(db_connection, item_kind, &version, false, &data) .await .map_err(ErrorInternalServerError)?; - insert_metadata(db_connection, table_name, &version, false, &data) - .await - .map_err(ErrorInternalServerError)?; - - insert_key_value(table_name, crd_kind); + insert_key_value(item_kind, kind_upper); } else { // 调用check_metadata函数 let metadata_exists = check_metadata(db_connection, &plural, &version, true).await.map_err(ErrorInternalServerError)?; @@ -779,6 +807,19 @@ impl Handler for DefaultHandler { return Ok(HttpResponse::NotFound().json(json!({ "error": "该 plural 不存在,请重新注册或检查 plural 版本以及是否需要 namespace" }))); } + // 从 json_data 中提取 metadata.name + let item_name = data + .get("metadata") + .and_then(|metadata| metadata.get("name")) + .and_then(|name| name.as_str()) + .unwrap_or("error"); + + let kine_exists = check_kine(db_connection, &plural, item_name, &version, Some(&namespace)).await.map_err(ErrorInternalServerError)?; + + if kine_exists { + return Ok(HttpResponse::InternalServerError().json(json!({ "error": "该资源已存在,请勿重复创建" }))); + } + let mut model_map = HashMap::new(); let kind = get_value(&*plural.clone()).unwrap(); @@ -797,7 +838,7 @@ impl Handler for DefaultHandler { send_request(request_message, nats_cli).await.map_err(ErrorInternalServerError)?; - insert_into_table(db_connection, &plural, &data, &version, Some(&namespace)) + insert_into_table(db_connection, &plural, item_name, &data, &version, Some(&namespace)) .await .map_err(ErrorInternalServerError)?; } @@ -819,14 +860,14 @@ impl Handler for DefaultHandler { //判断是正常的插入函数还是 crd 资源的注册函数 if plural == "crds" { - let table_name = data + let item_kind = data .get("spec") .and_then(|spec| spec.get("names")) .and_then(|names| names.get("plural")) .and_then(|plural| plural.as_str()) .unwrap_or("error"); - let crd_kind = data + let kind_upper = data .get("spec") .and_then(|spec| spec.get("names")) .and_then(|names| names.get("kind")) @@ -834,22 +875,17 @@ impl Handler for DefaultHandler { .unwrap_or("error"); // 调用check_metadata函数 - let metadata_exists = check_metadata(db_connection, table_name, &ver, false).await.map_err(ErrorInternalServerError)?; + let metadata_exists = check_metadata(db_connection, item_kind, &ver, false).await.map_err(ErrorInternalServerError)?; if metadata_exists { return Ok(HttpResponse::NotFound().json(json!({ "error": "该 crd 资源已存在,无需重复注册" }))); } - - create_table_if_not_exists(db_connection, table_name) - .await - .map_err(ErrorInternalServerError)?; - - insert_metadata(db_connection, table_name, &ver, false, &data) + insert_metadata(db_connection, item_kind, &ver, false, &data) .await .map_err(ErrorInternalServerError)?; - insert_key_value(table_name, crd_kind); + insert_key_value(item_kind, kind_upper); } else { // 调用check_metadata函数 let metadata_exists = check_metadata(db_connection, &plural, &ver, false).await.map_err(ErrorInternalServerError)?; @@ -858,6 +894,19 @@ impl Handler for DefaultHandler { return Ok(HttpResponse::NotFound().json(json!({ "error": "该 plural 不存在,请重新注册或检查 plural 版本以及是否需要 namespace" }))); } + // 从 json_data 中提取 metadata.name + let item_name = data + .get("metadata") + .and_then(|metadata| metadata.get("name")) + .and_then(|name| name.as_str()) + .unwrap_or("error"); + + let kine_exists = check_kine(db_connection, &plural, item_name, &ver, None).await.map_err(ErrorInternalServerError)?; + + if kine_exists { + return Ok(HttpResponse::InternalServerError().json(json!({ "error": "该资源已存在,请勿重复创建" }))); + } + let mut model_map = HashMap::new(); let kind = get_value(&*plural.clone()).unwrap(); @@ -876,7 +925,7 @@ impl Handler for DefaultHandler { send_request(request_message, nats_cli).await.map_err(ErrorInternalServerError)?; - insert_into_table(db_connection, &plural, &data, &ver, None) + insert_into_table(db_connection, &plural, item_name, &data, &ver, None) .await .map_err(ErrorInternalServerError)?; } @@ -899,14 +948,14 @@ impl Handler for DefaultHandler { //判断是正常的插入函数还是 crd 资源的注册函数 if plural == "crds" { - let table_name = data + let item_kind = data .get("spec") .and_then(|spec| spec.get("names")) .and_then(|names| names.get("plural")) .and_then(|plural| plural.as_str()) .unwrap_or("error"); - let crd_kind = data + let kind_upper = data .get("spec") .and_then(|spec| spec.get("names")) .and_then(|names| names.get("kind")) @@ -914,22 +963,17 @@ impl Handler for DefaultHandler { .unwrap_or("error"); // 调用 check_metadata 函数 - let metadata_exists = check_metadata(db_connection, table_name, &ver, true).await.map_err(ErrorInternalServerError)?; + let metadata_exists = check_metadata(db_connection, item_kind, &ver, true).await.map_err(ErrorInternalServerError)?; if metadata_exists { return Ok(HttpResponse::NotFound().json(json!({ "error": "该 crd 资源已存在,无需重复注册" }))); } - - create_table_if_not_exists(db_connection, table_name) + insert_metadata(db_connection, item_kind, &ver, false, &data) .await .map_err(ErrorInternalServerError)?; - insert_metadata(db_connection, table_name, &ver, false, &data) - .await - .map_err(ErrorInternalServerError)?; - - insert_key_value(table_name, crd_kind); + insert_key_value(item_kind, kind_upper); } else { // 调用 check_metadata 函数 let metadata_exists = check_metadata(db_connection, &plural, &ver, true).await.map_err(ErrorInternalServerError)?; @@ -938,6 +982,19 @@ impl Handler for DefaultHandler { return Ok(HttpResponse::NotFound().json(json!({ "error": "该 plural 不存在,请重新注册或检查 plural 版本以及是否需要 namespace" }))); } + // 从 json_data 中提取 metadata.name + let item_name = data + .get("metadata") + .and_then(|metadata| metadata.get("name")) + .and_then(|name| name.as_str()) + .unwrap_or("error"); + + let kine_exists = check_kine(db_connection, &plural, item_name, &ver, Some(&namespace)).await.map_err(ErrorInternalServerError)?; + + if kine_exists { + return Ok(HttpResponse::InternalServerError().json(json!({ "error": "该资源已存在,请勿重复创建" }))); + } + let mut model_map = HashMap::new(); let kind = get_value(&*plural.clone()).unwrap(); @@ -956,7 +1013,7 @@ impl Handler for DefaultHandler { send_request(request_message, nats_cli).await.map_err(ErrorInternalServerError)?; - insert_into_table(db_connection, &plural, &data, &ver, Some(&namespace)) + insert_into_table(db_connection, &plural, item_name, &data, &ver, Some(&namespace)) .await .map_err(ErrorInternalServerError)?; } @@ -982,6 +1039,12 @@ impl Handler for DefaultHandler { return Ok(HttpResponse::NotFound().json(json!({ "error": "该 plural 不存在,请检查 plural 版本以及是否需要 namespace" }))); } + let kine_exists = check_kine(db_connection, &plural, &name, &version, None).await.map_err(ErrorInternalServerError)?; + + if !kine_exists { + return Ok(HttpResponse::InternalServerError().json(json!({ "error": "指定数据不存在" }))); + } + let mut model_map = HashMap::new(); let kind = get_value(&*plural.clone()).unwrap(); @@ -1029,6 +1092,12 @@ impl Handler for DefaultHandler { return Ok(HttpResponse::NotFound().json(json!({ "error": "该 plural 不存在,请检查 plural 版本以及是否需要 namespace" }))); } + let kine_exists = check_kine(db_connection, &plural, &name, &version, Some(&namespace)).await.map_err(ErrorInternalServerError)?; + + if !kine_exists { + return Ok(HttpResponse::InternalServerError().json(json!({ "error": "指定数据不存在" }))); + } + let mut model_map = HashMap::new(); let kind = get_value(&*plural.clone()).unwrap(); @@ -1076,6 +1145,12 @@ impl Handler for DefaultHandler { return Ok(HttpResponse::NotFound().json(json!({ "error": "该 plural 不存在,请检查 plural 版本以及是否需要 namespace" }))); } + let kine_exists = check_kine(db_connection, &plural, &name, &ver, None).await.map_err(ErrorInternalServerError)?; + + if !kine_exists { + return Ok(HttpResponse::InternalServerError().json(json!({ "error": "指定数据不存在" }))); + } + let mut model_map = HashMap::new(); let kind = get_value(&*plural.clone()).unwrap(); @@ -1122,6 +1197,12 @@ impl Handler for DefaultHandler { return Ok(HttpResponse::NotFound().json(json!({ "error": "该 plural 不存在,请检查 plural 版本以及是否需要 namespace" }))); } + let kine_exists = check_kine(db_connection, &plural, &name, &ver, Some(&namespace)).await.map_err(ErrorInternalServerError)?; + + if !kine_exists { + return Ok(HttpResponse::InternalServerError().json(json!({ "error": "指定数据不存在" }))); + } + let mut model_map = HashMap::new(); let kind = get_value(&*plural.clone()).unwrap(); @@ -1168,6 +1249,29 @@ impl Handler for DefaultHandler { return Ok(HttpResponse::NotFound().json(json!({ "error": "该 plural 不存在,请检查 plural 版本以及是否需要 namespace" }))); } + let kine_exists = check_kine(db_connection, &plural, &name, &version, None).await.map_err(ErrorInternalServerError)?; + + if !kine_exists { + return Ok(HttpResponse::InternalServerError().json(json!({ "error": "指定数据不存在" }))); + } + + let mut model_map = HashMap::new(); + let kind = get_value(&*plural.clone()).unwrap(); + + model_map.insert("MODEL".to_string(), kind); + + // request消息 + let request_message = Message::new( + "UPDATE".to_string(), + message::NativeEventAction::Other, + Some(model_map), + Some(ApiServerMessage { + content: data.to_string(), + }), + None, + ); + send_request(request_message, nats_cli).await.map_err(ErrorInternalServerError)?; + // 查询 plural 表中是否存在 name 匹配的数据 let updated = update_data_in_table(db_connection, &plural, &name, &version, None, &data) .await @@ -1198,6 +1302,29 @@ impl Handler for DefaultHandler { return Ok(HttpResponse::NotFound().json(json!({ "error": "该 plural 不存在,请检查 plural 版本以及是否需要 namespace" }))); } + let kine_exists = check_kine(db_connection, &plural, &name, &version, Some(&namespace)).await.map_err(ErrorInternalServerError)?; + + if !kine_exists { + return Ok(HttpResponse::InternalServerError().json(json!({ "error": "指定数据不存在" }))); + } + + let mut model_map = HashMap::new(); + let kind = get_value(&*plural.clone()).unwrap(); + + model_map.insert("MODEL".to_string(), kind); + + // request消息 + let request_message = Message::new( + "UPDATE".to_string(), + message::NativeEventAction::Other, + Some(model_map), + Some(ApiServerMessage { + content: data.to_string(), + }), + None, + ); + send_request(request_message, nats_cli).await.map_err(ErrorInternalServerError)?; + let updated = update_data_in_table(db_connection, &plural, &name, &version, Some(&namespace), &data) .await .map_err(ErrorInternalServerError)?; @@ -1228,6 +1355,29 @@ impl Handler for DefaultHandler { return Ok(HttpResponse::NotFound().json(json!({ "error": "该 plural 不存在,请检查 plural 版本以及是否需要 namespace" }))); } + let kine_exists = check_kine(db_connection, &plural, &name, &ver, None).await.map_err(ErrorInternalServerError)?; + + if !kine_exists { + return Ok(HttpResponse::InternalServerError().json(json!({ "error": "指定数据不存在" }))); + } + + let mut model_map = HashMap::new(); + let kind = get_value(&*plural.clone()).unwrap(); + + model_map.insert("MODEL".to_string(), kind); + + // request消息 + let request_message = Message::new( + "UPDATE".to_string(), + message::NativeEventAction::Other, + Some(model_map), + Some(ApiServerMessage { + content: data.to_string(), + }), + None, + ); + send_request(request_message, nats_cli).await.map_err(ErrorInternalServerError)?; + let updated = update_data_in_table(db_connection, &plural, &name, &ver, None, &data) .await .map_err(ErrorInternalServerError)?; @@ -1258,6 +1408,29 @@ impl Handler for DefaultHandler { return Ok(HttpResponse::NotFound().json(json!({ "error": "该 plural 不存在,请检查 plural 版本以及是否需要 namespace" }))); } + let kine_exists = check_kine(db_connection, &plural, &name, &ver, Some(&namespace)).await.map_err(ErrorInternalServerError)?; + + if !kine_exists { + return Ok(HttpResponse::InternalServerError().json(json!({ "error": "指定数据不存在" }))); + } + + let mut model_map = HashMap::new(); + let kind = get_value(&*plural.clone()).unwrap(); + + model_map.insert("MODEL".to_string(), kind); + + // request消息 + let request_message = Message::new( + "UPDATE".to_string(), + message::NativeEventAction::Other, + Some(model_map), + Some(ApiServerMessage { + content: data.to_string(), + }), + None, + ); + send_request(request_message, nats_cli).await.map_err(ErrorInternalServerError)?; + let updated = update_data_in_table(db_connection, &plural, &name, &ver, Some(&namespace), &data) .await .map_err(ErrorInternalServerError)?; @@ -1275,7 +1448,7 @@ impl Handler for DefaultHandler { info: web::Path<(String, String, String)>, _data: web::Query, db_connection: &mut DbConnection, - nats_cli: Arc>, + _nats_cli: Arc>, ) -> Result { let (version, plural, name) = info.into_inner(); let metadata_exists = check_metadata(db_connection, &plural, &version, false) @@ -1304,7 +1477,7 @@ impl Handler for DefaultHandler { info: web::Path<(String, String, String, String)>, _data: web::Query, db_connection: &mut DbConnection, - nats_cli: Arc>, + _nats_cli: Arc>, ) -> Result { let (version, namespace, plural, name) = info.into_inner(); let metadata_exists = check_metadata(db_connection, &plural, &version, true) @@ -1333,7 +1506,7 @@ impl Handler for DefaultHandler { info: web::Path<(String, String, String, String)>, _data: web::Query, db_connection: &mut DbConnection, - nats_cli: Arc>, + _nats_cli: Arc>, ) -> Result { let (group, version, plural, name) = info.into_inner(); let ver = format!("{}/{}", group, version); @@ -1364,7 +1537,7 @@ impl Handler for DefaultHandler { info: web::Path<(String, String, String, String, String)>, _data: web::Query, db_connection: &mut DbConnection, - nats_cli: Arc>, + _nats_cli: Arc>, ) -> Result { let (group, version, namespace, plural, name) = info.into_inner(); let ver = format!("{}/{}", group, version); @@ -1395,7 +1568,7 @@ impl Handler for DefaultHandler { info: web::Path<(String, String)>, _data: web::Query, db_connection: &mut DbConnection, - nats_cli: Arc>, + _nats_cli: Arc>, ) -> Result { let (version, plural) = info.into_inner(); let metadata_exists = check_metadata(db_connection, &plural, &version, false) @@ -1425,7 +1598,7 @@ impl Handler for DefaultHandler { info: web::Path<(String, String, String)>, _data: web::Query, db_connection: &mut DbConnection, - nats_cli: Arc>, + _nats_cli: Arc>, ) -> Result { let (version, namespace, plural) = info.into_inner(); let metadata_exists = check_metadata(db_connection, &plural, &version, true) @@ -1455,7 +1628,7 @@ impl Handler for DefaultHandler { info: web::Path<(String, String, String)>, _data: web::Query, db_connection: &mut DbConnection, - nats_cli: Arc>, + _nats_cli: Arc>, ) -> Result { let (group, version, plural) = info.into_inner(); let ver = format!("{}/{}", group, version); @@ -1487,7 +1660,7 @@ impl Handler for DefaultHandler { info: web::Path<(String, String, String, String)>, _data: web::Query, db_connection: &mut DbConnection, - nats_cli: Arc>, + _nats_cli: Arc>, ) -> Result { let (group, version, namespace, plural) = info.into_inner(); let ver = format!("{}/{}", group, version); diff --git a/src/schema.rs b/src/schema.rs index 29ca975..687d79b 100644 --- a/src/schema.rs +++ b/src/schema.rs @@ -1,7 +1,19 @@ // @generated automatically by Diesel CLI. diesel::table! { - metadata (name) { + kine (kind, name, namespace, apigroup) { + kind -> Nullable, + name -> Nullable, + namespace -> Nullable, + apigroup -> Nullable, + data -> Nullable, + created_time -> Nullable, + updated_time -> Nullable, + } +} + +diesel::table! { + metadata (name, namespace, apigroup) { name -> Nullable, namespace -> Nullable, apigroup -> Nullable, @@ -10,3 +22,8 @@ diesel::table! { updated_time -> Nullable, } } + +diesel::allow_tables_to_appear_in_same_query!( + kine, + metadata, +); -- Gitee From a496f8498ff5761847e1a07415ff7fe367c48320 Mon Sep 17 00:00:00 2001 From: Yuichi <913637919@qq.com> Date: Tue, 26 Nov 2024 08:39:27 +0000 Subject: [PATCH 33/48] =?UTF-8?q?=E6=89=80=E6=9C=89=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=AD=98=E5=82=A8=E5=88=B0kine=E8=A1=A8=E5=86=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- database.sqlite | Bin 0 -> 28672 bytes src/cores/handlers.rs | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 database.sqlite diff --git a/database.sqlite b/database.sqlite new file mode 100644 index 0000000000000000000000000000000000000000..71aa76279a07eb61384b86c18b8cc0f393893d9c GIT binary patch literal 28672 zcmeI)?Qhyf90zbagoi{WG?gN>7f2^-(t<==%+nx!GlwvihLDapUE6804&zZejG663 zo4URT-T$z?-#@dreY@9ty%&46m-`*W4QX+s?!}~}-^0e|yR+}^V<(c&Hiuuf2EN6< zbzGbKtSH@-WLf%*F-el5G{00+UdZ(f34W?_` ztp*dRY;%=SplFXh)H?Mqw9aOsT*>C9$s=xCA<5pDn~U=Jc+hv9dx zJ2zd6`&Q5J2Ma4X9#i@7><69QeXaAD?KK{=P0{=u6Rn+nPaBtGL0huZ&SXD{#nSgS zWQht}KX~5{>DtTS$G$UNH-v_vitqU8Pmy>!laXKUP4#Tc=c4Vwa`}Q{ka{M0DcSbH zL93y)X9htF|5vTcobE2i()CQ3Q_x>S4Pw#LM{+!^Y4YUW)XOk>1Ix39hG#ytY;M?e zMsR=NjJ)uir3cRS?rE z^-E6uCDDWc0SG_<0uX=z1Rwwb2tWV=5P-n75Ll07S1t|-i2MJMWJXHeT-&Av0t6rc z0SG_<0uX=z1Rwx`4^v>GL=qb-nV02e^O@82y4*LP-aS#DEA-6#!`ZXn%9au&D>+5H z1VAbGoi42e&!#I|&y^wXT0@VrobEHr^eI<70Z;3m?+!+NjQ;GjhGj@9Q-JQ-kTTU6f&dH!>xw|{(siD0o zRf_Zp=}oCps;RY8TTXnmvOYO%HcfJL-rb$LDDp;s_-N$#vv&=sNtYk*Hx8cZ*fyV@ zMelL^7I&#!s}_s3MR)z_&{AflP@3NVkEC8nslQXNQh$D!f9B{l1Rwwb2tWV=5P$## zAOHafK;X&=+=|kOl{`OO6-h>Ed`3PSoLNdnX?$ZP7~Bx||LI5n5Fh{n2tWV=5P$## tAOHafKmY;|xW)qF{eN8lU*iLeu0a3-5P$##AOHafKmY;|fB*zY;9v0Y9$x?e literal 0 HcmV?d00001 diff --git a/src/cores/handlers.rs b/src/cores/handlers.rs index 3cf3524..a76d5e0 100644 --- a/src/cores/handlers.rs +++ b/src/cores/handlers.rs @@ -385,7 +385,7 @@ async fn insert_into_table( .execute(pg_conn)?; }, DbConnection::Sqlite(sqlite_conn) => { - let insert_query = "INSERT INTO kine (kind, name, namespace, apigroup, data, created_time, updated_time) VALUES (?, ?, ?, ?, ?, ?)".to_string(); + let insert_query = "INSERT INTO kine (kind, name, namespace, apigroup, data, created_time, updated_time) VALUES (?, ?, ?, ?, ?, ?, ?)".to_string(); diesel::sql_query(insert_query) .bind::(item_kind) .bind::(item_name) -- Gitee From 3c897da5279a7d26132c507ac3a71ade078d4f59 Mon Sep 17 00:00:00 2001 From: Yuichi <913637919@qq.com> Date: Tue, 26 Nov 2024 08:39:47 +0000 Subject: [PATCH 34/48] =?UTF-8?q?=E6=89=80=E6=9C=89=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=AD=98=E5=82=A8=E5=88=B0kine=E8=A1=A8=E5=86=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- database.sqlite | Bin 28672 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 database.sqlite diff --git a/database.sqlite b/database.sqlite deleted file mode 100644 index 71aa76279a07eb61384b86c18b8cc0f393893d9c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 28672 zcmeI)?Qhyf90zbagoi{WG?gN>7f2^-(t<==%+nx!GlwvihLDapUE6804&zZejG663 zo4URT-T$z?-#@dreY@9ty%&46m-`*W4QX+s?!}~}-^0e|yR+}^V<(c&Hiuuf2EN6< zbzGbKtSH@-WLf%*F-el5G{00+UdZ(f34W?_` ztp*dRY;%=SplFXh)H?Mqw9aOsT*>C9$s=xCA<5pDn~U=Jc+hv9dx zJ2zd6`&Q5J2Ma4X9#i@7><69QeXaAD?KK{=P0{=u6Rn+nPaBtGL0huZ&SXD{#nSgS zWQht}KX~5{>DtTS$G$UNH-v_vitqU8Pmy>!laXKUP4#Tc=c4Vwa`}Q{ka{M0DcSbH zL93y)X9htF|5vTcobE2i()CQ3Q_x>S4Pw#LM{+!^Y4YUW)XOk>1Ix39hG#ytY;M?e zMsR=NjJ)uir3cRS?rE z^-E6uCDDWc0SG_<0uX=z1Rwwb2tWV=5P-n75Ll07S1t|-i2MJMWJXHeT-&Av0t6rc z0SG_<0uX=z1Rwx`4^v>GL=qb-nV02e^O@82y4*LP-aS#DEA-6#!`ZXn%9au&D>+5H z1VAbGoi42e&!#I|&y^wXT0@VrobEHr^eI<70Z;3m?+!+NjQ;GjhGj@9Q-JQ-kTTU6f&dH!>xw|{(siD0o zRf_Zp=}oCps;RY8TTXnmvOYO%HcfJL-rb$LDDp;s_-N$#vv&=sNtYk*Hx8cZ*fyV@ zMelL^7I&#!s}_s3MR)z_&{AflP@3NVkEC8nslQXNQh$D!f9B{l1Rwwb2tWV=5P$## zAOHafK;X&=+=|kOl{`OO6-h>Ed`3PSoLNdnX?$ZP7~Bx||LI5n5Fh{n2tWV=5P$## tAOHafKmY;|xW)qF{eN8lU*iLeu0a3-5P$##AOHafKmY;|fB*zY;9v0Y9$x?e -- Gitee From 32edbc87d9dd5b7b90866a3b3ed4e4f42e097986 Mon Sep 17 00:00:00 2001 From: Yuichi <913637919@qq.com> Date: Tue, 26 Nov 2024 08:48:19 +0000 Subject: [PATCH 35/48] =?UTF-8?q?=E4=BF=AE=E6=94=B9.gitignore?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index ff47c2d..5d594ea 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ Cargo.lock # These are backup files generated by rustfmt **/*.rs.bk +.idea/ \ No newline at end of file -- Gitee From e3684251ed9de1235eb9edc145681afc1be823de Mon Sep 17 00:00:00 2001 From: Yuichi <913637919@qq.com> Date: Tue, 26 Nov 2024 08:49:42 +0000 Subject: [PATCH 36/48] =?UTF-8?q?=E4=BF=AE=E6=94=B9.gitignore?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 5d594ea..49f8c02 100644 --- a/.gitignore +++ b/.gitignore @@ -2,11 +2,10 @@ # will have compiled files and executables debug/ target/ - +.idea/ # Remove Cargo.lock from gitignore if creating an executable, leave it for libraries # More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html Cargo.lock # These are backup files generated by rustfmt **/*.rs.bk -.idea/ \ No newline at end of file -- Gitee From d166fda9622c13ec4df47e5e959f7f5c1d0dfca6 Mon Sep 17 00:00:00 2001 From: Yuichi <913637919@qq.com> Date: Tue, 26 Nov 2024 08:51:49 +0000 Subject: [PATCH 37/48] =?UTF-8?q?=E4=BF=AE=E6=94=B9.gitignore?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/.gitignore | 8 -------- .idea/apiserver.iml | 11 ----------- .idea/dataSources.xml | 20 -------------------- .idea/modules.xml | 8 -------- .idea/vcs.xml | 6 ------ 5 files changed, 53 deletions(-) delete mode 100644 .idea/.gitignore delete mode 100644 .idea/apiserver.iml delete mode 100644 .idea/dataSources.xml delete mode 100644 .idea/modules.xml delete mode 100644 .idea/vcs.xml diff --git a/.idea/.gitignore b/.idea/.gitignore deleted file mode 100644 index 35410ca..0000000 --- a/.idea/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -# 默认忽略的文件 -/shelf/ -/workspace.xml -# 基于编辑器的 HTTP 客户端请求 -/httpRequests/ -# Datasource local storage ignored files -/dataSources/ -/dataSources.local.xml diff --git a/.idea/apiserver.iml b/.idea/apiserver.iml deleted file mode 100644 index cf84ae4..0000000 --- a/.idea/apiserver.iml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/dataSources.xml b/.idea/dataSources.xml deleted file mode 100644 index ad76524..0000000 --- a/.idea/dataSources.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - sqlite.xerial - true - org.sqlite.JDBC - jdbc:sqlite:$PROJECT_DIR$/database.sqlite - $ProjectFileDir$ - - - file://$APPLICATION_CONFIG_DIR$/jdbc-drivers/Xerial SQLiteJDBC/3.45.1/org/xerial/sqlite-jdbc/3.45.1.0/sqlite-jdbc-3.45.1.0.jar - - - file://$APPLICATION_CONFIG_DIR$/jdbc-drivers/Xerial SQLiteJDBC/3.45.1/org/slf4j/slf4j-api/1.7.36/slf4j-api-1.7.36.jar - - - - - \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml deleted file mode 100644 index 3eff730..0000000 --- a/.idea/modules.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 35eb1dd..0000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file -- Gitee From 1cf9c488eb609a3c49e77c9bd0183c12f910a0a3 Mon Sep 17 00:00:00 2001 From: Yuichi <913637919@qq.com> Date: Tue, 26 Nov 2024 09:01:06 +0000 Subject: [PATCH 38/48] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dcrd=E9=87=8D=E5=A4=8D?= =?UTF-8?q?=E6=B3=A8=E5=86=8C=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/cores/handlers.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/cores/handlers.rs b/src/cores/handlers.rs index a76d5e0..436fcc5 100644 --- a/src/cores/handlers.rs +++ b/src/cores/handlers.rs @@ -702,6 +702,7 @@ impl Handler for DefaultHandler { .and_then(|kind| kind.as_str()) .unwrap_or("error"); + // 调用check_metadata函数 let metadata_exists = check_metadata(db_connection, item_kind, &version,false).await.map_err(ErrorInternalServerError)?; @@ -794,7 +795,7 @@ impl Handler for DefaultHandler { return Ok(HttpResponse::NotFound().json(json!({ "error": "该 crd 资源已存在,无需重复注册" }))); } - insert_metadata(db_connection, item_kind, &version, false, &data) + insert_metadata(db_connection, item_kind, &version, true, &data) .await .map_err(ErrorInternalServerError)?; @@ -969,7 +970,7 @@ impl Handler for DefaultHandler { return Ok(HttpResponse::NotFound().json(json!({ "error": "该 crd 资源已存在,无需重复注册" }))); } - insert_metadata(db_connection, item_kind, &ver, false, &data) + insert_metadata(db_connection, item_kind, &ver, true, &data) .await .map_err(ErrorInternalServerError)?; -- Gitee From 90a4d690cff87bcd344a028bb52e604824f5e000 Mon Sep 17 00:00:00 2001 From: syswu Date: Tue, 26 Nov 2024 21:32:40 +0800 Subject: [PATCH 39/48] =?UTF-8?q?=E6=B7=BB=E5=8A=A0watchall=5Froutes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/cores/config.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/cores/config.rs b/src/cores/config.rs index 17e2a92..16e5786 100644 --- a/src/cores/config.rs +++ b/src/cores/config.rs @@ -103,6 +103,7 @@ pub struct DefaultConfig { update_routes: HashMap, getone_routes: HashMap, listall_routes: HashMap, + watchall_routes: HashMap, } impl DefaultConfig { @@ -162,6 +163,17 @@ impl DefaultConfig { map.insert("/apis/{group}/{version}/namespaces/{namespace}/{plural}".to_string(), APIS_WITH_NAMESPACE.to_string()); map.insert("/apis/{group}/{version}/{plural}".to_string(), APIS_WITHOUT_NAMESPACE.to_string()); map + }, + watchall_routes: { + let mut map: HashMap = HashMap::new(); + // watch some resources: GET + // - with namespace: /api(s)/{group}/{version}/watch/namespaces/{namespace}/{plural} + // - without namespace/api(s)/{group}/{version}/watch/namespaces/{plural} + map.insert("/api/{version}/watch/namespaces/{namespace}/{plural}".to_string(), API_WITH_NAMESPACE.to_string()); + map.insert("/api/{version}/watch/{plural}".to_string(), API_WITHOUT_NAMESPACE.to_string()); + map.insert("/apis/{group}/{version}/watch/namespaces/{namespace}/{plural}".to_string(), APIS_WITH_NAMESPACE.to_string()); + map.insert("/apis/{group}/{version}/watch/{plural}".to_string(), APIS_WITHOUT_NAMESPACE.to_string()); + map } } } -- Gitee From 2166dec92c29a5029ab9570e00775a972314339b Mon Sep 17 00:00:00 2001 From: Yuichi <913637919@qq.com> Date: Wed, 27 Nov 2024 11:37:52 +0800 Subject: [PATCH 40/48] =?UTF-8?q?=E9=80=82=E9=85=8D0.3=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E7=9A=84feventbus?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.lock | 6 +-- Cargo.toml | 4 +- src/cores/apiserver.rs | 7 +-- src/cores/handlers.rs | 97 +++++++++++++++++++++++------------------- 4 files changed, 60 insertions(+), 54 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 616cd06..c48122b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -890,9 +890,9 @@ dependencies = [ [[package]] name = "feventbus" -version = "0.2.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b44fa2d92d2434c95a5da95cca25861a437eb63fc3c164a07ea023481e255d0" +checksum = "81b7cca7940f29e24592a89727028106825660bd8f9aae1d85283008fea92220" dependencies = [ "async-nats", "async-trait", @@ -918,7 +918,7 @@ dependencies = [ [[package]] name = "fleet_apiserver" -version = "0.2.0" +version = "0.3.0" dependencies = [ "actix-http", "actix-service", diff --git a/Cargo.toml b/Cargo.toml index 856e098..22083d1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "fleet_apiserver" -version = "0.2.0" +version = "0.3.0" license = "Apache-2.0" authors = ["wuheng ", "chenhongyu23@otcaix.iscas.ac.cn"] categories = ["api-bindings"] @@ -11,7 +11,7 @@ repository = "https://gitee.com/iscas-system/apiserver" readme = "README.md" [dependencies] -feventbus = "0.2.0" +feventbus = "0.3.0" r2d2 = "0.8.10" dotenv = "0.15.0" diesel = { version = "2.2.0", features = ["sqlite", "postgres", "r2d2"] } diff --git a/src/cores/apiserver.rs b/src/cores/apiserver.rs index 963d751..afaa16a 100644 --- a/src/cores/apiserver.rs +++ b/src/cores/apiserver.rs @@ -15,11 +15,6 @@ pub struct ApiServer config: Arc, } -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct ApiServerMessage { - pub content: String, -} - impl ApiServer { pub fn new (config: Box) -> Self { @@ -35,7 +30,7 @@ impl ApiServer let handler = Arc::new(handler); // 初始化 NatsCli 实例 - let nats_cli: Arc> = Arc::new(NatsCli::new().await.unwrap()); + let nats_cli = Arc::new(NatsCli::new().await.unwrap()); let server = HttpServer::new(move || { diff --git a/src/cores/handlers.rs b/src/cores/handlers.rs index 436fcc5..a79f7c1 100644 --- a/src/cores/handlers.rs +++ b/src/cores/handlers.rs @@ -16,7 +16,6 @@ use feventbus::message::Message; use feventbus::message; use feventbus::traits::producer::Producer; use serde::{Deserialize, Serialize}; -use cores::apiserver::ApiServerMessage; use crate::cores; // 定义全局哈希表来获取model名 @@ -48,7 +47,7 @@ pub trait Handler { info: web::Path<(String, String)>, data: web::Json, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc, ) -> Result; // /api/{version}/namespaces/{namespace}/{plural} @@ -57,7 +56,7 @@ pub trait Handler { info: web::Path<(String, String, String)>, data: web::Json, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc, ) -> Result; // /apis/{group}/{version}/{plural} @@ -66,7 +65,7 @@ pub trait Handler { info: web::Path<(String, String, String)>, data: web::Json, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc, ) -> Result; // /apis/{group}/{version}/namespaces/{namespace}/{plural} @@ -75,7 +74,7 @@ pub trait Handler { info: web::Path<(String, String, String, String)>, data: web::Json, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc, ) -> Result; // /api/{version}/{plural}/{name} @@ -83,7 +82,7 @@ pub trait Handler { &self, info: web::Path<(String, String, String)>, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc, ) -> Result; // /api/{version}/namespaces/{namespace}/{plural}/{name} @@ -91,7 +90,7 @@ pub trait Handler { &self, info: web::Path<(String, String, String, String)>, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc, ) -> Result; // /apis/{group}/{version}/{plural}/{name} @@ -99,7 +98,7 @@ pub trait Handler { &self, info: web::Path<(String, String, String, String)>, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc, ) -> Result; // /apis/{group}/{version}/namespaces/{namespace}/{plural}/{name} @@ -107,7 +106,7 @@ pub trait Handler { &self, info: web::Path<(String, String, String, String, String)>, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc, ) -> Result; // /api/{version}/{plural}/{name} @@ -116,7 +115,7 @@ pub trait Handler { info: web::Path<(String, String, String)>, data: web::Json, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc, ) -> Result; // /api/{version}/namespaces/{namespace}/{plural}/{name} @@ -125,7 +124,7 @@ pub trait Handler { info: web::Path<(String, String, String, String)>, data: web::Json, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc, ) -> Result; // /apis/{group}/{version}/{plural}/{name} @@ -134,7 +133,7 @@ pub trait Handler { info: web::Path<(String, String, String, String)>, data: web::Json, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc, ) -> Result; // /apis/{group}/{version}/namespaces/{namespace}/{plural}/{name} @@ -143,7 +142,7 @@ pub trait Handler { info: web::Path<(String, String, String, String, String)>, data: web::Json, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc, ) -> Result; // /api/{version}/{plural}/{name} @@ -152,7 +151,7 @@ pub trait Handler { info: web::Path<(String, String, String)>, data: web::Query, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc, ) -> Result; // /api/{version}/namespaces/{namespace}/{plural}/{name} @@ -161,7 +160,7 @@ pub trait Handler { info: web::Path<(String, String, String, String)>, data: web::Query, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc, ) -> Result; // /apis/{group}/{version}/{plural}/{name} @@ -170,7 +169,7 @@ pub trait Handler { info: web::Path<(String, String, String, String)>, data: web::Query, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc, ) -> Result; // /apis/{group}/{version}/namespaces/{namespace}/{plural}/{name} @@ -179,7 +178,7 @@ pub trait Handler { info: web::Path<(String, String, String, String, String)>, data: web::Query, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc, ) -> Result; // /api/{version}/{plural} @@ -188,7 +187,7 @@ pub trait Handler { info: web::Path<(String, String)>, data: web::Query, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc, ) -> Result; // /api/{version}/namespaces/{namespace}/{plural} @@ -197,7 +196,7 @@ pub trait Handler { info: web::Path<(String, String, String)>, data: web::Query, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc, ) -> Result; // /apis/{group}/{version}/{plural} @@ -206,7 +205,7 @@ pub trait Handler { info: web::Path<(String, String, String)>, data: web::Query, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc, ) -> Result; // /apis/{group}/{version}/namespaces/{namespace}/{plural} @@ -215,7 +214,7 @@ pub trait Handler { info: web::Path<(String, String, String, String)>, data: web::Query, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc, ) -> Result; // 不满足以上请求路径的处理 @@ -655,7 +654,10 @@ async fn get_all_data_from_table( // 发送请求并等待响应 -async fn send_request(message: Message, nats_cli: Arc>) -> Result<(), Box> +async fn send_request( + message: Message, + nats_cli: Arc, +) -> std::result::Result<(), Box> where T: Serialize + for<'de> Deserialize<'de> + Debug + Clone + Send + Sync + 'static, { @@ -663,7 +665,11 @@ where .request(message, time::Duration::from_secs(100)) .await { - Ok(_) => { + Ok(response) => { + println!( + "===============Received response: {:?}==================", + response + ); Ok(()) } Err(e) => { @@ -673,6 +679,11 @@ where } } +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct ApiServerMessage { + pub content: String, +} + #[async_trait] impl Handler for DefaultHandler { @@ -682,7 +693,7 @@ impl Handler for DefaultHandler { info: web::Path<(String, String)>, data: web::Json, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc, ) -> Result { let (version, plural) = info.into_inner(); @@ -768,7 +779,7 @@ impl Handler for DefaultHandler { info: web::Path<(String, String, String)>, data: web::Json, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc, ) -> Result { let (version, namespace, plural) = info.into_inner(); @@ -853,7 +864,7 @@ impl Handler for DefaultHandler { info: web::Path<(String, String, String)>, data: web::Json, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc, ) -> Result { let (group, version, plural) = info.into_inner(); let ver = group + "/" + &*version; @@ -940,7 +951,7 @@ impl Handler for DefaultHandler { info: web::Path<(String, String, String, String)>, data: web::Json, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc, ) -> Result { let (group, version, namespace, plural) = info.into_inner(); @@ -1027,7 +1038,7 @@ impl Handler for DefaultHandler { &self, info: web::Path<(String, String, String)>, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc, ) -> Result { let (version, plural, name) = info.into_inner(); @@ -1081,7 +1092,7 @@ impl Handler for DefaultHandler { &self, info: web::Path<(String, String, String, String)>, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc, ) -> Result { let (version, namespace, plural, name) = info.into_inner(); // 检查 metadata 中是否存在该 plural 且需要 namespace @@ -1133,7 +1144,7 @@ impl Handler for DefaultHandler { &self, info: web::Path<(String, String, String, String)>, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc, ) -> Result { let (group, version, plural, name) = info.into_inner(); let ver = format!("{}/{}", group, version); @@ -1185,7 +1196,7 @@ impl Handler for DefaultHandler { &self, info: web::Path<(String, String, String, String, String)>, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc, ) -> Result { let (group, version, namespace, plural, name) = info.into_inner(); let ver = format!("{}/{}", group, version); @@ -1238,7 +1249,7 @@ impl Handler for DefaultHandler { info: web::Path<(String, String, String)>, data: web::Json, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc, ) -> Result { let (version, plural, name) = info.into_inner(); @@ -1291,7 +1302,7 @@ impl Handler for DefaultHandler { info: web::Path<(String, String, String, String)>, data: web::Json, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc, ) -> Result { let (version, namespace, plural, name) = info.into_inner(); // 检查 metadata 中是否存在 plural 且要求 namespace @@ -1343,7 +1354,7 @@ impl Handler for DefaultHandler { info: web::Path<(String, String, String, String)>, data: web::Json, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc, ) -> Result { let (group, version, plural, name) = info.into_inner(); let ver = format!("{}/{}", group, version); @@ -1396,7 +1407,7 @@ impl Handler for DefaultHandler { info: web::Path<(String, String, String, String, String)>, data: web::Json, db_connection: &mut DbConnection, - nats_cli: Arc>, + nats_cli: Arc, ) -> Result { let (group, version, namespace, plural, name) = info.into_inner(); let ver = format!("{}/{}", group, version); @@ -1449,7 +1460,7 @@ impl Handler for DefaultHandler { info: web::Path<(String, String, String)>, _data: web::Query, db_connection: &mut DbConnection, - _nats_cli: Arc>, + _nats_cli: Arc, ) -> Result { let (version, plural, name) = info.into_inner(); let metadata_exists = check_metadata(db_connection, &plural, &version, false) @@ -1478,7 +1489,7 @@ impl Handler for DefaultHandler { info: web::Path<(String, String, String, String)>, _data: web::Query, db_connection: &mut DbConnection, - _nats_cli: Arc>, + _nats_cli: Arc, ) -> Result { let (version, namespace, plural, name) = info.into_inner(); let metadata_exists = check_metadata(db_connection, &plural, &version, true) @@ -1507,7 +1518,7 @@ impl Handler for DefaultHandler { info: web::Path<(String, String, String, String)>, _data: web::Query, db_connection: &mut DbConnection, - _nats_cli: Arc>, + _nats_cli: Arc, ) -> Result { let (group, version, plural, name) = info.into_inner(); let ver = format!("{}/{}", group, version); @@ -1538,7 +1549,7 @@ impl Handler for DefaultHandler { info: web::Path<(String, String, String, String, String)>, _data: web::Query, db_connection: &mut DbConnection, - _nats_cli: Arc>, + _nats_cli: Arc, ) -> Result { let (group, version, namespace, plural, name) = info.into_inner(); let ver = format!("{}/{}", group, version); @@ -1569,7 +1580,7 @@ impl Handler for DefaultHandler { info: web::Path<(String, String)>, _data: web::Query, db_connection: &mut DbConnection, - _nats_cli: Arc>, + _nats_cli: Arc, ) -> Result { let (version, plural) = info.into_inner(); let metadata_exists = check_metadata(db_connection, &plural, &version, false) @@ -1599,7 +1610,7 @@ impl Handler for DefaultHandler { info: web::Path<(String, String, String)>, _data: web::Query, db_connection: &mut DbConnection, - _nats_cli: Arc>, + _nats_cli: Arc, ) -> Result { let (version, namespace, plural) = info.into_inner(); let metadata_exists = check_metadata(db_connection, &plural, &version, true) @@ -1629,7 +1640,7 @@ impl Handler for DefaultHandler { info: web::Path<(String, String, String)>, _data: web::Query, db_connection: &mut DbConnection, - _nats_cli: Arc>, + _nats_cli: Arc, ) -> Result { let (group, version, plural) = info.into_inner(); let ver = format!("{}/{}", group, version); @@ -1661,7 +1672,7 @@ impl Handler for DefaultHandler { info: web::Path<(String, String, String, String)>, _data: web::Query, db_connection: &mut DbConnection, - _nats_cli: Arc>, + _nats_cli: Arc, ) -> Result { let (group, version, namespace, plural) = info.into_inner(); let ver = format!("{}/{}", group, version); -- Gitee From d3c784624abfef53c13f3cb02253cb681f35a7f3 Mon Sep 17 00:00:00 2001 From: Yuichi <913637919@qq.com> Date: Wed, 27 Nov 2024 14:24:09 +0800 Subject: [PATCH 41/48] =?UTF-8?q?=E5=88=A0=E9=99=A4envlogger?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.lock | 2 +- Cargo.toml | 2 +- src/cores/apiserver.rs | 1 - src/cores/handlers.rs | 1 - src/lib.rs | 5 +---- 5 files changed, 3 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c48122b..402550e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -918,7 +918,7 @@ dependencies = [ [[package]] name = "fleet_apiserver" -version = "0.3.0" +version = "0.3.1" dependencies = [ "actix-http", "actix-service", diff --git a/Cargo.toml b/Cargo.toml index 22083d1..c9599fe 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "fleet_apiserver" -version = "0.3.0" +version = "0.3.1" license = "Apache-2.0" authors = ["wuheng ", "chenhongyu23@otcaix.iscas.ac.cn"] categories = ["api-bindings"] diff --git a/src/cores/apiserver.rs b/src/cores/apiserver.rs index afaa16a..4cc38c0 100644 --- a/src/cores/apiserver.rs +++ b/src/cores/apiserver.rs @@ -6,7 +6,6 @@ use crate::cores::handlers::{Handler}; use std::sync::{Arc}; use feventbus::impls::nats::nats::NatsCli; use feventbus::traits::controller::EventBus; -use serde::{Deserialize, Serialize}; use crate::cores::db::{DbPool}; pub struct ApiServer diff --git a/src/cores/handlers.rs b/src/cores/handlers.rs index a79f7c1..a5c422d 100644 --- a/src/cores/handlers.rs +++ b/src/cores/handlers.rs @@ -16,7 +16,6 @@ use feventbus::message::Message; use feventbus::message; use feventbus::traits::producer::Producer; use serde::{Deserialize, Serialize}; -use crate::cores; // 定义全局哈希表来获取model名 static GLOBAL_HASHMAP: LazyLock>> = LazyLock::new(|| { diff --git a/src/lib.rs b/src/lib.rs index cdbf155..2f3e95c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,8 +6,6 @@ use cores::config::DefaultConfig; use cores::handlers::DefaultHandler; use cores::db::DbPool; use std::sync::Arc; -use env_logger; - /// 启动 Web 服务器 /// @@ -21,8 +19,7 @@ pub async fn start_server(database_url: &str, address: &str) -> Result<(), Box Date: Wed, 27 Nov 2024 16:00:11 +0800 Subject: [PATCH 42/48] =?UTF-8?q?request=E5=86=85=E5=AE=B9=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E4=B8=BAjson=E6=A0=BC=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.lock | 2 +- Cargo.toml | 2 +- src/cores/handlers.rs | 26 +++++++++++++------------- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 402550e..1f76641 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -918,7 +918,7 @@ dependencies = [ [[package]] name = "fleet_apiserver" -version = "0.3.1" +version = "0.3.2" dependencies = [ "actix-http", "actix-service", diff --git a/Cargo.toml b/Cargo.toml index c9599fe..484aa44 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "fleet_apiserver" -version = "0.3.1" +version = "0.3.2" license = "Apache-2.0" authors = ["wuheng ", "chenhongyu23@otcaix.iscas.ac.cn"] categories = ["api-bindings"] diff --git a/src/cores/handlers.rs b/src/cores/handlers.rs index a5c422d..71441a2 100644 --- a/src/cores/handlers.rs +++ b/src/cores/handlers.rs @@ -680,7 +680,7 @@ where #[derive(Serialize, Deserialize, Debug, Clone)] pub struct ApiServerMessage { - pub content: String, + pub content: Value, } #[async_trait] @@ -757,7 +757,7 @@ impl Handler for DefaultHandler { message::NativeEventAction::Other, Some(model_map), Some(ApiServerMessage { - content: data.to_string(), + content: data.clone(), }), None, ); @@ -842,7 +842,7 @@ impl Handler for DefaultHandler { message::NativeEventAction::Other, Some(model_map), Some(ApiServerMessage { - content: data.to_string(), + content: data.clone(), }), None, ); @@ -929,7 +929,7 @@ impl Handler for DefaultHandler { message::NativeEventAction::Other, Some(model_map), Some(ApiServerMessage { - content: data.to_string(), + content: data.clone(), }), None, ); @@ -1017,7 +1017,7 @@ impl Handler for DefaultHandler { message::NativeEventAction::Other, Some(model_map), Some(ApiServerMessage { - content: data.to_string(), + content: data.clone(), }), None, ); @@ -1067,7 +1067,7 @@ impl Handler for DefaultHandler { message::NativeEventAction::Other, Some(model_map), Some(ApiServerMessage { - content: name.clone(), + content: name.clone().parse()?, }), None, ); @@ -1120,7 +1120,7 @@ impl Handler for DefaultHandler { message::NativeEventAction::Other, Some(model_map), Some(ApiServerMessage { - content: name.clone(), + content: name.clone().parse()?, }), None, ); @@ -1173,7 +1173,7 @@ impl Handler for DefaultHandler { message::NativeEventAction::Other, Some(model_map), Some(ApiServerMessage { - content: name.clone(), + content: name.clone().parse()?, }), None, ); @@ -1225,7 +1225,7 @@ impl Handler for DefaultHandler { message::NativeEventAction::Other, Some(model_map), Some(ApiServerMessage { - content: name.clone(), + content: name.clone().parse()?, }), None, ); @@ -1277,7 +1277,7 @@ impl Handler for DefaultHandler { message::NativeEventAction::Other, Some(model_map), Some(ApiServerMessage { - content: data.to_string(), + content: data.clone(), }), None, ); @@ -1330,7 +1330,7 @@ impl Handler for DefaultHandler { message::NativeEventAction::Other, Some(model_map), Some(ApiServerMessage { - content: data.to_string(), + content: data.clone(), }), None, ); @@ -1383,7 +1383,7 @@ impl Handler for DefaultHandler { message::NativeEventAction::Other, Some(model_map), Some(ApiServerMessage { - content: data.to_string(), + content: data.clone(), }), None, ); @@ -1436,7 +1436,7 @@ impl Handler for DefaultHandler { message::NativeEventAction::Other, Some(model_map), Some(ApiServerMessage { - content: data.to_string(), + content: data.clone(), }), None, ); -- Gitee From 21a01e1b5aeede646b3cdba27536c060557da979 Mon Sep 17 00:00:00 2001 From: Yuichi <913637919@qq.com> Date: Wed, 27 Nov 2024 17:36:02 +0800 Subject: [PATCH 43/48] =?UTF-8?q?request=E5=86=85=E5=AE=B9=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E4=B8=BAjson=E6=A0=BC=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.lock | 2 +- Cargo.toml | 2 +- src/cores/handlers.rs | 28 ++++++++++++++++++---------- 3 files changed, 20 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1f76641..c291f84 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -918,7 +918,7 @@ dependencies = [ [[package]] name = "fleet_apiserver" -version = "0.3.2" +version = "0.3.3" dependencies = [ "actix-http", "actix-service", diff --git a/Cargo.toml b/Cargo.toml index 484aa44..91bde44 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "fleet_apiserver" -version = "0.3.2" +version = "0.3.3" license = "Apache-2.0" authors = ["wuheng ", "chenhongyu23@otcaix.iscas.ac.cn"] categories = ["api-bindings"] diff --git a/src/cores/handlers.rs b/src/cores/handlers.rs index 71441a2..8e3d13d 100644 --- a/src/cores/handlers.rs +++ b/src/cores/handlers.rs @@ -695,6 +695,7 @@ impl Handler for DefaultHandler { nats_cli: Arc, ) -> Result { let (version, plural) = info.into_inner(); + let data = data.into_inner(); //判断是正常的插入函数还是 crd 资源的注册函数 if plural == "crds" { @@ -751,6 +752,7 @@ impl Handler for DefaultHandler { model_map.insert("MODEL".to_string(), kind); + // request消息 let request_message = Message::new( "CREATE".to_string(), @@ -769,7 +771,7 @@ impl Handler for DefaultHandler { .map_err(ErrorInternalServerError)?; } - Ok(HttpResponse::Ok().json(data.into_inner())) + Ok(HttpResponse::Ok().json(data)) } // /api/{version}/namespaces/{namespace}/{plural} @@ -781,6 +783,7 @@ impl Handler for DefaultHandler { nats_cli: Arc, ) -> Result { let (version, namespace, plural) = info.into_inner(); + let data = data.into_inner(); //判断是正常的插入函数还是 crd 资源的注册函数 if plural == "crds" { @@ -854,7 +857,7 @@ impl Handler for DefaultHandler { .map_err(ErrorInternalServerError)?; } - Ok(HttpResponse::Ok().json(data.into_inner())) + Ok(HttpResponse::Ok().json(data)) } // /apis/{group}/{version}/{plural} @@ -867,7 +870,7 @@ impl Handler for DefaultHandler { ) -> Result { let (group, version, plural) = info.into_inner(); let ver = group + "/" + &*version; - + let data = data.into_inner(); //判断是正常的插入函数还是 crd 资源的注册函数 if plural == "crds" { @@ -941,7 +944,7 @@ impl Handler for DefaultHandler { .map_err(ErrorInternalServerError)?; } - Ok(HttpResponse::Ok().json(data.into_inner())) + Ok(HttpResponse::Ok().json(data)) } // /apis/{group}/{version}/namespaces/{namespace}/{plural} @@ -955,7 +958,7 @@ impl Handler for DefaultHandler { let (group, version, namespace, plural) = info.into_inner(); let ver = group + "/" + &*version; - + let data = data.into_inner(); //判断是正常的插入函数还是 crd 资源的注册函数 if plural == "crds" { @@ -1029,7 +1032,7 @@ impl Handler for DefaultHandler { .map_err(ErrorInternalServerError)?; } - Ok(HttpResponse::Ok().json(data.into_inner())) + Ok(HttpResponse::Ok().json(data)) } // /api/{version}/{plural}/{name} @@ -1251,6 +1254,7 @@ impl Handler for DefaultHandler { nats_cli: Arc, ) -> Result { let (version, plural, name) = info.into_inner(); + let data = data.into_inner(); let metadata_exists = check_metadata(db_connection, &plural, &version, false) .await @@ -1292,7 +1296,7 @@ impl Handler for DefaultHandler { return Ok(HttpResponse::NotFound().json(json!({ "error": "指定数据不存在" }))); } - Ok(HttpResponse::Ok().json(data.into_inner())) + Ok(HttpResponse::Ok().json(data)) } // /api/{version}/namespaces/{namespace}/{plural}/{name} @@ -1304,6 +1308,8 @@ impl Handler for DefaultHandler { nats_cli: Arc, ) -> Result { let (version, namespace, plural, name) = info.into_inner(); + let data = data.into_inner(); + // 检查 metadata 中是否存在 plural 且要求 namespace let metadata_exists = check_metadata(db_connection, &plural, &version, true) .await @@ -1344,7 +1350,7 @@ impl Handler for DefaultHandler { return Ok(HttpResponse::NotFound().json(json!({ "error": "指定数据不存在" }))); } - Ok(HttpResponse::Ok().json(data.into_inner())) + Ok(HttpResponse::Ok().json(data)) } // /apis/{group}/{version}/{plural}/{name} @@ -1357,6 +1363,7 @@ impl Handler for DefaultHandler { ) -> Result { let (group, version, plural, name) = info.into_inner(); let ver = format!("{}/{}", group, version); + let data = data.into_inner(); let metadata_exists = check_metadata(db_connection, &plural, &ver, false) .await @@ -1397,7 +1404,7 @@ impl Handler for DefaultHandler { return Ok(HttpResponse::NotFound().json(json!({ "error": "指定数据不存在" }))); } - Ok(HttpResponse::Ok().json(data.into_inner())) + Ok(HttpResponse::Ok().json(data)) } // /apis/{group}/{version}/namespaces/{namespace}/{plural}/{name} @@ -1410,6 +1417,7 @@ impl Handler for DefaultHandler { ) -> Result { let (group, version, namespace, plural, name) = info.into_inner(); let ver = format!("{}/{}", group, version); + let data = data.into_inner(); let metadata_exists = check_metadata(db_connection, &plural, &ver, true) .await @@ -1450,7 +1458,7 @@ impl Handler for DefaultHandler { return Ok(HttpResponse::NotFound().json(json!({ "error": "指定数据不存在" }))); } - Ok(HttpResponse::Ok().json(data.into_inner())) + Ok(HttpResponse::Ok().json(data)) } // /api/{version}/{plural}/{name} -- Gitee From 9b76df27ee74e6f871ed1729c5319a277a459282 Mon Sep 17 00:00:00 2001 From: Yuichi <913637919@qq.com> Date: Wed, 27 Nov 2024 20:09:06 +0800 Subject: [PATCH 44/48] =?UTF-8?q?=E6=B7=BB=E5=8A=A0watch=E6=A1=86=E6=9E=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/cores/apiserver.rs | 104 +++++++++++++++++++++++++++++++++++++++++ src/cores/config.rs | 4 ++ src/cores/handlers.rs | 44 +++++++++++++++++ 3 files changed, 152 insertions(+) diff --git a/src/cores/apiserver.rs b/src/cores/apiserver.rs index 4cc38c0..c8d2b31 100644 --- a/src/cores/apiserver.rs +++ b/src/cores/apiserver.rs @@ -570,6 +570,110 @@ impl ApiServer } } + for (key, route) in config.watchall_routes() { + if route == API_WITHOUT_NAMESPACE { + let handler = Arc::clone(&handler); + let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + + app = app.route(key, web::get().to( + move |path, data| { + let handler = Arc::clone(&handler); + let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + + async move { + match db_pool.get_connection() { + Ok(mut conn) => { + handler + .default() + .watch_api_without_namespace(path, data, &mut conn, nats_cli) + .await + }, + Err(_) => Err(actix_web::error::ErrorInternalServerError( + "Failed to get database connection", + )), + } + } + })); + } else if route == API_WITH_NAMESPACE { + let handler = Arc::clone(&handler); + let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + + app = app.route(key, web::get().to( + move |path, data| { + let handler = Arc::clone(&handler); + let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + + async move { + match db_pool.get_connection() { + Ok(mut conn) => { + handler + .default() + .watch_api_with_namespace(path, data, &mut conn, nats_cli) + .await + }, + Err(_) => Err(actix_web::error::ErrorInternalServerError( + "Failed to get database connection", + )), + } + } + })); + } else if route == APIS_WITHOUT_NAMESPACE { + let handler = Arc::clone(&handler); + let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + + app = app.route(key, web::get().to( + move |path, data| { + let handler = Arc::clone(&handler); + let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + + async move { + match db_pool.get_connection() { + Ok(mut conn) => { + handler + .default() + .watch_apis_without_namespace(path, data, &mut conn, nats_cli) + .await + }, + Err(_) => Err(actix_web::error::ErrorInternalServerError( + "Failed to get database connection", + )), + } + } + })); + } else if route == APIS_WITH_NAMESPACE { + let handler = Arc::clone(&handler); + let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + + app = app.route(key, web::get().to( + move |path, data| { + let handler = Arc::clone(&handler); + let db_pool = Arc::clone(&db_pool); + let nats_cli = Arc::clone(&nats_cli); + + async move { + match db_pool.get_connection() { + Ok(mut conn) => { + handler + .default() + .watch_apis_with_namespace(path, data, &mut conn, nats_cli) + .await + }, + Err(_) => Err(actix_web::error::ErrorInternalServerError( + "Failed to get database connection", + )), + } + } + })); + } + } + // TODO 与Kubernetes的状态一致 app.default_service(web::to(move || async { Ok::( diff --git a/src/cores/config.rs b/src/cores/config.rs index 16e5786..1ddcf8b 100644 --- a/src/cores/config.rs +++ b/src/cores/config.rs @@ -91,6 +91,8 @@ pub trait Config: Sync + Send { // 获取指定类型(如Pod、Job的所有实例)的URL列表和Web服务器路由的映射关系 fn listall_routes(&self) -> &HashMap; + fn watchall_routes(&self) -> &HashMap; + // TODO WatchOne和WatchAll两个接口 } @@ -200,4 +202,6 @@ impl Config for DefaultConfig { } fn listall_routes(&self) -> &HashMap { &self.listall_routes } + + fn watchall_routes(&self) -> &HashMap { &self.watchall_routes } } diff --git a/src/cores/handlers.rs b/src/cores/handlers.rs index 8e3d13d..45ea7e0 100644 --- a/src/cores/handlers.rs +++ b/src/cores/handlers.rs @@ -216,6 +216,50 @@ pub trait Handler { nats_cli: Arc, ) -> Result; + async fn watch_api_without_namespace( + &self, + info: web::Path<(String, String)>, + data: web::Query, + db_connection: &mut DbConnection, + nats_cli: Arc, + ) -> Result { + // 实现逻辑 + Ok(HttpResponse::Ok().json("watch API without namespace")) + } + + async fn watch_api_with_namespace( + &self, + info: web::Path<(String, String, String)>, + data: web::Query, + db_connection: &mut DbConnection, + nats_cli: Arc, + ) -> Result { + // 实现逻辑 + Ok(HttpResponse::Ok().json("watch API with namespace")) + } + + async fn watch_apis_without_namespace( + &self, + info: web::Path<(String, String, String)>, + data: web::Query, + db_connection: &mut DbConnection, + nats_cli: Arc, + ) -> Result { + // 实现逻辑 + Ok(HttpResponse::Ok().json("watch APIS without namespace")) + } + + async fn watch_apis_with_namespace( + &self, + info: web::Path<(String, String, String, String)>, + data: web::Query, + db_connection: &mut DbConnection, + nats_cli: Arc, + ) -> Result { + // 实现逻辑 + Ok(HttpResponse::Ok().json("watch APIS with namespace")) + } + // 不满足以上请求路径的处理 fn default(&self) -> DefaultHandler; } -- Gitee From fafe8ad2dce6af2dbdff69e828de8011b3ec7efe Mon Sep 17 00:00:00 2001 From: Yuichi <913637919@qq.com> Date: Thu, 28 Nov 2024 15:22:35 +0800 Subject: [PATCH 45/48] =?UTF-8?q?=E4=BF=AE=E5=A4=8DUPDATE=20DELETE?= =?UTF-8?q?=E5=90=91Nats=E7=9A=84=E4=BC=A0=E5=80=BC=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.lock | 2 +- Cargo.toml | 2 +- src/cores/handlers.rs | 76 ++++++++++++++++++++++++++++++++++++++----- 3 files changed, 70 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c291f84..c1466fe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -918,7 +918,7 @@ dependencies = [ [[package]] name = "fleet_apiserver" -version = "0.3.3" +version = "0.3.4" dependencies = [ "actix-http", "actix-service", diff --git a/Cargo.toml b/Cargo.toml index 91bde44..d37a6f8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "fleet_apiserver" -version = "0.3.3" +version = "0.3.4" license = "Apache-2.0" authors = ["wuheng ", "chenhongyu23@otcaix.iscas.ac.cn"] categories = ["api-bindings"] diff --git a/src/cores/handlers.rs b/src/cores/handlers.rs index 45ea7e0..7fc4482 100644 --- a/src/cores/handlers.rs +++ b/src/cores/handlers.rs @@ -1108,13 +1108,20 @@ impl Handler for DefaultHandler { model_map.insert("MODEL".to_string(), kind); + let request_data = json!({ + "apiVersion": version.clone(), + "Namespaces": "", + "Plural": plural.clone(), + "Name": name.clone(), + }); + // request消息 let request_message = Message::new( "DELETE".to_string(), message::NativeEventAction::Other, Some(model_map), Some(ApiServerMessage { - content: name.clone().parse()?, + content: request_data, }), None, ); @@ -1161,13 +1168,20 @@ impl Handler for DefaultHandler { model_map.insert("MODEL".to_string(), kind); + let request_data = json!({ + "apiVersion": version.clone(), + "Namespaces": namespace.clone(), + "Plural": plural.clone(), + "Name": name.clone(), + }); + // request消息 let request_message = Message::new( "DELETE".to_string(), message::NativeEventAction::Other, Some(model_map), Some(ApiServerMessage { - content: name.clone().parse()?, + content: request_data, }), None, ); @@ -1214,13 +1228,20 @@ impl Handler for DefaultHandler { model_map.insert("MODEL".to_string(), kind); + let request_data = json!({ + "apiVersion": ver.clone(), + "Namespaces": "", + "Plural": plural.clone(), + "Name": name.clone(), + }); + // request消息 let request_message = Message::new( "DELETE".to_string(), message::NativeEventAction::Other, Some(model_map), Some(ApiServerMessage { - content: name.clone().parse()?, + content: request_data, }), None, ); @@ -1266,13 +1287,20 @@ impl Handler for DefaultHandler { model_map.insert("MODEL".to_string(), kind); + let request_data = json!({ + "apiVersion": ver.clone(), + "Namespaces": namespace.clone(), + "Plural": plural.clone(), + "Name": name.clone(), + }); + // request消息 let request_message = Message::new( "DELETE".to_string(), message::NativeEventAction::Other, Some(model_map), Some(ApiServerMessage { - content: name.clone().parse()?, + content: request_data, }), None, ); @@ -1319,13 +1347,21 @@ impl Handler for DefaultHandler { model_map.insert("MODEL".to_string(), kind); + let request_data = json!({ + "apiVersion": version.clone(), + "Namespaces": "", + "Plural": plural.clone(), + "Name": name.clone(), + "Data": data.clone() + }); + // request消息 let request_message = Message::new( "UPDATE".to_string(), message::NativeEventAction::Other, Some(model_map), Some(ApiServerMessage { - content: data.clone(), + content: request_data, }), None, ); @@ -1374,13 +1410,21 @@ impl Handler for DefaultHandler { model_map.insert("MODEL".to_string(), kind); + let request_data = json!({ + "apiVersion": version.clone(), + "Namespaces": namespace.clone(), + "Plural": plural.clone(), + "Name": name.clone(), + "Data": data.clone() + }); + // request消息 let request_message = Message::new( "UPDATE".to_string(), message::NativeEventAction::Other, Some(model_map), Some(ApiServerMessage { - content: data.clone(), + content: request_data, }), None, ); @@ -1428,13 +1472,21 @@ impl Handler for DefaultHandler { model_map.insert("MODEL".to_string(), kind); + let request_data = json!({ + "apiVersion": ver, + "Namespaces": "", + "Plural": plural.clone(), + "Name": name.clone(), + "Data": data.clone() + }); + // request消息 let request_message = Message::new( "UPDATE".to_string(), message::NativeEventAction::Other, Some(model_map), Some(ApiServerMessage { - content: data.clone(), + content: request_data, }), None, ); @@ -1482,13 +1534,21 @@ impl Handler for DefaultHandler { model_map.insert("MODEL".to_string(), kind); + let request_data = json!({ + "apiVersion": ver, + "Namespaces": namespace.clone(), + "Plural": plural.clone(), + "Name": name.clone(), + "Data": data.clone() + }); + // request消息 let request_message = Message::new( "UPDATE".to_string(), message::NativeEventAction::Other, Some(model_map), Some(ApiServerMessage { - content: data.clone(), + content: request_data, }), None, ); -- Gitee From 455f753b004589a7ec24c66299ded436e7895cd3 Mon Sep 17 00:00:00 2001 From: Yuichi <913637919@qq.com> Date: Thu, 28 Nov 2024 18:54:13 +0800 Subject: [PATCH 46/48] =?UTF-8?q?=E6=90=AD=E5=BB=BAwatchall=E5=88=9D?= =?UTF-8?q?=E6=AD=A5=E6=A1=86=E6=9E=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.lock | 23 +++++ Cargo.toml | 3 +- database.sqlite | Bin 0 -> 28672 bytes src/cores/apiserver.rs | 94 ++++++----------- src/cores/handlers.rs | 228 ++++++++++++++++++++++++++++++++++++----- 5 files changed, 260 insertions(+), 88 deletions(-) create mode 100644 database.sqlite diff --git a/Cargo.lock b/Cargo.lock index c1466fe..3e5ebe5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -337,6 +337,28 @@ dependencies = [ "webpki-roots", ] +[[package]] +name = "async-stream" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476" +dependencies = [ + "async-stream-impl", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-stream-impl" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "async-trait" version = "0.1.83" @@ -923,6 +945,7 @@ dependencies = [ "actix-http", "actix-service", "actix-web", + "async-stream", "async-trait", "chrono", "diesel", diff --git a/Cargo.toml b/Cargo.toml index d37a6f8..1e81aea 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,4 +29,5 @@ jsonschema = "0.23.0" schemars = "0.8.21" chrono = "0.4.38" once_cell = "1.20.2" -lazy_static = "1.5.0" \ No newline at end of file +lazy_static = "1.5.0" +async-stream = "0.3.6" \ No newline at end of file diff --git a/database.sqlite b/database.sqlite new file mode 100644 index 0000000000000000000000000000000000000000..a1b3c195131e86c810841e69f1bbcaf2ef949911 GIT binary patch literal 28672 zcmeI(OHboQ8~|`TfrKD}mz7Y&0m-#0Es^r@BQLU-hLEN#f!&6%-G^4z#4%YzVyCu~ zE~0w?_B*uqevJJBz3#P#o_gr1hn{-u-%bnxV$k+bE$rWlUo&HS=4U5T=0D!~wx-!C zyJwhPVzUx;kD_VnE0(1wDma(_A;TU?~yg>BO8s0W(v&Y^O>QfgG# zMro~9VVzWVWtN2rHe2k|Qoa05slFm+bMb_mtdp+llWg^fGAWPrw6(q9*bSsx&y}HER#>5|l zLa~R7GzEp#H`ezZ`0pi?zHPYsvZEmj&N6)bV=x?BUZzhsUA?Yq6Q}Opdg_9rmpYQX zk!xFqsoMi6+3FNmU)clMHkkQ587 zz!$S(QOeIkyJ+Sw3O+cY01BW03ZMWApa2S>01BW03ZMWA+zEk&U_5fMOTdZ$2cydr zb8mhPRyd&m3ZMWApa2S>01BW03ZTH}DR9CCXBH#Nr`c+C-)LG*Vk@uH1L25+G4oG{ zW52l~=OuFq&Upy{QXUyi*zv}ubHyXBLz-&Gf-IxCuPQd=IwRm=-?B|jZ*y-GoYhkm zr>L!VdmVV~z}dd;6k~@dhHevhYrupnyoB1BZRb+NG|3@cN$ZmK*rl#q`qf*QCWMAl znT#mrvUzb*+<2Iohv@S0W?&{Zvv9Idt?EWgwXXOKgmal~DDmHEdPb|fv0guCOK?5Y z7-%ik+*m(P^=pkF3i*t{Pi`t?uJWtmahIN1iY%P$RI3U&8rL_c>=e1w9-`}pJ$%;y zs&w=HzI5{xquV9!Q}hw{Z*r4(Nz6!DpY}p#VRcn<;{QSB1I7H!d|>|gJiq4HY7{^L z6hHwKKmim$0Te(16hHwKxOD>er=iD+9`CLSMyH{Fh8}g!1ftW>zY*~|H=Ou?VD3+9 z-i8HED1ZVefC4Ch0w{n2D1ZVea0diVBZ0`$gQbOciWk^*{{bZxVyQ`9Xm^Yz>0BGS zzA@Hpl@)Idlnx(2hdm(q;1uG&8s=7AHBw^hs5Eg{_{%AiB^Bm{op6)gA<(r5w+5ug+ur?PR~X-_GWEG1)Sd1Jz9R4%#WjXu)8E6x1oL zSDu*f@ntb%QYjmtxLRQIJxin91`Ha?bc>W`#oL zG(ul{2pm literal 0 HcmV?d00001 diff --git a/src/cores/apiserver.rs b/src/cores/apiserver.rs index c8d2b31..fc9c06e 100644 --- a/src/cores/apiserver.rs +++ b/src/cores/apiserver.rs @@ -1,7 +1,7 @@ use actix_web::{HttpServer, App, web, HttpResponse}; use crate::cores::config::{Config, APIS_WITHOUT_NAMESPACE, APIS_WITH_NAMESPACE, API_WITHOUT_NAMESPACE, API_WITH_NAMESPACE}; -use crate::cores::handlers::{Handler}; +use crate::cores::handlers::{EventManager, Handler}; use std::sync::{Arc}; use feventbus::impls::nats::nats::NatsCli; @@ -31,6 +31,9 @@ impl ApiServer // 初始化 NatsCli 实例 let nats_cli = Arc::new(NatsCli::new().await.unwrap()); + // 初始化事件管理器 + let event_manager = EventManager::new(); + let server = HttpServer::new(move || { let mut app = App::new(); @@ -38,6 +41,7 @@ impl ApiServer let config = Arc::clone(&self.config); let db_pool = Arc::clone(&db_pool); let nats_cli = Arc::clone(&nats_cli); + let event_manager = event_manager.clone(); // URL是手动注册的,不会存在APIS_WITHOUT_NAMESPACE, APIS_WITH_NAMESPACE, // API_WITHOUT_NAMESPACE, API_WITH_NAMESPACE之外情况 @@ -71,19 +75,21 @@ impl ApiServer let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); let nats_cli = Arc::clone(&nats_cli); + let event_manager = event_manager.clone(); app = app.route(key, web::post().to( move |path, data| { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); let nats_cli = Arc::clone(&nats_cli); + let event_manager = event_manager.clone(); async move { match db_pool.get_connection() { Ok(mut conn) => { handler .default() - .create_api_with_namespace(path, data, &mut conn, nats_cli) + .create_api_with_namespace(path, data, &mut conn, nats_cli, event_manager) .await }, Err(_) => Err(actix_web::error::ErrorInternalServerError( @@ -573,102 +579,66 @@ impl ApiServer for (key, route) in config.watchall_routes() { if route == API_WITHOUT_NAMESPACE { let handler = Arc::clone(&handler); - let db_pool = Arc::clone(&db_pool); - let nats_cli = Arc::clone(&nats_cli); + let event_manager = event_manager.clone(); app = app.route(key, web::get().to( move |path, data| { let handler = Arc::clone(&handler); - let db_pool = Arc::clone(&db_pool); - let nats_cli = Arc::clone(&nats_cli); + let event_manager = event_manager.clone(); async move { - match db_pool.get_connection() { - Ok(mut conn) => { - handler - .default() - .watch_api_without_namespace(path, data, &mut conn, nats_cli) - .await - }, - Err(_) => Err(actix_web::error::ErrorInternalServerError( - "Failed to get database connection", - )), - } + handler + .default() + .watch_api_without_namespace(path, data, event_manager) + .await } })); } else if route == API_WITH_NAMESPACE { let handler = Arc::clone(&handler); - let db_pool = Arc::clone(&db_pool); - let nats_cli = Arc::clone(&nats_cli); + let event_manager = event_manager.clone(); app = app.route(key, web::get().to( move |path, data| { let handler = Arc::clone(&handler); - let db_pool = Arc::clone(&db_pool); - let nats_cli = Arc::clone(&nats_cli); + let event_manager = event_manager.clone(); async move { - match db_pool.get_connection() { - Ok(mut conn) => { - handler - .default() - .watch_api_with_namespace(path, data, &mut conn, nats_cli) - .await - }, - Err(_) => Err(actix_web::error::ErrorInternalServerError( - "Failed to get database connection", - )), - } + handler + .default() + .watch_api_with_namespace(path, data, event_manager) + .await } })); } else if route == APIS_WITHOUT_NAMESPACE { let handler = Arc::clone(&handler); - let db_pool = Arc::clone(&db_pool); - let nats_cli = Arc::clone(&nats_cli); + let event_manager = event_manager.clone(); app = app.route(key, web::get().to( move |path, data| { let handler = Arc::clone(&handler); - let db_pool = Arc::clone(&db_pool); - let nats_cli = Arc::clone(&nats_cli); + let event_manager = event_manager.clone(); async move { - match db_pool.get_connection() { - Ok(mut conn) => { - handler - .default() - .watch_apis_without_namespace(path, data, &mut conn, nats_cli) - .await - }, - Err(_) => Err(actix_web::error::ErrorInternalServerError( - "Failed to get database connection", - )), - } + handler + .default() + .watch_apis_without_namespace(path, data, event_manager) + .await } })); } else if route == APIS_WITH_NAMESPACE { let handler = Arc::clone(&handler); - let db_pool = Arc::clone(&db_pool); - let nats_cli = Arc::clone(&nats_cli); + let event_manager = event_manager.clone(); app = app.route(key, web::get().to( move |path, data| { let handler = Arc::clone(&handler); - let db_pool = Arc::clone(&db_pool); - let nats_cli = Arc::clone(&nats_cli); + let event_manager = event_manager.clone(); async move { - match db_pool.get_connection() { - Ok(mut conn) => { - handler - .default() - .watch_apis_with_namespace(path, data, &mut conn, nats_cli) - .await - }, - Err(_) => Err(actix_web::error::ErrorInternalServerError( - "Failed to get database connection", - )), - } + handler + .default() + .watch_apis_with_namespace(path, data, event_manager) + .await } })); } diff --git a/src/cores/handlers.rs b/src/cores/handlers.rs index 7fc4482..4f002c2 100644 --- a/src/cores/handlers.rs +++ b/src/cores/handlers.rs @@ -3,7 +3,7 @@ use std::fmt::Debug; use std::sync::{Arc, LazyLock, Mutex}; use std::time; use async_trait::async_trait; -use actix_web::{HttpResponse, Result, web}; +use actix_web::{HttpResponse, Result, web, Error}; use chrono::Utc; use diesel::{QueryResult, RunQueryDsl, QueryDsl, ExpressionMethods, OptionalExtension, QueryableByName}; use serde_json::json; @@ -11,11 +11,14 @@ use serde_json::Value; use crate::cores::db::DbConnection; use diesel::sql_types::{Text}; use actix_web::error::ErrorInternalServerError; +use actix_web::web::{Path, Query}; use feventbus::impls::nats::nats::NatsCli; use feventbus::message::Message; use feventbus::message; use feventbus::traits::producer::Producer; use serde::{Deserialize, Serialize}; +use tokio::sync::broadcast; +use actix_web::web::Bytes; // 定义全局哈希表来获取model名 static GLOBAL_HASHMAP: LazyLock>> = LazyLock::new(|| { @@ -56,6 +59,7 @@ pub trait Handler { data: web::Json, db_connection: &mut DbConnection, nats_cli: Arc, + event_manager: EventManager ) -> Result; // /apis/{group}/{version}/{plural} @@ -220,45 +224,29 @@ pub trait Handler { &self, info: web::Path<(String, String)>, data: web::Query, - db_connection: &mut DbConnection, - nats_cli: Arc, - ) -> Result { - // 实现逻辑 - Ok(HttpResponse::Ok().json("watch API without namespace")) - } + event_manager: EventManager + ) -> Result; async fn watch_api_with_namespace( &self, info: web::Path<(String, String, String)>, data: web::Query, - db_connection: &mut DbConnection, - nats_cli: Arc, - ) -> Result { - // 实现逻辑 - Ok(HttpResponse::Ok().json("watch API with namespace")) - } + event_manager: EventManager + ) -> Result; async fn watch_apis_without_namespace( &self, info: web::Path<(String, String, String)>, data: web::Query, - db_connection: &mut DbConnection, - nats_cli: Arc, - ) -> Result { - // 实现逻辑 - Ok(HttpResponse::Ok().json("watch APIS without namespace")) - } + event_manager: EventManager + ) -> Result; async fn watch_apis_with_namespace( &self, info: web::Path<(String, String, String, String)>, data: web::Query, - db_connection: &mut DbConnection, - nats_cli: Arc, - ) -> Result { - // 实现逻辑 - Ok(HttpResponse::Ok().json("watch APIS with namespace")) - } + event_manager: EventManager + ) -> Result; // 不满足以上请求路径的处理 fn default(&self) -> DefaultHandler; @@ -727,6 +715,59 @@ pub struct ApiServerMessage { pub content: Value, } + +// watch的事件类型 +#[derive(Clone, Debug, Serialize)] +pub enum EventType { + Create, + Update, + Delete, +} + +// 事件结构,包含事件类型和相关信息 +#[derive(Clone, Debug, Serialize)] +pub struct Event { + pub event_type: EventType, + pub message: Value +} + +// 事件管理器,管理不同资源类型的事件频道 +#[derive(Clone)] +pub struct EventManager { + // 使用 HashMap 来管理不同资源类型的广播通道 + resource_channels: Arc>>>, +} + +impl EventManager { + pub fn new() -> Self { + EventManager { + resource_channels: Arc::new(Mutex::new(HashMap::new())), + } + } + + // 获取资源类型对应的广播通道 + fn get_channel(&self, resource_type: &str) -> broadcast::Sender { + let mut channels = self.resource_channels.lock().unwrap(); + // 如果不存在该资源类型的通道,创建一个新的 + channels.entry(resource_type.to_string()).or_insert_with(|| { + let (tx, _) = broadcast::channel(100); // 创建一个容量为 100 的广播通道 + tx + }).clone() + } + + // 向指定资源类型广播事件 + pub async fn send_event(&self, resource_type: &str, event_type: EventType, message: Value) { + let channel = self.get_channel(resource_type); + + // 创建一个事件并发送到广播通道 + let event = Event { + event_type, + message, + }; + let _ = channel.send(event); // 发送事件 + } +} + #[async_trait] impl Handler for DefaultHandler { @@ -825,6 +866,7 @@ impl Handler for DefaultHandler { data: web::Json, db_connection: &mut DbConnection, nats_cli: Arc, + event_manager: EventManager, ) -> Result { let (version, namespace, plural) = info.into_inner(); let data = data.into_inner(); @@ -896,6 +938,10 @@ impl Handler for DefaultHandler { send_request(request_message, nats_cli).await.map_err(ErrorInternalServerError)?; + let resource_type = format!("{}/{}/{}", version, namespace, plural); + + event_manager.send_event(&resource_type, EventType::Create, data.clone()).await; + insert_into_table(db_connection, &plural, item_name, &data, &version, Some(&namespace)) .await .map_err(ErrorInternalServerError)?; @@ -1809,6 +1855,138 @@ impl Handler for DefaultHandler { Ok(HttpResponse::Ok().json(json_array)) } + async fn watch_api_without_namespace( + &self, + info: Path<(String, String)>, + _data: Query, + event_manager: EventManager + ) -> Result { + let (version, plural) = info.into_inner(); + let resource_type = format!("{}/{}", version, plural); + + let channel = event_manager.get_channel(&resource_type); + let mut rx = channel.subscribe(); + + let stream = async_stream::stream! { + loop { + match rx.recv().await { + Ok(event) => { + let json_event = serde_json::to_string(&event).unwrap(); + println!("{}", json_event); + yield Ok::(Bytes::from(json_event)); + } + Err(_) => { + yield Err(actix_web::error::ErrorInternalServerError("Error occurred").into()); + } + } + } + }; + + Ok(HttpResponse::Ok() + .content_type("text/event-stream") + .streaming(stream)) + } + + async fn watch_api_with_namespace( + &self, + info: Path<(String, String, String)>, + _data: Query, + event_manager: EventManager + ) -> Result { + let (version, namespace, plural) = info.into_inner(); + let resource_type = format!("{}/{}/{}", version, namespace, plural); + + let channel = event_manager.get_channel(&resource_type); + let mut rx = channel.subscribe(); + + let stream = async_stream::stream! { + loop { + match rx.recv().await { + Ok(event) => { + let json_event = serde_json::to_string(&event).unwrap(); + println!("{}", json_event); + yield Ok::(Bytes::from(json_event)); + } + Err(_) => { + yield Err(actix_web::error::ErrorInternalServerError("Error occurred").into()); + } + } + } + }; + + Ok(HttpResponse::Ok() + .content_type("text/event-stream") + .streaming(stream)) + } + + async fn watch_apis_without_namespace( + &self, + info: Path<(String, String, String)>, + _data: Query, + event_manager: EventManager + ) -> Result { + let (group, version, plural) = info.into_inner(); + let ver = format!("{}/{}", group, version); + let resource_type = format!("{}/{}", ver, plural); + + let channel = event_manager.get_channel(&resource_type); + let mut rx = channel.subscribe(); + + let stream = async_stream::stream! { + loop { + match rx.recv().await { + Ok(event) => { + let json_event = serde_json::to_string(&event).unwrap(); + println!("{}", json_event); + yield Ok::(Bytes::from(json_event)); + } + Err(_) => { + yield Err(actix_web::error::ErrorInternalServerError("Error occurred").into()); + } + } + } + }; + + Ok(HttpResponse::Ok() + .content_type("text/event-stream") + .streaming(stream)) + } + + async fn watch_apis_with_namespace( + &self, + info: Path<(String, String, String, String)>, + _data: Query, + event_manager: EventManager + ) -> Result { + let (group, version, namespace, plural) = info.into_inner(); + let ver = format!("{}/{}", group, version); + + let resource_type = format!("{}/{}/{}", ver, namespace, plural); + + let channel = event_manager.get_channel(&resource_type); + let mut rx = channel.subscribe(); + + let stream = async_stream::stream! { + loop { + match rx.recv().await { + Ok(event) => { + let json_event = serde_json::to_string(&event).unwrap(); + println!("{}", json_event); + yield Ok::(Bytes::from(json_event)); + } + Err(_) => { + yield Err(actix_web::error::ErrorInternalServerError("Error occurred").into()); + } + } + } + }; + + Ok(HttpResponse::Ok() + .content_type("text/event-stream") + .streaming(stream)) + } + + fn default(&self) -> DefaultHandler { DefaultHandler {} } -- Gitee From 2cab27da5b8b47da6e6286693cea1c75e0a88586 Mon Sep 17 00:00:00 2001 From: Yuichi <913637919@qq.com> Date: Fri, 29 Nov 2024 11:57:48 +0800 Subject: [PATCH 47/48] =?UTF-8?q?=E6=B7=BB=E5=8A=A0watchone=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.lock | 2 +- Cargo.toml | 2 +- database.sqlite | Bin 28672 -> 0 bytes src/cores/apiserver.rs | 120 +++++++++++++++--- src/cores/config.rs | 16 ++- src/cores/handlers.rs | 276 +++++++++++++++++++++++++++++++++++++---- 6 files changed, 371 insertions(+), 45 deletions(-) delete mode 100644 database.sqlite diff --git a/Cargo.lock b/Cargo.lock index 3e5ebe5..16e65dd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -940,7 +940,7 @@ dependencies = [ [[package]] name = "fleet_apiserver" -version = "0.3.4" +version = "0.4.0" dependencies = [ "actix-http", "actix-service", diff --git a/Cargo.toml b/Cargo.toml index 1e81aea..061a04d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "fleet_apiserver" -version = "0.3.4" +version = "0.4.0" license = "Apache-2.0" authors = ["wuheng ", "chenhongyu23@otcaix.iscas.ac.cn"] categories = ["api-bindings"] diff --git a/database.sqlite b/database.sqlite deleted file mode 100644 index a1b3c195131e86c810841e69f1bbcaf2ef949911..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 28672 zcmeI(OHboQ8~|`TfrKD}mz7Y&0m-#0Es^r@BQLU-hLEN#f!&6%-G^4z#4%YzVyCu~ zE~0w?_B*uqevJJBz3#P#o_gr1hn{-u-%bnxV$k+bE$rWlUo&HS=4U5T=0D!~wx-!C zyJwhPVzUx;kD_VnE0(1wDma(_A;TU?~yg>BO8s0W(v&Y^O>QfgG# zMro~9VVzWVWtN2rHe2k|Qoa05slFm+bMb_mtdp+llWg^fGAWPrw6(q9*bSsx&y}HER#>5|l zLa~R7GzEp#H`ezZ`0pi?zHPYsvZEmj&N6)bV=x?BUZzhsUA?Yq6Q}Opdg_9rmpYQX zk!xFqsoMi6+3FNmU)clMHkkQ587 zz!$S(QOeIkyJ+Sw3O+cY01BW03ZMWApa2S>01BW03ZMWA+zEk&U_5fMOTdZ$2cydr zb8mhPRyd&m3ZMWApa2S>01BW03ZTH}DR9CCXBH#Nr`c+C-)LG*Vk@uH1L25+G4oG{ zW52l~=OuFq&Upy{QXUyi*zv}ubHyXBLz-&Gf-IxCuPQd=IwRm=-?B|jZ*y-GoYhkm zr>L!VdmVV~z}dd;6k~@dhHevhYrupnyoB1BZRb+NG|3@cN$ZmK*rl#q`qf*QCWMAl znT#mrvUzb*+<2Iohv@S0W?&{Zvv9Idt?EWgwXXOKgmal~DDmHEdPb|fv0guCOK?5Y z7-%ik+*m(P^=pkF3i*t{Pi`t?uJWtmahIN1iY%P$RI3U&8rL_c>=e1w9-`}pJ$%;y zs&w=HzI5{xquV9!Q}hw{Z*r4(Nz6!DpY}p#VRcn<;{QSB1I7H!d|>|gJiq4HY7{^L z6hHwKKmim$0Te(16hHwKxOD>er=iD+9`CLSMyH{Fh8}g!1ftW>zY*~|H=Ou?VD3+9 z-i8HED1ZVefC4Ch0w{n2D1ZVea0diVBZ0`$gQbOciWk^*{{bZxVyQ`9Xm^Yz>0BGS zzA@Hpl@)Idlnx(2hdm(q;1uG&8s=7AHBw^hs5Eg{_{%AiB^Bm{op6)gA<(r5w+5ug+ur?PR~X-_GWEG1)Sd1Jz9R4%#WjXu)8E6x1oL zSDu*f@ntb%QYjmtxLRQIJxin91`Ha?bc>W`#oL zG(ul{2pm diff --git a/src/cores/apiserver.rs b/src/cores/apiserver.rs index fc9c06e..1a0597a 100644 --- a/src/cores/apiserver.rs +++ b/src/cores/apiserver.rs @@ -50,19 +50,21 @@ impl ApiServer let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); let nats_cli = Arc::clone(&nats_cli); + let event_manager = event_manager.clone(); app = app.route(key, web::post().to( move |path, data| { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); let nats_cli = Arc::clone(&nats_cli); + let event_manager = event_manager.clone(); async move { match db_pool.get_connection() { Ok(mut conn) => { handler .default() - .create_api_without_namespace(path, data, &mut conn, nats_cli) + .create_api_without_namespace(path, data, &mut conn, nats_cli, event_manager) .await }, Err(_) => Err(actix_web::error::ErrorInternalServerError( @@ -102,19 +104,21 @@ impl ApiServer let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); let nats_cli = Arc::clone(&nats_cli); + let event_manager = event_manager.clone(); app = app.route(key, web::post().to( move |path, data| { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); let nats_cli = Arc::clone(&nats_cli); + let event_manager = event_manager.clone(); async move { match db_pool.get_connection() { Ok(mut conn) => { handler .default() - .create_apis_without_namespace(path, data, &mut conn, nats_cli) + .create_apis_without_namespace(path, data, &mut conn, nats_cli, event_manager) .await }, Err(_) => Err(actix_web::error::ErrorInternalServerError( @@ -127,19 +131,21 @@ impl ApiServer let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); let nats_cli = Arc::clone(&nats_cli); + let event_manager = event_manager.clone(); app = app.route(key, web::post().to( move |path, data| { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); let nats_cli = Arc::clone(&nats_cli); + let event_manager = event_manager.clone(); async move { match db_pool.get_connection() { Ok(mut conn) => { handler .default() - .create_apis_with_namespace(path, data, &mut conn, nats_cli) + .create_apis_with_namespace(path, data, &mut conn, nats_cli, event_manager) .await }, Err(_) => Err(actix_web::error::ErrorInternalServerError( @@ -158,19 +164,21 @@ impl ApiServer let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); let nats_cli = Arc::clone(&nats_cli); + let event_manager = event_manager.clone(); app = app.route(key, web::delete().to( move |path| { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); let nats_cli = Arc::clone(&nats_cli); + let event_manager = event_manager.clone(); async move { match db_pool.get_connection() { Ok(mut conn) => { handler .default() - .delete_api_without_namespace(path, &mut conn, nats_cli) + .delete_api_without_namespace(path, &mut conn, nats_cli, event_manager) .await }, Err(_) => Err(actix_web::error::ErrorInternalServerError( @@ -183,19 +191,21 @@ impl ApiServer let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); let nats_cli = Arc::clone(&nats_cli); + let event_manager = event_manager.clone(); app = app.route(key, web::delete().to( move |path| { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); let nats_cli = Arc::clone(&nats_cli); + let event_manager = event_manager.clone(); async move { match db_pool.get_connection() { Ok(mut conn) => { handler .default() - .delete_api_with_namespace(path, &mut conn, nats_cli) + .delete_api_with_namespace(path, &mut conn, nats_cli, event_manager) .await }, Err(_) => Err(actix_web::error::ErrorInternalServerError( @@ -208,19 +218,21 @@ impl ApiServer let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); let nats_cli = Arc::clone(&nats_cli); + let event_manager = event_manager.clone(); app = app.route(key, web::delete().to( move |path| { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); let nats_cli = Arc::clone(&nats_cli); + let event_manager = event_manager.clone(); async move { match db_pool.get_connection() { Ok(mut conn) => { handler .default() - .delete_apis_without_namespace(path, &mut conn, nats_cli) + .delete_apis_without_namespace(path, &mut conn, nats_cli, event_manager) .await }, Err(_) => Err(actix_web::error::ErrorInternalServerError( @@ -233,19 +245,21 @@ impl ApiServer let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); let nats_cli = Arc::clone(&nats_cli); + let event_manager = event_manager.clone(); app = app.route(key, web::delete().to( move |path| { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); let nats_cli = Arc::clone(&nats_cli); + let event_manager = event_manager.clone(); async move { match db_pool.get_connection() { Ok(mut conn) => { handler .default() - .delete_apis_with_namespace(path, &mut conn, nats_cli) + .delete_apis_with_namespace(path, &mut conn, nats_cli, event_manager) .await }, Err(_) => Err(actix_web::error::ErrorInternalServerError( @@ -264,19 +278,21 @@ impl ApiServer let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); let nats_cli = Arc::clone(&nats_cli); + let event_manager = event_manager.clone(); app = app.route(key, web::put().to( move |path, data| { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); let nats_cli = Arc::clone(&nats_cli); + let event_manager = event_manager.clone(); async move { match db_pool.get_connection() { Ok(mut conn) => { handler .default() - .update_api_without_namespace(path, data, &mut conn, nats_cli) + .update_api_without_namespace(path, data, &mut conn, nats_cli, event_manager) .await }, Err(_) => Err(actix_web::error::ErrorInternalServerError( @@ -289,19 +305,21 @@ impl ApiServer let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); let nats_cli = Arc::clone(&nats_cli); + let event_manager = event_manager.clone(); app = app.route(key, web::put().to( move |path, data| { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); let nats_cli = Arc::clone(&nats_cli); + let event_manager = event_manager.clone(); async move { match db_pool.get_connection() { Ok(mut conn) => { handler .default() - .update_api_with_namespace(path, data, &mut conn, nats_cli) + .update_api_with_namespace(path, data, &mut conn, nats_cli,event_manager) .await }, Err(_) => Err(actix_web::error::ErrorInternalServerError( @@ -314,19 +332,21 @@ impl ApiServer let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); let nats_cli = Arc::clone(&nats_cli); + let event_manager = event_manager.clone(); app = app.route(key, web::put().to( move |path, data| { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); let nats_cli = Arc::clone(&nats_cli); + let event_manager = event_manager.clone(); async move { match db_pool.get_connection() { Ok(mut conn) => { handler .default() - .update_apis_without_namespace(path, data, &mut conn, nats_cli) + .update_apis_without_namespace(path, data, &mut conn, nats_cli, event_manager) .await }, Err(_) => Err(actix_web::error::ErrorInternalServerError( @@ -339,19 +359,21 @@ impl ApiServer let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); let nats_cli = Arc::clone(&nats_cli); + let event_manager = event_manager.clone(); app = app.route(key, web::put().to( move |path, data| { let handler = Arc::clone(&handler); let db_pool = Arc::clone(&db_pool); let nats_cli = Arc::clone(&nats_cli); + let event_manager = event_manager.clone(); async move { match db_pool.get_connection() { Ok(mut conn) => { handler .default() - .update_apis_with_namespace(path, data, &mut conn, nats_cli) + .update_apis_with_namespace(path, data, &mut conn, nats_cli, event_manager) .await }, Err(_) => Err(actix_web::error::ErrorInternalServerError( @@ -589,7 +611,75 @@ impl ApiServer async move { handler .default() - .watch_api_without_namespace(path, data, event_manager) + .watchall_api_without_namespace(path, data, event_manager) + .await + } + })); + } else if route == API_WITH_NAMESPACE { + let handler = Arc::clone(&handler); + let event_manager = event_manager.clone(); + + app = app.route(key, web::get().to( + move |path, data| { + let handler = Arc::clone(&handler); + let event_manager = event_manager.clone(); + + async move { + handler + .default() + .watchall_api_with_namespace(path, data, event_manager) + .await + } + })); + } else if route == APIS_WITHOUT_NAMESPACE { + let handler = Arc::clone(&handler); + let event_manager = event_manager.clone(); + + app = app.route(key, web::get().to( + move |path, data| { + let handler = Arc::clone(&handler); + let event_manager = event_manager.clone(); + + async move { + handler + .default() + .watchall_apis_without_namespace(path, data, event_manager) + .await + } + })); + } else if route == APIS_WITH_NAMESPACE { + let handler = Arc::clone(&handler); + let event_manager = event_manager.clone(); + + app = app.route(key, web::get().to( + move |path, data| { + let handler = Arc::clone(&handler); + let event_manager = event_manager.clone(); + + async move { + handler + .default() + .watchall_apis_with_namespace(path, data, event_manager) + .await + } + })); + } + } + + for (key, route) in config.watchone_routes() { + if route == API_WITHOUT_NAMESPACE { + let handler = Arc::clone(&handler); + let event_manager = event_manager.clone(); + + app = app.route(key, web::get().to( + move |path, data| { + let handler = Arc::clone(&handler); + let event_manager = event_manager.clone(); + + async move { + handler + .default() + .watchone_api_without_namespace(path, data, event_manager) .await } })); @@ -605,7 +695,7 @@ impl ApiServer async move { handler .default() - .watch_api_with_namespace(path, data, event_manager) + .watchone_api_with_namespace(path, data, event_manager) .await } })); @@ -621,7 +711,7 @@ impl ApiServer async move { handler .default() - .watch_apis_without_namespace(path, data, event_manager) + .watchone_apis_without_namespace(path, data, event_manager) .await } })); @@ -637,7 +727,7 @@ impl ApiServer async move { handler .default() - .watch_apis_with_namespace(path, data, event_manager) + .watchone_apis_with_namespace(path, data, event_manager) .await } })); diff --git a/src/cores/config.rs b/src/cores/config.rs index 1ddcf8b..f741fca 100644 --- a/src/cores/config.rs +++ b/src/cores/config.rs @@ -93,7 +93,7 @@ pub trait Config: Sync + Send { fn watchall_routes(&self) -> &HashMap; - // TODO WatchOne和WatchAll两个接口 + fn watchone_routes(&self) -> &HashMap; } // Config接口的默认实现,用户可以自定义自己需要的URL规则 @@ -106,6 +106,7 @@ pub struct DefaultConfig { getone_routes: HashMap, listall_routes: HashMap, watchall_routes: HashMap, + watchone_routes: HashMap, } impl DefaultConfig { @@ -176,6 +177,17 @@ impl DefaultConfig { map.insert("/apis/{group}/{version}/watch/namespaces/{namespace}/{plural}".to_string(), APIS_WITH_NAMESPACE.to_string()); map.insert("/apis/{group}/{version}/watch/{plural}".to_string(), APIS_WITHOUT_NAMESPACE.to_string()); map + }, + watchone_routes: { + let mut map: HashMap = HashMap::new(); + // watch one resource: GET + // - with namespace: /api(s)/{group}/{version}/watch/namespaces/{namespace}/{plural}/{name} + // - without namespace/api(s)/{group}/{version}/watch/namespaces/{plural}/{name} + map.insert("/api/{version}/watch/namespaces/{namespace}/{plural}/{name}".to_string(), API_WITH_NAMESPACE.to_string()); + map.insert("/api/{version}/watch/{plural}/{name}".to_string(), API_WITHOUT_NAMESPACE.to_string()); + map.insert("/apis/{group}/{version}/watch/namespaces/{namespace}/{plural}/{name}".to_string(), APIS_WITH_NAMESPACE.to_string()); + map.insert("/apis/{group}/{version}/watch/{plural}/{name}".to_string(), APIS_WITHOUT_NAMESPACE.to_string()); + map } } } @@ -204,4 +216,6 @@ impl Config for DefaultConfig { fn listall_routes(&self) -> &HashMap { &self.listall_routes } fn watchall_routes(&self) -> &HashMap { &self.watchall_routes } + + fn watchone_routes(&self) -> &HashMap { &self.watchone_routes } } diff --git a/src/cores/handlers.rs b/src/cores/handlers.rs index 4f002c2..a3ec741 100644 --- a/src/cores/handlers.rs +++ b/src/cores/handlers.rs @@ -1,12 +1,12 @@ use std::collections::HashMap; use std::fmt::Debug; use std::sync::{Arc, LazyLock, Mutex}; -use std::time; +use std::{time}; use async_trait::async_trait; use actix_web::{HttpResponse, Result, web, Error}; use chrono::Utc; use diesel::{QueryResult, RunQueryDsl, QueryDsl, ExpressionMethods, OptionalExtension, QueryableByName}; -use serde_json::json; +use serde_json::{json}; use serde_json::Value; use crate::cores::db::DbConnection; use diesel::sql_types::{Text}; @@ -50,6 +50,7 @@ pub trait Handler { data: web::Json, db_connection: &mut DbConnection, nats_cli: Arc, + event_manager: EventManager ) -> Result; // /api/{version}/namespaces/{namespace}/{plural} @@ -69,6 +70,7 @@ pub trait Handler { data: web::Json, db_connection: &mut DbConnection, nats_cli: Arc, + event_manager: EventManager ) -> Result; // /apis/{group}/{version}/namespaces/{namespace}/{plural} @@ -78,6 +80,7 @@ pub trait Handler { data: web::Json, db_connection: &mut DbConnection, nats_cli: Arc, + event_manager: EventManager ) -> Result; // /api/{version}/{plural}/{name} @@ -86,6 +89,7 @@ pub trait Handler { info: web::Path<(String, String, String)>, db_connection: &mut DbConnection, nats_cli: Arc, + event_manager: EventManager ) -> Result; // /api/{version}/namespaces/{namespace}/{plural}/{name} @@ -94,6 +98,7 @@ pub trait Handler { info: web::Path<(String, String, String, String)>, db_connection: &mut DbConnection, nats_cli: Arc, + event_manager: EventManager ) -> Result; // /apis/{group}/{version}/{plural}/{name} @@ -102,6 +107,7 @@ pub trait Handler { info: web::Path<(String, String, String, String)>, db_connection: &mut DbConnection, nats_cli: Arc, + event_manager: EventManager ) -> Result; // /apis/{group}/{version}/namespaces/{namespace}/{plural}/{name} @@ -110,6 +116,7 @@ pub trait Handler { info: web::Path<(String, String, String, String, String)>, db_connection: &mut DbConnection, nats_cli: Arc, + event_manager: EventManager ) -> Result; // /api/{version}/{plural}/{name} @@ -119,6 +126,7 @@ pub trait Handler { data: web::Json, db_connection: &mut DbConnection, nats_cli: Arc, + event_manager: EventManager ) -> Result; // /api/{version}/namespaces/{namespace}/{plural}/{name} @@ -128,6 +136,7 @@ pub trait Handler { data: web::Json, db_connection: &mut DbConnection, nats_cli: Arc, + event_manager: EventManager ) -> Result; // /apis/{group}/{version}/{plural}/{name} @@ -137,6 +146,7 @@ pub trait Handler { data: web::Json, db_connection: &mut DbConnection, nats_cli: Arc, + event_manager: EventManager ) -> Result; // /apis/{group}/{version}/namespaces/{namespace}/{plural}/{name} @@ -146,6 +156,7 @@ pub trait Handler { data: web::Json, db_connection: &mut DbConnection, nats_cli: Arc, + event_manager: EventManager ) -> Result; // /api/{version}/{plural}/{name} @@ -220,34 +231,62 @@ pub trait Handler { nats_cli: Arc, ) -> Result; - async fn watch_api_without_namespace( + async fn watchall_api_without_namespace( &self, info: web::Path<(String, String)>, data: web::Query, event_manager: EventManager ) -> Result; - async fn watch_api_with_namespace( + async fn watchall_api_with_namespace( + &self, + info: web::Path<(String, String, String)>, + data: web::Query, + event_manager: EventManager + ) -> Result; + + async fn watchall_apis_without_namespace( &self, info: web::Path<(String, String, String)>, data: web::Query, event_manager: EventManager ) -> Result; - async fn watch_apis_without_namespace( + async fn watchall_apis_with_namespace( + &self, + info: web::Path<(String, String, String, String)>, + data: web::Query, + event_manager: EventManager + ) -> Result; + + async fn watchone_api_without_namespace( &self, info: web::Path<(String, String, String)>, data: web::Query, event_manager: EventManager ) -> Result; - async fn watch_apis_with_namespace( + async fn watchone_api_with_namespace( &self, info: web::Path<(String, String, String, String)>, data: web::Query, event_manager: EventManager ) -> Result; + async fn watchone_apis_without_namespace( + &self, + info: web::Path<(String, String, String, String)>, + data: web::Query, + event_manager: EventManager + ) -> Result; + + async fn watchone_apis_with_namespace( + &self, + info: web::Path<(String, String, String, String, String)>, + data: web::Query, + event_manager: EventManager + ) -> Result; + // 不满足以上请求路径的处理 fn default(&self) -> DefaultHandler; } @@ -697,14 +736,13 @@ where .await { Ok(response) => { - println!( - "===============Received response: {:?}==================", - response - ); - Ok(()) + if response.contains("Error handling reply") { + Err(Box::new(std::io::Error::new(std::io::ErrorKind::Other, "Error found in the eventbus reply!")) as Box) + } else { + Ok(()) + } } Err(e) => { - println!("Failed to get response: {:?}", e); Err(Box::new(e) as Box) } } @@ -778,6 +816,7 @@ impl Handler for DefaultHandler { data: web::Json, db_connection: &mut DbConnection, nats_cli: Arc, + event_manager: EventManager, ) -> Result { let (version, plural) = info.into_inner(); let data = data.into_inner(); @@ -851,6 +890,12 @@ impl Handler for DefaultHandler { send_request(request_message, nats_cli).await.map_err(ErrorInternalServerError)?; + let resource_type = format!("{}/{}", version, plural); + let watchone_resource_type = format!("{}/{}/{}", version, plural, item_name); + + event_manager.send_event(&resource_type, EventType::Create, data.clone()).await; + event_manager.send_event(&watchone_resource_type, EventType::Create, data.clone()).await; + insert_into_table(db_connection, &plural, item_name, &data, &version, None) .await .map_err(ErrorInternalServerError)?; @@ -939,8 +984,10 @@ impl Handler for DefaultHandler { send_request(request_message, nats_cli).await.map_err(ErrorInternalServerError)?; let resource_type = format!("{}/{}/{}", version, namespace, plural); + let watchone_resource_type = format!("{}/{}/{}/{}", version, namespace, plural, item_name); event_manager.send_event(&resource_type, EventType::Create, data.clone()).await; + event_manager.send_event(&watchone_resource_type, EventType::Create, data.clone()).await; insert_into_table(db_connection, &plural, item_name, &data, &version, Some(&namespace)) .await @@ -957,6 +1004,7 @@ impl Handler for DefaultHandler { data: web::Json, db_connection: &mut DbConnection, nats_cli: Arc, + event_manager: EventManager, ) -> Result { let (group, version, plural) = info.into_inner(); let ver = group + "/" + &*version; @@ -1029,6 +1077,12 @@ impl Handler for DefaultHandler { send_request(request_message, nats_cli).await.map_err(ErrorInternalServerError)?; + let resource_type = format!("{}/{}", ver, plural); + let watchone_resource_type = format!("{}/{}/{}", ver, plural, item_name); + + event_manager.send_event(&resource_type, EventType::Create, data.clone()).await; + event_manager.send_event(&watchone_resource_type, EventType::Create, data.clone()).await; + insert_into_table(db_connection, &plural, item_name, &data, &ver, None) .await .map_err(ErrorInternalServerError)?; @@ -1044,6 +1098,7 @@ impl Handler for DefaultHandler { data: web::Json, db_connection: &mut DbConnection, nats_cli: Arc, + event_manager: EventManager, ) -> Result { let (group, version, namespace, plural) = info.into_inner(); @@ -1117,6 +1172,12 @@ impl Handler for DefaultHandler { send_request(request_message, nats_cli).await.map_err(ErrorInternalServerError)?; + let resource_type = format!("{}/{}/{}", ver, namespace, plural); + let watchone_resource_type = format!("{}/{}/{}/{}", ver, namespace, plural, item_name); + + event_manager.send_event(&resource_type, EventType::Create, data.clone()).await; + event_manager.send_event(&watchone_resource_type, EventType::Create, data.clone()).await; + insert_into_table(db_connection, &plural, item_name, &data, &ver, Some(&namespace)) .await .map_err(ErrorInternalServerError)?; @@ -1131,6 +1192,7 @@ impl Handler for DefaultHandler { info: web::Path<(String, String, String)>, db_connection: &mut DbConnection, nats_cli: Arc, + event_manager: EventManager, ) -> Result { let (version, plural, name) = info.into_inner(); @@ -1167,13 +1229,19 @@ impl Handler for DefaultHandler { message::NativeEventAction::Other, Some(model_map), Some(ApiServerMessage { - content: request_data, + content: request_data.clone(), }), None, ); send_request(request_message, nats_cli).await.map_err(ErrorInternalServerError)?; + let resource_type = format!("{}/{}", version, plural); + let watchone_resource_type = format!("{}/{}/{}", version, plural, name); + + event_manager.send_event(&resource_type, EventType::Delete, request_data.clone()).await; + event_manager.send_event(&watchone_resource_type, EventType::Delete, request_data).await; + // 从 plural 表中删除指定的 name let deleted = delete_from_table(db_connection, &plural, &name, &version, None) .await @@ -1192,6 +1260,7 @@ impl Handler for DefaultHandler { info: web::Path<(String, String, String, String)>, db_connection: &mut DbConnection, nats_cli: Arc, + event_manager: EventManager, ) -> Result { let (version, namespace, plural, name) = info.into_inner(); // 检查 metadata 中是否存在该 plural 且需要 namespace @@ -1227,12 +1296,18 @@ impl Handler for DefaultHandler { message::NativeEventAction::Other, Some(model_map), Some(ApiServerMessage { - content: request_data, + content: request_data.clone(), }), None, ); send_request(request_message, nats_cli).await.map_err(ErrorInternalServerError)?; + let resource_type = format!("{}/{}/{}", version, namespace, plural); + let watchone_resource_type = format!("{}/{}/{}/{}", version, namespace, plural, name); + + event_manager.send_event(&resource_type, EventType::Delete, request_data.clone()).await; + event_manager.send_event(&watchone_resource_type, EventType::Delete, request_data).await; + // 从 plural 表中删除指定的数据 let deleted = delete_from_table(db_connection, &plural, &name, &version, Some(&namespace)) .await @@ -1251,6 +1326,7 @@ impl Handler for DefaultHandler { info: web::Path<(String, String, String, String)>, db_connection: &mut DbConnection, nats_cli: Arc, + event_manager: EventManager, ) -> Result { let (group, version, plural, name) = info.into_inner(); let ver = format!("{}/{}", group, version); @@ -1287,12 +1363,18 @@ impl Handler for DefaultHandler { message::NativeEventAction::Other, Some(model_map), Some(ApiServerMessage { - content: request_data, + content: request_data.clone(), }), None, ); send_request(request_message, nats_cli).await.map_err(ErrorInternalServerError)?; + let resource_type = format!("{}/{}", ver, plural); + let watchone_resource_type = format!("{}/{}/{}", ver, plural, name); + + event_manager.send_event(&resource_type, EventType::Delete, request_data.clone()).await; + event_manager.send_event(&watchone_resource_type, EventType::Delete, request_data).await; + let deleted = delete_from_table(db_connection, &plural, &name, &ver, None) .await .map_err(ErrorInternalServerError)?; @@ -1310,6 +1392,7 @@ impl Handler for DefaultHandler { info: web::Path<(String, String, String, String, String)>, db_connection: &mut DbConnection, nats_cli: Arc, + event_manager: EventManager, ) -> Result { let (group, version, namespace, plural, name) = info.into_inner(); let ver = format!("{}/{}", group, version); @@ -1346,12 +1429,18 @@ impl Handler for DefaultHandler { message::NativeEventAction::Other, Some(model_map), Some(ApiServerMessage { - content: request_data, + content: request_data.clone(), }), None, ); send_request(request_message, nats_cli).await.map_err(ErrorInternalServerError)?; + let resource_type = format!("{}/{}/{}", ver, namespace, plural); + let watchone_resource_type = format!("{}/{}/{}/{}", ver, namespace, plural, name); + + event_manager.send_event(&resource_type, EventType::Delete, request_data.clone()).await; + event_manager.send_event(&watchone_resource_type, EventType::Delete, request_data).await; + let deleted = delete_from_table(db_connection, &plural, &name, &ver, Some(&namespace)) .await .map_err(ErrorInternalServerError)?; @@ -1370,6 +1459,7 @@ impl Handler for DefaultHandler { data: web::Json, db_connection: &mut DbConnection, nats_cli: Arc, + event_manager: EventManager, ) -> Result { let (version, plural, name) = info.into_inner(); let data = data.into_inner(); @@ -1407,12 +1497,18 @@ impl Handler for DefaultHandler { message::NativeEventAction::Other, Some(model_map), Some(ApiServerMessage { - content: request_data, + content: request_data.clone(), }), None, ); send_request(request_message, nats_cli).await.map_err(ErrorInternalServerError)?; + let resource_type = format!("{}/{}", version, plural); + let watchone_resource_type = format!("{}/{}/{}", version, plural, name); + + event_manager.send_event(&resource_type, EventType::Update, request_data.clone()).await; + event_manager.send_event(&watchone_resource_type, EventType::Update, request_data).await; + // 查询 plural 表中是否存在 name 匹配的数据 let updated = update_data_in_table(db_connection, &plural, &name, &version, None, &data) .await @@ -1432,6 +1528,7 @@ impl Handler for DefaultHandler { data: web::Json, db_connection: &mut DbConnection, nats_cli: Arc, + event_manager: EventManager, ) -> Result { let (version, namespace, plural, name) = info.into_inner(); let data = data.into_inner(); @@ -1470,12 +1567,18 @@ impl Handler for DefaultHandler { message::NativeEventAction::Other, Some(model_map), Some(ApiServerMessage { - content: request_data, + content: request_data.clone(), }), None, ); send_request(request_message, nats_cli).await.map_err(ErrorInternalServerError)?; + let resource_type = format!("{}/{}/{}", version, namespace, plural); + let watchone_resource_type = format!("{}/{}/{}/{}", version, namespace, plural, name); + + event_manager.send_event(&resource_type, EventType::Update, request_data.clone()).await; + event_manager.send_event(&watchone_resource_type, EventType::Update, request_data).await; + let updated = update_data_in_table(db_connection, &plural, &name, &version, Some(&namespace), &data) .await .map_err(ErrorInternalServerError)?; @@ -1494,6 +1597,7 @@ impl Handler for DefaultHandler { data: web::Json, db_connection: &mut DbConnection, nats_cli: Arc, + event_manager: EventManager, ) -> Result { let (group, version, plural, name) = info.into_inner(); let ver = format!("{}/{}", group, version); @@ -1532,12 +1636,18 @@ impl Handler for DefaultHandler { message::NativeEventAction::Other, Some(model_map), Some(ApiServerMessage { - content: request_data, + content: request_data.clone(), }), None, ); send_request(request_message, nats_cli).await.map_err(ErrorInternalServerError)?; + let resource_type = format!("{}/{}", ver, plural); + let watchone_resource_type = format!("{}/{}/{}", ver, plural, name); + + event_manager.send_event(&resource_type, EventType::Update, request_data.clone()).await; + event_manager.send_event(&watchone_resource_type, EventType::Update, request_data).await; + let updated = update_data_in_table(db_connection, &plural, &name, &ver, None, &data) .await .map_err(ErrorInternalServerError)?; @@ -1556,6 +1666,7 @@ impl Handler for DefaultHandler { data: web::Json, db_connection: &mut DbConnection, nats_cli: Arc, + event_manager: EventManager, ) -> Result { let (group, version, namespace, plural, name) = info.into_inner(); let ver = format!("{}/{}", group, version); @@ -1594,12 +1705,18 @@ impl Handler for DefaultHandler { message::NativeEventAction::Other, Some(model_map), Some(ApiServerMessage { - content: request_data, + content: request_data.clone(), }), None, ); send_request(request_message, nats_cli).await.map_err(ErrorInternalServerError)?; + let resource_type = format!("{}/{}/{}", ver, namespace, plural); + let watchone_resource_type = format!("{}/{}/{}/{}", ver, namespace, plural, name); + + event_manager.send_event(&resource_type, EventType::Update, request_data.clone()).await; + event_manager.send_event(&watchone_resource_type, EventType::Update, request_data).await; + let updated = update_data_in_table(db_connection, &plural, &name, &ver, Some(&namespace), &data) .await .map_err(ErrorInternalServerError)?; @@ -1855,7 +1972,7 @@ impl Handler for DefaultHandler { Ok(HttpResponse::Ok().json(json_array)) } - async fn watch_api_without_namespace( + async fn watchall_api_without_namespace( &self, info: Path<(String, String)>, _data: Query, @@ -1887,7 +2004,7 @@ impl Handler for DefaultHandler { .streaming(stream)) } - async fn watch_api_with_namespace( + async fn watchall_api_with_namespace( &self, info: Path<(String, String, String)>, _data: Query, @@ -1904,7 +2021,6 @@ impl Handler for DefaultHandler { match rx.recv().await { Ok(event) => { let json_event = serde_json::to_string(&event).unwrap(); - println!("{}", json_event); yield Ok::(Bytes::from(json_event)); } Err(_) => { @@ -1919,7 +2035,7 @@ impl Handler for DefaultHandler { .streaming(stream)) } - async fn watch_apis_without_namespace( + async fn watchall_apis_without_namespace( &self, info: Path<(String, String, String)>, _data: Query, @@ -1937,7 +2053,6 @@ impl Handler for DefaultHandler { match rx.recv().await { Ok(event) => { let json_event = serde_json::to_string(&event).unwrap(); - println!("{}", json_event); yield Ok::(Bytes::from(json_event)); } Err(_) => { @@ -1952,7 +2067,7 @@ impl Handler for DefaultHandler { .streaming(stream)) } - async fn watch_apis_with_namespace( + async fn watchall_apis_with_namespace( &self, info: Path<(String, String, String, String)>, _data: Query, @@ -1971,7 +2086,114 @@ impl Handler for DefaultHandler { match rx.recv().await { Ok(event) => { let json_event = serde_json::to_string(&event).unwrap(); - println!("{}", json_event); + yield Ok::(Bytes::from(json_event)); + } + Err(_) => { + yield Err(actix_web::error::ErrorInternalServerError("Error occurred").into()); + } + } + } + }; + + Ok(HttpResponse::Ok() + .content_type("text/event-stream") + .streaming(stream)) + } + + async fn watchone_api_without_namespace(&self, info: Path<(String, String, String)>, _data: Query, event_manager: EventManager) -> Result { + let (version, plural, name) = info.into_inner(); + let resource_type = format!("{}/{}/{}", version, plural, name); + + let channel = event_manager.get_channel(&resource_type); + let mut rx = channel.subscribe(); + + let stream = async_stream::stream! { + loop { + match rx.recv().await { + Ok(event) => { + let json_event = serde_json::to_string(&event).unwrap(); + yield Ok::(Bytes::from(json_event)); + } + Err(_) => { + yield Err(actix_web::error::ErrorInternalServerError("Error occurred").into()); + } + } + } + }; + + Ok(HttpResponse::Ok() + .content_type("text/event-stream") + .streaming(stream)) + } + + async fn watchone_api_with_namespace(&self, info: Path<(String, String, String, String)>, _data: Query, event_manager: EventManager) -> Result { + let (version, namespace, plural, name) = info.into_inner(); + let resource_type = format!("{}/{}/{}/{}", version, namespace, plural, name); + + let channel = event_manager.get_channel(&resource_type); + let mut rx = channel.subscribe(); + + let stream = async_stream::stream! { + loop { + match rx.recv().await { + Ok(event) => { + let json_event = serde_json::to_string(&event).unwrap(); + yield Ok::(Bytes::from(json_event)); + } + Err(_) => { + yield Err(actix_web::error::ErrorInternalServerError("Error occurred").into()); + } + } + } + }; + + Ok(HttpResponse::Ok() + .content_type("text/event-stream") + .streaming(stream)) + } + + async fn watchone_apis_without_namespace(&self, info: Path<(String, String, String, String)>, _data: Query, event_manager: EventManager) -> Result { + let (group, version, plural, name) = info.into_inner(); + let ver = format!("{}/{}", group, version); + + let resource_type = format!("{}/{}/{}", ver, plural, name); + + let channel = event_manager.get_channel(&resource_type); + let mut rx = channel.subscribe(); + + let stream = async_stream::stream! { + loop { + match rx.recv().await { + Ok(event) => { + let json_event = serde_json::to_string(&event).unwrap(); + yield Ok::(Bytes::from(json_event)); + } + Err(_) => { + yield Err(actix_web::error::ErrorInternalServerError("Error occurred").into()); + } + } + } + }; + + Ok(HttpResponse::Ok() + .content_type("text/event-stream") + .streaming(stream)) + } + + async fn watchone_apis_with_namespace(&self, info: Path<(String, String, String, String, String)>, _data: Query, event_manager: EventManager) -> Result { + let (group, version, namespace, plural, name) = info.into_inner(); + let ver = format!("{}/{}", group, version); + + let resource_type = format!("{}/{}/{}/{}", ver, namespace, plural, name); + + let channel = event_manager.get_channel(&resource_type); + let mut rx = channel.subscribe(); + + let stream = async_stream::stream! { + loop { + match rx.recv().await { + Ok(event) => { + let json_event = serde_json::to_string(&event).unwrap(); yield Ok::(Bytes::from(json_event)); } Err(_) => { -- Gitee From 543bb4bf2a25bc290f52015f03e5a2b3027670ab Mon Sep 17 00:00:00 2001 From: Yuichi <913637919@qq.com> Date: Fri, 29 Nov 2024 15:07:01 +0800 Subject: [PATCH 48/48] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Cargo.lock | 2 +- Cargo.toml | 2 +- database.sqlite | Bin 28672 -> 0 bytes 3 files changed, 2 insertions(+), 2 deletions(-) delete mode 100644 database.sqlite diff --git a/Cargo.lock b/Cargo.lock index 16e65dd..4a3d527 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -940,7 +940,7 @@ dependencies = [ [[package]] name = "fleet_apiserver" -version = "0.4.0" +version = "0.3.5" dependencies = [ "actix-http", "actix-service", diff --git a/Cargo.toml b/Cargo.toml index 061a04d..66c88d3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "fleet_apiserver" -version = "0.4.0" +version = "0.3.5" license = "Apache-2.0" authors = ["wuheng ", "chenhongyu23@otcaix.iscas.ac.cn"] categories = ["api-bindings"] diff --git a/database.sqlite b/database.sqlite deleted file mode 100644 index a1b3c195131e86c810841e69f1bbcaf2ef949911..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 28672 zcmeI(OHboQ8~|`TfrKD}mz7Y&0m-#0Es^r@BQLU-hLEN#f!&6%-G^4z#4%YzVyCu~ zE~0w?_B*uqevJJBz3#P#o_gr1hn{-u-%bnxV$k+bE$rWlUo&HS=4U5T=0D!~wx-!C zyJwhPVzUx;kD_VnE0(1wDma(_A;TU?~yg>BO8s0W(v&Y^O>QfgG# zMro~9VVzWVWtN2rHe2k|Qoa05slFm+bMb_mtdp+llWg^fGAWPrw6(q9*bSsx&y}HER#>5|l zLa~R7GzEp#H`ezZ`0pi?zHPYsvZEmj&N6)bV=x?BUZzhsUA?Yq6Q}Opdg_9rmpYQX zk!xFqsoMi6+3FNmU)clMHkkQ587 zz!$S(QOeIkyJ+Sw3O+cY01BW03ZMWApa2S>01BW03ZMWA+zEk&U_5fMOTdZ$2cydr zb8mhPRyd&m3ZMWApa2S>01BW03ZTH}DR9CCXBH#Nr`c+C-)LG*Vk@uH1L25+G4oG{ zW52l~=OuFq&Upy{QXUyi*zv}ubHyXBLz-&Gf-IxCuPQd=IwRm=-?B|jZ*y-GoYhkm zr>L!VdmVV~z}dd;6k~@dhHevhYrupnyoB1BZRb+NG|3@cN$ZmK*rl#q`qf*QCWMAl znT#mrvUzb*+<2Iohv@S0W?&{Zvv9Idt?EWgwXXOKgmal~DDmHEdPb|fv0guCOK?5Y z7-%ik+*m(P^=pkF3i*t{Pi`t?uJWtmahIN1iY%P$RI3U&8rL_c>=e1w9-`}pJ$%;y zs&w=HzI5{xquV9!Q}hw{Z*r4(Nz6!DpY}p#VRcn<;{QSB1I7H!d|>|gJiq4HY7{^L z6hHwKKmim$0Te(16hHwKxOD>er=iD+9`CLSMyH{Fh8}g!1ftW>zY*~|H=Ou?VD3+9 z-i8HED1ZVefC4Ch0w{n2D1ZVea0diVBZ0`$gQbOciWk^*{{bZxVyQ`9Xm^Yz>0BGS zzA@Hpl@)Idlnx(2hdm(q;1uG&8s=7AHBw^hs5Eg{_{%AiB^Bm{op6)gA<(r5w+5ug+ur?PR~X-_GWEG1)Sd1Jz9R4%#WjXu)8E6x1oL zSDu*f@ntb%QYjmtxLRQIJxin91`Ha?bc>W`#oL zG(ul{2pm -- Gitee