blob: 0b2365467af235c1ab067e07d059bf2b433b7bc8 [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) {
giolekvacba39b82020-04-18 20:56:05 +040048 req := []byte(fmt.Sprintf(getQuery, typ, id))
giolekvac76b21b2020-04-18 19:28:43 +040049 glog.Info("Getting node with query:")
50 glog.Info(string(req))
51 resp, err := http.Post(g.serverAddress, "application/json", bytes.NewReader(req))
giolekvacba39b82020-04-18 20:56:05 +040052 glog.Infof("Response status: %d", resp.StatusCode)
giolekvac76b21b2020-04-18 19:28:43 +040053 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)
giolekvacba39b82020-04-18 20:56:05 +040071 if err != nil {
72 glog.Error(err)
73 http.Error(w, "Could not read HTTP request body", http.StatusInternalServerError)
74 return
75 }
giolekva07f6be92020-04-16 21:09:30 +040076 if len(body) == 0 {
77 return
78 }
giolekvac76b21b2020-04-18 19:28:43 +040079 glog.Infof("Received event from Minio: %s", string(body))
giolekvac76b21b2020-04-18 19:28:43 +040080 key, err := regogo.Get(string(body), "input.Key")
giolekva07f6be92020-04-16 21:09:30 +040081 if err != nil {
giolekvacba39b82020-04-18 20:56:05 +040082 glog.Error(err)
giolekvac76b21b2020-04-18 19:28:43 +040083 http.Error(w, "Could not find object key", http.StatusBadRequest)
giolekva07f6be92020-04-16 21:09:30 +040084 return
85 }
giolekvac76b21b2020-04-18 19:28:43 +040086 resp, err := m.gqlClient.Insert("Image", fmt.Sprintf(imgJson, key.String()))
giolekva07f6be92020-04-16 21:09:30 +040087 if err != nil {
giolekvacba39b82020-04-18 20:56:05 +040088 glog.Error(err)
giolekvac76b21b2020-04-18 19:28:43 +040089 http.Error(w, "Can not add given objects", http.StatusInternalServerError)
giolekva07f6be92020-04-16 21:09:30 +040090 return
91 }
giolekvacba39b82020-04-18 20:56:05 +040092 id, err := regogo.Get(resp, "input.data.addImage.image[0].id")
giolekva07f6be92020-04-16 21:09:30 +040093 if err != nil {
giolekvacba39b82020-04-18 20:56:05 +040094 glog.Error(err)
giolekvac76b21b2020-04-18 19:28:43 +040095 http.Error(w, "Could not extract node id", http.StatusInternalServerError)
giolekva07f6be92020-04-16 21:09:30 +040096 return
97 }
giolekva07f6be92020-04-16 21:09:30 +040098}
99
100func main() {
101 flag.Parse()
giolekvac76b21b2020-04-18 19:28:43 +0400102 dgraphAdminClient, err := schema.NewDgraphSchemaStore(*dgraphAdminAddress)
103 if err != nil {
104 panic(err)
105 }
106 err = dgraphAdminClient.SetSchema(`
107 type Image {
108 id: ID!
109 objectPath: String! @search(by: [exact])
110 segments: [ImageSegment] @hasInverse(field: sourceImage)
111 }
112
113 type ImageSegment {
114 id: ID!
115 upperLeftX: Int!
116 upperLeftY: Int!
117 lowerRightX: Int!
118 lowerRightY: Int!
119 sourceImage: Image!
120 objectPath: String
121 }`)
122 if err != nil {
123 panic(err)
124 }
125 mw := MinioWebhook{
126 &GraphQLClient{*graphqlAddress},
127 nil}
128 http.HandleFunc("/minio_webhook", mw.handler)
giolekva07f6be92020-04-16 21:09:30 +0400129 log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", *port), nil))
130}