Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .env
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE=cumulative
# Core Demo Services
# ******************
# Accounting Service
ACCOUNTING_SERVICE_PORT=7050
ACCOUNTING_ADDR=accounting:${ACCOUNTING_SERVICE_PORT}
ACCOUNTING_DOCKERFILE=./src/accounting/Dockerfile

# Ad Service
Expand Down Expand Up @@ -125,6 +127,10 @@ QUOTE_PORT=8090
QUOTE_ADDR=http://quote:${QUOTE_PORT}
QUOTE_DOCKERFILE=./src/quote/Dockerfile

# Order Expiry sidecar (psql DELETE on a loop; reuses ${POSTGRES_IMAGE})
ORDER_EXPIRY_INTERVAL_SECONDS=3600
ORDER_TTL_HOURS=48

# Recommendation Service
RECOMMENDATION_PORT=9001
RECOMMENDATION_ADDR=recommendation:${RECOMMENDATION_PORT}
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ the release.

## Unreleased

* [accounting][payment] Add `OrderService` for order lookup and a
refund flow on `payment`, with refund completion propagated to
`accounting` via a new `refunds` Kafka topic; lays the groundwork
for an order-management UX.
* [frontend] fix: handle corrupted session data in localStorage
([#3313](https://github.com/open-telemetry/opentelemetry-demo/pull/3313))
* [docker] Podman doesn't support the tag feature of docker logs,
Expand Down
47 changes: 47 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,19 +30,57 @@ services:
limits:
memory: 160M
restart: unless-stopped
ports:
- "${ACCOUNTING_SERVICE_PORT}"
environment:
- ACCOUNTING_SERVICE_PORT
- KAFKA_ADDR
- OTEL_EXPORTER_OTLP_ENDPOINT=http://${OTEL_COLLECTOR_HOST}:${OTEL_COLLECTOR_PORT_HTTP}
- OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE
- OTEL_RESOURCE_ATTRIBUTES=${OTEL_RESOURCE_ATTRIBUTES},service.criticality=low
- OTEL_SERVICE_NAME=accounting
- DB_CONNECTION_STRING=Host=${POSTGRES_HOST};Username=astronomy_user;Password=${POSTGRES_ASTRONOMY_PASSWORD};Database=astronomy_db
- OTEL_DOTNET_AUTO_TRACES_ENTITYFRAMEWORKCORE_INSTRUMENTATION_ENABLED=false
- ASPNETCORE_URLS=http://*:${ACCOUNTING_SERVICE_PORT}
depends_on:
otel-collector:
condition: service_started
kafka:
condition: service_healthy
astronomy-db:
condition: service_started
logging: *logging

# Order Expiry sidecar — periodically deletes orders older than ORDER_TTL_HOURS.
# Reuses ${POSTGRES_IMAGE} (already pulled for astronomy-db) so there is no
# extra image to build or publish. The Helm chart mirrors this with a CronJob
# running the same psql one-liner.
order-expiry:
image: ${POSTGRES_IMAGE}
container_name: order-expiry
deploy:
resources:
limits:
memory: 40M
restart: unless-stopped
environment:
- PGHOST=${POSTGRES_HOST}
- PGUSER=astronomy_user
- PGPASSWORD=${POSTGRES_ASTRONOMY_PASSWORD}
- PGDATABASE=astronomy_db
- ORDER_EXPIRY_INTERVAL_SECONDS
- ORDER_TTL_HOURS
command:
- sh
- -c
- |
while true; do
psql -c "DELETE FROM accounting.\"order\" WHERE created_at < NOW() - make_interval(hours => $$ORDER_TTL_HOURS)" || true
sleep "$$ORDER_EXPIRY_INTERVAL_SECONDS"
done
depends_on:
astronomy-db:
condition: service_started
logging: *logging

# AdService
Expand Down Expand Up @@ -289,6 +327,8 @@ services:
- PRODUCT_REVIEWS_ADDR
- RECOMMENDATION_ADDR
- SHIPPING_ADDR
- ACCOUNTING_ADDR
- PAYMENT_ADDR
- OTEL_EXPORTER_OTLP_ENDPOINT
- OTEL_RESOURCE_ATTRIBUTES=${OTEL_RESOURCE_ATTRIBUTES},service.criticality=critical
- ENV_PLATFORM
Expand Down Expand Up @@ -316,6 +356,10 @@ services:
condition: service_started
shipping:
condition: service_started
accounting:
condition: service_started
payment:
condition: service_started
otel-collector:
condition: service_started
image-provider:
Expand Down Expand Up @@ -468,6 +512,7 @@ services:
- PAYMENT_PORT
- FLAGD_HOST
- FLAGD_PORT
- KAFKA_ADDR
- OTEL_EXPORTER_OTLP_ENDPOINT
- OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE
- OTEL_RESOURCE_ATTRIBUTES=${OTEL_RESOURCE_ATTRIBUTES},service.criticality=critical
Expand All @@ -477,6 +522,8 @@ services:
condition: service_started
flagd:
condition: service_started
kafka:
condition: service_healthy
logging: *logging

# Product Catalog service
Expand Down
59 changes: 59 additions & 0 deletions pb/demo.proto
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ message CurrencyConversionRequest {

service PaymentService {
rpc Charge(ChargeRequest) returns (ChargeResponse) {}
rpc Refund(RefundRequest) returns (RefundResponse) {}
}

message CreditCardInfo {
Expand All @@ -233,6 +234,28 @@ message ChargeResponse {
string transaction_id = 1;
}

message RefundRequest {
string order_id = 1;
string transaction_id = 2;
Money amount = 3;
string email = 4;
}

message RefundResponse {
string refund_transaction_id = 1;
bool success = 2;
}

// Published to the "refunds" Kafka topic by the payment service after a
// successful refund, so the accounting consumer can mark the order refunded.
message RefundResult {
string order_id = 1;
string transaction_id = 2;
string refund_transaction_id = 3;
Money amount = 4;
string email = 5;
}

// -------------Email service-----------------

service EmailService {
Expand All @@ -250,6 +273,10 @@ message OrderResult {
Money shipping_cost = 3;
Address shipping_address = 4;
repeated OrderItem items = 5;
string user_id = 6;
string email = 7;
string transaction_id = 8;
Money total_cost = 9;
}

message SendOrderConfirmationRequest {
Expand Down Expand Up @@ -277,6 +304,38 @@ message PlaceOrderResponse {
OrderResult order = 1;
}

// -------------Order service-----------------

service OrderService {
rpc GetOrdersByEmail(GetOrdersByEmailRequest) returns (GetOrdersByEmailResponse) {}
rpc GetOrder(GetOrderRequest) returns (OrderDetail) {}
}

message GetOrdersByEmailRequest {
string email = 1;
}

message GetOrdersByEmailResponse {
repeated OrderDetail orders = 1;
}

message GetOrderRequest {
string order_id = 1;
}

message OrderDetail {
string order_id = 1;
string email = 2;
string status = 3;
Money total_cost = 4;
string shipping_tracking_id = 5;
Address shipping_address = 6;
repeated OrderItem items = 7;
string created_at = 8;
string transaction_id = 9;
string refund_transaction_id = 10;
}

// ------------Ad service------------------

service AdService {
Expand Down
7 changes: 3 additions & 4 deletions src/accounting/Accounting.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
Expand All @@ -12,6 +11,7 @@
<PackageReference Include="Confluent.Kafka" Version="2.14.0" />
<PackageReference Include="EFCore.NamingConventions" Version="10.0.1" />
<PackageReference Include="Google.Protobuf" Version="3.34.1" />
<PackageReference Include="Grpc.AspNetCore" Version="2.76.0" />
<PackageReference Include="Grpc.Tools" Version="2.68.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
Expand All @@ -23,8 +23,7 @@
</ItemGroup>

<ItemGroup>
<!-- GrpcServices is 'none' so that we do not need to depend on the grpc nuget package, and we only need protobuf support. -->
<Protobuf Include="src\protos\demo.proto" GrpcServices="none" />
<Protobuf Include="src\protos\demo.proto" GrpcServices="Both" />
</ItemGroup>

<ItemGroup>
Expand Down
Loading
Loading