2. Who Am I ?
● Open source evangelist
● Former Board member of OpenSourceMatters
(Non-profit-org behind Joomla)
● S.D.O.C. Ltd. Co-Founder
3. What are we doing?
● We increase business success through great
open source technologies and services
○ Open & Transparent
○ Don't reinvent the wheel
○ High Quality
○ Lean & Effective
4. How did we get to billing (history)
● Client: Golan Telecom (Israel)
5. How did we get to billing (history)
● Client: Golan Telecom
○ New & lean player in the market
○ 0=>~1M subscribers in 4 years
○ Limited resources & love open source
6. How did we get to billing (history)
● Client: Golan Telecom
○ Start environment from Day 1
○ Short and aggressive time to market
○ Unlimited plan for ~25$
○ Customer can do almost everything in the website
■ Obviously requires 24/7 uptime
7. How did we get to billing (history)
● Start with Anti-Fraud solution
● 2 Different data structure, 2 separated tables
○ Outgoing calls (MOC)
○ incoming calls (MTC)
○ SMS (duration=0 means SMS)
8. Anti-Fraud in RDBMS
How was it look like? Example code...
$base_query = "SELECT imsi FROM moc WHERE callEventStartTimeStamp >=" . $start
. " UNION SELECT imsi FROM mtc WHERE callEventStartTimeStamp >=" . $start
$base_query = "SELECT imsi FROM (" . $base_query . ") AS qry ";
if (isset($args['imsi']))
$base_query .= "WHERE imsi = '" . $this->_connection->real_escape_string($args['imsi']) . "'";
$base_query .= "GROUP BY imsi ";
$mtc_join_query = "SELECT 'mtc' AS type, imsi, SUM(callEventDuration) AS duration, SUM(CEILING(callEventDuration/60)*60) AS duration_round "
. ", SUM(chargeAmount) charge "
. ", SUM(IF(SUBSTRING(callingNumber, 1, 3)='972', callEventDuration, IF(CHAR_LENGTH(callingNumber)<=10, callEventDuration, 0))) AS israel_duration "
. ", SUM(IF(SUBSTRING(callingNumber, 1, 3)='972', CEILING(callEventDuration/60)*60, IF(CHAR_LENGTH(callingNumber)<=10, CEILING(callEventDuration/60)*60, 0))) AS
israel_duration_round "
. ", SUM(IF(SUBSTRING(callingNumber, 1, 3)!='972', IF(CHAR_LENGTH(callingNumber)>10, callEventDuration, 0), 0)) AS non_israel_duration "
. ", SUM(IF(SUBSTRING(callingNumber, 1, 3)!='972', IF(CHAR_LENGTH(callingNumber)>10, CEILING(callEventDuration/60)*60, 0), 0)) AS non_israel_duration_round "
. ", SUM(IF(callEventDuration = 0, 1, 0)) AS sms_count "
. "FROM mtc "
. "WHERE callEventStartTimeStamp >=" . $start . " "
. "GROUP BY type, imsi";
9. Anti-Fraud in RDBMS
How was it look like? Example code...
$moc_join_query = "SELECT 'moc' AS type, imsi, SUM(callEventDuration) AS duration, SUM(CEILING(callEventDuration/60)*60) AS duration_round "
. ", SUM(chargeAmount) charge "
. ", SUM(IF(SUBSTRING(connectedNumber, 1, 3)='972', callEventDuration, IF(CHAR_LENGTH(connectedNumber)<=10, callEventDuration, 0))) AS israel_duration "
. ", SUM(IF(SUBSTRING(connectedNumber, 1, 3)='972', CEILING(callEventDuration/60)*60, IF(CHAR_LENGTH(connectedNumber)<=10, CEILING(callEventDuration/60)*60, 0))) AS israel_duration_round "
. ", SUM(IF(SUBSTRING(connectedNumber, 1, 3)!='972', IF(CHAR_LENGTH(connectedNumber)>10, callEventDuration, 0), 0)) AS non_israel_duration "
. ", SUM(IF(SUBSTRING(connectedNumber, 1, 3)!='972', IF(CHAR_LENGTH(connectedNumber)>10, CEILING(callEventDuration/60)*60, 0), 0)) AS non_israel_duration_round "
. ", SUM(IF(callEventDuration = 0, 1, 0)) AS sms_count "
. "FROM moc "
. "WHERE callEventStartTimeStamp >=" . $start . " "
. "GROUP BY type, imsi";
10. Anti-Fraud in RDBMS
How was it look like? Example code...
$group_query = "SELECT base.imsi, moc.duration AS moc_duration, moc.charge AS moc_charge, "
. "mtc.duration AS mtc_duration, mtc.charge AS mtc_charge, "
. "mtc.duration_round AS mtc_duration_round, moc.duration_round AS moc_duration_round, "
. "moc.israel_duration AS moc_israel_duration, moc.non_israel_duration AS moc_non_israel_duration, "
. "moc.israel_duration_round AS moc_israel_duration_round, moc.non_israel_duration_round AS moc_non_israel_duration_round, "
. "mtc.israel_duration AS mtc_israel_duration, mtc.non_israel_duration AS mtc_non_israel_duration, "
. "mtc.israel_duration_round AS mtc_israel_duration_round, mtc.non_israel_duration_round AS mtc_non_israel_duration_round, "
. "mtc.sms_count AS mtc_sms_count, moc.sms_count AS moc_sms_count "
. "FROM "
. "( " . $base_query . " ) AS base "
. " LEFT JOIN (" . $mtc_join_query . " ) AS mtc ON base.imsi = mtc.imsi "
. " LEFT JOIN (" . $moc_join_query . " ) AS moc ON base.imsi = moc.imsi " ;
if (isset($args['limit'])) {
$limit = (int) $args['limit'];
} else {
$limit = 100000;
}
15. What is billing?
● Group of processes of communications
service providers
● responsible to collect consumption data
● calculate charging and billing information
● produce bills to customers
● process their payments and manage debt
collection
Wikipedia
23. Billing and MongoDB - Pros
Loose coupling and loose traditional billing components
Old
w/o MongoDb New
with MongoDb
24. Billing and MongoDB - Pros
● Call can be separated CDRs
● BillRun unify records only on export or
presentation layer you are aggregate not in
the DB.
● No need for mediation
● Can monitor CDR level and use billing in one
system
25. Billing and MongoDB - Pros
Sophisticated rating module
● Rating module depends on CDR structure
● Easy to implement recurring rating
26. MongoDB advantages with Billing
Invoice JSON2PDF process
● Use json as metadata for the PDF
● Easy to export
● Fast processing
29. Infrastructure
BETA
First Production
Today
Data center 1
Data center 2
Data center 1
Data center 2 Data center 1
Data center 2
BillRun application
BillRun core
PHP Yaf
framework
Mongodloid,
Zend and more
libraries
MongoDB
App stack
Web service Cli/Cron services
30. Pay Attention! What to keep in mind
Transactional (tx) processes
● write concern - acknowledged (default in 2.4)
● findAndModify (A.K.A FAM) - document tx
● value=oldValue
● 2 phase commit - app side
● Transaction lock by design
31. High performance tricks
● With SSD you get x20 more performance
● MongoDB loves RAM
● Follow MongoDB production notes
○ Readahead low as possible
○ THP - transparent hugepages
Pay Attention! What to keep in mind
32. TCO - MongoDB based solution
● 3 Months dev
● 3 Months QA
● Few days of maintenance infra and app
● Easy to scale
● Easy to add features
33. Thank you, Ofer Cohen S.
D.O.C. Ltd.
ofer@billrun.net @oc666
BillRun
Billing on Top of