|
|
@ -22,6 +22,8 @@ import ( |
|
|
|
const headerRequestId = "X-Request-Id" |
|
|
|
const headerServiceKey = "X-Service-Key" |
|
|
|
const tokenInterval = 1 * time.Minute |
|
|
|
const constOperationDelete = "delete" |
|
|
|
const constOperationAdd = "add" |
|
|
|
|
|
|
|
type api struct { |
|
|
|
url string |
|
|
@ -43,6 +45,8 @@ type Obj interface { |
|
|
|
ObjDelete(ctx context.Context, uids string) (result models.ResponseData, err error) |
|
|
|
ObjAttrUpdate(ctx context.Context, uid, name, value, src, editor string) (result models.ResponseData, err error) |
|
|
|
LinkGet(ctx context.Context, tpl, obj, mode, short string) (result models.ResponseData, err error) |
|
|
|
LinkAdd(ctx context.Context, element, from, to string) (result models.ResponseData, err error) |
|
|
|
LinkDelete(ctx context.Context, element, from, to string) (result models.ResponseData, err error) |
|
|
|
LinkGetWithCache(ctx context.Context, tpl, obj, mode, short string) (result models.ResponseData, err error) |
|
|
|
Query(ctx context.Context, query, method, bodyJSON string) (result string, err error) |
|
|
|
Search(ctx context.Context, query, method, bodyJSON string) (resp string, err error) |
|
|
@ -53,7 +57,10 @@ type Obj interface { |
|
|
|
|
|
|
|
// Query результат выводим в объект как при вызове Curl
|
|
|
|
func (a *api) Query(ctx context.Context, query, method, bodyJSON string) (result string, err error) { |
|
|
|
//_, err = a.cb.Execute(func() (interface{}, error) {
|
|
|
|
result, err = a.query(ctx, query, method, bodyJSON) |
|
|
|
//return result, err
|
|
|
|
//})
|
|
|
|
if err != nil { |
|
|
|
logger.Error(ctx, "error UpdateFilter primary haproxy", zap.Error(err)) |
|
|
|
return "", fmt.Errorf("error request Query (primary route). err: %s", err) |
|
|
@ -94,14 +101,19 @@ func (a *api) QueryWithCache(ctx context.Context, query, method, bodyJSON string |
|
|
|
res, err = a.Query(ctx, query, method, bodyJSON) |
|
|
|
return res, err |
|
|
|
}, a.cacheUpdateInterval) |
|
|
|
if err != nil { |
|
|
|
return "", fmt.Errorf("error from cache update. err: %s", err) |
|
|
|
} |
|
|
|
if value == nil { |
|
|
|
return "", fmt.Errorf("returned result from cache update is empty") |
|
|
|
if err == nil && value != nil { |
|
|
|
return fmt.Sprint(value), nil |
|
|
|
} else { |
|
|
|
err = fmt.Errorf("error exec cache query (Query). err: %s, value is empty: %t, value: %+v", err, value == nil, value) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return fmt.Sprint(value), err |
|
|
|
if err != nil { |
|
|
|
logger.Error(ctx, "error exec cache query", zap.String("func", "QueryWithCache"), zap.String("key", key), zap.Error(err)) |
|
|
|
cacheValue, err = a.Query(ctx, query, method, bodyJSON) |
|
|
|
if err != nil { |
|
|
|
return result, fmt.Errorf("error get cache (Query). err: %s", err) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return fmt.Sprint(cacheValue), err |
|
|
@ -111,8 +123,10 @@ func (a *api) ObjGet(ctx context.Context, uids string) (result models.ResponseDa |
|
|
|
if uids == "" { |
|
|
|
return result, fmt.Errorf("error ObjGet. uids is empty") |
|
|
|
} |
|
|
|
|
|
|
|
//_, err = a.cb.Execute(func() (interface{}, error) {
|
|
|
|
result, err = a.objGet(ctx, uids) |
|
|
|
//return result, err
|
|
|
|
//})
|
|
|
|
if err != nil { |
|
|
|
logger.Error(ctx, "error ObjGet primary haproxy", zap.Error(err)) |
|
|
|
return result, fmt.Errorf("error request ObjGet (primary route). err: %s", err) |
|
|
@ -122,16 +136,6 @@ func (a *api) ObjGet(ctx context.Context, uids string) (result models.ResponseDa |
|
|
|
} |
|
|
|
|
|
|
|
func (a *api) ObjGetWithCache(ctx context.Context, uids string) (result *models.ResponseData, err error) { |
|
|
|
|
|
|
|
//t, e := a.ObjGet(ctx, uids)
|
|
|
|
//return &t, e
|
|
|
|
|
|
|
|
//t := time.Now()
|
|
|
|
//defer func() {
|
|
|
|
// fmt.Printf("\nDEFER Время выполнения общее ObjGetWithCache: %fc\n", time.Since(t).Seconds())
|
|
|
|
//}()
|
|
|
|
|
|
|
|
var ok bool |
|
|
|
var handlers = map[string]string{} |
|
|
|
handlers[headerRequestId] = logger.GetRequestIDCtx(ctx) |
|
|
|
if a.observeLog { |
|
|
@ -140,7 +144,6 @@ func (a *api) ObjGetWithCache(ctx context.Context, uids string) (result *models. |
|
|
|
key := lib.Hash(uids) |
|
|
|
|
|
|
|
cacheValue, err := cache.Cache().Get(key) |
|
|
|
//fmt.Printf("\nберем объект из кеша. cacheValue uids: %s len %s, время: %fc, err: %s, reqID: %s", uids, len(fmt.Sprint(cacheValue)), time.Since(t).Seconds(), err, logger.GetRequestIDCtx(ctx))
|
|
|
|
|
|
|
|
if errors.Is(err, cache.ErrorKeyNotFound) { |
|
|
|
var value interface{} |
|
|
@ -148,35 +151,89 @@ func (a *api) ObjGetWithCache(ctx context.Context, uids string) (result *models. |
|
|
|
res, err = a.ObjGet(ctx, uids) |
|
|
|
return res, err |
|
|
|
}, a.cacheUpdateInterval) |
|
|
|
if err != nil { |
|
|
|
return nil, fmt.Errorf("error from cache update. err: %s", err) |
|
|
|
} |
|
|
|
if value == nil { |
|
|
|
return nil, fmt.Errorf("returned result from cache update is empty") |
|
|
|
if err == nil && value != nil { |
|
|
|
res, ok := value.(models.ResponseData) |
|
|
|
if ok { |
|
|
|
return &res, nil |
|
|
|
} |
|
|
|
err = fmt.Errorf("error cast type in cache query (ObjGetWithCache). err: %s, value is empty: %t, result: %+v", err, value == nil, value) |
|
|
|
} else { |
|
|
|
err = fmt.Errorf("error exec cache query (ObjGet). err: %s, value is empty: %t", err, value == nil) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
res, ok := value.(models.ResponseData) |
|
|
|
if !ok { |
|
|
|
err = fmt.Errorf("[ObjGetWithCache] error. cast type (ResponseData) is fail for cache.ErrorKeyNotFound. result: %+v", value) |
|
|
|
// повторяем запрос (без кеша)
|
|
|
|
if err != nil { |
|
|
|
logger.Error(ctx, "error exec cache query", zap.String("func", "ObjGetWithCache"), zap.String("key", key), zap.Error(err)) |
|
|
|
cacheValue, err = a.ObjGet(ctx, uids) |
|
|
|
if err == nil && cacheValue != nil { |
|
|
|
res, ok := cacheValue.(models.ResponseData) |
|
|
|
if ok { |
|
|
|
return &res, nil |
|
|
|
} |
|
|
|
err = fmt.Errorf("error cast type in query (ObjGet). err: %s, value is empty: %t, result: %+v", err, cacheValue == nil, cacheValue) |
|
|
|
} else { |
|
|
|
err = fmt.Errorf("error exec query (ObjGet). err: %s, value is empty: %t", err, cacheValue == nil) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return &res, err |
|
|
|
if err == nil && cacheValue != nil { |
|
|
|
res, ok := cacheValue.(models.ResponseData) |
|
|
|
if ok { |
|
|
|
return &res, nil |
|
|
|
} |
|
|
|
err = fmt.Errorf("error cast type in query (ObjGet). err: %s, value is empty: %t, result: %+v", err, cacheValue == nil, cacheValue) |
|
|
|
} else { |
|
|
|
err = fmt.Errorf("error exec query (ObjGet). err: %s, value is empty: %t", err, cacheValue == nil) |
|
|
|
} |
|
|
|
|
|
|
|
res, ok := cacheValue.(models.ResponseData) |
|
|
|
if !ok { |
|
|
|
return result, fmt.Errorf("[ObjGetWithCache] error. cast type (ResponseData) is fail. result: %+v", cacheValue) |
|
|
|
return result, err |
|
|
|
} |
|
|
|
|
|
|
|
// LinkDelete - удаление линки
|
|
|
|
func (a *api) LinkDelete(ctx context.Context, element, from, to string) (result models.ResponseData, err error) { |
|
|
|
//_, err = a.cb.Execute(func() (interface{}, error) {
|
|
|
|
result, err = a.linkOperation(ctx, constOperationDelete, element, from, to) |
|
|
|
//return result, err
|
|
|
|
//})
|
|
|
|
if err != nil { |
|
|
|
logger.Error(ctx, "error LinkDelete primary haproxy", |
|
|
|
zap.String("operation", constOperationDelete), |
|
|
|
zap.String("element", element), |
|
|
|
zap.String("from", from), |
|
|
|
zap.String("to", to)) |
|
|
|
//zap.Any("status CircuitBreaker", a.cb.State().String()), zap.Error(err))
|
|
|
|
return result, fmt.Errorf("error request LinkDelete (primary route). check apiCircuitBreaker. err: %s", err) |
|
|
|
} |
|
|
|
|
|
|
|
//fmt.Printf("\nберем объект из кеша. общее время: %fc, err: %s reqID: %s\n\n", time.Since(t).Seconds(), err, logger.GetRequestIDCtx(ctx))
|
|
|
|
return result, err |
|
|
|
} |
|
|
|
|
|
|
|
// LinkAdd - добавление линки в объект
|
|
|
|
func (a *api) LinkAdd(ctx context.Context, element, from, to string) (result models.ResponseData, err error) { |
|
|
|
//_, err = a.cb.Execute(func() (interface{}, error) {
|
|
|
|
result, err = a.linkOperation(ctx, constOperationAdd, element, from, to) |
|
|
|
//return result, err
|
|
|
|
//})
|
|
|
|
if err != nil { |
|
|
|
logger.Error(ctx, "error LinkAdd primary haproxy", |
|
|
|
zap.String("operation", constOperationAdd), |
|
|
|
zap.String("element", element), |
|
|
|
zap.String("from", from), |
|
|
|
zap.String("to", to)) |
|
|
|
//zap.Any("status CircuitBreaker", a.cb.State().String()), zap.Error(err))
|
|
|
|
return result, fmt.Errorf("error request LinkAdd (primary route). check apiCircuitBreaker. err: %s", err) |
|
|
|
} |
|
|
|
|
|
|
|
return &res, err |
|
|
|
return result, err |
|
|
|
} |
|
|
|
|
|
|
|
// LinkGet - получение связанных объектов
|
|
|
|
func (a *api) LinkGet(ctx context.Context, tpl, obj, mode, short string) (result models.ResponseData, err error) { |
|
|
|
//_, err = a.cb.Execute(func() (interface{}, error) {
|
|
|
|
result, err = a.linkGet(ctx, tpl, obj, mode, short) |
|
|
|
|
|
|
|
//return result, err
|
|
|
|
//})
|
|
|
|
if err != nil { |
|
|
|
logger.Error(ctx, "error LinkGet primary haproxy", zap.Error(err)) |
|
|
|
return result, fmt.Errorf("error request LinkGet (primary route). err: %s", err) |
|
|
@ -188,9 +245,6 @@ func (a *api) LinkGet(ctx context.Context, tpl, obj, mode, short string) (result |
|
|
|
// LinkGetWithCache - получение связанных объектов
|
|
|
|
// (с кешем если задан TTL кеширования при инициализации кеша)
|
|
|
|
func (a *api) LinkGetWithCache(ctx context.Context, tpl, obj, mode, short string) (result models.ResponseData, err error) { |
|
|
|
|
|
|
|
//return a.LinkGet(ctx, tpl, obj, mode, short)
|
|
|
|
|
|
|
|
var ok bool |
|
|
|
var handlers = map[string]string{} |
|
|
|
handlers[headerRequestId] = logger.GetRequestIDCtx(ctx) |
|
|
@ -207,24 +261,40 @@ func (a *api) LinkGetWithCache(ctx context.Context, tpl, obj, mode, short string |
|
|
|
res, err = a.LinkGet(ctx, tpl, obj, mode, short) |
|
|
|
return res, err |
|
|
|
}, a.cacheUpdateInterval) |
|
|
|
if err != nil { |
|
|
|
return result, fmt.Errorf("error from cache update. err: %s", err) |
|
|
|
} |
|
|
|
if value == nil { |
|
|
|
return result, fmt.Errorf("returned result from cache update is empty") |
|
|
|
if err == nil && value != nil { |
|
|
|
result, ok = value.(models.ResponseData) |
|
|
|
if ok { |
|
|
|
return result, nil |
|
|
|
} |
|
|
|
err = fmt.Errorf("error cast type in cache query (LinkGetWithCache). err: %s, value is empty: %t, result: %+v", err, value == nil, value) |
|
|
|
} else { |
|
|
|
err = fmt.Errorf("error exec cache query (LinkGet). err: %s, value is empty: %t", err, value == nil) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
result, ok = value.(models.ResponseData) |
|
|
|
if !ok { |
|
|
|
err = fmt.Errorf("[LinkGetWithCache] error. cast type (ResponseData) is fail. result: %+v", value) |
|
|
|
// повторяем запрос (без кеша)
|
|
|
|
if err != nil { |
|
|
|
logger.Error(ctx, "error exec cache query", zap.String("func", "LinkGetWithCache"), zap.String("key", key), zap.Error(err)) |
|
|
|
cacheValue, err = a.LinkGet(ctx, tpl, obj, mode, short) |
|
|
|
if err == nil && cacheValue != nil { |
|
|
|
res, ok := cacheValue.(models.ResponseData) |
|
|
|
if ok { |
|
|
|
return res, nil |
|
|
|
} |
|
|
|
err = fmt.Errorf("error cast type in query (LinkGet). err: %s, value is empty: %t, result: %+v", err, cacheValue == nil, cacheValue) |
|
|
|
} else { |
|
|
|
err = fmt.Errorf("error exec query (LinkGet). err: %s, value is empty: %t", err, cacheValue == nil) |
|
|
|
} |
|
|
|
|
|
|
|
return result, err |
|
|
|
} |
|
|
|
|
|
|
|
result, ok = cacheValue.(models.ResponseData) |
|
|
|
if !ok { |
|
|
|
return result, fmt.Errorf("[LinkGetWithCache] error. cast type (ResponseData) is fail. result: %+v", cacheValue) |
|
|
|
if err == nil && cacheValue != nil { |
|
|
|
res, ok := cacheValue.(models.ResponseData) |
|
|
|
if ok { |
|
|
|
return res, nil |
|
|
|
} |
|
|
|
err = fmt.Errorf("error cast type in query (ObjGet). err: %s, value is empty: %t, result: %+v", err, cacheValue == nil, cacheValue) |
|
|
|
} else { |
|
|
|
err = fmt.Errorf("error exec query (ObjGet). err: %s, value is empty: %t", err, cacheValue == nil) |
|
|
|
} |
|
|
|
|
|
|
|
return result, err |
|
|
@ -235,8 +305,10 @@ func (a *api) ObjAttrUpdate(ctx context.Context, uid, name, value, src, editor s |
|
|
|
if uid == "" { |
|
|
|
return result, fmt.Errorf("[ObjAttrUpdate] error ObjAttrUpdate. uid is empty") |
|
|
|
} |
|
|
|
|
|
|
|
//_, err = a.cb.Execute(func() (interface{}, error) {
|
|
|
|
result, err = a.objAttrUpdate(ctx, uid, name, value, src, editor) |
|
|
|
//return result, err
|
|
|
|
//})
|
|
|
|
if err != nil { |
|
|
|
logger.Error(ctx, "error ObjAttrUpdate primary haproxy", zap.Error(err)) |
|
|
|
return result, fmt.Errorf("[ObjAttrUpdate] error request ObjAttrUpdate (primary route). err: %s", err) |
|
|
@ -256,7 +328,10 @@ func (a *api) ObjAttrUpdate(ctx context.Context, uid, name, value, src, editor s |
|
|
|
// all (elements) - Получаем поля, по заданному в параметрах типу
|
|
|
|
// "" - без действия - получаем все поля для объекта
|
|
|
|
func (a *api) Element(ctx context.Context, action, body string) (result models.ResponseData, err error) { |
|
|
|
//_, err = a.cb.Execute(func() (interface{}, error) {
|
|
|
|
result, err = a.element(ctx, action, body) |
|
|
|
//return result, err
|
|
|
|
//})
|
|
|
|
if err != nil { |
|
|
|
logger.Error(ctx, "error Element primary haproxy", zap.Error(err)) |
|
|
|
return result, fmt.Errorf("[Element] error request Element (primary route). err: %s", err) |
|
|
@ -292,31 +367,53 @@ func (a *api) ElementWithCache(ctx context.Context, action, body string) (result |
|
|
|
res, err = a.Element(ctx, action, body) |
|
|
|
return res, err |
|
|
|
}, a.cacheUpdateInterval) |
|
|
|
if err != nil { |
|
|
|
return result, fmt.Errorf("error from cache update. err: %s", err) |
|
|
|
} |
|
|
|
if value == nil { |
|
|
|
return result, fmt.Errorf("returned result from cache update is empty") |
|
|
|
if err == nil && value != nil { |
|
|
|
result, ok = value.(models.ResponseData) |
|
|
|
if ok { |
|
|
|
return result, nil |
|
|
|
} |
|
|
|
err = fmt.Errorf("error cast type in cache query (ElementWithCache). err: %s, value is empty: %t, result: %+v", err, value == nil, value) |
|
|
|
} else { |
|
|
|
err = fmt.Errorf("error exec cache query. err: %s, value is empty: %t", err, value == nil) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
result, ok = value.(models.ResponseData) |
|
|
|
if !ok { |
|
|
|
err = fmt.Errorf("[ElementWithCache] error. cast type (ResponseData) is fail. result: %+v", value) |
|
|
|
// повторяем запрос (без кеша)
|
|
|
|
if err != nil { |
|
|
|
logger.Error(ctx, "error exec cache query", zap.String("func", "ElementWithCache"), zap.String("key", key), zap.Error(err)) |
|
|
|
cacheValue, err = a.Element(ctx, action, body) |
|
|
|
if err == nil && cacheValue != nil { |
|
|
|
res, ok := cacheValue.(models.ResponseData) |
|
|
|
if ok { |
|
|
|
return res, nil |
|
|
|
} |
|
|
|
err = fmt.Errorf("error cast type in query (Element). err: %s, value is empty: %t, result: %+v", err, cacheValue == nil, cacheValue) |
|
|
|
} else { |
|
|
|
err = fmt.Errorf("error exec query (Element). err: %s, value is empty: %t", err, cacheValue == nil) |
|
|
|
} |
|
|
|
|
|
|
|
return result, err |
|
|
|
} |
|
|
|
|
|
|
|
result, ok = cacheValue.(models.ResponseData) |
|
|
|
if !ok { |
|
|
|
return result, fmt.Errorf("[ElementWithCache] error. cast type (ResponseData) is fail. result: %+v", cacheValue) |
|
|
|
if err == nil && cacheValue != nil { |
|
|
|
res, ok := cacheValue.(models.ResponseData) |
|
|
|
if ok { |
|
|
|
return res, nil |
|
|
|
} |
|
|
|
err = fmt.Errorf("error cast type in query (ObjGet). err: %s, value is empty: %t, result: %+v", err, cacheValue == nil, cacheValue) |
|
|
|
} else { |
|
|
|
err = fmt.Errorf("error exec query (ObjGet). err: %s, value is empty: %t", err, cacheValue == nil) |
|
|
|
} |
|
|
|
|
|
|
|
return result, err |
|
|
|
} |
|
|
|
|
|
|
|
func (a *api) ObjCreate(ctx context.Context, bodymap map[string]string) (result models.ResponseData, err error) { |
|
|
|
//_, err = a.cb.Execute(func() (interface{}, error) {
|
|
|
|
result, err = a.objCreate(ctx, bodymap) |
|
|
|
//if err != nil {
|
|
|
|
// err = fmt.Errorf("error ObjCreate, bodymap: %+v, err: %s)", bodymap, err)
|
|
|
|
//}
|
|
|
|
//return result, err
|
|
|
|
//})
|
|
|
|
if err != nil { |
|
|
|
logger.Error(ctx, "error ObjCreate primary haproxy", zap.Error(err), zap.Any("bodymap", bodymap)) |
|
|
|
return result, fmt.Errorf("error request ObjCreate (primary route). err: %s", err) |
|
|
@ -326,7 +423,10 @@ func (a *api) ObjCreate(ctx context.Context, bodymap map[string]string) (result |
|
|
|
} |
|
|
|
|
|
|
|
func (a *api) ObjDelete(ctx context.Context, uids string) (result models.ResponseData, err error) { |
|
|
|
//_, err = a.cb.Execute(func() (interface{}, error) {
|
|
|
|
result, err = a.objDelete(ctx, uids) |
|
|
|
//return result, err
|
|
|
|
//})
|
|
|
|
if err != nil { |
|
|
|
logger.Error(ctx, "error ObjDelete primary haproxy", zap.Error(err)) |
|
|
|
return result, fmt.Errorf("error request ObjDelete (primary route). err: %s", err) |
|
|
|