blob: 5c3df86bfb8ae4086eafaf0c6c070ddac0f3e080 [file] [log] [blame]
giolekva07f6be92020-04-16 21:09:30 +04001package main
2
3import (
giolekva88d6e352020-04-30 13:32:38 +04004 "errors"
giolekva07f6be92020-04-16 21:09:30 +04005 "flag"
6 "fmt"
giolekvafb52e0d2020-04-23 22:52:13 +04007 "io"
giolekva07f6be92020-04-16 21:09:30 +04008 "io/ioutil"
9 "log"
10 "net/http"
giolekvafb52e0d2020-04-23 22:52:13 +040011
giolekvac76b21b2020-04-18 19:28:43 +040012 "github.com/giolekva/pcloud/controller/schema"
13
14 "github.com/golang/glog"
15 "github.com/itaysk/regogo"
giolekva07f6be92020-04-16 21:09:30 +040016)
17
giolekvafb52e0d2020-04-23 22:52:13 +040018var kubeconfig = flag.String("kubeconfig", "", "Absolute path to the kubeconfig file.")
19
giolekva07f6be92020-04-16 21:09:30 +040020var port = flag.Int("port", 123, "Port to listen on.")
giolekvafb52e0d2020-04-23 22:52:13 +040021var dgraphGqlAddress = flag.String("graphql_address", "", "GraphQL server address.")
22var dgraphSchemaAddress = flag.String("dgraph_admin_address", "", "Dgraph server admin address.")
giolekva07f6be92020-04-16 21:09:30 +040023
giolekvac76b21b2020-04-18 19:28:43 +040024const imgJson = `{ objectPath: \"%s\"}`
giolekvafb52e0d2020-04-23 22:52:13 +040025const insertQuery = `mutation { add%s(input: [%s]) { %s { id } } }`
giolekvac76b21b2020-04-18 19:28:43 +040026const getQuery = `{ "query": "{ get%s(id: \"%s\") { id objectPath } } " }`
27
giolekva180a0b92020-05-12 13:34:11 +040028type ApiHandler struct {
giolekva8fe32df2020-05-12 13:31:46 +040029 gql schema.GraphQLClient
giolekvafb52e0d2020-04-23 22:52:13 +040030}
31
giolekva88d6e352020-04-30 13:32:38 +040032type query struct {
33 query string
34 operation string
35 variables string
36}
37
38func extractQuery(r *http.Request) (*query, error) {
39 if r.Method == "GET" {
40 if err := r.ParseForm(); err != nil {
41 return nil, err
42 }
43 q, ok := r.Form["query"]
44 if !ok || len(q) != 1 {
45 return nil, errors.New("Exactly one query must be provided")
46 }
47 return &query{query: q[0]}, nil
48 } else {
49 body, err := ioutil.ReadAll(r.Body)
50 if err != nil {
51 return nil, err
52 }
53 q, err := regogo.Get(string(body), "input.query")
54 if err != nil {
55 return nil, err
56 }
57 return &query{query: q.String()}, nil
58 }
59}
60
giolekvafe0765f2020-05-12 14:09:09 +040061func (a *ApiHandler) graphql(w http.ResponseWriter, r *http.Request) {
giolekvafb52e0d2020-04-23 22:52:13 +040062 glog.Infof("New GraphQL query received: %s", r.Method)
giolekva88d6e352020-04-30 13:32:38 +040063 q, err := extractQuery(r)
giolekvafb52e0d2020-04-23 22:52:13 +040064 if err != nil {
giolekva88d6e352020-04-30 13:32:38 +040065 glog.Error(err.Error())
66 http.Error(w, "Could not extract query", http.StatusBadRequest)
giolekvafb52e0d2020-04-23 22:52:13 +040067 }
giolekva180a0b92020-05-12 13:34:11 +040068 resp, err := a.gql.RunQuery(q.query)
giolekvafb52e0d2020-04-23 22:52:13 +040069 if err != nil {
70 glog.Error(err)
71 http.Error(w, err.Error(), http.StatusInternalServerError)
72 return
73 }
74 io.WriteString(w, resp)
75 w.Header().Set("Content-Type", "application/json")
76}
77
giolekvafe0765f2020-05-12 14:09:09 +040078func (a *ApiHandler) addSchema(w http.ResponseWriter, r *http.Request) {
79 if r.Method != "POST" {
80 http.Error(w, "Only POST requests are accepted in /add_schema", http.StatusBadRequest)
81 return
82 }
83 body, err := ioutil.ReadAll(r.Body)
84 if err != nil {
85 http.Error(w, "Could not read request", http.StatusInternalServerError)
86 return
87 }
88 err = a.gql.AddSchema(string(body))
89 if err != nil {
90 http.Error(w, err.Error(), http.StatusPreconditionFailed)
91 return
92 }
93}
94
giolekva07f6be92020-04-16 21:09:30 +040095func main() {
96 flag.Parse()
giolekvafb52e0d2020-04-23 22:52:13 +040097 gqlClient, err := schema.NewDgraphClient(
98 *dgraphGqlAddress, *dgraphSchemaAddress)
99 if err != nil {
100 panic(err)
101 }
giolekva180a0b92020-05-12 13:34:11 +0400102 api := ApiHandler{gqlClient}
giolekvafe0765f2020-05-12 14:09:09 +0400103 http.HandleFunc("/graphql", api.graphql)
104 http.HandleFunc("/add_schema", api.addSchema)
giolekva07f6be92020-04-16 21:09:30 +0400105 log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", *port), nil))
106}