-
Notifications
You must be signed in to change notification settings - Fork 52
/
Copy pathorginzationMetadata.go
233 lines (203 loc) · 7.97 KB
/
orginzationMetadata.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
package blockchain
import (
"encoding/json"
"fmt"
"github.com/ethereum/go-ethereum/common"
"github.com/singnet/snet-daemon/config"
"github.com/singnet/snet-daemon/ipfsutils"
log "github.com/sirupsen/logrus"
"math/big"
"strings"
"time"
)
/*
This metadata structure defines the organization to group mappings.
Please note , that groups are logical bucketing of managing payments ( same recipient for each group across the services in an organization)
A given Organization will be associated with multiple groups and every group will be associated to a payment
Sample example of the JSON structure from the block chain is given below .
Please note that all the services that belong to a given group in an organization will have the same recipient address.
*/
/*
{
"org_name": "organization_name",
"org_id": "org_id1",
"groups": [
{
"group_name": "default_group2",
"group_id": "99ybRIg2wAx55mqVsA6sB4S7WxPQHNKqa4BPu/bhj+U=",
"payment": {
"payment_address": "0x671276c61943A35D5F230d076bDFd91B0c47bF09",
"payment_expiration_threshold": 40320,
"payment_channel_storage_type": "etcd",
"payment_channel_storage_client": {
"connection_timeout": "5s",
"request_timeout": "3s",
"endpoints": [
"http://127.0.0.1:2379"
]
}
}
},
{
"group_name": "default_group2",
"group_id": "99ybRIg2wAx55mqVsA6sB4S7WxPQHNKqa4BPu/bhj+U=",
"payment": {
"payment_address": "0x671276c61943A35D5F230d076bDFd91B0c47bF09",
"payment_expiration_threshold": 40320,
"payment_channel_storage_type": "etcd",
"payment_channel_storage_client": {
"connection_timeout": "5s",
"request_timeout": "3s",
"endpoints": [
"http://127.0.0.1:2379"
]
}
}
}
]
}*/
type OrganizationMetaData struct {
OrgName string `json:"org_name"`
OrgID string `json:"org_id"`
Groups []Group `json:"groups"`
//This will used to determine which group the daemon belongs to
daemonGroup *Group
daemonGroupID [32]byte
recipientPaymentAddress common.Address
}
type Payment struct {
PaymentAddress string `json:"payment_address"`
PaymentExpirationThreshold *big.Int `json:"payment_expiration_threshold"`
PaymentChannelStorageType string `json:"payment_channel_storage_type"`
PaymentChannelStorageClient PaymentChannelStorageClient `json:"payment_channel_storage_client"`
}
//Structure to hold the individual group details , an Organization can have multiple groups
type Group struct {
GroupName string `json:"group_name"`
GroupID string `json:"group_id"`
PaymentDetails Payment `json:"payment"`
}
//Structure to hold the storage details of the payment
type PaymentChannelStorageClient struct {
ConnectionTimeout string `json:"connection_timeout" mapstructure:"connection_timeout"`
RequestTimeout string `json:"request_timeout" mapstructure:"request_timeout"`
Endpoints []string `json:"endpoints"`
}
//Construct the Organization metadata from the JSON Passed
func InitOrganizationMetaDataFromJson(jsonData string) (metaData *OrganizationMetaData, err error) {
metaData = new(OrganizationMetaData)
err = json.Unmarshal([]byte(jsonData), &metaData)
if err != nil {
log.WithError(err).WithField("jsondata", jsonData)
return nil, err
}
//Check for mandatory validations
if err = setDerivedAttributes(metaData); err != nil {
log.WithError(err)
return nil, err
}
if err = checkMandatoryFields(metaData); err != nil {
return nil,err
}
return metaData, nil
}
func checkMandatoryFields(metaData *OrganizationMetaData) (err error ){
if metaData.daemonGroup.PaymentDetails.PaymentChannelStorageClient.Endpoints == nil {
err = fmt.Errorf("Mandatory field : ETCD Client Endpoints are mising for the Group %v ",metaData.daemonGroup.GroupName)
}
if &metaData.recipientPaymentAddress == nil {
err = fmt.Errorf("Mandatory field : Recepient Address is missing for the Group %v ",metaData.daemonGroup.GroupName)
}
return
}
func setDerivedAttributes(metaData *OrganizationMetaData) (err error) {
if metaData.daemonGroup, err = getDaemonGroup(*metaData); err != nil {
return err
}
metaData.daemonGroupID, err = ConvertBase64Encoding(metaData.daemonGroup.GroupID)
//use the checksum address ( convert the address in to a checksum address and set it back)
metaData.daemonGroup.PaymentDetails.PaymentAddress = ToChecksumAddress(metaData.daemonGroup.PaymentDetails.PaymentAddress)
metaData.recipientPaymentAddress = common.HexToAddress(metaData.daemonGroup.PaymentDetails.PaymentAddress)
return err
}
//Determine the group this Daemon belongs to
func getDaemonGroup(metaData OrganizationMetaData) (group *Group, err error) {
groupName := config.GetString(config.DaemonGroupName)
for _, group := range metaData.Groups {
if strings.Compare(group.GroupName, groupName) == 0 {
return &group, 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 nil, err
}
//Will be used to load the Organization metadata when Daemon starts
//To be part of components
func GetOrganizationMetaData() *OrganizationMetaData {
var metadata *OrganizationMetaData
var err error
if config.GetBool(config.BlockchainEnabledKey) {
ipfsHash := string(getMetaDataURI())
metadata, err = GetOrganizationMetaDataFromIPFS(FormatHash(ipfsHash))
} else {
metadata = &OrganizationMetaData{daemonGroup:&Group{}}
}
if err != nil {
log.WithError(err).
Panic("error on retrieving / parsing organization metadata from block chain")
}
return metadata
}
func GetOrganizationMetaDataFromIPFS(hash string) (*OrganizationMetaData, error) {
jsondata := ipfsutils.GetIpfsFile(hash)
return InitOrganizationMetaDataFromJson(jsondata)
}
func getMetaDataURI() []byte {
//Block chain call here to get the hash of the metadata for the given Organization
reg := getRegistryCaller()
orgId := StringToBytes32(config.GetString(config.OrganizationId))
organizationRegistered, err := reg.GetOrganizationById(nil, orgId)
if err != nil || !organizationRegistered.Found {
log.WithError(err).WithField("OrganizationId", config.GetString(config.OrganizationId)).
Panic("Error Retrieving contract details for the Given Organization")
}
return organizationRegistered.OrgMetadataURI[:]
}
//Get the Group ID the Daemon needs to associate itself to , requests belonging to a different group if will be rejected
func (metaData OrganizationMetaData) GetGroupIdString() string {
return metaData.daemonGroup.GroupID
}
// Return the group id in bytes
func (metaData OrganizationMetaData) GetGroupId() [32]byte {
return metaData.daemonGroupID
}
//Pass the group Name and retrieve the details of the payment address/ recipient address.
func (metaData OrganizationMetaData) GetPaymentAddress() common.Address {
return metaData.recipientPaymentAddress
}
//Payment expiration threshold
func (metaData *OrganizationMetaData) GetPaymentExpirationThreshold() *big.Int {
return metaData.daemonGroup.PaymentDetails.PaymentExpirationThreshold
}
//Get the End points of the Payment Storage used to update the storage state
func (metaData OrganizationMetaData) GetPaymentStorageEndPoints() []string {
return metaData.daemonGroup.PaymentDetails.PaymentChannelStorageClient.Endpoints
}
//Get the connection time out defined
func (metaData OrganizationMetaData) GetConnectionTimeOut() ( connectionTimeOut time.Duration) {
connectionTimeOut, err := time.ParseDuration(metaData.daemonGroup.PaymentDetails.PaymentChannelStorageClient.ConnectionTimeout);
if err != nil {
log.Errorf(err.Error())
}
return connectionTimeOut
}
//Get the Request time out defined
func (metaData OrganizationMetaData) GetRequestTimeOut() time.Duration {
timeOut, err := time.ParseDuration(metaData.daemonGroup.PaymentDetails.PaymentChannelStorageClient.RequestTimeout);
if err != nil {
log.Errorf(err.Error())
}
return timeOut
}