skovzhaw edited this page Jul 26, 2017 · 28 revisions

Architecture diagram

Prerequisites

  • Java 8 and Maven 3
  • PostgreSQL 9.6: set up all database tables as per instructions in Install/schema.sh
  • RabbitMQ 3.6: set up all queues, exchanges and bindings as per instructions in Install/bindings.sh

Deployment

  • Execute mvn package assembly:single in UDR, CDR, Coin and Billing folders
  • Fill information and credentials in each microservice's configuration file
  • Start compiled JARs with java -jar service.jar service.conf

Usage data

Upload usage data representing consumption of your services/users to the UDR micro service

  • via RabbitMQ's queue cyclops.udr.consume
  • via HTTP POST at IP:PORT/usage

Both accept data in JSON and require metric, account, usage and unit fields to be present. Time field is either provided in milliseconds or generated automatically, where remaining data you might have goes into data, as in the example below.

{
  "metric": "Memory",
  "account": "Martin",
  "time": 1493450936000,
  "usage": 1024,
  "unit": "MB",
  "data": {
    "project": "ABC",
    "host": "gentoo"
  }
}

Pricing rules

Rule engine sitting between UDR and CDR micro service expects pricing rules via HTTP POST at IP:PORT/rule as plain text. The full documentation is available here.

An example pricing rule rating Storage metric (3 CHF per unit of storage):

import ch.icclab.cyclops.facts.Usage;
import ch.icclab.cyclops.facts.Charge;

rule "Static rating for Storage"
salience 50
when
  $usage: Usage(metric == "Storage") 
then
  Charge charge = new Charge($usage);
  charge.setCharge(3 * $usage.getUsage());
  charge.setCurrency("CHF");

  retract($usage);
  insert(charge);
end

And system rule that always needs to be present:

import ch.icclab.cyclops.facts.Charge;
import java.util.List;

global ch.icclab.cyclops.publish.Messenger messenger;

rule "Broadcast charge data"
salience 20
when
  $charge: List( size > 0 ) from collect ( Charge() )
then
  messenger.broadcast($charge);
  $charge.forEach(c->retract(c));
end

Billing rules

Second rule engine is put between CDR and Billing micro services and expects billing rules via HTTP POST at IP:PORT/rule as plain text. The full documentation is available here.

Two system rules are necessary, first responsible for collecting CDRs based on received Bill request (with priority 50):

import ch.icclab.cyclops.facts.BillRequest;
import ch.icclab.cyclops.facts.Charge;
import ch.icclab.cyclops.facts.Bill;
import java.util.List;

rule "Collect CDRs for the Bill Request"
salience 50
when
  $request: BillRequest($accounts: accounts)
  $CDRs: List(size > 0) from collect (Charge(account memberOf $accounts))
then
  // bills for each currency of account\'s CDRs
  List<Bill> bills = $request.process($CDRs);

  // add bills to the working memory
  bills.forEach(bill->insert(bill));

  // remove processed CDRs and the bill request
  $CDRs.forEach(c->retract(c));
  retract($request);
end

And second rule responsible for broadcasting generated bills (with priority 30):

import ch.icclab.cyclops.facts.Bill;
import java.util.List;

global ch.icclab.cyclops.publish.Messenger messenger;

rule "Broadcast generated bills"
salience 30
when
  $bills: List(size > 0) from collect (Bill())
then
  // broadcast and remove processed bills
  messenger.broadcast($bills);
  $bills.forEach(bill->retract(bill));
end

Feel free and add your own discounting and tax rules, intercepting the bill generation and broadcasting, working in the priority range of (30, 50).

Generating UDRs

Once rules have been added and your collector has sent some usage data in, the next step is to generate UDR records, which can be done by sending HTTP POST to UDR micro service at IP:PORT/command as follows:

{
  "command": "GenerateUDRs",
  "time_from": 1501027200000,
  "time_to": 1501113599999
}

This consolidates usage data and generates UDRs in the period time_from and time_to (in milliseconds).

Generated UDRs can be listed via IP:PORT/udr endpoint of the UDR micro service. Scope can be limited by adding time_from, time_to, metric and/or account URL parameters.

Generating CDRs

Once the system has UDR records present, the next step is to flush them further. This can be achieved by sending HTTP POST to UDR micro service at IP:PORT/command in the following format:

{
  "command": "FlushUDRs",
  "time_from": 1501027200000,
  "time_to": 1501113599999
}

This will send data from UDR micro service to first rule engine, apply pricing rules and send generated records to the CDR micro service. CDR records can be listed via IP:PORT/cdr endpoint of the CDR micro service. Scope can be limited by adding time_from, time_to, metric and/or account URL parameters.

Generating Bills

The last step is to generate bills for a specified accounts, by sending HTTP POST to Billing micro service listening on IP:PORT/command endpoint as follows:

{
  "command": "GenerateBill",
  "time_from": 1498867200000,
  "time_to": 1501545599999,
  "request": "Martin"
}

Which will utilize the second rule engine, optionally applying discounts and tax deductions. Generated bills can be then listed via IP:PORT/cdr endpoint of the Billing micro service. Scope can be limited by adding time_from, time_to and/or account URL parameters.

You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Press h to open a hovercard with more details.