Skip to content

Commit f86cbb6

Browse files
committed
added user address for usage and free calls
1 parent ab9a95b commit f86cbb6

File tree

9 files changed

+134
-81
lines changed

9 files changed

+134
-81
lines changed
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
"""user address added
2+
3+
Revision ID: b0f9443a30de
4+
Revises: 66d97ed3bdc5
5+
Create Date: 2019-08-23 18:32:06.447515
6+
7+
"""
8+
from alembic import op
9+
import sqlalchemy as sa
10+
from sqlalchemy.dialects import mysql
11+
12+
# revision identifiers, used by Alembic.
13+
revision = 'b0f9443a30de'
14+
down_revision = '66d97ed3bdc5'
15+
branch_labels = None
16+
depends_on = None
17+
18+
19+
def upgrade():
20+
# ### commands auto generated by Alembic - please adjust! ###
21+
op.add_column('usage_table', sa.Column('payment_mode', sa.VARCHAR(length=225), nullable=True))
22+
op.add_column('usage_table', sa.Column('service_id', sa.VARCHAR(length=225), nullable=True))
23+
op.add_column('user_org_group', sa.Column('user_address', sa.VARCHAR(length=225), nullable=True))
24+
op.alter_column('user_org_group', 'user_name',
25+
existing_type=mysql.VARCHAR(length=225),
26+
nullable=True)
27+
# ### end Alembic commands ###
28+
29+
30+
def downgrade():
31+
# ### commands auto generated by Alembic - please adjust! ###
32+
op.alter_column('user_org_group', 'user_name',
33+
existing_type=mysql.VARCHAR(length=225),
34+
nullable=False)
35+
op.drop_column('user_org_group', 'user_address')
36+
op.drop_column('usage_table', 'service_id')
37+
op.drop_column('usage_table', 'payment_mode')
38+
# ### end Alembic commands ###

metering/alembic/versions/eeec29a1af7b_added_tables.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ def upgrade():
2727
sa.Column('free_calls', sa.Integer(), nullable=False),
2828
sa.Column('effective_start_date', sa.TIMESTAMP(
2929
timezone=True), nullable=True),
30-
sa.Column('effective_end_date', sa.TIMESTAMP(timezone=True),
31-
server_default=sa.text('CURRENT_TIMESTAMP'), nullable=True),
30+
sa.Column('effective_end_date', sa.TIMESTAMP(
31+
timezone=True), nullable=True),
3232
sa.Column('created_at', sa.TIMESTAMP(
3333
timezone=True), nullable=True),
3434
sa.PrimaryKeyConstraint('id')

metering/constants.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ class StatusCode:
1010
"Access-Control-Allow-Origin": "*",
1111
"Access-Control-Allow-Methods": "OPTIONS,POST,GET"
1212
}
13+
PAYMENT_MODE_FREE_CALL = 'freecall'
1314

1415

1516
class StatusMessage:

metering/models.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ class UserOrgGroupModel(Base):
2222
id = Column('id', Integer, primary_key=True)
2323
payment_group_id = Column('group', VARCHAR(225))
2424
org_id = Column('org_id', VARCHAR(225), nullable=False)
25-
user_name = Column('user_name', VARCHAR(225), nullable=False)
25+
user_name = Column('user_name', VARCHAR(225))
26+
user_address = Column('user_address', VARCHAR(225))
2627
created_at = Column('created_at', TIMESTAMP(
2728
timezone=True), nullable=False, server_default=func.current_timestamp())
2829
service_id = Column('service_id', VARCHAR(225), nullable=False)
@@ -41,7 +42,7 @@ class UsageModel(Base):
4142
end_time = Column('end_time', TIMESTAMP(timezone=True))
4243
created_at = Column('created_at', TIMESTAMP(
4344
timezone=True), nullable=False, server_default=func.current_timestamp())
44-
45+
payment_mode = Column('payment_mode', VARCHAR(225))
4546
group_id = Column('group_id', VARCHAR(225))
4647
registry_address_key = Column('registry_address_key', VARCHAR(225))
4748
ethereum_json_rpc_endpoint = Column('ethereum_json_rpc_endpoint', VARCHAR(225))
@@ -56,6 +57,6 @@ class UsageModel(Base):
5657
user_address = Column('user_address', VARCHAR(225))
5758
user_name = Column('username', VARCHAR(225))
5859
org_id = Column('org_id', VARCHAR(225))
59-
service_id = Column('org_id', VARCHAR(225))
60+
service_id = Column('service_id', VARCHAR(225))
6061
resource = Column('resource', VARCHAR(225))
6162
request_id = Column('request_id', VARCHAR(225))

metering/repository/user_org_group_repository.py

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,26 @@
33

44

55
class UserOrgGroupRepository(BaseRepository):
6-
def get_user_org_group_data(self, payment_group_id, org_id, user_name, service_id, resource):
6+
7+
def get_user_org_group_id_by_username(self, username, org_id, service_id, resource):
78
session = self.get_default_session()
8-
user_org_query = session.query(UserOrgGroupModel) \
9-
.filter(UserOrgGroupModel.resource == resource) \
9+
user_org_query = session.query(UserOrgGroupModel).filter(UserOrgGroupModel.user_name == username) \
1010
.filter(UserOrgGroupModel.service_id == service_id) \
11-
.filter(UserOrgGroupModel.user_name == user_name) \
11+
.filter(UserOrgGroupModel.resource == resource) \
1212
.filter(UserOrgGroupModel.org_id == org_id)
1313

14-
if payment_group_id is not None:
15-
user_org_query = user_org_query.filter(
16-
UserOrgGroupModel.payment_group_id == payment_group_id)
14+
user_org_group_data = user_org_query.first()
15+
session.commit()
16+
session.flush()
17+
return user_org_group_data
1718

19+
def get_user_org_group_id_by_user_address(self, user_address, org_id, service_id, resource, payment_group_id):
20+
session = self.get_default_session()
21+
user_org_query = session.query(UserOrgGroupModel).filter(UserOrgGroupModel.user_address == user_address) \
22+
.filter(UserOrgGroupModel.service_id == service_id) \
23+
.filter(UserOrgGroupModel.resource == resource) \
24+
.filter(UserOrgGroupModel.org_id == org_id) \
25+
.filter(UserOrgGroupModel.payment_group_id == payment_group_id)
1826
user_org_group_data = user_org_query.first()
1927
session.commit()
2028
session.flush()

metering/serverless.yml

Lines changed: 20 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
plugins:
2-
- serverless-offline
3-
- serverless-python-requirements
41

52
service: metering
63

@@ -38,14 +35,14 @@ package:
3835
functions:
3936
get-freecalls:
4037
handler: handlers/freecall_handler.main
41-
role: ${file(./config.${self:provider.stage}.json):ROLE}
42-
vpc:
43-
securityGroupIds:
44-
- ${file(./config.${self:provider.stage}.json):SG1}
45-
- ${file(./config.${self:provider.stage}.json):SG2}
46-
subnetIds:
47-
- ${file(./config.${self:provider.stage}.json):VPC1}
48-
- ${file(./config.${self:provider.stage}.json):VPC2}
38+
# role: ${file(./config.${self:provider.stage}.json):ROLE}
39+
# vpc:
40+
# securityGroupIds:
41+
# - ${file(./config.${self:provider.stage}.json):SG1}
42+
# - ${file(./config.${self:provider.stage}.json):SG2}
43+
# subnetIds:
44+
# - ${file(./config.${self:provider.stage}.json):VPC1}
45+
# - ${file(./config.${self:provider.stage}.json):VPC2}
4946
# The following are a few example events you can configure
5047
# NOTE: Please make sure to change your handler code to work with those events
5148
# Check the event documentation for details
@@ -70,25 +67,25 @@ functions:
7067
- x-requested-with
7168
create-usage:
7269
handler: handlers.usage_handler.main
73-
role: ${file(./config.${self:provider.stage}.json):ROLE}
74-
vpc:
75-
securityGroupIds:
76-
- ${file(./config.${self:provider.stage}.json):SG1}
77-
- ${file(./config.${self:provider.stage}.json):SG2}
78-
subnetIds:
79-
- ${file(./config.${self:provider.stage}.json):VPC1}
80-
- ${file(./config.${self:provider.stage}.json):VPC2}
70+
# role: ${file(./config.${self:provider.stage}.json):ROLE}
71+
# vpc:
72+
# securityGroupIds:
73+
# - ${file(./config.${self:provider.stage}.json):SG1}
74+
# - ${file(./config.${self:provider.stage}.json):SG2}
75+
# subnetIds:
76+
# - ${file(./config.${self:provider.stage}.json):VPC1}
77+
# - ${file(./config.${self:provider.stage}.json):VPC2}
8178
# The following are a few example events you can configure
8279
# NOTE: Please make sure to change your handler code to work with those events
8380
# Check the event documentation for details
8481
events:
8582
- http:
8683
path: /usage
8784
method: post
88-
authorizer:
89-
type: request
90-
arn: ${file(./config.${self:provider.stage}.json):SIGN_AUTHORIZER}
91-
identitySource: ${file(./config.${self:provider.stage}.json):SIGN_HEADERS}
85+
# authorizer:
86+
# type: request
87+
# arn: ${file(./config.${self:provider.stage}.json):SIGN_AUTHORIZER}
88+
# identitySource: ${file(./config.${self:provider.stage}.json):SIGN_HEADERS}
9289
cors:
9390
origin: ${self:custom.origin.${self:provider.stage}}
9491
headers:

metering/services.py

Lines changed: 3 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55

66

77
def is_free_call(usage_details_dict):
8-
if not usage_details_dict['username'] or len(usage_details_dict['username']):
9-
return False
10-
return True
8+
if not usage_details_dict['payment_mode'] == 'free_call':
9+
return True
10+
return False
1111

1212

1313
class UsageService(object):
@@ -27,25 +27,5 @@ def get_free_call_details(self, username, org_id, service_id, group_id=None):
2727

2828
def save_usage_details(self, usage_details_dict):
2929
# nedd to introduce entities when we enhance feature to this service right now directly using dicts
30-
if is_free_call(usage_details_dict):
31-
channel_id = usage_details_dict['channel_id']
32-
group_id = usage_details_dict['group_id']
33-
username = APIUtilityService().get_user_name(channel_id, group_id)
34-
usage_details_dict['username'] = username
3530
self.storage_service.add_usage_data(usage_details_dict)
3631
return
37-
38-
39-
class APIUtilityService:
40-
41-
@staticmethod
42-
def get_user_name(channel_id, group_id):
43-
url = MARKETPLACE_CHANNEL_USER_URL.format(group_id, channel_id)
44-
response = requests.get(url)
45-
user_data = response.json()
46-
try:
47-
username = user_data[0]['username']
48-
except Exception as e:
49-
print(e)
50-
raise Exception("Failed to get username from marketplace")
51-
return username

metering/storage.py

Lines changed: 45 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,16 @@
1+
from constants import PAYMENT_MODE_FREE_CALL
12
from models import UserOrgGroupModel, UsageModel
23
from repository.org_service_config_repository import OrgServiceRepo
34
from repository.usage_repository import UsageRepository
45
from repository.user_org_group_repository import UserOrgGroupRepository
56

67

8+
def is_free_call(usage_details_dict):
9+
if not usage_details_dict['payment_mode'] == 'free_call':
10+
return True
11+
return False
12+
13+
714
class Storage(object):
815

916
# Interface to raad write data fom cache or database
@@ -16,38 +23,56 @@ def get_usage_details(self, username, org_id, service_id, group_id=None):
1623

1724

1825
class DatabaseStorage(Storage):
19-
usage_repo = UsageRepository()
20-
org_service_config_repo = OrgServiceRepo()
21-
user_org_group_repo = UserOrgGroupRepository()
2226

23-
def get_user_org_group(self, usage_details):
24-
user_org_group_repo_data = self.user_org_group_repo.get_user_org_group_data(
25-
payment_group_id=usage_details["group_id"],
26-
org_id=usage_details["organization_id"],
27-
user_name=usage_details["username"],
28-
service_id=usage_details["service_id"],
29-
resource=usage_details["service_method"]
30-
)
27+
def __init__(self):
28+
self.usage_repo = UsageRepository()
29+
self.org_service_config_repo = OrgServiceRepo()
30+
self.user_org_group_repo = UserOrgGroupRepository()
31+
32+
def get_user_org_group_id(self, usage_details):
3133

32-
return user_org_group_repo_data
34+
if usage_details['payment_mode'] == PAYMENT_MODE_FREE_CALL:
35+
user_org_group_id = self.user_org_group_repo.get_user_org_group_id_by_username(
36+
usage_details['username'],
37+
usage_details['organization_id'],
38+
usage_details['service_id'],
39+
usage_details['service_method']
40+
)
41+
elif usage_details['user_address'] is None:
42+
user_org_group_id = self.user_org_group_repo.get_user_org_group_id_by_user_address(
43+
usage_details['user_address'],
44+
usage_details['organization_id'],
45+
usage_details['service_id'],
46+
usage_details['service_method'],
47+
usage_details['group_id']
48+
)
49+
else:
50+
raise Exception('Unknown user request error')
51+
52+
if user_org_group_id is not None:
53+
return user_org_group_id.id
54+
return user_org_group_id
55+
56+
def add_user_org_group(self, username, user_address, service_id, group_id):
57+
pass
3358

3459
def add_usage_data(self, usage_details):
35-
existing_user_org_group_repo_data = self.get_user_org_group(
36-
usage_details)
60+
user_org_group_id = self.get_user_org_group_id(usage_details)
3761

38-
if existing_user_org_group_repo_data is None:
39-
print("existing_user_org_group_repo_data is None")
62+
if user_org_group_id is None:
63+
print(f"No user org group data found for user")
4064
new_user_org_record = UserOrgGroupModel(
4165
payment_group_id=usage_details["group_id"],
4266
org_id=usage_details["organization_id"],
4367
user_name=usage_details["username"],
68+
user_address=usage_details["user_address"],
4469
service_id=usage_details["service_id"],
4570
resource=usage_details["service_method"]
4671
)
4772
self.user_org_group_repo.create_item(new_user_org_record)
4873

49-
user_org_group_repo_data = self.get_user_org_group(usage_details)
50-
user_org_group_id = user_org_group_repo_data.id
74+
user_org_group_id = self.get_user_org_group_id(usage_details)
75+
5176
usage_record = UsageModel(
5277
client_type=usage_details['client_type'],
5378
ethereum_json_rpc_endpoint=usage_details['ethereum_json_rpc_endpoint'],
@@ -70,8 +95,7 @@ def add_usage_data(self, usage_details):
7095
user_name=usage_details["username"],
7196
service_id=usage_details["service_id"],
7297
resource=usage_details["service_method"],
73-
request_id=usage_details["request_id"],
74-
98+
request_id=usage_details["request_id"]
7599
)
76100
self.usage_repo.create_item(usage_record)
77101

@@ -82,4 +106,4 @@ def get_usage_details(self, user_name, org_id, service_id, group_id=None):
82106
org_id, service_id, optin_time)
83107
total_calls = self.usage_repo.get_total_calls(
84108
user_name, org_id, service_id)
85-
return total_calls, free_calls
109+
return total_calls, free_calls

metering/tests/test_total_calls.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ def test_success_usage_record(self):
5050
"error_message": "",
5151
"version": "v1.0.0",
5252
'username': 'user@snet',
53+
'payment_mode': 'freecall',
5354
"operation": "read",
5455
"usage_type": "apicall",
5556
"status": "success",
@@ -60,7 +61,8 @@ def test_success_usage_record(self):
6061
"client_type": None,
6162
"channel_id": None,
6263
"user_details": None,
63-
"user_agent": None
64+
"user_agent": None,
65+
"user_address": None
6466
})
6567

6668
self.storage_service.add_usage_data({
@@ -79,6 +81,7 @@ def test_success_usage_record(self):
7981
"error_message": "",
8082
"version": "v1.0.0",
8183
'username': 'user@snet',
84+
'payment_mode': 'freecall',
8285
"operation": "read",
8386
"usage_type": "apicall",
8487
"status": "failed",
@@ -89,7 +92,8 @@ def test_success_usage_record(self):
8992
"client_type": None,
9093
"channel_id": None,
9194
"user_details": None,
92-
"user_agent": None
95+
"user_agent": None,
96+
"user_address": None
9397
})
9498
self.assertEqual((1, 100), self.storage_service.get_usage_details(
9599
user_name='user@snet', org_id='snet', service_id='example-service'))

0 commit comments

Comments
 (0)