Static Rule Processing via Predefined and Database Based Rules¶
In this guide, we are going to explore how to process static rules stored in a database and make a decision according to those stored rules.
Scenario - Static Rule Processing¶
After completing this scenario, you will be able to implement a system capable of making decisions according to a set of static rules. The static rules will be stored in a relational database(MySQL). You can dynamically change the rules in the database according to your business requirements without touching the deployed system. All the dynamic values need for each rule can be templated and pump into the rule at runtime.
What You'll Build¶
The implementation of this use case explains using the functional requirements of the Combo supermart. Combo supermart is a supermarket that resides in our town. This Combo supermarket gives a loyalty card for their frequent customers. Each loyalty card has a type. These card types are Platinum, Gold, and Silver, etc. In each season management of the combo supermart planning to give discounts for each loyalty card. The percentage of the discount will change according to the type of loyalty card. Moreover, each loyalty card will select to have these discounts if that loyalty card fulfills several requirements. Those requirements are stored in a database as rules. These rules can be changed from time to time. Since combo supermart has to handle thousands of customer transaction per day in this season they cannot calculate these discounts in a manual process. Hence they planning to build an automatic system to calculate these discounts.
As shown in the following diagram the business process has to execute using six steps.
- A user sends an HTTP request with a JSON payload that contained an ID of a promo card and the amount of the transaction.
- That JSON payload will consume by the HTTP service. Then parse the mapped values to the processing logic of the Siddhi query.
- Initially, processing logic inputs the promo card ID to the MySQL database.
- And retrieves all the rules relevant to the given promo card type.
- After that process these rules and send output to the HTTP service response.
- The HTTP service response will send back another JSON payload which indicating, whether this user allowed to have a discount or not. If this user allowed to have a discount then what is the percentage of the discount.
Prerequisites¶
Mandatory Requirements¶
- Siddhi tooling VM/Local distribution
- One of the Siddhi runner distributions
- VM/Local Runtime
- Docker Image
- K8S Operator (commands are given in Kubernetes deployment section)
- MySQL database
- Java 8 or higher
Requirements needed to deploy Siddhi in Docker/Kubernetes¶
- Docker
- Kubernetes cluster
- Refer to this documentation about Configuring a Google Kubernetes Engine (GKE) Cluster to deploy Siddhi apps in GKE.
Implementation¶
First of all, we assume that the Combo supermart has a MySQL database that contained the all promo card and user details. The following ER diagram describes the schema of the database.
Now, you have to start the Siddhi tooling editor before implementing the Siddhi app. Siddhi tooling editor is an IDE that supports to implement Siddhi apps.
- First, you can download the Siddhi tooling pack as a zip file from here and extract it.
-
After creating the above database we need to have a mechanism to connect this database to Siddhi runtime. To do that you have to update the Siddhi tooling configuration file. Siddhi tooling configuration file is
<TOOLING_HOME>/conf/tooling/deployment.yaml
. You have to add the following YAML block under the dataSources entry in the deployment.yaml. The following YAML block contained all the details that need to connect to the database. For example, database username, password, and URL, etc.- name: COMBO_SUPERMART_DB description: The datasource used for lending process of the Combo supermarket jndiConfig: name: jdbc/ComboSuperMart definition: type: RDBMS configuration: jdbcUrl: 'jdbc:mysql://127.0.0.1:3306/ComboSuperMart' username: siddhi_user password: siddhiio driverClassName: com.mysql.jdbc.Driver maxPoolSize: 10 idleTimeout: 60000 connectionTestQuery: SELECT 1 validationTimeout: 30000 isAutoCommit: false
-
In order to connect to a MySQL server Siddhi tooling needs the MySQL connector JAR. You can download the MySQL connector JAR from here and copy that JAR into
<TOOLING_HOME>/jars
directory. - Start the following binary file. Using this link http://localhost:9390/editor now you can access the Siddhi tooling editor from your web browser.
- For Linux/Mac:
<TOOLING_HOME>/bin/tooling.sh
- For Windows:
<TOOLING_HOME>/bin/tooling.bat
- For Linux/Mac:
- Select
File -> New
option, then you could either use the source view or design view to write/build the Siddhi Application. You can find the Siddhi Application bellow, that implements the requirements mentioned above.
Siddhi Query Guide
The execution steps and the logic of the Siddhi query described as comments in the following Siddhi app. Therefore here we are not going to explain in detail here. For more details about Siddhi queries please refer Siddhi query guide.
@App:name("ComboSuperMartPromoProcess")
@App:description("The promotion selection process of Combo super mart.")
/*
Purpose:
The combo supermart has multiple promotion cards that given to their loyal users. For a particular season combo supermart plan to give discounts for each card. These discounts will change according to the card type and several rules. So, the combo supermart needed an automatic system to retrieve the discounts for a given card. To do that we implement this Siddhi app which interacts with a MySQL database and executes their functionalities. All card details and rules were stored in a MySQL database. All the rules for a particular card were in the templated format. Therefore all rules executed dynamically and give the final result.
Input:
HTTP POST with JSON payload {
"event": {
"promoCardId": "PC001",
"amount": 20000
}
}
Output:
{
"event": {
"messageId": "1817d06b-22ae-438e-990d-42fedcb50607",
"discountAmount": 15.0,
"discountApplied": true
}
}
*/
-- HTTP source
@source(
type='http-service',
source.id='adder',
receiver.url='http://0.0.0.0:8088/comboSuperMart/promo',
basic.auth.enabled='',
@map(type='json', @attributes(messageId='trp:messageId', promoCardId='$.event.promoCardId', amount='$.event.amount'))
)
define stream InputTransactionStream(messageId string, promoCardId string, amount long);
-- RDBMS data stores
@Store(type="rdbms", datasource="COMBO_SUPERMART_DB")
define table Customer(customerId string, promoCardId string);
@Store(type="rdbms", datasource="COMBO_SUPERMART_DB")
define table PromoCard(promoCardId string, promoCardTypeId string, promoCardIssueDate string);
@Store(type="rdbms", datasource="COMBO_SUPERMART_DB")
define table PromoRule(promoRuleId string, promoCardTypeId string, promoRule string);
@Store(type="rdbms", datasource="COMBO_SUPERMART_DB")
define table PromoCardType(promoCardTypeId string, promoCardTypeDiscount double);
-- Output stream
@sink(type='http-service-response', source.id='adder',
message.id='{{messageId}}', @map(type = 'json'))
define stream ResultStream (messageId string, discountAmount double, discountApplied bool);
-- Find and execute rules
@info(name='get-promocard-type')
from InputTransactionStream#window.length(1) join PromoCard on InputTransactionStream.promoCardId==PromoCard.promoCardId
select InputTransactionStream.messageId, InputTransactionStream.promoCardId, PromoCard.promoCardTypeId, PromoCard.promoCardIssueDate, InputTransactionStream.amount
insert into GetPromoCardTypeStream;
@info(name='get-promocard-type-details')
from GetPromoCardTypeStream#window.length(1) join PromoCardType on GetPromoCardTypeStream.promoCardTypeId==PromoCardType.promoCardTypeId
select GetPromoCardTypeStream.messageId, GetPromoCardTypeStream.promoCardId, GetPromoCardTypeStream.promoCardTypeId, GetPromoCardTypeStream.amount, PromoCardType.promoCardTypeDiscount, GetPromoCardTypeStream.promoCardIssueDate
insert into GetPromoCardTypeDetailsStream;
@info(name='get-promocard-rules')
from GetPromoCardTypeDetailsStream#window.length(1) left outer join PromoRule on GetPromoCardTypeDetailsStream.promoCardTypeId==PromoRule.promoCardTypeId
select GetPromoCardTypeDetailsStream.messageId, GetPromoCardTypeDetailsStream.promoCardId, GetPromoCardTypeDetailsStream.promoCardTypeId, GetPromoCardTypeDetailsStream.amount, GetPromoCardTypeDetailsStream.promoCardTypeDiscount, PromoRule.promoRuleId, PromoRule.promoRule, GetPromoCardTypeDetailsStream.promoCardIssueDate
insert into RuleStream;
@info(name='execute-promocard-rules')
from RuleStream#window.length(1)
select RuleStream.messageId, RuleStream.promoCardTypeDiscount, js:eval(str:fillTemplate(RuleStream.promoRule, map:create("amount", RuleStream.amount, "cardPeriod", time:dateDiff(time:currentDate(), RuleStream.promoCardIssueDate, 'yyyy-MM-dd', 'yyyy-MM-dd'))), 'bool') as result
insert into RuleReslutsStream;
-- Output results
@info(name='filter-true-rules')
from RuleReslutsStream[result == true]#window.batch()
select RuleReslutsStream.messageId, RuleReslutsStream.promoCardTypeDiscount, count(result) as result
insert into TrueResultStream;
@info(name='get-all-results')
from RuleReslutsStream#window.batch()
select RuleReslutsStream.messageId, RuleReslutsStream.promoCardTypeDiscount, count(result) as result
insert into AllResultStream;
@info(name='discout-reply-stream')
from AllResultStream#window.length(1) unidirectional join TrueResultStream#window.length(1) on TrueResultStream.result==AllResultStream.result
select AllResultStream.messageId, AllResultStream.promoCardTypeDiscount as discountAmount, true as discountApplied
insert into ResultStream;
@info(name='filter-true-rules-and-reply')
from RuleReslutsStream[result == false]#window.batch()
select RuleReslutsStream.messageId, 0.00 as discountAmount, false as discountApplied
insert into ResultStream;
The following flow diagram depicts the design view of the above Siddhi app.
Testing¶
Let’s run and test the above Siddhi app in your local machine. If you completed the implementation process correctly you will be able to start your Siddhi application without any error.
Before you run the application your database should have sample data to be processed. The following images show the sample data tables that we are using for this guide.
Customer Table¶
Promo Card Table¶
Promo Card Rule Table¶
Promo Card Type Table¶
To connect to the database Siddhi app will use a user called siddhi_user
identified by password siddhiio
. To access the database you have to give correct permissions to the user. For testing purposes, you can grant all privileges to this user using the following command.
> GRANT ALL PRIVILEGES ON ComboSuperMart.* TO 'siddhi_user'@'siddhiio';
To create those tables, you can use the following SQL script.
CREATE DATABASE IF NOT EXISTS `ComboSuperMart` /*!40100 DEFAULT CHARACTER SET utf8 */;
USE `ComboSuperMart`;
--
-- Table structure for table `PromoCardType`
--
DROP TABLE IF EXISTS `PromoCardType`;
CREATE TABLE `PromoCardType` (
`promoCardTypeId` varchar(45) NOT NULL,
`promoCardType` varchar(45) NOT NULL,
`promoCardTypeDiscount` decimal(5,2) DEFAULT NULL,
PRIMARY KEY (`promoCardTypeId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Dumping data for table `PromoCardType`
--
LOCK TABLES `PromoCardType` WRITE;
INSERT INTO `PromoCardType` VALUES ('PCT01','PLATINUM',15.00),('PCT02','GOLD',10.00),('PCT03','SILVER',5.00);
UNLOCK TABLES;
--
-- Table structure for table `PromoCard`
--
DROP TABLE IF EXISTS `PromoCard`;
CREATE TABLE `PromoCard` (
`promoCardId` varchar(40) NOT NULL,
`promoCardIssueDate` date NOT NULL,
`promoCardTypeId` varchar(45) NOT NULL,
PRIMARY KEY (`promoCardId`),
KEY `promoCardTypeIdKF_idx` (`promoCardTypeId`),
CONSTRAINT `promoCardIdTypeFK` FOREIGN KEY (`promoCardTypeId`) REFERENCES `PromoCardType` (`promoCardTypeId`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Dumping data for table `PromoCard`
--
LOCK TABLES `PromoCard` WRITE;
INSERT INTO `PromoCard` VALUES ('PC001','2018-04-03','PCT01'),('PC002','2017-04-30','PCT02'),('PC003','2017-08-09','PCT03'),('PC004','2018-03-06','PCT01');
UNLOCK TABLES;
--
-- Table structure for table `Customer`
--
DROP TABLE IF EXISTS `Customer`;
CREATE TABLE `Customer` (
`customerId` varchar(45) NOT NULL,
`cutomerName` varchar(60) NOT NULL,
`promoCardId` varchar(40) NOT NULL,
PRIMARY KEY (`customerId`),
KEY `promoCardIdFK_idx` (`promoCardId`),
CONSTRAINT `promoCardIdFK` FOREIGN KEY (`promoCardId`) REFERENCES `PromoCard` (`promoCardId`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Dumping data for table `Customer`
--
LOCK TABLES `Customer` WRITE;
INSERT INTO `Customer` VALUES ('C001','John Doy','PC001'),('C002','Micheal Dawson','PC002'),('C003','Neil Clain','PC003'),('C004','Anne Cath','PC004');
UNLOCK TABLES;
--
-- Table structure for table `PromoRule`
--
DROP TABLE IF EXISTS `PromoRule`;
CREATE TABLE `PromoRule` (
`promoRuleId` varchar(40) NOT NULL,
`promoCardTypeId` varchar(45) NOT NULL,
`promoRule` varchar(200) NOT NULL,
PRIMARY KEY (`promoRuleId`),
KEY `cardId_idx` (`promoCardTypeId`),
CONSTRAINT `promoCardTypeIdFK` FOREIGN KEY (`promoCardTypeId`) REFERENCES `PromoCardType` (`promoCardTypeId`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- Dumping data for table `PromoRule`
--
LOCK TABLES `PromoRule` WRITE;
INSERT INTO `PromoRule` VALUES ('RULE001','PCT01','{{amount}} > 10000 && {{amount}} < 50000'),('RULE002','PCT01','{{cardPeriod}} > 200');
UNLOCK TABLES;
The above Siddhi app will start an HTTP service in 8088 port. Therefore, you can send a request to that service using the following CURL command.
curl -X POST \
http://0.0.0.0:8088/comboSuperMart/promo \
-H 'Accept: */*' \
-H 'Content-Type: application/json' \
-H 'Host: 0.0.0.0:8088' \
-d '{
"event": {
"promoCardId": "PC001",
"amount": 10000
}
}'
This request will response back the following JSON.
{
"event": {
"messageId": "8f38faea-9dbd-4387-b807-b9f170db20dd",
"discountAmount": 0.0,
"discountApplied": false
}
}
Deployment¶
Deploy on VM/ Bare Metal¶
- First you have to setup MySQL as described earlier. Refer this link to setup MySQL.
- Download the latest Siddhi Runner distribution and unzip it.
-
Add following YAML block to the
<RUNNER_HOME>/conf/runner/deployment.yaml
.- name: COMBO_SUPERMART_DB description: The datasource used for lending process of the Combo supermarket jndiConfig: name: jdbc/ComboSuperMart definition: type: RDBMS configuration: jdbcUrl: 'jdbc:mysql://127.0.0.1:3306/ComboSuperMart' username: siddhi_user password: siddhiio driverClassName: com.mysql.jdbc.Driver maxPoolSize: 10 idleTimeout: 60000 connectionTestQuery: SELECT 1 validationTimeout: 30000 isAutoCommit: false
-
Download the MySQL connector JAR from here and copy that JAR into
<RUNNER_HOME>/jars
directory. - Copy your Siddhi file into
<RUNNER_HOME>/wso2/runner/deployment/siddhi-files
- Start the following binary file. Using this link http://localhost:9390/editor now you can access the Siddhi tooling editor from your web browser.
- For Linux/Mac:
<RUNNER_HOME>/bin/runner.sh
- For Windows:
<RUNNER_HOME>/bin/runner.bat
- For Linux/Mac:
Execute the following CURL command.
curl -X POST \
http://0.0.0.0:8088/comboSuperMart/promo \
-H 'Accept: */*' \
-H 'Content-Type: application/json' \
-H 'Host: 0.0.0.0:8088' \
-d '{
"event": {
"promoCardId": "PC001",
"amount": 10000
}
}'
It will results the following JSON.
{
"event": {
"messageId": "8f38faea-9dbd-4387-b807-b9f170db20dd",
"discountAmount": 0.0,
"discountApplied": false
}
}
Deploy on Docker¶
Prerequisite¶
Install Docker into your machine.
Siddhi Docker Configurations¶
In the tooling editor itself, you can export your Siddhi app into a runnable docker artifact. You can go to Export->For Docker
and it will give to a zip file.
Database URL for Docker
When you changing the deployment.yaml
configuration of the data source in the Docker export process, you have to specify this URL in the configuration as below.
- name: COMBO_SUPERMART_DB
description: The datasource used for lending process of the Combo supermarket
jndiConfig:
name: jdbc/ComboSuperMart
definition:
type: RDBMS
configuration:
jdbcUrl: jdbc:mysql://mysqldb:3306/ComboSuperMart
username: siddhi_user
password: siddhiio
driverClassName: com.mysql.jdbc.Driver
maxPoolSize: 10
idleTimeout: 60000
connectionTestQuery: SELECT 1
validationTimeout: 30000
isAutoCommit: false
The extracted zip file will be looks like follows.
├── Dockerfile
├── configurations.yaml
├── jars
│ └── mysql-connector.jar
└── siddhi-files
└── ComboSuperMartPromoProcess.siddhi
You also need to set up a MySQL docker container and connect it into the Siddhi docker runtime. You can do it very easily from writing a docker composer file like below. Now you need to have a Docker compose file like below to set up all the prerequisites. This compose file contains volume mounts to change configurations of the MySQL container.
version: "3"
services:
backend:
container_name: combosupermart-promo
user: 802:802
build:
context: .
dockerfile: ./Dockerfile
ports:
- "8088:8088"
links:
- mysqldb
networks:
- default
restart: on-failure
mysqldb:
image: 'mysql:5.7'
container_name: combosupermart-db
environment:
MYSQL_USER: siddhi_user
MYSQL_PASSWORD: siddhiio
MYSQL_ROOT_PASSWORD: siddhiio
ports:
- "3304:3306"
networks:
- default
restart: on-failure
Save this file as docker-compose.yaml
to the root directory of the extracted zip file. And the extracted zip file directory now looks like below:
├── Dockerfile
├── configurations.yaml
├── docker-compose.yaml
├── jars
│ └── mysql-connector.jar
└── siddhi-files
└── ComboSuperMartPromoProcess.siddhi
Now, you have to build the docker composer.
$ docker-compose build
Now you have to start the MySQL container. And then set up your MySQL database as described above.
$ docker-compose up -d mysqldb
Now you can connect to the MySQL server using the following configurations.
- Host: 0.0.0.0
- Port: 3304
- Root user: root
- Root password: siddhiio
- Custom user: siddhi_user
- Custom user password: siddhiio
Then you can create the database schema in that MySQL container. After that, you can start the Siddhi runtime using the following command.
$ docker-compose up -d backend
To check the deployments up and running, send the following CURL request.
curl -X POST \
http://0.0.0.0:8088/comboSuperMart/promo \
-H 'Accept: */*' \
-H 'Content-Type: application/json' \
-H 'Host: 0.0.0.0:8088' \
-d '{
"event": {
"promoCardId": "PC001",
"amount": 20000
}
}'
It will results the following JSON.
{
"event": {
"messageId": "285703c1-866a-4a88-8e1f-e75543e18373",
"discountAmount": 15.0,
"discountApplied": true
}
}
Deploy on Kubernetes¶
Prerequisites¶
- Kubernetes cluster
- Install HELM
Siddhi Kubernetes Configurations¶
In the tooling editor itself, you can export your Siddhi app into a runnable Kubernetes artifact. You can go to Export->For Kubernetes
and it will give to a zip file that contained the following files.
├── Dockerfile
├── configurations.yaml
├── jars
│ └── mysql-connector.jar
├── siddhi-files
│ └── ComboSuperMartPromoProcess.siddhi.siddhi
└── siddhi-process.yaml
First, you need to install the Siddhi Kubernetes operator using following commands. For more details about the Siddhi operator refer to this documentation.
$ kubectl apply -f https://github.com/siddhi-io/siddhi-operator/releases/download/v0.2.0/00-prereqs.yaml
$ kubectl apply -f https://github.com/siddhi-io/siddhi-operator/releases/download/v0.2.0/01-siddhi-operator.yaml
Now you have to set up MySQL in your Kubernetes cluster. To do that use the following helm command.
$ helm install --name mysql-db --set mysqlRootPassword=siddhiio,mysqlUser=siddhi_user,mysqlPassword=siddhiio,mysqlDatabase=ComboSuperMart stable/mysql
Then, you can set a port forwarding to the MySQL service which allows you to connect from the Host
$ kubectl port-forward svc/mysql-db 3307:3306
Now you can access the MySQL cluster externally. Accessing MySQL cluster externally you can create ComboSuperMart database and the database schema. Using jdbc:mysql://mysql-db:3306/ComboSuperMart URL you can access the database.
Database URL for Kubernetes
When you changing the deployment.yaml
configuration of the data source in the Kubernetes export process, you have to specify this URL in the configuration as below.
- name: COMBO_SUPERMART_DB
description: The datasource used for lending process of the Combo supermarket
jndiConfig:
name: jdbc/ComboSuperMart
definition:
type: RDBMS
configuration:
jdbcUrl: jdbc:mysql://mysql-db:3306/ComboSuperMart
username: siddhi_user
password: siddhiio
driverClassName: com.mysql.jdbc.Driver
maxPoolSize: 10
idleTimeout: 60000
connectionTestQuery: SELECT 1
validationTimeout: 30000
isAutoCommit: false
Siddhi operator will automatically set up the external access to any HTTP service in a Siddhi app. To set up that external access Siddhi operator by default uses ingress NGINX. Set up the NGINX controller in your Kubernetes cluster as described in this document.
Now you need to create your own docker image with including all the custom libraries and configuration changes that you have made. Use following command to build and push the docker image with the tag <DOCKER_HUB_USER_NAME>/siddhi-runner-alpine:latest
.
$ docker build -t <DOCKER_HUB_USER_NAME>/siddhi-runner-alpine:latest .
$ docker push <DOCKER_HUB_USER_NAME>/siddhi-runner-alpine:latest
After the Kubernetes export now you already have this siddhi-process.yaml
file.
apiVersion: siddhi.io/v1alpha2
kind: SiddhiProcess
metadata:
name: combo-super-mart
spec:
apps:
- script: |
@App:name("ComboSuperMartPromoProcess")
@App:description("The promotion selection process of Combo super mart.")
/*
Purpose:
The combo supermart has multiple promotion card that given to their loyal users. For a particular season combo supermart plan to give discounts for each card. These discounts will change according to the card type and several rules. So, combo supermart needed an automatic system to retrieve the discounts for a given card. To do that we implement this Siddhi app which interacts with a MySQL database and executes their functionalities. All card details and rules were stored in a MySQL database. All the rules for a particular card were in the templated format. Therefore all rules executed dynamically and give the final result.
Input:
HTTP POST with JSON payload {
"event": {
"promoCardId": "PC001",
"amount": 20000
}
}
Output:
{
"event": {
"messageId": "1817d06b-22ae-438e-990d-42fedcb50607",
"discountAmount": 15.0,
"discountApplied": true
}
}
*/
-- HTTP source
@source(
type='http-service',
source.id='adder',
receiver.url='http://0.0.0.0:8088/comboSuperMart/promo',
basic.auth.enabled='',
@map(type='json', @attributes(messageId='trp:messageId', promoCardId='$.event.promoCardId', amount='$.event.amount'))
)
define stream InputTransactionStream(messageId string, promoCardId string, amount long);
-- RDBMS data stores
@Store(type="rdbms", datasource="COMBO_SUPERMART_DB")
define table Customer(customerId string, promoCardId string);
@Store(type="rdbms", datasource="COMBO_SUPERMART_DB")
define table PromoCard(promoCardId string, promoCardTypeId string, promoCardIssueDate string);
@Store(type="rdbms", datasource="COMBO_SUPERMART_DB")
define table PromoRule(promoRuleId string, promoCardTypeId string, promoRule string);
@Store(type="rdbms", datasource="COMBO_SUPERMART_DB")
define table PromoCardType(promoCardTypeId string, promoCardTypeDiscount double);
-- Output stream
@sink(type='http-service-response', source.id='adder',
message.id='{{messageId}}', @map(type = 'json'))
define stream ResultStream (messageId string, discountAmount double, discountApplied bool);
-- Find and execute rules
@info(name='get-promocard-type')
from InputTransactionStream#window.length(1) join PromoCard on InputTransactionStream.promoCardId==PromoCard.promoCardId
select InputTransactionStream.messageId, InputTransactionStream.promoCardId, PromoCard.promoCardTypeId, PromoCard.promoCardIssueDate, InputTransactionStream.amount
insert into GetPromoCardTypeStream;
@info(name='get-promocard-type-details')
from GetPromoCardTypeStream#window.length(1) join PromoCardType on GetPromoCardTypeStream.promoCardTypeId==PromoCardType.promoCardTypeId
select GetPromoCardTypeStream.messageId, GetPromoCardTypeStream.promoCardId, GetPromoCardTypeStream.promoCardTypeId, GetPromoCardTypeStream.amount, PromoCardType.promoCardTypeDiscount, GetPromoCardTypeStream.promoCardIssueDate
insert into GetPromoCardTypeDetailsStream;
@info(name='get-promocard-rules')
from GetPromoCardTypeDetailsStream#window.length(1) right outer join PromoRule on GetPromoCardTypeDetailsStream.promoCardTypeId==PromoRule.promoCardTypeId
select GetPromoCardTypeDetailsStream.messageId, GetPromoCardTypeDetailsStream.promoCardId, GetPromoCardTypeDetailsStream.promoCardTypeId, GetPromoCardTypeDetailsStream.amount, GetPromoCardTypeDetailsStream.promoCardTypeDiscount, PromoRule.promoRuleId, PromoRule.promoRule, GetPromoCardTypeDetailsStream.promoCardIssueDate
insert into RuleStream;
@info(name='execute-promocard-rules')
from RuleStream#window.length(1)
select RuleStream.messageId, RuleStream.promoCardTypeDiscount, js:eval(str:fillTemplate(RuleStream.promoRule, map:create("amount", RuleStream.amount, "cardPeriod", time:dateDiff(time:currentDate(), RuleStream.promoCardIssueDate, 'yyyy-MM-dd', 'yyyy-MM-dd'))), 'bool') as result
insert into RuleReslutsStream;
-- Output results
@info(name='filter-true-rules')
from RuleReslutsStream[result == true]#window.batch()
select RuleReslutsStream.messageId, RuleReslutsStream.promoCardTypeDiscount, count(result) as result
insert into TrueResultStream;
@info(name='get-all-results')
from RuleReslutsStream#window.batch()
select RuleReslutsStream.messageId, RuleReslutsStream.promoCardTypeDiscount, count(result) as result
insert into AllResultStream;
@info(name='discout-reply-stream')
from AllResultStream#window.length(1) unidirectional join TrueResultStream#window.length(1) on TrueResultStream.result==AllResultStream.result
select AllResultStream.messageId, AllResultStream.promoCardTypeDiscount as discountAmount, true as discountApplied
insert into ResultStream;
@info(name='filter-true-rules-and-reply')
from RuleReslutsStream[result == false]#window.batch()
select RuleReslutsStream.messageId, 0.00 as discountAmount, false as discountApplied
insert into ResultStream;
runner: |
wso2.carbon:
id: siddhi-runner
name: Siddhi Runner Distribution
ports:
offset: 0
transports:
http:
listenerConfigurations:
- id: default
host: 0.0.0.0
port: 9090
- id: msf4j-https
host: 0.0.0.0
port: 9443
scheme: https
keyStoreFile: ${carbon.home}/resources/security/wso2carbon.jks
keyStorePassword: wso2carbon
certPass: wso2carbon
transportProperties:
- name: server.bootstrap.socket.timeout
value: 60
- name: client.bootstrap.socket.timeout
value: 60
- name: latency.metrics.enabled
value: true
dataSources:
- name: WSO2_CARBON_DB
description: The datasource used for registry and user manager
definition:
type: RDBMS
configuration:
jdbcUrl: jdbc:h2:${sys:carbon.home}/wso2/${sys:wso2.runtime}/database/WSO2_CARBON_DB;DB_CLOSE_ON_EXIT=FALSE;LOCK_TIMEOUT=60000
username: wso2carbon
password: wso2carbon
driverClassName: org.h2.Driver
maxPoolSize: 10
idleTimeout: 60000
connectionTestQuery: SELECT 1
validationTimeout: 30000
isAutoCommit: false
- name: COMBO_SUPERMART_DB
description: The datasource used for lending process of the Combo supermarket
jndiConfig:
name: jdbc/ComboSuperMart
definition:
type: RDBMS
configuration:
jdbcUrl: jdbc:mysql://mysql-db:3306/ComboSuperMart
username: siddhi_user
password: siddhiio
driverClassName: com.mysql.jdbc.Driver
maxPoolSize: 10
idleTimeout: 60000
connectionTestQuery: SELECT 1
validationTimeout: 30000
isAutoCommit: false
persistentVolumeClaim:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: standard
volumeMode: Filesystem
container:
image: <DOCKER_HUB_USER_NAME>/siddhi-runner-alpine:latest
Now you can install the SiddhiProcess using following kubectl
command. Before you install the SiddhiProcess
you have to add the docker image tag in the siddhi-process.yaml
file. You have to add the docker image name(<DOCKER_HUB_USER_NAME>/siddhi-runner-alpine:latest
) in the YAML entry spec.container.image
.
$ kubectl apply -f siddhi-process.yaml
The ingress created by Siddhi operator will use the hostname as siddhi. Therefore you have to update your /etc/host
file with siddhi hostname along with the external IP of ingress.
External IP of Ingress
For minikube the ingress external IP is minikube IP and in docker, for Mac, the external IP is 0.0.0.0. For more details about Siddhi, ingress setup refer to this documentation.
Now you can send HTTP requests to deployed the Siddhi app in the Kubernetes cluster using following CURL command.
curl -X POST \
http://siddhi/combo-super-mart-0/8088/comboSuperMart/promo \
-H 'Accept: */*' \
-H 'Accept-Encoding: gzip, deflate' \
-H 'Content-Type: application/json' \
-H 'Host: siddhi' \
-d '{
"event": {
"promoCardId": "PC001",
"amount": 20000
}
}'
It will results the following JSON.
{
"event": {
"messageId": "285703c1-866a-4a88-8e1f-e75543e18374",
"discountAmount": 15.0,
"discountApplied": true
}
}
Top