diff --git a/backend/.sqlx/query-60473446809d8d5a8d13ad0fe94c7420b716a4529da589c6698874f8836f89aa.json b/backend/.sqlx/query-e304538ad4380d75d473ca2f4d4a9693f5ff124a40f8811b8bc208ebfee54b36.json similarity index 89% rename from backend/.sqlx/query-60473446809d8d5a8d13ad0fe94c7420b716a4529da589c6698874f8836f89aa.json rename to backend/.sqlx/query-e304538ad4380d75d473ca2f4d4a9693f5ff124a40f8811b8bc208ebfee54b36.json index 3638a03..3284ad2 100644 --- a/backend/.sqlx/query-60473446809d8d5a8d13ad0fe94c7420b716a4529da589c6698874f8836f89aa.json +++ b/backend/.sqlx/query-e304538ad4380d75d473ca2f4d4a9693f5ff124a40f8811b8bc208ebfee54b36.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "INSERT INTO assets (id, symbol, class, exchange, trading, date_added) VALUES ($1, $2, $3::CLASS, $4::EXCHANGE, $5, $6) RETURNING id, symbol, class as \"class: Class\", exchange as \"exchange: Exchange\", trading, date_added", + "query": "INSERT INTO assets (id, symbol, class, exchange, trading, date_added) VALUES ($1, $2, $3, $4, $5, $6) RETURNING id, symbol, class as \"class: Class\", exchange as \"exchange: Exchange\", trading, date_added", "describe": { "columns": [ { @@ -107,5 +107,5 @@ false ] }, - "hash": "60473446809d8d5a8d13ad0fe94c7420b716a4529da589c6698874f8836f89aa" + "hash": "e304538ad4380d75d473ca2f4d4a9693f5ff124a40f8811b8bc208ebfee54b36" } diff --git a/backend/Cargo.lock b/backend/Cargo.lock index 290dea6..5ecda39 100644 --- a/backend/Cargo.lock +++ b/backend/Cargo.lock @@ -35,54 +35,6 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" -[[package]] -name = "amq-protocol" -version = "7.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d40d8b2465c7959dd40cee32ba6ac334b5de57e9fca0cc756759894a4152a5d" -dependencies = [ - "amq-protocol-tcp", - "amq-protocol-types", - "amq-protocol-uri", - "cookie-factory", - "nom", - "serde", -] - -[[package]] -name = "amq-protocol-tcp" -version = "7.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cb2100adae7da61953a2c3a01935d86caae13329fadce3333f524d6d6ce12e2" -dependencies = [ - "amq-protocol-uri", - "tcp-stream", - "tracing", -] - -[[package]] -name = "amq-protocol-types" -version = "7.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "156ff13c8a3ced600b4e54ed826a2ae6242b6069d00dd98466827cef07d3daff" -dependencies = [ - "cookie-factory", - "nom", - "serde", - "serde_json", -] - -[[package]] -name = "amq-protocol-uri" -version = "7.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "751bbd7d440576066233e740576f1b31fdc6ab86cfabfbd48c548de77eca73e4" -dependencies = [ - "amq-protocol-types", - "percent-encoding", - "url", -] - [[package]] name = "android-tzdata" version = "0.1.1" @@ -139,35 +91,6 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bddcadddf5e9015d310179a59bb28c4d4b9920ad0f11e8e14dbadf654890c9a6" -[[package]] -name = "assets" -version = "0.1.0" -dependencies = [ - "apca", - "axum", - "common", - "deadpool", - "dotenv", - "lapin", - "log", - "log4rs", - "serde", - "serde_json", - "sqlx", - "tokio", -] - -[[package]] -name = "async-channel" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" -dependencies = [ - "concurrent-queue", - "event-listener", - "futures-core", -] - [[package]] name = "async-compression" version = "0.4.1" @@ -181,93 +104,6 @@ dependencies = [ "pin-project-lite", ] -[[package]] -name = "async-executor" -version = "1.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fa3dc5f2a8564f07759c008b9109dc0d39de92a88d5588b8a5036d286383afb" -dependencies = [ - "async-lock", - "async-task", - "concurrent-queue", - "fastrand 1.9.0", - "futures-lite", - "slab", -] - -[[package]] -name = "async-global-executor" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1b6f5d7df27bd294849f8eec66ecfc63d11814df7a4f5d74168a2394467b776" -dependencies = [ - "async-channel", - "async-executor", - "async-io", - "async-lock", - "blocking", - "futures-lite", - "once_cell", -] - -[[package]] -name = "async-global-executor-trait" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33dd14c5a15affd2abcff50d84efd4009ada28a860f01c14f9d654f3e81b3f75" -dependencies = [ - "async-global-executor", - "async-trait", - "executor-trait", -] - -[[package]] -name = "async-io" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fc5b45d93ef0529756f812ca52e44c221b35341892d3dcc34132ac02f3dd2af" -dependencies = [ - "async-lock", - "autocfg", - "cfg-if", - "concurrent-queue", - "futures-lite", - "log", - "parking", - "polling", - "rustix 0.37.23", - "slab", - "socket2 0.4.9", - "waker-fn", -] - -[[package]] -name = "async-lock" -version = "2.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "287272293e9d8c41773cec55e365490fe034813a2f172f502d6ddcf75b2f582b" -dependencies = [ - "event-listener", -] - -[[package]] -name = "async-reactor-trait" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a6012d170ad00de56c9ee354aef2e358359deb1ec504254e0e5a3774771de0e" -dependencies = [ - "async-io", - "async-trait", - "futures-core", - "reactor-trait", -] - -[[package]] -name = "async-task" -version = "4.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc7ab41815b3c653ccd2978ec3255c81349336702dfdf62ee6f7069b12a3aae" - [[package]] name = "async-trait" version = "0.1.73" @@ -288,12 +124,6 @@ dependencies = [ "num-traits", ] -[[package]] -name = "atomic-waker" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1181e1e0d1fce796a03db1ae795d67167da795f9cf4a39c37589e85ef57f26d3" - [[package]] name = "autocfg" version = "1.1.0" @@ -349,6 +179,23 @@ dependencies = [ "tower-service", ] +[[package]] +name = "backend" +version = "0.1.0" +dependencies = [ + "apca", + "axum", + "deadpool", + "dotenv", + "log", + "log4rs", + "serde", + "serde_json", + "sqlx", + "time 0.3.28", + "tokio", +] + [[package]] name = "backtrace" version = "0.3.69" @@ -406,30 +253,6 @@ dependencies = [ "generic-array", ] -[[package]] -name = "block-padding" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8894febbff9f758034a5b8e12d87918f56dfc64a8e1fe757d65e29041538d93" -dependencies = [ - "generic-array", -] - -[[package]] -name = "blocking" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77231a1c8f801696fc0123ec6150ce92cffb8e164a02afb9c8ddee0e9b65ad65" -dependencies = [ - "async-channel", - "async-lock", - "async-task", - "atomic-waker", - "fastrand 1.9.0", - "futures-lite", - "log", -] - [[package]] name = "bumpalo" version = "3.13.0" @@ -448,15 +271,6 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" -[[package]] -name = "cbc" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b52a9543ae338f279b96b0b9fed9c8093744685043739079ce85cd58f289a6" -dependencies = [ - "cipher", -] - [[package]] name = "cc" version = "1.0.83" @@ -488,50 +302,12 @@ dependencies = [ "winapi", ] -[[package]] -name = "cipher" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" -dependencies = [ - "crypto-common", - "inout", -] - -[[package]] -name = "common" -version = "0.1.0" -dependencies = [ - "apca", - "deadpool", - "deadpool-lapin", - "lapin", - "serde", - "sqlx", - "time 0.3.27", -] - -[[package]] -name = "concurrent-queue" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62ec6771ecfa0762d24683ee5a32ad78487a3d3afdc0fb8cae19d2c5deb50b7c" -dependencies = [ - "crossbeam-utils", -] - [[package]] name = "const-oid" version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" -[[package]] -name = "cookie-factory" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "396de984970346b0d9e93d1415082923c679e5ae5c3ee3dcbd104f5610af126b" - [[package]] name = "core-foundation" version = "0.9.3" @@ -623,17 +399,6 @@ dependencies = [ "tokio", ] -[[package]] -name = "deadpool-lapin" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20ed9da47e51ead8acbf364b4c5c311fb4d7dd3efa9dab91ee41cac05b59f313" -dependencies = [ - "deadpool", - "lapin", - "tokio-executor-trait", -] - [[package]] name = "deadpool-runtime" version = "0.1.2" @@ -674,15 +439,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "des" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffdd80ce8ce993de27e9f063a444a4d53ce8e8db4c1f00cc03af5ad5a9867a1e" -dependencies = [ - "cipher", -] - [[package]] name = "destructure_traitobject" version = "0.2.0" @@ -701,12 +457,6 @@ dependencies = [ "subtle", ] -[[package]] -name = "doc-comment" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" - [[package]] name = "dotenv" version = "0.15.0" @@ -772,24 +522,6 @@ version = "2.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" -[[package]] -name = "executor-trait" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a1052dd43212a7777ec6a69b117da52f5e52f07aec47d00c1a2b33b85d06b08" -dependencies = [ - "async-trait", -] - -[[package]] -name = "fastrand" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" -dependencies = [ - "instant", -] - [[package]] name = "fastrand" version = "2.0.0" @@ -906,21 +638,6 @@ version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" -[[package]] -name = "futures-lite" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" -dependencies = [ - "fastrand 1.9.0", - "futures-core", - "futures-io", - "memchr", - "parking", - "pin-project-lite", - "waker-fn", -] - [[package]] name = "futures-macro" version = "0.3.28" @@ -1200,36 +917,6 @@ dependencies = [ "hashbrown 0.14.0", ] -[[package]] -name = "inout" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" -dependencies = [ - "block-padding", - "generic-array", -] - -[[package]] -name = "instant" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "io-lifetimes" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" -dependencies = [ - "hermit-abi", - "libc", - "windows-sys", -] - [[package]] name = "itertools" version = "0.10.5" @@ -1254,28 +941,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "lapin" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f3067a1fcfbc3fc46455809c023e69b8f6602463201010f4ae5a3b572adb9dc" -dependencies = [ - "amq-protocol", - "async-global-executor-trait", - "async-reactor-trait", - "async-trait", - "executor-trait", - "flume", - "futures-core", - "futures-io", - "parking_lot", - "pinky-swear", - "reactor-trait", - "serde", - "tracing", - "waker-fn", -] - [[package]] name = "lazy_static" version = "1.4.0" @@ -1314,12 +979,6 @@ version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" -[[package]] -name = "linux-raw-sys" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" - [[package]] name = "linux-raw-sys" version = "0.4.5" @@ -1568,11 +1227,11 @@ checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] name = "openssl" -version = "0.10.56" +version = "0.10.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "729b745ad4a5575dd06a3e1af1414bd330ee561c01b3899eb584baeaa8def17e" +checksum = "bac25ee399abb46215765b1cb35bc0212377e58a061560d8b29b024fd0430e7c" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.4.0", "cfg-if", "foreign-types", "libc", @@ -1600,9 +1259,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-sys" -version = "0.9.91" +version = "0.9.92" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "866b5f16f90776b9bb8dc1e1802ac6f0513de3a7a7465867bfbc563dc737faac" +checksum = "db7e971c2c2bba161b2d2fdf37080177eff520b3bc044787c7f1f5f9e78d869b" dependencies = [ "cc", "libc", @@ -1619,29 +1278,6 @@ dependencies = [ "num-traits", ] -[[package]] -name = "p12" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4873306de53fe82e7e484df31e1e947d61514b6ea2ed6cd7b45d63006fd9224" -dependencies = [ - "cbc", - "cipher", - "des", - "getrandom", - "hmac", - "lazy_static", - "rc2", - "sha1", - "yasna", -] - -[[package]] -name = "parking" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14f2252c834a40ed9bb5422029649578e63aa341ac401f74e719dd1afda8394e" - [[package]] name = "parking_lot" version = "0.12.1" @@ -1718,18 +1354,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" -[[package]] -name = "pinky-swear" -version = "6.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d894b67aa7a4bf295db5e85349078c604edaa6fa5c8721e8eca3c7729a27f2ac" -dependencies = [ - "doc-comment", - "flume", - "parking_lot", - "tracing", -] - [[package]] name = "pkcs1" version = "0.7.5" @@ -1757,22 +1381,6 @@ version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" -[[package]] -name = "polling" -version = "2.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b2d323e8ca7996b3e23126511a523f7e62924d93ecd5ae73b333815b0eb3dce" -dependencies = [ - "autocfg", - "bitflags 1.3.2", - "cfg-if", - "concurrent-queue", - "libc", - "log", - "pin-project-lite", - "windows-sys", -] - [[package]] name = "ppv-lite86" version = "0.2.17" @@ -1827,26 +1435,6 @@ dependencies = [ "getrandom", ] -[[package]] -name = "rc2" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62c64daa8e9438b84aaae55010a93f396f8e60e3911590fcba770d04643fc1dd" -dependencies = [ - "cipher", -] - -[[package]] -name = "reactor-trait" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "438a4293e4d097556730f4711998189416232f009c137389e0f961d2bc0ddc58" -dependencies = [ - "async-trait", - "futures-core", - "futures-io", -] - [[package]] name = "redox_syscall" version = "0.2.16" @@ -1871,21 +1459,6 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4389f1d5789befaf6029ebd9f7dac4af7f7e3d61b69d4f30e2ac02b57e7712b0" -[[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", - "web-sys", - "winapi", -] - [[package]] name = "rsa" version = "0.9.2" @@ -1914,20 +1487,6 @@ version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" -[[package]] -name = "rustix" -version = "0.37.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d69718bf81c6127a49dc64e44a742e8bb9213c0ff8869a22c308f84c1d4ab06" -dependencies = [ - "bitflags 1.3.2", - "errno", - "io-lifetimes", - "libc", - "linux-raw-sys 0.3.8", - "windows-sys", -] - [[package]] name = "rustix" version = "0.38.9" @@ -1937,65 +1496,10 @@ dependencies = [ "bitflags 2.4.0", "errno", "libc", - "linux-raw-sys 0.4.5", + "linux-raw-sys", "windows-sys", ] -[[package]] -name = "rustls" -version = "0.21.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d1feddffcfcc0b33f5c6ce9a29e341e4cd59c3f78e7ee45f4a40c038b1d6cbb" -dependencies = [ - "log", - "ring", - "rustls-webpki", - "sct", -] - -[[package]] -name = "rustls-connector" -version = "0.18.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "060bcc1795b840d0e56d78f3293be5f652aa1611d249b0e63ffe19f4a8c9ae23" -dependencies = [ - "log", - "rustls", - "rustls-native-certs", - "rustls-webpki", -] - -[[package]] -name = "rustls-native-certs" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" -dependencies = [ - "openssl-probe", - "rustls-pemfile", - "schannel", - "security-framework", -] - -[[package]] -name = "rustls-pemfile" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2" -dependencies = [ - "base64 0.21.3", -] - -[[package]] -name = "rustls-webpki" -version = "0.101.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d93931baf2d282fff8d3a532bbfd7653f734643161b87e3e01e59a04439bf0d" -dependencies = [ - "ring", - "untrusted", -] - [[package]] name = "rustversion" version = "1.0.14" @@ -2023,16 +1527,6 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" -[[package]] -name = "sct" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" -dependencies = [ - "ring", - "untrusted", -] - [[package]] name = "security-framework" version = "2.9.2" @@ -2290,7 +1784,7 @@ dependencies = [ "smallvec", "sqlformat", "thiserror", - "time 0.3.27", + "time 0.3.28", "tokio", "tokio-stream", "tracing", @@ -2375,7 +1869,7 @@ dependencies = [ "sqlx-core", "stringprep", "thiserror", - "time 0.3.27", + "time 0.3.28", "tracing", "uuid", "whoami", @@ -2416,7 +1910,7 @@ dependencies = [ "sqlx-core", "stringprep", "thiserror", - "time 0.3.27", + "time 0.3.28", "tracing", "uuid", "whoami", @@ -2440,7 +1934,7 @@ dependencies = [ "percent-encoding", "serde", "sqlx-core", - "time 0.3.27", + "time 0.3.28", "tracing", "url", "uuid", @@ -2490,18 +1984,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" -[[package]] -name = "tcp-stream" -version = "0.26.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4da30af7998f51ee1aa48ab24276fe303a697b004e31ff542b192c088d5630a5" -dependencies = [ - "cfg-if", - "p12", - "rustls-connector", - "rustls-pemfile", -] - [[package]] name = "tempfile" version = "3.8.0" @@ -2509,9 +1991,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" dependencies = [ "cfg-if", - "fastrand 2.0.0", + "fastrand", "redox_syscall 0.3.5", - "rustix 0.38.9", + "rustix", "windows-sys", ] @@ -2559,9 +2041,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.27" +version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bb39ee79a6d8de55f48f2293a830e040392f1c5f16e336bdd1788cd0aadce07" +checksum = "17f6bb557fd245c28e6411aa56b6403c689ad95061f50e4be16c274e70a17e48" dependencies = [ "deranged", "itoa", @@ -2578,9 +2060,9 @@ checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" [[package]] name = "time-macros" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "733d258752e9303d392b94b75230d07b0b9c489350c69b851fc6c065fde3e8f9" +checksum = "1a942f44339478ef67935ab2bbaec2fb0322496cf3cbe84b261e06ac3814c572" dependencies = [ "time-core", ] @@ -2617,17 +2099,6 @@ dependencies = [ "windows-sys", ] -[[package]] -name = "tokio-executor-trait" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "802ccf58e108fe16561f35348fabe15ff38218968f033d587e399a84937533cc" -dependencies = [ - "async-trait", - "executor-trait", - "tokio", -] - [[package]] name = "tokio-macros" version = "2.1.0" @@ -2828,17 +2299,11 @@ dependencies = [ "destructure_traitobject", ] -[[package]] -name = "untrusted" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" - [[package]] name = "url" -version = "2.4.0" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50bff7831e19200a85b17131d085c25d7811bc4e186efdaf54bbd132994a88cb" +checksum = "143b538f18257fac9cad154828a57c6bf5157e1aa604d4816b5995bf6de87ae5" dependencies = [ "form_urlencoded", "idna", @@ -2872,12 +2337,6 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" -[[package]] -name = "waker-fn" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca" - [[package]] name = "want" version = "0.3.1" @@ -2953,16 +2412,6 @@ version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1" -[[package]] -name = "web-sys" -version = "0.3.64" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - [[package]] name = "websocket-util" version = "0.11.2" @@ -3087,12 +2536,6 @@ dependencies = [ "linked-hash-map", ] -[[package]] -name = "yasna" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e17bb3549cc1321ae1296b9cdc2698e2b6cb1992adfa19a8c72e5b7a738f44cd" - [[package]] name = "zeroize" version = "1.6.0" diff --git a/backend/Cargo.toml b/backend/Cargo.toml index ebb6b4d..b0de2e4 100644 --- a/backend/Cargo.toml +++ b/backend/Cargo.toml @@ -1,7 +1,31 @@ -[workspace] +[package] +name = "backend" +version = "0.1.0" +edition = "2021" -resolver = "2" -members = [ - "common", - "assets", -] +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +apca = "0.27.2" +axum = "0.6.20" +dotenv = "0.15.0" +sqlx = { version = "0.7.1", features = [ + "uuid", + "time", + "postgres", + "runtime-tokio", +] } +tokio = { version = "1.32.0", features = [ + "macros", + "rt-multi-thread", +] } +deadpool = { version = "0.9.5", features = [ + "rt_tokio_1", +] } +serde = "1.0.188" +log = "0.4.20" +serde_json = "1.0.105" +log4rs = "1.2.0" +time = { version = "0.3.27", features = [ + "serde", +] } diff --git a/backend/Dockerfile b/backend/Dockerfile index a0f1760..6fcde0c 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -1,12 +1,23 @@ FROM rust AS builder + WORKDIR /usr/src/qrust -COPY . . + ENV SQLX_OFFLINE true + +RUN mkdir src && echo "fn main() {}" > src/main.rs +COPY Cargo.toml .sqlx ./ +RUN cargo build --release +RUN rm -rf src + +COPY . . RUN cargo build --release -FROM frolvlad/alpine-glibc AS assets -WORKDIR /usr/src/assets -COPY --from=builder /usr/src/qrust/target/release/assets . +FROM frolvlad/alpine-glibc AS backend + +WORKDIR /usr/src/qrust + +COPY --from=builder /usr/src/qrust/target/release/backend . COPY log4rs.yaml . + EXPOSE 7878 -CMD ["./assets"] +CMD ["./qrust"] diff --git a/backend/assets/Cargo.toml b/backend/assets/Cargo.toml deleted file mode 100644 index 5d2f43b..0000000 --- a/backend/assets/Cargo.toml +++ /dev/null @@ -1,30 +0,0 @@ -[package] -name = "assets" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -common = { path = "../common" } -apca = "0.27.2" -axum = "0.6.20" -dotenv = "0.15.0" -sqlx = { version = "0.7.1", features = [ - "uuid", - "time", - "postgres", - "runtime-tokio", -] } -tokio = { version = "1.32.0", features = [ - "macros", - "rt-multi-thread", -] } -deadpool = { version = "0.9.5", features = [ - "rt_tokio_1", -] } -serde = "1.0.188" -log = "0.4.20" -lapin = "2.3.1" -serde_json = "1.0.105" -log4rs = "1.2.0" diff --git a/backend/assets/docker-compose.yml b/backend/assets/docker-compose.yml deleted file mode 100644 index dbfbfb6..0000000 --- a/backend/assets/docker-compose.yml +++ /dev/null @@ -1,8 +0,0 @@ -services: - assets: - build: - context: .. - dockerfile: Dockerfile - target: assets - hostname: assets - restart: unless-stopped diff --git a/backend/assets/src/main.rs b/backend/assets/src/main.rs deleted file mode 100644 index 9f6ae9c..0000000 --- a/backend/assets/src/main.rs +++ /dev/null @@ -1,61 +0,0 @@ -use axum::{ - routing::{delete, get, post}, - Extension, Router, Server, -}; -use common::pool::{ - create_alpaca_pool_from_env, create_database_pool_from_env, create_rabbitmq_pool_from_env, -}; -use deadpool::managed::{Hook, HookError, HookErrorCause}; -use dotenv::dotenv; -use lapin::ExchangeKind; -use log::info; -use std::{error::Error, net::SocketAddr}; - -mod routes; - -#[tokio::main] -async fn main() -> Result<(), Box> { - dotenv().ok(); - log4rs::init_file("log4rs.yaml", Default::default()).unwrap(); - - let num_clients = 10; - let database_pool = create_database_pool_from_env(num_clients).await?; - let alpaca_pool = create_alpaca_pool_from_env(num_clients).await?; - let rabbitmq_pool = create_rabbitmq_pool_from_env( - num_clients, - Hook::async_fn(|connection: &mut lapin::Connection, _| { - Box::pin(async move { - connection - .create_channel() - .await - .map_err(|e| HookError::Abort(HookErrorCause::Backend(e)))? - .exchange_declare( - "assets", - ExchangeKind::Topic, - Default::default(), - Default::default(), - ) - .await - .map_err(|e| HookError::Abort(HookErrorCause::Backend(e)))?; - Ok(()) - }) - }), - ) - .await?; - - let app = Router::new() - .route("/assets", get(routes::get_assets)) - .route("/assets/:symbol", get(routes::get_asset)) - .route("/assets", post(routes::add_asset)) - .route("/assets/:symbol", post(routes::update_asset)) - .route("/assets/:symbol", delete(routes::delete_asset)) - .layer(Extension(database_pool)) - .layer(Extension(alpaca_pool)) - .layer(Extension(rabbitmq_pool)); - - let addr = SocketAddr::from(([0, 0, 0, 0], 7878)); - info!("Listening on {}...", addr); - Server::bind(&addr).serve(app.into_make_service()).await?; - - Ok(()) -} diff --git a/backend/assets/src/routes.rs b/backend/assets/src/routes.rs deleted file mode 100644 index d0b4b97..0000000 --- a/backend/assets/src/routes.rs +++ /dev/null @@ -1,170 +0,0 @@ -use apca::api::v2::asset::{self, Symbol}; -use axum::{extract::Path, http::StatusCode, Extension, Json}; -use common::{ - database::{Asset, Class, Exchange}, - pool::{AlpacaPool, RabbitmqPool}, -}; -use serde::Deserialize; -use sqlx::{ - query_as, - types::{time::OffsetDateTime, Uuid}, - PgPool, -}; - -pub async fn get_assets( - Extension(database_pool): Extension, -) -> Result<(StatusCode, Json>), StatusCode> { - let assets = query_as!(Asset, r#"SELECT id, symbol, class as "class: Class", exchange as "exchange: Exchange", trading, date_added FROM assets"#) - .fetch_all(&database_pool) - .await - .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?; - - Ok((StatusCode::OK, Json(assets))) -} - -pub async fn get_asset( - Extension(database_pool): Extension, - Path(symbol): Path, -) -> Result<(StatusCode, Json), StatusCode> { - let asset = query_as!(Asset, r#"SELECT id, symbol, class as "class: Class", exchange as "exchange: Exchange", trading, date_added FROM assets WHERE symbol = $1"#, symbol) - .fetch_one(&database_pool) - .await - .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?; - - Ok((StatusCode::OK, Json(asset))) -} - -#[allow(dead_code)] -#[derive(Deserialize)] -pub struct AddAssetRequest { - symbol: String, - trading: Option, -} - -pub async fn add_asset( - Extension(database_pool): Extension, - Extension(alpaca_pool): Extension, - Extension(rabbitmq_pool): Extension, - Json(request): Json, -) -> Result { - if query_as!(Asset, r#"SELECT id, symbol, class as "class: Class", exchange as "exchange: Exchange", trading, date_added FROM assets WHERE symbol = $1"#, request.symbol) - .fetch_optional(&database_pool) - .await - .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)? - .is_some() { - return Err(StatusCode::CONFLICT); - } - - let asset = alpaca_pool - .get() - .await - .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)? - .issue::(&Symbol::Sym(request.symbol)) - .await - .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?; - - let asset = query_as!( - Asset, - r#"INSERT INTO assets (id, symbol, class, exchange, trading, date_added) VALUES ($1, $2, $3::CLASS, $4::EXCHANGE, $5, $6) RETURNING id, symbol, class as "class: Class", exchange as "exchange: Exchange", trading, date_added"#, - Uuid::parse_str(&asset.id.to_string()).map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?, - asset.symbol, - Class::from(asset.class) as Class, - Exchange::from(asset.exchange) as Exchange, - request.trading.unwrap_or(false), - OffsetDateTime::now_utc(), - ) - .fetch_one(&database_pool) - .await - .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?; - - rabbitmq_pool - .get() - .await - .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)? - .create_channel() - .await - .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)? - .basic_publish( - "assets", - "assets.added", - Default::default(), - &serde_json::to_vec(&asset).map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?, - Default::default(), - ) - .await - .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?; - - Ok(StatusCode::CREATED) -} - -#[allow(dead_code)] -#[derive(Deserialize)] -pub struct UpdateAssetRequest { - trading: bool, -} - -pub async fn update_asset( - Extension(database_pool): Extension, - Extension(rabbitmq_pool): Extension, - Path(symbol): Path, - Json(request): Json, -) -> Result { - let asset = query_as!( - Asset, - r#"UPDATE assets SET trading = $1 WHERE symbol = $2 RETURNING id, symbol, class as "class: Class", exchange as "exchange: Exchange", trading, date_added"#, - request.trading, - symbol - ) - .fetch_one(&database_pool) - .await - .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?; - - rabbitmq_pool - .get() - .await - .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)? - .create_channel() - .await - .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)? - .basic_publish( - "assets", - "assets.updated", - Default::default(), - &serde_json::to_vec(&asset).map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?, - Default::default(), - ) - .await - .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?; - - Ok(StatusCode::OK) -} - -pub async fn delete_asset( - Extension(database_pool): Extension, - Extension(rabbitmq_pool): Extension, - Path(symbol): Path, -) -> Result { - let asset = query_as!(Asset, r#"DELETE FROM assets WHERE symbol = $1 RETURNING id, symbol, class as "class: Class", exchange as "exchange: Exchange", trading, date_added"#, symbol) - .fetch_one(&database_pool) - .await - .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?; - - rabbitmq_pool - .get() - .await - .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)? - .create_channel() - .await - .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)? - .basic_publish( - "assets", - "assets.deleted", - Default::default(), - &serde_json::to_vec(&asset).map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?, - Default::default(), - ) - .await - .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?; - - Ok(StatusCode::NO_CONTENT) -} diff --git a/backend/common/Cargo.toml b/backend/common/Cargo.toml deleted file mode 100644 index f52223e..0000000 --- a/backend/common/Cargo.toml +++ /dev/null @@ -1,21 +0,0 @@ -[package] -name = "common" -version = "0.1.0" -edition = "2021" - -[dependencies] -lapin = "2.3.1" -apca = "0.27.2" -deadpool = "0.9.5" -deadpool-lapin = "0.10.0" -serde = { version = "1.0.188", features = [ - "derive", -] } -sqlx = { version = "0.7.1", features = [ - "uuid", - "time", - "postgres", -] } -time = { version = "0.3.27", features = [ - "serde", -] } diff --git a/backend/common/src/lib.rs b/backend/common/src/lib.rs deleted file mode 100644 index 6dc7443..0000000 --- a/backend/common/src/lib.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub mod pool; -pub mod database; diff --git a/backend/docker-compose.yml b/backend/docker-compose.yml new file mode 100644 index 0000000..dbae8c7 --- /dev/null +++ b/backend/docker-compose.yml @@ -0,0 +1,9 @@ +services: + backend: + build: + context: . + dockerfile: Dockerfile + hostname: backend + restart: unless-stopped + ports: + - 7878:7878 diff --git a/backend/src/database/assets.rs b/backend/src/database/assets.rs new file mode 100644 index 0000000..a0fef3e --- /dev/null +++ b/backend/src/database/assets.rs @@ -0,0 +1,54 @@ +use std::error::Error; + +use crate::types::{Asset, Class, Exchange}; +use sqlx::{query_as, PgPool}; + +pub async fn get_assets( + database_pool: &PgPool, +) -> Result, Box> { + query_as!(Asset, r#"SELECT id, symbol, class as "class: Class", exchange as "exchange: Exchange", trading, date_added FROM assets"#) + .fetch_all(database_pool) + .await + .map_err(|e| e.into()) +} + +pub async fn get_asset( + database_pool: &PgPool, + symbol: &str, +) -> Result, Box> { + query_as!(Asset, r#"SELECT id, symbol, class as "class: Class", exchange as "exchange: Exchange", trading, date_added FROM assets WHERE symbol = $1"#, symbol) + .fetch_optional(database_pool) + .await + .map_err(|e| e.into()) +} + +pub async fn add_asset( + database_pool: &PgPool, + asset: Asset, +) -> Result> { + query_as!(Asset, r#"INSERT INTO assets (id, symbol, class, exchange, trading, date_added) VALUES ($1, $2, $3, $4, $5, $6) RETURNING id, symbol, class as "class: Class", exchange as "exchange: Exchange", trading, date_added"#, asset.id, asset.symbol, asset.class as Class, asset.exchange as Exchange, asset.trading, asset.date_added) + .fetch_one(database_pool) + .await + .map_err(|e| e.into()) +} + +pub async fn update_asset_trading( + database_pool: &PgPool, + symbol: &str, + trading: bool, +) -> Result, Box> { + query_as!(Asset, r#"UPDATE assets SET trading = $1 WHERE symbol = $2 RETURNING id, symbol, class as "class: Class", exchange as "exchange: Exchange", trading, date_added"#, trading, symbol) + .fetch_optional(database_pool) + .await + .map_err(|e| e.into()) +} + +pub async fn delete_asset( + database_pool: &PgPool, + symbol: &str, +) -> Result, Box> { + query_as!(Asset, r#"DELETE FROM assets WHERE symbol = $1 RETURNING id, symbol, class as "class: Class", exchange as "exchange: Exchange", trading, date_added"#, symbol) + .fetch_optional(database_pool) + .await + .map_err(|e| e.into()) +} diff --git a/backend/src/database/mod.rs b/backend/src/database/mod.rs new file mode 100644 index 0000000..5d8c80b --- /dev/null +++ b/backend/src/database/mod.rs @@ -0,0 +1 @@ +pub mod assets; diff --git a/backend/src/main.rs b/backend/src/main.rs new file mode 100644 index 0000000..e21e022 --- /dev/null +++ b/backend/src/main.rs @@ -0,0 +1,39 @@ +mod database; +mod pool; +mod routes; +mod types; + +use axum::{ + routing::{delete, get, post}, + Extension, Router, Server, +}; +use dotenv::dotenv; +use log::info; +use pool::{create_alpaca_pool_from_env, create_database_pool_from_env}; +use routes::assets; +use std::{error::Error, net::SocketAddr}; + +#[tokio::main] +async fn main() -> Result<(), Box> { + dotenv().ok(); + log4rs::init_file("log4rs.yaml", Default::default()).unwrap(); + + let num_clients = 10; + let database_pool = create_database_pool_from_env(num_clients).await?; + let alpaca_pool = create_alpaca_pool_from_env(num_clients).await?; + + let app = Router::new() + .route("/assets", get(assets::get_assets)) + .route("/assets/:symbol", get(assets::get_asset)) + .route("/assets", post(assets::add_asset)) + .route("/assets/:symbol", post(assets::update_asset)) + .route("/assets/:symbol", delete(assets::delete_asset)) + .layer(Extension(database_pool)) + .layer(Extension(alpaca_pool)); + + let addr = SocketAddr::from(([0, 0, 0, 0], 7878)); + info!("Listening on {}...", addr); + Server::bind(&addr).serve(app.into_make_service()).await?; + + Ok(()) +} diff --git a/backend/common/src/pool.rs b/backend/src/pool.rs similarity index 64% rename from backend/common/src/pool.rs rename to backend/src/pool.rs index 2376428..049e6d7 100644 --- a/backend/common/src/pool.rs +++ b/backend/src/pool.rs @@ -1,6 +1,5 @@ use apca::{ApiInfo, Client}; -use deadpool::{unmanaged::Pool, Runtime}; -use deadpool_lapin::Hook; +use deadpool::unmanaged::Pool; use sqlx::postgres::PgPoolOptions; use std::{env, error::Error}; @@ -52,28 +51,3 @@ pub async fn create_database_pool_from_env( ) -> Result> { create_database_pool(&env::var("DATABASE_URL")?, num_clients).await } - -pub type RabbitmqPool = deadpool_lapin::Pool; - -pub async fn create_rabbitmq_pool( - rabbitmq_url: &str, - num_clients: usize, - post_create: impl Into, -) -> Result> { - deadpool_lapin::Config { - url: Some(rabbitmq_url.into()), - ..Default::default() - } - .builder(Some(Runtime::Tokio1)) - .max_size(num_clients) - .post_create(post_create) - .build() - .map_err(|e| e.into()) -} - -pub async fn create_rabbitmq_pool_from_env( - num_clients: usize, - post_create: impl Into, -) -> Result> { - create_rabbitmq_pool(&env::var("RABBITMQ_URL")?, num_clients, post_create).await -} diff --git a/backend/src/routes/assets.rs b/backend/src/routes/assets.rs new file mode 100644 index 0000000..873950f --- /dev/null +++ b/backend/src/routes/assets.rs @@ -0,0 +1,115 @@ +use crate::database; +use crate::database::assets::update_asset_trading; +use crate::pool::AlpacaPool; +use crate::types::{Asset, Class, Exchange}; +use apca::api::v2::asset::{self, Symbol}; +use axum::{extract::Path, http::StatusCode, Extension, Json}; +use serde::Deserialize; +use sqlx::{ + types::{time::OffsetDateTime, Uuid}, + PgPool, +}; + +pub async fn get_assets( + Extension(database_pool): Extension, +) -> Result<(StatusCode, Json>), StatusCode> { + let assets = database::assets::get_assets(&database_pool) + .await + .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?; + + Ok((StatusCode::OK, Json(assets))) +} + +pub async fn get_asset( + Extension(database_pool): Extension, + Path(symbol): Path, +) -> Result<(StatusCode, Json), StatusCode> { + let asset = database::assets::get_asset(&database_pool, &symbol) + .await + .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?; + + match asset { + Some(asset) => Ok((StatusCode::OK, Json(asset))), + None => Err(StatusCode::NOT_FOUND), + } +} + +#[allow(dead_code)] +#[derive(Deserialize)] +pub struct AddAssetRequest { + symbol: String, + trading: Option, +} + +pub async fn add_asset( + Extension(database_pool): Extension, + Extension(alpaca_pool): Extension, + Json(request): Json, +) -> Result<(StatusCode, Json), StatusCode> { + if database::assets::get_asset(&database_pool, &request.symbol) + .await + .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)? + .is_some() + { + return Err(StatusCode::CONFLICT); + } + + let asset = alpaca_pool + .get() + .await + .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)? + .issue::(&Symbol::Sym(request.symbol)) + .await + .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?; + + let asset = Asset { + id: Uuid::parse_str(&asset.id.to_string()) + .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?, + symbol: asset.symbol, + class: Class::from(asset.class) as Class, + exchange: Exchange::from(asset.exchange) as Exchange, + trading: request.trading.unwrap_or(false), + date_added: OffsetDateTime::now_utc(), + }; + + let asset = database::assets::add_asset(&database_pool, asset) + .await + .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?; + + Ok((StatusCode::CREATED, Json(asset))) +} + +#[allow(dead_code)] +#[derive(Deserialize)] +pub struct UpdateAssetRequest { + trading: bool, +} + +pub async fn update_asset( + Extension(database_pool): Extension, + Path(symbol): Path, + Json(request): Json, +) -> Result<(StatusCode, Json), StatusCode> { + let asset = update_asset_trading(&database_pool, &symbol, request.trading) + .await + .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?; + + match asset { + Some(asset) => Ok((StatusCode::OK, Json(asset))), + None => Err(StatusCode::NOT_FOUND), + } +} + +pub async fn delete_asset( + Extension(database_pool): Extension, + Path(symbol): Path, +) -> Result<(StatusCode, Json), StatusCode> { + let asset = database::assets::delete_asset(&database_pool, &symbol) + .await + .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?; + + match asset { + Some(asset) => Ok((StatusCode::NO_CONTENT, Json(asset))), + None => Err(StatusCode::NOT_FOUND), + } +} diff --git a/backend/src/routes/mod.rs b/backend/src/routes/mod.rs new file mode 100644 index 0000000..5d8c80b --- /dev/null +++ b/backend/src/routes/mod.rs @@ -0,0 +1 @@ +pub mod assets; diff --git a/backend/common/src/database.rs b/backend/src/types.rs similarity index 100% rename from backend/common/src/database.rs rename to backend/src/types.rs diff --git a/docker-compose.yml b/docker-compose.yml index 8376745..3fad3ba 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -4,31 +4,15 @@ services: file: support/timescaledb/docker-compose.yml service: timescaledb - rabbitmq: + backend: extends: - file: support/rabbitmq/docker-compose.yml - service: rabbitmq - - nginx: - extends: - file: support/nginx/docker-compose.yml - service: nginx - - assets: - extends: - file: backend/assets/docker-compose.yml - service: assets - env_file: - - .env.docker + file: backend/docker-compose.yml + service: backend depends_on: - timescaledb - - rabbitmq - profiles: - - backend + env_file: + - .env.docker volumes: timescaledb-data: timescaledb-logs: - rabbitmq-data: - rabbitmq-logs: - nginx-logs: diff --git a/support/nginx/config/default.conf b/support/nginx/config/default.conf deleted file mode 100644 index 07c42eb..0000000 --- a/support/nginx/config/default.conf +++ /dev/null @@ -1,15 +0,0 @@ -server { - listen 80; - - location /assets { - resolver 127.0.0.11; - proxy_set_header Host $host; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - - set $upstream_proto http; - set $upstream_host assets; - set $upstream_port 7878; - - proxy_pass $upstream_proto://$upstream_host:$upstream_port; - } -} diff --git a/support/nginx/docker-compose.yml b/support/nginx/docker-compose.yml deleted file mode 100644 index 3ea1096..0000000 --- a/support/nginx/docker-compose.yml +++ /dev/null @@ -1,14 +0,0 @@ -services: - nginx: - image: nginx - hostname: nginx - restart: unless-stopped - ports: - - 8080:80 - volumes: - - ./nginx.conf:/etc/nginx/nginx.conf - - ./config:/etc/nginx/conf.d - - nginx-logs:/var/log/nginx - -volumes: - nginx-logs: diff --git a/support/nginx/nginx.conf b/support/nginx/nginx.conf deleted file mode 100644 index 5e076aa..0000000 --- a/support/nginx/nginx.conf +++ /dev/null @@ -1,32 +0,0 @@ - -user nginx; -worker_processes auto; - -error_log /var/log/nginx/error.log notice; -pid /var/run/nginx.pid; - - -events { - worker_connections 1024; -} - - -http { - include /etc/nginx/mime.types; - default_type application/octet-stream; - - log_format main '$remote_addr - $remote_user [$time_local] "$request" ' - '$status $body_bytes_sent "$http_referer" ' - '"$http_user_agent" "$http_x_forwarded_for"'; - - access_log /var/log/nginx/access.log main; - - sendfile on; - #tcp_nopush on; - - keepalive_timeout 65; - - #gzip on; - - include /etc/nginx/conf.d/*.conf; -} diff --git a/support/rabbitmq/Dockerfile b/support/rabbitmq/Dockerfile deleted file mode 100644 index 2045e7f..0000000 --- a/support/rabbitmq/Dockerfile +++ /dev/null @@ -1,8 +0,0 @@ -FROM rabbitmq - -RUN apt-get update && apt-get install -y curl jq wget && rm -rf /var/lib/apt/lists/* - -RUN curl -s "https://api.github.com/repos/noxdafox/rabbitmq-message-deduplication/releases/latest" | jq -r '.assets[] | select(.name | endswith(".ez")).browser_download_url' | while read url; do file=$(basename $url); new_name=$(echo $file | sed 's/-[^-]*\.ez/\.ez/'); wget $url -O plugins/$new_name; done - -RUN rabbitmq-plugins disable --offline rabbitmq_prometheus -RUN rabbitmq-plugins enable --offline rabbitmq_management rabbitmq_message_deduplication diff --git a/support/rabbitmq/docker-compose.yml b/support/rabbitmq/docker-compose.yml deleted file mode 100644 index 7b64157..0000000 --- a/support/rabbitmq/docker-compose.yml +++ /dev/null @@ -1,21 +0,0 @@ -services: - rabbitmq: - build: - context: . - dockerfile: Dockerfile - hostname: rabbitmq - restart: unless-stopped - ports: - - 5672:5672 - - 15672:15672 - volumes: - - rabbitmq-data:/var/lib/rabbitmq - - rabbitmq-logs:/var/log/rabbitmq - environment: - - RABBITMQ_DEFAULT_VHOST=${RABBITMQ_VHOST} - - RABBITMQ_DEFAULT_USER=${RABBITMQ_USER} - - RABBITMQ_DEFAULT_PASS=${RABBITMQ_PASSWORD} - -volumes: - rabbitmq-data: - rabbitmq-logs: