Skip to content
This repository has been archived by the owner on Sep 26, 2018. It is now read-only.

Include Top-Up checks: #83

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions client/core/checkin.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
from core.bts import bts
from core.config_database import ConfigDB
from core.event_store import EventStore
from core.denomination_store import DenominationStore
from core.registration import reset_registration
from core.subscriber import subscriber

Expand All @@ -30,6 +31,7 @@ class CheckinHandler(object):
CONFIG_SECTION = "config"
EVENTS_SECTION = "events"
SUBSCRIBERS_SECTION = "subscribers"
NETWORK_DENOMINATION = "network_denomination"

# NOTE: Keys in section_ctx dictionary below must match the keys of
# optimized checkin sections: "config", "events", "subscribers", etc.
Expand All @@ -42,6 +44,7 @@ class CheckinHandler(object):
def __init__(self, response):
self.conf = ConfigDB()
self.eventstore = EventStore()
self.denominationstore = DenominationStore()
r = self.validate(response)
self.process(r)

Expand All @@ -59,6 +62,8 @@ def process(self, resp_dict):
self.process_events(resp_dict[section])
elif section == CheckinHandler.SUBSCRIBERS_SECTION:
self.process_subscribers(resp_dict[section])
elif section == CheckinHandler.NETWORK_DENOMINATION:
self.process_denomination(resp_dict[section])
elif section != 'status':
logger.error("Unexpected checkin section: %s" % section)

Expand Down Expand Up @@ -93,6 +98,18 @@ def process_config(self, config_dict):
def process_subscribers(self, data_dict):
subscriber.process_update(data_dict)

# process denomination table if denomination bracket is not then it add,
# if it's deleted then it delete , if it's updated then update
def process_denomination(self, data_dict):
for data in data_dict:
if self.denominationstore.get_record(data['id']) == None:
self.denominationstore.add_record(data['id'],data['start_amount'],
data['end_amount'],data['validity'])
id_list = self.denominationstore.get_all_id()
for id in id_list:
if id not in [d['id'] for d in data_dict]:
self.denominationstore.delete_record(id)

def process_events(self, data_dict):
"""Process information about events.

Expand Down
5 changes: 3 additions & 2 deletions client/core/config_database.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,8 +154,9 @@ def set_defaults(force_replace=False):
'external_interface': 'tun0',
# The internal interface is the NIC used by the BSC/BTS to address this
# system
'internal_interface': 'lo'

'internal_interface': 'lo',
# default network balance limit
'network_max_balance': 100000

}
config = ConfigDB()
Expand Down
124 changes: 124 additions & 0 deletions client/core/denomination_store.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
"""
store denomination bracket in the backend database.

Copyright (c) 2017-present, Facebook, Inc.
All rights reserved.

This source code is licensed under the BSD-style license found in the
LICENSE file in the root directory of this source tree. An additional grant
of patent rights can be found in the PATENTS file in the same directory.
"""






import os

import psycopg2


# In our CI system, Postgres credentials are stored in env vars.
PG_USER = os.environ.get('PG_USER', 'endaga')
PG_PASSWORD = os.environ.get('PG_PASSWORD', 'endaga')


class DenominationStore(object):
"""Update denomination bracket from cloud to get validity days."""

def __init__(self):
self.connection = psycopg2.connect(host='localhost', database='endaga',
user=PG_USER, password=PG_PASSWORD)
self.table_name = 'denomination_store'
# Create the table if it doesn't yet exist.
with self.connection.cursor() as cursor:
command = ("CREATE TABLE IF NOT EXISTS %s("
" id integer NOT NULL,"
" start_amount bigint NOT NULL,"
" end_amount bigint NOT NULL,"
" validity_days integer NOT NULL"
");")
cursor.execute(command % self.table_name)
self.connection.commit()

def empty(self):
"""Drops all records from the table."""
with self.connection.cursor() as cursor:
command = 'truncate %s' % self.table_name
cursor.execute(command)
self.connection.commit()

def get_records(self):
res = []
template = ('select * from %s ')
command = template % (self.table_name)
with self.connection.cursor() as cursor:

cursor.execute(command)
self.connection.commit()
r = cursor.fetchall()
for item in r:
data = {'start_amount': item[1],
'end_amount': item[2], 'validity': item[3]}

return res

def get_all_id(self):
res =[]

template = 'select * from %s '
command = template % (self.table_name)
with self.connection.cursor() as cursor:
cursor.execute(command)
self.connection.commit()
r = cursor.fetchall()
for item in r:
res.append(item[0])
return res

def get_record(self, id):
"""Gets the most recent record for an Id.

Returns None if no record was found.
"""
command = "select * from %s where id='%s'"
with self.connection.cursor() as cursor:
cursor.execute(command % (self.table_name, id))
self.connection.commit()
if not cursor.rowcount:
return None
else:
return cursor.fetchall()[0]

def delete_record(self, id):
template = 'delete from %s where id = %s'
command = template % (self.table_name, id)
with self.connection.cursor() as cursor:
cursor.execute(command)
self.connection.commit()

def get_validity_days(self,top_up):

template = "select validity_days from %s where start_amount <=%s " \
"and end_amount >=%s order by -end_amount"
command = template %(self.table_name, top_up, top_up)
with self.connection.cursor() as cursor:
cursor.execute(command)
self.connection.commit()
r = cursor.fetchall()
if len(r):
return r[0]
else:
return None

def add_record(self,id, start_amount, end_amount, validity):
schema = ('id, start_amount, end_amount, validity_days')
values = "'%s','%s', '%s', %s" % (
id, start_amount, end_amount, validity)
command = 'insert into %s (%s) values(%s)' % (
self.table_name, schema, values)
with self.connection.cursor() as cursor:
cursor.execute(command)
self.connection.commit()

18 changes: 17 additions & 1 deletion cloud/endagaweb/checkin.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
from endagaweb.models import TimeseriesStat
from endagaweb.models import UsageEvent
from endagaweb.util.parse_destination import parse_destination

from endagaweb.models import NetworkDenomination

class CheckinResponder(object):

Expand Down Expand Up @@ -163,6 +163,8 @@ def process(self, status):
self.gen_subscribers())
resp['events'] = self.gen_events()
resp['sas'] = self.gen_spectrum()
# send network denomination bracket data with response
resp['network_denomination'] = self.get_network_denomination()
self.bts.save()
return resp

Expand Down Expand Up @@ -403,6 +405,7 @@ def gen_config(self):
'latest_stable_version': latest_stable_version,
'latest_beta_version': latest_beta_version,
}
result['endaga']['network_max_balance'] = self.bts.network.max_balance
return result

def gen_events(self):
Expand Down Expand Up @@ -485,6 +488,19 @@ def sas_request():
}
return {'ok': False}

def get_network_denomination(self):
"""
Returns a list of denomination bracket for status done
"""
res = []
for s in NetworkDenomination.objects.filter(network=self.bts.network,
status='done'):
data = {'id': s.id,'start_amount': s.start_amount,
'end_amount': s.end_amount, 'validity': str(s.validity_days)}
res.append(data)
return res



def handle_event(bts, event, destinations=None):
"""Handles a usage event from a BTS.
Expand Down