Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue #426: get number of free calls allowed from the service metadata #427

Merged
merged 2 commits into from
Dec 5, 2019
Merged
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
89 changes: 47 additions & 42 deletions blockchain/serviceMetadata.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"math/big"
"strings"
)

/*
{
"version": 1,
Expand Down Expand Up @@ -57,50 +58,49 @@ import (
const IpfsPrefix = "ipfs://"

type ServiceMetadata struct {
Version int `json:"version"`
DisplayName string `json:"display_name"`
Encoding string `json:"encoding"`
ServiceType string `json:"service_type"`
Groups []OrganizationGroup `json:"groups"`
ModelIpfsHash string `json:"model_ipfs_hash"`
MpeAddress string `json:"mpe_address"`

multiPartyEscrowAddress common.Address
defaultPricing Pricing

defaultGroup OrganizationGroup

freeCallSignerAddress common.Address
isfreeCallAllowed bool
Version int `json:"version"`
DisplayName string `json:"display_name"`
Encoding string `json:"encoding"`
ServiceType string `json:"service_type"`
Groups []OrganizationGroup `json:"groups"`
ModelIpfsHash string `json:"model_ipfs_hash"`
MpeAddress string `json:"mpe_address"`

multiPartyEscrowAddress common.Address
defaultPricing Pricing

defaultGroup OrganizationGroup

freeCallSignerAddress common.Address
isfreeCallAllowed bool
freeCallsAllowed int
}

type OrganizationGroup struct {
Endpoints []string `json:"endpoints"`
GroupID string `json:"group_id"`
GroupName string `json:"group_name"`
Pricing []Pricing `json:"pricing"`
FreeCalls int `json:"free_calls"`
FreeCallSigner string `json:"free_call_signer_address"`
Endpoints []string `json:"endpoints"`
GroupID string `json:"group_id"`
GroupName string `json:"group_name"`
Pricing []Pricing `json:"pricing"`
FreeCalls int `json:"free_calls"`
FreeCallSigner string `json:"free_call_signer_address"`
}
type Pricing struct {
PriceModel string `json:"price_model"`
PriceInCogs *big.Int `json:"price_in_cogs,omitempty"`
PackageName string `json:"package_name,omitempty"`
Default bool `json:"default,omitempty"`
PriceModel string `json:"price_model"`
PriceInCogs *big.Int `json:"price_in_cogs,omitempty"`
PackageName string `json:"package_name,omitempty"`
Default bool `json:"default,omitempty"`
PricingDetails []PricingDetails `json:"details,omitempty"`
}

type PricingDetails struct {
ServiceName string `json:"service_name"`
ServiceName string `json:"service_name"`
MethodPricing []MethodPricing `json:"method_pricing"`
}
type MethodPricing struct {
MethodName string `json:"method_name"`
PriceInCogs *big.Int `json:"price_in_cogs"`
MethodName string `json:"method_name"`
PriceInCogs *big.Int `json:"price_in_cogs"`
}



func getRegistryAddressKey() common.Address {
address := config.GetRegistryAddress()
return common.HexToAddress(address)
Expand All @@ -121,7 +121,7 @@ func ServiceMetaData() *ServiceMetadata {
Panic("error on determining service metadata from file")
}
} else {
metadata = &ServiceMetadata{Encoding:"proto",ServiceType:"grpc"}
metadata = &ServiceMetadata{Encoding: "proto", ServiceType: "grpc"}
}
return metadata
}
Expand Down Expand Up @@ -188,16 +188,16 @@ func InitServiceMetaDataFromJson(jsonData string) (*ServiceMetadata, error) {
}

if err := setDerivedFields(metaData); err != nil {
return nil,err
return nil, err
}
if err := setFreeCallData(metaData) ; err != nil {
return nil,err
if err := setFreeCallData(metaData); err != nil {
return nil, err
}
return metaData, err
}

func setDerivedFields(metaData *ServiceMetadata) (err error) {
if err= setDefaultPricing(metaData); err != nil {
if err = setDefaultPricing(metaData); err != nil {
return err
}
setMultiPartyEscrowAddress(metaData)
Expand All @@ -211,23 +211,23 @@ func setGroup(metaData *ServiceMetadata) (err error) {
for _, group := range metaData.Groups {
if strings.Compare(group.GroupName, groupName) == 0 {
metaData.defaultGroup = group
return nil
return nil
}
}
err = fmt.Errorf("group name %v in config is invalid, "+
"there was no group found with this name in the metadata", groupName)
log.WithError(err)
return err
return err
}

func setDefaultPricing(metaData *ServiceMetadata) (err error) {
if err = setGroup(metaData);err != nil {
if err = setGroup(metaData); err != nil {
return err
}
for _, pricing := range metaData.defaultGroup.Pricing {
if pricing.Default {
metaData.defaultPricing = pricing
return nil
return nil
}
}
err = fmt.Errorf("MetaData does not have the default pricing set ")
Expand All @@ -240,10 +240,11 @@ func setMultiPartyEscrowAddress(metaData *ServiceMetadata) {
metaData.multiPartyEscrowAddress = common.HexToAddress(metaData.MpeAddress)
}

func setFreeCallData(metaData *ServiceMetadata) (error) {
func setFreeCallData(metaData *ServiceMetadata) error {

if (metaData.defaultGroup.FreeCalls > 0 ) {
if metaData.defaultGroup.FreeCalls > 0 {
metaData.isfreeCallAllowed = true
metaData.freeCallsAllowed = metaData.defaultGroup.FreeCalls
//If the signer address is not a valid address, then return back an error
if !common.IsHexAddress((metaData.defaultGroup.FreeCallSigner)) {
return fmt.Errorf("MetaData does not have 'free_call_signer_address defined correctly")
Expand Down Expand Up @@ -282,4 +283,8 @@ func (metaData *ServiceMetadata) GetDisplayName() string {

func (metaData *ServiceMetadata) IsFreeCallAllowed() bool {
return metaData.isfreeCallAllowed
}
}

func (metaData *ServiceMetadata) GetFreeCallsAllowed() int {
return metaData.freeCallsAllowed
}
44 changes: 32 additions & 12 deletions blockchain/serviceMetadata_test.go
Original file line number Diff line number Diff line change
@@ -1,40 +1,39 @@
package blockchain

import (
"github.com/ethereum/go-ethereum/common"
"github.com/singnet/snet-daemon/config"
"github.com/stretchr/testify/assert"
"math/big"
"strings"
"testing"

"github.com/ethereum/go-ethereum/common"
"github.com/singnet/snet-daemon/config"
"github.com/stretchr/testify/assert"
)

var testJsonData = "{ \"version\": 1, \"display_name\": \"Example1\", \"encoding\": \"grpc\", \"service_type\": \"grpc\", \"payment_expiration_threshold\": 40320, \"model_ipfs_hash\": \"Qmdiq8Hu6dYiwp712GtnbBxagyfYyvUY1HYqkH7iN76UCc\", " +
" \"mpe_address\": \"0x7E6366Fbe3bdfCE3C906667911FC5237Cc96BD08\", \"groups\": [ { \"free_calls\": 12, \"free_call_signer_address\": \"0x7DF35C98f41F3Af0df1dc4c7F7D4C19a71Dd059F\", \"endpoints\": [\"http://34.344.33.1:2379\",\"http://34.344.33.1:2389\"], \"group_id\": \"88ybRIg2wAx55mqVsA6sB4S7WxPQHNKqa4BPu/bhj+U=\",\"group_name\": \"default_group\", \"pricing\": [ { \"price_model\": \"fixed_price\", \"price_in_cogs\": 2 }, { \"package_name\": \"example_service\", \"price_model\": \"fixed_price_per_method\", \"default\":true, \"details\": [ { \"service_name\": \"Calculator\", \"method_pricing\": [ { \"method_name\": \"add\", \"price_in_cogs\": 2 }, { \"method_name\": \"sub\", \"price_in_cogs\": 1 }, { \"method_name\": \"div\", \"price_in_cogs\": 2 }, { \"method_name\": \"mul\", \"price_in_cogs\": 3 } ] }, { \"service_name\": \"Calculator2\", \"method_pricing\": [ { \"method_name\": \"add\", \"price_in_cogs\": 2 }, { \"method_name\": \"sub\", \"price_in_cogs\": 1 }, { \"method_name\": \"div\", \"price_in_cogs\": 3 }, { \"method_name\": \"mul\", \"price_in_cogs\": 2 } ] } ] }] }, { \"endpoints\": [\"http://97.344.33.1:2379\",\"http://67.344.33.1:2389\"], \"group_id\": \"99ybRIg2wAx55mqVsA6sB4S7WxPQHNKqa4BPu/bhj+U=\", \"pricing\": [ { \"package_name\": \"example_service\", \"price_model\": \"fixed_price_per_method\", \"details\": [ { \"service_name\": \"Calculator\", \"method_pricing\": [ { \"method_name\": \"add\", \"price_in_cogs\": 2 }, { \"method_name\": \"sub\", \"price_in_cogs\": 1 }, { \"method_name\": \"div\", \"price_in_cogs\": 2 }, { \"method_name\": \"mul\", \"price_in_cogs\": 3 } ] }, { \"service_name\": \"Calculator2\", \"method_pricing\": [ { \"method_name\": \"add\", \"price_in_cogs\": 2 }, { \"method_name\": \"sub\", \"price_in_cogs\": 1 }, { \"method_name\": \"div\", \"price_in_cogs\": 3 }, { \"method_name\": \"mul\", \"price_in_cogs\": 2 } ] } ] }] } ] } "

func TestAllGetterMethods(t *testing.T) {
config.Vip().Set(config.FreeCallEndPoint,"http://demo8325345.mockable.io")
config.Vip().Set(config.FreeCallEndPoint, "http://demo8325345.mockable.io")
anandrgitnirman marked this conversation as resolved.
Show resolved Hide resolved
metaData, err := InitServiceMetaDataFromJson(testJsonData)
assert.Equal(t, err, nil)

assert.Equal(t, metaData.GetVersion(), 1)
assert.Equal(t, metaData.GetDisplayName(), "Example1")
assert.Equal(t, metaData.GetServiceType(), "grpc")
assert.Equal(t, metaData.GetWireEncoding(), "grpc")
assert.Nil(t,metaData.GetDefaultPricing().PriceInCogs)
assert.Nil(t, metaData.GetDefaultPricing().PriceInCogs)
assert.Equal(t, metaData.GetDefaultPricing().PricingDetails[0].MethodPricing[0].PriceInCogs, big.NewInt(2))
assert.Equal(t, metaData.GetMpeAddress(), common.HexToAddress("0x7E6366Fbe3bdfCE3C906667911FC5237Cc96BD08"))
assert.Equal(t, metaData.FreeCallSignerAddress(), common.HexToAddress("0x7DF35C98f41F3Af0df1dc4c7F7D4C19a71Dd059F"))
assert.True(t, metaData.IsFreeCallAllowed())


assert.Equal(t, 12, metaData.GetFreeCallsAllowed())

}


func TestInitServiceMetaDataFromJson(t *testing.T) {
//Parse Bad JSON
_, err := InitServiceMetaDataFromJson(strings.Replace(testJsonData, "{", "", 1))
_, err := InitServiceMetaDataFromJson(strings.Replace(testJsonData, "{", "", 1))
if err != nil {
assert.Equal(t, err.Error(), "invalid character ':' after top-level value")
}
Expand All @@ -44,18 +43,39 @@ func TestInitServiceMetaDataFromJson(t *testing.T) {
if err != nil {
assert.Equal(t, err.Error(), "MetaData does not have 'free_call_signer_address defined correctly")
}
config.Vip().Set(config.FreeCallEndPoint,"badurl")
_, err = InitServiceMetaDataFromJson(strings.Replace(testJsonData, "default_pricing", "dummy", 1))
if err != nil {
assert.Equal(t, err.Error(), "MetaData does not have the default pricing set ")
}
config.Vip().Set(config.FreeCallEndPoint, "badurl")
_, err = InitServiceMetaDataFromJson(testJsonData)
if err != nil {
assert.Equal(t, err.Error(), "Please specify a valid end point for 'free_call_end_point' tracking usage of free calls ")
}
}

func TestReadServiceMetaDataFromLocalFile(t *testing.T) {


metadata, err := ReadServiceMetaDataFromLocalFile("../service_metadata.json")
assert.Equal(t, err, nil)
assert.Equal(t, metadata.Version, 1)
}

func Test_getServiceMetaDataUrifromRegistry(t *testing.T) {
assert.Panics(t, func() { getServiceMetaDataUrifromRegistry() })
config.Vip().Set(config.BlockChainNetworkSelected, "ropsten")
config.Validate()
assert.Panics(t, func() { getServiceMetaDataUrifromRegistry() })

}

func Test_setDefaultPricing(t *testing.T) {
err := setDefaultPricing(&ServiceMetadata{})
assert.NotNil(t, err)
err = setDefaultPricing(&ServiceMetadata{Groups: []OrganizationGroup{{GroupName: "default_group"}}})
assert.Equal(t, err.Error(), "MetaData does not have the default pricing set ")
}

func Test_setGroup(t *testing.T) {
err := setGroup(&ServiceMetadata{})
assert.Equal(t, err.Error(), "group name default_group in config is invalid, there was no group found with this name in the metadata")
}