Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
authIrmaAPI "github.com/nuts-foundation/nuts-node/auth/api/irma"
authV1API "github.com/nuts-foundation/nuts-node/auth/api/v0"
authCmd "github.com/nuts-foundation/nuts-node/auth/cmd"
"github.com/nuts-foundation/nuts-node/core/status"
"io"
"os"

Expand Down Expand Up @@ -144,7 +145,7 @@ func CreateSystem() *core.System {
networkInstance := network.NewNetworkInstance(network.DefaultConfig(), cryptoInstance)
vdrInstance := vdr.NewVDR(vdr.DefaultConfig(), cryptoInstance, networkInstance)
credentialInstance := vcr.NewVCRInstance(cryptoInstance, vdrInstance, networkInstance)
statusEngine := core.NewStatusEngine(system)
statusEngine := status.NewStatusEngine(system)
metricsEngine := core.NewMetricsEngine()
authInstance := auth.NewAuthInstance(auth.DefaultConfig(), vdrInstance, cryptoInstance)

Expand Down Expand Up @@ -182,6 +183,7 @@ func Execute(system *core.System) {
func addSubCommands(system *core.System, root *cobra.Command) {
// Register client commands
clientCommands := []*cobra.Command{
status.Cmd(),
cryptoCmd.Cmd(),
networkCmd.Cmd(),
vdrCmd.Cmd(),
Expand Down
5 changes: 5 additions & 0 deletions core/metrics_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ import (
"github.com/stretchr/testify/assert"
)

func TestMetricsEngine_Name(t *testing.T) {
named := NewMetricsEngine().(Named)
assert.Equal(t, "Metrics", named.Name())
}

func TestNewMetricsEngine(t *testing.T) {
mEngine := NewMetricsEngine().(*metrics)
_ = mEngine.Configure(ServerConfig{})
Expand Down
54 changes: 54 additions & 0 deletions core/status/cmd.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* Nuts node
* Copyright (C) 2021. Nuts community
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

package status

import (
"fmt"
"github.com/spf13/cobra"
"io/ioutil"
"net/http"

"github.com/nuts-foundation/nuts-node/core"
)

// Cmd contains sub-commands for the remote client
func Cmd() *cobra.Command {
cmd := &cobra.Command{
Use: "status",
Short: "Shows the status of the Nuts Node.",
RunE: func(cmd *cobra.Command, args []string) error {
config := core.NewClientConfig()
if err := config.Load(cmd.PersistentFlags()); err != nil {
return err
}
targetURL := config.GetAddress() + diagnosticsEndpoint
response, err := http.Get(targetURL)
if err != nil {
return err
}
if response.StatusCode != http.StatusOK {
return fmt.Errorf("unexpected HTTP response code (url=%s): %d", targetURL, response.StatusCode)
}
bytes, _ := ioutil.ReadAll(response.Body)
cmd.Println(string(bytes))
return nil
},
}
return cmd
}
63 changes: 63 additions & 0 deletions core/status/cmd_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
* Nuts node
* Copyright (C) 2021. Nuts community
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

package status

import (
"bytes"
"net/http"
"net/http/httptest"
"os"
"testing"

"github.com/nuts-foundation/nuts-node/core"
http2 "github.com/nuts-foundation/nuts-node/test/http"
"github.com/stretchr/testify/assert"
)

func TestEngine_Command(t *testing.T) {
t.Run("ok", func(t *testing.T) {
cmd := Cmd()
s := httptest.NewServer(http2.Handler{StatusCode: http.StatusOK, ResponseData: "diagnostics"})
os.Setenv("NUTS_ADDRESS", s.URL)
defer os.Unsetenv("NUTS_ADDRESS")
core.NewServerConfig().Load(cmd)
defer s.Close()

buf := new(bytes.Buffer)
cmd.SetArgs([]string{"status"})
cmd.SetOut(buf)
err := cmd.Execute()
assert.NoError(t, err)
assert.Equal(t, "diagnostics\n", buf.String())
})
t.Run("unexpected status code", func(t *testing.T) {
cmd := Cmd()
s := httptest.NewServer(http2.Handler{StatusCode: http.StatusInternalServerError, ResponseData: ""})
os.Setenv("NUTS_ADDRESS", s.URL)
defer os.Unsetenv("NUTS_ADDRESS")
core.NewServerConfig().Load(cmd)
defer s.Close()

buf := new(bytes.Buffer)
cmd.SetArgs([]string{"status"})
cmd.SetOut(buf)
err := cmd.Execute()
assert.Error(t, err)
})
}
31 changes: 17 additions & 14 deletions core/status.go → core/status/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,11 @@
*
*/

package core
package status

import (
"fmt"
"github.com/nuts-foundation/nuts-node/core"
"net/http"
"strings"
"time"
Expand All @@ -29,14 +30,16 @@ import (
)

const moduleName = "Status"
const diagnosticsEndpoint = "/status/diagnostics"
const statusEndpoint = "/status"

type status struct {
system *System
system *core.System
startTime time.Time
}

//NewStatusEngine creates a new Engine for viewing all engines
func NewStatusEngine(system *System) Engine {
func NewStatusEngine(system *core.System) core.Engine {
return &status{
system: system,
startTime: time.Now(),
Expand All @@ -47,9 +50,9 @@ func (s *status) Name() string {
return moduleName
}

func (s *status) Routes(router EchoRouter) {
router.Add(http.MethodGet, "/status/diagnostics", s.diagnosticsOverview)
router.Add(http.MethodGet, "/status", statusOK)
func (s *status) Routes(router core.EchoRouter) {
router.Add(http.MethodGet, diagnosticsEndpoint, s.diagnosticsOverview)
router.Add(http.MethodGet, statusEndpoint, statusOK)
}

func (s *status) diagnosticsOverview(ctx echo.Context) error {
Expand All @@ -58,8 +61,8 @@ func (s *status) diagnosticsOverview(ctx echo.Context) error {

func (s *status) diagnosticsSummaryAsText() string {
var lines []string
s.system.VisitEngines(func(engine Engine) {
if m, ok := engine.(ViewableDiagnostics); ok {
s.system.VisitEngines(func(engine core.Engine) {
if m, ok := engine.(core.ViewableDiagnostics); ok {
lines = append(lines, m.Name())
diagnostics := m.Diagnostics()
for _, d := range diagnostics {
Expand All @@ -72,17 +75,17 @@ func (s *status) diagnosticsSummaryAsText() string {

// Diagnostics returns list of DiagnosticResult for the StatusEngine.
// The results are a list of all registered engines
func (s *status) Diagnostics() []DiagnosticResult {
return []DiagnosticResult{
&GenericDiagnosticResult{Title: "Registered engines", Outcome: strings.Join(s.listAllEngines(), ",")},
&GenericDiagnosticResult{Title: "Uptime", Outcome: time.Now().Sub(s.startTime).String()},
func (s *status) Diagnostics() []core.DiagnosticResult {
return []core.DiagnosticResult{
&core.GenericDiagnosticResult{Title: "Registered engines", Outcome: strings.Join(s.listAllEngines(), ",")},
&core.GenericDiagnosticResult{Title: "Uptime", Outcome: time.Now().Sub(s.startTime).String()},
}
}

func (s *status) listAllEngines() []string {
var names []string
s.system.VisitEngines(func(engine Engine) {
if m, ok := engine.(Named); ok {
s.system.VisitEngines(func(engine core.Engine) {
if m, ok := engine.(core.Named); ok {
names = append(names, m.Name())
}
})
Expand Down
11 changes: 6 additions & 5 deletions core/status_test.go → core/status/engine_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package core
package status

import (
"github.com/nuts-foundation/nuts-node/core"
"github.com/nuts-foundation/nuts-node/test"
"net/http"
"testing"
Expand All @@ -14,19 +15,19 @@ func TestNewStatusEngine_Routes(t *testing.T) {
t.Run("Registers a single route for listing all engines", func(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
echo := NewMockEchoRouter(ctrl)
echo := core.NewMockEchoRouter(ctrl)

echo.EXPECT().Add(http.MethodGet, "/status/diagnostics", gomock.Any())
echo.EXPECT().Add(http.MethodGet, "/status", gomock.Any())

NewStatusEngine(NewSystem()).(*status).Routes(echo)
NewStatusEngine(core.NewSystem()).(*status).Routes(echo)
})
}

func TestNewStatusEngine_Diagnostics(t *testing.T) {
system := NewSystem()
system := core.NewSystem()
system.RegisterEngine(NewStatusEngine(system))
system.RegisterEngine(NewMetricsEngine())
system.RegisterEngine(core.NewMetricsEngine())

t.Run("diagnostics() returns engine list", func(t *testing.T) {
system := NewStatusEngine(system)
Expand Down