diff --git a/.env b/.env index 2a5716e..667317f 100644 --- a/.env +++ b/.env @@ -1,2 +1,2 @@ MONGO_URI=mongodb://localhost:27017 -MONGO_DB_NAME=sensors +MONGO_DB_NAME=online diff --git a/.env_template b/.env_template index 2a5716e..6e86c4d 100644 --- a/.env_template +++ b/.env_template @@ -1,2 +1,2 @@ MONGO_URI=mongodb://localhost:27017 -MONGO_DB_NAME=sensors +MONGO_DB_NAME=online \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 46f57fd..043c690 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -120,7 +120,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] @@ -131,7 +131,7 @@ checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] @@ -237,7 +237,7 @@ dependencies = [ "base64 0.13.1", "bitvec", "hex", - "indexmap", + "indexmap 2.5.0", "js-sys", "once_cell", "rand", @@ -256,9 +256,9 @@ checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "bytemuck" -version = "1.17.0" +version = "1.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fd4c6dcc3b0aea2f5c0b4b82c2b15fe39ddbc76041a310848f4706edf76bb31" +checksum = "773d90827bc3feecfb67fab12e24de0749aad83c74b9504ecde46237b5cd24e2" [[package]] name = "byteorder" @@ -274,9 +274,9 @@ checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" [[package]] name = "cc" -version = "1.1.13" +version = "1.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72db2f7947ecee9b03b510377e8bb9077afa27176fdbff55c51027e976fdcc48" +checksum = "57b6a275aa2903740dc87da01c62040406b8812552e97129a63ea8850a17c6e6" dependencies = [ "shlex", ] @@ -296,6 +296,7 @@ dependencies = [ "android-tzdata", "iana-time-zone", "num-traits", + "serde", "windows-targets 0.52.6", ] @@ -369,9 +370,9 @@ dependencies = [ [[package]] name = "darling" -version = "0.13.4" +version = "0.20.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a01d95850c592940db9b8194bc39f4bc0e89dee5c4265e4b1807c34a9aba453c" +checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" dependencies = [ "darling_core", "darling_macro", @@ -379,27 +380,27 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.13.4" +version = "0.20.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "859d65a907b6852c9361e3185c862aae7fafd2887876799fa55f5f99dc40d610" +checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", "strsim", - "syn 1.0.109", + "syn 2.0.77", ] [[package]] name = "darling_macro" -version = "0.13.4" +version = "0.20.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c972679f83bdf9c42bd905396b6c3588a843a17f0f16dfcfa3e2c5d57441835" +checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core", "quote", - "syn 1.0.109", + "syn 2.0.77", ] [[package]] @@ -415,6 +416,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" dependencies = [ "powerfmt", + "serde", ] [[package]] @@ -437,8 +439,8 @@ dependencies = [ "convert_case", "proc-macro2", "quote", - "rustc_version 0.4.0", - "syn 2.0.75", + "rustc_version", + "syn 2.0.77", ] [[package]] @@ -449,9 +451,9 @@ checksum = "3c877555693c14d2f84191cfd3ad8582790fc52b5e2274b40b59cf5f5cea25c7" [[package]] name = "devise" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6eacefd3f541c66fc61433d65e54e0e46e0a029a819a7dbbc7a7b489e8a85f8" +checksum = "f1d90b0c4c777a2cad215e3c7be59ac7c15adf45cf76317009b7d096d46f651d" dependencies = [ "devise_codegen", "devise_core", @@ -459,9 +461,9 @@ dependencies = [ [[package]] name = "devise_codegen" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8cf4b8dd484ede80fd5c547592c46c3745a617c8af278e2b72bea86b2dfed6" +checksum = "71b28680d8be17a570a2334922518be6adc3f58ecc880cbb404eaeb8624fd867" dependencies = [ "devise_core", "quote", @@ -469,15 +471,15 @@ dependencies = [ [[package]] name = "devise_core" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35b50dba0afdca80b187392b24f2499a88c336d5a8493e4b4ccfb608708be56a" +checksum = "b035a542cf7abf01f2e3c4d5a7acbaebfefe120ae4efc7bde3df98186e4b8af7" dependencies = [ "bitflags 2.6.0", "proc-macro2", "proc-macro2-diagnostics", "quote", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] @@ -520,14 +522,14 @@ dependencies = [ [[package]] name = "enum-as-inner" -version = "0.4.0" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21cdad81446a7f7dc43f6a77409efeb9733d2fa65553efef6018ef257c959b73" +checksum = "5ffccbb6966c05b32ef8fbac435df276c4ae4d3dc55a8cd0eb9745e6c12f546a" dependencies = [ "heck", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.77", ] [[package]] @@ -557,9 +559,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.1.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" +checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" [[package]] name = "figment" @@ -652,7 +654,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] @@ -753,13 +755,19 @@ dependencies = [ "futures-sink", "futures-util", "http 0.2.12", - "indexmap", + "indexmap 2.5.0", "slab", "tokio", "tokio-util", "tracing", ] +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + [[package]] name = "hashbrown" version = "0.14.5" @@ -790,6 +798,51 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +[[package]] +name = "hickory-proto" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07698b8420e2f0d6447a436ba999ec85d8fbf2a398bbd737b82cac4a2e96e512" +dependencies = [ + "async-trait", + "cfg-if", + "data-encoding", + "enum-as-inner", + "futures-channel", + "futures-io", + "futures-util", + "idna 0.4.0", + "ipnet", + "once_cell", + "rand", + "thiserror", + "tinyvec", + "tokio", + "tracing", + "url", +] + +[[package]] +name = "hickory-resolver" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28757f23aa75c98f254cf0405e6d8c25b831b32921b050a66692427679b1f243" +dependencies = [ + "cfg-if", + "futures-util", + "hickory-proto", + "ipconfig", + "lru-cache", + "once_cell", + "parking_lot", + "rand", + "resolv-conf", + "smallvec", + "thiserror", + "tokio", + "tracing", +] + [[package]] name = "hkdf" version = "0.12.4" @@ -925,11 +978,10 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] name = "idna" -version = "0.2.3" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" +checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" dependencies = [ - "matches", "unicode-bidi", "unicode-normalization", ] @@ -946,12 +998,23 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.4.0" +version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93ead53efc7ea8ed3cfb0c79fc8023fbb782a5432b52830b6518941cebe6505c" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", + "serde", +] + +[[package]] +name = "indexmap" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5" dependencies = [ "equivalent", - "hashbrown", + "hashbrown 0.14.5", "serde", ] @@ -1015,8 +1078,8 @@ dependencies = [ ] [[package]] -name = "ks89-register" -version = "1.1.1" +name = "ks89-online" +version = "1.0.0" dependencies = [ "dotenvy", "envy", @@ -1025,7 +1088,6 @@ dependencies = [ "log4rs", "mongodb", "pretty_assertions", - "rand", "rocket", "serde", "serde_json", @@ -1148,12 +1210,6 @@ dependencies = [ "regex-automata 0.1.10", ] -[[package]] -name = "matches" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" - [[package]] name = "md-5" version = "0.10.6" @@ -1199,9 +1255,9 @@ dependencies = [ [[package]] name = "mongodb" -version = "3.0.1" +version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60f61f1556ee1d65e0b256e5bbc6d61e10022d1e3df86c23526d469bd832fa24" +checksum = "c857d71f918b38221baf2fdff7207fec9984b4504901544772b1edf0302d669f" dependencies = [ "async-trait", "base64 0.13.1", @@ -1215,6 +1271,8 @@ dependencies = [ "futures-io", "futures-util", "hex", + "hickory-proto", + "hickory-resolver", "hmac", "md-5", "mongodb-internal-macros", @@ -1238,8 +1296,6 @@ dependencies = [ "tokio", "tokio-rustls", "tokio-util", - "trust-dns-proto", - "trust-dns-resolver", "typed-builder", "uuid", "webpki-roots", @@ -1247,13 +1303,13 @@ dependencies = [ [[package]] name = "mongodb-internal-macros" -version = "3.0.1" +version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "934305ae9c66ef6a3aa728c66dec8fa2424de4dfcd043c7acaffacae2bf99442" +checksum = "3a6dbc533e93429a71c44a14c04547ac783b56d3f22e6c4f12b1b994cf93844e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] @@ -1312,9 +1368,9 @@ dependencies = [ [[package]] name = "object" -version = "0.36.3" +version = "0.36.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27b64972346851a39438c60b341ebc01bba47464ae329e55cf343eb93964efd9" +checksum = "084f1a5821ac4c651660a94a7153d27ac9d8a53736203f58b31945ded098070a" dependencies = [ "memchr", ] @@ -1398,7 +1454,7 @@ dependencies = [ "proc-macro2", "proc-macro2-diagnostics", "quote", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] @@ -1473,7 +1529,7 @@ checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.77", "version_check", "yansi 1.0.1", ] @@ -1486,9 +1542,9 @@ checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" [[package]] name = "quote" -version = "1.0.36" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -1555,7 +1611,7 @@ checksum = "bcc303e793d3734489387d205e9b186fac9c6cfacedd98cbb2e8a5943595f3e6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] @@ -1641,7 +1697,7 @@ dependencies = [ "either", "figment", "futures", - "indexmap", + "indexmap 2.5.0", "log", "memchr", "multer", @@ -1674,11 +1730,11 @@ checksum = "575d32d7ec1a9770108c879fc7c47815a80073f96ca07ff9525a94fcede1dd46" dependencies = [ "devise", "glob", - "indexmap", + "indexmap 2.5.0", "proc-macro2", "quote", "rocket_http", - "syn 2.0.75", + "syn 2.0.77", "unicode-xid", "version_check", ] @@ -1694,7 +1750,7 @@ dependencies = [ "futures", "http 0.2.12", "hyper", - "indexmap", + "indexmap 2.5.0", "log", "memchr", "pear", @@ -1719,37 +1775,28 @@ checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustc_version" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" -dependencies = [ - "semver 0.9.0", -] - -[[package]] -name = "rustc_version" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" dependencies = [ - "semver 1.0.23", + "semver", ] [[package]] name = "rustc_version_runtime" -version = "0.2.1" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d31b7153270ebf48bf91c65ae5b0c00e749c4cfad505f66530ac74950249582f" +checksum = "2dd18cd2bae1820af0b6ad5e54f4a51d0f3fcc53b05f845675074efcc7af071d" dependencies = [ - "rustc_version 0.2.3", - "semver 0.9.0", + "rustc_version", + "semver", ] [[package]] name = "rustix" -version = "0.38.34" +version = "0.38.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +checksum = "a85d50532239da68e9addb745ba38ff4612a242c1c7ceea689c4bc7c2f43c36f" dependencies = [ "bitflags 2.6.0", "errno", @@ -1823,32 +1870,17 @@ dependencies = [ "untrusted", ] -[[package]] -name = "semver" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" -dependencies = [ - "semver-parser", -] - [[package]] name = "semver" version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" -[[package]] -name = "semver-parser" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" - [[package]] name = "serde" -version = "1.0.208" +version = "1.0.209" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cff085d2cb684faa248efb494c39b68e522822ac0de72ccf08109abde717cfb2" +checksum = "99fce0ffe7310761ca6bf9faf5115afbc19688edd00171d81b1bb1b116c63e09" dependencies = [ "serde_derive", ] @@ -1874,22 +1906,22 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.208" +version = "1.0.209" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24008e81ff7613ed8e5ba0cfaf24e2c2f1e5b8a0495711e44fcd4882fca62bcf" +checksum = "a5831b979fd7b5439637af1752d535ff49f4860c0f341d1baeb6faf0f4242170" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] name = "serde_json" -version = "1.0.125" +version = "1.0.127" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83c8e735a073ccf5be70aa8066aa984eaf2fa000db6c8d0100ae605b366d31ed" +checksum = "8043c06d9f82bd7271361ed64f415fe5e12a77fdb52e573e7f06a516dea329ad" dependencies = [ - "indexmap", + "indexmap 2.5.0", "itoa", "memchr", "ryu", @@ -1907,24 +1939,32 @@ dependencies = [ [[package]] name = "serde_with" -version = "1.14.0" +version = "3.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "678b5a069e50bf00ecd22d0cd8ddf7c236f68581b03db652061ed5eb13a312ff" +checksum = "69cecfa94848272156ea67b2b1a53f20fc7bc638c4a46d2f8abde08f05f4b857" dependencies = [ + "base64 0.22.1", + "chrono", + "hex", + "indexmap 1.9.3", + "indexmap 2.5.0", "serde", + "serde_derive", + "serde_json", "serde_with_macros", + "time", ] [[package]] name = "serde_with_macros" -version = "1.5.2" +version = "3.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e182d6ec6f05393cc0e5ed1bf81ad6db3a8feedf8ee515ecdd369809bcce8082" +checksum = "a8fee4991ef4f274617a51ad4af30519438dacb2f56ac773b08a1922ff743350" dependencies = [ "darling", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.77", ] [[package]] @@ -1933,7 +1973,7 @@ version = "0.9.34+deprecated" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" dependencies = [ - "indexmap", + "indexmap 2.5.0", "itoa", "ryu", "serde", @@ -2048,9 +2088,9 @@ dependencies = [ [[package]] name = "strsim" -version = "0.10.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "subtle" @@ -2071,9 +2111,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.75" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6af063034fc1935ede7be0122941bafa9bacb949334d090b77ca98b5817c7d9" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -2122,7 +2162,7 @@ checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] @@ -2193,9 +2233,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.39.3" +version = "1.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9babc99b9923bfa4804bd74722ff02c0381021eafa4db9949217e3be8e84fff5" +checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998" dependencies = [ "backtrace", "bytes", @@ -2216,7 +2256,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] @@ -2281,7 +2321,7 @@ version = "0.22.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d" dependencies = [ - "indexmap", + "indexmap 2.5.0", "serde", "serde_spanned", "toml_datetime", @@ -2313,7 +2353,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] @@ -2355,51 +2395,6 @@ dependencies = [ "tracing-log", ] -[[package]] -name = "trust-dns-proto" -version = "0.21.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c31f240f59877c3d4bb3b3ea0ec5a6a0cff07323580ff8c7a605cd7d08b255d" -dependencies = [ - "async-trait", - "cfg-if", - "data-encoding", - "enum-as-inner", - "futures-channel", - "futures-io", - "futures-util", - "idna 0.2.3", - "ipnet", - "lazy_static", - "log", - "rand", - "smallvec", - "thiserror", - "tinyvec", - "tokio", - "url", -] - -[[package]] -name = "trust-dns-resolver" -version = "0.21.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4ba72c2ea84515690c9fcef4c6c660bb9df3036ed1051686de84605b74fd558" -dependencies = [ - "cfg-if", - "futures-util", - "ipconfig", - "lazy_static", - "log", - "lru-cache", - "parking_lot", - "resolv-conf", - "smallvec", - "thiserror", - "tokio", - "trust-dns-proto", -] - [[package]] name = "try-lock" version = "0.2.5" @@ -2546,7 +2541,7 @@ checksum = "ee1cd046f83ea2c4e920d6ee9f7c3537ef928d75dce5d84a87c2c5d6b3999a3a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.77", ] [[package]] @@ -2598,7 +2593,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.77", "wasm-bindgen-shared", ] @@ -2620,7 +2615,7 @@ checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.77", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -2892,5 +2887,5 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.75", + "syn 2.0.77", ] diff --git a/Cargo.toml b/Cargo.toml index 688e161..f35a455 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,15 +1,15 @@ [package] -name = "ks89-register" -version = "1.1.1" +name = "ks89-online" +version = "1.0.0" edition = "2021" resolver = "2" [[bin]] -name = "register" +name = "online" path = "src/main.rs" [lib] -name = "register" +name = "online" path = "src/lib.rs" [profile.release] @@ -20,7 +20,7 @@ panic = "abort" [dependencies] rocket = { version = "0.5.1", features = ["uuid", "secrets", "json"] } -mongodb = "^3.0.1" +mongodb = "^3.1.0" log = "^0.4.22" log4rs = { version = "^1.3.0", features = ["console_appender", "rolling_file_appender"] } dotenvy = "^0.15.7" @@ -31,14 +31,13 @@ futures = "^0.3.30" # The "derive" feature is only required when # using #[derive(Serialize, Deserialize)] to make Serde work with structs # and enums defined in your crate. -serde = { version = "^1.0.208", features = ["derive"] } -serde_json = "^1.0.125" +serde = { version = "^1.0.209", features = ["derive"] } +serde_json = "^1.0.127" [dev-dependencies] uuid = { version = "1.10.0", features = ["v4", "fast-rng", "macro-diagnostics"] } -rand = "0.8.5" # better looking rust assertions pretty_assertions = "^1.4.0" # include also serde_json with the feature 'preserve_order' to don't change the order of keys # 'preserve_order' is required to compare results in a predictible way in testing -serde_json = { version = "^1.0.125", features = ["preserve_order"] } +serde_json = { version = "^1.0.127", features = ["preserve_order"] } diff --git a/Dockerfile b/Dockerfile index b51699e..c879d8c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -48,6 +48,6 @@ WORKDIR /app COPY --from=builder /app/Rocket.toml Rocket.toml COPY --from=builder /app/log4rs.yaml log4rs.yaml COPY --from=builder /app/.env_template /.env -COPY --from=builder /app/target/release/register register +COPY --from=builder /app/target/release/online online -ENTRYPOINT ["./register"] +ENTRYPOINT ["./online"] diff --git a/README.md b/README.md index 215224c..62c772c 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@
home-anthill
-register +online @@ -15,20 +15,13 @@ Take a look here [home-anthill/docs](https://github.com/home-anthill/docs) ## :fire: Releases :fire: -DockerHub releases [HERE](https://hub.docker.com/repository/registry-1.docker.io/ks89/register/general) +DockerHub releases [HERE](https://hub.docker.com/repository/registry-1.docker.io/ks89/online/general) -GitHub releases [HERE](https://github.com/home-anthill/register/releases) +GitHub releases [HERE](https://github.com/home-anthill/online/releases) Versions: -- 20/08/2024 - 1.1.1 -- 20/08/2024 - 1.1.0 -- 19/08/2024 - 1.0.2 -- 19/05/2024 - 1.0.1 -- 19/05/2024 - 1.0.0 -- 08/03/2023 - 1.0.0-beta.3 -- 26/01/2023 - 1.0.0-beta.2 -- 11/01/2023 - 1.0.0-beta.1 +- 31/09/2024 - 1.0.0 ## :sparkling_heart: A big thank you to :sparkling_heart: diff --git a/src/db/mod.rs b/src/db/mod.rs index f89dc57..b9dfbcf 100644 --- a/src/db/mod.rs +++ b/src/db/mod.rs @@ -1,13 +1,13 @@ use crate::config::Env; -use std::env; -use std::future::Future; use log::{error, info, warn}; use mongodb::bson::doc; use mongodb::options::{ClientOptions, ServerApi, ServerApiVersion}; use mongodb::{Client, Database}; use rocket::fairing::AdHoc; +use std::env; +use std::future::Future; -pub mod sensor; +pub mod online; pub fn init(env_config: Env) -> AdHoc { AdHoc::on_ignite("Connecting to MongoDB", |rocket| async { @@ -21,12 +21,12 @@ pub fn init(env_config: Env) -> AdHoc { }) } -async fn connect(env_config: Env) -> mongodb::error::Result { +pub async fn connect(env_config: Env) -> mongodb::error::Result { let mongo_uri = env_config.mongo_uri.clone(); let mongo_db_name = if env::var("ENV") == Ok(String::from("testing")) { - warn!("TESTING ENVIRONMENT - forcing mongo_db_name = 'sensors_test'"); - String::from("sensors_test") + warn!("TESTING ENVIRONMENT - forcing mongo_db_name = 'online_test'"); + String::from("online_test") } else { env_config.mongo_db_name.clone() }; @@ -36,7 +36,7 @@ async fn connect(env_config: Env) -> mongodb::error::Result { let server_api = ServerApi::builder().version(ServerApiVersion::V1).build(); client_options.server_api = Some(server_api); // Set app_name - client_options.app_name = Some("register".to_string()); + client_options.app_name = Some("online".to_string()); // Create a new client and connect to the server let client = Client::with_options(client_options)?; @@ -51,7 +51,7 @@ async fn connect(env_config: Env) -> mongodb::error::Result { async fn retry_connect_mongodb(mut f: F, retries: usize) -> Result where F: FnMut() -> Fut, - Fut: Future>, + Fut: Future>, { let mut count = 0; loop { diff --git a/src/db/online.rs b/src/db/online.rs new file mode 100644 index 0000000..007f01e --- /dev/null +++ b/src/db/online.rs @@ -0,0 +1,21 @@ +use log::info; + +use mongodb::bson::{doc, Document}; +use mongodb::Database; + +use crate::errors::db_error::DbError; + +pub async fn find_online_by_uuid(db: &Database, uuid: &str) -> Result { + info!(target: "app", "find_online_by_uuid - Called with uuid = {} to get online status from db", uuid); + let collection = db.collection::("online"); + + let filter = doc! { "uuid": uuid }; + let projection = doc! {"_id": 0, "online": 1, "createdAt": 1, "modifiedAt": 1}; + match collection.find_one(filter).projection(projection).await { + Ok(doc_result) => match doc_result { + Some(doc) => Ok(doc), + None => Err(DbError::new(String::from("Cannot find online"), 404)), + }, + Err(err) => Err(DbError::new(err.to_string(), 500)), + } +} diff --git a/src/db/sensor.rs b/src/db/sensor.rs deleted file mode 100644 index 9cef616..0000000 --- a/src/db/sensor.rs +++ /dev/null @@ -1,66 +0,0 @@ -use log::{debug, error, info}; - -use mongodb::bson::{doc, Bson, Document}; -use mongodb::Database; -use rocket::serde::json::Json; - -use crate::errors::db_error::DbError; -use crate::models::inputs::RegisterInput; -use crate::models::sensor::{new_from_register_input, FloatSensor, IntSensor}; - -pub async fn insert_sensor(db: &Database, input: Json, sensor_type: &str) -> Result { - info!(target: "app", "insert_sensor - Called with sensor_type = {}", sensor_type); - - let collection = db.collection::(sensor_type); - - let serialized_input: Bson = match sensor_type { - "temperature" | "humidity" | "light" | "airpressure" => { - let result = new_from_register_input::(input); - match result { - Ok(res) => res, - Err(err) => return Err(DbError::new(err.to_string())), - } - } - "motion" | "airquality" => { - let result = new_from_register_input::(input); - match result { - Ok(res) => res, - Err(err) => return Err(DbError::new(err.to_string())), - } - } - _ => { - error!(target: "app", "insert_sensor - Unknown sensor_type = {}", sensor_type); - return Err(DbError::new(format!("Unknown sensor_type = {}", sensor_type))); - } - }; - - debug!(target: "app", "insert_sensor - Adding sensor into db"); - - let document = serialized_input.as_document().unwrap(); - let insert_one_result = collection.insert_one(document.to_owned()).await.unwrap(); - Ok(insert_one_result.inserted_id.as_object_id().unwrap().to_hex()) -} - -pub async fn find_sensor_value_by_uuid( - db: &Database, - uuid: &String, - sensor_type: &String, -) -> Result { - info!(target: "app", "find_sensor_value_by_uuid - Called with uuid = {}, sensor_type = {}", uuid, sensor_type); - let collection = db.collection::(sensor_type.as_str()); - - // find by uuid - let filter = doc! { "uuid": uuid }; - // limit the output to {"value", "createdAt" and "modifiedAt"} - let projection = doc! {"_id": 0, "value": 1, "createdAt": 1, "modifiedAt": 1}; - - debug!(target: "app", "find_sensor_value_by_uuid - Getting sensor value with uuid = {} from db", uuid); - - match collection.find_one(filter).projection(projection).await { - Ok(doc_result) => match doc_result { - Some(doc) => Ok(doc), - None => Err(DbError::new(String::from("Cannot find sensor"))), - }, - Err(err) => Err(DbError::new(err.to_string())), - } -} diff --git a/src/errors/api_error.rs b/src/errors/api_error.rs index 14d133e..f43a374 100644 --- a/src/errors/api_error.rs +++ b/src/errors/api_error.rs @@ -13,7 +13,7 @@ pub struct ApiResponse { #[rocket::async_trait] impl<'r> Responder<'r, 'r> for ApiResponse { fn respond_to(self, req: &'r Request<'_>) -> Result<'static> { - Response::build_from(self.json.respond_to(req).unwrap()) + Response::build_from(self.json.respond_to(req)?) .status(Status { code: self.code }) .header(ContentType::JSON) .ok() diff --git a/src/errors/db_error.rs b/src/errors/db_error.rs index 0baf00e..e2ecfb3 100644 --- a/src/errors/db_error.rs +++ b/src/errors/db_error.rs @@ -1,12 +1,13 @@ use rocket::serde::{Deserialize, Serialize}; -#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)] +#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)] pub struct DbError { pub message: String, + pub code: u16, } impl DbError { - pub fn new(message: String) -> Self { - Self { message } + pub fn new(message: String, code: u16) -> Self { + Self { message, code } } } diff --git a/src/main.rs b/src/main.rs index 8871e86..c4aa534 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,10 +4,10 @@ extern crate rocket; use log::info; use rocket::{Build, Rocket}; -use register::catchers; -use register::config::{init, Env}; -use register::db; -use register::routes; +use online::catchers; +use online::config::{init, Env}; +use online::db; +use online::routes; #[launch] fn rocket() -> Rocket { @@ -15,25 +15,13 @@ fn rocket() -> Rocket { let env: Env = init(); // 2. Init Rocket - // a) connect to DB + // a) assign Database to Rocket (you can get a reference inside REST functions) // b) define APIs // c) define error handlers info!(target: "app", "Starting Rocket..."); rocket::build() .attach(db::init(env)) - .mount( - "/", - routes![ - routes::api::post_register_temperature, - routes::api::post_register_humidity, - routes::api::post_register_light, - routes::api::post_register_motion, - routes::api::post_register_airquality, - routes::api::post_register_airpressure, - routes::api::get_sensor_value, - routes::api::keep_alive, - ], - ) + .mount("/", routes![routes::api::get_online, routes::api::keep_alive]) .register( "/", catchers![ diff --git a/src/models/inputs.rs b/src/models/inputs.rs deleted file mode 100644 index 1911fdc..0000000 --- a/src/models/inputs.rs +++ /dev/null @@ -1,12 +0,0 @@ -use serde::{Deserialize, Serialize}; - -#[allow(non_snake_case)] -#[derive(Debug, Serialize, Deserialize, Clone)] -pub struct RegisterInput { - pub uuid: String, - pub mac: String, - pub manufacturer: String, - pub model: String, - pub profileOwnerId: String, - pub apiToken: String, -} diff --git a/src/models/mod.rs b/src/models/mod.rs index e1ee3c0..e62e99d 100644 --- a/src/models/mod.rs +++ b/src/models/mod.rs @@ -1,2 +1 @@ -pub mod inputs; -pub mod sensor; +pub mod online; diff --git a/src/models/online.rs b/src/models/online.rs new file mode 100644 index 0000000..1da09e1 --- /dev/null +++ b/src/models/online.rs @@ -0,0 +1,26 @@ +use mongodb::bson::oid::ObjectId; +use mongodb::bson::DateTime; +use serde::{Deserialize, Serialize}; + +#[allow(non_snake_case)] +#[derive(Debug, Serialize, Deserialize, Clone)] +pub struct OnlineDocument { + #[serde(rename = "_id")] + pub id: ObjectId, + pub uuid: String, + pub apiToken: String, + pub createdAt: DateTime, + pub modifiedAt: DateTime, + pub online: bool, +} + +#[allow(non_snake_case)] +#[derive(Debug, Serialize, Deserialize, Clone)] +pub struct Online { + pub _id: String, + pub uuid: String, + pub apiToken: String, + pub createdAt: String, + pub modifiedAt: String, + pub online: bool, +} diff --git a/src/models/sensor.rs b/src/models/sensor.rs deleted file mode 100644 index b593503..0000000 --- a/src/models/sensor.rs +++ /dev/null @@ -1,146 +0,0 @@ -use std::str::FromStr; - -use mongodb::bson::oid::ObjectId; -use mongodb::bson::{oid, to_bson, Bson, DateTime}; -use oid::Error; -use rocket::serde::json::Json; -use serde::{Deserialize, Serialize}; - -use crate::models::inputs::RegisterInput; - -#[allow(non_snake_case)] -#[derive(Debug, Serialize, Deserialize, Clone)] -pub struct IntSensor { - #[serde(rename = "_id")] - pub id: ObjectId, - pub uuid: String, - pub mac: String, - pub manufacturer: String, - pub model: String, - pub profileOwnerId: ObjectId, - pub apiToken: String, - pub createdAt: DateTime, - pub modifiedAt: DateTime, - pub value: i64, -} - -#[allow(non_snake_case)] -#[derive(Debug, Serialize, Deserialize, Clone)] -pub struct FloatSensor { - #[serde(rename = "_id")] - pub id: ObjectId, - pub uuid: String, - pub mac: String, - pub manufacturer: String, - pub model: String, - pub profileOwnerId: ObjectId, - pub apiToken: String, - pub createdAt: DateTime, - pub modifiedAt: DateTime, - pub value: f64, -} - -pub trait Sensor { - fn new( - uuid: String, - mac: String, - manufacturer: String, - model: String, - profile_owner_id: ObjectId, - api_token: String, - ) -> Self; -} - -impl Sensor for IntSensor { - fn new( - uuid: String, - mac: String, - manufacturer: String, - model: String, - profile_owner_id: ObjectId, - api_token: String, - ) -> Self { - Self::new(uuid, mac, manufacturer, model, profile_owner_id, api_token) - } -} - -impl Sensor for FloatSensor { - fn new( - uuid: String, - mac: String, - manufacturer: String, - model: String, - profile_owner_id: ObjectId, - api_token: String, - ) -> Self { - Self::new(uuid, mac, manufacturer, model, profile_owner_id, api_token) - } -} - -impl IntSensor { - pub fn new( - uuid: String, - mac: String, - manufacturer: String, - model: String, - profile_owner_id: ObjectId, - api_token: String, - ) -> Self { - let date_now: DateTime = DateTime::now(); - Self { - id: ObjectId::new(), - uuid, - mac, - manufacturer, - model, - profileOwnerId: profile_owner_id, - apiToken: api_token, - createdAt: date_now, - modifiedAt: date_now, - value: 0, - } - } -} - -impl FloatSensor { - pub fn new( - uuid: String, - mac: String, - manufacturer: String, - model: String, - profile_owner_id: ObjectId, - api_token: String, - ) -> Self { - let date_now: DateTime = DateTime::now(); - Self { - id: ObjectId::new(), - uuid, - mac, - manufacturer, - model, - profileOwnerId: profile_owner_id, - apiToken: api_token, - createdAt: date_now, - modifiedAt: date_now, - value: 0.0, - } - } -} - -pub fn new_from_register_input(input: Json) -> Result { - let profile_owner_id = ObjectId::from_str(input.profileOwnerId.as_str()); - match profile_owner_id { - Ok(profile_id) => { - let result = T::new( - input.uuid.clone(), - input.mac.clone(), - input.manufacturer.clone(), - input.model.clone(), - profile_id, - input.apiToken.clone(), - ); - Ok(to_bson(&result).unwrap()) - } - Err(err) => Err(err), - } -} diff --git a/src/routes/api.rs b/src/routes/api.rs index d309d1f..396434e 100644 --- a/src/routes/api.rs +++ b/src/routes/api.rs @@ -2,12 +2,11 @@ use log::{debug, error, info}; use mongodb::bson::doc; use mongodb::Database; use rocket::http::Status; -use rocket::serde::json::{json, Json}; +use rocket::serde::json::json; use rocket::State; -use crate::db::sensor; +use crate::db::online; use crate::errors::api_error::{ApiError, ApiResponse}; -use crate::models::inputs::RegisterInput; /// keepalive #[get("/keepalive")] @@ -18,104 +17,20 @@ pub async fn keep_alive() -> ApiResponse { } } -/// register a new temperature sensor -#[post("/sensors/register/temperature", data = "")] -pub async fn post_register_temperature(db: &State, input: Json) -> ApiResponse { - info!(target: "app", "REST - POST - post_register_temperature"); - insert_register(db, input, "temperature").await -} - -/// register a new humidity sensor -#[post("/sensors/register/humidity", data = "")] -pub async fn post_register_humidity(db: &State, input: Json) -> ApiResponse { - info!(target: "app", "REST - POST - post_register_humidity"); - insert_register(db, input, "humidity").await -} - -/// register a new light sensor -#[post("/sensors/register/light", data = "")] -pub async fn post_register_light(db: &State, input: Json) -> ApiResponse { - info!(target: "app", "REST - POST - post_register_light"); - insert_register(db, input, "light").await -} - -/// register a new motion sensor -#[post("/sensors/register/motion", data = "")] -pub async fn post_register_motion(db: &State, input: Json) -> ApiResponse { - info!(target: "app", "REST - POST - post_register_motion"); - insert_register(db, input, "motion").await -} - -/// register a new airquality sensor -#[post("/sensors/register/airquality", data = "")] -pub async fn post_register_airquality(db: &State, input: Json) -> ApiResponse { - info!(target: "app", "REST - POST - post_register_airquality"); - insert_register(db, input, "airquality").await -} - -/// register a new airpressure sensor -#[post("/sensors/register/airpressure", data = "")] -pub async fn post_register_airpressure(db: &State, input: Json) -> ApiResponse { - info!(target: "app", "REST - POST - post_register_airpressure"); - insert_register(db, input, "airpressure").await -} - /// get sensor value by UUID and type -#[get("/sensors//")] -pub async fn get_sensor_value(db: &State, uuid: String, sensor_type: String) -> ApiResponse { - info!(target: "app", "REST - GET - get_sensor_value"); - find_sensor_value(db, uuid, sensor_type).await -} - -async fn insert_register(db: &State, input: Json, sensor_type: &str) -> ApiResponse { - debug!(target: "app", "insert_register - called with sensor_type = {}", sensor_type); - match sensor::insert_sensor(db, input, sensor_type).await { - Ok(register_doc_id) => { - debug!(target: "app", "insert_register - document inserted with id = {}", register_doc_id); - ApiResponse { - json: json!({ "id": register_doc_id }), - code: Status::Ok.code, - } - } - Err(error) => { - error!(target: "app", "insert_register - error = {:?}", error); - ApiResponse { - json: serde_json::to_value(ApiError { - message: "Invalid input".to_string(), - code: Status::BadRequest.code, - }) - .unwrap(), - code: Status::BadRequest.code, - } - } - } -} - -async fn find_sensor_value(db: &State, uuid: String, sensor_type: String) -> ApiResponse { - debug!(target: "app", "get_sensor - called with sensor_type = {}, uuid = {}", sensor_type, uuid); - match sensor::find_sensor_value_by_uuid(db, &uuid, &sensor_type).await { - Ok(sensor_doc) => { - info!(target: "app", "get_sensor - result sensor_doc = {}", sensor_doc); - let value: f64 = match sensor_type.as_str() { - "temperature" | "humidity" | "light" | "airpressure" => sensor_doc.get_f64("value").unwrap(), - "motion" | "airquality" => sensor_doc.get_i64("value").unwrap() as f64, - _ => { - return ApiResponse { - json: serde_json::to_value(ApiError { - message: "Unknown sensor type".to_string(), - code: Status::InternalServerError.code, - }) - .unwrap(), - code: Status::InternalServerError.code, - }; - } - }; - let created_at = sensor_doc.get_datetime("createdAt").unwrap().timestamp_millis(); - let modified_at = sensor_doc.get_datetime("modifiedAt").unwrap().timestamp_millis(); +#[get("/online/")] +pub async fn get_online(db: &State, uuid: &str) -> ApiResponse { + info!(target: "app", "REST - GET - get_online"); + debug!(target: "app", "REST - GET - called with uuid = {}", uuid); + match online::find_online_by_uuid(db, uuid).await { + Ok(online_doc) => { + info!(target: "app", "REST - GET - result online_doc = {}", online_doc); + let online = online_doc.get_bool("online").unwrap(); + let created_at = online_doc.get_datetime("createdAt").unwrap().timestamp_millis(); + let modified_at = online_doc.get_datetime("modifiedAt").unwrap().timestamp_millis(); ApiResponse { json: json!({ - // in json response, 'value' is always a f64, even if in db it's a i64 - "value": value, + "online": online, "createdAt": created_at, "modifiedAt": modified_at, }), @@ -123,14 +38,14 @@ async fn find_sensor_value(db: &State, uuid: String, sensor_type: Stri } } Err(error) => { - error!(target: "app", "get_sensor - error {:?}", error); + error!(target: "app", "REST - GET - error {:?}", &error); ApiResponse { json: serde_json::to_value(ApiError { message: "Internal server error".to_string(), - code: Status::InternalServerError.code, + code: error.clone().code, }) .unwrap(), - code: Status::InternalServerError.code, + code: error.clone().code, } } } diff --git a/src/tests_integration/db_utils.rs b/src/tests_integration/db_utils.rs index 6fa225a..7c63bad 100644 --- a/src/tests_integration/db_utils.rs +++ b/src/tests_integration/db_utils.rs @@ -1,18 +1,17 @@ -use mongodb::bson::{doc, Bson, Document}; -use mongodb::options::ClientOptions; -use mongodb::{Client, Database}; -use rocket::serde::json::Json as RocketJson; +use log::info; use std::env; -use register::models::inputs::RegisterInput; -use register::models::sensor::{new_from_register_input, FloatSensor, IntSensor}; +use mongodb::bson::DateTime; +use mongodb::bson::{doc, Document}; +use mongodb::options::ClientOptions; +use mongodb::{Client, Database}; pub async fn connect() -> mongodb::error::Result { let mongo_uri = env::var("MONGO_URI").expect("MONGO_URI is not found."); - let mongo_db_name = String::from("sensors_test"); + let mongo_db_name = String::from("online_test"); let mut client_options = ClientOptions::parse(mongo_uri).await?; - client_options.app_name = Some("register-test".to_string()); + client_options.app_name = Some("online-test".to_string()); let client = Client::with_options(client_options)?; let database = client.database(mongo_db_name.as_str()); @@ -21,81 +20,34 @@ pub async fn connect() -> mongodb::error::Result { Ok(database) } -pub async fn drop_all_collections(db: &Database) -> () { - db.collection::("temperature") - .drop() - .await - .expect("drop 'temperature' collection"); - db.collection::("humidity") - .drop() - .await - .expect("drop 'humidity' collection"); - db.collection::("light") - .drop() - .await - .expect("drop 'light' collection"); - db.collection::("motion") - .drop() - .await - .expect("drop 'motion' collection"); - db.collection::("airpressure") - .drop() - .await - .expect("drop 'airpressure' collection"); - db.collection::("airquality") +pub async fn drop_all_collections(db: &Database) { + db.collection::("online") .drop() .await - .expect("drop 'airquality' collection"); + .expect("drop 'online' collection"); } -pub async fn find_sensor_by_uuid( - db: &Database, - uuid: &String, - sensor_type: &str, -) -> mongodb::error::Result> { - let collection = db.collection::(sensor_type); +pub async fn find_online_by_uuid(db: &Database, uuid: &String) -> mongodb::error::Result> { + let collection = db.collection::("online"); let filter = doc! { "uuid": uuid }; collection.find_one(filter).await } -pub async fn insert_sensor( +pub async fn insert_online( db: &Database, - input: RocketJson, - sensor_type: &str, + uuid: &String, + api_token: &String, + online: bool, ) -> mongodb::error::Result { - let collection = db.collection::(sensor_type); - let serialized_data: Bson = match sensor_type { - "temperature" | "humidity" | "light" => new_from_register_input::(input).unwrap(), - "motion" | "airquality" | "airpressure" => new_from_register_input::(input).unwrap(), - _ => { - panic!("Unknown type") - } - }; - let document = serialized_data.as_document().unwrap(); - let insert_one_result = collection.insert_one(document.to_owned()).await?; + let collection = db.collection::("online"); + let insert_one_result = collection + .insert_one(doc! { + "uuid": uuid, + "apiToken": api_token, + "createdAt": DateTime::now(), + "modifiedAt": DateTime::now(), + "online": online, + }) + .await?; Ok(insert_one_result.inserted_id.as_object_id().unwrap().to_hex()) } - -pub async fn update_sensor_float_value_by_uuid( - db: &Database, - uuid: &String, - sensor_type: &str, - value: f64, -) -> mongodb::error::Result> { - let collection = db.collection::(sensor_type); - let filter = doc! { "uuid": uuid }; - let update = doc! {"$set": {"value": value}}; - collection.find_one_and_update(filter.clone(), update).await -} - -pub async fn update_sensor_int_value_by_uuid( - db: &Database, - uuid: &String, - sensor_type: &str, - value: i64, -) -> mongodb::error::Result> { - let collection = db.collection::(sensor_type); - let filter = doc! { "uuid": uuid }; - let update = doc! {"$set": {"value": value}}; - collection.find_one_and_update(filter.clone(), update).await -} diff --git a/src/tests_integration/errors_catchers.rs b/src/tests_integration/errors_catchers.rs index cba7a3c..46eb20a 100644 --- a/src/tests_integration/errors_catchers.rs +++ b/src/tests_integration/errors_catchers.rs @@ -1,5 +1,5 @@ use super::rocket; -use rocket::http::{ContentType, Status}; +use rocket::http::Status; use rocket::local::asynchronous::{Client, LocalRequest, LocalResponse}; #[rocket::async_test] @@ -11,16 +11,3 @@ async fn error_catcher_not_found() { assert_eq!(res.status(), Status::NotFound); assert_eq!(res.into_string().await.unwrap(), String::from("Not found")); } - -#[rocket::async_test] -async fn error_catcher_bad_request() { - let client: Client = Client::tracked(rocket()).await.unwrap(); - - let req: LocalRequest = client - .post("/sensors/register/temperature") - .header(ContentType::JSON) - .body("bad-input"); - let res: LocalResponse = req.dispatch().await; - assert_eq!(res.status(), Status::BadRequest); - assert_eq!(res.into_string().await.unwrap(), String::from("Bad request")); -} diff --git a/src/tests_integration/mod.rs b/src/tests_integration/mod.rs index f5bc33c..c846d07 100644 --- a/src/tests_integration/mod.rs +++ b/src/tests_integration/mod.rs @@ -2,8 +2,7 @@ use super::rocket; mod errors_catchers; mod keepalive; -mod register; +mod online; // test utils mod db_utils; -mod test_utils; diff --git a/src/tests_integration/online.rs b/src/tests_integration/online.rs new file mode 100644 index 0000000..89300b3 --- /dev/null +++ b/src/tests_integration/online.rs @@ -0,0 +1,46 @@ +use uuid::Uuid; + +use super::rocket; +use mongodb::Database; +use rocket::http::Status; +use rocket::local::asynchronous::{Client, LocalRequest, LocalResponse}; + +use serde_json::{json, Value}; + +use crate::tests_integration::db_utils::{connect, drop_all_collections, find_online_by_uuid, insert_online}; + +#[rocket::async_test] +async fn get_online() { + // init + let client: Client = Client::tracked(rocket()).await.unwrap(); + let db: Database = connect().await.unwrap(); + drop_all_collections(&db).await; + // inputs + let sensor_uuid: String = Uuid::new_v4().to_string(); + let api_token: String = Uuid::new_v4().to_string(); + // fill db with a sensor with default zero value + let _ = insert_online(&db, &sensor_uuid, &api_token, true).await; + // read again the sensor document, previously updated + let document = find_online_by_uuid(&db, &sensor_uuid).await.unwrap().unwrap(); + assert_eq!(document.get("online").unwrap().as_bool().unwrap(), true); + + // read dates from db + let created_at = document.get_datetime("createdAt").unwrap().timestamp_millis(); + let modified_at = document.get_datetime("modifiedAt").unwrap().timestamp_millis(); + + // test api + let req: LocalRequest = client.get(format!("/online/{}", sensor_uuid)); + let res: LocalResponse = req.dispatch().await; + + // check results + assert_eq!(res.status(), Status::Ok); + let expected = json!({ + "online": true, + "createdAt": created_at, + "modifiedAt": modified_at, + }); + assert_eq!(res.into_json::().await.unwrap(), expected); + + // cleanup + drop_all_collections(&db).await; +} diff --git a/src/tests_integration/register.rs b/src/tests_integration/register.rs deleted file mode 100644 index 29ed310..0000000 --- a/src/tests_integration/register.rs +++ /dev/null @@ -1,214 +0,0 @@ -use log::info; -use std::collections::HashMap; -use uuid::Uuid; - -use super::rocket; -use mongodb::Database; -use rocket::http::{ContentType, Status}; -use rocket::local::asynchronous::{Client, LocalRequest, LocalResponse}; -use rocket::serde::json::Json; -use serde_json::{json, Value}; - -use crate::tests_integration::db_utils::{ - connect, drop_all_collections, find_sensor_by_uuid, insert_sensor, update_sensor_float_value_by_uuid, - update_sensor_int_value_by_uuid, -}; -use crate::tests_integration::test_utils::{build_register_input, create_register_input, get_random_mac}; -use register::models::inputs::RegisterInput; - -#[rocket::async_test] -async fn register_sensor() { - // init - let client: Client = Client::tracked(rocket()).await.unwrap(); - let db: Database = connect().await.unwrap(); - drop_all_collections(&db).await; - - // run tests for every sensor_type - let sensor_types = vec![ - "temperature", - "humidity", - "light", - "airpressure", - "motion", - "airquality", - ]; - for sensor_type in sensor_types.into_iter() { - // inputs - let sensor_uuid: String = Uuid::new_v4().to_string(); - let mac: String = get_random_mac(); - let profile_owner_id = String::from("63963ce7c7fd6d463c6c77a3"); - let register_body = build_register_input(&sensor_uuid, &mac, &profile_owner_id); - - // test api - let req: LocalRequest = client - .post("/sensors/register/".to_owned() + sensor_type) - .header(ContentType::JSON) - .body(register_body); - let res: LocalResponse = req.dispatch().await; - - let document = find_sensor_by_uuid(&db, &sensor_uuid, sensor_type) - .await - .unwrap() - .unwrap(); - let inserted_id = document.get_object_id("_id").unwrap().to_hex(); - - // check results - assert_eq!(res.status(), Status::Ok); - assert_eq!(res.into_json::().await.unwrap(), json!({ "id": inserted_id })); - } - - // cleanup - drop_all_collections(&db).await; -} - -#[rocket::async_test] -async fn register_sensor_error() { - // init - let client = Client::tracked(rocket()).await.unwrap(); - let db: Database = connect().await.unwrap(); - drop_all_collections(&db).await; - - // run tests for every sensor_type - let sensor_types = vec![ - "temperature", - "humidity", - "light", - "airpressure", - "motion", - "airquality", - ]; - for sensor_type in sensor_types.into_iter() { - // inputs - let sensor_uuid: String = Uuid::new_v4().to_string(); - let mac: String = get_random_mac(); - let wrong_profile_id = String::from("dasd7dasjdhdsygsyuad"); - // try to add a sensor with POST body using a 'profileOwnerId' - // with bad format (it must be a mongodb ObjectId) - let register_body = build_register_input(&sensor_uuid, &mac, &wrong_profile_id); - - // test api - let req: LocalRequest = client - .post("/sensors/register/".to_owned() + sensor_type) - .header(ContentType::JSON) - .body(register_body); - let res: LocalResponse = req.dispatch().await; - - // check results - assert_eq!(res.status(), Status::BadRequest); - } - - // cleanup - drop_all_collections(&db).await; -} - -#[rocket::async_test] -async fn get_float_sensor_value() { - // init - let client: Client = Client::tracked(rocket()).await.unwrap(); - let db: Database = connect().await.unwrap(); - drop_all_collections(&db).await; - - // run tests for every sensor_type - let sensors_inputs: HashMap = HashMap::from([ - (String::from("temperature"), 28.12), - (String::from("humidity"), 67_f64), - (String::from("light"), 12_f64), - (String::from("airpressure"), 10.99), - ]); - - for (sensor_type, sensor_val) in &sensors_inputs { - info!(target: "test", "get_sensor_value - TEST with type = {} and value = {}", &sensor_type, sensor_val); - // inputs - let sensor_uuid: String = Uuid::new_v4().to_string(); - let mac: String = get_random_mac(); - let profile_owner_id = "63963ce7c7fd6d463c6c77a3"; - let register_body: RegisterInput = create_register_input(&sensor_uuid, &mac, profile_owner_id); - - // fill db with a sensor with default zero value - let _ = insert_sensor(&db, Json(register_body), sensor_type).await; - update_sensor_float_value_by_uuid(&db, &sensor_uuid, sensor_type, *sensor_val) - .await - .unwrap() - .unwrap(); - // read again the sensor document, previously updated - let document = find_sensor_by_uuid(&db, &sensor_uuid, sensor_type) - .await - .unwrap() - .unwrap(); - assert_eq!(document.get("value").unwrap().as_f64().unwrap(), *sensor_val); - - // read dates from db - let created_at = document.get_datetime("createdAt").unwrap().timestamp_millis(); - let modified_at = document.get_datetime("modifiedAt").unwrap().timestamp_millis(); - - // test api - let req: LocalRequest = client.get(format!("/sensors/{}/{}", sensor_uuid, sensor_type)); - let res: LocalResponse = req.dispatch().await; - - // check results - assert_eq!(res.status(), Status::Ok); - let expected = json!({ - "value": *sensor_val, - "createdAt": created_at, - "modifiedAt": modified_at, - }); - assert_eq!(res.into_json::().await.unwrap(), expected); - } - - // cleanup - drop_all_collections(&db).await; -} - -#[rocket::async_test] -async fn get_int_sensor_value() { - // init - let client: Client = Client::tracked(rocket()).await.unwrap(); - let db: Database = connect().await.unwrap(); - drop_all_collections(&db).await; - - // run tests for every sensor_type - let sensors_inputs: HashMap = - HashMap::from([(String::from("motion"), 1), (String::from("airquality"), 2)]); - - for (sensor_type, sensor_val) in &sensors_inputs { - info!(target: "test", "get_sensor_value - TEST with type = {} and value = {}", &sensor_type, sensor_val); - // inputs - let sensor_uuid: String = Uuid::new_v4().to_string(); - let mac: String = get_random_mac(); - let profile_owner_id = "63963ce7c7fd6d463c6c77a3"; - let register_body: RegisterInput = create_register_input(&sensor_uuid, &mac, profile_owner_id); - - // fill db with a sensor with default zero value - let _ = insert_sensor(&db, Json(register_body), sensor_type).await; - update_sensor_int_value_by_uuid(&db, &sensor_uuid, sensor_type, *sensor_val) - .await - .unwrap() - .unwrap(); - // read again the sensor document, previously updated - let document = find_sensor_by_uuid(&db, &sensor_uuid, sensor_type) - .await - .unwrap() - .unwrap(); - assert_eq!(document.get_i64("value").unwrap(), *sensor_val); - - // read dates from db - let created_at = document.get_datetime("createdAt").unwrap().timestamp_millis(); - let modified_at = document.get_datetime("modifiedAt").unwrap().timestamp_millis(); - - // test api - let req: LocalRequest = client.get(format!("/sensors/{}/{}", sensor_uuid, sensor_type)); - let res: LocalResponse = req.dispatch().await; - - // check results - assert_eq!(res.status(), Status::Ok); - let expected = json!({ - "value": *sensor_val as f64, - "createdAt": created_at, - "modifiedAt": modified_at, - }); - assert_eq!(res.into_json::().await.unwrap(), expected); - } - - // cleanup - drop_all_collections(&db).await; -} diff --git a/src/tests_integration/test_utils.rs b/src/tests_integration/test_utils.rs deleted file mode 100644 index 42a2ce8..0000000 --- a/src/tests_integration/test_utils.rs +++ /dev/null @@ -1,40 +0,0 @@ -use rand::Rng; - -use register::models::inputs::RegisterInput; - -pub fn create_register_input(sensor_uuid: &str, mac: &str, profile_owner_id: &str) -> RegisterInput { - RegisterInput { - uuid: sensor_uuid.to_string(), - mac: mac.to_string(), - manufacturer: String::from("ks89"), - model: String::from("test-model"), - profileOwnerId: profile_owner_id.to_string(), - apiToken: String::from("473a4861-632b-4915-b01e-cf1d418966c6"), - } -} - -pub fn build_register_input(sensor_uuid: &str, mac: &str, profile_owner_id: &str) -> String { - serde_json::to_string(&create_register_input(sensor_uuid, mac, profile_owner_id)).unwrap() -} - -pub fn get_random_mac() -> String { - const CHARSET: &[u8] = b"ABCDEF0123456789"; - let mut rng = rand::thread_rng(); - let mut mac = String::from(""); - for i in 0..6 { - let group: String = (0..2) - .map(|_| { - let idx = rng.gen_range(0..CHARSET.len()); - CHARSET[idx] as char - }) - .collect(); - if i == 0 { - mac = format!("{}:", group); - } else if i > 0 && i < 5 { - mac = format!("{}{}:", mac, group); - } else { - mac = format!("{}{}", mac, group); - } - } - mac -}