Skip to content

Commit

Permalink
add scaffolding for heartbeats
Browse files Browse the repository at this point in the history
  • Loading branch information
equinox0815 committed Oct 30, 2023
1 parent 0aa5777 commit a7b6888
Show file tree
Hide file tree
Showing 5 changed files with 169 additions and 0 deletions.
7 changes: 7 additions & 0 deletions api/v1/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,13 @@ func InstallHTTPHandler(r *gin.RouterGroup, st *store.Store) {
alerts.PATCH(":alert-id/state", api.UpdateAlertState)
alerts.DELETE(":alert-id", api.DeleteAlert)
}
heartbeats := r.Group("heartbeats")
{
heartbeats.GET("", api.ListHeartbeats)
heartbeats.POST("", api.CreateHeartbeat)
heartbeats.GET(":heartbeat-id", api.ReadHeartbeat)
heartbeats.DELETE(":heartbeat-id", api.DeleteAlert)
}

submit := r.Group("submit")
{
Expand Down
91 changes: 91 additions & 0 deletions api/v1/heartbeats.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
//
// Copyright (c) 2023 whawty contributors (see AUTHORS file)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of whawty.alerts nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//

package v1

import (
"encoding/json"
"net/http"

"github.com/gin-gonic/gin"
"github.com/oklog/ulid/v2"
"github.com/whawty/alerts/store"
)

func (api *API) ListHeartbeats(c *gin.Context) {
offset, limit, ok := getPaginationParameter(c)
if !ok {
return
}

heartbeats, err := api.store.ListHeartbeats(offset, limit)
if err != nil {
sendError(c, err)
return
}
c.JSON(http.StatusOK, HeartbeatsListing{heartbeats})
}

func (api *API) CreateHeartbeat(c *gin.Context) {
heartbeat := &store.Heartbeat{}
err := json.NewDecoder(c.Request.Body).Decode(heartbeat)
if err != nil {
c.JSON(http.StatusBadRequest, ErrorResponse{Error: "error decoding heartbeat: " + err.Error()})
return
}
heartbeat.ID = ulid.Make().String()

if heartbeat, err = api.store.CreateHeartbeat(heartbeat); err != nil {
sendError(c, err)
return
}
c.JSON(http.StatusCreated, heartbeat)
}

func (api *API) ReadHeartbeat(c *gin.Context) {
id := c.Param("heartbeat-id")

heartbeat, err := api.store.GetHeartbeat(id)
if err != nil {
sendError(c, err)
return
}
c.JSON(http.StatusOK, heartbeat)
}

func (api *API) DeleteHeartbeat(c *gin.Context) {
id := c.Param("heartbeat-id")

if err := api.store.DeleteHeartbeat(id); err != nil {
sendError(c, err)
return
}
c.JSON(http.StatusNoContent, nil)
}
5 changes: 5 additions & 0 deletions api/v1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,8 @@ type ErrorResponse struct {
type AlertsListing struct {
Alerts []store.Alert `json:"results"`
}

// Heartbeats
type HeartbeatsListing struct {
Heartbeats []store.Heartbeat `json:"results"`
}
56 changes: 56 additions & 0 deletions store/heartbeats.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
//
// Copyright (c) 2023 whawty contributors (see AUTHORS file)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// * Neither the name of whawty.alerts nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//

package store

func (s *Store) CreateHeartbeat(alert *Heartbeat) (*Heartbeat, error) {
// TODO: implement this
return nil, ErrNotImplemented
}

func (s *Store) ListHeartbeats(offset, limit int) ([]Heartbeat, error) {
// TODO: implement this
return nil, ErrNotImplemented
}

func (s *Store) GetHeartbeat(id string) (*Heartbeat, error) {
// TODO: implement this
return nil, ErrNotImplemented
}

func (s *Store) RefreshHeartbeat(id string) (*Heartbeat, error) {
// TODO: implement this
return nil, ErrNotImplemented
}

func (s *Store) DeleteHeartbeat(id string) error {
// TODO: implement this
return ErrNotImplemented
}
10 changes: 10 additions & 0 deletions store/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -193,8 +193,18 @@ type Alert struct {
Name string `json:"name"`
State AlertState `json:"state"`
Severity AlertSeverity `json:"severity"`
// TODO: additinial fields
}

func (a Alert) String() string {
return a.ID
}

// Heartbeats

type Heartbeat struct {
ID string `json:"id"`
CreatedAt time.Time `json:"created"`
UpdatedAt time.Time `json:"updated"`
// TODO: additinial fields
}

0 comments on commit a7b6888

Please sign in to comment.