Skip to content
Merged
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
12 changes: 12 additions & 0 deletions designer/application-customizations.conf
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,18 @@
scenarioTypes {
"streaming" {
# customize Flink streaming scenario type

modelConfig: {
components {
"customerProfileOffers" {
providerType: "openAPI"
url: "http://mocks:8080/__admin/files/openapi/CustomerApi.yaml"
rootUrl: "http://mocks:8080/"
namePattern: "get.*"
allowedMethods: ["GET"]
}
}
}
}
"streaming-lite-embedded" {
# customize Lite streaming scenario type
Expand Down
15 changes: 15 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,19 @@ services:
limits:
memory: 128M

### Quickstart mocks
mocks:
build:
context: mocks/
dockerfile: Dockerfile
# todo added temporary
ports:
- 18080:8080
deploy:
resources:
limits:
memory: 256M

### Nussknacker-related services

nginx:
Expand Down Expand Up @@ -71,6 +84,8 @@ services:
condition: service_healthy
flink-taskmanager:
condition: service_started
mocks:
condition: service_healthy
expose:
- 8181
healthcheck:
Expand Down
30 changes: 30 additions & 0 deletions mocks/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
FROM holomekc/wiremock-gui:3.8.1 AS wiremock

RUN apt-get update && \
apt-get install -y wget && \
wget -P /var/wiremock/extensions https://repo1.maven.org/maven2/org/wiremock/extensions/wiremock-faker-extension-standalone/0.2.0/wiremock-faker-extension-standalone-0.2.0.jar

FROM phusion/baseimage:noble-1.0.0

# Use baseimage-docker's init system.
CMD ["/sbin/my_init"]

# install
USER root

RUN apt-get update -y && \
apt -y install openjdk-11-jre-headless && \
apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

# WIREMOCK
COPY --from=wiremock /var/wiremock /var/wiremock
COPY --from=wiremock /home/wiremock /home/wiremock

COPY http-service/mocks /home/wiremock/
COPY http-service/scripts /etc/service/http-service
RUN mv /etc/service/http-service/run-wiremock.sh /etc/service/http-service/run

EXPOSE 8080

HEALTHCHECK --interval=30s --timeout=10s --start-period=30s --retries=30 \
CMD (curl -f http://localhost:8080/__admin/) || exit 1
6 changes: 6 additions & 0 deletions mocks/Readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# MOCKS
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we could add information that OpenApi mappings can be modified in gui with address: http://localhost:18080/__admin/webapp/? Or we should not provide gui to the user?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe it can be useful for testing purposes but it won't be useful in runtime. I will write example dev docs in the next task, so I will write about it there (at the moment I've added the Readme file to not forget about these links)


## Resources:
https://github.com/wiremock/wiremock-faker-extension/blob/main/docs/reference.md
https://docs.wiremock.io/response-templating/basics/
https://docs.wiremock.io/response-templating/dates-and-times/
Empty file.
106 changes: 106 additions & 0 deletions mocks/http-service/mocks/__files/openapi/CustomerApi.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
openapi: 3.0.0
info:
title: Customer API
version: 1.0.0
description: API for retrieving customer profiles and offers based on customer type.

paths:
'/customer/{customerId}/profile':
get:
summary: Get customer profile by customer's ID
description: Retrieve detailed profile information for a customer using their unique customer ID.
operationId: getCustomerProfile
parameters:
- name: customerId
in: path
required: true
description: The unique identifier of the customer.
schema:
type: string
responses:
'200':
description: Customer profile found successfully.
content:
application/json:
schema:
$ref: '#/components/schemas/CustomerProfile'
'404':
description: No customer profile found for the given ID.

'/customer/{customerType}/offers':
get:
summary: Get offers by customer type
description: Retrieve offers available for a specific type of customer.
operationId: getOffersForCustomerType
parameters:
- name: customerType
in: path
required: true
description: The type/category of the customer.
schema:
type: string
responses:
'200':
description: Offers found for the specified customer type.
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/CustomerTypeOffer'
'404':
description: No offer found for the specified customer type.

components:
schemas:
CustomerProfile:
title: CustomerProfile
type: object
description: Schema representing a customer's profile information.
properties:
id:
type: string
description: The unique identifier of the customer profile.
customerId:
type: string
description: The identifier of customer
customerType:
type: string
description: The type or category of the customer.
customerName:
type: string
description: The customer's name
customerMsisdn:
type: string
description: The customer's phone number
customerAge:
type: integer
description: The customer's age
customerSex:
type: string
description: The customer's sex
isPremiumCustomer:
type: boolean
description: Indicates if the customer is a premium one

CustomerTypeOffer:
title: CustomerTypeOffer
type: object
description: Schema representing an offer available for a specific type of customer.
properties:
id:
type: string
description: The unique identifier of the offer.
name:
type: string
description: The name or title of the offer.
message:
type: string
description: A human-readable offer description
price:
type: integer
description: Price of the offer
validity:
type: string
format: date-time
description: The validity date of the offer.
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"id": "{{randomValue length=10 type='NUMERIC'}}",
"customerId": "{{request.path.[1]}}",
"customerType": "{{{pickRandom 'Freemium' 'Regular' 'VIP'}}}",
"customerName": "{{random 'Name.fullName'}}",
"customerMsisdn": "{{random 'PhoneNumber.phoneNumber'}}",
"customerAge": {{randomInt lower=10 upper=99}},
"customerSex": "{{{pickRandom 'Male' 'Female' 'N/A'}}}",
"isPremiumCustomer": {{random 'Bool.bool'}}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[]
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[
{
"id": "{{randomValue length=10 type='NUMERIC'}}",
"name": "{{random 'Commerce.productName'}} promotion",
"message": "{{random 'Lorem.sentence'}} {{random 'Lorem.sentence'}} {{random 'Lorem.sentence'}}",
"price": {{randomInt lower=10 upper=50}},
"validity": "{{dateFormat (now offset='3 days') format='yyyy-MM-dd\'T\'HH:mm:ss\'Z\''}}"
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[
{
"id": "{{randomValue length=10 type='NUMERIC'}}",
"name": "{{random 'Commerce.productName'}} promotion",
"message": "{{random 'Lorem.sentence'}} {{random 'Lorem.sentence'}} {{random 'Lorem.sentence'}}",
"price": {{randomInt lower=10 upper=50}},
"validity": "{{dateFormat (now offset='3 days') format='yyyy-MM-dd\'T\'HH:mm:ss\'Z\''}}"
},
{
"id": "{{randomValue length=10 type='NUMERIC'}}",
"name": "{{random 'Commerce.productName'}} promotion",
"message": "{{random 'Lorem.sentence'}} {{random 'Lorem.sentence'}} {{random 'Lorem.sentence'}}",
"price": {{randomInt lower=10 upper=50}},
"validity": "{{dateFormat (now offset='3 days') format='yyyy-MM-dd\'T\'HH:mm:ss\'Z\''}}"
}
]
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"request": {
"urlPattern": "/customer/(.+)/profile",
"method": "GET"
},
"response": {
"status": 200,
"headers": {
"Content-Type": "application/json"
},
"bodyFileName": "responses/customer-api/CustomerProfile.json"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"mappings": [
{
"request": {
"urlPattern": "/customer/(.+)/offers",
"method": "GET"
},
"response": {
"status": 404
}
},
{
"request": {
"urlPattern": "/customer/(?i)(Freemium|Regular|VIP)/offers",
"method": "GET"
},
"response": {
"status": 200,
"headers": {
"Content-Type": "application/json"
},
"bodyFileName": "responses/customer-api/CustomerTypeOffers{{{pickRandom '0' '1' '2'}}}.json"
}
}
]
}
10 changes: 10 additions & 0 deletions mocks/http-service/scripts/run-wiremock.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/bin/sh -e

java $JAVA_OPTS -cp /var/wiremock/lib/*:/var/wiremock/extensions/* wiremock.Run \
--port=8080 \
--root-dir=/home/wiremock \
--max-request-journal=1000 \
--global-response-templating \
--extensions=org.wiremock.RandomExtension \
--async-response-enable=true \
--async-response-threads=30
10 changes: 10 additions & 0 deletions quickstart-setup/data/kafka/generate-messages/customerEvents.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/bin/bash -e

cd "$(dirname "$0")"

source ../../../scripts/utils/lib.sh

ID=$(random_Ndigit_number 10)
EVENT_TYPE="$(pick_randomly "ClientCloseToShowroom" "ClientBrowseOffers" "ClientEndedCallWithCustomerService" "ClientSentTerminationLetter" "Other")"

echo "{ \"customerId\": \"$ID\", \"eventType\": \"$EVENT_TYPE\" }"
1 change: 1 addition & 0 deletions quickstart-setup/data/kafka/topics.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
# Topic name the static and generated messages should be sent to
Transactions
CustomerEvents
32 changes: 26 additions & 6 deletions quickstart-setup/scripts/utils/lib.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,41 @@ function verifyBashScript() {
fi
}

function random_Ndigit_number() {
if [ "$#" -ne 1 ]; then
echo "Error: One parameter required: 1) number of digits"
exit 1
fi

local LENGTH=$1
local RESULT=""

local FIRST_DIGIT=$((RANDOM % 9 + 1))
RESULT+="$FIRST_DIGIT"

while [ ${#RESULT} -lt $LENGTH ]; do
local REMAINING=$((LENGTH - ${#RESULT}))
local PART=$(printf "%05d" $((RANDOM % 100000)))
RESULT+=${PART:0:$REMAINING}
done
echo "$RESULT"
}

function random_4digit_number() {
od -An -t d -N 2 /dev/urandom | head -n 1 | tr -d ' ' | head -c 4
random_Ndigit_number 4
}

function random_3digit_number() {
random_4digit_number | head -c 3
random_Ndigit_number 3
}

function now() {
echo "$(date +%s)$(random_3digit_number)"
}

function pick_randomly() {
local options=("$@")
local count=${#options[@]}
local random_index=$((RANDOM % count))
echo "${options[$random_index]}"
local OPTIONS=("$@")
local COUNT=${#OPTIONS[@]}
local RANDOM_INDEX=$((RANDOM % COUNT))
echo "${OPTIONS[$RANDOM_INDEX]}"
}
2 changes: 2 additions & 0 deletions quickstart-setup/setup/kafka/topics.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@ Customers
ProcessedTransactions
SmsesWithOffer
Transactions
CustomerEvents
OfferProposalsBasedOnCustomerEvents
1 change: 1 addition & 0 deletions quickstart-setup/setup/nu/examples.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
DetectLargeTransactions.json
#DetermineOfferedPlan.json
LoanRequest.json
OfferCustomerProposalBasedOnActivityEvent.json
Loading