Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

perf(GraphQL): JSON Part-6: Admin Server and custom HTTP query/mutation are now resolved separately (GRAPHQL-937) #7317

Merged
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
4 changes: 3 additions & 1 deletion ee/acl/acl_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ func TestInvalidGetUser(t *testing.T) {
require.Equal(t, x.GqlErrorList{{
Message: "couldn't rewrite query getCurrentUser because unable to parse jwt token: token" +
" contains an invalid number of segments",
Path: []interface{}{"getCurrentUser"},
}}, currentUser.Errors)
}

Expand Down Expand Up @@ -196,7 +197,7 @@ func TestPasswordReturn(t *testing.T) {

func TestGetCurrentUser(t *testing.T) {
token := testutil.GrootHttpLogin(adminEndpoint)

currentUser := getCurrentUser(t, token)
currentUser.RequireNoGraphQLErrors(t)
require.Equal(t, string(currentUser.Data), `{"getCurrentUser":{"name":"groot"}}`)
Expand Down Expand Up @@ -231,6 +232,7 @@ func TestCreateAndDeleteUsers(t *testing.T) {
require.Equal(t, x.GqlErrorList{{
Message: "couldn't rewrite query for mutation addUser because id alice already exists" +
" for type User",
Path: []interface{}{"addUser"},
}}, resp.Errors)
checkUserCount(t, resp.Data, 0)

Expand Down
89 changes: 20 additions & 69 deletions graphql/admin/admin.go
Original file line number Diff line number Diff line change
Expand Up @@ -347,11 +347,11 @@ var (
resolve.LoggingMWMutation,
}
adminQueryMWConfig = map[string]resolve.QueryMiddlewares{
"health": {resolve.IpWhitelistingMW4Query, resolve.LoggingMWQuery}, // dgraph checks Guardian auth for health
"state": {resolve.IpWhitelistingMW4Query, resolve.LoggingMWQuery}, // dgraph checks Guardian auth for state
"config": commonAdminQueryMWs,
"listBackups": commonAdminQueryMWs,
"getGQLSchema": commonAdminQueryMWs,
"health": {resolve.IpWhitelistingMW4Query, resolve.LoggingMWQuery}, // dgraph checks Guardian auth for health
"state": {resolve.IpWhitelistingMW4Query, resolve.LoggingMWQuery}, // dgraph checks Guardian auth for state
"config": commonAdminQueryMWs,
"listBackups": commonAdminQueryMWs,
"getGQLSchema": commonAdminQueryMWs,
// for queries and mutations related to User/Group, dgraph handles Guardian auth,
// so no need to apply GuardianAuth Middleware
"queryGroup": {resolve.IpWhitelistingMW4Query, resolve.LoggingMWQuery},
Expand Down Expand Up @@ -716,113 +716,64 @@ func (as *adminServer) addConnectedAdminResolvers() {

as.rf.WithMutationResolver("updateGQLSchema",
func(m schema.Mutation) resolve.MutationResolver {
return &updateSchemaResolver{
admin: as,
}
return &updateSchemaResolver{admin: as}
}).
WithQueryResolver("getGQLSchema",
func(q schema.Query) resolve.QueryResolver {
getResolver := &getSchemaResolver{
admin: as,
}

return resolve.NewQueryResolver(
getResolver,
getResolver,
resolve.StdQueryCompletion())
return &getSchemaResolver{admin: as}
}).
WithQueryResolver("queryGroup",
func(q schema.Query) resolve.QueryResolver {
return resolve.NewQueryResolver(
qryRw,
dgEx,
resolve.StdQueryCompletion())
return resolve.NewQueryResolver(qryRw, dgEx)
}).
WithQueryResolver("queryUser",
func(q schema.Query) resolve.QueryResolver {
return resolve.NewQueryResolver(
qryRw,
dgEx,
resolve.StdQueryCompletion())
return resolve.NewQueryResolver(qryRw, dgEx)
}).
WithQueryResolver("getGroup",
func(q schema.Query) resolve.QueryResolver {
return resolve.NewQueryResolver(
qryRw,
dgEx,
resolve.StdQueryCompletion())
return resolve.NewQueryResolver(qryRw, dgEx)
}).
WithQueryResolver("getCurrentUser",
func(q schema.Query) resolve.QueryResolver {
cuResolver := &currentUserResolver{
baseRewriter: qryRw,
}

return resolve.NewQueryResolver(
cuResolver,
dgEx,
resolve.StdQueryCompletion())
return resolve.NewQueryResolver(&currentUserResolver{baseRewriter: qryRw}, dgEx)
}).
WithQueryResolver("getUser",
func(q schema.Query) resolve.QueryResolver {
return resolve.NewQueryResolver(
qryRw,
dgEx,
resolve.StdQueryCompletion())
return resolve.NewQueryResolver(qryRw, dgEx)
}).
WithQueryResolver("getAllowedCORSOrigins", func(q schema.Query) resolve.QueryResolver {
return resolve.QueryResolverFunc(resolveGetCors)
}).
WithQueryResolver("querySchemaHistory", func(q schema.Query) resolve.QueryResolver {
// Add the desceding order to the created_at to get the schema history in
// Add the descending order to the created_at to get the schema history in
// descending order.
q.Arguments()["order"] = map[string]interface{}{"desc": "created_at"}
return resolve.NewQueryResolver(
qryRw,
dgEx,
resolve.StdQueryCompletion())
return resolve.NewQueryResolver(qryRw, dgEx)
}).
WithMutationResolver("addUser",
func(m schema.Mutation) resolve.MutationResolver {
return resolve.NewDgraphResolver(
resolve.NewAddRewriter(),
dgEx,
resolve.StdMutationCompletion(m.Name()))
return resolve.NewDgraphResolver(resolve.NewAddRewriter(), dgEx)
}).
WithMutationResolver("addGroup",
func(m schema.Mutation) resolve.MutationResolver {
return resolve.NewDgraphResolver(
NewAddGroupRewriter(),
dgEx,
resolve.StdMutationCompletion(m.Name()))
return resolve.NewDgraphResolver(NewAddGroupRewriter(), dgEx)
}).
WithMutationResolver("updateUser",
func(m schema.Mutation) resolve.MutationResolver {
return resolve.NewDgraphResolver(
resolve.NewUpdateRewriter(),
dgEx,
resolve.StdMutationCompletion(m.Name()))
return resolve.NewDgraphResolver(resolve.NewUpdateRewriter(), dgEx)
}).
WithMutationResolver("updateGroup",
func(m schema.Mutation) resolve.MutationResolver {
return resolve.NewDgraphResolver(
NewUpdateGroupRewriter(),
dgEx,
resolve.StdMutationCompletion(m.Name()))
return resolve.NewDgraphResolver(NewUpdateGroupRewriter(), dgEx)
}).
WithMutationResolver("deleteUser",
func(m schema.Mutation) resolve.MutationResolver {
return resolve.NewDgraphResolver(
resolve.NewDeleteRewriter(),
dgEx,
resolve.StdDeleteCompletion(m.Name()))
return resolve.NewDgraphResolver(resolve.NewDeleteRewriter(), dgEx)
}).
WithMutationResolver("deleteGroup",
func(m schema.Mutation) resolve.MutationResolver {
return resolve.NewDgraphResolver(
resolve.NewDeleteRewriter(),
dgEx,
resolve.StdDeleteCompletion(m.Name()))
return resolve.NewDgraphResolver(resolve.NewDeleteRewriter(), dgEx)
}).
WithMutationResolver("replaceAllowedCORSOrigins", func(m schema.Mutation) resolve.MutationResolver {
return resolve.MutationResolverFunc(resolveReplaceAllowedCORSOrigins)
Expand Down
9 changes: 5 additions & 4 deletions graphql/admin/backup.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,11 @@ func resolveBackup(ctx context.Context, m schema.Mutation) (*resolve.Resolved, b
return resolve.EmptyResult(m, err), false
}

return &resolve.Resolved{
Data: map[string]interface{}{m.Name(): response("Success", "Backup completed.")},
Field: m,
}, true
return resolve.DataResult(
m,
map[string]interface{}{m.Name(): response("Success", "Backup completed.")},
nil,
), true
}

func getBackupInput(m schema.Mutation) (*backupInput, error) {
Expand Down
24 changes: 13 additions & 11 deletions graphql/admin/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package admin
import (
"context"
"encoding/json"
"strconv"

"github.com/dgraph-io/dgraph/graphql/resolve"
"github.com/dgraph-io/dgraph/graphql/schema"
Expand Down Expand Up @@ -54,22 +55,23 @@ func resolveUpdateConfig(ctx context.Context, m schema.Mutation) (*resolve.Resol
worker.UpdateLogRequest(*input.LogRequest)
}

return &resolve.Resolved{
Data: map[string]interface{}{m.Name(): response("Success", "Config updated successfully")},
Field: m,
}, true
return resolve.DataResult(
m,
map[string]interface{}{m.Name(): response("Success", "Config updated successfully")},
nil,
), true
}

func resolveGetConfig(ctx context.Context, q schema.Query) *resolve.Resolved {
glog.Info("Got config query through GraphQL admin API")

conf := make(map[string]interface{})
conf["cacheMb"] = float64(worker.Config.CacheMb)

return &resolve.Resolved{
Data: map[string]interface{}{q.Name(): conf},
Field: q,
}
return resolve.DataResult(
q,
map[string]interface{}{q.Name(): map[string]interface{}{
"cacheMb": json.Number(strconv.FormatInt(worker.Config.CacheMb, 10)),
}},
nil,
)

}

Expand Down
35 changes: 13 additions & 22 deletions graphql/admin/cors.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,23 +47,23 @@ func resolveReplaceAllowedCORSOrigins(ctx context.Context, m schema.Mutation) (*
if err != nil {
return resolve.EmptyResult(m, err), false
}
// Aleast one origin is required to add allowlist. Since, no origin is provided, so we'll
// all origin to access dgraph.
// At-least one origin is required to add allowList. Since, no origin is provided, so we'll
// allow all origin to access dgraph.
if len(origins) == 0 {
origins = append(origins, "*")
}
if err = edgraph.AddCorsOrigins(ctx, origins); err != nil {
return resolve.EmptyResult(m, err), false
}
return &resolve.Resolved{
Data: map[string]interface{}{
return resolve.DataResult(
m,
map[string]interface{}{
m.Name(): map[string]interface{}{
"acceptedOrigins": arrayToInterface(origins),
"acceptedOrigins": toInterfaceSlice(origins),
},
},
Field: m,
Err: nil,
}, true
nil,
), true
}

// resolveGetCors retrieves cors details from the database.
Expand All @@ -72,21 +72,12 @@ func resolveGetCors(ctx context.Context, q schema.Query) *resolve.Resolved {
if err != nil {
return resolve.EmptyResult(q, err)
}
return &resolve.Resolved{
Data: map[string]interface{}{
return resolve.DataResult(
q,
map[string]interface{}{
q.Name(): map[string]interface{}{
"acceptedOrigins": arrayToInterface(origins),
"acceptedOrigins": toInterfaceSlice(origins),
},
},
Field: q,
}
}

// arrayToInterface convers array string to array interface
func arrayToInterface(in []string) []interface{} {
out := make([]interface{}, len(in))
for i, v := range in {
out[i] = v
}
return out
nil)
}
12 changes: 7 additions & 5 deletions graphql/admin/draining.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,13 @@ func resolveDraining(ctx context.Context, m schema.Mutation) (*resolve.Resolved,
enable := getDrainingInput(m)
x.UpdateDrainingMode(enable)

return &resolve.Resolved{
Data: map[string]interface{}{
m.Name(): response("Success", fmt.Sprintf("draining mode has been set to %v", enable))},
Field: m,
}, true
return resolve.DataResult(
m,
map[string]interface{}{
m.Name(): response("Success", fmt.Sprintf("draining mode has been set to %v", enable)),
},
nil,
), true
}

func getDrainingInput(m schema.Mutation) bool {
Expand Down
22 changes: 12 additions & 10 deletions graphql/admin/export.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,20 +63,22 @@ func resolveExport(ctx context.Context, m schema.Mutation) (*resolve.Resolved, b
}

responseData := response("Success", "Export completed.")
responseData["exportedFiles"] = toGraphQLArray(files)
responseData["exportedFiles"] = toInterfaceSlice(files)

return &resolve.Resolved{
Data: map[string]interface{}{m.Name(): responseData},
Field: m,
}, true
return resolve.DataResult(
m,
map[string]interface{}{m.Name(): responseData},
nil,
), true
}

func toGraphQLArray(s []string) []interface{} {
outputFiles := make([]interface{}, 0, len(s))
for _, f := range s {
outputFiles = append(outputFiles, f)
// toInterfaceSlice converts []string to []interface{}
func toInterfaceSlice(in []string) []interface{} {
out := make([]interface{}, 0, len(in))
for _, s := range in {
out = append(out, s)
}
return outputFiles
return out
}

func getExportInput(m schema.Mutation) (*exportInput, error) {
Expand Down
14 changes: 6 additions & 8 deletions graphql/admin/health.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ package admin

import (
"context"
"encoding/json"

"github.com/dgraph-io/dgraph/edgraph"
"github.com/dgraph-io/dgraph/graphql/resolve"
Expand All @@ -37,12 +36,11 @@ func resolveHealth(ctx context.Context, q schema.Query) *resolve.Resolved {
}

var health []map[string]interface{}
err = json.Unmarshal(resp.GetJson(), &health)

return &resolve.Resolved{
Data: map[string]interface{}{q.Name(): health},
Field: q,
Err: err,
}
err = resolve.Unmarshal(resp.GetJson(), &health)

return resolve.DataResult(
q,
map[string]interface{}{q.Name(): health},
err,
)
}
11 changes: 6 additions & 5 deletions graphql/admin/list_backups.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,17 +76,18 @@ func resolveListBackups(ctx context.Context, q schema.Query) *resolve.Resolved {
return resolve.EmptyResult(q, err)
}
var result map[string]interface{}
err = json.Unmarshal(b, &result)
err = resolve.Unmarshal(b, &result)
if err != nil {
return resolve.EmptyResult(q, err)
}
results = append(results, result)
}

return &resolve.Resolved{
Data: map[string]interface{}{q.Name(): results},
Field: q,
}
return resolve.DataResult(
q,
map[string]interface{}{q.Name(): results},
nil,
)
}

func getLsBackupInput(q schema.Query) (*lsBackupInput, error) {
Expand Down
Loading