Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions alter.go → alter_v25.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
/*
* SPDX-FileCopyrightText: © Hypermode Inc. <hello@hypermode.com>
* SPDX-License-Identifier: Apache-2.0
*/

package dgo

import (
Expand Down Expand Up @@ -55,8 +60,7 @@ func (d *Dgraph) SetSchema(ctx context.Context, nsName string, schema string) er
}

func (d *Dgraph) doAlter(ctx context.Context, req *apiv25.AlterRequest) error {
dc := d.anyClientv25()
_, err := doWithRetryLogin(ctx, d, func() (*apiv25.AlterResponse, error) {
_, err := doWithRetryLogin(ctx, d, func(dc apiv25.DgraphClient) (*apiv25.AlterResponse, error) {
return dc.Alter(d.getContext(ctx), req)
})
return err
Expand Down
99 changes: 8 additions & 91 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import (
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/credentials/insecure"
"google.golang.org/grpc/metadata"
"google.golang.org/grpc/status"
"google.golang.org/protobuf/proto"
Expand All @@ -28,17 +27,7 @@ import (
)

const (
cloudPort = "443"
dgraphScheme = "dgraph"
// optional parameter for providing a Dgraph Cloud API key
cloudAPIKeyParam = "apikey"
// optional parameter for providing an access token
bearerTokenParam = "bearertoken"
// optional parameter for providing a Dgraph SSL mode
sslModeParam = "sslmode"
sslModeDisable = "disable"
sslModeRequire = "require"
sslModeVerifyCA = "verify-ca"
cloudPort = "443"
)

// Dgraph is a transaction-aware client to a Dgraph cluster.
Expand All @@ -65,82 +54,6 @@ func (a *authCreds) RequireTransportSecurity() bool {
return true
}

// Open creates a new Dgraph client by parsing a connection string of the form:
// dgraph://<optional-login>:<optional-password>@<host>:<port>?<optional-params>
// For example `dgraph://localhost:9080?sslmode=require`
//
// Parameters:
// - apikey: a Dgraph Cloud API key for authentication
// - bearertoken: a token for bearer authentication
// - sslmode: SSL connection mode (options: disable, require, verify-ca)
// - disable: No TLS (default)
// - require: Use TLS but skip certificate verification
// - verify-ca: Use TLS and verify the certificate against system CA
//
// If credentials are provided, Open connects to the gRPC endpoint and authenticates the user.
// An error can be returned if the Dgraph cluster is not yet ready to accept requests--the text
// of the error in this case will contain the string "Please retry".
func Open(connStr string) (*Dgraph, error) {
u, err := url.Parse(connStr)
if err != nil {
return nil, fmt.Errorf("invalid connection string: %w", err)
}

if u.Scheme != dgraphScheme {
return nil, fmt.Errorf("invalid scheme: must start with %s://", dgraphScheme)
}

opts := []ClientOption{}

apiKey := u.Query().Get(cloudAPIKeyParam)
bearerToken := u.Query().Get(bearerTokenParam)
sslMode := u.Query().Get(sslModeParam)

if apiKey != "" && bearerToken != "" {
return nil, errors.New("invalid connection string: both apikey and bearertoken cannot be provided")
}

if apiKey != "" {
opts = append(opts, WithDgraphAPIKey(apiKey))
}

if bearerToken != "" {
opts = append(opts, WithBearerToken(bearerToken))
}

if sslMode == "" {
sslMode = sslModeDisable
}
switch sslMode {
case sslModeDisable:
opts = append(opts, WithGrpcOption(grpc.WithTransportCredentials(insecure.NewCredentials())))
case sslModeRequire:
opts = append(opts, WithSkipTLSVerify())
case sslModeVerifyCA:
opts = append(opts, WithSystemCertPool())
default:
return nil, fmt.Errorf("invalid SSL mode: %s (must be one of %s, %s, %s)", sslMode, sslModeDisable, sslModeRequire, sslModeVerifyCA)
}

if u.User != nil {
username := u.User.Username()
password, _ := u.User.Password()
if username == "" || password == "" {
return nil, errors.New("invalid connection string: both username and password must be provided")
}
opts = append(opts, WithACLCreds(username, password))
}

return NewClient(u.Host, opts...)
}

// Close shutdown down all the connections to the Dgraph Cluster.
func (d *Dgraph) Close() {
for _, conn := range d.conns {
_ = conn.Close()
}
}

// NewDgraphClient creates a new Dgraph (client) for interacting with Alphas.
// The client is backed by multiple connections to the same or different
// servers in a cluster.
Expand Down Expand Up @@ -260,9 +173,13 @@ func (d *Dgraph) LoginIntoNamespace(ctx context.Context,
// Deprecated: use DropAllNamespaces, DropAll, DropData, DropPredicate, DropType, SetSchema instead.
func (d *Dgraph) Alter(ctx context.Context, op *api.Operation) error {
dc := d.anyClient()
_, err := doWithRetryLogin(ctx, d, func() (*api.Payload, error) {
return dc.Alter(d.getContext(ctx), op)
})
_, err := dc.Alter(d.getContext(ctx), op)
if isJwtExpired(err) {
if err := d.retryLogin(ctx); err != nil {
return err
}
_, err = dc.Alter(d.getContext(ctx), op)
}
return err
}

Expand Down
Loading
Loading