From 47e18919f0f15e0bb3d311f95dd0cdaf00b8b8b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Djk=C3=A1=C5=A5o?= Date: Mon, 18 Mar 2024 16:12:39 +0100 Subject: [PATCH] fix logging, docker building- sitemap args --- .dockerignore | 5 ++ .gitignore | 1 + Cargo.lock | 7 +++ Dockerfile | 36 ++++++----- Makefile.toml | 12 ++-- app-template/src/app.rs | 15 ++++- docker-compose.yml | 61 +++++++++++++++++++ docker-gateway.env | 25 ++++++++ docker-sitemap.env | 25 ++++++++ rust-toolchain.tomln => rust-toolchain.toml | 1 - sdk/src/apl/redis_apl.rs | 2 +- sdk/src/config.rs | 6 +- sdk/src/webhooks/sync_response.rs | 16 ++--- simple-payment-gateway/src/app.rs | 23 +++++-- simple-payment-gateway/src/main.rs | 11 +++- simple-payment-gateway/src/routes/webhooks.rs | 4 +- sitemap-generator/Cargo.toml | 1 + sitemap-generator/README.md | 7 +++ sitemap-generator/src/app.rs | 3 +- sitemap-generator/src/main.rs | 23 +++++-- sitemap-generator/src/routes/register.rs | 12 ++-- 21 files changed, 238 insertions(+), 58 deletions(-) create mode 100644 docker-compose.yml create mode 100644 docker-gateway.env create mode 100644 docker-sitemap.env rename rust-toolchain.tomln => rust-toolchain.toml (63%) diff --git a/.dockerignore b/.dockerignore index 6e26e15..f2f4636 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,6 +1,11 @@ target/ tmp/ +.git +.github +volumes/ +temp/ Cargo.lock Dockerfile Makefile.toml +rust-toolchain.toml diff --git a/.gitignore b/.gitignore index dd32a0d..3475a3c 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ .env temp temp/**.* +volumes/ # Allow !.env.example diff --git a/Cargo.lock b/Cargo.lock index c52371e..7c58663 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2133,6 +2133,12 @@ dependencies = [ "sha2 0.10.8", ] +[[package]] +name = "pico-args" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315" + [[package]] name = "pin-project" version = "1.1.4" @@ -2983,6 +2989,7 @@ dependencies = [ "envy", "fd-lock", "flate2", + "pico-args", "quick-xml", "redis", "saleor-app-sdk", diff --git a/Dockerfile b/Dockerfile index 259ca6b..99c8977 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,24 +1,28 @@ -FROM rust:alpine as chef -RUN apk add musl-dev pkgconfig openssl openssl-dev -ENV OPENSSL_DIR=/usr -# RUN rustup default nightly -# RUN rustup target add x86_64-unknown-linux-musl +FROM rust:latest as chef +RUN apt-get update -y && \ + apt-get install -y pkg-config libssl-dev +# ENV OPENSSL_DIR=/usr +RUN rustup default nightly RUN cargo install cargo-chef -WORKDIR /src +WORKDIR /apps FROM chef as planner COPY . . RUN cargo chef prepare --recipe-path recipe.json FROM chef as builder -COPY --from=planner /src/recipe.json recipe.json -RUN cargo chef cook --target=x86_64-unknown-linux-musl --release --recipe-path=recipe.json +COPY --from=planner /apps/recipe.json recipe.json +#--target=x86_64-unknown-linux-musl +RUN cargo chef cook --release --recipe-path=recipe.json COPY . . -RUN cargo build --target=x86_64-unknown-linux-musl --release +RUN cargo build --release -FROM scratch as chef-sitemap-generator -COPY --from=builder /src/target/x86_64-unknown-linux-musl/release/sitemap-generator /sitemap-generator -CMD [ "/sitemap-generator" ] +FROM debian:bookworm-slim as chef-sitemap-generator +COPY --from=builder /apps/target/release/sitemap-generator /sitemap-generator +RUN apt-get update -y && \ + apt-get install -y pkg-config libssl-dev curl +RUN mkdir /sitemaps +CMD [ "./sitemap-generator" ] LABEL service=chef-sitemap-generator LABEL org.opencontainers.image.title="djkato/saleor-sitemap-generator"\ org.opencontainers.image.description="Creates and keeps Sitemap.xml uptodate with Saleor." \ @@ -27,9 +31,11 @@ LABEL org.opencontainers.image.title="djkato/saleor-sitemap-generator"\ org.opencontainers.image.authors="Djkáťo "\ org.opencontainers.image.licenses="PolyForm-Noncommercial-1.0.0" -FROM scratch as chef-simple-payment-gateway -COPY --from=builder /src/target/x86_64-unknown-linux-musl/release/simple-payment-gateway /simple-payment-gateway -CMD [ "/simple-payment-gateway" ] +FROM debian:bookworm-slim as chef-simple-payment-gateway +COPY --from=builder /apps/target/release/simple-payment-gateway /simple-payment-gateway +RUN apt-get update -y && \ + apt-get install -y pkg-config libssl-dev curl +CMD [ "./simple-payment-gateway" ] LABEL service=chef-simple-payment-gateway LABEL org.opencontainers.image.title="djkato/saleor-simple-payment-gateway"\ org.opencontainers.image.description="Payment gateway that adds payment methods that don't need actual verification: Cash on delivery, Cash on warehouse pickup, bank tranfer." \ diff --git a/Makefile.toml b/Makefile.toml index 1b9bfaa..9fc35c2 100644 --- a/Makefile.toml +++ b/Makefile.toml @@ -22,7 +22,11 @@ docker tag $(docker image ls -q --filter=label=service=chef-simple-payment-gatew [tasks.build-containers] workspace = false -dependencies = ["build-sitemap-generator", "build-simple-payment-gateway"] +dependencies = [ + "delete-images", + "build-sitemap-generator", + "build-simple-payment-gateway", +] [tasks.push-containers] workspace = false @@ -31,9 +35,9 @@ docker push ghcr.io/djkato/saleor-sitemap-generator:latest docker push ghcr.io/djkato/saleor-simple-payment-gateway:latest ''' -[tasks.delete-containers] +[tasks.delete-images] workspace = false script = ''' -docker image rm $(docker image ls -q --filter=label=service=chef-simple-payment-gateway) -docker image rm $(docker image ls -q --filter=label=service=chef-sitemap-generator) +docker rmi -f $(docker image ls -q --filter=label=service=chef-sitemap-generator) 2>&1 || true +docker rmi -f $(docker image ls -q --filter=label=service=chef-simple-payment-gateway) 2>&1 || true ''' diff --git a/app-template/src/app.rs b/app-template/src/app.rs index 14944ec..d21cec6 100644 --- a/app-template/src/app.rs +++ b/app-template/src/app.rs @@ -6,6 +6,8 @@ use axum::{ }; use saleor_app_sdk::{config::Config, manifest::AppManifest, SaleorApp}; +use tracing::level_filters::LevelFilter; +use tracing_subscriber::EnvFilter; // Make our own error that wraps `anyhow::Error`. pub struct AppError(anyhow::Error); @@ -32,9 +34,20 @@ where } pub fn trace_to_std(config: &Config) { + let filter = EnvFilter::builder() + .with_default_directive(LevelFilter::DEBUG.into()) + .from_env() + .unwrap() + .add_directive( + format!("{}={}", env!("CARGO_PKG_NAME"), config.log_level) + .parse() + .unwrap(), + ); tracing_subscriber::fmt() .with_max_level(config.log_level) - .with_target(false) + .with_env_filter(filter) + .with_target(true) + .compact() .init(); } diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..83f38cc --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,61 @@ +services: + app-payment-gateway: + image: ghcr.io/djkato/saleor-simple-payment-gateway:latest + tty: true + restart: unless-stopped + stdin_open: true + env_file: + - docker-gateway.env + networks: + - saleor-app-tier + depends_on: + - redis-apl + ports: + - 3001:3001 + + app-sitemap-generator: + tty: true + restart: unless-stopped + stdin_open: true + image: ghcr.io/djkato/saleor-sitemap-generator:latest + env_file: + - docker-sitemap.env + networks: + - saleor-app-tier + depends_on: + - redis-apl + ports: + - 3002:3002 + volumes: + - sitemaps:/sitemaps + + redis-apl: + image: bitnami/redis:latest + environment: + - ALLOW_EMPTY_PASSWORD=yes + - DISABLE_COMMANDS=FLUSHDB,FLUSHALL,CONFIG + ports: + - 6380:6379 + restart: unless-stopped + networks: + - saleor-app-tier + volumes: + - redis-apl:/bitnami/redis/data + +volumes: + redis-apl: + driver: local + driver_opts: + type: none + device: ./temp/volumes/redis/ + o: bind + sitemaps: + driver: local + driver_opts: + type: none + device: ./temp/docker-sitemaps/ + o: bind + +networks: + saleor-app-tier: + driver: bridge diff --git a/docker-gateway.env b/docker-gateway.env new file mode 100644 index 0000000..6762396 --- /dev/null +++ b/docker-gateway.env @@ -0,0 +1,25 @@ +## COMMON VARIABLES FOR ALL APPS +REQUIRED_SALEOR_VERSION="^3.13" +APP_API_BASE_URL="http://0.0.0.0:3001" +APL="Redis" +APL_URL="redis://redis-apl:6379/1" +LOG_LEVEL="DEBUG" + +## THESE VARIABLES ARE FOR SITEMAP-GENERATOR APP +SITEMAP_TARGET_FOLDER="./temp" +# Available fields can be found in ./sitemap-generator/src/queries/event_subjects_updated.rs: ProductUpdate +SITEMAP_PRODUCT_TEMPLATE="https://example.com/{product.category.slug}/{product.slug}" +# Available fields can be found in ./sitemap-generator/src/queries/event_subjects_updated.rs: CategoryUpdate +SITEMAP_CATEGORY_TEMPLATE="https://example.com/{category.slug}" +# Available fields can be found in ./sitemap-generator/src/queries/event_subjects_updated.rs: CollectionUpdate +SITEMAP_COLLECTION_TEMPLATE="https://example.com/collection/{collection.slug}" +# Available fields can be found in ./sitemap-generator/src/queries/event_subjects_updated.rs: PageUpdate +SITEMAP_PAGES_TEMPLATE="https://example.com/{page.slug}" +# Without trailing "/"! +SITEMAP_INDEX_HOSTNAME="https://example.com" + +## THESE VARIABLES ARE FOR SIMPLE-PAYMENT-GATEWAY APP +#To see all possible options, check simple-payment-gateway/src/app:GatewayTypes +ACTIVE_GATEWAYS="cod,cash,transfer" +# only SK,EN available :). Determines what language the gateway names will be in storefront +LOCALE="SK" diff --git a/docker-sitemap.env b/docker-sitemap.env new file mode 100644 index 0000000..5c0a857 --- /dev/null +++ b/docker-sitemap.env @@ -0,0 +1,25 @@ +## COMMON VARIABLES FOR ALL APPS +REQUIRED_SALEOR_VERSION="^3.13" +APP_API_BASE_URL="http://0.0.0.0:3002" +APL="Redis" +APL_URL="redis://redis-apl:6379/1" +LOG_LEVEL="DEBUG" + +## THESE VARIABLES ARE FOR SITEMAP-GENERATOR APP +SITEMAP_TARGET_FOLDER="./sitemaps" +# Available fields can be found in ./sitemap-generator/src/queries/event_subjects_updated.rs: ProductUpdate +SITEMAP_PRODUCT_TEMPLATE="https://example.com/{product.category.slug}/{product.slug}" +# Available fields can be found in ./sitemap-generator/src/queries/event_subjects_updated.rs: CategoryUpdate +SITEMAP_CATEGORY_TEMPLATE="https://example.com/{category.slug}" +# Available fields can be found in ./sitemap-generator/src/queries/event_subjects_updated.rs: CollectionUpdate +SITEMAP_COLLECTION_TEMPLATE="https://example.com/collection/{collection.slug}" +# Available fields can be found in ./sitemap-generator/src/queries/event_subjects_updated.rs: PageUpdate +SITEMAP_PAGES_TEMPLATE="https://example.com/{page.slug}" +# Without trailing "/"! +SITEMAP_INDEX_HOSTNAME="https://example.com" + +## THESE VARIABLES ARE FOR SIMPLE-PAYMENT-GATEWAY APP +#To see all possible options, check simple-payment-gateway/src/app:GatewayTypes +ACTIVE_GATEWAYS="cod,cash,transfer" +# only SK,EN available :). Determines what language the gateway names will be in storefront +LOCALE="SK" diff --git a/rust-toolchain.tomln b/rust-toolchain.toml similarity index 63% rename from rust-toolchain.tomln rename to rust-toolchain.toml index 4c8ab40..6071aa5 100644 --- a/rust-toolchain.tomln +++ b/rust-toolchain.toml @@ -1,4 +1,3 @@ [toolchain] channel = "nightly" -#targets = ["x86_64-unknown-linux-musl"] targets = ["x86_64-unknown-linux-gnu"] diff --git a/sdk/src/apl/redis_apl.rs b/sdk/src/apl/redis_apl.rs index d98b22c..2174128 100644 --- a/sdk/src/apl/redis_apl.rs +++ b/sdk/src/apl/redis_apl.rs @@ -78,7 +78,7 @@ impl APL for RedisApl { impl RedisApl { pub fn new(redis_url: &str, app_api_base_url: &str) -> Result { - debug!("creating redis apl..."); + debug!("creating redis apl with {redis_url}..."); let client = redis::Client::open(redis_url)?; let mut conn = client.get_connection_with_timeout(Duration::from_secs(3))?; let val: Result = diff --git a/sdk/src/config.rs b/sdk/src/config.rs index afe847f..00ed45a 100644 --- a/sdk/src/config.rs +++ b/sdk/src/config.rs @@ -38,11 +38,9 @@ impl std::fmt::Display for Config { impl Config { pub fn load() -> Result { - dotenvy::dotenv().unwrap(); + _ = dotenvy::dotenv(); let env = envy::from_env::(); - if let Ok(e) = &env { - debug!("{}", e); - } + debug!("{:?}", &env); env } } diff --git a/sdk/src/webhooks/sync_response.rs b/sdk/src/webhooks/sync_response.rs index 6107020..28f1cfc 100644 --- a/sdk/src/webhooks/sync_response.rs +++ b/sdk/src/webhooks/sync_response.rs @@ -220,17 +220,17 @@ pub struct PaymentMethod { #[derive(Serialize, Debug, Clone)] #[serde(rename_all = "camelCase")] pub struct CreditCardInfo { - brand: String, - last_digits: String, - exp_month: String, - exp_year: String, - first_digits: Option, + pub brand: String, + pub last_digits: String, + pub exp_month: String, + pub exp_year: String, + pub first_digits: Option, } #[derive(Serialize, Debug, Clone)] #[serde(rename_all = "camelCase")] pub struct ListStoredPaymentMethodsResponse { - payment_methods: Vec>, - name: Option, - data: Option, + pub payment_methods: Vec>, + pub name: Option, + pub data: Option, } diff --git a/simple-payment-gateway/src/app.rs b/simple-payment-gateway/src/app.rs index 2837c58..7d862ca 100644 --- a/simple-payment-gateway/src/app.rs +++ b/simple-payment-gateway/src/app.rs @@ -3,12 +3,12 @@ use axum::{ response::{IntoResponse, Response}, }; use enum_iterator::{all, Sequence}; -use std::{sync::Arc}; +use std::sync::Arc; +use tracing::level_filters::LevelFilter; +use tracing_subscriber::EnvFilter; use saleor_app_sdk::{config::Config, locales::LocaleCode, manifest::AppManifest, SaleorApp}; -use serde::{ - Serialize, -}; +use serde::Serialize; // Make our own error that wraps `anyhow::Error`. pub struct AppError(anyhow::Error); @@ -35,9 +35,20 @@ where } pub fn trace_to_std(config: &Config) { + let filter = EnvFilter::builder() + .with_default_directive(LevelFilter::DEBUG.into()) + .from_env() + .unwrap() + .add_directive( + format!("{}={}", env!("CARGO_PKG_NAME"), config.log_level) + .parse() + .unwrap(), + ); tracing_subscriber::fmt() .with_max_level(config.log_level) - .with_target(false) + .with_env_filter(filter) + .with_target(true) + .compact() .init(); } @@ -64,7 +75,7 @@ pub struct AppState { } pub fn get_active_gateways_from_env() -> anyhow::Result> { - dotenvy::dotenv()?; + _ = dotenvy::dotenv(); //eg: "accreditation,cod,other,transfer" let env_types = std::env::var("ACTIVE_GATEWAYS")?; let locale = std::env::var("LOCALE")?; diff --git a/simple-payment-gateway/src/main.rs b/simple-payment-gateway/src/main.rs index 2c9d2bb..a9cc458 100644 --- a/simple-payment-gateway/src/main.rs +++ b/simple-payment-gateway/src/main.rs @@ -19,8 +19,9 @@ use crate::{ app::{get_active_gateways_from_env, trace_to_std, AppState}, queries::event_transactions::{ sub_list_payment_gateways, sub_payment_gateway_initialize_session, - sub_transaction_charge_requested, sub_transaction_initialize_session, - sub_transaction_process_session, sub_transaction_refund_requested, + sub_transaction_cancelation_requested, sub_transaction_charge_requested, + sub_transaction_initialize_session, sub_transaction_process_session, + sub_transaction_refund_requested, }, routes::create_routes, }; @@ -63,6 +64,12 @@ async fn main() -> anyhow::Result<()> { .add_sync_event(SyncWebhookEventType::PaymentGatewayInitializeSession) .build(), ) + .add_webhook( + WebhookManifest::new(&config) + .set_query(sub_transaction_cancelation_requested) + .add_sync_event(SyncWebhookEventType::TransactionCancelationRequested) + .build(), + ) .add_webhook( WebhookManifest::new(&config) .set_query(sub_list_payment_gateways) diff --git a/simple-payment-gateway/src/routes/webhooks.rs b/simple-payment-gateway/src/routes/webhooks.rs index 897e3f6..d21d9c5 100644 --- a/simple-payment-gateway/src/routes/webhooks.rs +++ b/simple-payment-gateway/src/routes/webhooks.rs @@ -25,7 +25,7 @@ use crate::{ app::{ActiveGateway, AppError, AppState, GatewayType}, queries::{ event_transactions::{ - TransactionCancelationRequested, TransactionChargeRequested2, + TransactionCancelationRequested2, TransactionChargeRequested2, TransactionFlowStrategyEnum, TransactionInitializeSession2, TransactionProcessSession2, TransactionRefundRequested2, }, @@ -53,7 +53,7 @@ pub async fn webhooks( let res: Json = match event_type { EitherWebhookType::Sync(a) => match a { SyncWebhookEventType::TransactionCancelationRequested => { - let data = serde_json::from_str::(&body)?; + let data = serde_json::from_str::(&body)?; Json::from(serde_json::to_value( TransactionCancelationRequestedResponse { time: None, diff --git a/sitemap-generator/Cargo.toml b/sitemap-generator/Cargo.toml index 1bd2785..3a84e68 100644 --- a/sitemap-generator/Cargo.toml +++ b/sitemap-generator/Cargo.toml @@ -41,6 +41,7 @@ tinytemplate = "1.2.1" sitemap-rs = "0.2.1" chrono = { version = "0.4.34", features = ["serde"] } serde_cbor = "0.11.2" +pico-args = "0.5.0" [build-dependencies] cynic-codegen.workspace = true diff --git a/sitemap-generator/README.md b/sitemap-generator/README.md index 02a223d..be34f03 100644 --- a/sitemap-generator/README.md +++ b/sitemap-generator/README.md @@ -1,3 +1,10 @@ +# Using sitemap-generator + +To clear the cache, you can run the program with `./sitemap-generator --for-url https://my-saleor-api.com/graphql --cache-clear` or `docker compose --rm app-sitemap-generator sitemap-generator --for-url https://my-saleor-api.com/graphql --cache-clear` +To regenerate the cache, you can run the program with `./sitemap-generator --for-url https://my-saleor-api.com/graphql --cache-regenerate` or `docker compose --rm app-sitemap-generator sitemap-generator --for-url https://my-saleor-api.com/graphql --cache-regenerate` + +You can also add both flags (do --cache-regenerate first), which will clear and then regenerate. + # Unofficial Saleor App Template To update the saleor schema, you can download it from [here](https://raw.githubusercontent.com/saleor/saleor/main/saleor/graphql/schema.graphql) and put into schema/schema.graphql diff --git a/sitemap-generator/src/app.rs b/sitemap-generator/src/app.rs index b7bc120..4570be8 100644 --- a/sitemap-generator/src/app.rs +++ b/sitemap-generator/src/app.rs @@ -85,8 +85,7 @@ pub struct SitemapConfig { impl SitemapConfig { pub fn load() -> Result { - dotenvy::dotenv().unwrap(); - + _ = dotenvy::dotenv(); envy::from_env::() } } diff --git a/sitemap-generator/src/main.rs b/sitemap-generator/src/main.rs index e0b224d..3a053ce 100644 --- a/sitemap-generator/src/main.rs +++ b/sitemap-generator/src/main.rs @@ -18,7 +18,7 @@ use tracing::{debug, info}; use crate::{ app::{trace_to_std, AppState, SitemapConfig, XmlCache}, queries::event_subjects_updated::EVENTS_QUERY, - routes::create_routes, + routes::{create_routes, register::regenerate}, }; #[tokio::main] @@ -69,12 +69,23 @@ async fn main() -> anyhow::Result<()> { saleor_app: Arc::new(Mutex::new(saleor_app)), }; debug!("Created AppState..."); + { - let xml_cache = app_state.xml_cache.lock().await; - xml_cache - .delete_all("http://localhost:8000/graphpl/") - .await?; - debug!("Cleared Xml Cache"); + // either clear the cache, regenerate or both from command args + let mut pargs = pico_args::Arguments::from_env(); + + if let Some(for_url) = pargs.opt_value_from_str::<_, String>("--for-url")? { + if pargs.contains("--cache-clear") { + let xml_cache = app_state.xml_cache.lock().await; + xml_cache.delete_all(&for_url).await?; + debug!("Cleared Xml Cache for {for_url}"); + } + + if pargs.contains("--cache-regenerate") { + regenerate(app_state.clone(), for_url).await?; + } + std::process::exit(0) + } } let app = create_routes(app_state); diff --git a/sitemap-generator/src/routes/register.rs b/sitemap-generator/src/routes/register.rs index f8f3fb7..9db31e0 100644 --- a/sitemap-generator/src/routes/register.rs +++ b/sitemap-generator/src/routes/register.rs @@ -76,21 +76,21 @@ pub async fn register( pub async fn regenerate(state: AppState, saleor_api_url: String) -> anyhow::Result<()> { info!("regeneration: fetching all categories, products, collections, pages"); let xml_cache = state.xml_cache.lock().await; - let apl = state.saleor_app.lock().await; - let token = token.apl.get(&saleor_api_url).await?; + let app = state.saleor_app.lock().await; + let auth_data = app.apl.get(&saleor_api_url).await?; let mut categories: Vec<(Category3, Vec>)> = - get_all_categories(&saleor_api_url, token) + get_all_categories(&saleor_api_url, &auth_data.token) .await? .into_iter() .map(|c| (c, vec![])) .collect(); let mut products = vec![]; for category in categories.iter_mut() { - products.append(&mut get_all_products(&saleor_api_url, token, category).await?); + products.append(&mut get_all_products(&saleor_api_url, &auth_data.token, category).await?); } - let pages = get_all_pages(&saleor_api_url, token).await?; - let collections = get_all_collections(&saleor_api_url, token).await?; + let pages = get_all_pages(&saleor_api_url, &auth_data.token).await?; + let collections = get_all_collections(&saleor_api_url, &auth_data.token).await?; info!( "regeneration: found {} products, {} categories, {} pages, {} collections", products.len(),