Newer
Older
package routebuildermdl
import (
"encoding/json"
"strconv"
"strings"
"corelab.mkcl.org/MKCLOS/coredevelopmentplatform/corepkgv2/servicebuildermdl"
"corelab.mkcl.org/MKCLOS/coredevelopmentplatform/corepkgv2/dalmdl/dao"
"corelab.mkcl.org/MKCLOS/coredevelopmentplatform/corepkgv2/loggermdl"
"corelab.mkcl.org/MKCLOS/coredevelopmentplatform/corepkgv2/errormdl"
"corelab.mkcl.org/MKCLOS/coredevelopmentplatform/corepkgv2/dalmdl/mongodb"
"github.com/tidwall/gjson"
)
// Master - struct for master Service
type Master struct {
serviceName string
isCach bool
cacheTime time.Duration
isRestricted bool
isRoleBased bool
isMongo bool
}
// MongoQuery - for mongo service
type MongoQuery struct {
collection string
host string
query string
projectionQuery string
args []string
isAggregationQuery bool
}
// FDBQuery - for fdb services
type FDBQuery struct {
filePath string
query []string
}
// Runable - helps to run
type Runable struct {
Master
MongoQuery
FDBQuery
}
// MongoService - return mongo query object
func (m *Master) MongoService(collectionName, mongoQuery string) *Runable {
collection: collectionName,
query: mongoQuery,
runable := &Runable{
Master: *m,
MongoQuery: mongo,
}
return runable
}
// MongoServiceWithHost - return mongo query object
func (m *Master) MongoServiceWithHost(hostName, collectionName, mongoQuery string) *Runable {
host: hostName,
collection: collectionName,
query: mongoQuery,
runable := &Runable{
Master: *m,
MongoQuery: mongo,
}
return runable
}
// FDBService - return mongo query object
func (m *Master) FDBService(filPath string, query ...string) *Runable {
FDB := FDBQuery{
filePath: filPath,
query: query,
}
runable := &Runable{
Master: *m,
FDBQuery: FDB,
}
return runable
}
// IsCachable for both fdb and mongo
return m
}
// IsCachableWithExpiration for both fdb and mongo
func (m *Master) IsCachableWithExpiration(cacheExpirationTime time.Duration) *Master {
m.isCach = true
m.cacheTime = cacheExpirationTime
return m
}
// SetArgs set argument for query string
func (m *Runable) SetArgs(args ...string) *Runable {
if m.Master.isMongo {
m.MongoQuery.args = args
}
return m
}
// SetProjectionQuery set SetProjectionQuery for query string
func (m *Runable) SetProjectionQuery(query string) *Runable {
if m.Master.isMongo {
m.MongoQuery.projectionQuery = query
}
return m
}
// IsAggregationQuery - Set flag for aggregation query
func (m *Runable) IsAggregationQuery() *Runable {
if m.Master.isMongo {
m.MongoQuery.isAggregationQuery = true
}
return m
}
// Register - register it in cacahe
func (m *Runable) Register() {
service := ServiceCache{
MasterService: m,
IsMasterService: true,
}
commonServiceRegistration(m.Master.serviceName, service, m.Master.isRestricted, m.Master.isRoleBased)
}
// Run - execute and return output and error
func (m *Runable) Run(data []byte, principal *servicebuildermdl.Principal) (interface{}, error) {
if m.Master.isMongo {
return m.runMongoService(data, principal)
func (m *Runable) runMongoService(data []byte, principal *servicebuildermdl.Principal) (interface{}, error) {
tmp := m.MongoQuery.query
var principalError error
tmp, principalError = parsePricipalObject(tmp, principal)
if errormdl.CheckErr(principalError) != nil {
loggermdl.LogError(principalError)
return nil, errormdl.CheckErr(principalError)
}
if m.MongoQuery.isAggregationQuery {
v, formatError := m.formatAggregateQuery(&rs, tmp)
if errormdl.CheckErr(formatError) != nil {
loggermdl.LogError(formatError)
return nil, errormdl.CheckErr(formatError)
}
query, getError := mongodb.GetMongoDAOWithHost(m.MongoQuery.host, m.MongoQuery.collection).GetAggregateData(v)
if errormdl.CheckErr(getError) != nil {
loggermdl.LogError(getError)
return nil, errormdl.CheckErr(getError)
}
return query.Value(), nil
v, p, formatError := m.formatNormalQuery(&rs, tmp)
if errormdl.CheckErr(formatError) != nil {
loggermdl.LogError(formatError)
return nil, errormdl.CheckErr(formatError)
query, getError := mongodb.GetMongoDAOWithHost(m.MongoQuery.host, m.MongoQuery.collection).GetProjectedData(v, p)
if errormdl.CheckErr(getError) != nil {
loggermdl.LogError(getError)
return nil, errormdl.CheckErr(getError)
}
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
func (m *Runable) formatAggregateQuery(rs *gjson.Result, tmp string) ([]interface{}, error) {
for i, arg := range m.MongoQuery.args {
result := rs.Get(arg).String()
argNotation := "~" + strconv.Itoa(i+1)
tmp = strings.Replace(tmp, argNotation, result, 1)
}
v, ok := gjson.Parse(tmp).Value().([]interface{})
if !ok {
loggermdl.LogError("Invalid Mongo Query")
return nil, errormdl.Wrap("Invalid Mongo Query")
}
return v, nil
}
func (m *Runable) formatNormalQuery(rs *gjson.Result, tmp string) (map[string]interface{}, map[string]interface{}, error) {
for i, arg := range m.MongoQuery.args {
result := rs.Get(arg).String()
argNotation := "~" + strconv.Itoa(i+1)
tmp = strings.Replace(tmp, argNotation, result, 1)
}
v, ok := gjson.Parse(tmp).Value().(map[string]interface{})
if !ok {
loggermdl.LogError("Invalid Mongo Query")
return nil, nil, errormdl.Wrap("Invalid Mongo Query")
}
if m.MongoQuery.projectionQuery == "" {
m.MongoQuery.projectionQuery = "{}"
}
p, ok := gjson.Parse(m.MongoQuery.projectionQuery).Value().(map[string]interface{})
if !ok {
loggermdl.LogError("Invalid Mongo Projection Query Query")
return nil, nil, errormdl.Wrap("Invalid Mongo Projection Query Query")
}
return v, p, nil
}
func parsePricipalObject(query string, principal *servicebuildermdl.Principal) (string, error) {
ba, marshalError := json.Marshal(principal)
if errormdl.CheckErr(marshalError) != nil {
loggermdl.LogError(marshalError)
return "", errormdl.CheckErr(marshalError)
}
pricipalRS := gjson.ParseBytes(ba)
result := pricipalRS.Get("userId").String()
argNotation := "~tokenUserId"
query = strings.Replace(query, argNotation, result, 1)
return query, nil
}
func (m *Runable) runFDBService() (interface{}, error) {
rs, getError := dalmdl.GetDAO().
FilePath(m.FDBQuery.filePath).
Query(m.FDBQuery.query...).
IsCacheableWithDuration(m.Master.cacheTime).
Run()
if errormdl.CheckErr(getError) != nil {
loggermdl.LogError(getError)
return nil, errormdl.CheckErr(getError)
}
return rs.Value(), nil
}