Skip to content

Commit

Permalink
Merge pull request #5 from bmeg/feature/testing
Browse files Browse the repository at this point in the history
Feature/testing
  • Loading branch information
matthewpeterkort authored Aug 27, 2024
2 parents e66b69a + a268bd7 commit 57ad725
Show file tree
Hide file tree
Showing 8 changed files with 185 additions and 193 deletions.
30 changes: 16 additions & 14 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,27 +1,29 @@
FROM golang:1.22.6-alpine AS build-env
RUN apk add --no-cache bash
RUN apk add make git bash build-base libc-dev binutils-gold
RUN apk add make git bash build-base libc-dev binutils-gold curl
ENV GOPATH=/go
ENV PATH="/go/bin:${PATH}"

WORKDIR /go/src/github.com/bmeg/grip-graphql
ADD ./ /go/src/github.com/bmeg/grip-graphql

RUN go install github.com/bmeg/[email protected]20240808185832-ab51dee8a7aa
RUN go install github.com/bmeg/[email protected]20240812223417-99c314b06713
RUN go build --buildmode=plugin ./graphql_gen3
RUN go build --buildmode=plugin ./gen3_writer
RUN go build --buildmode=plugin ./grip-graphql-endpoint

RUN cp /go/src/github.com/bmeg/grip-graphql/mongo.yml /mongo.yml
RUN cp /go/src/github.com/bmeg/grip-graphql/mongo.yml /
RUN cp /go/src/github.com/bmeg/grip-graphql/gen3_writer.so /
RUN cp /go/src/github.com/bmeg/grip-graphql/graphql_gen3.so /
RUN cp /go/src/github.com/bmeg/grip-graphql/grip-graphql-endpoint.so /


#FROM alpine
#WORKDIR /data
#VOLUME /data
#ENV PATH="/app:${PATH}"
#COPY --from=build-env /graphql_gen3.so /data/
#COPY --from=build-env /gen3_writer.so /data/
#COPY --from=build-env /graphql_peregrine.so /data/
#COPY --from=build-env /schema.json /data/
#COPY --from=build-env /mongo.yml /data/
#COPY --from=build-env /go/bin/grip /app/

FROM alpine
WORKDIR /data
VOLUME /data
ENV PATH="/app:${PATH}"
COPY --from=build-env /graphql_gen3.so /data/
COPY --from=build-env /gen3_writer.so /data/
COPY --from=build-env /grip-graphql-endpoint.so /data/
COPY --from=build-env /mongo.yml /data/
COPY --from=build-env /go/bin/grip /app/
195 changes: 94 additions & 101 deletions gen3_writer/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ import (
"google.golang.org/protobuf/encoding/protojson"
)


type Handler struct {
router *gin.Engine
client gripql.Client
Expand All @@ -42,7 +41,7 @@ func getFields(c *gin.Context) (gin.ResponseWriter, *http.Request, string) {
}

func convertAnyToStringSlice(anySlice []any) ([]string, error) {
/* converts []any to []string */
/* converts []any to []string */
var stringSlice []string
for _, v := range anySlice {
str, ok := v.(string)
Expand All @@ -55,8 +54,8 @@ func convertAnyToStringSlice(anySlice []any) ([]string, error) {
}

func ParseAccess(c *gin.Context, resourceList []string, resource string, method string) error {
/* Iterates through a list of Gen3 resoures and returns true if
resource matches the allowable list of resource types for the provided method */
/* Iterates through a list of Gen3 resoures and returns true if
resource matches the allowable list of resource types for the provided method */

if len(resourceList) == 0 {
return &middleware.ServerError{StatusCode: 401, Message: fmt.Sprintf("User is not allowed to %s on any resource path", method)}
Expand All @@ -70,23 +69,19 @@ func ParseAccess(c *gin.Context, resourceList []string, resource string, method
}

func TokenAuthMiddleware() gin.HandlerFunc {
/* Authentication middleware function. Maps HTTP method to expected permssions.
If user permissions don't match, abort command and return 401 */
/* Authentication middleware function. Maps HTTP method to expected permssions.
If user permissions don't match, abort command and return 401 */

return func(c *gin.Context) {
// If request path is open access then no token needed no project_id needed.
if c.Request.URL.Path == "list-graphs"{
c.Next()
return
}

project_split := strings.Split(c.Param("project-id"), "-")
if len(project_split) != 2{
// This error usually occurs when part of the path is correct or a typo in path.
RegError(c, c.Writer, c.Param("graph"), &middleware.ServerError{StatusCode: 404, Message: fmt.Sprintf("incorrect path %s", c.Request.URL)})
return
}
project_id := "/programs/" + project_split[0] + "/projects/" + project_split[1]
// If request path is open access then no token needed no project_id needed.
project_split := strings.Split(c.Param("project-id"), "-")
if len(project_split) != 2 {
// This error usually occurs when part of the path is correct or a typo in path.
RegError(c, c.Writer, c.Param("graph"), &middleware.ServerError{StatusCode: 404, Message: fmt.Sprintf("incorrect path %s", c.Request.URL)})
return
}

project_id := "/programs/" + project_split[0] + "/projects/" + project_split[1]
requestHeaders := c.Request.Header
if val, ok := requestHeaders["Authorization"]; ok {
Token := val[0]
Expand All @@ -112,11 +107,11 @@ func TokenAuthMiddleware() gin.HandlerFunc {
return
}

log.Infof("Resource List for method '%s': %s", method, resourceList)
log.Infof("Resource List for method '%s': %s", method, resourceList)
err = ParseAccess(c, resourceList, project_id, method)
if err != nil{
RegError(c, c.Writer, c.Param("graph"), err)
return
if err != nil {
RegError(c, c.Writer, c.Param("graph"), err)
return
}
} else {
RegError(c, c.Writer, c.Param("graph"), &middleware.ServerError{StatusCode: 400, Message: "Authorization token not provided"})
Expand All @@ -126,97 +121,96 @@ func TokenAuthMiddleware() gin.HandlerFunc {
}
}


func NewHTTPHandler(client gripql.Client, config map[string]string) (http.Handler, error) {
// Including below line to run in prod mode
// Including below line to run in prod mode

gin.SetMode(gin.ReleaseMode)
gin.SetMode(gin.ReleaseMode)
r := gin.New()

// Since using Grip logging functions, log config needs to be set to properly format JSON data outputs
logConfig := log.Logger{
Level: "info",
Formatter: "json",
}
log.ConfigureLogger(logConfig)
// Since using Grip logging functions, log config needs to be set to properly format JSON data outputs
logConfig := log.Logger{
Level: "info",
Formatter: "json",
}
log.ConfigureLogger(logConfig)

r.Use(gin.Logger())

r.NoRoute(func(c *gin.Context) {
log.WithFields(log.Fields{
"graph": nil,
"status": "404",
}).Info(c.Request.URL.Path + " Not Found")
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{
"status": "404",
"message": c.Request.URL.Path + " Not Found",
"data": nil,
})
})

r.Use(TokenAuthMiddleware())
r.NoRoute(func(c *gin.Context) {
log.WithFields(log.Fields{
"graph": nil,
"status": "404",
}).Info(c.Request.URL.Path + " Not Found")
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{
"status": "404",
"message": c.Request.URL.Path + " Not Found",
"data": nil,
})
})
r.Use(gin.Recovery())

// Was getting 404s before adding this.
r.RemoveExtraSlash = true


h := &Handler{
router: r,
client: client,
config: config,
}

r.POST(":graph/add-vertex/:project-id", func(c *gin.Context) {
r.GET("list-graphs", func(c *gin.Context) {
h.ListGraphs(c, c.Writer)
})
r.GET("_status", func(c *gin.Context) {
Response(c, c.Writer, "", 200, 200, fmt.Sprintf("[200] healthy _status"))
})

g := r.Group(":graph")
g.Use(TokenAuthMiddleware())
g.POST("/add-vertex/:project-id", func(c *gin.Context) {
h.WriteVertex(c)
})
r.POST(":graph/add-edge/:project-id", func(c *gin.Context) {
g.POST("/add-edge/:project-id", func(c *gin.Context) {
h.WriteEdge(c)
})
r.POST(":graph/add-graph/:project-id", func(c *gin.Context) {
g.POST("/add-graph/:project-id", func(c *gin.Context) {
h.AddGraph(c)
})
r.POST(":graph/mongo-load/:project-id", func(c *gin.Context) {
g.POST("/mongo-load/:project-id", func(c *gin.Context) {
h.MongoBulk(c)
})
r.POST(":graph/bulk-load/:project-id", func(c *gin.Context) {
g.POST("/bulk-load/:project-id", func(c *gin.Context) {
h.BulkStream(c)
})
r.POST(":graph/add-schema/:project-id", func(c *gin.Context) {
g.POST("/add-schema/:project-id", func(c *gin.Context) {
h.AddSchema(c)
})
r.DELETE(":graph/del-graph/:project-id", func(c *gin.Context) {
g.DELETE("/del-graph/:project-id", func(c *gin.Context) {
h.DeleteGraph(c)
})
r.DELETE(":graph/del-edge/:edge-id/:project-id", func(c *gin.Context) {
g.DELETE("/del-edge/:edge-id/:project-id", func(c *gin.Context) {
h.DeleteEdge(c, c.Param("edge-id"))
})
r.DELETE(":graph/del-vertex/:vertex-id/:project-id", func(c *gin.Context) {
g.DELETE("/del-vertex/:vertex-id/:project-id", func(c *gin.Context) {
h.DeleteVertex(c, c.Param("vertex-id"))
})
r.DELETE(":graph/bulk-delete/:project-id", func(c *gin.Context) {
g.DELETE("/bulk-delete/:project-id", func(c *gin.Context) {
h.BulkDelete(c)
})
r.DELETE(":graph/proj-delete/:project-id", func(c *gin.Context) {
h.ProjectDelete(c)
})
r.GET(":graph/list-labels/:project-id", func(c *gin.Context) {
g.DELETE("/proj-delete/:project-id", func(c *gin.Context) {
h.ProjectDelete(c)
})
g.GET("/list-labels", func(c *gin.Context) {
h.ListLabels(c)
})
r.GET(":graph/get-schema/:project-id", func(c *gin.Context) {
g.GET("/get-schema/:project-id", func(c *gin.Context) {
h.GetSchema(c)
})
r.GET(":graph/get-graph/:project-id", func(c *gin.Context) {
g.GET("/get-graph/:project-id", func(c *gin.Context) {
h.GetGraph(c)
})
r.GET(":graph/get-vertex/:vertex-id/:project-id", func(c *gin.Context) {
g.GET("/get-vertex/:vertex-id/:project-id", func(c *gin.Context) {
h.GetVertex(c, c.Param("vertex-id"))
})
r.GET("list-graphs", func(c *gin.Context) {
h.ListGraphs(c, c.Writer)
})


return h, nil
}

Expand Down Expand Up @@ -315,7 +309,7 @@ func (gh *Handler) AddSchema(c *gin.Context) {

graphs, err = gripql.ParseJSONGraphs(buf.Bytes())
if err != nil {
RegError(c, writer, graph, GetInternalServerErr(fmt.Errorf("json parse error: %s", err)))
RegError(c, writer, graph, GetInternalServerErr(fmt.Errorf("json parse error: %s", err)))
return
}
for _, g := range graphs {
Expand Down Expand Up @@ -444,37 +438,36 @@ func (gh *Handler) BulkDelete(c *gin.Context) {
}

func (gh *Handler) ProjectDelete(c *gin.Context) {
ctx := context.Background()
var delVs []string

writer, _, graph := getFields(c)
project_id := c.Param("project-id")
str_split := strings.Split(project_id, "-")
project := "/programs/" + str_split[0] + "/projects/" + str_split[1]


Vquery := gripql.V().Has(gripql.Eq("auth_resource_path", project)).Render("_gid")
query := &gripql.GraphQuery{Graph: c.Param("graph"), Query: Vquery.Statements}
result, err := gh.client.Traversal(ctx, query);
if err != nil{
RegError(c, writer, graph, GetInternalServerErr(err))
return
}

/* Running bulkDelete with only the vertex ids specified will remove all of the disconnected edges caused by removing
All vertices in the graph. */
for i := range result {
v := i.ToInterface().(map[string]any)["render"].(string)
delVs = append(delVs, v)
}

delData := &gripql.DeleteData{Graph: graph, Vertices: delVs, Edges: []string{}}

if err := gh.client.BulkDelete(delData); err != nil {
RegError(c, writer, graph, GetInternalServerErr(err))
return
}
Response(c, writer, graph, nil, 200, fmt.Sprintf("[200] project-delete on project %s", project_id))
ctx := context.Background()
var delVs []string

writer, _, graph := getFields(c)
project_id := c.Param("project-id")
str_split := strings.Split(project_id, "-")
project := "/programs/" + str_split[0] + "/projects/" + str_split[1]

Vquery := gripql.V().Has(gripql.Eq("auth_resource_path", project)).Render("_gid")
query := &gripql.GraphQuery{Graph: c.Param("graph"), Query: Vquery.Statements}
result, err := gh.client.Traversal(ctx, query)
if err != nil {
RegError(c, writer, graph, GetInternalServerErr(err))
return
}

/* Running bulkDelete with only the vertex ids specified will remove all of the disconnected edges caused by removing
All vertices in the graph. */
for i := range result {
v := i.ToInterface().(map[string]any)["render"].(string)
delVs = append(delVs, v)
}

delData := &gripql.DeleteData{Graph: graph, Vertices: delVs, Edges: []string{}}

if err := gh.client.BulkDelete(delData); err != nil {
RegError(c, writer, graph, GetInternalServerErr(err))
return
}
Response(c, writer, graph, nil, 200, fmt.Sprintf("[200] project-delete on project %s", project_id))
}

func (gh *Handler) WriteVertex(c *gin.Context) {
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module github.com/bmeg/grip-graphql
go 1.22.6

require (
github.com/bmeg/grip v0.0.0-20240808185832-ab51dee8a7aa
github.com/bmeg/grip v0.0.0-20240812223417-99c314b06713
github.com/dop251/goja v0.0.0-20240707163329-b1681fb2a2f5
github.com/gin-gonic/gin v1.8.1
github.com/golang-jwt/jwt/v5 v5.2.1
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ github.com/antlr/antlr4/runtime/Go/antlr v1.4.10 h1:yL7+Jz0jTC6yykIK/Wh74gnTJnrG
github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230512164433-5d1fd1a340c9 h1:goHVqTbFX3AIo0tzGr14pgfAW2ZfPChKO21Z9MGf/gk=
github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230512164433-5d1fd1a340c9/go.mod h1:pSwJ0fSY5KhvocuWSx4fz3BA8OrA1bQn+K1Eli3BRwM=
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
github.com/bmeg/grip v0.0.0-20240808185832-ab51dee8a7aa h1:jNZWh1aEEReKUnncVarAHhgg6HHp1Av+A5PBbOa1Srs=
github.com/bmeg/grip v0.0.0-20240808185832-ab51dee8a7aa/go.mod h1:8gAdpKQAoY/Cf1dfubAN3xyHX/hmbUiC1XPi12VVSUk=
github.com/bmeg/grip v0.0.0-20240812223417-99c314b06713 h1:uRQAIqpcofB6b3QUa77au2UJ71KESBlolIFfl09fLDM=
github.com/bmeg/grip v0.0.0-20240812223417-99c314b06713/go.mod h1:8gAdpKQAoY/Cf1dfubAN3xyHX/hmbUiC1XPi12VVSUk=
github.com/bmeg/jsonpath v0.0.0-20210207014051-cca5355553ad h1:ICgBexeLB7iv/IQz4rsP+MimOXFZUwWSPojEypuOaQ8=
github.com/bmeg/jsonpath v0.0.0-20210207014051-cca5355553ad/go.mod h1:ft96Irkp72C7ZrUWRenG7LrF0NKMxXdRvsypo5Njhm4=
github.com/bufbuild/protovalidate-go v0.4.0 h1:ModSkCLEW07fiyGtdtMXKY+Gz3oPFKSfiaSCgL+FtpU=
Expand Down
8 changes: 4 additions & 4 deletions gripgraphql/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ func (e *Endpoint) Add(x map[string]any) {
objField, err := parseField(name, schemaA)
if err == nil {
objField.Resolve = func(params graphql.ResolveParams) (interface{}, error) {
fmt.Printf("Calling resolver \n")
log.Infof("Calling resolver \n")
uArgs := map[string]any{}
for k, v := range defaults {
uArgs[k] = v
Expand Down Expand Up @@ -266,14 +266,14 @@ func NewHTTPHandler(client gripql.Client, config map[string]string) (http.Handle
}
var hnd *handler.Handler

fmt.Println("NEW POOL IS BEING MADE ==============================================================+")
log.Infof("Creating new pool ==============================================================")
Pool := sync.Pool{
New: func() any {
vm := goja.New()
vm.SetFieldNameMapper(JSRenamer{})
jsClient, err := GetJSClient(graph, client, vm)
if err != nil {
fmt.Printf("js error: %s\n", err)
log.Infof("js error: %s\n", err)
}

e := &Endpoint{queryNodes: map[string]QueryField{}, client: client, vm: vm, cw: jsClient}
Expand Down Expand Up @@ -344,7 +344,7 @@ func (gh *GraphQLJS) ServeHTTP(writer http.ResponseWriter, request *http.Request
ctx = context.WithValue(ctx, "ResourceList", resourceList)
} else {
err := middleware.HandleError(&middleware.ServerError{StatusCode: http.StatusUnauthorized, Message: "No authorization header provided."}, writer)
fmt.Println("ERR: ", err)
log.Infoln("ERR: ", err)
return err
}

Expand Down
Loading

0 comments on commit 57ad725

Please sign in to comment.