Skip to content
This repository has been archived by the owner on Mar 5, 2023. It is now read-only.

Commit

Permalink
Merge pull request #13 from oceanprotocol/feature/refactor-service-fa…
Browse files Browse the repository at this point in the history
…ctory

feature/refactor-service-factory
  • Loading branch information
ssallam authored Dec 2, 2019
2 parents b34a0ea + 7e7aeeb commit 308f7da
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 95 deletions.
2 changes: 1 addition & 1 deletion .bumpversion.cfg
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[bumpversion]
current_version = 0.3.1
current_version = 0.3.2
commit = True
tag = True

Expand Down
2 changes: 1 addition & 1 deletion ocean_utils/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
__version__ = '0.3.1'
__version__ = '0.3.2'

# Copyright 2018 Ocean Protocol Foundation
# SPDX-License-Identifier: Apache-2.0
29 changes: 28 additions & 1 deletion ocean_utils/agreements/service_agreement.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from ocean_utils.agreements.service_agreement_template import ServiceAgreementTemplate
from ocean_utils.agreements.service_types import ServiceTypes, ServiceTypesIndices
from ocean_utils.ddo.service import Service
from ocean_utils.did import did_to_id
from ocean_utils.utils.utilities import generate_prefixed_id

Agreement = namedtuple('Agreement', ('template', 'conditions'))
Expand Down Expand Up @@ -89,6 +90,33 @@ def as_dictionary(self):
attributes[ServiceAgreement.AGREEMENT_TEMPLATE] = self.service_agreement_template.template
return values

def _get_condition_param_map(self, keeper):
template_contract = keeper.get_contract(self.service_agreement_template.contract_name)
condition_contracts = [keeper.get_contract_by_address(cond_address)
for cond_address in template_contract.get_condition_types()]
condition_to_args = dict()
for cc in condition_contracts:
f_abis = {f.fn_name: f.abi for f in cc.contract.all_functions()}
condition_to_args[cc.CONTRACT_NAME] = [i['name'] for i in f_abis['fulfill']['inputs']]

return condition_to_args

def init_conditions_values(self, did, contract_name_to_address):
param_map = {
'_documentId': did_to_id(did),
'_amount': self.attributes['main']['price'],
'_rewardAddress': contract_name_to_address['EscrowReward']
}
conditions = self.conditions[:]
for cond in conditions:
for param in cond.parameters:
param.value = param_map.get(param.name, '')

if cond.timeout > 0:
cond.timeout = self.attributes['main']['timeout']

self.service_agreement_template.set_conditions(conditions)

def get_price(self):
"""
Return the price from the conditions parameters.
Expand Down Expand Up @@ -212,7 +240,6 @@ def generate_agreement_condition_ids(self, agreement_id, asset_id, consumer_addr
:param consumer_address: ethereum account address of consumer, hex str
:param publisher_address: ethereum account address of publisher, hex str
:param keeper:
:param template_type: type of template, currently only access and compute are supported
:return:
"""
lock_cond_id = keeper.lock_reward_condition.generate_id(
Expand Down
115 changes: 30 additions & 85 deletions ocean_utils/agreements/service_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
from ocean_utils.agreements.service_types import ServiceTypes, ServiceTypesIndices
from ocean_utils.agreements.utils import get_sla_template
from ocean_utils.ddo.service import Service
from ocean_utils.did import did_to_id


class ServiceDescriptor(object):
Expand Down Expand Up @@ -37,31 +36,37 @@ def authorization_service_descriptor(service_endpoint):
{'attributes': {'main': {}}, 'serviceEndpoint': service_endpoint})

@staticmethod
def access_service_descriptor(attributes, service_endpoint):
def access_service_descriptor(attributes, service_endpoint, template_id):
"""
Access service descriptor.
:param attributes: attributes of the access service, dict
:param service_endpoint: identifier of the service inside the asset DDO, str
:param template_id:
:return: Service descriptor.
"""
return (
ServiceTypes.ASSET_ACCESS,
{'attributes': attributes, 'serviceEndpoint': service_endpoint}
{'attributes': attributes,
'serviceEndpoint': service_endpoint,
'templateId': template_id}
)

@staticmethod
def compute_service_descriptor(attributes, service_endpoint):
def compute_service_descriptor(attributes, service_endpoint, template_id):
"""
Compute service descriptor.
:param attributes: attributes of the compute service, dict
:param service_endpoint: identifier of the service inside the asset DDO, str
:param template_id:
:return: Service descriptor.
"""
return (
ServiceTypes.CLOUD_COMPUTE,
{'attributes': attributes, 'serviceEndpoint': service_endpoint}
{'attributes': attributes,
'serviceEndpoint': service_endpoint,
'templateId': template_id}
)


Expand Down Expand Up @@ -114,12 +119,14 @@ def build_service(service_descriptor):
elif service_type == ServiceTypes.ASSET_ACCESS:
return ServiceFactory.build_access_service(
kwargs['attributes'],
kwargs['serviceEndpoint']
kwargs['serviceEndpoint'],
kwargs['templateId']
)
elif service_type == ServiceTypes.CLOUD_COMPUTE:
return ServiceFactory.build_compute_service(
kwargs['attributes'],
kwargs['serviceEndpoint']
kwargs['serviceEndpoint'],
kwargs['templateId']
)
raise ValueError(f'Unknown service type {service_type}')

Expand Down Expand Up @@ -152,111 +159,49 @@ def build_authorization_service(attributes, service_endpoint):
index=ServiceTypesIndices.DEFAULT_AUTHORIZATION_INDEX)

@staticmethod
def build_access_service(attributes, service_endpoint):
def build_access_service(attributes, service_endpoint, template_id):
"""
Build an authorization service.
:param attributes: attributes of access service, dict
:param service_endpoint: identifier of the service inside the asset DDO, str
:return: Service
"""
return Service(service_endpoint, ServiceTypes.ASSET_ACCESS,
attributes=attributes,
index=ServiceTypesIndices.DEFAULT_ACCESS_INDEX)

@staticmethod
def build_compute_service(attributes, service_endpoint):
:param template_id: hex str the ethereum smart contract address of the
service agreement template contract.
:return: ServiceAgreement instance
"""
Build an authorization service.
:param attributes: attributes of compute service, dict
:param service_endpoint: identifier of the service inside the asset DDO, str
:return: Service
"""
return Service(service_endpoint, ServiceTypes.CLOUD_COMPUTE,
attributes=attributes,
index=ServiceTypesIndices.DEFAULT_COMPUTING_INDEX)

@staticmethod
def complete_access_service(did, service_endpoint, attributes, template_id,
reward_contract_address):
"""
Build the access service.
:param did: DID, str
:param service_endpoint: identifier of the service inside the asset DDO, str
:param attributes: dict of main attributes in the service including `main` and
optionally `additionalInformation`
:param template_id: id of the template use to create the service, str
:param reward_contract_address: hex str ethereum address of deployed reward condition
smart contract
:return: ServiceAgreement
"""
param_map = {
'_documentId': did_to_id(did),
'_amount': attributes['main']['price'],
'_rewardAddress': reward_contract_address
}
sla_template_dict = get_sla_template()
sla_template = ServiceAgreementTemplate(
template_id, 'dataAssetAccessServiceAgreement',
attributes['main']['creator'], sla_template_dict
)
sla_template.template_id = template_id
conditions = sla_template.conditions[:]
for cond in conditions:
for param in cond.parameters:
param.value = param_map.get(param.name, '')

if cond.timeout > 0:
cond.timeout = attributes['main']['timeout']

sla_template.set_conditions(conditions)
sa = ServiceAgreement(
return ServiceAgreement(
attributes,
sla_template,
service_endpoint,
ServiceTypes.ASSET_ACCESS,
ServiceTypesIndices.DEFAULT_ACCESS_INDEX
)
return sa

@staticmethod
def complete_compute_service(did, service_endpoint, attributes, template_id,
reward_contract_address):
def build_compute_service(attributes, service_endpoint, template_id):
"""
Build the access service.
Build an authorization service.
:param did: DID, str
:param attributes: attributes of compute service, dict
:param service_endpoint: identifier of the service inside the asset DDO, str
:param template_id: id of the template use to create the service, str
:param reward_contract_address: hex str ethereum address of deployed reward condition
smart contract
:return: ServiceAgreement
:param template_id: hex str the ethereum smart contract address of the
service agreement template contract.
:return: ServiceAgreement instance
"""
param_map = {
'_documentId': did_to_id(did),
'_amount': attributes['main']['price'],
'_rewardAddress': reward_contract_address
}
sla_template_dict = get_sla_template(ServiceTypes.CLOUD_COMPUTE)
sla_template = ServiceAgreementTemplate(template_id, 'dataComputeServiceAgreement',
attributes['main']['creator'], sla_template_dict)
sla_template.template_id = template_id
conditions = sla_template.conditions[:]
for cond in conditions:
for param in cond.parameters:
param.value = param_map.get(param.name, '')

if cond.timeout > 0:
cond.timeout = attributes['main']['timeout']

sla_template.set_conditions(conditions)
sa = ServiceAgreement(
sla_template = ServiceAgreementTemplate(
template_id, 'dataComputeServiceAgreement',
attributes['main']['creator'], sla_template_dict
)
return ServiceAgreement(
attributes,
sla_template,
service_endpoint,
ServiceTypes.CLOUD_COMPUTE,
ServiceTypesIndices.DEFAULT_COMPUTING_INDEX
)
return sa
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,6 @@
test_suite='tests',
tests_require=test_requirements,
url='https://github.com/oceanprotocol/common-utils-py',
version='0.3.1',
version='0.3.2',
zip_safe=False,
)
14 changes: 8 additions & 6 deletions tests/ddo/test_ddo.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,19 +177,21 @@ def test_service_factory():

md_descriptor = ServiceDescriptor.metadata_service_descriptor(metadata, type_to_service[ServiceTypes.METADATA].service_endpoint)
access_service = type_to_service[ServiceTypes.ASSET_ACCESS]
access_descriptor = ServiceDescriptor.access_service_descriptor(access_service.attributes, access_service.service_endpoint)
compute_descriptor = ServiceDescriptor.compute_service_descriptor(access_service.attributes, access_service.service_endpoint)
access_descriptor = ServiceDescriptor.access_service_descriptor(access_service.attributes, access_service.service_endpoint, access_service.template_id)
compute_descriptor = ServiceDescriptor.compute_service_descriptor(access_service.attributes, access_service.service_endpoint, access_service.template_id)

services = ServiceFactory.build_services([md_descriptor, access_descriptor, compute_descriptor])
assert len(services) == 3
assert services[0].type == ServiceTypes.METADATA
assert services[1].type == ServiceTypes.ASSET_ACCESS
assert services[2].type == ServiceTypes.CLOUD_COMPUTE

keeper = Keeper.get_instance()
name_to_address = {name: i.address for name, i in keeper.contract_name_to_instance.items()}
s = services[1]
_access_service = ServiceFactory.complete_access_service(ddo.did, s.service_endpoint, s.attributes, access_service.template_id, '0x010101')
s.init_conditions_values(ddo.did, name_to_address)
s = services[2]
_compute_service = ServiceFactory.complete_compute_service(ddo.did, s.service_endpoint, s.attributes, access_service.template_id, '0x010101')
s.init_conditions_values(ddo.did, name_to_address)

assert isinstance(_access_service, ServiceAgreement)
assert isinstance(_compute_service, ServiceAgreement)
assert isinstance(services[1], ServiceAgreement)
assert isinstance(services[2], ServiceAgreement)

0 comments on commit 308f7da

Please sign in to comment.