Install & Configure: Billing¶
Let us setup Billing micro-service to run as a linux system service.
Preparing the host machine¶
Start by creating system folders for Billing service.
sudo mkdir -p /var/log/cyclops/billing/
sudo mkdir -p /etc/cyclops/billing/
sudo mkdir -p /usr/local/bin/cyclops/billing/
For logging to work properly, these files must exist, perform the next commands to ensure the same.
- errors.log
- trace.log
- rest.log
- dispatch.log
- data.log
- commands.log
- timeseries.log
sudo touch /var/log/cyclops/billing/errors.log
sudo touch /var/log/cyclops/billing/trace.log
sudo touch /var/log/cyclops/billing/rest.log
sudo touch /var/log/cyclops/billing/dispatch.log
sudo touch /var/log/cyclops/billing/data.log
sudo touch /var/log/cyclops/billing/commands.log
sudo touch /var/log/cyclops/billing/timeseries.log
Let’s move the binary and the configuration files from the compiled locations to the target system destinations.
sudo mv Billing/target/billing.jar /usr/local/bin/cyclops/billing/
sudo mv Billing/config/billing.conf /etc/cyclops/billing/
Preparing the Postgressql / TimescaleDB¶
Before working with the billing service, it is necessary to setup the appropriate database and table schemas. This can be achieved by executing the following commands on the host where the Postgresql service is running.
psql -U postgres -h localhost <<EOF
CREATE DATABASE cyclops_billing WITH OWNER cyclops;
GRANT ALL PRIVILEGES ON DATABASE cyclops_billing TO cyclops;
EOF
psql -U cyclops -h localhost -d cyclops_billing <<EOF
CREATE TABLE IF NOT EXISTS billrun (
id SERIAL primary key,
time TIMESTAMP NOT NULL,
data JSONB
);
EOF
psql -U cyclops -h localhost -d cyclops_billing <<EOF
CREATE TABLE IF NOT EXISTS bill (
id SERIAL,
run INTEGER REFERENCES billrun,
time_from TIMESTAMP NOT NULL,
time_to TIMESTAMP NOT NULL,
account TEXT NOT NULL,
charge DOUBLE PRECISION NOT NULL,
discount TEXT,
data JSONB,
currency TEXT
);
CREATE INDEX IF NOT EXISTS bill_account ON bill (account, time_from DESC);
CREATE INDEX IF NOT EXISTS bill_currency ON bill (currency, time_from DESC);
CREATE INDEX IF NOT EXISTS bill_data ON bill USING HASH (data);
EOF
Preparing RabbitMQ¶
Assuming that RabbitMQ is running on the same machine where the following commands are to be executed, running these will setup necessary exchanges, queues and bindings between them for billing process to function properly.
curl -u "cyclops:pass1234" -H "content-type:application/json" -XPUT -d '{"durable":true}' http://localhost:15672/api/queues/cyclops/cyclops.billing.consume
curl -u "cyclops:pass1234" -H "content-type:application/json" -XPUT -d '{"durable":true}' http://localhost:15672/api/queues/cyclops/cyclops.billing.commands
curl -u "cyclops:pass1234" -H "content-type:application/json" -XPUT -d '{"type":"fanout", "durable":true}' http://localhost:15672/api/exchanges/cyclops/cyclops.coinbill.broadcast
curl -u "cyclops:pass1234" -H "content-type:application/json" -XPUT -d '{"type":"direct", "durable":true}' http://localhost:15672/api/exchanges/cyclops/cyclops.billing.dispatch
curl -u "cyclops:pass1234" -H "content-type:application/json" -XPUT -d '{"type":"fanout", "durable":true}' http://localhost:15672/api/exchanges/cyclops/cyclops.billing.broadcast
curl -u "cyclops:pass1234" -H "content-type:application/json" -XPOST -d '{}' http://localhost:15672/api/bindings/cyclops/e/cyclops.coinbill.broadcast/q/cyclops.billing.consume
curl -u "cyclops:pass1234" -H "content-type:application/json" -XPUT -d '{"durable":true}' http://localhost:15672/api/queues/cyclops/cyclops.cdr.commands
curl -u "cyclops:pass1234" -H "content-type:application/json" -XPUT -d '{"durable":true}' http://localhost:15672/api/queues/cyclops/cyclops.coinbill.consume
curl -u "cyclops:pass1234" -H "content-type:application/json" -XPOST -d "{\"routing_key\":\"CDR\"}" http://localhost:15672/api/bindings/cyclops/e/cyclops.billing.dispatch/q/cyclops.cdr.commands
curl -u "cyclops:pass1234" -H "content-type:application/json" -XPOST -d "{\"routing_key\":\"CoinBill\"}" http://localhost:15672/api/bindings/cyclops/e/cyclops.billing.dispatch/q/cyclops.coinbill.consume
curl -u "cyclops:pass1234" -H "content-type:application/json" -XPOST -d "{\"routing_key\":\"SelfPublish\"}" http://localhost:15672/api/bindings/cyclops/e/cyclops.billing.dispatch/q/cyclops.billing.commands
In the above commands, do not forget to replace the -u values cyclops and pass1234 to correct RabbitMQ user/pass values that was setup earlier.
Configuring Billing¶
You can configure the service endpoints and dependencies in the configuration file located under /etc/cyclops/billing/
Default content is shown next:
# HTTP and/or HTTPS port to be exposed at
ServerHTTPPort=4569
#ServerHTTPSPort=5569
#ServerHTTPSCertPath=/path/to/cert.p12
#ServerHTTPSPassword=password
# Health check every X seconds
ServerHealthCheck=30
ServerHealthShutdown=false
# Database credentials to TimescaleDB
DatabasePort=5432
DatabaseHost=localhost
DatabaseUsername=cyclops
DatabasePassword=password
DatabaseName=cyclops_billing
DatabasePageLimit=500
DatabaseConnections=2
# Publisher (RabbitMQ) credentials
PublisherHost=localhost
PublisherUsername=cyclops
PublisherPassword=password
PublisherPort=5672
PublisherVirtualHost=cyclops
PublisherDispatchExchange=cyclops.billing.dispatch
PublisherBroadcastExchange=cyclops.billing.broadcast
# Consumer (RabbitMQ) credentials
ConsumerHost=localhost
ConsumerUsername=cyclops
ConsumerPassword=password
ConsumerPort=5672
ConsumerVirtualHost=cyclops
ConsumerDataQueue=cyclops.billing.consume
ConsumerCommandsQueue=cyclops.billing.commands
# Bill generation workflow
PublishToCDRWithKey=CDR
PublishToCoinBillWithKey=CoinBill
PublishToSelf=SelfPublish
# Connection to customer-database
CustomerDatabaseHost=localhost
CustomerDatabasePort=8888
- ServerHTTPPort / ServerHTTPSPort: You can configure the port where the service will be running at. HTTPS is supported if you provide a valid certificate and the associated password.
- TimescaleDB parameters are same as Postgressql parameters
- RabbitMQ block configures how this service communicates with an existing RabbitMQ service endpoint, they are defined for both the consumer as well as publisher process.
Fixing permissions¶
Before running any of the Cyclops framework services via systemctl command, make sure that the process user cyclops which was created earlier to run the process has full read/write access to Cyclops specific system folder and files.
sudo chown -R cyclops:cyclops /var/log/cyclops/
sudo chown -R cyclops:cyclops /usr/local/bin/cyclops/
sudo chown -R cyclops:cyclops /etc/cyclops/
sudo chown -R cyclops:cyclops /var/lib/cyclops/
Setup as a service¶
Create a file called cyclops-billing.service in /etc/systemd/system/ directory. Add the following content to this file:
[Unit]
Description=Cyclops billing Service
After=network.target rabbitmq-server.service postgresql-9.6.service
[Service]
ExecStartPre=/bin/sleep 2
Type=simple
User=cyclops
ExecStart=/usr/bin/java -jar /usr/local/bin/cyclops/billing/billing.jar /etc/cyclops/billing/billing.conf
Restart=on-abort
[Install]
WantedBy=multi-user.target
This assumes that the rabbitmq and postgres server is running in the same machine where you are setting up billing service. If not then remove them from the dependencies list by changing the After line above. Do make sure that these services are running and reachable before billing service is started.
You can enable and manage the billing service and start it by using the following systemctl commands.
sudo systemctl enable cyclops-billing.service
sudo systemctl start/stop/restart/status cyclops-billing.service