Change account manager into microservice
This commit is contained in:
parent
c994f00076
commit
8e037fe1e7
221
Cargo.lock
generated
221
Cargo.lock
generated
@ -9,14 +9,17 @@ dependencies = [
|
|||||||
"actix 0.13.0",
|
"actix 0.13.0",
|
||||||
"actix-rt",
|
"actix-rt",
|
||||||
"bincode",
|
"bincode",
|
||||||
"bus",
|
|
||||||
"bytes",
|
"bytes",
|
||||||
|
"channels",
|
||||||
"config",
|
"config",
|
||||||
"database_manager",
|
"database_manager",
|
||||||
"dotenv",
|
"dotenv",
|
||||||
"futures 0.3.25",
|
"futures 0.3.25",
|
||||||
|
"gumdrop",
|
||||||
"json",
|
"json",
|
||||||
"model",
|
"model",
|
||||||
|
"opentelemetry 0.17.0",
|
||||||
|
"opentelemetry-jaeger",
|
||||||
"pretty_env_logger",
|
"pretty_env_logger",
|
||||||
"rumqttc",
|
"rumqttc",
|
||||||
"serde",
|
"serde",
|
||||||
@ -24,6 +27,7 @@ dependencies = [
|
|||||||
"thiserror",
|
"thiserror",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tracing",
|
"tracing",
|
||||||
|
"tracing-opentelemetry",
|
||||||
"tracing-subscriber",
|
"tracing-subscriber",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -419,8 +423,8 @@ dependencies = [
|
|||||||
"actix-http",
|
"actix-http",
|
||||||
"actix-web",
|
"actix-web",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"opentelemetry",
|
"opentelemetry 0.17.0",
|
||||||
"opentelemetry-semantic-conventions",
|
"opentelemetry-semantic-conventions 0.9.0",
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -653,7 +657,6 @@ checksum = "b645a089122eccb6111b4f81cbc1a49f5900ac4666bb93ac027feaecf15607bf"
|
|||||||
name = "bazzar"
|
name = "bazzar"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"account_manager",
|
|
||||||
"actix 0.13.0",
|
"actix 0.13.0",
|
||||||
"actix-broker",
|
"actix-broker",
|
||||||
"actix-cors",
|
"actix-cors",
|
||||||
@ -669,6 +672,7 @@ dependencies = [
|
|||||||
"async-trait",
|
"async-trait",
|
||||||
"bytes",
|
"bytes",
|
||||||
"cart_manager",
|
"cart_manager",
|
||||||
|
"channels",
|
||||||
"chrono",
|
"chrono",
|
||||||
"config",
|
"config",
|
||||||
"database_manager",
|
"database_manager",
|
||||||
@ -694,6 +698,7 @@ dependencies = [
|
|||||||
"serde_json",
|
"serde_json",
|
||||||
"sqlx",
|
"sqlx",
|
||||||
"sqlx-core",
|
"sqlx-core",
|
||||||
|
"tarpc",
|
||||||
"tera",
|
"tera",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"token_manager",
|
"token_manager",
|
||||||
@ -791,19 +796,6 @@ version = "3.11.1"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba"
|
checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "bus"
|
|
||||||
version = "0.1.0"
|
|
||||||
dependencies = [
|
|
||||||
"bincode",
|
|
||||||
"bytes",
|
|
||||||
"model",
|
|
||||||
"rumqttc",
|
|
||||||
"serde",
|
|
||||||
"thiserror",
|
|
||||||
"tracing",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bytecodec"
|
name = "bytecodec"
|
||||||
version = "0.4.15"
|
version = "0.4.15"
|
||||||
@ -841,7 +833,7 @@ version = "0.1.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"actix 0.13.0",
|
"actix 0.13.0",
|
||||||
"actix-rt",
|
"actix-rt",
|
||||||
"bus",
|
"channels",
|
||||||
"chrono",
|
"chrono",
|
||||||
"config",
|
"config",
|
||||||
"database_manager",
|
"database_manager",
|
||||||
@ -875,6 +867,21 @@ version = "1.0.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "channels"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"bincode",
|
||||||
|
"bytes",
|
||||||
|
"config",
|
||||||
|
"model",
|
||||||
|
"rumqttc",
|
||||||
|
"serde",
|
||||||
|
"tarpc",
|
||||||
|
"thiserror",
|
||||||
|
"tracing",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "chrono"
|
name = "chrono"
|
||||||
version = "0.4.22"
|
version = "0.4.22"
|
||||||
@ -1329,6 +1336,18 @@ dependencies = [
|
|||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "educe"
|
||||||
|
version = "0.4.20"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cb0188e3c3ba8df5753894d54461f0e39bc91741dc5b22e1c46999ec2c71f4e4"
|
||||||
|
dependencies = [
|
||||||
|
"enum-ordinalize",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "either"
|
name = "either"
|
||||||
version = "1.8.0"
|
version = "1.8.0"
|
||||||
@ -1370,6 +1389,20 @@ dependencies = [
|
|||||||
"cfg-if 1.0.0",
|
"cfg-if 1.0.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "enum-ordinalize"
|
||||||
|
version = "3.1.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a62bb1df8b45ecb7ffa78dca1c17a438fb193eb083db0b1b494d2a61bcb5096a"
|
||||||
|
dependencies = [
|
||||||
|
"num-bigint",
|
||||||
|
"num-traits",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"rustc_version 0.4.0",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "env_logger"
|
name = "env_logger"
|
||||||
version = "0.7.1"
|
version = "0.7.1"
|
||||||
@ -2172,6 +2205,12 @@ dependencies = [
|
|||||||
"cfg-if 1.0.0",
|
"cfg-if 1.0.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "integer-encoding"
|
||||||
|
version = "3.0.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8bb03732005da905c88227371639bf1ad885cc712789c011c31c5fb3ab3ccf02"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "intl-memoizer"
|
name = "intl-memoizer"
|
||||||
version = "0.5.1"
|
version = "0.5.1"
|
||||||
@ -2411,6 +2450,15 @@ dependencies = [
|
|||||||
"winapi 0.3.9",
|
"winapi 0.3.9",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "matchers"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558"
|
||||||
|
dependencies = [
|
||||||
|
"regex-automata",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "matches"
|
name = "matches"
|
||||||
version = "0.1.9"
|
version = "0.1.9"
|
||||||
@ -2785,13 +2833,81 @@ dependencies = [
|
|||||||
"tokio-stream",
|
"tokio-stream",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "opentelemetry"
|
||||||
|
version = "0.18.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "69d6c3d7288a106c0a363e4b0e8d308058d56902adefb16f4936f417ffef086e"
|
||||||
|
dependencies = [
|
||||||
|
"opentelemetry_api",
|
||||||
|
"opentelemetry_sdk",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "opentelemetry-jaeger"
|
||||||
|
version = "0.17.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1e785d273968748578931e4dc3b4f5ec86b26e09d9e0d66b55adda7fce742f7a"
|
||||||
|
dependencies = [
|
||||||
|
"async-trait",
|
||||||
|
"futures 0.3.25",
|
||||||
|
"futures-executor",
|
||||||
|
"once_cell",
|
||||||
|
"opentelemetry 0.18.0",
|
||||||
|
"opentelemetry-semantic-conventions 0.10.0",
|
||||||
|
"thiserror",
|
||||||
|
"thrift",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "opentelemetry-semantic-conventions"
|
name = "opentelemetry-semantic-conventions"
|
||||||
version = "0.9.0"
|
version = "0.9.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "985cc35d832d412224b2cffe2f9194b1b89b6aa5d0bef76d080dce09d90e62bd"
|
checksum = "985cc35d832d412224b2cffe2f9194b1b89b6aa5d0bef76d080dce09d90e62bd"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"opentelemetry",
|
"opentelemetry 0.17.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "opentelemetry-semantic-conventions"
|
||||||
|
version = "0.10.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9b02e0230abb0ab6636d18e2ba8fa02903ea63772281340ccac18e0af3ec9eeb"
|
||||||
|
dependencies = [
|
||||||
|
"opentelemetry 0.18.0",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "opentelemetry_api"
|
||||||
|
version = "0.18.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c24f96e21e7acc813c7a8394ee94978929db2bcc46cf6b5014fc612bf7760c22"
|
||||||
|
dependencies = [
|
||||||
|
"futures-channel",
|
||||||
|
"futures-util",
|
||||||
|
"indexmap",
|
||||||
|
"js-sys",
|
||||||
|
"once_cell",
|
||||||
|
"pin-project-lite",
|
||||||
|
"thiserror",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "opentelemetry_sdk"
|
||||||
|
version = "0.18.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1ca41c4933371b61c2a2f214bf16931499af4ec90543604ec828f7a625c09113"
|
||||||
|
dependencies = [
|
||||||
|
"async-trait",
|
||||||
|
"crossbeam-channel",
|
||||||
|
"futures-channel",
|
||||||
|
"futures-executor",
|
||||||
|
"futures-util",
|
||||||
|
"once_cell",
|
||||||
|
"opentelemetry_api",
|
||||||
|
"percent-encoding",
|
||||||
|
"rand",
|
||||||
|
"thiserror",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -2812,6 +2928,15 @@ dependencies = [
|
|||||||
"uuid 1.2.1",
|
"uuid 1.2.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ordered-float"
|
||||||
|
version = "1.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3305af35278dd29f46fcdd139e0b1fbfae2153f0e5928b39b035542dd31e37b7"
|
||||||
|
dependencies = [
|
||||||
|
"num-traits",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "os_type"
|
name = "os_type"
|
||||||
version = "2.6.0"
|
version = "2.6.0"
|
||||||
@ -3248,6 +3373,15 @@ dependencies = [
|
|||||||
"regex-syntax",
|
"regex-syntax",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex-automata"
|
||||||
|
version = "0.1.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132"
|
||||||
|
dependencies = [
|
||||||
|
"regex-syntax",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex-syntax"
|
name = "regex-syntax"
|
||||||
version = "0.6.27"
|
version = "0.6.27"
|
||||||
@ -3952,13 +4086,15 @@ dependencies = [
|
|||||||
"fnv",
|
"fnv",
|
||||||
"futures 0.3.25",
|
"futures 0.3.25",
|
||||||
"humantime 2.1.0",
|
"humantime 2.1.0",
|
||||||
"opentelemetry",
|
"opentelemetry 0.17.0",
|
||||||
"pin-project",
|
"pin-project",
|
||||||
"rand",
|
"rand",
|
||||||
|
"serde",
|
||||||
"static_assertions",
|
"static_assertions",
|
||||||
"tarpc-plugins",
|
"tarpc-plugins",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
"tokio-serde",
|
||||||
"tokio-util 0.7.4",
|
"tokio-util 0.7.4",
|
||||||
"tracing",
|
"tracing",
|
||||||
"tracing-opentelemetry",
|
"tracing-opentelemetry",
|
||||||
@ -4063,6 +4199,28 @@ dependencies = [
|
|||||||
"once_cell",
|
"once_cell",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "threadpool"
|
||||||
|
version = "1.8.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa"
|
||||||
|
dependencies = [
|
||||||
|
"num_cpus",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thrift"
|
||||||
|
version = "0.16.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "09678c4cdbb4eed72e18b7c2af1329c69825ed16fcbac62d083fc3e2b0590ff0"
|
||||||
|
dependencies = [
|
||||||
|
"byteorder",
|
||||||
|
"integer-encoding",
|
||||||
|
"log",
|
||||||
|
"ordered-float",
|
||||||
|
"threadpool",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "time"
|
name = "time"
|
||||||
version = "0.1.44"
|
version = "0.1.44"
|
||||||
@ -4219,6 +4377,22 @@ dependencies = [
|
|||||||
"webpki",
|
"webpki",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio-serde"
|
||||||
|
version = "0.8.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "911a61637386b789af998ee23f50aa30d5fd7edcec8d6d3dedae5e5815205466"
|
||||||
|
dependencies = [
|
||||||
|
"bincode",
|
||||||
|
"bytes",
|
||||||
|
"educe",
|
||||||
|
"futures-core",
|
||||||
|
"futures-sink",
|
||||||
|
"pin-project",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio-stream"
|
name = "tokio-stream"
|
||||||
version = "0.1.11"
|
version = "0.1.11"
|
||||||
@ -4326,9 +4500,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "fbbe89715c1dbbb790059e2565353978564924ee85017b5fff365c872ff6721f"
|
checksum = "fbbe89715c1dbbb790059e2565353978564924ee85017b5fff365c872ff6721f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"opentelemetry",
|
"opentelemetry 0.17.0",
|
||||||
"tracing",
|
"tracing",
|
||||||
"tracing-core",
|
"tracing-core",
|
||||||
|
"tracing-log",
|
||||||
"tracing-subscriber",
|
"tracing-subscriber",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -4338,10 +4513,14 @@ version = "0.3.16"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a6176eae26dd70d0c919749377897b54a9276bd7061339665dd68777926b5a70"
|
checksum = "a6176eae26dd70d0c919749377897b54a9276bd7061339665dd68777926b5a70"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"matchers",
|
||||||
"nu-ansi-term",
|
"nu-ansi-term",
|
||||||
|
"once_cell",
|
||||||
|
"regex",
|
||||||
"sharded-slab",
|
"sharded-slab",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"thread_local",
|
"thread_local",
|
||||||
|
"tracing",
|
||||||
"tracing-core",
|
"tracing-core",
|
||||||
"tracing-log",
|
"tracing-log",
|
||||||
]
|
]
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
members = [
|
members = [
|
||||||
# shared
|
# shared
|
||||||
"shared/model",
|
"shared/model",
|
||||||
"shared/bus",
|
"shared/channels",
|
||||||
"shared/config",
|
"shared/config",
|
||||||
"shared/testx",
|
"shared/testx",
|
||||||
# actors
|
# actors
|
||||||
|
@ -11,19 +11,23 @@ path = "./src/main.rs"
|
|||||||
actix = { version = "0.13", features = [] }
|
actix = { version = "0.13", features = [] }
|
||||||
actix-rt = { version = "2.7", features = [] }
|
actix-rt = { version = "2.7", features = [] }
|
||||||
bincode = { version = "1.3.3" }
|
bincode = { version = "1.3.3" }
|
||||||
bus = { path = "../../shared/bus" }
|
|
||||||
bytes = { version = "1.2.1" }
|
bytes = { version = "1.2.1" }
|
||||||
|
channels = { path = "../../shared/channels" }
|
||||||
config = { path = "../../shared/config" }
|
config = { path = "../../shared/config" }
|
||||||
database_manager = { path = "../database_manager" }
|
database_manager = { path = "../database_manager" }
|
||||||
dotenv = { version = "0.15.0" }
|
dotenv = { version = "0.15.0" }
|
||||||
futures = { version = "0.3.25" }
|
futures = { version = "0.3.25" }
|
||||||
|
gumdrop = { version = "0.8.1" }
|
||||||
json = { version = "0.12.4" }
|
json = { version = "0.12.4" }
|
||||||
model = { path = "../../shared/model" }
|
model = { path = "../../shared/model" }
|
||||||
|
opentelemetry = { version = "0.17.0" }
|
||||||
|
opentelemetry-jaeger = { version = "0.17.0" }
|
||||||
pretty_env_logger = { version = "0.4", features = [] }
|
pretty_env_logger = { version = "0.4", features = [] }
|
||||||
rumqttc = { version = "*" }
|
rumqttc = { version = "*" }
|
||||||
serde = { version = "1.0.137", features = ["derive"] }
|
serde = { version = "1.0.137", features = ["derive"] }
|
||||||
tarpc = { version = "0.30.0", features = ["tokio1"] }
|
tarpc = { version = "0.30.0", features = ["tokio1", "serde-transport-bincode", "serde-transport", "serde", "serde-transport-json", "tcp"] }
|
||||||
thiserror = { version = "1.0.31" }
|
thiserror = { version = "1.0.31" }
|
||||||
tokio = { version = "1.21.2", features = ['full'] }
|
tokio = { version = "1.21.2", features = ['full'] }
|
||||||
tracing = { version = "0.1.6" }
|
tracing = { version = "0.1.6" }
|
||||||
tracing-subscriber = { version = "0.3.16" }
|
tracing-opentelemetry = { version = "0.17.4" }
|
||||||
|
tracing-subscriber = { version = "0.3.16", features = ["env-filter"] }
|
||||||
|
82
actors/account_manager/src/actions.rs
Normal file
82
actors/account_manager/src/actions.rs
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
use channels::account::{CreateAccount, MeResult};
|
||||||
|
use config::SharedAppConfig;
|
||||||
|
use database_manager::Database;
|
||||||
|
use model::{Encrypt, FullAccount};
|
||||||
|
|
||||||
|
use crate::{Error, Result};
|
||||||
|
|
||||||
|
#[allow(unused)]
|
||||||
|
pub async fn me(account_id: model::AccountId, db: Database) -> MeResult {
|
||||||
|
use channels::account::Error;
|
||||||
|
|
||||||
|
let msg = database_manager::FindAccount { account_id };
|
||||||
|
let account: model::FullAccount = match msg.inner_find_account(db.pool().clone()).await {
|
||||||
|
Ok(account) => account,
|
||||||
|
Err(e) => {
|
||||||
|
tracing::error!("{}", e);
|
||||||
|
return MeResult {
|
||||||
|
error: Some(Error::Account),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let msg = database_manager::AccountAddresses { account_id };
|
||||||
|
let addresses = match msg.inner_account_addresses(db.pool().clone()).await {
|
||||||
|
Ok(v) => v,
|
||||||
|
Err(e) => {
|
||||||
|
tracing::error!("{}", e);
|
||||||
|
return MeResult {
|
||||||
|
error: Some(Error::Addresses),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
MeResult {
|
||||||
|
account: Some(account),
|
||||||
|
addresses: Some(addresses),
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn create_account(
|
||||||
|
msg: CreateAccount,
|
||||||
|
db: &Database,
|
||||||
|
config: SharedAppConfig,
|
||||||
|
) -> Result<FullAccount> {
|
||||||
|
let hash = msg
|
||||||
|
.password
|
||||||
|
.encrypt(&config.lock().web().pass_salt())
|
||||||
|
.map_err(|e| {
|
||||||
|
tracing::error!("{e:?}");
|
||||||
|
Error::Hashing
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let mut t = db.pool().begin().await.map_err(|e| {
|
||||||
|
tracing::error!("{}", e);
|
||||||
|
Error::DbCritical
|
||||||
|
})?;
|
||||||
|
let account: FullAccount = match database_manager::create_account(
|
||||||
|
database_manager::CreateAccount {
|
||||||
|
email: msg.email,
|
||||||
|
login: msg.login,
|
||||||
|
pass_hash: model::PassHash::new(hash),
|
||||||
|
role: msg.role,
|
||||||
|
},
|
||||||
|
&mut t,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
Ok(r) => r,
|
||||||
|
Err(e) => {
|
||||||
|
tracing::error!("{}", e);
|
||||||
|
t.rollback().await.ok();
|
||||||
|
return Err(Error::Saving);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
t.commit().await.map_err(|e| {
|
||||||
|
tracing::error!("{}", e);
|
||||||
|
Error::DbCritical
|
||||||
|
})?;
|
||||||
|
|
||||||
|
Ok(account)
|
||||||
|
}
|
43
actors/account_manager/src/bin/account-client.rs
Normal file
43
actors/account_manager/src/bin/account-client.rs
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
use std::net::SocketAddr;
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
|
use config::UpdateConfig;
|
||||||
|
use tarpc::tokio_serde::formats::Json;
|
||||||
|
use tarpc::{client, context};
|
||||||
|
use tokio::time::sleep;
|
||||||
|
|
||||||
|
#[derive(gumdrop::Options)]
|
||||||
|
struct Flags {
|
||||||
|
help: bool,
|
||||||
|
/// Sets the name to say hello to.
|
||||||
|
name: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl UpdateConfig for Flags {}
|
||||||
|
|
||||||
|
#[tokio::main]
|
||||||
|
async fn main() -> std::io::Result<()> {
|
||||||
|
let opts: Flags = gumdrop::Options::parse_args_default_or_exit();
|
||||||
|
|
||||||
|
let config = config::default_load(&opts);
|
||||||
|
let client = channels::account::rpc::create_client(config).await;
|
||||||
|
|
||||||
|
let r = client.me(context::current(), 1.into()).await;
|
||||||
|
println!("{:?}", r);
|
||||||
|
|
||||||
|
let hello = async move {
|
||||||
|
tokio::join! {
|
||||||
|
client.me(context::current(), 1.into()),
|
||||||
|
client.me(context::current(), 2.into()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.await;
|
||||||
|
|
||||||
|
eprintln!("{:?}", hello);
|
||||||
|
|
||||||
|
// Let the background span processor finish.
|
||||||
|
sleep(Duration::from_micros(1)).await;
|
||||||
|
opentelemetry::global::shutdown_tracer_provider();
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
@ -1,164 +0,0 @@
|
|||||||
use actix::Addr;
|
|
||||||
use config::SharedAppConfig;
|
|
||||||
use database_manager::query_db;
|
|
||||||
use model::{Email, Encrypt, FullAccount, Login, Password, Role};
|
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, serde::Serialize, thiserror::Error)]
|
|
||||||
#[serde(rename_all = "kebab-case", tag = "account")]
|
|
||||||
pub enum Error {
|
|
||||||
#[error("Unable to send or receive msg from database")]
|
|
||||||
DbCritical,
|
|
||||||
#[error("Failed to load account data")]
|
|
||||||
Account,
|
|
||||||
#[error("Failed to load account addresses")]
|
|
||||||
Addresses,
|
|
||||||
#[error("Unable to save record")]
|
|
||||||
Saving,
|
|
||||||
#[error("Unable to hash password")]
|
|
||||||
Hashing,
|
|
||||||
#[error("{0}")]
|
|
||||||
Db(#[from] database_manager::Error),
|
|
||||||
}
|
|
||||||
|
|
||||||
pub type Result<T> = std::result::Result<T, Error>;
|
|
||||||
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! account_async_handler {
|
|
||||||
($msg: ty, $async: ident, $res: ty) => {
|
|
||||||
impl actix::Handler<$msg> for AccountManager {
|
|
||||||
type Result = actix::ResponseActFuture<Self, Result<$res>>;
|
|
||||||
|
|
||||||
fn handle(&mut self, msg: $msg, _ctx: &mut Self::Context) -> Self::Result {
|
|
||||||
use actix::WrapFuture;
|
|
||||||
let db = self.db.clone();
|
|
||||||
let config = self.config.clone();
|
|
||||||
Box::pin(async { $async(msg, db, config).await }.into_actor(self))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! query_account {
|
|
||||||
($cart: expr, $msg: expr, default $fail: expr) => {
|
|
||||||
match $cart.send($msg).await {
|
|
||||||
Ok(Ok(r)) => r,
|
|
||||||
Ok(Err(e)) => {
|
|
||||||
tracing::error!("{e}");
|
|
||||||
$fail
|
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
tracing::error!("{e:?}");
|
|
||||||
$fail
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
($cart: expr, $msg: expr, $fail: expr) => {
|
|
||||||
$crate::query_cart!($cart, $msg, $fail, $fail)
|
|
||||||
};
|
|
||||||
|
|
||||||
($cart: expr, $msg: expr, $db_fail: expr, $act_fail: expr) => {
|
|
||||||
match $cart.send($msg).await {
|
|
||||||
Ok(Ok(r)) => r,
|
|
||||||
Ok(Err(e)) => {
|
|
||||||
tracing::error!("{e}");
|
|
||||||
return Err($db_fail);
|
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
tracing::error!("{e:?}");
|
|
||||||
return Err($act_fail);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct AccountManager {
|
|
||||||
db: Addr<database_manager::Database>,
|
|
||||||
config: SharedAppConfig,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AccountManager {
|
|
||||||
pub fn new(config: SharedAppConfig, db: Addr<database_manager::Database>) -> Self {
|
|
||||||
Self { config, db }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl actix::Actor for AccountManager {
|
|
||||||
type Context = actix::Context<Self>;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct MeResult {
|
|
||||||
pub account: FullAccount,
|
|
||||||
pub addresses: Vec<model::AccountAddress>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(actix::Message, Debug)]
|
|
||||||
#[rtype(result = "Result<MeResult>")]
|
|
||||||
pub struct Me {
|
|
||||||
pub account_id: model::AccountId,
|
|
||||||
}
|
|
||||||
|
|
||||||
account_async_handler!(Me, me, MeResult);
|
|
||||||
|
|
||||||
pub(crate) async fn me(
|
|
||||||
msg: Me,
|
|
||||||
db: Addr<database_manager::Database>,
|
|
||||||
_config: SharedAppConfig,
|
|
||||||
) -> Result<MeResult> {
|
|
||||||
let account: FullAccount = query_db!(
|
|
||||||
db,
|
|
||||||
database_manager::FindAccount {
|
|
||||||
account_id: msg.account_id
|
|
||||||
},
|
|
||||||
Error::Account
|
|
||||||
);
|
|
||||||
let addresses = query_db!(
|
|
||||||
db,
|
|
||||||
database_manager::AccountAddresses {
|
|
||||||
account_id: msg.account_id
|
|
||||||
},
|
|
||||||
Error::Addresses
|
|
||||||
);
|
|
||||||
Ok(MeResult { account, addresses })
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(actix::Message)]
|
|
||||||
#[rtype(result = "Result<FullAccount>")]
|
|
||||||
pub struct CreateAccount {
|
|
||||||
pub email: Email,
|
|
||||||
pub login: Login,
|
|
||||||
pub password: Password,
|
|
||||||
pub role: Role,
|
|
||||||
}
|
|
||||||
|
|
||||||
account_async_handler!(CreateAccount, create_account, FullAccount);
|
|
||||||
|
|
||||||
pub(crate) async fn create_account(
|
|
||||||
msg: CreateAccount,
|
|
||||||
db: Addr<database_manager::Database>,
|
|
||||||
config: SharedAppConfig,
|
|
||||||
) -> Result<FullAccount> {
|
|
||||||
let hash = {
|
|
||||||
match msg.password.encrypt(&config.lock().web().pass_salt()) {
|
|
||||||
Ok(hash) => hash,
|
|
||||||
Err(e) => {
|
|
||||||
tracing::error!("{e:?}");
|
|
||||||
return Err(Error::Hashing);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let account: FullAccount = query_db!(
|
|
||||||
db,
|
|
||||||
database_manager::CreateAccount {
|
|
||||||
email: msg.email,
|
|
||||||
login: msg.login,
|
|
||||||
pass_hash: model::PassHash::new(hash),
|
|
||||||
role: msg.role,
|
|
||||||
},
|
|
||||||
Error::DbCritical,
|
|
||||||
Error::Saving
|
|
||||||
);
|
|
||||||
Ok(account)
|
|
||||||
}
|
|
@ -1,12 +1,16 @@
|
|||||||
#![feature(structural_match)]
|
#![feature(structural_match)]
|
||||||
|
|
||||||
use std::time::Duration;
|
use std::env;
|
||||||
|
|
||||||
use bus::account::{AccountFailure, CreateAccount, Topic};
|
use config::UpdateConfig;
|
||||||
use config::{SharedAppConfig, UpdateConfig};
|
|
||||||
use database_manager::Database;
|
use database_manager::Database;
|
||||||
use model::{Encrypt, FullAccount};
|
use tracing_subscriber::fmt::format::FmtSpan;
|
||||||
use rumqttc::{AsyncClient, Event, Incoming, MqttOptions, QoS};
|
use tracing_subscriber::layer::SubscriberExt;
|
||||||
|
use tracing_subscriber::util::SubscriberInitExt;
|
||||||
|
|
||||||
|
pub mod actions;
|
||||||
|
pub mod mqtt;
|
||||||
|
pub mod rpc;
|
||||||
|
|
||||||
pub type Result<T> = std::result::Result<T, Error>;
|
pub type Result<T> = std::result::Result<T, Error>;
|
||||||
|
|
||||||
@ -33,7 +37,7 @@ impl UpdateConfig for Opts {}
|
|||||||
#[actix::main]
|
#[actix::main]
|
||||||
async fn main() {
|
async fn main() {
|
||||||
dotenv::dotenv().ok();
|
dotenv::dotenv().ok();
|
||||||
tracing_subscriber::fmt::init();
|
init_tracing("account-manager");
|
||||||
|
|
||||||
let opts = Opts {};
|
let opts = Opts {};
|
||||||
|
|
||||||
@ -41,213 +45,26 @@ async fn main() {
|
|||||||
|
|
||||||
let db = Database::build(config.clone()).await;
|
let db = Database::build(config.clone()).await;
|
||||||
|
|
||||||
mqtt::start(config, &db).await;
|
let mqtt_client = mqtt::start(config.clone(), db.clone()).await;
|
||||||
|
rpc::start(config.clone(), db.clone(), mqtt_client.clone()).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
mod grpc {
|
pub fn init_tracing(_service_name: &str) {
|
||||||
use config::SharedAppConfig;
|
env::set_var("OTEL_BSP_MAX_EXPORT_BATCH_SIZE", "12");
|
||||||
use database_manager::Database;
|
|
||||||
use futures::future::{self, Ready};
|
|
||||||
use futures::prelude::*;
|
|
||||||
use futures::stream::StreamExt;
|
|
||||||
use json::JsonValue;
|
|
||||||
use tarpc::server::incoming::Incoming;
|
|
||||||
use tarpc::server::{self, Channel};
|
|
||||||
use tarpc::{client, context};
|
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, serde::Serialize, thiserror::Error)]
|
let tracer = {
|
||||||
#[serde(rename_all = "kebab-case", tag = "account")]
|
use opentelemetry::sdk::export::trace::stdout::new_pipeline;
|
||||||
pub enum Error {
|
use opentelemetry::sdk::trace::Config;
|
||||||
#[error("Unable to send or receive msg from database")]
|
new_pipeline()
|
||||||
DbCritical,
|
.with_trace_config(Config::default())
|
||||||
#[error("Failed to load account data")]
|
.with_pretty_print(true)
|
||||||
Account,
|
.install_simple()
|
||||||
#[error("Failed to load account addresses")]
|
};
|
||||||
Addresses,
|
|
||||||
#[error("Unable to save record")]
|
|
||||||
Saving,
|
|
||||||
#[error("Unable to hash password")]
|
|
||||||
Hashing,
|
|
||||||
#[error("{0}")]
|
|
||||||
Db(#[from] database_manager::Error),
|
|
||||||
}
|
|
||||||
|
|
||||||
pub type Result<T> = std::result::Result<T, Error>;
|
tracing_subscriber::registry()
|
||||||
|
.with(tracing_subscriber::EnvFilter::from_default_env())
|
||||||
pub struct MeResult {
|
.with(tracing_subscriber::fmt::layer().with_span_events(FmtSpan::NEW | FmtSpan::CLOSE))
|
||||||
pub account: model::FullAccount,
|
.with(tracing_opentelemetry::layer().with_tracer(tracer))
|
||||||
pub addresses: Vec<model::AccountAddress>,
|
.try_init()
|
||||||
}
|
|
||||||
|
|
||||||
#[tarpc::service]
|
|
||||||
trait Accounts {
|
|
||||||
/// Returns a greeting for name.
|
|
||||||
async fn me(account_id: model::AccountId) -> String;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
|
||||||
struct AccountsServer {
|
|
||||||
db: Database,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Accounts for AccountsServer {
|
|
||||||
// Each defined rpc generates two items in the trait, a fn that serves the RPC,
|
|
||||||
// and an associated type representing the future output by the fn.
|
|
||||||
|
|
||||||
type AccountsFut = Ready<String>;
|
|
||||||
|
|
||||||
fn me(self, _: context::Context, account_id: model::AccountId) -> Self::AccountsFut {
|
|
||||||
future::ready(format!("Hello, {name}!"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn me(
|
|
||||||
account_id: model::AccountId,
|
|
||||||
db: Database,
|
|
||||||
_config: SharedAppConfig,
|
|
||||||
) -> Result<MeResult> {
|
|
||||||
let account: model::FullAccount = query_db!(
|
|
||||||
db,
|
|
||||||
database_manager::FindAccount {
|
|
||||||
account_id: msg.account_id
|
|
||||||
},
|
|
||||||
Error::Account
|
|
||||||
);
|
|
||||||
let addresses = query_db!(
|
|
||||||
db,
|
|
||||||
database_manager::AccountAddresses {
|
|
||||||
account_id: msg.account_id
|
|
||||||
},
|
|
||||||
Error::Addresses
|
|
||||||
);
|
|
||||||
Ok(MeResult { account, addresses })
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn start(config: SharedAppConfig) {
|
|
||||||
let port = { config.lock().account_manager().port };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mod mqtt {
|
|
||||||
use std::time::Duration;
|
|
||||||
|
|
||||||
use account_manager::CreateAccount;
|
|
||||||
use bus::account::{AccountFailure, Topic};
|
|
||||||
use config::SharedAppConfig;
|
|
||||||
use database_manager::Database;
|
|
||||||
use model::{Encrypt, FullAccount};
|
|
||||||
use rumqttc::{AsyncClient, Event, Incoming, MqttOptions, QoS};
|
|
||||||
|
|
||||||
use crate::{Error, Result};
|
|
||||||
|
|
||||||
pub async fn start(config: SharedAppConfig, db: &Database) {
|
|
||||||
let mut mqtt_options = MqttOptions::new(bus::account::CLIENT_NAME, "0.0.0.0", 1883);
|
|
||||||
mqtt_options.set_keep_alive(Duration::from_secs(5));
|
|
||||||
|
|
||||||
let (client, mut event_loop) = AsyncClient::new(mqtt_options, 10);
|
|
||||||
client
|
|
||||||
.subscribe(Topic::CreateAccount, QoS::AtLeastOnce)
|
|
||||||
.await
|
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let client = bus::AsyncClient(client);
|
|
||||||
loop {
|
|
||||||
let notification = event_loop.poll().await;
|
|
||||||
|
|
||||||
match notification {
|
|
||||||
Ok(Event::Incoming(Incoming::Publish(publish))) => match publish.topic.as_str() {
|
|
||||||
topic if Topic::CreateAccount == topic => {
|
|
||||||
if let Ok(msg) = CreateAccount::try_from(publish.payload) {
|
|
||||||
match create_account(msg, &db, config.clone()).await {
|
|
||||||
Ok(account) => {
|
|
||||||
client
|
|
||||||
.publish_or_log(
|
|
||||||
Topic::AccountCreated,
|
|
||||||
QoS::AtLeastOnce,
|
|
||||||
true,
|
|
||||||
model::Account::from(account),
|
|
||||||
)
|
|
||||||
.await;
|
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
tracing::error!("{}", e);
|
|
||||||
let m = match e {
|
|
||||||
Error::Hashing => {
|
|
||||||
Some(AccountFailure::FailedToHashPassword)
|
|
||||||
}
|
|
||||||
Error::Saving => Some(AccountFailure::SaveAccount),
|
|
||||||
Error::DbCritical => {
|
|
||||||
Some(AccountFailure::InternalServerError)
|
|
||||||
}
|
|
||||||
_ => None,
|
|
||||||
};
|
|
||||||
if let Some(m) = m {
|
|
||||||
client
|
|
||||||
.publish_or_log(
|
|
||||||
Topic::SignUpFailure,
|
|
||||||
QoS::AtLeastOnce,
|
|
||||||
true,
|
|
||||||
m,
|
|
||||||
)
|
|
||||||
.await;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
},
|
|
||||||
Ok(Event::Incoming(_incoming)) => {}
|
|
||||||
Ok(Event::Outgoing(_outgoing)) => {}
|
|
||||||
Err(e) => {
|
|
||||||
tracing::error!("{}", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) async fn create_account(
|
|
||||||
msg: CreateAccount,
|
|
||||||
db: &database_manager::Database,
|
|
||||||
config: SharedAppConfig,
|
|
||||||
) -> Result<FullAccount> {
|
|
||||||
let hash = {
|
|
||||||
match msg.password.encrypt(&config.lock().web().pass_salt()) {
|
|
||||||
Ok(hash) => hash,
|
|
||||||
Err(e) => {
|
|
||||||
tracing::error!("{e:?}");
|
|
||||||
return Err(Error::Hashing);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut t = db.pool().begin().await.map_err(|e| {
|
|
||||||
tracing::error!("{}", e);
|
|
||||||
Error::DbCritical
|
|
||||||
})?;
|
|
||||||
let account: FullAccount = match database_manager::create_account(
|
|
||||||
database_manager::CreateAccount {
|
|
||||||
email: msg.email,
|
|
||||||
login: msg.login,
|
|
||||||
pass_hash: model::PassHash::new(hash),
|
|
||||||
role: msg.role,
|
|
||||||
},
|
|
||||||
&mut t,
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
{
|
|
||||||
Ok(r) => r,
|
|
||||||
Err(e) => {
|
|
||||||
tracing::error!("{}", e);
|
|
||||||
t.rollback().await.ok();
|
|
||||||
return Err(Error::Saving);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
t.commit().await.map_err(|e| {
|
|
||||||
tracing::error!("{}", e);
|
|
||||||
Error::DbCritical
|
|
||||||
})?;
|
|
||||||
|
|
||||||
Ok(account)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
99
actors/account_manager/src/mqtt.rs
Normal file
99
actors/account_manager/src/mqtt.rs
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
|
use channels::account::{AccountFailure, CreateAccount, Topic};
|
||||||
|
use config::SharedAppConfig;
|
||||||
|
use database_manager::Database;
|
||||||
|
use rumqttc::{AsyncClient, Event, Incoming, MqttOptions, QoS};
|
||||||
|
|
||||||
|
use crate::{actions, Error};
|
||||||
|
|
||||||
|
pub async fn start(config: SharedAppConfig, db: Database) -> channels::AsyncClient {
|
||||||
|
tracing::info!("Starting account mqtt at 0.0.0.0:1883");
|
||||||
|
let mut mqtt_options = MqttOptions::new(channels::account::CLIENT_NAME, "0.0.0.0", 1883);
|
||||||
|
mqtt_options.set_keep_alive(Duration::from_secs(5));
|
||||||
|
|
||||||
|
let (client, mut event_loop) = AsyncClient::new(mqtt_options, 10);
|
||||||
|
client
|
||||||
|
.subscribe(Topic::CreateAccount, QoS::AtLeastOnce)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let client = channels::AsyncClient(client);
|
||||||
|
let spawn_client = client.clone();
|
||||||
|
tokio::spawn(async move {
|
||||||
|
let client = spawn_client.clone();
|
||||||
|
loop {
|
||||||
|
let notification = event_loop.poll().await;
|
||||||
|
|
||||||
|
match notification {
|
||||||
|
Ok(Event::Incoming(Incoming::Publish(publish))) => match publish.topic.as_str() {
|
||||||
|
topic if Topic::CreateAccount == topic => {
|
||||||
|
if let Ok(channels::account::CreateAccount {
|
||||||
|
email,
|
||||||
|
login,
|
||||||
|
password,
|
||||||
|
role,
|
||||||
|
}) = channels::account::CreateAccount::try_from(publish.payload)
|
||||||
|
{
|
||||||
|
match actions::create_account(
|
||||||
|
CreateAccount {
|
||||||
|
email,
|
||||||
|
login,
|
||||||
|
password,
|
||||||
|
role,
|
||||||
|
},
|
||||||
|
&db,
|
||||||
|
config.clone(),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
Ok(account) => {
|
||||||
|
client
|
||||||
|
.publish_or_log(
|
||||||
|
Topic::AccountCreated,
|
||||||
|
QoS::AtLeastOnce,
|
||||||
|
true,
|
||||||
|
model::Account::from(account),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
tracing::error!("{}", e);
|
||||||
|
let m = match e {
|
||||||
|
Error::Hashing => {
|
||||||
|
Some(AccountFailure::FailedToHashPassword)
|
||||||
|
}
|
||||||
|
Error::Saving => Some(AccountFailure::SaveAccount),
|
||||||
|
Error::DbCritical => {
|
||||||
|
Some(AccountFailure::InternalServerError)
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
|
};
|
||||||
|
if let Some(m) = m {
|
||||||
|
client
|
||||||
|
.publish_or_log(
|
||||||
|
Topic::SignUpFailure,
|
||||||
|
QoS::AtLeastOnce,
|
||||||
|
true,
|
||||||
|
m,
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
},
|
||||||
|
Ok(Event::Incoming(_incoming)) => {}
|
||||||
|
Ok(Event::Outgoing(_outgoing)) => {}
|
||||||
|
Err(e) => {
|
||||||
|
tracing::error!("{}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
client
|
||||||
|
// tracing::info!("Mqtt channel closed");
|
||||||
|
}
|
111
actors/account_manager/src/rpc.rs
Normal file
111
actors/account_manager/src/rpc.rs
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
use std::net::{IpAddr, Ipv4Addr};
|
||||||
|
|
||||||
|
use channels::account::{CreateAccount, MeResult, RegisterResult};
|
||||||
|
use channels::AsyncClient;
|
||||||
|
use config::SharedAppConfig;
|
||||||
|
use database_manager::Database;
|
||||||
|
use futures::future::{self};
|
||||||
|
use futures::stream::StreamExt;
|
||||||
|
use rumqttc::QoS;
|
||||||
|
use tarpc::context;
|
||||||
|
use tarpc::server::incoming::Incoming;
|
||||||
|
use tarpc::server::{self, Channel};
|
||||||
|
use tarpc::tokio_serde::formats::Json;
|
||||||
|
|
||||||
|
use crate::actions;
|
||||||
|
|
||||||
|
#[derive(Debug, Copy, Clone, serde::Serialize, thiserror::Error)]
|
||||||
|
#[serde(rename_all = "kebab-case", tag = "account")]
|
||||||
|
pub enum Error {
|
||||||
|
#[error("Unable to send or receive msg from database")]
|
||||||
|
DbCritical,
|
||||||
|
#[error("Failed to load account data")]
|
||||||
|
Account,
|
||||||
|
#[error("Failed to load account addresses")]
|
||||||
|
Addresses,
|
||||||
|
#[error("Unable to save record")]
|
||||||
|
Saving,
|
||||||
|
#[error("Unable to hash password")]
|
||||||
|
Hashing,
|
||||||
|
#[error("{0}")]
|
||||||
|
Db(#[from] database_manager::Error),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
struct AccountsServer {
|
||||||
|
db: Database,
|
||||||
|
config: SharedAppConfig,
|
||||||
|
mqtt_client: AsyncClient,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tarpc::server]
|
||||||
|
impl channels::account::rpc::Accounts for AccountsServer {
|
||||||
|
async fn me(self, _: context::Context, account_id: model::AccountId) -> MeResult {
|
||||||
|
let res = actions::me(account_id, self.db).await;
|
||||||
|
tracing::info!("ME result: {:?}", res);
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn register_account(self, _: context::Context, details: CreateAccount) -> RegisterResult {
|
||||||
|
let res = actions::create_account(details, &self.db, self.config).await;
|
||||||
|
tracing::info!("REGISTER result: {:?}", res);
|
||||||
|
match res {
|
||||||
|
Ok(account) => {
|
||||||
|
self.mqtt_client
|
||||||
|
.publish_or_log(
|
||||||
|
channels::account::Topic::AccountCreated,
|
||||||
|
QoS::AtLeastOnce,
|
||||||
|
true,
|
||||||
|
&account,
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
RegisterResult {
|
||||||
|
account: Some(account),
|
||||||
|
error: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(_e) => RegisterResult {
|
||||||
|
account: None,
|
||||||
|
error: Some(channels::account::Error::Account),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn start(config: SharedAppConfig, db: Database, mqtt_client: AsyncClient) {
|
||||||
|
use channels::account::rpc::Accounts;
|
||||||
|
|
||||||
|
let port = { config.lock().account_manager().port };
|
||||||
|
|
||||||
|
let server_addr = (IpAddr::V4(Ipv4Addr::LOCALHOST), port);
|
||||||
|
|
||||||
|
let mut listener = tarpc::serde_transport::tcp::listen(&server_addr, Json::default)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
tracing::info!("Starting account rpc at {}", listener.local_addr());
|
||||||
|
listener.config_mut().max_frame_length(usize::MAX);
|
||||||
|
listener
|
||||||
|
// Ignore accept errors.
|
||||||
|
.filter_map(|r| future::ready(r.ok()))
|
||||||
|
.map(server::BaseChannel::with_defaults)
|
||||||
|
// Limit channels to 8 per IP.
|
||||||
|
.max_channels_per_key(8, |t| t.transport().peer_addr().unwrap().ip())
|
||||||
|
.max_concurrent_requests_per_channel(20)
|
||||||
|
// serve is generated by the service attribute. It takes as input any type implementing
|
||||||
|
// the generated World trait.
|
||||||
|
.map(|channel| {
|
||||||
|
channel.execute(
|
||||||
|
AccountsServer {
|
||||||
|
db: db.clone(),
|
||||||
|
config: config.clone(),
|
||||||
|
mqtt_client: mqtt_client.clone(),
|
||||||
|
}
|
||||||
|
.serve(),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
// Max 10 channels.
|
||||||
|
.buffer_unordered(10)
|
||||||
|
.for_each(|_| async {})
|
||||||
|
.await;
|
||||||
|
tracing::info!("RPC channel closed");
|
||||||
|
}
|
@ -6,7 +6,7 @@ edition = "2021"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
actix = { version = "0.13", features = [] }
|
actix = { version = "0.13", features = [] }
|
||||||
actix-rt = { version = "2.7", features = [] }
|
actix-rt = { version = "2.7", features = [] }
|
||||||
bus = { path = "../../shared/bus" }
|
channels = { path = "../../shared/channels" }
|
||||||
chrono = { version = "0.4", features = ["serde"] }
|
chrono = { version = "0.4", features = ["serde"] }
|
||||||
config = { path = "../../shared/config" }
|
config = { path = "../../shared/config" }
|
||||||
database_manager = { path = "../database_manager" }
|
database_manager = { path = "../database_manager" }
|
||||||
|
@ -43,12 +43,13 @@ macro_rules! db_async_handler {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
($msg: ty, $async: ident, $res: ty, $inner_async: ident) => {
|
($msg: ty, $async: ident, $res: ty, $inner_async: ident) => {
|
||||||
async fn $inner_async(msg: $msg, pool: sqlx::PgPool) -> Result<$res> {
|
impl $msg {
|
||||||
|
pub async fn $inner_async(self, pool: sqlx::PgPool) -> Result<$res> {
|
||||||
let mut t = pool.begin().await.map_err(|e| {
|
let mut t = pool.begin().await.map_err(|e| {
|
||||||
tracing::error!("{:?}", e);
|
tracing::error!("{:?}", e);
|
||||||
$crate::Error::TransactionFailed
|
$crate::Error::TransactionFailed
|
||||||
})?;
|
})?;
|
||||||
match $async(msg, &mut t).await {
|
match $async(self, &mut t).await {
|
||||||
Ok(res) => {
|
Ok(res) => {
|
||||||
t.commit().await.map_err(|e| {
|
t.commit().await.map_err(|e| {
|
||||||
tracing::error!("{:?}", e);
|
tracing::error!("{:?}", e);
|
||||||
@ -62,6 +63,7 @@ macro_rules! db_async_handler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl actix::Handler<$msg> for $crate::Database {
|
impl actix::Handler<$msg> for $crate::Database {
|
||||||
type Result = actix::ResponseActFuture<Self, Result<$res>>;
|
type Result = actix::ResponseActFuture<Self, Result<$res>>;
|
||||||
@ -69,7 +71,7 @@ macro_rules! db_async_handler {
|
|||||||
fn handle(&mut self, msg: $msg, _ctx: &mut Self::Context) -> Self::Result {
|
fn handle(&mut self, msg: $msg, _ctx: &mut Self::Context) -> Self::Result {
|
||||||
use actix::WrapFuture;
|
use actix::WrapFuture;
|
||||||
let pool = self.pool.clone();
|
let pool = self.pool.clone();
|
||||||
Box::pin(async { $inner_async(msg, pool).await }.into_actor(self))
|
Box::pin(async { msg.$inner_async(pool).await }.into_actor(self))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -170,7 +172,7 @@ pub type Result<T> = std::result::Result<T, Error>;
|
|||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Database {
|
pub struct Database {
|
||||||
pool: PgPool,
|
pool: PgPool,
|
||||||
config: SharedAppConfig,
|
_config: SharedAppConfig,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type SharedDatabase = actix::Addr<Database>;
|
pub type SharedDatabase = actix::Addr<Database>;
|
||||||
@ -182,7 +184,10 @@ impl Database {
|
|||||||
tracing::error!("Failed to connect to database. {e:?}");
|
tracing::error!("Failed to connect to database. {e:?}");
|
||||||
std::process::exit(1);
|
std::process::exit(1);
|
||||||
});
|
});
|
||||||
Self { pool, config }
|
Self {
|
||||||
|
pool,
|
||||||
|
_config: config,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pool(&self) -> &PgPool {
|
pub fn pool(&self) -> &PgPool {
|
||||||
|
@ -4,7 +4,6 @@ version = "0.1.0"
|
|||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
account_manager = { path = "../actors/account_manager" }
|
|
||||||
actix = { version = "0.13", features = [] }
|
actix = { version = "0.13", features = [] }
|
||||||
actix-broker = { version = "0.4", features = [] }
|
actix-broker = { version = "0.4", features = [] }
|
||||||
actix-cors = { version = "0.6", features = [] }
|
actix-cors = { version = "0.6", features = [] }
|
||||||
@ -20,6 +19,7 @@ actix-web-opentelemetry = { version = "0.12", features = [] }
|
|||||||
async-trait = { version = "0.1", features = [] }
|
async-trait = { version = "0.1", features = [] }
|
||||||
bytes = { version = "1.1.0" }
|
bytes = { version = "1.1.0" }
|
||||||
cart_manager = { path = "../actors/cart_manager" }
|
cart_manager = { path = "../actors/cart_manager" }
|
||||||
|
channels = { path = "../shared/channels" }
|
||||||
chrono = { version = "0.4", features = ["serde"] }
|
chrono = { version = "0.4", features = ["serde"] }
|
||||||
config = { path = "../shared/config" }
|
config = { path = "../shared/config" }
|
||||||
database_manager = { path = "../actors/database_manager" }
|
database_manager = { path = "../actors/database_manager" }
|
||||||
@ -54,3 +54,4 @@ tracing = { version = "0.1.34" }
|
|||||||
tracing-subscriber = { version = "0.3.11" }
|
tracing-subscriber = { version = "0.3.11" }
|
||||||
uuid = { version = "1.2.1", features = ["serde"] }
|
uuid = { version = "1.2.1", features = ["serde"] }
|
||||||
validator = { version = "0.14", features = [] }
|
validator = { version = "0.14", features = [] }
|
||||||
|
tarpc = { version = "0.30.0", features = ["tokio1", "serde-transport-bincode", "serde-transport", "serde", "serde-transport-json", "tcp"] }
|
||||||
|
@ -59,8 +59,7 @@ async fn server(opts: ServerOpts) -> Result<()> {
|
|||||||
.await
|
.await
|
||||||
.expect("Failed to initialize file system storage");
|
.expect("Failed to initialize file system storage");
|
||||||
let cart_manager = cart_manager::CartManager::new(db.clone()).start();
|
let cart_manager = cart_manager::CartManager::new(db.clone()).start();
|
||||||
let account_manager =
|
let account_manager = channels::account::rpc::create_client(app_config.clone()).await;
|
||||||
account_manager::AccountManager::new(app_config.clone(), db.clone()).start();
|
|
||||||
let addr = {
|
let addr = {
|
||||||
let l = app_config.lock();
|
let l = app_config.lock();
|
||||||
let w = l.web();
|
let w = l.web();
|
||||||
|
@ -40,7 +40,6 @@ pub enum Error {
|
|||||||
CriticalFailure,
|
CriticalFailure,
|
||||||
Public(public::Error),
|
Public(public::Error),
|
||||||
Admin(admin::Error),
|
Admin(admin::Error),
|
||||||
Account(account_manager::Error),
|
|
||||||
Cart(cart_manager::Error),
|
Cart(cart_manager::Error),
|
||||||
Database(database_manager::Error),
|
Database(database_manager::Error),
|
||||||
Email(email_manager::Error),
|
Email(email_manager::Error),
|
||||||
@ -79,7 +78,6 @@ impl Display for Error {
|
|||||||
})
|
})
|
||||||
.unwrap_or_default(),
|
.unwrap_or_default(),
|
||||||
Error::CriticalFailure => String::from("Something went wrong"),
|
Error::CriticalFailure => String::from("Something went wrong"),
|
||||||
Error::Account(_e) => serde_json::to_string(&self).unwrap_or_default(),
|
|
||||||
Error::Cart(_e) => serde_json::to_string(&self).unwrap_or_default(),
|
Error::Cart(_e) => serde_json::to_string(&self).unwrap_or_default(),
|
||||||
Error::Database(_e) => serde_json::to_string(&self).unwrap_or_default(),
|
Error::Database(_e) => serde_json::to_string(&self).unwrap_or_default(),
|
||||||
Error::Email(_e) => serde_json::to_string(&self).unwrap_or_default(),
|
Error::Email(_e) => serde_json::to_string(&self).unwrap_or_default(),
|
||||||
@ -102,7 +100,6 @@ impl ResponseError for Error {
|
|||||||
}
|
}
|
||||||
Error::Admin(_) => StatusCode::BAD_REQUEST,
|
Error::Admin(_) => StatusCode::BAD_REQUEST,
|
||||||
Error::Public(_) => StatusCode::BAD_REQUEST,
|
Error::Public(_) => StatusCode::BAD_REQUEST,
|
||||||
Error::Account(_) => StatusCode::BAD_REQUEST,
|
|
||||||
Error::Cart(_) => StatusCode::BAD_REQUEST,
|
Error::Cart(_) => StatusCode::BAD_REQUEST,
|
||||||
Error::Database(_) => StatusCode::BAD_REQUEST,
|
Error::Database(_) => StatusCode::BAD_REQUEST,
|
||||||
Error::Email(_) => StatusCode::BAD_REQUEST,
|
Error::Email(_) => StatusCode::BAD_REQUEST,
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
use account_manager::query_account;
|
|
||||||
use actix::Addr;
|
use actix::Addr;
|
||||||
use actix_web::web::{scope, Data, Json, ServiceConfig};
|
use actix_web::web::{scope, Data, Json, ServiceConfig};
|
||||||
use actix_web::{delete, get, post, put, HttpRequest, HttpResponse};
|
use actix_web::{delete, get, post, put, HttpRequest, HttpResponse};
|
||||||
@ -210,7 +209,7 @@ async fn delete_cart_item(
|
|||||||
|
|
||||||
#[get("/me")]
|
#[get("/me")]
|
||||||
pub(crate) async fn me(
|
pub(crate) async fn me(
|
||||||
account: Data<Addr<account_manager::AccountManager>>,
|
account: Data<channels::account::rpc::AccountsClient>,
|
||||||
tm: Data<Addr<TokenManager>>,
|
tm: Data<Addr<TokenManager>>,
|
||||||
credentials: BearerAuth,
|
credentials: BearerAuth,
|
||||||
) -> routes::Result<Json<model::api::Account>> {
|
) -> routes::Result<Json<model::api::Account>> {
|
||||||
@ -218,14 +217,14 @@ pub(crate) async fn me(
|
|||||||
.require_user(tm.into_inner())
|
.require_user(tm.into_inner())
|
||||||
.await?
|
.await?
|
||||||
.account_id();
|
.account_id();
|
||||||
let account_manager::MeResult { account, addresses } = query_account!(
|
|
||||||
account,
|
|
||||||
account_manager::Me { account_id },
|
|
||||||
PublicError::DatabaseConnection.into(),
|
|
||||||
PublicError::DatabaseConnection.into()
|
|
||||||
);
|
|
||||||
|
|
||||||
Ok(Json((account, addresses).into()))
|
match account.me(tarpc::context::current(), account_id).await {
|
||||||
|
Ok(me) => Ok(Json((me.account.unwrap(), me.addresses.unwrap()).into())),
|
||||||
|
Err(e) => {
|
||||||
|
tracing::error!("{}", e);
|
||||||
|
Err(routes::Error::CriticalFailure)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[post("/order")]
|
#[post("/order")]
|
||||||
|
@ -1,13 +1,15 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "bus"
|
name = "channels"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
serde = { version = "*", features = ['derive'] }
|
|
||||||
bincode = { version = "*" }
|
bincode = { version = "*" }
|
||||||
model = { path = "../model" }
|
|
||||||
bytes = { version = "1.2.1" }
|
bytes = { version = "1.2.1" }
|
||||||
|
config = { path = "../config" }
|
||||||
|
model = { path = "../model" }
|
||||||
|
rumqttc = { version = "0.17.0" }
|
||||||
|
serde = { version = "*", features = ['derive'] }
|
||||||
|
tarpc = { version = "0.30.0", features = ["tokio1", "serde-transport-bincode", "serde-transport", "serde", "serde-transport-json", "tcp"] }
|
||||||
thiserror = { version = "1.0.37" }
|
thiserror = { version = "1.0.37" }
|
||||||
tracing = { version = "0.1.37" }
|
tracing = { version = "0.1.37" }
|
||||||
rumqttc = { version = "0.17.0" }
|
|
@ -1,5 +1,6 @@
|
|||||||
#![feature(structural_match)]
|
#![feature(structural_match)]
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
pub struct AsyncClient(pub rumqttc::AsyncClient);
|
pub struct AsyncClient(pub rumqttc::AsyncClient);
|
||||||
|
|
||||||
impl AsyncClient {
|
impl AsyncClient {
|
||||||
@ -31,12 +32,16 @@ impl AsyncClient {
|
|||||||
pub mod account {
|
pub mod account {
|
||||||
use model::{Email, Login, Password, Role};
|
use model::{Email, Login, Password, Role};
|
||||||
|
|
||||||
#[derive(Debug, thiserror::Error)]
|
#[derive(Debug, thiserror::Error, serde::Serialize, serde::Deserialize)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
#[error("mqtt payload has invalid create account data")]
|
#[error("mqtt payload has invalid create account data")]
|
||||||
InvalidCreateAccount,
|
InvalidCreateAccount,
|
||||||
#[error("mqtt payload has invalid account failure data")]
|
#[error("mqtt payload has invalid account failure data")]
|
||||||
InvalidAccountFailure,
|
InvalidAccountFailure,
|
||||||
|
#[error("Account does not exists")]
|
||||||
|
Account,
|
||||||
|
#[error("Account does have any addresses")]
|
||||||
|
Addresses,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub static CLIENT_NAME: &str = "account-manager";
|
pub static CLIENT_NAME: &str = "account-manager";
|
||||||
@ -115,4 +120,52 @@ pub mod account {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, serde::Serialize, serde::Deserialize)]
|
||||||
|
pub struct MeResult {
|
||||||
|
pub account: Option<model::FullAccount>,
|
||||||
|
pub addresses: Option<Vec<model::AccountAddress>>,
|
||||||
|
pub error: Option<Error>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, serde::Serialize, serde::Deserialize)]
|
||||||
|
pub struct RegisterResult {
|
||||||
|
pub account: Option<model::FullAccount>,
|
||||||
|
pub error: Option<Error>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub mod rpc {
|
||||||
|
use config::SharedAppConfig;
|
||||||
|
|
||||||
|
#[tarpc::service]
|
||||||
|
pub trait Accounts {
|
||||||
|
/// Returns a greeting for name.
|
||||||
|
async fn me(account_id: model::AccountId) -> crate::account::MeResult;
|
||||||
|
|
||||||
|
/// Creates new user account.
|
||||||
|
async fn register_account(
|
||||||
|
details: crate::account::CreateAccount,
|
||||||
|
) -> crate::account::RegisterResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn create_client(config: SharedAppConfig) -> AccountsClient {
|
||||||
|
use tarpc::client;
|
||||||
|
use tarpc::tokio_serde::formats::Json;
|
||||||
|
|
||||||
|
let addr = {
|
||||||
|
let l = config.lock();
|
||||||
|
(l.account_manager().bind.clone(), l.account_manager().port)
|
||||||
|
};
|
||||||
|
|
||||||
|
let transport = tarpc::serde_transport::tcp::connect(addr, Json::default);
|
||||||
|
|
||||||
|
let client = AccountsClient::new(
|
||||||
|
client::Config::default(),
|
||||||
|
transport.await.expect("Failed to connect to server"),
|
||||||
|
)
|
||||||
|
.spawn();
|
||||||
|
|
||||||
|
client
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -4,18 +4,18 @@ version = "0.1.0"
|
|||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
|
||||||
serde_json = { version = "1.0", features = [] }
|
actix-web = { version = "4.0", features = [] }
|
||||||
toml = { version = "0.5", features = [] }
|
|
||||||
|
|
||||||
parking_lot = { version = "0.12", features = [] }
|
parking_lot = { version = "0.12", features = [] }
|
||||||
|
|
||||||
password-hash = { version = "0.4", features = ["alloc"] }
|
password-hash = { version = "0.4", features = ["alloc"] }
|
||||||
|
|
||||||
pay_u = { version = '0.1', features = ["single-client"] }
|
pay_u = { version = '0.1', features = ["single-client"] }
|
||||||
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
actix-web = { version = "4.0", features = [] }
|
serde_json = { version = "1.0", features = [] }
|
||||||
|
|
||||||
tracing = { version = "0.1.34" }
|
|
||||||
|
|
||||||
thiserror = { version = "1.0" }
|
thiserror = { version = "1.0" }
|
||||||
|
toml = { version = "0.5", features = [] }
|
||||||
|
|
||||||
|
tracing = { version = "0.1.34" }
|
||||||
|
@ -425,17 +425,24 @@ impl FilesConfig {
|
|||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
pub struct AccountManagerConfig {
|
pub struct AccountManagerConfig {
|
||||||
pub port: u16,
|
pub port: u16,
|
||||||
|
pub bind: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for AccountManagerConfig {
|
impl Default for AccountManagerConfig {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self { port: 19329 }
|
Self {
|
||||||
|
port: 19329,
|
||||||
|
bind: "0.0.0.0".into(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Example for AccountManagerConfig {
|
impl Example for AccountManagerConfig {
|
||||||
fn example() -> Self {
|
fn example() -> Self {
|
||||||
Self { port: 19329 }
|
Self {
|
||||||
|
port: 19329,
|
||||||
|
bind: "0.0.0.0".into(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user