Skip to content

Commit

Permalink
add balance-by-account service in rust
Browse files Browse the repository at this point in the history
  • Loading branch information
mxfactorial committed Mar 24, 2024
1 parent 9bb77aa commit c026a40
Show file tree
Hide file tree
Showing 6 changed files with 139 additions and 16 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ members = [
"crates/service",
"crates/shutdown",
"crates/types",
"services/balance-by-account",
"services/graphql",
"services/request-approve",
"services/request-by-id",
Expand Down
38 changes: 30 additions & 8 deletions docker/dev/balance-by-account.Dockerfile
Original file line number Diff line number Diff line change
@@ -1,17 +1,39 @@
FROM mxfactorial/go-base:v1 as builder
FROM rust:latest as builder

COPY . .
WORKDIR /app

WORKDIR /app/services/balance-by-account
COPY . ./

RUN go build -o balance-by-account ./cmd
RUN rustup target add x86_64-unknown-linux-musl
RUN apt update && \
apt install -y musl-tools perl make
RUN update-ca-certificates

FROM golang:alpine
ENV USER=balance-by-account
ENV UID=10004

WORKDIR /app
RUN adduser \
--disabled-password \
--gecos "" \
--home "/nonexistent" \
--shell "/sbin/nologin" \
--no-create-home \
--uid "${UID}" \
"${USER}"

RUN USER=root cargo build \
--manifest-path=services/balance-by-account/Cargo.toml \
--target x86_64-unknown-linux-musl \
--release

COPY --from=builder /app/services/balance-by-account/balance-by-account .
FROM alpine

COPY --from=builder /etc/passwd /etc/passwd
COPY --from=builder /etc/group /etc/group
COPY --from=builder /app/target/x86_64-unknown-linux-musl/release/balance-by-account /usr/local/bin

EXPOSE 10004

CMD ["/app/balance-by-account"]
USER balance-by-account:balance-by-account

CMD [ "/usr/local/bin/balance-by-account" ]
4 changes: 2 additions & 2 deletions project.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -598,13 +598,13 @@ services:
- PGPASSWORD
- PGDATABASE
balance-by-account:
runtime: go1.x
runtime: rust1.x
min_code_cov: null
type: app
local_dev: true
params: []
deploy: true
build_src_path: cmd
build_src_path: null
dependents: []
env_var:
set:
Expand Down
18 changes: 18 additions & 0 deletions services/balance-by-account/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[package]
name = "balance-by-account"
version = "0.1.0"
edition = "2021"
rust-version.workspace = true

[dependencies]
axum = "0.7.4"
tracing = "0.1.40"
tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
tokio = { version = "1.35.1", features = ["macros", "rt-multi-thread"] }
shutdown = { path = "../../crates/shutdown" }
pg = { path = "../../crates/pg" }
service = { path = "../../crates/service" }
types = { path = "../../crates/types" }

[target.x86_64-unknown-linux-musl.dependencies]
openssl = { version = "0.10", features = ["vendored"] }
20 changes: 14 additions & 6 deletions services/balance-by-account/makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
RELATIVE_PROJECT_ROOT_PATH=$(shell REL_PATH="."; while [ $$(ls "$$REL_PATH" | grep project.yaml | wc -l | xargs) -eq 0 ]; do REL_PATH="$$REL_PATH./.."; done; printf '%s' "$$REL_PATH")
include $(RELATIVE_PROJECT_ROOT_PATH)/make/shared.mk
include $(RELATIVE_PROJECT_ROOT_PATH)/make/go.mk
include $(RELATIVE_PROJECT_ROOT_PATH)/make/rust.mk

BALANCE_BY_ACCOUNT_PORT=$(shell yq '.services["$(APP_NAME)"].env_var.set.BALANCE_BY_ACCOUNT_PORT.default' $(PROJECT_CONF))
BALANCE_BY_ACCOUNT_URL=$(HOST):$(BALANCE_BY_ACCOUNT_PORT)
Expand All @@ -10,13 +10,21 @@ TEST_AUTH_ACCOUNT=$(TEST_ACCOUNT)
TEST_EVENT='{"auth_account":"$(TEST_AUTH_ACCOUNT)","account_name":"$(TEST_ACCOUNT)"}'
TEST_SENDER_ACCOUNT=$(TEST_ACCOUNT)

run:
@$(DOCKER_ENV_VARS) \
TEST_EVENT=$(TEST_EVENT) \
go run ./cmd/main.go
start:
@$(MAKE) get-secrets ENV=local
nohup cargo watch --env-file $(ENV_FILE) -w src -w $(RELATIVE_PROJECT_ROOT_PATH)/crates -x run >> $(NOHUP_LOG) &

start-alone:
rm -f $(NOHUP_LOG)
$(MAKE) -C $(MIGRATIONS_DIR) run
$(MAKE) start
tail -F $(NOHUP_LOG)

stop:
$(MAKE) -C $(RELATIVE_PROJECT_ROOT_PATH) stop

invoke-local:
@curl -s -d $(TEST_EVENT) $(BALANCE_BY_ACCOUNT_URL)
@curl -s -H 'Content-Type: application/json' -d $(TEST_EVENT) $(BALANCE_BY_ACCOUNT_URL)

demo:
@printf "*** request to %s at %s\n" $(SUB_PATH) $(BALANCE_BY_ACCOUNT_URL)
Expand Down
74 changes: 74 additions & 0 deletions services/balance-by-account/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
use axum::{
extract::{Json, State},
http::StatusCode,
routing::{get, post},
Router,
};
use pg::postgres::{ConnectionPool, DB};
use service::Service;
use shutdown::shutdown_signal;
use std::{env, net::ToSocketAddrs};
use tokio::net::TcpListener;
use types::request_response::QueryByAccount;

// used by lambda to test for service availability
const READINESS_CHECK_PATH: &str = "READINESS_CHECK_PATH";

async fn handle_event(
State(pool): State<ConnectionPool>,
event: Json<QueryByAccount>,
) -> Result<String, StatusCode> {
let client_request = event.0;

let svc = Service::new(pool.get_conn().await);

let account = client_request.account_name;

let account_balance = svc.get_account_balance(account).await.map_err(|e| {
tracing::error!("error: {}", e);
StatusCode::INTERNAL_SERVER_ERROR
})?;

Ok(account_balance)
}

#[tokio::main]
async fn main() {
tracing_subscriber::fmt::init();

let readiness_check_path = env::var(READINESS_CHECK_PATH)
.unwrap_or_else(|_| panic!("{READINESS_CHECK_PATH} variable assignment"));

let conn_uri = DB::create_conn_uri_from_env_vars();

let pool = DB::new_pool(&conn_uri).await;

let app = Router::new()
.route("/", post(handle_event))
.route(
readiness_check_path.as_str(),
get(|| async { StatusCode::OK }),
)
.with_state(pool);

let hostname_or_ip = env::var("HOSTNAME_OR_IP").unwrap_or("0.0.0.0".to_string());

let port = env::var("BALANCE_BY_ACCOUNT_PORT").unwrap_or("10004".to_string());

let serve_addr = format!("{hostname_or_ip}:{port}");

let mut addrs_iter = serve_addr.to_socket_addrs().unwrap_or(
format!("{hostname_or_ip}:{port}")
.to_socket_addrs()
.unwrap(),
);

let addr = addrs_iter.next().unwrap();

tracing::info!("listening on {}", addr);

axum::serve(TcpListener::bind(addr).await.unwrap(), app)
.with_graceful_shutdown(shutdown_signal())
.await
.unwrap();
}

0 comments on commit c026a40

Please sign in to comment.