-
Notifications
You must be signed in to change notification settings - Fork 0
/
store.go
142 lines (121 loc) · 4.87 KB
/
store.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
/*
Copyright IBM Corp. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package privdata
import (
"fmt"
"github.com/golang/protobuf/proto"
"github.com/hyperledger/fabric/core/ledger"
"github.com/hyperledger/fabric/msp"
"github.com/hyperledger/fabric/protos/common"
"github.com/pkg/errors"
)
// Support is an interface used to inject dependencies
type Support interface {
// GetQueryExecutorForLedger returns a query executor for the specified channel
GetQueryExecutorForLedger(cid string) (ledger.QueryExecutor, error)
// GetIdentityDeserializer returns an IdentityDeserializer
// instance for the specified chain
GetIdentityDeserializer(chainID string) msp.IdentityDeserializer
}
// StateGetter retrieves data from the state
type State interface {
// GetState retrieves the value for the given key in the given namespace
GetState(namespace string, key string) ([]byte, error)
}
type NoSuchCollectionError common.CollectionCriteria
func (f NoSuchCollectionError) Error() string {
return fmt.Sprintf("collection %s/%s/%s could not be found", f.Channel, f.Namespace, f.Collection)
}
type simpleCollectionStore struct {
s Support
}
// NewSimpleCollectionStore returns a collection stored backed
// by a ledger supplied by the specified ledgerGetter with
// an internal name formed as specified by the supplied
// collectionNamer function
func NewSimpleCollectionStore(s Support) CollectionStore {
return &simpleCollectionStore{s}
}
func (c *simpleCollectionStore) retrieveCollectionConfigPackage(cc common.CollectionCriteria) (*common.CollectionConfigPackage, error) {
qe, err := c.s.GetQueryExecutorForLedger(cc.Channel)
if err != nil {
return nil, errors.WithMessage(err, fmt.Sprintf("could not retrieve query executor for collection criteria %#v", cc))
}
defer qe.Done()
return RetrieveCollectionConfigPackageFromState(cc, qe)
}
// RetrieveCollectionConfigPackageFromState retrieves the collection config package from the given key from the given state
func RetrieveCollectionConfigPackageFromState(cc common.CollectionCriteria, state State) (*common.CollectionConfigPackage, error) {
cb, err := state.GetState("lscc", BuildCollectionKVSKey(cc.Namespace))
if err != nil {
return nil, errors.WithMessage(err, fmt.Sprintf("error while retrieving collection for collection criteria %#v", cc))
}
if cb == nil {
return nil, NoSuchCollectionError(cc)
}
conf, err := ParseCollectionConfig(cb)
if err != nil {
return nil, errors.Wrapf(err, "invalid configuration for collection criteria %#v", cc)
}
return conf, nil
}
// ParseCollectionConfig parses the collection configuration from the given serialized representation
func ParseCollectionConfig(colBytes []byte) (*common.CollectionConfigPackage, error) {
collections := &common.CollectionConfigPackage{}
err := proto.Unmarshal(colBytes, collections)
if err != nil {
return nil, errors.WithStack(err)
}
return collections, nil
}
func (c *simpleCollectionStore) retrieveCollectionConfig(cc common.CollectionCriteria) (*common.StaticCollectionConfig, error) {
collections, err := c.retrieveCollectionConfigPackage(cc)
if err != nil {
return nil, err
}
if collections == nil {
return nil, nil
}
for _, cconf := range collections.Config {
switch cconf := cconf.Payload.(type) {
case *common.CollectionConfig_StaticCollectionConfig:
if cconf.StaticCollectionConfig.Name == cc.Collection {
return cconf.StaticCollectionConfig, nil
}
default:
return nil, errors.New("unexpected collection type")
}
}
return nil, NoSuchCollectionError(cc)
}
func (c *simpleCollectionStore) retrieveSimpleCollection(cc common.CollectionCriteria) (*SimpleCollection, error) {
staticCollectionConfig, err := c.retrieveCollectionConfig(cc)
if err != nil {
return nil, err
}
sc := &SimpleCollection{}
err = sc.Setup(staticCollectionConfig, c.s.GetIdentityDeserializer(cc.Channel))
if err != nil {
return nil, errors.WithMessage(err, fmt.Sprintf("error setting up collection for collection criteria %#v", cc))
}
return sc, nil
}
func (c *simpleCollectionStore) RetrieveCollection(cc common.CollectionCriteria) (Collection, error) {
return c.retrieveSimpleCollection(cc)
}
func (c *simpleCollectionStore) RetrieveCollectionAccessPolicy(cc common.CollectionCriteria) (CollectionAccessPolicy, error) {
return c.retrieveSimpleCollection(cc)
}
func (c *simpleCollectionStore) RetrieveCollectionConfigPackage(cc common.CollectionCriteria) (*common.CollectionConfigPackage, error) {
return c.retrieveCollectionConfigPackage(cc)
}
// RetrieveCollectionPersistenceConfigs retrieves the collection's persistence related configurations
func (c *simpleCollectionStore) RetrieveCollectionPersistenceConfigs(cc common.CollectionCriteria) (CollectionPersistenceConfigs, error) {
staticCollectionConfig, err := c.retrieveCollectionConfig(cc)
if err != nil {
return nil, err
}
return &SimpleCollectionPersistenceConfigs{staticCollectionConfig.BlockToLive}, nil
}