Skip to content

Commit e58e3cf

Browse files
author
enikon
authored
GT-586 Foxx API support in V2 (#685)
1 parent 05836fd commit e58e3cf

File tree

5 files changed

+268
-1
lines changed

5 files changed

+268
-1
lines changed

v2/arangodb/client.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@
2020

2121
package arangodb
2222

23-
import "github.com/arangodb/go-driver/v2/connection"
23+
import (
24+
"github.com/arangodb/go-driver/v2/connection"
25+
)
2426

2527
type Client interface {
2628
// Connection returns current Driver Connection
@@ -33,4 +35,5 @@ type Client interface {
3335
ClientServerInfo
3436
ClientAdmin
3537
ClientAsyncJob
38+
ClientFoxx
3639
}

v2/arangodb/client_foxx.go

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
//
2+
// DISCLAIMER
3+
//
4+
// Copyright 2025 ArangoDB GmbH, Cologne, Germany
5+
//
6+
// Licensed under the Apache License, Version 2.0 (the "License");
7+
// you may not use this file except in compliance with the License.
8+
// You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing, software
13+
// distributed under the License is distributed on an "AS IS" BASIS,
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License.
17+
//
18+
// Copyright holder is ArangoDB GmbH, Cologne, Germany
19+
20+
package arangodb
21+
22+
import (
23+
"context"
24+
"strconv"
25+
26+
"github.com/arangodb/go-driver/v2/connection"
27+
)
28+
29+
type ClientFoxx interface {
30+
ClientFoxxService
31+
//ClientFoxxDependencies
32+
}
33+
34+
type ClientFoxxService interface {
35+
// InstallFoxxService installs a new service at a given mount path.
36+
InstallFoxxService(ctx context.Context, dbName string, zipFile string, options *FoxxCreateOptions) error
37+
// UninstallFoxxService uninstalls service at a given mount path.
38+
UninstallFoxxService(ctx context.Context, dbName string, options *FoxxDeleteOptions) error
39+
}
40+
41+
type FoxxCreateOptions struct {
42+
Mount *string
43+
}
44+
45+
type FoxxDeleteOptions struct {
46+
Mount *string
47+
Teardown *bool
48+
}
49+
50+
// ImportDocumentRequest holds Query parameters for /import.
51+
type InstallFoxxServiceRequest struct {
52+
FoxxCreateOptions `json:",inline"`
53+
}
54+
55+
type UninstallFoxxServiceRequest struct {
56+
FoxxDeleteOptions `json:",inline"`
57+
}
58+
59+
func (c *InstallFoxxServiceRequest) modifyRequest(r connection.Request) error {
60+
if c == nil {
61+
return nil
62+
}
63+
64+
r.AddHeader(connection.ContentType, "application/zip")
65+
r.AddQuery("mount", *c.Mount)
66+
67+
return nil
68+
}
69+
70+
func (c *UninstallFoxxServiceRequest) modifyRequest(r connection.Request) error {
71+
if c == nil {
72+
return nil
73+
}
74+
75+
r.AddQuery("mount", *c.Mount)
76+
r.AddQuery("teardown", strconv.FormatBool(*c.Teardown))
77+
return nil
78+
79+
}

v2/arangodb/client_foxx_impl.go

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
//
2+
// DISCLAIMER
3+
//
4+
// Copyright 2025 ArangoDB GmbH, Cologne, Germany
5+
//
6+
// Licensed under the Apache License, Version 2.0 (the "License");
7+
// you may not use this file except in compliance with the License.
8+
// You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing, software
13+
// distributed under the License is distributed on an "AS IS" BASIS,
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License.
17+
//
18+
// Copyright holder is ArangoDB GmbH, Cologne, Germany
19+
20+
package arangodb
21+
22+
import (
23+
"context"
24+
"net/http"
25+
"os"
26+
27+
"github.com/arangodb/go-driver/v2/arangodb/shared"
28+
"github.com/arangodb/go-driver/v2/connection"
29+
"github.com/pkg/errors"
30+
)
31+
32+
var _ ClientFoxx = &clientFoxx{}
33+
34+
type clientFoxx struct {
35+
client *client
36+
}
37+
38+
func newClientFoxx(client *client) *clientFoxx {
39+
return &clientFoxx{
40+
client: client,
41+
}
42+
}
43+
44+
// InstallFoxxService installs a new service at a given mount path.
45+
func (c *clientFoxx) InstallFoxxService(ctx context.Context, dbName string, zipFile string, opts *FoxxCreateOptions) error {
46+
47+
url := connection.NewUrl("_db", dbName, "_api/foxx")
48+
var response struct {
49+
shared.ResponseStruct `json:",inline"`
50+
}
51+
52+
request := &InstallFoxxServiceRequest{}
53+
if opts != nil {
54+
request.FoxxCreateOptions = *opts
55+
}
56+
57+
bytes, err := os.ReadFile(zipFile)
58+
if err != nil {
59+
return errors.WithStack(err)
60+
}
61+
62+
resp, err := connection.CallPost(ctx, c.client.connection, url, &response, bytes, request.modifyRequest)
63+
if err != nil {
64+
return errors.WithStack(err)
65+
}
66+
67+
switch code := resp.Code(); code {
68+
case http.StatusOK:
69+
return nil
70+
default:
71+
return response.AsArangoErrorWithCode(code)
72+
}
73+
74+
}
75+
76+
// UninstallFoxxService uninstalls service at a given mount path.
77+
func (c *clientFoxx) UninstallFoxxService(ctx context.Context, dbName string, opts *FoxxDeleteOptions) error {
78+
url := connection.NewUrl("_db", dbName, "_api/foxx/service")
79+
80+
var response struct {
81+
shared.ResponseStruct `json:",inline"`
82+
}
83+
84+
request := &UninstallFoxxServiceRequest{}
85+
if opts != nil {
86+
request.FoxxDeleteOptions = *opts
87+
}
88+
89+
resp, err := connection.CallPost(ctx, c.client.connection, url, &response, nil, request.modifyRequest)
90+
if err != nil {
91+
return errors.WithStack(err)
92+
}
93+
94+
switch code := resp.Code(); code {
95+
case http.StatusOK:
96+
return nil
97+
default:
98+
return response.AsArangoErrorWithCode(code)
99+
}
100+
}

v2/arangodb/client_impl.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ func newClient(connection connection.Connection) *client {
3838
c.clientServerInfo = newClientServerInfo(c)
3939
c.clientAdmin = newClientAdmin(c)
4040
c.clientAsyncJob = newClientAsyncJob(c)
41+
c.clientFoxx = newClientFoxx(c)
4142

4243
c.Requests = NewRequests(connection)
4344

@@ -54,6 +55,7 @@ type client struct {
5455
*clientServerInfo
5556
*clientAdmin
5657
*clientAsyncJob
58+
*clientFoxx
5759

5860
Requests
5961
}

v2/tests/foxx_test.go

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
//
2+
// DISCLAIMER
3+
//
4+
// Copyright 2025 ArangoDB GmbH, Cologne, Germany
5+
//
6+
// Licensed under the Apache License, Version 2.0 (the "License");
7+
// you may not use this file except in compliance with the License.
8+
// You may obtain a copy of the License at
9+
//
10+
// http://www.apache.org/licenses/LICENSE-2.0
11+
//
12+
// Unless required by applicable law or agreed to in writing, software
13+
// distributed under the License is distributed on an "AS IS" BASIS,
14+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
// See the License for the specific language governing permissions and
16+
// limitations under the License.
17+
//
18+
// Copyright holder is ArangoDB GmbH, Cologne, Germany
19+
//
20+
21+
package tests
22+
23+
import (
24+
"context"
25+
"os"
26+
"testing"
27+
"time"
28+
29+
"github.com/stretchr/testify/require"
30+
31+
"github.com/arangodb/go-driver/v2/arangodb"
32+
"github.com/arangodb/go-driver/v2/connection"
33+
"github.com/arangodb/go-driver/v2/utils"
34+
)
35+
36+
func Test_FoxxItzpapalotlService(t *testing.T) {
37+
Wrap(t, func(t *testing.T, client arangodb.Client) {
38+
WithDatabase(t, client, nil, func(db arangodb.Database) {
39+
t.Run("Install and uninstall Foxx", func(t *testing.T) {
40+
withContextT(t, defaultTestTimeout, func(ctx context.Context, t testing.TB) {
41+
42+
if os.Getenv("TEST_CONNECTION") == "vst" {
43+
skipBelowVersion(client, ctx, "3.6", t)
44+
}
45+
46+
// /tmp/resources/ directory is provided by .travis.yml
47+
zipFilePath := "/tmp/resources/itzpapalotl-v1.2.0.zip"
48+
if _, err := os.Stat(zipFilePath); os.IsNotExist(err) {
49+
// Test works only via travis pipeline unless the above file exists locally
50+
t.Skipf("file %s does not exist", zipFilePath)
51+
}
52+
53+
timeoutCtx, cancel := context.WithTimeout(context.Background(), time.Minute*30)
54+
mountName := "test"
55+
options := &arangodb.FoxxCreateOptions{
56+
Mount: utils.NewType[string]("/" + mountName),
57+
}
58+
err := client.InstallFoxxService(timeoutCtx, db.Name(), zipFilePath, options)
59+
cancel()
60+
require.NoError(t, err)
61+
62+
timeoutCtx, cancel = context.WithTimeout(context.Background(), time.Second*30)
63+
resp, err := connection.CallGet(ctx, client.Connection(), "_db/_system/"+mountName+"/random", nil, nil, nil)
64+
require.NotNil(t, resp)
65+
66+
value, ok := resp, true
67+
require.Equal(t, true, ok)
68+
require.NotEmpty(t, value)
69+
cancel()
70+
71+
timeoutCtx, cancel = context.WithTimeout(context.Background(), time.Second*30)
72+
deleteOptions := &arangodb.FoxxDeleteOptions{
73+
Mount: utils.NewType[string]("/" + mountName),
74+
Teardown: utils.NewType[bool](true),
75+
}
76+
err = client.UninstallFoxxService(timeoutCtx, db.Name(), deleteOptions)
77+
cancel()
78+
require.NoError(t, err)
79+
})
80+
})
81+
})
82+
})
83+
}

0 commit comments

Comments
 (0)