-
Notifications
You must be signed in to change notification settings - Fork 0
/
exporter.go
108 lines (97 loc) · 3.18 KB
/
exporter.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
/*
* Copyright 2019 Insolar Technologies
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package api
import (
"context"
"net/http"
"strings"
jsonrpc "github.com/gorilla/rpc/v2/json2"
"github.com/insolar/insolar/core"
"github.com/pkg/errors"
)
const (
errCodePulseNotFound = 10404
)
// StorageExporterArgs is arguments that StorageExporter service accepts.
type StorageExporterArgs struct {
From uint32
Size int
}
// StorageExporterReply is reply for StorageExporter service requests.
type StorageExporterReply = core.StorageExportResult
// StorageExporterService is a service that provides API for exporting storage data.
type StorageExporterService struct {
runner *Runner
}
// NewStorageExporterService creates new StorageExporter service instance.
func NewStorageExporterService(runner *Runner) *StorageExporterService {
return &StorageExporterService{runner: runner}
}
// Export returns data view from storage.
//
// Request structure:
// {
// "jsonrpc": "2.0",
// "method": "exporter.Export",
// "params": {
// // Pulse number from which data load should start.
// // If less than first pulse, the load will start from the first pulse (e.i. use "0" to load from the beginning).
// "From": int,
// // Number of pulses to load.
// "Size": int
// },
// "id": str|int|null
// }
//
// Response structure:
// {
// "Data": {
// [pulse number]: [{
// "Records": {
// [record ID]: {
// "Type": str, // Constant record type.
// "Data": { ... }, // Structured record data.
// "Payload": { ... }|null // Additional data related to the record (e.g. Object's memory).
// }
// },
// "Pulse": {
// "PulseNumber": int, // Pulse number. Same as parent key.
// },
// "JetID": string,
// }],
// "NextFrom": int|null, // Pulse number from which to start next batch. Put it as "From" param for next incremental fetch.
// "Size": int // Number of returned pulses (length of the "Data" dictionary).
// }
//
func (s *StorageExporterService) Export(r *http.Request, args *StorageExporterArgs, reply *StorageExporterReply) error {
exp := s.runner.StorageExporter
ctx := context.TODO()
result, err := exp.Export(ctx, core.PulseNumber(args.From), args.Size)
if err != nil {
if strings.Contains(err.Error(), "failed to fetch pulse data") {
return &jsonrpc.Error{
Code: errCodePulseNotFound,
Message: "[ Export ]: " + err.Error(),
Data: nil,
}
}
return errors.Wrap(err, "[ Export ]")
}
reply.Data = result.Data
reply.Size = result.Size
reply.NextFrom = result.NextFrom
return nil
}