Skip to content

Commit

Permalink
feat(endpoint): get single endpoint
Browse files Browse the repository at this point in the history
All data about a single endpoint may now be retrieved, to support this
feature sids are provided when listing endpoints.
  • Loading branch information
crazybolillo committed Aug 18, 2024
1 parent 9f4b256 commit 838c4cc
Show file tree
Hide file tree
Showing 5 changed files with 184 additions and 8 deletions.
7 changes: 6 additions & 1 deletion cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,5 +81,10 @@ func serve(ctx context.Context) error {
r.Mount("/bouncer", authorization.Router())

slog.Info("Listening on :8080")
return http.ListenAndServe(":8080", r)
err = http.ListenAndServe(":8080", r)
if err != nil {
slog.Error("Failed to start server", "reason", err.Error())
}

return err
}
47 changes: 45 additions & 2 deletions docs/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,25 @@ definitions:
transport:
type: string
type: object
handler.getEndpointResponse:
properties:
codecs:
items:
type: string
type: array
context:
type: string
displayName:
type: string
extension:
type: string
id:
type: string
maxContacts:
type: integer
transport:
type: string
type: object
handler.listEndpointEntry:
properties:
context:
Expand All @@ -48,8 +67,10 @@ definitions:
type: string
id:
type: string
sid:
type: integer
type: object
handler.listEndpointsRequest:
handler.listEndpointsResponse:
properties:
endpoints:
items:
Expand Down Expand Up @@ -103,7 +124,7 @@ paths:
"200":
description: OK
schema:
$ref: '#/definitions/handler.listEndpointsRequest'
$ref: '#/definitions/handler.listEndpointsResponse'
"400":
description: Bad Request
"500":
Expand Down Expand Up @@ -149,4 +170,26 @@ paths:
summary: Delete an endpoint and its associated resources.
tags:
- endpoints
/endpoints/{sid}:
get:
parameters:
- description: Requested endpoint's sid
in: path
name: sid
required: true
type: integer
produces:
- application/json
responses:
"200":
description: OK
schema:
$ref: '#/definitions/handler.getEndpointResponse'
"400":
description: Bad Request
"500":
description: Internal Server Error
summary: Get information from a specific endpoint.
tags:
- endpoints
swagger: "2.0"
82 changes: 79 additions & 3 deletions internal/handler/endpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"crypto/md5"
"encoding/hex"
"encoding/json"
"errors"
"fmt"
"github.com/crazybolillo/eryth/internal/db"
"github.com/crazybolillo/eryth/internal/sqlc"
Expand Down Expand Up @@ -32,20 +33,32 @@ type createEndpointRequest struct {
}

type listEndpointEntry struct {
Sid int32 `json:"sid"`
ID string `json:"id"`
Extension string `json:"extension"`
Context string `json:"context"`
DisplayName string `json:"displayName"`
}

type listEndpointsRequest struct {
type listEndpointsResponse struct {
Endpoints []listEndpointEntry `json:"endpoints"`
}

type getEndpointResponse struct {
ID string `json:"id"`
DisplayName string `json:"displayName"`
Transport string `json:"transport"`
Context string `json:"context"`
Codecs []string `json:"codecs"`
MaxContacts int32 `json:"maxContacts"`
Extension string `json:"extension"`
}

func (e *Endpoint) Router() chi.Router {
r := chi.NewRouter()
r.Post("/", e.create)
r.Get("/", e.list)
r.Get("/{sid}", e.get)
r.Delete("/{id}", e.delete)

return r
Expand All @@ -72,10 +85,72 @@ func displayNameFromClid(callerID string) string {
return callerID[1:end]
}

// @Summary Get information from a specific endpoint.
// @Param sid path int true "Requested endpoint's sid"
// @Produce json
// @Success 200 {object} getEndpointResponse
// @Failure 400
// @Failure 500
// @Tags endpoints
// @Router /endpoints/{sid} [get]
func (e *Endpoint) get(w http.ResponseWriter, r *http.Request) {
sid := chi.URLParam(r, "sid")
if sid == "" {
w.WriteHeader(http.StatusBadRequest)
return
}
id, err := strconv.ParseInt(sid, 10, 32)
if err != nil {
w.WriteHeader(http.StatusBadRequest)
return
}

tx, err := e.Begin(r.Context())
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
return
}
defer tx.Rollback(r.Context())

queries := sqlc.New(tx)

row, err := queries.GetEndpointByID(r.Context(), int32(id))
if errors.Is(err, pgx.ErrNoRows) {
w.WriteHeader(http.StatusNotFound)
return
} else if err != nil {
w.WriteHeader(http.StatusInternalServerError)
slog.Error("Failed to retrieve endpoint", slog.String("path", r.URL.Path), slog.String("reason", err.Error()))
return
}

endpoint := getEndpointResponse{
ID: row.ID,
Transport: row.Transport.String,
Context: row.Context.String,
Codecs: strings.Split(row.Allow.String, ","),
MaxContacts: row.MaxContacts.Int32,
Extension: row.Extension.String,
DisplayName: displayNameFromClid(row.Callerid.String),
}
content, err := json.Marshal(endpoint)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
slog.Error("Failed to marshall response", slog.String("path", r.URL.Path))
return
}

w.Header().Set("Content-Type", "application/json")
_, err = w.Write(content)
if err != nil {
slog.Error("Failed to write response", slog.String("path", r.URL.Path), slog.String("reason", err.Error()))
}
}

// @Summary List existing endpoints.
// @Param limit query int false "Limit the amount of endpoints returned" default(15)
// @Produce json
// @Success 200 {object} listEndpointsRequest
// @Success 200 {object} listEndpointsResponse
// @Failure 400
// @Failure 500
// @Tags endpoints
Expand Down Expand Up @@ -107,13 +182,14 @@ func (e *Endpoint) list(w http.ResponseWriter, r *http.Request) {
for idx := range len(rows) {
row := rows[idx]
endpoints[idx] = listEndpointEntry{
Sid: row.Sid,
ID: row.ID,
Extension: row.Extension.String,
Context: row.Context.String,
DisplayName: displayNameFromClid(row.Callerid.String),
}
}
response := listEndpointsRequest{
response := listEndpointsResponse{
Endpoints: endpoints,
}
content, err := json.Marshal(response)
Expand Down
42 changes: 41 additions & 1 deletion internal/sqlc/queries.sql.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 13 additions & 1 deletion queries.sql
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ DELETE FROM ps_auths WHERE id = $1;

-- name: ListEndpoints :many
SELECT
pe.id, pe.callerid, pe.context, ee.extension
pe.sid, pe.id, pe.callerid, pe.context, ee.extension
FROM
ps_endpoints pe
LEFT JOIN
Expand All @@ -53,3 +53,15 @@ INNER JOIN
ps_endpoints src ON src.id = $1
WHERE
ee.extension = $2;

-- name: GetEndpointByID :one
SELECT
pe.id, pe.callerid, pe.context, ee.extension, pe.transport, aor.max_contacts, pe.allow
FROM
ps_endpoints pe
INNER JOIN
ery_extension ee ON ee.endpoint_id = pe.sid
INNER JOIN
ps_aors aor ON aor.id = pe.id
WHERE
pe.sid = $1;

0 comments on commit 838c4cc

Please sign in to comment.