From 352f6b36aaa905aec74a2b9250d47b61145c6ad1 Mon Sep 17 00:00:00 2001 From: Mohammed Madi Date: Thu, 22 Feb 2024 10:29:08 +0000 Subject: [PATCH 01/12] Add handling and test for get all doc channels --- rest/diagnostic_doc_api.go | 35 +++++++++++++++++++++++++++++++++ rest/diagnostic_doc_api_test.go | 32 ++++++++++++++++++++++++++++++ rest/routing.go | 6 +++++- 3 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 rest/diagnostic_doc_api.go create mode 100644 rest/diagnostic_doc_api_test.go diff --git a/rest/diagnostic_doc_api.go b/rest/diagnostic_doc_api.go new file mode 100644 index 0000000000..be26fc4dbe --- /dev/null +++ b/rest/diagnostic_doc_api.go @@ -0,0 +1,35 @@ +package rest + +import ( + "github.com/couchbase/sync_gateway/auth" + "github.com/couchbase/sync_gateway/db" + "log" +) + +// HTTP handler for a GET of a document +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 := 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 { + if hist.Name == chanSetInfo.Name { + resp[chanSetInfo.Name] = append(resp[chanSetInfo.Name], auth.GrantHistorySequencePair{StartSeq: hist.Start, EndSeq: hist.End}) + continue + } + } + } + log.Print(resp) + + h.writeJSON(resp) + return nil +} diff --git a/rest/diagnostic_doc_api_test.go b/rest/diagnostic_doc_api_test.go new file mode 100644 index 0000000000..5a04d2fbfc --- /dev/null +++ b/rest/diagnostic_doc_api_test.go @@ -0,0 +1,32 @@ +package rest + +import ( + "encoding/json" + "github.com/stretchr/testify/assert" + "log" + "net/http" + "testing" +) + +func TestGetAlldocChannels(t *testing.T) { + rt := NewRestTester(t, &RestTesterConfig{SyncFn: `function(doc) {channel(doc.channel);}`}) + defer rt.Close() + + version := rt.PutDoc("doc", `{"channel":["CHAN1"]}`) + updatedVersion := rt.UpdateDoc("doc", version, `{"channel":["CHAN2"]}`) + updatedVersion = rt.UpdateDoc("doc", updatedVersion, `{"channel":["CHAN1"]}`) + updatedVersion = rt.UpdateDoc("doc", updatedVersion, `{"channel":["CHAN1", "CHAN2"]}`) + updatedVersion = rt.UpdateDoc("doc", updatedVersion, `{"channel":["CHAN3"]}`) + updatedVersion = rt.UpdateDoc("doc", updatedVersion, `{"channel":["CHAN1"]}`) + + response := rt.SendDiagnosticRequest("GET", "/{{.keyspace}}/doc/_all_channels", "") + RequireStatus(t, response, http.StatusOK) + log.Printf(response.BodyString()) + var channelMap map[string][]string + err := json.Unmarshal(response.BodyBytes(), &channelMap) + assert.NoError(t, err) + assert.ElementsMatch(t, channelMap["CHAN1"], []string{"6-0", "1-2", "3-5"}) + assert.ElementsMatch(t, channelMap["CHAN2"], []string{"4-5", "2-3"}) + assert.ElementsMatch(t, channelMap["CHAN3"], []string{"5-6"}) + +} diff --git a/rest/routing.go b/rest/routing.go index cdb3643272..4012918949 100644 --- a/rest/routing.go +++ b/rest/routing.go @@ -368,7 +368,11 @@ func CreateMetricRouter(sc *ServerContext) *mux.Router { func createDiagnosticRouter(sc *ServerContext) *mux.Router { r := CreatePingRouter(sc) - + dbr := r.PathPrefix("/{db:" + dbRegex + "}/").Subrouter() + dbr.StrictSlash(true) + keyspace := r.PathPrefix("/{keyspace:" + dbRegex + "}/").Subrouter() + keyspace.StrictSlash(true) + keyspace.Handle("/{docid:"+docRegex+"}/_all_channels", makeHandler(sc, adminPrivs, []Permission{PermReadAppData}, nil, (*handler).handleGetDocChannels)).Methods("GET") return r } From 4423426701b6383d44ee08b646496083a40cbf09 Mon Sep 17 00:00:00 2001 From: Mohammed Madi Date: Thu, 22 Feb 2024 10:33:33 +0000 Subject: [PATCH 02/12] Fix lint --- rest/diagnostic_doc_api.go | 3 ++- rest/diagnostic_doc_api_test.go | 8 ++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/rest/diagnostic_doc_api.go b/rest/diagnostic_doc_api.go index be26fc4dbe..fb4941c6d4 100644 --- a/rest/diagnostic_doc_api.go +++ b/rest/diagnostic_doc_api.go @@ -1,9 +1,10 @@ package rest import ( + "log" + "github.com/couchbase/sync_gateway/auth" "github.com/couchbase/sync_gateway/db" - "log" ) // HTTP handler for a GET of a document diff --git a/rest/diagnostic_doc_api_test.go b/rest/diagnostic_doc_api_test.go index 5a04d2fbfc..29de283906 100644 --- a/rest/diagnostic_doc_api_test.go +++ b/rest/diagnostic_doc_api_test.go @@ -2,10 +2,10 @@ package rest import ( "encoding/json" - "github.com/stretchr/testify/assert" - "log" "net/http" "testing" + + "github.com/stretchr/testify/assert" ) func TestGetAlldocChannels(t *testing.T) { @@ -17,11 +17,11 @@ func TestGetAlldocChannels(t *testing.T) { updatedVersion = rt.UpdateDoc("doc", updatedVersion, `{"channel":["CHAN1"]}`) updatedVersion = rt.UpdateDoc("doc", updatedVersion, `{"channel":["CHAN1", "CHAN2"]}`) updatedVersion = rt.UpdateDoc("doc", updatedVersion, `{"channel":["CHAN3"]}`) - updatedVersion = rt.UpdateDoc("doc", updatedVersion, `{"channel":["CHAN1"]}`) + _ = rt.UpdateDoc("doc", updatedVersion, `{"channel":["CHAN1"]}`) response := rt.SendDiagnosticRequest("GET", "/{{.keyspace}}/doc/_all_channels", "") RequireStatus(t, response, http.StatusOK) - log.Printf(response.BodyString()) + var channelMap map[string][]string err := json.Unmarshal(response.BodyBytes(), &channelMap) assert.NoError(t, err) From 2e9fac9a4bf1ca968eef549342ccc9e5bffe402a Mon Sep 17 00:00:00 2001 From: Mohammed Madi Date: Thu, 22 Feb 2024 10:34:52 +0000 Subject: [PATCH 03/12] Add licensing --- rest/diagnostic_doc_api.go | 10 ++++++++++ rest/diagnostic_doc_api_test.go | 10 ++++++++++ 2 files changed, 20 insertions(+) diff --git a/rest/diagnostic_doc_api.go b/rest/diagnostic_doc_api.go index fb4941c6d4..720893d9cb 100644 --- a/rest/diagnostic_doc_api.go +++ b/rest/diagnostic_doc_api.go @@ -1,3 +1,13 @@ +/* +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 ( diff --git a/rest/diagnostic_doc_api_test.go b/rest/diagnostic_doc_api_test.go index 29de283906..31d308e35b 100644 --- a/rest/diagnostic_doc_api_test.go +++ b/rest/diagnostic_doc_api_test.go @@ -1,3 +1,13 @@ +/* +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 ( From 09557defc7a499d0d7fec9acfdfb49632edcd2f0 Mon Sep 17 00:00:00 2001 From: Mohammed Madi Date: Fri, 23 Feb 2024 11:25:07 +0000 Subject: [PATCH 04/12] Address comments --- rest/diagnostic_doc_api.go | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/rest/diagnostic_doc_api.go b/rest/diagnostic_doc_api.go index 720893d9cb..bf0ce26c49 100644 --- a/rest/diagnostic_doc_api.go +++ b/rest/diagnostic_doc_api.go @@ -11,8 +11,6 @@ licenses/APL2.txt. package rest import ( - "log" - "github.com/couchbase/sync_gateway/auth" "github.com/couchbase/sync_gateway/db" ) @@ -32,14 +30,13 @@ func (h *handler) handleGetDocChannels() error { 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 { - if hist.Name == chanSetInfo.Name { - resp[chanSetInfo.Name] = append(resp[chanSetInfo.Name], auth.GrantHistorySequencePair{StartSeq: hist.Start, EndSeq: hist.End}) - continue - } + } + for _, hist := range doc.SyncData.ChannelSetHistory { + if _, ok := resp[hist.Name]; ok { + resp[hist.Name] = append(resp[hist.Name], auth.GrantHistorySequencePair{StartSeq: hist.Start, EndSeq: hist.End}) + continue } } - log.Print(resp) h.writeJSON(resp) return nil From 696c11eafc2e93d512e33f966a6fdb56d2f856d9 Mon Sep 17 00:00:00 2001 From: Mohammed Madi Date: Fri, 23 Feb 2024 16:14:49 +0000 Subject: [PATCH 05/12] Add docs --- docs/api/diagnostic.yaml | 2 + .../keyspace-docid-_all_channels.yaml | 37 +++++++++++++++++++ 2 files changed, 39 insertions(+) create mode 100644 docs/api/paths/diagnostic/keyspace-docid-_all_channels.yaml diff --git a/docs/api/diagnostic.yaml b/docs/api/diagnostic.yaml index ede60965de..a601cbbce8 100644 --- a/docs/api/diagnostic.yaml +++ b/docs/api/diagnostic.yaml @@ -30,6 +30,8 @@ servers: paths: /_ping: $ref: ./paths/common/_ping.yaml + '/{keyspace}/{docid}/_all_channels': + $ref: './paths/diagnostic/keyspace-docid-_all_channels.yaml' externalDocs: description: Sync Gateway Quickstart | Couchbase Docs url: 'https://docs.couchbase.com/sync-gateway/current/index.html' diff --git a/docs/api/paths/diagnostic/keyspace-docid-_all_channels.yaml b/docs/api/paths/diagnostic/keyspace-docid-_all_channels.yaml new file mode 100644 index 0000000000..1c1342bd82 --- /dev/null +++ b/docs/api/paths/diagnostic/keyspace-docid-_all_channels.yaml @@ -0,0 +1,37 @@ +# Copyright 2022-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. +parameters: + - $ref: ../../components/parameters.yaml#/db + - $ref: ../../components/parameters.yaml#/user-name +get: + summary: Get all channels for a user + description: |- + Retrieve all doc channels and the sequence spans showing when the doc was added to a channel and when it was removed. + Required Sync Gateway RBAC roles: + * Sync Gateway Application Read Only + responses: + '200': + description: Document found successfully + content: + application/json: + schema: + properties: + channel_set: + description: The channels the document has been in. + type: array + items: + sequences: + description: The sequence number that document was added to the channel. + type: string + example: "28-48" + + '404': + $ref: ../../components/responses.yaml#/Not-found + tags: + - Database Security + operationId: get_db-_user-name-_all_channels \ No newline at end of file From 0ec77e4dc7228de272f23783a47d9fc97d5dc28f Mon Sep 17 00:00:00 2001 From: Mohammed Madi Date: Fri, 23 Feb 2024 16:46:36 +0000 Subject: [PATCH 06/12] fix yamllint --- docs/api/paths/diagnostic/keyspace-docid-_all_channels.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/api/paths/diagnostic/keyspace-docid-_all_channels.yaml b/docs/api/paths/diagnostic/keyspace-docid-_all_channels.yaml index 1c1342bd82..d2b7ad7c03 100644 --- a/docs/api/paths/diagnostic/keyspace-docid-_all_channels.yaml +++ b/docs/api/paths/diagnostic/keyspace-docid-_all_channels.yaml @@ -24,8 +24,8 @@ get: channel_set: description: The channels the document has been in. type: array - items: - sequences: + items: + sequences: description: The sequence number that document was added to the channel. type: string example: "28-48" @@ -34,4 +34,4 @@ get: $ref: ../../components/responses.yaml#/Not-found tags: - Database Security - operationId: get_db-_user-name-_all_channels \ No newline at end of file + operationId: get_db-_user-name-_all_channels From 54e8d0099edff84fc9ba7dce7abe7a385f21f7f1 Mon Sep 17 00:00:00 2001 From: Mohammed Madi Date: Mon, 26 Feb 2024 13:26:50 +0000 Subject: [PATCH 07/12] Add DocumentHistoryMaxEntriesPerChannel test case and fix docs --- .../keyspace-docid-_all_channels.yaml | 28 +++++++++---------- rest/diagnostic_doc_api.go | 6 ++-- rest/diagnostic_doc_api_test.go | 19 ++++++++++++- 3 files changed, 34 insertions(+), 19 deletions(-) diff --git a/docs/api/paths/diagnostic/keyspace-docid-_all_channels.yaml b/docs/api/paths/diagnostic/keyspace-docid-_all_channels.yaml index d2b7ad7c03..5b69ece930 100644 --- a/docs/api/paths/diagnostic/keyspace-docid-_all_channels.yaml +++ b/docs/api/paths/diagnostic/keyspace-docid-_all_channels.yaml @@ -6,10 +6,10 @@ # software will be governed by the Apache License, Version 2.0, included in # the file licenses/APL2.txt. parameters: - - $ref: ../../components/parameters.yaml#/db - - $ref: ../../components/parameters.yaml#/user-name + - $ref: ../../components/parameters.yaml#/keyspace + - $ref: ../../components/parameters.yaml#/docid get: - summary: Get all channels for a user + summary: Get channel history for a document description: |- Retrieve all doc channels and the sequence spans showing when the doc was added to a channel and when it was removed. Required Sync Gateway RBAC roles: @@ -20,18 +20,18 @@ get: content: application/json: schema: - properties: - channel_set: - description: The channels the document has been in. - type: array - items: - sequences: - description: The sequence number that document was added to the channel. - type: string - example: "28-48" + additionalProperties: + x-additionalPropertiesName: channel + description: The channels the document has been in. + type: array + items: + sequences: + description: The sequence number that document was added to the channel. + type: string + example: "28-48" '404': $ref: ../../components/responses.yaml#/Not-found tags: - - Database Security - operationId: get_db-_user-name-_all_channels + - Document + operationId: get_keyspace-docid-_all_channels diff --git a/rest/diagnostic_doc_api.go b/rest/diagnostic_doc_api.go index bf0ce26c49..0c1b705625 100644 --- a/rest/diagnostic_doc_api.go +++ b/rest/diagnostic_doc_api.go @@ -32,10 +32,8 @@ func (h *handler) handleGetDocChannels() error { resp[chanSetInfo.Name] = append(resp[chanSetInfo.Name], auth.GrantHistorySequencePair{StartSeq: chanSetInfo.Start, EndSeq: chanSetInfo.End}) } for _, hist := range doc.SyncData.ChannelSetHistory { - if _, ok := resp[hist.Name]; ok { - resp[hist.Name] = append(resp[hist.Name], auth.GrantHistorySequencePair{StartSeq: hist.Start, EndSeq: hist.End}) - continue - } + resp[hist.Name] = append(resp[hist.Name], auth.GrantHistorySequencePair{StartSeq: hist.Start, EndSeq: hist.End}) + continue } h.writeJSON(resp) diff --git a/rest/diagnostic_doc_api_test.go b/rest/diagnostic_doc_api_test.go index 31d308e35b..5d2fca288a 100644 --- a/rest/diagnostic_doc_api_test.go +++ b/rest/diagnostic_doc_api_test.go @@ -12,6 +12,8 @@ package rest import ( "encoding/json" + "github.com/couchbase/sync_gateway/db" + "log" "net/http" "testing" @@ -27,7 +29,7 @@ func TestGetAlldocChannels(t *testing.T) { updatedVersion = rt.UpdateDoc("doc", updatedVersion, `{"channel":["CHAN1"]}`) updatedVersion = rt.UpdateDoc("doc", updatedVersion, `{"channel":["CHAN1", "CHAN2"]}`) updatedVersion = rt.UpdateDoc("doc", updatedVersion, `{"channel":["CHAN3"]}`) - _ = rt.UpdateDoc("doc", updatedVersion, `{"channel":["CHAN1"]}`) + updatedVersion = rt.UpdateDoc("doc", updatedVersion, `{"channel":["CHAN1"]}`) response := rt.SendDiagnosticRequest("GET", "/{{.keyspace}}/doc/_all_channels", "") RequireStatus(t, response, http.StatusOK) @@ -39,4 +41,19 @@ func TestGetAlldocChannels(t *testing.T) { assert.ElementsMatch(t, channelMap["CHAN2"], []string{"4-5", "2-3"}) assert.ElementsMatch(t, channelMap["CHAN3"], []string{"5-6"}) + for i := 1; i <= 10; i++ { + updatedVersion = rt.UpdateDoc("doc", updatedVersion, `{}`) + updatedVersion = rt.UpdateDoc("doc", updatedVersion, `{"channel":["CHAN3"]}`) + } + response = rt.SendAdminRequest("GET", "/{{.keyspace}}/doc", "") + RequireStatus(t, response, http.StatusOK) + response = rt.SendDiagnosticRequest("GET", "/{{.keyspace}}/doc/_all_channels", "") + RequireStatus(t, response, http.StatusOK) + + err = json.Unmarshal(response.BodyBytes(), &channelMap) + assert.NoError(t, err) + log.Print(response.BodyString()) + // If the channel is still in channel_set, then the total will be 5 entries in history and 1 in channel_set + assert.Equal(t, len(channelMap["CHAN3"]), db.DocumentHistoryMaxEntriesPerChannel+1) + } From c2e51e02089953449ab4e9171f9df59f4eed9860 Mon Sep 17 00:00:00 2001 From: Mohammed Madi Date: Mon, 26 Feb 2024 15:02:50 +0000 Subject: [PATCH 08/12] Denote compacted sequence pairs with ~ --- auth/role.go | 12 +++++++++--- db/document.go | 8 +++++--- rest/diagnostic_doc_api.go | 2 +- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/auth/role.go b/auth/role.go index 0858702aa4..aba91c723f 100644 --- a/auth/role.go +++ b/auth/role.go @@ -59,13 +59,19 @@ type GrantHistory struct { // Struct is for ease of internal use // Bucket store has each entry as a string "seq-endSeq" type GrantHistorySequencePair struct { - StartSeq uint64 // Sequence at which a grant was performed to give access to a role / channel. Only populated once endSeq is available. - EndSeq uint64 // Sequence when access to a role / channel was revoked. + StartSeq uint64 // Sequence at which a grant was performed to give access to a role / channel. Only populated once endSeq is available. + EndSeq uint64 // Sequence when access to a role / channel was revoked. + Compacted bool } // MarshalJSON will handle conversion from having a seq / endSeq struct to the bucket format of "seq-endSeq" func (pair *GrantHistorySequencePair) MarshalJSON() ([]byte, error) { - stringPair := fmt.Sprintf("%d-%d", pair.StartSeq, pair.EndSeq) + var stringPair string + if pair.Compacted { + stringPair = fmt.Sprintf("%d~%d", pair.StartSeq, pair.EndSeq) + } else { + stringPair = fmt.Sprintf("%d-%d", pair.StartSeq, pair.EndSeq) + } return base.JSONMarshal(stringPair) } diff --git a/db/document.go b/db/document.go index 83d67f5389..f8b20913db 100644 --- a/db/document.go +++ b/db/document.go @@ -57,9 +57,10 @@ type UserAccessMap map[string]channels.TimedSet type AttachmentsMeta map[string]interface{} // AttachmentsMeta metadata as included in sync metadata type ChannelSetEntry struct { - Name string `json:"name"` - Start uint64 `json:"start"` - End uint64 `json:"end,omitempty"` + Name string `json:"name"` + Start uint64 `json:"start"` + End uint64 `json:"end,omitempty"` + Compacted bool `json:"compacted,omitempty"` } // The sync-gateway metadata stored in the "_sync" property of a Couchbase document. @@ -930,6 +931,7 @@ func (doc *Document) addToChannelSetHistory(channelName string, historyEntry Cha if entryCount >= DocumentHistoryMaxEntriesPerChannel { doc.ChannelSetHistory[secondOldestEntryIdx].Start = oldestEntryStartSeq + doc.ChannelSetHistory[secondOldestEntryIdx].Compacted = true doc.ChannelSetHistory = append(doc.ChannelSetHistory[:oldestEntryIdx], doc.ChannelSetHistory[oldestEntryIdx+1:]...) } diff --git a/rest/diagnostic_doc_api.go b/rest/diagnostic_doc_api.go index 0c1b705625..3add7fc9ec 100644 --- a/rest/diagnostic_doc_api.go +++ b/rest/diagnostic_doc_api.go @@ -32,7 +32,7 @@ func (h *handler) handleGetDocChannels() error { 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}) + resp[hist.Name] = append(resp[hist.Name], auth.GrantHistorySequencePair{StartSeq: hist.Start, EndSeq: hist.End, Compacted: hist.Compacted}) continue } From 2cea1f4095f0009e553ceb58f09ed0240b8781e7 Mon Sep 17 00:00:00 2001 From: Mohammed Madi Date: Mon, 26 Feb 2024 15:05:52 +0000 Subject: [PATCH 09/12] Fix goimports --- rest/diagnostic_doc_api_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rest/diagnostic_doc_api_test.go b/rest/diagnostic_doc_api_test.go index 5d2fca288a..bb11104286 100644 --- a/rest/diagnostic_doc_api_test.go +++ b/rest/diagnostic_doc_api_test.go @@ -12,11 +12,11 @@ package rest import ( "encoding/json" - "github.com/couchbase/sync_gateway/db" - "log" "net/http" "testing" + "github.com/couchbase/sync_gateway/db" + "github.com/stretchr/testify/assert" ) @@ -52,7 +52,7 @@ func TestGetAlldocChannels(t *testing.T) { err = json.Unmarshal(response.BodyBytes(), &channelMap) assert.NoError(t, err) - log.Print(response.BodyString()) + // If the channel is still in channel_set, then the total will be 5 entries in history and 1 in channel_set assert.Equal(t, len(channelMap["CHAN3"]), db.DocumentHistoryMaxEntriesPerChannel+1) From 9d008c3277d8da642e20b198f40a471c497c4ec0 Mon Sep 17 00:00:00 2001 From: Mohammed Madi Date: Mon, 26 Feb 2024 15:08:51 +0000 Subject: [PATCH 10/12] Fix comment --- auth/role.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/auth/role.go b/auth/role.go index aba91c723f..c34108654d 100644 --- a/auth/role.go +++ b/auth/role.go @@ -64,7 +64,7 @@ type GrantHistorySequencePair struct { Compacted bool } -// MarshalJSON will handle conversion from having a seq / endSeq struct to the bucket format of "seq-endSeq" +// MarshalJSON will handle conversion from having a seq / endSeq struct to the bucket format of "seq-endSeq" and "seq~endSeq" if the pair was compacted func (pair *GrantHistorySequencePair) MarshalJSON() ([]byte, error) { var stringPair string if pair.Compacted { From fda8bfe380947226d4b85fd52279f4b6d36af05c Mon Sep 17 00:00:00 2001 From: Mohammed Madi Date: Mon, 26 Feb 2024 15:09:29 +0000 Subject: [PATCH 11/12] Fix comment --- auth/role.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/auth/role.go b/auth/role.go index c34108654d..db1837f5e1 100644 --- a/auth/role.go +++ b/auth/role.go @@ -64,7 +64,7 @@ type GrantHistorySequencePair struct { Compacted bool } -// MarshalJSON will handle conversion from having a seq / endSeq struct to the bucket format of "seq-endSeq" and "seq~endSeq" if the pair was compacted +// MarshalJSON will handle conversion from having a seq / endSeq struct to the bucket format of "seq-endSeq" and "seq~endSeq" if the pair was compacted func (pair *GrantHistorySequencePair) MarshalJSON() ([]byte, error) { var stringPair string if pair.Compacted { From e27372ea2c22ce2d44c6272465a37c641d30d429 Mon Sep 17 00:00:00 2001 From: Mohammed Madi Date: Mon, 26 Feb 2024 17:16:16 +0000 Subject: [PATCH 12/12] Add unmarshalJSON handlign for compacted sequence pair --- auth/role.go | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/auth/role.go b/auth/role.go index db1837f5e1..cef756aaa1 100644 --- a/auth/role.go +++ b/auth/role.go @@ -86,7 +86,12 @@ func (pair *GrantHistorySequencePair) UnmarshalJSON(data []byte) error { splitPair := strings.Split(stringPair, "-") if len(splitPair) != 2 { - return fmt.Errorf("unexpected sequence pair length") + // try again with compacted sequence pair format + splitPair = strings.Split(stringPair, "~") + if len(splitPair) != 2 { + return fmt.Errorf("unexpected sequence pair length") + } + pair.Compacted = true } pair.StartSeq, err = strconv.ParseUint(splitPair[0], 10, 64)