Skip to content

Commit

Permalink
feat(agent): Adding graphql trigger
Browse files Browse the repository at this point in the history
  • Loading branch information
xoscar committed Aug 23, 2024
1 parent 72b7997 commit 50b98a3
Show file tree
Hide file tree
Showing 3 changed files with 179 additions and 0 deletions.
86 changes: 86 additions & 0 deletions agent/workers/trigger/graphql.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package trigger

import (
"context"
"fmt"
)

func GRAPHQL(httpTriggerer Triggerer) Triggerer {
return &graphqlTriggerer{httpTriggerer}
}

type graphqlTriggerer struct {
httpTriggerer Triggerer
}

func (te *graphqlTriggerer) Trigger(ctx context.Context, triggerConfig Trigger, opts *Options) (Response, error) {
response := Response{
Result: TriggerResult{
Type: te.Type(),
},
}

if triggerConfig.Type != TriggerTypeGraphql {
return response, fmt.Errorf(`trigger type "%s" not supported by HTTP triggerer`, triggerConfig.Type)
}

triggerConfig = mapGraphqlToHttp(triggerConfig)

response, err := te.httpTriggerer.Trigger(ctx, triggerConfig, opts)
if err != nil {
return response, fmt.Errorf("error triggering Graphql trigger: %w", err)
}

return mapHttpToGraphql(response), nil
}

func (t *graphqlTriggerer) Type() TriggerType {
return TriggerTypeGraphql
}

const TriggerTypeGraphql TriggerType = "graphql"

func mapGraphqlToHttp(triggerConfig Trigger) Trigger {
return Trigger{
Type: TriggerTypeHTTP,
HTTP: &HTTPRequest{
URL: triggerConfig.Graphql.URL,
Method: HTTPMethodPOST,
Body: triggerConfig.Graphql.Body,
Headers: triggerConfig.Graphql.Headers,
SSLVerification: triggerConfig.Graphql.SSLVerification,
},
}
}

func mapHttpToGraphql(response Response) Response {
return Response{
TraceID: response.TraceID,
SpanID: response.SpanID,
SpanAttributes: response.SpanAttributes,
Result: TriggerResult{
Type: TriggerTypeGraphql,
Graphql: &GraphqlResponse{
Status: response.Result.HTTP.Status,
StatusCode: response.Result.HTTP.StatusCode,
Headers: response.Result.HTTP.Headers,
Body: response.Result.HTTP.Body,
},
},
}
}

type GraphqlRequest struct {
URL string `expr_enabled:"true" json:"url,omitempty"`
Body string `expr_enabled:"true" json:"body,omitempty"`
Headers []HTTPHeader `json:"headers,omitempty"`
Auth *HTTPAuthenticator `json:"auth,omitempty"`
SSLVerification bool `json:"sslVerification,omitempty"`
}

type GraphqlResponse struct {
Status string
StatusCode int
Headers []HTTPHeader
Body string
}
58 changes: 58 additions & 0 deletions agent/workers/trigger/graphql_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package trigger_test

import (
"io"
"net/http"
"net/http/httptest"
"testing"

"github.com/kubeshop/tracetest/agent/workers/trigger"
triggerer "github.com/kubeshop/tracetest/agent/workers/trigger"
"github.com/stretchr/testify/assert"
)

func TestGraphqlTrigger(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
t.Log(req.Header)

tp, ok := req.Header["Traceparent"]
if !ok {
t.Fatalf("missing Traceparent header %#v", req.Header)
}
assert.Len(t, tp, 1)

assert.Equal(t, "POST", req.Method)
assert.Equal(t, "Value1", req.Header.Get("Key1"))

b, err := io.ReadAll(req.Body)
assert.NoError(t, err)
assert.Equal(t, `query { films { name } }`, string(b))

rw.Header().Add("Content-Type", "application/json")
rw.WriteHeader(200)
_, err = rw.Write([]byte(`{ "data": { "films": [{ "name": "A New Hope" }] } }`))
assert.NoError(t, err)
}))
defer server.Close()

triggerConfig := trigger.Trigger{
Type: trigger.TriggerTypeGraphql,
Graphql: &trigger.GraphqlRequest{
URL: server.URL,
Headers: []trigger.HTTPHeader{
{Key: "Key1", Value: "Value1"},
},
Body: `query { films { name } }`,
},
}

httpTriggerer := triggerer.HTTP()

ex := triggerer.GRAPHQL(httpTriggerer)

resp, err := ex.Trigger(createContext(), triggerConfig, nil)
assert.NoError(t, err)

assert.Equal(t, 200, resp.Result.Graphql.StatusCode)
assert.Equal(t, `{ "data": { "films": [{ "name": "A New Hope" }] } }`, resp.Result.Graphql.Body)
}
35 changes: 35 additions & 0 deletions api/graphql.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
openapi: 3.0.0
components:
schemas:
GraphqlRequest:
type: object
properties:
url:
type: string
headers:
type: array
items:
$ref: "./http.yaml#/components/schemas/HTTPHeader"
auth:
$ref: "./http.yaml#/components/schemas/HTTPAuth"
body:
type: string
sslVerification:
type: boolean
default: false
schema:
type: string

GraphqlResponse:
type: object
properties:
status:
type: string
statusCode:
type: integer
headers:
type: array
items:
$ref: "#/components/schemas/HTTPHeader"
body:
type: string

0 comments on commit 50b98a3

Please sign in to comment.