Example: Simple Rating
Introduction
This walkthrough provides a step by step guide to running through a number of simple rating scenarios with the OCS. This walkthrough assumes that the OCS is running, and that the OCS HTTP API is accessible.
To trigger these API requests, it is suggested that a HTTP REST interface tester such as postman is used.
Setup
Create a subscriber
POST
http://localhost:5490/resource/wallet
{
"id": "6463581140"
}
Give the subscriber money and data
1000 units of cash are given. The OCS uses microcents internally, but this denomination may be granted different meaning by the environment.
POST
http://localhost:5490/resource/wallet/6463581140/bucket
{
"value": 1000,
"unit": "microcents"
}
Grant 10MB:
POST
http://localhost:5490/resource/wallet/6463581140/bucket
{
"value": 100000000,
"unit": "bytes"
}
Create an immediate use lifecycle
This is a simple lifecycle that grants buckets to a subscriber after debiting their wallet
POST
http://localhost:5490/resource/lifecycle
{
"id": "single-use-lifecycle",
"name": "SingleUseLifecycle",
"description": "Single use subscription lifecycle, for use for once-off purchases.",
"active": true,
"lifecycleclass": "subscription"
}
POST
http://localhost:5490/resource/lifecycle/single-use-lifecycle/state
{
"id": "initial-state",
"name": "INITIAL",
"description": "the starting point",
"action": "engine.debit_wallet(context.getJsonObject('debit')); wallet.add_buckets_j(context.getJsonArray('buckets')); 'success'"
}
POST
http://localhost:5490/resource/lifecycle/single-use-lifecycle/state
{
"id": "complete-state",
"name": "COMPLETE",
"description": "cleanup point",
"action": "lifecycle.delete()"
}
PUT
http://localhost:5490/resource/lifecycle/single-use-lifecycle
{
"initial_state": "INITIAL"
}
POST
http://localhost:5490/resource/lifecycle/single-use-lifecycle/state/initial-state/transition
{
"event": "success"
, "to_state": "COMPLETE"
}
Create a service which will charge the user 150 units, for 1 day of seconds:
POST
http://localhost:5490/resource/service
{
"id": "24-hour-basic-cable",
"name": "24 Hour Basic Cable",
"description": "Access to cable for 24 hours from time of purchase.",
"active": true,
"lifecycle": "single-use-lifecycle",
"serviceclass": "value-pack",
"properties": {
"buckets": [
{
"value": 86400,
"unit": "seconds",
"expiry": {
"days": 1
}
}
]
, "debit": {
"rating_requested": [{
"unit": "microcents",
"value": 150
}]
}
},
"cardinality": 1
}
Event Charging
In this example, we want to charge a user 50 units, but we want to reserve it, then ultimately commit it 10 minutes later. We simulate this using two messages , a reservation request, then a commit, highlighting between these two the subscriber’s intermediate wallet.
Initially display the user’s wallet
GET
http://localhost:5490/resource/wallet/6463581140
First, we want to perform session based charging. We include a session ID, because that will often come from the client. We include the rating requested as well.
POST
http://localhost:5490/engine/wallet/6463581140/session
{
"id": "session-1",
"rating_requested": [
{
"unit": "microcents",
"value": 50
}]}
We can review the user’s wallet, to see the session in progress, and the ongoing reservations on a per-bucket basis:
GET
http://localhost:5490/resource/wallet/6463581140
We can see the user’s wallet - the session, and the reservation, and the bucket value.
[{
"sessions": {
"session-1": {
"initial_creation_timestamp": "2018-01-11T07:29:14.408Z",
"id": "session-1"
}},
"buckets": [
{
"value": 1000,
"id": "8470ede6-d3b5-4406-b7bf-9a402b497c55",
"unit": "microcents",
"reservations": [
{
"value": 50,
"session": "session-1"
}]}],
"id": "6463581140"
}]
We can further see the affect ongoing sessions have, but doing a price enquiry:
POST
http://localhost:5490/engine/wallet/6463581140/enquire
{
"rating_requested": [
{
"unit": "microcents"
,"value":0
}]
}
In the response, the decrease in available funds is clear:
"funds_available": [{
"unit": "microcents",
"value": 950
}]
We can then commit the reservation:
POST
http://localhost:5490/engine/wallet/6463581140/session/session-1/commit
Once the commit has been complete, the OCS can be queried to see the wallet’s session list is empty, and the reservations on the bucket are removed.
We can additional see the use of unit conversions to charge for MB using money:
POST
http://localhost:5490/engine/wallet/6463581140/enquire
{
"rating_requested": [
{
"unit": "bytes"
,"value":0
}],
"rating_context": {
"unit_conversion_ratios": [{
"from_unit": "bytes",
"to_unit": "microcents",
"from_unit_count": 1024,
"to_unit_count": 1
}]}}
Time Based Usage
In this example, we purchase 48 hours of unlimited data access:
POST
http://localhost:5490/engine/wallet/6463581140/subscribe
{
"service": "24-hour-basic-cable"
}
This grants the user a time based bucket. On a subscriber query, we can see this in their wallet:
[
{
"audit": {
"initial_creation_timestamp": "2018-01-09T03:02:47.848Z",
"last_change_timestamp": "2018-01-09T19:30:44.647Z",
"last_change_host": "localhost:5490",
"lock": "2018-01-09T19:30:44.647Z"
},
"buckets": [
{
"value": 950,
"id": "539816c8-d5eb-400a-95bb-6f659bd21f33",
"unit": "microcents"
},
{
"value": 86400,
"id": "4505374b-2319-4f8f-9618-f0f2ac9ee074",
"unit": "seconds",
"expiry": "2018-01-10T19:30:44.645Z"
}
],
"id": "6463581140"
}
]
Note that bucket annotations - e.g. to flag this time based bucket as “unlimited” time, with its expiry, and with a minimum value (so it doesn’t go negative) can be incorporated. For simplicity this demonstration has skipped this.
Note also that the user may be granted 24 hours of time - e.g. of cumulative time which they can use of the course of a week, or unlimited watching within 24 hours. This may the be charged and then we can request time usage can be charge. First we can request how much time the user has available using an enquire method:
POST
http://localhost:5490//engine/wallet/6463581140/enquire
{
"rating_requested": [{
"value": 0
, "unit": "seconds"
}]}
This will confirm the user has time. The system will respond with funds available:
"funds_available": [
{
"unit": "seconds",
"value": 86400
}]
(Note that the expiry of these funds will occur 24 hours after being granted).
The cable system can then grant access, and use these funds through standard debiting - e.g. debit every 60 seconds:
POST
http://localhost:5490/engine/wallet/6463581140/debit
{
"rating_requested": [{
"value": 60
, "unit": "seconds"
}]}
Once the time bucket expires, or has been completely used, e.g. delete the bucket using:
DELETE
http://localhost:5490/resource/wallet/6463581140/bucket/4505374b-2319-4f8f-9618-f0f2ac9ee074
Then the debit will fail:
POST
http://localhost:5490/engine/wallet/6463581140/xfe
{
"rating_requested": [{
"value": 60
, "unit": "seconds"
}]}
with a return value of 402: Insufficient Funds
.
Data Charging
In this example, we want to charge a user for data usage during a data session. For this, we reserve funds in 1MB chunks, and then, at the end of the session, charge for the actual data MB used.
First, we want to perform session based charging. We include a session ID, because that will often come from the client. We include the rating requested as well.
POST
http://localhost:5490/engine/wallet/6463581140/session
{
"id": "session-1",
"rating_requested": [
{
"unit": "byte",
"value": 1000000
}]}
We can review the user’s wallet, to see the session in progress, and the ongoing reservations on a per-bucket basis:
GET
http://localhost:5490/resource/wallet/6463581140
We can see the user’s wallet - the session, and the reservation, and the bucket value.
[{
"sessions": {
"session-1": {
"initial_creation_timestamp": "2018-01-11T07:29:14.408Z",
"id": "session-1"
}},
"buckets": [
{
"value": 100000000,
"id": "8470ede6-d3b5-4406-b7bf-9a402b497c55",
"unit": "bytes",
"reservations": [
{
"value": 1000000,
"session": "session-1"
}]}],
"id": "6463581140"
}]
We can further see the affect ongoing sessions have, by doing a price enquiry:
POST
http://localhost:5490/engine/wallet/6463581140/enquire
{
"rating_requested": [
{
"unit": "bytes"
,"value":0
}]
}
In the response, the decrease in available funds is clear:
"funds_available": [{
"unit": "bytes",
"value": 102809580
}]
We can then perform more reservations to request more time. Eventually, we can then commit the reservation:
POST
http://localhost:5490/engine/wallet/6463581140/session/session-1/commit
{
"id": "session-1",
"rating_used": [
{
"unit": "bytes",
"value": 500000
}]}
Once the commit has been complete, the OCS can be queried to see the wallet’s session list is empty, and the reservations on the bucket are removed, and the actually requested rating has been used.