-
Notifications
You must be signed in to change notification settings - Fork 139
/
Copy pathdiagnostic_doc_api.go
132 lines (115 loc) · 3.78 KB
/
diagnostic_doc_api.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
/*
Copyright 2024-Present Couchbase, Inc.
Use of this software is governed by the Business Source License included in
the file licenses/BSL-Couchbase.txt. As of the Change Date specified in that
file, in accordance with the Business Source License, use of this software will
be governed by the Apache License, Version 2.0, included in the file
licenses/APL2.txt.
*/
package rest
import (
"fmt"
"net/http"
"github.com/couchbase/sync_gateway/auth"
"github.com/couchbase/sync_gateway/base"
"github.com/couchbase/sync_gateway/channels"
"github.com/couchbase/sync_gateway/db"
)
type SyncFnDryRun struct {
Channels base.Set `json:"channels"`
Access channels.AccessMap `json:"access"`
Roles channels.AccessMap `json:"roles"`
Exception string `json:"exception"`
Expiry *uint32 `json:"expiry,omitempty"`
}
type ImportFilterDryRun struct {
ShouldImport bool `json:"shouldImport"`
Error string `json:"error"`
}
func populateDocChannelInfo(doc db.Document) map[string][]auth.GrantHistorySequencePair {
resp := make(map[string][]auth.GrantHistorySequencePair, len(doc.Channels))
for _, chanSetInfo := range doc.SyncData.ChannelSet {
resp[chanSetInfo.Name] = append(resp[chanSetInfo.Name], auth.GrantHistorySequencePair{StartSeq: chanSetInfo.Start, EndSeq: chanSetInfo.End})
}
for _, hist := range doc.SyncData.ChannelSetHistory {
resp[hist.Name] = append(resp[hist.Name], auth.GrantHistorySequencePair{StartSeq: hist.Start, EndSeq: hist.End, Compacted: hist.Compacted})
continue
}
return resp
}
// HTTP handler for a GET of a document's channels and their sequence spans
func (h *handler) handleGetDocChannels() error {
docid := h.PathVar("docid")
doc, err := h.collection.GetDocument(h.ctx(), docid, db.DocUnmarshalSync)
if err != nil {
return err
}
if doc == nil {
return kNotFoundError
}
resp := populateDocChannelInfo(*doc)
h.writeJSON(resp)
return nil
}
// HTTP handler for running a document through the sync function and returning the results
// body only provided, the sync function will run with no oldDoc provided
// body and doc ID provided, the sync function will run using the current revision in the bucket as oldDoc
// docid only provided, the sync function will run using the current revision in the bucket as doc
// If docid is specified and the document does not exist in the bucket, it will return error
func (h *handler) handleSyncFnDryRun() error {
docid := h.getQuery("doc_id")
body, err := h.readDocument()
if err != nil {
if docid == "" {
return fmt.Errorf("no doc id provided for dry run and error reading body: %s", err)
}
}
output, err, syncFnErr := h.collection.SyncFnDryrun(h.ctx(), body, docid)
if err != nil {
return err
}
if syncFnErr != nil {
resp := SyncFnDryRun{
Exception: syncFnErr.Error(),
}
h.writeJSON(resp)
return nil
}
errorMsg := ""
if output.Rejection != nil {
errorMsg = output.Rejection.Error()
}
resp := SyncFnDryRun{
output.Channels,
output.Access,
output.Roles,
errorMsg,
output.Expiry,
}
h.writeJSON(resp)
return nil
}
// HTTP handler for running a document through the import filter and returning the results
func (h *handler) handleImportFilterDryRun() error {
docid := h.getQuery("doc_id")
body, err := h.readDocument()
if err != nil {
if docid == "" {
return fmt.Errorf("Error reading body: %s, no doc id provided for dry run", err)
}
}
if docid != "" && body != nil {
return base.HTTPErrorf(http.StatusBadRequest, "doc body and doc id provided. Please provide either the body or a doc id for the import filter dry run")
}
shouldImport, err := h.collection.ImportFilterDryRun(h.ctx(), body, docid)
errorMsg := ""
if err != nil {
errorMsg = err.Error()
}
resp := ImportFilterDryRun{
shouldImport,
errorMsg,
}
h.writeJSON(resp)
return nil
}