Translate to monolithic architecture
Signed-off-by: Nikolaos Karaolidis <nick@karaolidis.com>
This commit is contained in:
@@ -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"
|
||||
}
|
627
backend/Cargo.lock
generated
627
backend/Cargo.lock
generated
@@ -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"
|
||||
|
@@ -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",
|
||||
] }
|
||||
|
@@ -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"]
|
||||
|
@@ -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"
|
@@ -1,8 +0,0 @@
|
||||
services:
|
||||
assets:
|
||||
build:
|
||||
context: ..
|
||||
dockerfile: Dockerfile
|
||||
target: assets
|
||||
hostname: assets
|
||||
restart: unless-stopped
|
@@ -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<dyn Error + Send + Sync>> {
|
||||
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(())
|
||||
}
|
@@ -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<PgPool>,
|
||||
) -> Result<(StatusCode, Json<Vec<Asset>>), 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<PgPool>,
|
||||
Path(symbol): Path<String>,
|
||||
) -> Result<(StatusCode, Json<Asset>), 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<bool>,
|
||||
}
|
||||
|
||||
pub async fn add_asset(
|
||||
Extension(database_pool): Extension<PgPool>,
|
||||
Extension(alpaca_pool): Extension<AlpacaPool>,
|
||||
Extension(rabbitmq_pool): Extension<RabbitmqPool>,
|
||||
Json(request): Json<AddAssetRequest>,
|
||||
) -> Result<StatusCode, StatusCode> {
|
||||
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::<asset::Get>(&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<PgPool>,
|
||||
Extension(rabbitmq_pool): Extension<RabbitmqPool>,
|
||||
Path(symbol): Path<String>,
|
||||
Json(request): Json<UpdateAssetRequest>,
|
||||
) -> Result<StatusCode, StatusCode> {
|
||||
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<PgPool>,
|
||||
Extension(rabbitmq_pool): Extension<RabbitmqPool>,
|
||||
Path(symbol): Path<String>,
|
||||
) -> Result<StatusCode, StatusCode> {
|
||||
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)
|
||||
}
|
@@ -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",
|
||||
] }
|
@@ -1,2 +0,0 @@
|
||||
pub mod pool;
|
||||
pub mod database;
|
9
backend/docker-compose.yml
Normal file
9
backend/docker-compose.yml
Normal file
@@ -0,0 +1,9 @@
|
||||
services:
|
||||
backend:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: Dockerfile
|
||||
hostname: backend
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- 7878:7878
|
54
backend/src/database/assets.rs
Normal file
54
backend/src/database/assets.rs
Normal file
@@ -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<Vec<Asset>, Box<dyn Error + Send + Sync>> {
|
||||
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<Option<Asset>, Box<dyn Error + Send + Sync>> {
|
||||
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<Asset, Box<dyn Error + Send + Sync>> {
|
||||
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<Option<Asset>, Box<dyn Error + Send + Sync>> {
|
||||
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<Option<Asset>, Box<dyn Error + Send + Sync>> {
|
||||
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())
|
||||
}
|
1
backend/src/database/mod.rs
Normal file
1
backend/src/database/mod.rs
Normal file
@@ -0,0 +1 @@
|
||||
pub mod assets;
|
39
backend/src/main.rs
Normal file
39
backend/src/main.rs
Normal file
@@ -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<dyn Error + Send + Sync>> {
|
||||
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(())
|
||||
}
|
@@ -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<sqlx::PgPool, Box<dyn Error + Send + Sync>> {
|
||||
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<Hook>,
|
||||
) -> Result<RabbitmqPool, Box<dyn Error + Send + Sync>> {
|
||||
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<Hook>,
|
||||
) -> Result<deadpool_lapin::Pool, Box<dyn Error + Send + Sync>> {
|
||||
create_rabbitmq_pool(&env::var("RABBITMQ_URL")?, num_clients, post_create).await
|
||||
}
|
115
backend/src/routes/assets.rs
Normal file
115
backend/src/routes/assets.rs
Normal file
@@ -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<PgPool>,
|
||||
) -> Result<(StatusCode, Json<Vec<Asset>>), 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<PgPool>,
|
||||
Path(symbol): Path<String>,
|
||||
) -> Result<(StatusCode, Json<Asset>), 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<bool>,
|
||||
}
|
||||
|
||||
pub async fn add_asset(
|
||||
Extension(database_pool): Extension<PgPool>,
|
||||
Extension(alpaca_pool): Extension<AlpacaPool>,
|
||||
Json(request): Json<AddAssetRequest>,
|
||||
) -> Result<(StatusCode, Json<Asset>), 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::<asset::Get>(&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<PgPool>,
|
||||
Path(symbol): Path<String>,
|
||||
Json(request): Json<UpdateAssetRequest>,
|
||||
) -> Result<(StatusCode, Json<Asset>), 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<PgPool>,
|
||||
Path(symbol): Path<String>,
|
||||
) -> Result<(StatusCode, Json<Asset>), 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),
|
||||
}
|
||||
}
|
1
backend/src/routes/mod.rs
Normal file
1
backend/src/routes/mod.rs
Normal file
@@ -0,0 +1 @@
|
||||
pub mod assets;
|
Reference in New Issue
Block a user