[notification] add /notification/read, add message_type (#47)
[notification] add /notification/read, add message_type Co-authored-by: Kassian Sun <kassiansun@outlook.com>
This commit is contained in:
parent
55ac534b02
commit
8fddcdaf09
|
@ -7,9 +7,16 @@ import (
|
||||||
type NotificationType string
|
type NotificationType string
|
||||||
|
|
||||||
const (
|
const (
|
||||||
NotificationTypeProductNews NotificationType = "PRODUCT_NEWS"
|
NotificationTypeNotification NotificationType = "NOTIFICATION"
|
||||||
NotificationTypeAlertTriggered NotificationType = "ALERT_TRIGGERED"
|
NotificationTypeTodo NotificationType = "TODO"
|
||||||
NotificationTypeDataMigration NotificationType = "DATA_MIGRATION"
|
)
|
||||||
|
|
||||||
|
type MessageType string
|
||||||
|
|
||||||
|
const (
|
||||||
|
MessageTypeNews MessageType = "NEWS"
|
||||||
|
MessageTypeAlerting MessageType = "ALERTING"
|
||||||
|
MessageTypeMigration MessageType = "MIGRATION"
|
||||||
)
|
)
|
||||||
|
|
||||||
type NotificationStatus string
|
type NotificationStatus string
|
||||||
|
@ -24,6 +31,7 @@ type Notification struct {
|
||||||
|
|
||||||
UserId string `json:"user_id,omitempty" elastic_mapping:"user_id: { type: keyword }"`
|
UserId string `json:"user_id,omitempty" elastic_mapping:"user_id: { type: keyword }"`
|
||||||
NotificationType NotificationType `json:"notification_type,omitempty" elastic_mapping:"notification_type:{type:keyword,fields:{text: {type: text}}}"`
|
NotificationType NotificationType `json:"notification_type,omitempty" elastic_mapping:"notification_type:{type:keyword,fields:{text: {type: text}}}"`
|
||||||
|
MessageType MessageType `json:"message_type,omitempty" elastic_mapping:"message_type:{type:keyword,fields:{text: {type: text}}}"`
|
||||||
Status NotificationStatus `json:"status,omitempty" elastic_mapping:"status: { type: keyword }"`
|
Status NotificationStatus `json:"status,omitempty" elastic_mapping:"status: { type: keyword }"`
|
||||||
Title string `json:"title,omitempty" elastic_mapping:"title: { type: keyword }"`
|
Title string `json:"title,omitempty" elastic_mapping:"title: { type: keyword }"`
|
||||||
Body string `json:"body,omitempty" elastic_mapping:"body: { type: keyword }"`
|
Body string `json:"body,omitempty" elastic_mapping:"body: { type: keyword }"`
|
||||||
|
|
|
@ -11,4 +11,5 @@ type NotificationAPI struct {
|
||||||
func InitAPI() {
|
func InitAPI() {
|
||||||
notification := NotificationAPI{}
|
notification := NotificationAPI{}
|
||||||
api.HandleAPIMethod(api.GET, "/notification", notification.RequireLogin(notification.listNotifications))
|
api.HandleAPIMethod(api.GET, "/notification", notification.RequireLogin(notification.listNotifications))
|
||||||
|
api.HandleAPIMethod(api.POST, "/notification/read", notification.RequireLogin(notification.setNotificationsRead))
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"time"
|
||||||
|
|
||||||
log "github.com/cihub/seelog"
|
log "github.com/cihub/seelog"
|
||||||
"infini.sh/console/model"
|
"infini.sh/console/model"
|
||||||
|
@ -17,7 +18,7 @@ import (
|
||||||
func (h *NotificationAPI) listNotifications(w http.ResponseWriter, req *http.Request, ps httprouter.Params) {
|
func (h *NotificationAPI) listNotifications(w http.ResponseWriter, req *http.Request, ps httprouter.Params) {
|
||||||
user, err := rbac.FromUserContext(req.Context())
|
user, err := rbac.FromUserContext(req.Context())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error(err)
|
log.Error("failed to get user from context, err: %v", err)
|
||||||
h.WriteError(w, err.Error(), http.StatusInternalServerError)
|
h.WriteError(w, err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -35,7 +36,8 @@ func (h *NotificationAPI) listNotifications(w http.ResponseWriter, req *http.Req
|
||||||
],
|
],
|
||||||
"query": {
|
"query": {
|
||||||
"bool": { "must": [
|
"bool": { "must": [
|
||||||
{ "term": {"user_id": { "value": "%s" } } }
|
{ "term": {"user_id": { "value": "%s" } } },
|
||||||
|
{ "term": {"status": { "value": "%s" } } }
|
||||||
] }
|
] }
|
||||||
},
|
},
|
||||||
"size": %d, "from": %d
|
"size": %d, "from": %d
|
||||||
|
@ -53,7 +55,7 @@ func (h *NotificationAPI) listNotifications(w http.ResponseWriter, req *http.Req
|
||||||
}
|
}
|
||||||
|
|
||||||
q := orm.Query{}
|
q := orm.Query{}
|
||||||
queryDSL = fmt.Sprintf(queryDSL, user.UserId, size, from)
|
queryDSL = fmt.Sprintf(queryDSL, user.UserId, model.NotificationStatusNew, size, from)
|
||||||
q.RawQuery = util.UnsafeStringToBytes(queryDSL)
|
q.RawQuery = util.UnsafeStringToBytes(queryDSL)
|
||||||
|
|
||||||
err, res := orm.Search(&model.Notification{}, &q)
|
err, res := orm.Search(&model.Notification{}, &q)
|
||||||
|
@ -65,3 +67,64 @@ func (h *NotificationAPI) listNotifications(w http.ResponseWriter, req *http.Req
|
||||||
h.WriteJSONHeader(w)
|
h.WriteJSONHeader(w)
|
||||||
h.Write(w, res.Raw)
|
h.Write(w, res.Raw)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type SetNotificationsReadRequest struct {
|
||||||
|
Ids []string `json:"ids"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *NotificationAPI) setNotificationsRead(w http.ResponseWriter, req *http.Request, ps httprouter.Params) {
|
||||||
|
user, err := rbac.FromUserContext(req.Context())
|
||||||
|
if err != nil {
|
||||||
|
log.Error("failed to get user from context, err: %v", err)
|
||||||
|
h.WriteError(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if user == nil {
|
||||||
|
log.Error(errors.New("no user info"))
|
||||||
|
h.WriteError(w, "no user info", http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var reqData = SetNotificationsReadRequest{}
|
||||||
|
err = h.DecodeJSON(req, &reqData)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("failed to parse request: ", err)
|
||||||
|
h.WriteError(w, err.Error(), http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
now := time.Now().Format(time.RFC3339Nano)
|
||||||
|
|
||||||
|
queryDsl := util.MapStr{
|
||||||
|
"query": util.MapStr{
|
||||||
|
"bool": util.MapStr{
|
||||||
|
"must": []util.MapStr{
|
||||||
|
{
|
||||||
|
"terms": util.MapStr{
|
||||||
|
"_id": reqData.Ids,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"term": util.MapStr{
|
||||||
|
"status": util.MapStr{
|
||||||
|
"value": model.NotificationStatusNew,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"script": util.MapStr{
|
||||||
|
"source": fmt.Sprintf("ctx._source['status'] = '%s';ctx._source['updated'] = '%s'", model.NotificationStatusRead, now),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
err = orm.UpdateBy(model.Notification{}, util.MustToJSONBytes(queryDsl))
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("failed to update notifications, err: %v", err)
|
||||||
|
h.WriteError(w, "update notifications failed", http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
h.WriteAckOKJSON(w)
|
||||||
|
}
|
||||||
|
|
|
@ -7,6 +7,11 @@ package migration
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
log "github.com/cihub/seelog"
|
log "github.com/cihub/seelog"
|
||||||
"infini.sh/console/model"
|
"infini.sh/console/model"
|
||||||
"infini.sh/framework/core/api"
|
"infini.sh/framework/core/api"
|
||||||
|
@ -17,16 +22,10 @@ import (
|
||||||
"infini.sh/framework/core/orm"
|
"infini.sh/framework/core/orm"
|
||||||
task2 "infini.sh/framework/core/task"
|
task2 "infini.sh/framework/core/task"
|
||||||
"infini.sh/framework/core/util"
|
"infini.sh/framework/core/util"
|
||||||
"net/http"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
func InitAPI() {
|
func InitAPI() {
|
||||||
handler := APIHandler{
|
handler := APIHandler{}
|
||||||
}
|
|
||||||
api.HandleAPIMethod(api.GET, "/migration/data/_search", handler.RequireLogin(handler.searchDataMigrationTask))
|
api.HandleAPIMethod(api.GET, "/migration/data/_search", handler.RequireLogin(handler.searchDataMigrationTask))
|
||||||
api.HandleAPIMethod(api.POST, "/migration/data", handler.RequireLogin(handler.createDataMigrationTask))
|
api.HandleAPIMethod(api.POST, "/migration/data", handler.RequireLogin(handler.createDataMigrationTask))
|
||||||
api.HandleAPIMethod(api.POST, "/migration/data/_validate", handler.RequireLogin(handler.validateDataMigration))
|
api.HandleAPIMethod(api.POST, "/migration/data/_validate", handler.RequireLogin(handler.validateDataMigration))
|
||||||
|
@ -591,7 +590,7 @@ func getMajorTaskInfoByIndex(taskID string) (map[string]IndexStateInfo, error){
|
||||||
return resBody, nil
|
return resBody, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getIndexTaskDocCount(index *IndexConfig, targetESClient elastic.API) (int64, error) {
|
func getIndexTaskDocCount(ctx context.Context, index *IndexConfig, targetESClient elastic.API) (int64, error) {
|
||||||
targetIndexName := index.Target.Name
|
targetIndexName := index.Target.Name
|
||||||
if targetIndexName == "" {
|
if targetIndexName == "" {
|
||||||
if v, ok := index.IndexRename[index.Source.Name].(string); ok {
|
if v, ok := index.IndexRename[index.Source.Name].(string); ok {
|
||||||
|
@ -622,8 +621,6 @@ func getIndexTaskDocCount(index *IndexConfig, targetESClient elastic.API) (int64
|
||||||
body = util.MustToJSONBytes(query)
|
body = util.MustToJSONBytes(query)
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second*3)
|
|
||||||
defer cancel()
|
|
||||||
countRes, err := targetESClient.Count(ctx, targetIndexName, body)
|
countRes, err := targetESClient.Count(ctx, targetIndexName, body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
|
@ -893,8 +890,8 @@ func (h *APIHandler) countDocuments(w http.ResponseWriter, req *http.Request, ps
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
|
ctx := req.Context()
|
||||||
defer cancel()
|
|
||||||
countRes, err := client.Count(ctx, index, query)
|
countRes, err := client.Count(ctx, index, query)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error(err)
|
log.Error(err)
|
||||||
|
@ -1125,7 +1122,6 @@ func getMajorTaskStatsFromInstances(majorTaskID string) (taskStats MajorTaskStat
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -1503,7 +1503,8 @@ func (p *DispatcherProcessor) sendMajorTaskNotification(taskItem *task2.Task) {
|
||||||
}
|
}
|
||||||
notification := &model.Notification{
|
notification := &model.Notification{
|
||||||
UserId: util.ToString(creatorID),
|
UserId: util.ToString(creatorID),
|
||||||
NotificationType: model.NotificationTypeDataMigration,
|
NotificationType: model.NotificationTypeNotification,
|
||||||
|
MessageType: model.MessageTypeMigration,
|
||||||
Status: model.NotificationStatusNew,
|
Status: model.NotificationStatusNew,
|
||||||
Title: title,
|
Title: title,
|
||||||
Body: body,
|
Body: body,
|
||||||
|
|
Loading…
Reference in New Issue