Repository: scality/bucketclient
Pull request #277: BKTCLT-41: Add query parameter to appendToLog API
Author: login: dvasilas
Created: 2025-04-01T09:35:14Z | Merged: 2025-04-03T13:27:41Z

Update bucketclient for the changes in https://github.com/scality/MetaData/pull/2300


Diff:
diff --git a/go/appendToLog.go b/go/appendToLog.go
index 5e1787f..3eb6984 100644
--- a/go/appendToLog.go
+++ b/go/appendToLog.go
@@ -4,6 +4,7 @@ import (
 	"context"
 	"encoding/json"
 	"fmt"
+	"net/url"
 )
 
 type AppendToLogEntry struct {
@@ -14,8 +15,18 @@ type AppendToLogEntry struct {
 }
 
 func (client *BucketClient) AppendToLog(ctx context.Context,
-	bucketName string, batch []AppendToLogEntry, opts ...RequestOption) error {
+	bucketName string, batch []AppendToLogEntry, sessionId *string, opts ...RequestOption) error {
 	resource := fmt.Sprintf("/default/appendToLog/%s", bucketName)
+	query := url.Values{}
+
+	if sessionId != nil && *sessionId != "" {
+		query.Set("raftsession", *sessionId)
+	}
+
+	u, _ := url.Parse(resource)
+	u.RawQuery = query.Encode()
+	resource = u.String()
+
 	postPayload := struct {
 		Batch []AppendToLogEntry `json:"batch"`
 	}{Batch: batch}
diff --git a/go/appendToLog_test.go b/go/appendToLog_test.go
index f745e4d..d52ef96 100644
--- a/go/appendToLog_test.go
+++ b/go/appendToLog_test.go
@@ -30,6 +30,28 @@ var _ = Describe("AppendToLog()", func() {
 
 		Expect(client.AppendToLog(ctx, "somebucket", []bucketclient.AppendToLogEntry{
 			{Type: "append", Value: "{}"},
-		})).To(Succeed())
+		}, nil)).To(Succeed())
+	})
+
+	It("POSTs a batch to bucketd's appendToLog route", func(ctx SpecContext) {
+		httpmock.RegisterResponder(
+			"POST", "http://localhost:9000/default/appendToLog/somebucket?raftsession=4",
+			func(req *http.Request) (*http.Response, error) {
+				defer req.Body.Close()
+				Expect(io.ReadAll(req.Body)).To(Equal(
+					[]byte(`{"batch":[{"type":"append","value":"{}"}]}`)))
+
+				contentType, hasHeader := req.Header["Content-Type"]
+				Expect(hasHeader).To(BeTrue())
+				Expect(contentType).To(Equal([]string{"application/json"}))
+
+				return httpmock.NewStringResponse(200, "got it"), nil
+			},
+		)
+
+		raftsession := "4"
+		Expect(client.AppendToLog(ctx, "somebucket", []bucketclient.AppendToLogEntry{
+			{Type: "append", Value: "{}"},
+		}, &raftsession)).To(Succeed())
 	})
 })
diff --git a/index.d.ts b/index.d.ts
index c08788c..97647c5 100644
--- a/index.d.ts
+++ b/index.d.ts
@@ -34,7 +34,7 @@ declare module 'bucketclient' {
         getRaftBuckets(raftId: string, reqUids: string[], callback: Callback, reqLogger: any): void;
         getBucketInformation(bucketName: string, reqUids: string[], callback: Callback, reqLogger: any): void;
         execBatch(bucketName: string, batch: Array<BatchOperation>, reqUids: string[], callback: Callback, reqLogger: any): void;
-        appendToLog(bucketName: string, batch: Array<BatchOperation>, reqUids: string[], callback: Callback, reqLogger: any): void;
+        appendToLog(bucketName: string, batch: Array<BatchOperation>, raftsession: string | null | undefined, reqUids: string[], callback: Callback, reqLogger: any): void;
         healthcheck(log: any, callback: Callback): void;
         livecheck(log: any, callback: Callback): void;
         private endRespond(res: any, ret: any, log: any, callback: Callback): void;
diff --git a/lib/RESTClient.js b/lib/RESTClient.js
index 9eb4e22..e2d7e54 100644
--- a/lib/RESTClient.js
+++ b/lib/RESTClient.js
@@ -539,14 +539,19 @@ class RESTClient {
             null, JSON.stringify({ batch }), callback);
     }
 
-    appendToLog(bucketName, batch, reqUids, callback, logger) {
+    appendToLog(bucketName, batch, raftsession, reqUids, callback, logger) {
         const log = logger || this.createLogger(reqUids);
         assert(typeof bucketName === 'string', 'bucketName must be a string');
         assert(Array.isArray(batch), 'batch must be an array');
 
+        const query = {};
+        if (raftsession !== undefined && raftsession !== null) {
+            query.raftsession = raftsession;
+        }
+
         log.debug('appendToLog', { bucketName, batch });
         this.request('POST', `/default/appendToLog/${bucketName}`, log,
-            null, JSON.stringify({ batch }), callback);
+            query, JSON.stringify({ batch }), callback);
     }
 }
 
diff --git a/package.json b/package.json
index 29b45c9..6b17c0d 100644
--- a/package.json
+++ b/package.json
@@ -3,7 +3,7 @@
   "engines": {
     "node": ">=16"
   },
-  "version": "7.10.18",
+  "version": "7.10.19",
   "description": "Bucket Client",
   "main": "index.js",
   "files": [


Reviews:
user: login: fredmnl
body: LGTM. Small comment on using the `net/url` package
state: APPROVED
author_association: NONE
submitted_at: 2025-04-03T09:59:51Z
user: login: dvasilas
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-03T10:18:46Z
user: login: BourgoisMickael
state: APPROVED
author_association: NONE
submitted_at: 2025-04-03T11:40:36Z
user: login: fredmnl
state: APPROVED
author_association: NONE
submitted_at: 2025-04-03T11:47:55Z

Review comments:
diff_hunk: @@ -14,8 +14,13 @@ type AppendToLogEntry struct {
 }
 
 func (client *BucketClient) AppendToLog(ctx context.Context,
-	bucketName string, batch []AppendToLogEntry, opts ...RequestOption) error {
+	bucketName string, batch []AppendToLogEntry, sessionId *string, opts ...RequestOption) error {
 	resource := fmt.Sprintf("/default/appendToLog/%s", bucketName)
+
+	if sessionId != nil && *sessionId != "" {
+		resource = fmt.Sprintf("%s?raftsession=%s", resource, *sessionId)
path: go/appendToLog.go
user: login: fredmnl
body: Go has an equivalent to the nodejs code below for formatting urls. https://pkg.go.dev/net/url 

See `go/createbucket.go:48` for example. I think we're better off using it everywhere. 
created_at: 2025-04-03T09:59:07Z
author_association: NONE
diff_hunk: @@ -14,8 +14,13 @@ type AppendToLogEntry struct {
 }
 
 func (client *BucketClient) AppendToLog(ctx context.Context,
-	bucketName string, batch []AppendToLogEntry, opts ...RequestOption) error {
+	bucketName string, batch []AppendToLogEntry, sessionId *string, opts ...RequestOption) error {
 	resource := fmt.Sprintf("/default/appendToLog/%s", bucketName)
+
+	if sessionId != nil && *sessionId != "" {
+		resource = fmt.Sprintf("%s?raftsession=%s", resource, *sessionId)
path: go/appendToLog.go
user: login: dvasilas
body: Changed it to use `net/url`, thanks.
created_at: 2025-04-03T10:18:46Z
author_association: CONTRIBUTOR

PR comments:
user: login: bert-e
created_at: 2025-04-01T09:35:18Z
body: # Hello dvasilas,



My role is to assist you with the merge of this
pull request. Please type `@bert-e help` to get information
on this process, or consult the [user documentation](
https://bert-e.scality.net/scality/bucketclient/doc/user).


<details>
  <summary><b>Available options</b></summary>

  name   | description  | privileged   | authored
  ------ | ------------ | ------------ |----------
  `/after_pull_request` | Wait for the given pull request id to be merged before continuing with the current one. |  | 
  `/bypass_author_approval` | Bypass the pull request author's approval |  :star:  | 
  `/bypass_build_status` | Bypass the build and test status |  :star:  | 
  `/bypass_commit_size` | Bypass the check on the size of the changeset ```TBA``` |  :star:  | 
  `/bypass_incompatible_branch` | Bypass the check on the source branch prefix |  :star:  | 
  `/bypass_jira_check` | Bypass the Jira issue check |  :star:  | 
  `/bypass_peer_approval` | Bypass the pull request peers' approval |  :star:  | 
  `/bypass_leader_approval` | Bypass the pull request leaders' approval |  :star:  | 
  `/approve` | Instruct Bert-E that the author has approved the pull request. |  |  :writing_hand: 
  `/create_pull_requests` | Allow the creation of integration pull requests. |  | 
  `/create_integration_branches` | Allow the creation of integration branches. |  | 
  `/no_octopus` | Prevent Wall-E from doing any octopus merge and use multiple consecutive merge instead |  | 
  `/unanimity` | Change review acceptance criteria from `one reviewer at least` to `all reviewers` |  | 
  `/wait` | Instruct Bert-E not to run until further notice. |  | 
  

</details>



<details>
  <summary><b>Available commands</b></summary>

  name   | description  | privileged
  ------ | ------------ | ------------
  `/help` | Print Bert-E's manual in the pull request. | 
  `/status` | Print Bert-E's current status in the pull request ```TBA``` | 
  `/clear` | Remove all comments from Bert-E from the history ```TBA``` | 
  `/retry` | Re-start a fresh build ```TBA``` | 
  `/build` | Re-start a fresh build ```TBA``` | 
  `/force_reset` | Delete integration branches & pull requests, and restart merge process from the beginning. | 
  `/reset` | Try to remove integration branches unless there are commits on them which do not appear on the source branch. | 
  
</details>




*Status report is not available.*







author_association: CONTRIBUTOR
user: login: bert-e
created_at: 2025-04-01T09:35:22Z
body: # Incorrect fix version



The `Fix Version/s` in issue BKTCLT-41 contains:


* *None*



Considering where you are trying to merge, I ignored possible hotfix versions and I expected to find:



* `8.2.2`


Please check the `Fix Version/s` of BKTCLT-41, or the target
branch of this pull request.





author_association: CONTRIBUTOR
user: login: bert-e
created_at: 2025-04-01T09:37:06Z
body: # Incorrect fix version



The `Fix Version/s` in issue BKTCLT-41 contains:


* *None*



Considering where you are trying to merge, I ignored possible hotfix versions and I expected to find:



* `7.10.19`

* `8.1.12`

* `8.2.2`


Please check the `Fix Version/s` of BKTCLT-41, or the target
branch of this pull request.





author_association: CONTRIBUTOR
user: login: bert-e
created_at: 2025-04-01T09:40:37Z
body: # Request integration branches



Waiting for integration branch creation to be requested by the user.

To request integration branches, please comment on this pull request with the following command:

```
/create_integration_branches
```

Alternatively, the `/approve` and `/create_pull_requests` commands will automatically
create the integration branches.






author_association: CONTRIBUTOR
user: login: dvasilas
created_at: 2025-04-03T13:15:40Z
body: /create_integration_branches
author_association: CONTRIBUTOR
user: login: bert-e
created_at: 2025-04-03T13:15:49Z
body: # Conflict




A conflict has been raised during the creation of
integration branch `w/8.1/improvement/BKTCLT-41` with contents from `improvement/BKTCLT-41`
and `development/8.1`.

**I have not created the integration branch.**


Here are the steps to resolve this conflict:

```bash
 $ git fetch
 $ git checkout -B w/8.1/improvement/BKTCLT-41 origin/development/8.1
 $ git merge origin/improvement/BKTCLT-41
 $ # <intense conflict resolution>
 $ git commit
 $ git push -u origin w/8.1/improvement/BKTCLT-41
```





*The following options are set:* **create_integration_branches**


author_association: CONTRIBUTOR
user: login: dvasilas
created_at: 2025-04-03T13:17:14Z
body: ping
author_association: CONTRIBUTOR
user: login: bert-e
created_at: 2025-04-03T13:17:25Z
body: # Conflict




A conflict has been raised during the creation of
integration branch `w/8.2/improvement/BKTCLT-41` with contents from `w/8.1/improvement/BKTCLT-41`
and `development/8.2`.

**I have not created the integration branch.**


Here are the steps to resolve this conflict:

```bash
 $ git fetch
 $ git checkout -B w/8.2/improvement/BKTCLT-41 origin/development/8.2
 $ git merge origin/w/8.1/improvement/BKTCLT-41
 $ # <intense conflict resolution>
 $ git commit
 $ git push -u origin w/8.2/improvement/BKTCLT-41
```





*The following options are set:* **create_integration_branches**


author_association: CONTRIBUTOR
user: login: dvasilas
created_at: 2025-04-03T13:26:19Z
body: ping
author_association: CONTRIBUTOR
user: login: bert-e
created_at: 2025-04-03T13:26:28Z
body: # Waiting for approval



The following approvals are needed before I can proceed with the merge:


* the author


* 2 peers











*The following options are set:* **create_integration_branches**


author_association: CONTRIBUTOR
user: login: dvasilas
created_at: 2025-04-03T13:26:38Z
body: /approve
author_association: CONTRIBUTOR
user: login: bert-e
created_at: 2025-04-03T13:27:41Z
body: # 


I have successfully merged the changeset of this pull request
into targetted development branches:


* :heavy_check_mark: `development/7.10`

* :heavy_check_mark: `development/8.1`

* :heavy_check_mark: `development/8.2`



The following branches have **NOT** changed:

* `development/6.4`
* `development/7.4`



Please check the status of the associated issue BKTCLT-41.

Goodbye dvasilas.




*The following options are set:* **approve, create_integration_branches**


author_association: CONTRIBUTOR