Commit 64041a2ea429b17719d3c5b9b8d37fa24ebfed7a

Authored by Marko Tikvić
0 parents
Exists in master and in 1 other branch v2

first commit

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