blob: bd37cac32bd2d19a5818c53fc8ecd074641f8643 [file] [log] [blame]
giolekva07f6be92020-04-16 21:09:30 +04001package main
2
3import (
4 "bytes"
giolekva07f6be92020-04-16 21:09:30 +04005 "flag"
6 "fmt"
7 "io/ioutil"
8 "log"
9 "net/http"
giolekvac76b21b2020-04-18 19:28:43 +040010 "strings"
11
12 "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
18var port = flag.Int("port", 123, "Port to listen on.")
giolekvac76b21b2020-04-18 19:28:43 +040019var graphqlAddress = flag.String("graphql_address", "", "GraphQL server address.")
20var dgraphAdminAddress = flag.String("dgraph_admin_address", "", "Dgraph server admin address.")
giolekva07f6be92020-04-16 21:09:30 +040021
giolekvac76b21b2020-04-18 19:28:43 +040022const imgJson = `{ objectPath: \"%s\"}`
23const insertQuery = `{ "query": "mutation { add%s(input: [%s]) { %s { id } } }" }`
24const getQuery = `{ "query": "{ get%s(id: \"%s\") { id objectPath } } " }`
25
26type GraphQLClient struct {
27 serverAddress string
28}
29
30func (g *GraphQLClient) Insert(typ string, obj string) (string, error) {
31 req := []byte(fmt.Sprintf(insertQuery, typ, obj, strings.ToLower(typ)))
32 glog.Info("Insering new item, mutation query:")
33 glog.Info(string(req))
34 resp, err := http.Post(g.serverAddress, "application/json", bytes.NewReader(req))
35 glog.Infof("Response status: %d", resp.StatusCode)
36 if err != nil {
37 return "", err
38 }
39 respBody, err := ioutil.ReadAll(resp.Body)
40 if err != nil {
41 return "", err
42 }
43 glog.Infof("Response: %s", string(respBody))
44 return string(respBody), nil
45}
46
47func (g *GraphQLClient) Get(typ string, id string) (string, error) {
48 req := []byte(fmt.Sprintf(insertQuery, typ, id, strings.ToLower(typ)))
49 glog.Info("Getting node with query:")
50 glog.Info(string(req))
51 resp, err := http.Post(g.serverAddress, "application/json", bytes.NewReader(req))
52 glog.Infof("Response status: %s", resp.StatusCode)
53 if err != nil {
54 return "", err
55 }
56 respBody, err := ioutil.ReadAll(resp.Body)
57 if err != nil {
58 return "", err
59 }
60 glog.Info(string(respBody))
61 return string(respBody), nil
62}
63
64type MinioWebhook struct {
65 gqlClient *GraphQLClient
66 dgraphAdminClient schema.SchemaStore
67}
68
69func (m *MinioWebhook) handler(w http.ResponseWriter, r *http.Request) {
giolekva07f6be92020-04-16 21:09:30 +040070 body, err := ioutil.ReadAll(r.Body)
71 if len(body) == 0 {
72 return
73 }
giolekvac76b21b2020-04-18 19:28:43 +040074 glog.Infof("Received event from Minio: %s", string(body))
giolekva07f6be92020-04-16 21:09:30 +040075 if err != nil {
giolekva07f6be92020-04-16 21:09:30 +040076 http.Error(w, "Could not read HTTP request body", http.StatusInternalServerError)
77 return
78 }
giolekvac76b21b2020-04-18 19:28:43 +040079 key, err := regogo.Get(string(body), "input.Key")
giolekva07f6be92020-04-16 21:09:30 +040080 if err != nil {
giolekvac76b21b2020-04-18 19:28:43 +040081 http.Error(w, "Could not find object key", http.StatusBadRequest)
giolekva07f6be92020-04-16 21:09:30 +040082 return
83 }
giolekvac76b21b2020-04-18 19:28:43 +040084 resp, err := m.gqlClient.Insert("Image", fmt.Sprintf(imgJson, key.String()))
giolekva07f6be92020-04-16 21:09:30 +040085 if err != nil {
giolekvac76b21b2020-04-18 19:28:43 +040086 http.Error(w, "Can not add given objects", http.StatusInternalServerError)
giolekva07f6be92020-04-16 21:09:30 +040087 return
88 }
giolekvac76b21b2020-04-18 19:28:43 +040089 id, err := regogo.Get(resp, "input.data.addImage.image[0]id")
giolekva07f6be92020-04-16 21:09:30 +040090 if err != nil {
giolekvac76b21b2020-04-18 19:28:43 +040091 http.Error(w, "Could not extract node id", http.StatusInternalServerError)
giolekva07f6be92020-04-16 21:09:30 +040092 return
93 }
giolekvac76b21b2020-04-18 19:28:43 +040094 resp, err = m.gqlClient.Get("Image", id.String())
95 if err != nil {
96 http.Error(w, "Could not fetch node", http.StatusInternalServerError)
97 return
98 }
giolekva07f6be92020-04-16 21:09:30 +040099}
100
101func main() {
102 flag.Parse()
giolekvac76b21b2020-04-18 19:28:43 +0400103 dgraphAdminClient, err := schema.NewDgraphSchemaStore(*dgraphAdminAddress)
104 if err != nil {
105 panic(err)
106 }
107 err = dgraphAdminClient.SetSchema(`
108 type Image {
109 id: ID!
110 objectPath: String! @search(by: [exact])
111 segments: [ImageSegment] @hasInverse(field: sourceImage)
112 }
113
114 type ImageSegment {
115 id: ID!
116 upperLeftX: Int!
117 upperLeftY: Int!
118 lowerRightX: Int!
119 lowerRightY: Int!
120 sourceImage: Image!
121 objectPath: String
122 }`)
123 if err != nil {
124 panic(err)
125 }
126 mw := MinioWebhook{
127 &GraphQLClient{*graphqlAddress},
128 nil}
129 http.HandleFunc("/minio_webhook", mw.handler)
giolekva07f6be92020-04-16 21:09:30 +0400130 log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", *port), nil))
131}