-
Notifications
You must be signed in to change notification settings - Fork 111
Expand file tree
/
Copy pathstore.go
More file actions
183 lines (150 loc) · 6.42 KB
/
Copy pathstore.go
File metadata and controls
183 lines (150 loc) · 6.42 KB
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
/*
Copyright IBM Corp. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package endorserdb
import (
"context"
"reflect"
"github.com/LFDT-Panurus/panurus/token"
driver2 "github.com/LFDT-Panurus/panurus/token/driver"
"github.com/LFDT-Panurus/panurus/token/services/logging"
"github.com/LFDT-Panurus/panurus/token/services/storage/db"
"github.com/LFDT-Panurus/panurus/token/services/storage/db/common"
dbdriver "github.com/LFDT-Panurus/panurus/token/services/storage/db/driver"
"github.com/LFDT-Panurus/panurus/token/services/storage/db/multiplexed"
"github.com/hyperledger-labs/fabric-smart-client/pkg/utils/errors"
)
//go:generate counterfeiter -o mock/endorser_store_service_manager.go --fake-name EndorserStoreServiceManager . StoreServiceManager
type StoreServiceManager db.StoreServiceManager[*StoreService]
var (
managerType = reflect.TypeFor[*StoreServiceManager]()
logger = logging.MustGetLogger()
)
func NewStoreServiceManager(cp db.ConfigService, drivers multiplexed.Driver) StoreServiceManager {
return db.NewStoreServiceManager(cp, "endorserdb.persistence", drivers.NewEndorser, newStoreService)
}
func GetByTMSId(sp token.ServiceProvider, tmsID token.TMSID) (*StoreService, error) {
s, err := sp.GetService(managerType)
if err != nil {
return nil, errors.Wrapf(err, "failed to get manager service")
}
c, err := s.(StoreServiceManager).StoreServiceByTMSId(tmsID)
if err != nil {
return nil, errors.Wrapf(err, "failed to get db for tms [%s]", tmsID)
}
return c, nil
}
// TxStatus is the status of a transaction
type TxStatus = dbdriver.TxStatus
const (
// Unknown is the status of a transaction that is unknown
Unknown = dbdriver.Unknown
// Pending is the status of a transaction that has been submitted to the ledger
Pending = dbdriver.Pending
// Confirmed is the status of a transaction that has been confirmed by the ledger
Confirmed = dbdriver.Confirmed
// Deleted is the status of a transaction that has been deleted due to a failure to commit
Deleted = dbdriver.Deleted
// Orphan is the status of a transaction that never reached the ledger
Orphan = dbdriver.Orphan
)
// TxStatusMessage maps TxStatus to string
var TxStatusMessage = dbdriver.TxStatusMessage
// ValidationRecord is a record that contains information about the validation of a given token request
type ValidationRecord = dbdriver.ValidationRecord
// ValidationRecordsIterator is an iterator over validation records
type ValidationRecordsIterator struct {
it dbdriver.ValidationRecordsIterator
}
// Close closes the iterator. It must be called when done with the iterator.
func (t *ValidationRecordsIterator) Close() {
t.it.Close()
}
// Next returns the next validation record, if any.
// It returns nil, nil if there are no more records.
func (t *ValidationRecordsIterator) Next() (*ValidationRecord, error) {
next, err := t.it.Next()
if err != nil {
return nil, err
}
if next == nil {
return nil, nil
}
return next, nil
}
// QueryValidationRecordsParams defines the parameters for querying validation records
type QueryValidationRecordsParams = dbdriver.QueryValidationRecordsParams
// StoreService is a database that stores token transaction endorsement validation records
type StoreService struct {
*common.StatusSupport
db dbdriver.EndorserStore
}
func newStoreService(p dbdriver.EndorserStore) (*StoreService, error) {
return &StoreService{
StatusSupport: common.NewStatusSupport(),
db: p,
}, nil
}
// ValidationRecords returns an iterator of validation records filtered by the given params.
func (d *StoreService) ValidationRecords(ctx context.Context, params QueryValidationRecordsParams) (*ValidationRecordsIterator, error) {
it, err := d.db.QueryValidations(ctx, params)
if err != nil {
return nil, errors.Wrapf(err, "failed to query validation records")
}
return &ValidationRecordsIterator{it: it}, nil
}
// AppendValidationRecord appends the given validation metadata related to the given transaction id
func (d *StoreService) AppendValidationRecord(ctx context.Context, txID string, tokenRequest []byte, meta map[string][]byte, ppHash driver2.PPHash) error {
logger.DebugfContext(ctx, "appending new validation record... [%s]", txID)
w, err := d.db.NewEndorserStoreTransaction()
if err != nil {
return errors.WithMessagef(err, "begin update for txid [%s] failed", txID)
}
// Store the token request directly in the validation record
if err := w.AddValidationRecord(ctx, txID, tokenRequest, meta, ppHash); err != nil {
w.Rollback()
return errors.WithMessagef(err, "append validation record for txid [%s] failed", txID)
}
if err := w.Commit(); err != nil {
return errors.WithMessagef(err, "append validation record commit for txid [%s] failed", txID)
}
logger.DebugfContext(ctx, "appending validation record completed without errors")
return nil
}
// SetStatus sets the status of the validation record with the passed transaction id to the passed status
func (d *StoreService) SetStatus(ctx context.Context, txID string, status dbdriver.TxStatus, message string) error {
logger.DebugfContext(ctx, "set status [%s][%s]...", txID, status)
w, err := d.db.NewEndorserStoreTransaction()
if err != nil {
return errors.WithMessagef(err, "begin update for txid [%s] failed", txID)
}
if err := w.SetStatus(ctx, txID, status, message); err != nil {
w.Rollback()
return errors.Wrapf(err, "failed setting status [%s][%s]", txID, dbdriver.TxStatusMessage[status])
}
// No Rollback() here: once Commit() fails the driver transaction is already finalized, so
// rolling back is a guaranteed no-op. This matches AppendValidationRecord above and ttxdb.
if err := w.Commit(); err != nil {
return errors.Wrapf(err, "failed committing status [%s][%s]", txID, dbdriver.TxStatusMessage[status])
}
// notify the listeners
d.Notify(common.StatusEvent{
Ctx: ctx,
TxID: txID,
ValidationCode: status,
})
logger.DebugfContext(ctx, "set status [%s][%s] done", txID, dbdriver.TxStatusMessage[status])
return nil
}
// GetStatus return the status of the given transaction id.
// It returns an error if no transaction with that id is found
func (d *StoreService) GetStatus(ctx context.Context, txID string) (TxStatus, string, error) {
logger.DebugfContext(ctx, "get status [%s]...", txID)
status, message, err := d.db.GetStatus(ctx, txID)
if err != nil {
return Unknown, "", errors.Wrapf(err, "failed getting status [%s]", txID)
}
logger.DebugfContext(ctx, "got status [%s][%s]", txID, status)
return status, message, nil
}