model.go 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  1. package worker
  2. /*
  3. the worker middleware is for doing some part of tranformtion on the business object side.
  4. Here you will find functions for validating the model validating and storage and retrieval in an storage technologie indipendent way.
  5. */
  6. import (
  7. "errors"
  8. "fmt"
  9. "reflect"
  10. "sync"
  11. "time"
  12. "wkla.no-ip.biz/gogs/Willie/MsgService/MessageService/config"
  13. "wkla.no-ip.biz/gogs/Willie/MsgService/MessageService/dao"
  14. "wkla.no-ip.biz/gogs/Willie/MsgService/MessageService/internal"
  15. "wkla.no-ip.biz/gogs/Willie/MsgService/MessageService/logging"
  16. "wkla.no-ip.biz/gogs/Willie/MsgService/MessageService/model"
  17. )
  18. //ErrMissingID the id of the model is mandatory and not availble
  19. var ErrMissingID = errors.New("Missing _id")
  20. //ErrBackendNotFound backend with that name was not found
  21. var ErrBackendNotFound = errors.New("Missing backend")
  22. //ErrBackendModelNotFound backend model with that name was not found
  23. var ErrBackendModelNotFound = errors.New("Missing backend model")
  24. type ErrValidationError struct {
  25. message string
  26. }
  27. func (p ErrValidationError) Error() string {
  28. return p.message
  29. }
  30. var modelCount = make(map[string]int)
  31. var modelCountMutex = &sync.Mutex{}
  32. func GetModelCount() map[string]int {
  33. internaleCountMap := make(map[string]int)
  34. modelCountMutex.Lock()
  35. for k, v := range modelCount {
  36. internaleCountMap[k] = v
  37. }
  38. modelCountMutex.Unlock()
  39. return internaleCountMap
  40. }
  41. func IncModelCounter(name string, count int) {
  42. modelCountMutex.Lock()
  43. modelCount[name] = modelCount[name] + count
  44. modelCountMutex.Unlock()
  45. }
  46. var log logging.ServiceLogger
  47. //CheckRoute checking if the route inforamtion are ok
  48. func CheckRoute(route model.Route) error {
  49. if !config.Get().AllowAnonymousBackend {
  50. backend, ok := model.BackendList.Get(route.Backend)
  51. if !ok {
  52. log.Alertf("backend not found: %s", route.Backend)
  53. return ErrBackendNotFound
  54. }
  55. _, ok = backend.GetModel(route.Model)
  56. if !ok {
  57. log.Alertf("backend model not found: %s.%s", route.Backend, route.Model)
  58. return ErrBackendModelNotFound
  59. }
  60. }
  61. return nil
  62. }
  63. //Validate validates the model against the definition, and convert attributes, if there is something to convert (like dateTime attributes)
  64. func Validate(route model.Route, data model.JSONMap) (model.JSONMap, error) {
  65. // return false, dao.ErrNotImplemented
  66. err := CheckRoute(route)
  67. if err != nil {
  68. return nil, err
  69. }
  70. modelDefinition, ok := model.BackendList.GetModel(route)
  71. if !ok || !config.Get().AllowAnonymousBackend {
  72. return nil, ErrBackendModelNotFound
  73. }
  74. log.Info(modelDefinition.Name)
  75. // check fieldtypes, eventually convert
  76. //TODO check field values
  77. for key, value := range data {
  78. field, ok := modelDefinition.GetField(key)
  79. if !ok {
  80. continue
  81. }
  82. if field.Mandatory {
  83. if isEmpty(value) {
  84. return nil, ErrValidationError{
  85. message: fmt.Sprintf("mandatory field \"%s\" is empty", key),
  86. }
  87. }
  88. }
  89. if field.Collection {
  90. if !isEmpty(value) {
  91. //TODO check and convert every array entry
  92. if reflect.TypeOf(value).Kind() != reflect.Slice {
  93. return nil, ErrValidationError{
  94. message: fmt.Sprintf("collection field \"%s\" is not a collection", key),
  95. }
  96. }
  97. }
  98. }
  99. if field.Type == model.FieldTypeBool {
  100. switch v := value.(type) {
  101. case float64:
  102. data[key] = v > 0
  103. case int:
  104. data[key] = v > 0
  105. case bool:
  106. data[key] = v
  107. }
  108. }
  109. if field.Type == model.FieldTypeTime {
  110. switch v := value.(type) {
  111. case string:
  112. layout := "2006-01-02T15:04:05.000Z07:00"
  113. time, err := time.Parse(layout, v)
  114. if err != nil {
  115. return nil, ErrValidationError{
  116. message: fmt.Sprintf("wrong time format: key: \"%s\", err: %v", key, err),
  117. }
  118. }
  119. data[key] = time
  120. case float64:
  121. data[key] = time.Unix(0, int64(v)*int64(time.Millisecond))
  122. }
  123. }
  124. }
  125. //check mandatory fields
  126. for _, field := range modelDefinition.Fields {
  127. if field.Mandatory {
  128. if isEmpty(data[field.Name]) {
  129. return nil, ErrValidationError{
  130. message: fmt.Sprintf("mandatory field \"%s\" is empty", field.Name),
  131. }
  132. }
  133. }
  134. }
  135. return data, nil
  136. }
  137. func isEmpty(value interface{}) bool {
  138. if value == nil {
  139. return true
  140. }
  141. switch v := value.(type) {
  142. case string:
  143. return v == ""
  144. }
  145. return false
  146. }
  147. //Store create a new model
  148. func Store(route model.Route, data model.JSONMap) (model.JSONMap, error) {
  149. err := CheckRoute(route)
  150. if err != nil {
  151. return nil, err
  152. }
  153. // adding system attributes
  154. data[internal.AttributeOwner] = route.Username
  155. data[internal.AttributeCreated] = time.Now()
  156. data[internal.AttributeModified] = time.Now()
  157. modelid, err := dao.GetStorage().CreateModel(route, data)
  158. if err != nil {
  159. return nil, err
  160. }
  161. IncModelCounter(route.GetRouteName(), 1)
  162. route.Identity = modelid
  163. modelData, err := Get(route)
  164. if err != nil {
  165. return nil, err
  166. }
  167. return modelData, nil
  168. }
  169. //StoreMany create a bunch of new model
  170. func StoreMany(route model.Route, datas []model.JSONMap) ([]string, error) {
  171. err := CheckRoute(route)
  172. if err != nil {
  173. return nil, err
  174. }
  175. now := time.Now()
  176. for _, data := range datas {
  177. // adding system attributes
  178. data[internal.AttributeOwner] = route.Username
  179. data[internal.AttributeCreated] = now
  180. data[internal.AttributeModified] = now
  181. }
  182. modelids, err := dao.GetStorage().CreateModels(route, datas)
  183. if err != nil {
  184. return nil, err
  185. }
  186. return modelids, nil
  187. }
  188. //Get getting one model
  189. func Get(route model.Route) (model.JSONMap, error) {
  190. err := CheckRoute(route)
  191. if err != nil {
  192. return nil, err
  193. }
  194. model, err := dao.GetStorage().GetModel(route)
  195. if err != nil {
  196. return nil, err
  197. }
  198. return model, nil
  199. }
  200. //Update update an existing model
  201. func Update(route model.Route, data model.JSONMap) (model.JSONMap, error) {
  202. err := CheckRoute(route)
  203. if err != nil {
  204. return nil, err
  205. }
  206. if route.Identity == "" {
  207. return nil, ErrMissingID
  208. }
  209. dataModel, err := dao.GetStorage().GetModel(route)
  210. if err != nil {
  211. return nil, err
  212. }
  213. // adding system attributes
  214. data[internal.AttributeID] = route.Identity
  215. data[internal.AttributeOwner] = route.Username
  216. data[internal.AttributeCreated] = dataModel[internal.AttributeCreated]
  217. data[internal.AttributeModified] = time.Now()
  218. modelData, err := dao.GetStorage().UpdateModel(route, data)
  219. if err != nil {
  220. fmt.Printf("%v\n", err)
  221. return nil, err
  222. }
  223. return modelData, nil
  224. }
  225. //Delete delete an existing model
  226. func Delete(route model.Route, deleteRef bool) error {
  227. err := CheckRoute(route)
  228. if err != nil {
  229. return err
  230. }
  231. if route.Identity == "" {
  232. return ErrMissingID
  233. }
  234. data, err := dao.GetStorage().GetModel(route)
  235. if err != nil {
  236. return err
  237. }
  238. beModel, ok := model.BackendList.Get(route.Backend)
  239. if ok {
  240. fmt.Printf("getting backend %s\n", beModel.Backendname)
  241. if beModel.IsValidDatamodel(route.Model, data) && deleteRef {
  242. files, err := beModel.GetReferencedFiles(route.Model, data)
  243. if err != nil {
  244. return err
  245. }
  246. for _, fileID := range files {
  247. err = dao.GetStorage().DeleteFile(route.Backend, fileID)
  248. if err != nil {
  249. return err
  250. }
  251. }
  252. }
  253. }
  254. err = dao.GetStorage().DeleteModel(route)
  255. if err != nil {
  256. return err
  257. }
  258. return nil
  259. }
  260. //Query query for existing models
  261. func Query(route model.Route, query string, offset int, limit int) (int, []model.JSONMap, error) {
  262. err := CheckRoute(route)
  263. if err != nil {
  264. return 0, nil, err
  265. }
  266. n, dataModels, err := dao.GetStorage().QueryModel(route, query, offset, limit)
  267. if err != nil {
  268. return 0, nil, err
  269. }
  270. return n, dataModels, nil
  271. }
  272. //GetCount query for existing models
  273. func GetCount(route model.Route) (int, error) {
  274. err := CheckRoute(route)
  275. if err != nil {
  276. return 0, err
  277. }
  278. n, err := dao.GetStorage().CountModel(route)
  279. if err != nil {
  280. return 0, err
  281. }
  282. return n, nil
  283. }