Commit 8dbe745c3c68225cda3bf800460592e7f6184038

Authored by Marko Tikvić
1 parent 39765a4304
Exists in master and in 1 other branch v2

merged tables utility into JSON utility

1 package restutility 1 package restutility
2 2
3 import ( 3 import (
4 "net/http" 4 "net/http"
5 "encoding/json" 5 "encoding/json"
6 ) 6 )
7 7
8 var _apiVersion = "/api/v1" 8 var _apiVersion = "/api/v1"
9 9
10 func SetApiVersion(ver string) string { 10 func SetApiVersion(ver string) string {
11 _apiVersion = ver 11 _apiVersion = ver
12 return _apiVersion 12 return _apiVersion
13 } 13 }
14 14
15 //// 15 ////
16 //// ERROR UTILITY 16 //// ERROR UTILITY
17 //// 17 ////
18 18
19 const templateHttpErr500_EN = "An internal server error has occurred." 19 const templateHttpErr500_EN = "An internal server error has occurred."
20 const templateHttpErr500_RS = "Došlo je do greške na serveru." 20 const templateHttpErr500_RS = "Došlo je do greške na serveru."
21 const templateHttpErr400_EN = "Bad request: invalid request body." 21 const templateHttpErr400_EN = "Bad request: invalid request body."
22 const templateHttpErr400_RS = "Neispravan zahtev." 22 const templateHttpErr400_RS = "Neispravan zahtev."
23 23
24 type HttpError struct { 24 type HttpError struct {
25 Error []HttpErrorDesc `json:"error"` 25 Error []HttpErrorDesc `json:"error"`
26 Request string `json:"request"` 26 Request string `json:"request"`
27 } 27 }
28 28
29 type HttpErrorDesc struct { 29 type HttpErrorDesc struct {
30 Lang string `json:"lang"` 30 Lang string `json:"lang"`
31 Desc string `json:"description"` 31 Desc string `json:"description"`
32 } 32 }
33 33
34 func RespondWithHttpError(w http.ResponseWriter, 34 func RespondWithHttpError(w http.ResponseWriter,
35 req *http.Request, 35 req *http.Request,
36 code int, 36 code int,
37 httpErr []HttpErrorDesc) { 37 httpErr []HttpErrorDesc) {
38 38
39 err := HttpError{ 39 err := HttpError{
40 Error: httpErr, 40 Error: httpErr,
41 Request: req.Method + " " + req.URL.Path, 41 Request: req.Method + " " + req.URL.Path,
42 } 42 }
43 w.WriteHeader(code) 43 w.WriteHeader(code)
44 json.NewEncoder(w).Encode(err) 44 json.NewEncoder(w).Encode(err)
45 } 45 }
46 46
47 func RespondWithHttpError400(w http.ResponseWriter, req *http.Request) { 47 func RespondWithHttpError400(w http.ResponseWriter, req *http.Request) {
48 RespondWithHttpError(w, req, http.StatusBadRequest, []HttpErrorDesc{ 48 RespondWithHttpError(w, req, http.StatusBadRequest, []HttpErrorDesc{
49 {Lang: "en", Desc: templateHttpErr400_EN}, 49 {Lang: "en", Desc: templateHttpErr400_EN},
50 {Lang: "rs", Desc: templateHttpErr400_RS}, 50 {Lang: "rs", Desc: templateHttpErr400_RS},
51 }) 51 })
52 } 52 }
53 53
54 func RespondWithHttpError500(w http.ResponseWriter, req *http.Request) { 54 func RespondWithHttpError500(w http.ResponseWriter, req *http.Request) {
55 RespondWithHttpError(w, req, http.StatusInternalServerError, []HttpErrorDesc{ 55 RespondWithHttpError(w, req, http.StatusInternalServerError, []HttpErrorDesc{
56 {Lang: "en", Desc: templateHttpErr500_EN}, 56 {Lang: "en", Desc: templateHttpErr500_EN},
57 {Lang: "rs", Desc: templateHttpErr500_RS}, 57 {Lang: "rs", Desc: templateHttpErr500_RS},
58 }) 58 })
59 } 59 }
60 60
61 func DeliverPayload(w http.ResponseWriter, payload JSONPayload) {
62 json.NewEncoder(w).Encode(payload)
63 payload.Data = nil
64 }
65
66 //// 61 ////
67 //// HANDLER FUNC WRAPPER 62 //// HANDLER FUNC WRAPPER
68 //// 63 ////
69 64
70 // wrapHandlerFunc is as wrapper function for route handlers.
71 // Sets common headers and checks for token validity. 65 // Sets common headers and checks for token validity.
72 func HandleFuncWrap(fn http.HandlerFunc) http.HandlerFunc { 66 func ProcessHeaders(fn http.HandlerFunc) http.HandlerFunc {
73 return func(w http.ResponseWriter, req *http.Request) { 67 return func(w http.ResponseWriter, req *http.Request) {
74 // @TODO: check Content-type header (must be application/json) 68 // @TODO: check Content-type header (must be application/json)
75 // ctype := w.Header.Get("Content-Type") 69 // ctype := w.Header.Get("Content-Type")
76 // if req.Method != "GET" && ctype != "application/json" { 70 // if req.Method != "GET" && ctype != "application/json" {
77 // replyWithHttpError(w, req, http.StatusBadRequest, 71 // replyWithHttpError(w, req, http.StatusBadRequest,
78 // "Not a supported content type: " + ctype) 72 // "Not a supported content type: " + ctype)
79 // } 73 // }
80 74
81 w.Header().Set("Access-Control-Allow-Origin", "*") 75 w.Header().Set("Access-Control-Allow-Origin", "*")
82 w.Header().Set("Access-Control-Allow-Methods", 76 w.Header().Set("Access-Control-Allow-Methods",
83 `POST, 77 `POST,
84 GET, 78 GET,
85 PUT, 79 PUT,
86 DELETE, 80 DELETE,
87 OPTIONS`) 81 OPTIONS`)
88 w.Header().Set("Access-Control-Allow-Headers", 82 w.Header().Set("Access-Control-Allow-Headers",
89 `Accept, 83 `Accept,
90 Content-Type, 84 Content-Type,
91 Content-Length, 85 Content-Length,
92 Accept-Encoding, 86 Accept-Encoding,
93 X-CSRF-Token, 87 X-CSRF-Token,
94 Authorization`) 88 Authorization`)
95 w.Header().Set("Content-Type", "application/json; charset=utf-8") 89 w.Header().Set("Content-Type", "application/json; charset=utf-8")
96 90
97 if req.Method == "OPTIONS" { 91 if req.Method == "OPTIONS" {
98 return 92 return
99 } 93 }
100 94
101 if req.URL.Path != _apiVersion + "/token/new" { 95 if req.URL.Path != _apiVersion + "/token/new" {
102 token := req.Header.Get("Authorization") 96 token := req.Header.Get("Authorization")
103 if _, err := ParseAPIToken(token); err != nil { 97 if _, err := ParseAPIToken(token); err != nil {
104 RespondWithHttpError(w, req, http.StatusUnauthorized, 98 RespondWithHttpError(w, req, http.StatusUnauthorized,
105 []HttpErrorDesc{ 99 []HttpErrorDesc{
106 {Lang: "en", Desc: "Unauthorized request."}, 100 {Lang: "en", Desc: "Unauthorized request."},
107 {Lang: "rs", Desc: "Neautorizovani zahtev."}, 101 {Lang: "rs", Desc: "Neautorizovani zahtev."},
108 }) 102 })
109 return 103 return
110 } 104 }
111 } 105 }
112 106
113 err := req.ParseForm() 107 err := req.ParseForm()
114 if err != nil { 108 if err != nil {
115 RespondWithHttpError(w, req, http.StatusBadRequest, 109 RespondWithHttpError(w, req, http.StatusBadRequest,
116 []HttpErrorDesc{ 110 []HttpErrorDesc{
117 {Lang: "en", Desc: templateHttpErr400_EN}, 111 {Lang: "en", Desc: templateHttpErr400_EN},
118 {Lang: "rs", Desc: templateHttpErr400_RS}, 112 {Lang: "rs", Desc: templateHttpErr400_RS},
119 }) 113 })
120 return 114 return
121 } 115 }
122 fn(w, req) 116 fn(w, req)
123 } 117 }
124 } 118 }
125 119
126 //// 120 ////
127 //// NOT FOUND HANDLER 121 //// NOT FOUND HANDLER
128 //// 122 ////
129 123
130 func NotFoundHandler(w http.ResponseWriter, req *http.Request) { 124 func NotFoundHandler(w http.ResponseWriter, req *http.Request) {
131 RespondWithHttpError(w, req, http.StatusNotFound, []HttpErrorDesc{ 125 RespondWithHttpError(w, req, http.StatusNotFound, []HttpErrorDesc{
132 {Lang: "en", Desc: "Not found."}, 126 {Lang: "en", Desc: "Not found."},
133 {Lang: "rs", Desc: "Traženi resurs ne postoji."}, 127 {Lang: "rs", Desc: "Traženi resurs ne postoji."},
134 }) 128 })
135 } 129 }
136 130
1 package restutility 1 package restutility
2 2
3 import ( 3 import (
4 "net/http" 4 "net/http"
5 "strings" 5 "strings"
6 "encoding/json"
7 "errors"
8 "gopkg.in/rana/ora.v3"
9 "io"
10 "io/ioutil"
11 "fmt"
6 ) 12 )
7 13
14 var allPayloads []Payload
15
8 type LangMap map[string]map[string]string 16 type LangMap map[string]map[string]string
9 17
10 type Field struct { 18 type Field struct {
11 Parameter string `json:"param"` 19 Parameter string `json:"param"`
12 Type string `json:"type"` 20 Type string `json:"type"`
13 Visible bool `json:"visible"` 21 Visible bool `json:"visible"`
14 Editable bool `json:"editable"` 22 Editable bool `json:"editable"`
15 } 23 }
16 24
17 type JSONParams struct { 25 type CorrelationField struct {
18 Lang LangMap 26 Result string `json:"result"`
19 Fields []Field 27 Elements []string `json:"elements"`
20 IdField string 28 Type string `json:"type"`
21 Correlations []CorrelationField `json:"correlation_fields"` 29 }
30
31 type Translation struct {
32 Language string `json:"language"`
33 FieldsLabels map[string]string `json:"fieldsLabels"`
22 } 34 }
23 35
24 type JSONPayload struct { 36 type Payload struct {
37 Type string `json:"tableType"`
25 Method string `json:"method"` 38 Method string `json:"method"`
26 Params map[string]string `json:"params"` 39 Params map[string]string `json:"params"`
27 Lang LangMap `json:"lang"` 40 Lang []Translation `json:"lang"`
28 Fields []Field `json:"fields"` 41 Fields []Field `json:"fields"`
29 Correlations []CorrelationField `json:"correlationFields"` 42 Correlations []CorrelationField `json:"correlationFields"`
30 IdField string `json:"idField"` 43 IdField string `json:"idField"`
31 // Data can only hold slices of any type. It can't be used for itteration 44 // Data can only hold slices of any type. It can't be used for itteration
32 Data interface{} `json:"data"` 45 Data interface{} `json:"data"`
33 } 46 }
34 47
35 func NewJSONParams(lang LangMap, 48 func NewPayload(r *http.Request, table string) Payload {
36 fields []Field, 49 var pload Payload
37 id string,
38 correlations []CorrelationField) JSONParams {
39 50
40 var jp JSONParams 51 pload.Method = strings.ToLower(r.Method + " " + r.URL.Path)
52 pload.Params = make(map[string]string, 0)
53 pload.Lang = loadTranslations(allPayloads, table)
54 pload.Fields = loadFields(allPayloads, table)
55 pload.IdField = loadIdField(allPayloads, table)
56 pload.Correlations = loadCorrelations(allPayloads, table)
41 57
42 jp.Lang = lang 58 return pload
43 jp.Fields = fields 59 }
44 jp.IdField = id
45 jp.Correlations = correlations
46 60
47 return jp 61 func DeliverPayload(w http.ResponseWriter, payload Payload) {
62 json.NewEncoder(w).Encode(payload)
63 payload.Data = nil
48 } 64 }
49 65
50 func NewJSONPayload(r *http.Request, table string) JSONPayload { 66 func loadTranslations(payloads []Payload, id string) []Translation {
51 var obj JSONPayload 67 translations := make([]Translation, 0)
52 params := loadTable(table) 68
53 obj.Method = strings.ToLower(r.Method + " " + r.URL.Path) 69 for _, pload := range payloads {
54 obj.Params = make(map[string]string, 0) 70 if pload.Type == id {
55 obj.Lang = make(map[string]map[string]string, 0) 71 for _, t := range pload.Lang {
56 obj.Fields = make([]Field, 0) 72 //translations[t.Language] = t.FieldsLabels
57 obj.IdField = params.IdField 73 translations = append(translations, Translation{
58 obj.Correlations = params.Correlations 74 Language: t.Language,
59 75 FieldsLabels: t.FieldsLabels,
60 for k, m := range params.Lang { 76 })
61 obj.Lang[k] = m 77 }
78 }
62 } 79 }
63 for _, f := range params.Fields { 80
64 obj.Fields = append(obj.Fields, f) 81 return translations
82 }
83
84 func loadFields(payloads []Payload, id string) []Field {
85 fields := make([]Field, 0)
86
87 for _, pload := range payloads {
88 if pload.Type == id{
89 for _, f := range pload.Fields {
90 fields = append(fields, f)
91 }
92 }
93 }
94
95 return fields
96 }
97
98 func loadIdField(payloads []Payload, id string) string {
99 for _, pload := range payloads {
100 if pload.Type == id {
101 return pload.IdField
102 }
103 }
104 return ""
105 }
106
107 func loadCorrelations(payloads []Payload, id string) []CorrelationField {
108 resp := make([]CorrelationField, 0)
109
110 for _, pload := range payloads {
111 if pload.Type == id {
112 for _, f := range pload.Correlations {
113 resp = append(resp, f)
114 }
115 }
116 }
117
118 return resp
119 }
120
121 func InitTables(db *ora.Ses, project string) error {
122 jsonbuf, _ := fetchTablesConfig(db, EqualQuotes(project))
123 json.Unmarshal(jsonbuf, &allPayloads)
124 if len(allPayloads) == 0 {
125 return errors.New("tables config is corrupt")
126 }
127 fmt.Printf("broj ucitanih tabela: %d\n", len(allPayloads))
128 return nil
129 }
130
131 func fetchTablesConfig(db *ora.Ses, project string) ([]byte, error) {
132 stmt, err := db.Prep(`SELECT
133 JSON_CLOB
134 FROM TABLES_CONFIG
135 WHERE PROJEKAT` + project, ora.S)
136 defer stmt.Close()
137
138 if err != nil {
139 return nil, err
140 }
141
142 rset, err := stmt.Qry()
143 if err != nil {
144 return nil, err
145 }
146
147 bytes := make([]byte, 0)
148 if rset.Next() {
149 lob := rset.Row[0].(io.Reader)
150 bytes, err = ioutil.ReadAll(lob)
151 if err != nil {
152 fmt.Printf("mega error: %v\n", err)
153 }
65 } 154 }
66 155
tables_utility.go
1 package restutility File was deleted
2
3 import (
4 "encoding/json"
5 "errors"
6 "gopkg.in/rana/ora.v3"
7 "io"
8 "io/ioutil"
9 "fmt"
10 )
11
12 type TableConfig struct {
13 Tables []Table
14 }
15
16 type Table struct {
17 TableType string `json:"tableType"`
18 Translations []TableTranslation `json:"translations"`
19 TableFields []Field `json:"tableFields"`
20 Correlations []CorrelationField `json:"correlationFields"`
21 IdField string `json:"idField"`
22 }
23
24 type CorrelationField struct {
25 Result string `json:"result"`
26 Elements []string `json:"elements"`
27 Type string `json:"type"`
28 }
29
30 type TableTranslation struct {
31 Language string `json:"language"`
32 FieldsLabels map[string]string `json:"fieldsLabels"`
33 }
34
35 func (tl TableConfig) LoadTranslations(tableType string) LangMap {
36 translations := make(LangMap, 0)
37
38 for _, table := range tl.Tables {
39 if tableType == table.TableType {
40 for _, t := range table.Translations {
41 translations[t.Language] = t.FieldsLabels
42 }
43 }
44 }
45
46 return translations
47 }
48
49 func (tl TableConfig) LoadFields(tableType string) []Field {
50 fields := make([]Field, 0)
51
52 for _, table := range tl.Tables {
53 if tableType == table.TableType {
54 for _, f := range table.TableFields {
55 fields = append(fields, f)
56 }
57 }
58 }
59
60 return fields
61 }
62
63 func (tl TableConfig) LoadIdField(tableType string) string {
64 for _, table := range tl.Tables {
65 if tableType == table.TableType {
66 return table.IdField
67 }
68 }
69 return ""
70 }
71
72 func (tl TableConfig) LoadCorrelations(tableType string) []CorrelationField {
73 resp := make([]CorrelationField, 0)
74
75 for _, table := range tl.Tables {
76 if tableType == table.TableType {
77 for _, f := range table.Correlations {
78 resp = append(resp, f)
79 }
80 }
81 }
82
83 return resp
84 }
85
86 var _tables TableConfig
87 var _prevProject string
88
89 func InitTables(db *ora.Ses, project string) error {
90 jsonbuf, _ := fetchTablesConfig(db, EqualQuotes(project))
91 json.Unmarshal(jsonbuf, &_tables.Tables)
92 if len(_tables.Tables) == 0 {
93 return errors.New("tables config is corrupt")
94 }
95 return nil
96 }
97
98 func fetchTablesConfig(db *ora.Ses, project string) ([]byte, error) {
99 stmt, err := db.Prep(`SELECT
100 JSON_CLOB
101 FROM TABLES_CONFIG
102 WHERE PROJEKAT` + project, ora.S)
103 defer stmt.Close()
104
105 if err != nil {
106 return nil, err
107 }
108
109 rset, err := stmt.Qry()
110 if err != nil {
111 return nil, err
112 }
113
114 bytes := make([]byte, 0)
115 if rset.Next() {
116 lob := rset.Row[0].(io.Reader)
117 bytes, err = ioutil.ReadAll(lob)
118 if err != nil {
119 fmt.Printf("mega error: %v\n", err)
120 }
121 }
122
123 return bytes, nil
124 }
125
126 func loadTable(table string) JSONParams {
127 return NewJSONParams(_tables.LoadTranslations(table),
128 _tables.LoadFields(table),
129 _tables.LoadIdField(table),
130 _tables.LoadCorrelations(table))
131 }
132
133 1 package restutility