mirror of
https://github.com/absmach/magistrala.git
synced 2026-06-23 04:10:28 +00:00
ef5c253c51
Signed-off-by: nyagamunene <stevenyaga2014@gmail.com> Signed-off-by: dusan <borovcanindusan1@gmail.com> Co-authored-by: Steve Munene <stevenyaga2014@gmail.com>
210 lines
6.4 KiB
Go
210 lines
6.4 KiB
Go
// Copyright (c) Abstract Machines
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
package api
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"log/slog"
|
|
"math"
|
|
"net/http"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/absmach/supermq"
|
|
"github.com/absmach/supermq/alarms"
|
|
api "github.com/absmach/supermq/api/http"
|
|
apiutil "github.com/absmach/supermq/api/http/util"
|
|
smqauthn "github.com/absmach/supermq/pkg/authn"
|
|
"github.com/absmach/supermq/pkg/errors"
|
|
"github.com/go-chi/chi/v5"
|
|
kithttp "github.com/go-kit/kit/transport/http"
|
|
"github.com/prometheus/client_golang/prometheus/promhttp"
|
|
"go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"
|
|
)
|
|
|
|
func MakeHandler(svc alarms.Service, logger *slog.Logger, idp supermq.IDProvider, instanceID string, authn smqauthn.AuthNMiddleware) http.Handler {
|
|
opts := []kithttp.ServerOption{
|
|
kithttp.ServerErrorEncoder(apiutil.LoggingErrorEncoder(logger, api.EncodeError)),
|
|
}
|
|
|
|
mux := chi.NewRouter()
|
|
|
|
mux.Route("/{domainID}/alarms", func(r chi.Router) {
|
|
r.Group(func(r chi.Router) {
|
|
r.Use(authn.WithOptions(smqauthn.WithDomainCheck(true)).Middleware())
|
|
r.Use(api.RequestIDMiddleware(idp))
|
|
|
|
r.Get("/", otelhttp.NewHandler(kithttp.NewServer(
|
|
listAlarmsEndpoint(svc),
|
|
decodeListAlarmsReq,
|
|
api.EncodeResponse,
|
|
opts...,
|
|
), "list_alarms").ServeHTTP)
|
|
r.Route("/{alarmID}", func(r chi.Router) {
|
|
r.Get("/", otelhttp.NewHandler(kithttp.NewServer(
|
|
viewAlarmEndpoint(svc),
|
|
decodeAlarmReq,
|
|
api.EncodeResponse,
|
|
opts...,
|
|
), "get_alarm").ServeHTTP)
|
|
r.Put("/", otelhttp.NewHandler(kithttp.NewServer(
|
|
updateAlarmEndpoint(svc),
|
|
decodeUpdateAlarmReq,
|
|
api.EncodeResponse,
|
|
opts...,
|
|
), "update_alarm").ServeHTTP)
|
|
r.Delete("/", otelhttp.NewHandler(kithttp.NewServer(
|
|
deleteAlarmEndpoint(svc),
|
|
decodeAlarmReq,
|
|
api.EncodeResponse,
|
|
opts...,
|
|
), "delete_alarm").ServeHTTP)
|
|
})
|
|
})
|
|
})
|
|
|
|
mux.Get("/health", supermq.Health("alarms", instanceID))
|
|
mux.Handle("/metrics", promhttp.Handler())
|
|
|
|
return mux
|
|
}
|
|
|
|
func decodeListAlarmsReq(_ context.Context, r *http.Request) (any, error) {
|
|
offset, err := apiutil.ReadNumQuery[uint64](r, api.OffsetKey, api.DefOffset)
|
|
if err != nil {
|
|
return listAlarmsReq{}, errors.Wrap(apiutil.ErrValidation, err)
|
|
}
|
|
limit, err := apiutil.ReadNumQuery[uint64](r, api.LimitKey, api.DefLimit)
|
|
if err != nil {
|
|
return listAlarmsReq{}, errors.Wrap(apiutil.ErrValidation, err)
|
|
}
|
|
domainID, err := apiutil.ReadStringQuery(r, "domain_id", "")
|
|
if err != nil {
|
|
return listAlarmsReq{}, errors.Wrap(apiutil.ErrValidation, err)
|
|
}
|
|
channelID, err := apiutil.ReadStringQuery(r, "channel_id", "")
|
|
if err != nil {
|
|
return listAlarmsReq{}, errors.Wrap(apiutil.ErrValidation, err)
|
|
}
|
|
clientID, err := apiutil.ReadStringQuery(r, "client_id", "")
|
|
if err != nil {
|
|
return listAlarmsReq{}, errors.Wrap(apiutil.ErrValidation, err)
|
|
}
|
|
subtopic, err := apiutil.ReadStringQuery(r, "subtopic", "")
|
|
if err != nil {
|
|
return listAlarmsReq{}, errors.Wrap(apiutil.ErrValidation, err)
|
|
}
|
|
ruleID, err := apiutil.ReadStringQuery(r, "rule_id", "")
|
|
if err != nil {
|
|
return listAlarmsReq{}, errors.Wrap(apiutil.ErrValidation, err)
|
|
}
|
|
s, err := apiutil.ReadStringQuery(r, api.StatusKey, alarms.All)
|
|
if err != nil {
|
|
return listAlarmsReq{}, errors.Wrap(apiutil.ErrValidation, err)
|
|
}
|
|
status, err := alarms.ToStatus(s)
|
|
if err != nil {
|
|
return listAlarmsReq{}, errors.Wrap(apiutil.ErrValidation, err)
|
|
}
|
|
assigneeID, err := apiutil.ReadStringQuery(r, "assignee_id", "")
|
|
if err != nil {
|
|
return listAlarmsReq{}, errors.Wrap(apiutil.ErrValidation, err)
|
|
}
|
|
serverity, err := apiutil.ReadNumQuery(r, "severity", uint64(math.MaxUint8))
|
|
if err != nil {
|
|
return listAlarmsReq{}, errors.Wrap(apiutil.ErrValidation, err)
|
|
}
|
|
updatedBy, err := apiutil.ReadStringQuery(r, "updated_by", "")
|
|
if err != nil {
|
|
return listAlarmsReq{}, errors.Wrap(apiutil.ErrValidation, err)
|
|
}
|
|
assignedBy, err := apiutil.ReadStringQuery(r, "assigned_by", "")
|
|
if err != nil {
|
|
return listAlarmsReq{}, errors.Wrap(apiutil.ErrValidation, err)
|
|
}
|
|
acknowledgedBy, err := apiutil.ReadStringQuery(r, "acknowledged_by", "")
|
|
if err != nil {
|
|
return listAlarmsReq{}, errors.Wrap(apiutil.ErrValidation, err)
|
|
}
|
|
resolvedBy, err := apiutil.ReadStringQuery(r, "resolved_by", "")
|
|
if err != nil {
|
|
return listAlarmsReq{}, errors.Wrap(apiutil.ErrValidation, err)
|
|
}
|
|
cfrom, err := apiutil.ReadStringQuery(r, "created_from", "")
|
|
if err != nil {
|
|
return listAlarmsReq{}, errors.Wrap(apiutil.ErrValidation, err)
|
|
}
|
|
cto, err := apiutil.ReadStringQuery(r, "created_to", "")
|
|
if err != nil {
|
|
return listAlarmsReq{}, errors.Wrap(apiutil.ErrValidation, err)
|
|
}
|
|
order, err := apiutil.ReadStringQuery(r, api.OrderKey, api.DefOrder)
|
|
if err != nil {
|
|
return listAlarmsReq{}, errors.Wrap(apiutil.ErrValidation, err)
|
|
}
|
|
dir, err := apiutil.ReadStringQuery(r, api.DirKey, "desc")
|
|
if err != nil {
|
|
return listAlarmsReq{}, errors.Wrap(apiutil.ErrValidation, err)
|
|
}
|
|
|
|
var createdFrom, createdTo time.Time
|
|
if cfrom != "" {
|
|
if createdFrom, err = time.Parse(time.RFC3339, cfrom); err != nil {
|
|
return listAlarmsReq{}, errors.Wrap(apiutil.ErrValidation, err)
|
|
}
|
|
}
|
|
if cto != "" {
|
|
if createdTo, err = time.Parse(time.RFC3339, cto); err != nil {
|
|
return listAlarmsReq{}, errors.Wrap(apiutil.ErrValidation, err)
|
|
}
|
|
}
|
|
|
|
return listAlarmsReq{
|
|
PageMetadata: alarms.PageMetadata{
|
|
Offset: offset,
|
|
Limit: limit,
|
|
DomainID: domainID,
|
|
ChannelID: channelID,
|
|
ClientID: clientID,
|
|
Subtopic: subtopic,
|
|
RuleID: ruleID,
|
|
Status: status,
|
|
AssigneeID: assigneeID,
|
|
ResolvedBy: resolvedBy,
|
|
Severity: uint8(serverity),
|
|
UpdatedBy: updatedBy,
|
|
AcknowledgedBy: acknowledgedBy,
|
|
AssignedBy: assignedBy,
|
|
CreatedFrom: createdFrom,
|
|
CreatedTo: createdTo,
|
|
Dir: dir,
|
|
Order: order,
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
func decodeAlarmReq(_ context.Context, r *http.Request) (any, error) {
|
|
return alarmReq{
|
|
Alarm: alarms.Alarm{
|
|
ID: chi.URLParam(r, "alarmID"),
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
func decodeUpdateAlarmReq(_ context.Context, r *http.Request) (any, error) {
|
|
if !strings.Contains(r.Header.Get("Content-Type"), api.ContentType) {
|
|
return updateAlarmReq{}, apiutil.ErrUnsupportedContentType
|
|
}
|
|
|
|
req := updateAlarmReq{}
|
|
if err := json.NewDecoder(r.Body).Decode(&req.Alarm); err != nil {
|
|
return updateAlarmReq{}, errors.Wrap(apiutil.ErrMalformedRequestBody, err)
|
|
}
|
|
|
|
req.Alarm.ID = chi.URLParam(r, "alarmID")
|
|
|
|
return req, nil
|
|
}
|