Fix cluster api responses

This commit is contained in:
Ingo Oppermann
2022-09-28 21:49:25 +02:00
parent 692b65b97c
commit 9ef4ae9b5e
6 changed files with 89 additions and 33 deletions

View File

@@ -2,6 +2,7 @@ package cluster
import (
"context"
"errors"
"fmt"
"io"
"sync"
@@ -11,6 +12,8 @@ import (
"github.com/datarhei/core/v16/net"
)
var ErrNodeNotFound = errors.New("node not found")
type ClusterReader interface {
GetURL(path string) (string, error)
GetFile(path string) (io.ReadCloser, error)
@@ -182,7 +185,7 @@ func (c *cluster) RemoveNode(id string) error {
node, ok := c.nodes[id]
if !ok {
return nil
return ErrNodeNotFound
}
node.stop()

View File

@@ -62,7 +62,7 @@ const docTemplate = `{
"operationId": "graph-playground",
"responses": {
"200": {
"description": ""
"description": "OK"
}
}
}
@@ -327,14 +327,14 @@ const docTemplate = `{
"ApiKeyAuth": []
}
],
"description": "Replace an existing Node",
"description": "Replaces an existing node and returns the new node ID",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"summary": "Replace an existing Node",
"summary": "Replaces an existing node",
"operationId": "cluster-3-update-node",
"parameters": [
{
@@ -403,8 +403,14 @@ const docTemplate = `{
"type": "string"
}
},
"400": {
"description": "Bad Request",
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/api.Error"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/api.Error"
}
@@ -438,10 +444,7 @@ const docTemplate = `{
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"type": "string"
}
"$ref": "#/definitions/api.ClusterNodeFiles"
}
},
"404": {
@@ -2581,6 +2584,15 @@ const docTemplate = `{
}
}
},
"api.ClusterNodeFiles": {
"type": "object",
"additionalProperties": {
"type": "array",
"items": {
"type": "string"
}
}
},
"api.Command": {
"type": "object",
"required": [

View File

@@ -54,7 +54,7 @@
"operationId": "graph-playground",
"responses": {
"200": {
"description": ""
"description": "OK"
}
}
}
@@ -319,14 +319,14 @@
"ApiKeyAuth": []
}
],
"description": "Replace an existing Node",
"description": "Replaces an existing node and returns the new node ID",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"summary": "Replace an existing Node",
"summary": "Replaces an existing node",
"operationId": "cluster-3-update-node",
"parameters": [
{
@@ -395,8 +395,14 @@
"type": "string"
}
},
"400": {
"description": "Bad Request",
"404": {
"description": "Not Found",
"schema": {
"$ref": "#/definitions/api.Error"
}
},
"500": {
"description": "Internal Server Error",
"schema": {
"$ref": "#/definitions/api.Error"
}
@@ -430,10 +436,7 @@
"200": {
"description": "OK",
"schema": {
"type": "array",
"items": {
"type": "string"
}
"$ref": "#/definitions/api.ClusterNodeFiles"
}
},
"404": {
@@ -2573,6 +2576,15 @@
}
}
},
"api.ClusterNodeFiles": {
"type": "object",
"additionalProperties": {
"type": "array",
"items": {
"type": "string"
}
}
},
"api.Command": {
"type": "object",
"required": [

View File

@@ -76,6 +76,12 @@ definitions:
username:
type: string
type: object
api.ClusterNodeFiles:
additionalProperties:
items:
type: string
type: array
type: object
api.Command:
properties:
command:
@@ -1774,7 +1780,7 @@ paths:
- text/html
responses:
"200":
description: ""
description: OK
security:
- ApiKeyAuth: []
summary: Load GraphQL playground
@@ -1933,8 +1939,12 @@ paths:
description: OK
schema:
type: string
"400":
description: Bad Request
"404":
description: Not Found
schema:
$ref: '#/definitions/api.Error'
"500":
description: Internal Server Error
schema:
$ref: '#/definitions/api.Error'
security:
@@ -1966,7 +1976,7 @@ paths:
put:
consumes:
- application/json
description: Replace an existing Node
description: Replaces an existing node and returns the new node ID
operationId: cluster-3-update-node
parameters:
- description: Node ID
@@ -1997,7 +2007,7 @@ paths:
$ref: '#/definitions/api.Error'
security:
- ApiKeyAuth: []
summary: Replace an existing Node
summary: Replaces an existing node
/api/v3/cluster/node/{id}/proxy:
get:
description: List the files of a node by its ID
@@ -2014,9 +2024,7 @@ paths:
"200":
description: OK
schema:
items:
type: string
type: array
$ref: '#/definitions/api.ClusterNodeFiles'
"404":
description: Not Found
schema:

View File

@@ -13,4 +13,4 @@ type ClusterNode struct {
State string `json:"state"`
}
type ClusterNodeFiles []string
type ClusterNodeFiles map[string][]string

View File

@@ -2,7 +2,9 @@ package api
import (
"net/http"
"regexp"
"sort"
"strings"
"github.com/datarhei/core/v16/cluster"
"github.com/datarhei/core/v16/http/api"
@@ -14,12 +16,14 @@ import (
// The ClusterHandler type provides handler functions for manipulating the cluster config.
type ClusterHandler struct {
cluster cluster.Cluster
prefix *regexp.Regexp
}
// NewCluster return a new ClusterHandler type. You have to provide a cluster.
func NewCluster(cluster cluster.Cluster) *ClusterHandler {
return &ClusterHandler{
cluster: cluster,
prefix: regexp.MustCompile(`^[a-z]+:`),
}
}
@@ -85,14 +89,19 @@ func (h *ClusterHandler) AddNode(c echo.Context) error {
// @Produce json
// @Param id path string true "Node ID"
// @Success 200 {string} string
// @Failure 400 {object} api.Error
// @Failure 404 {object} api.Error
// @Failure 500 {object} api.Error
// @Security ApiKeyAuth
// @Router /api/v3/cluster/node/{id} [delete]
func (h *ClusterHandler) DeleteNode(c echo.Context) error {
id := util.PathParam(c, "id")
if err := h.cluster.RemoveNode(id); err != nil {
return api.Err(http.StatusBadRequest, "Failed to remove node", "%s", err)
if err == cluster.ErrNodeNotFound {
return api.Err(http.StatusNotFound, err.Error(), "%s", id)
}
return api.Err(http.StatusInternalServerError, "Failed to remove node", "%s", err)
}
return c.JSON(http.StatusOK, "OK")
@@ -146,16 +155,25 @@ func (h *ClusterHandler) GetNodeProxy(c echo.Context) error {
return api.Err(http.StatusNotFound, "Node not found", "%s", err)
}
files := api.ClusterNodeFiles{}
state := peer.State()
sort.Strings(state.Files)
return c.JSON(http.StatusOK, state.Files)
for _, path := range state.Files {
prefix := strings.TrimSuffix(h.prefix.FindString(path), ":")
path = h.prefix.ReplaceAllString(path, "")
files[prefix] = append(files[prefix], path)
}
return c.JSON(http.StatusOK, files)
}
// UpdateNode replaces an existing node
// @Summary Replace an existing Node
// @Description Replace an existing Node
// @Summary Replaces an existing node
// @Description Replaces an existing node and returns the new node ID
// @ID cluster-3-update-node
// @Accept json
// @Produce json
@@ -176,6 +194,9 @@ func (h *ClusterHandler) UpdateNode(c echo.Context) error {
}
if err := h.cluster.RemoveNode(id); err != nil {
if err == cluster.ErrNodeNotFound {
return api.Err(http.StatusNotFound, err.Error(), "%s", id)
}
return api.Err(http.StatusBadRequest, "Failed to remove node", "%s", err)
}