From 248d88a57c367a5e17ecfe2cc813900b486cd476 Mon Sep 17 00:00:00 2001 From: Donatas Kucinskas Date: Fri, 26 Jan 2018 10:29:06 +0200 Subject: [PATCH 1/8] Add "SessionStatsHandler" interface in bytescount middleware --- .../client/bytescount/middleware.go | 16 +++++++++------ .../client/bytescount/middleware_test.go | 20 +++++++++---------- .../client/bytescount/stats_sender.go | 3 ++- 3 files changed, 22 insertions(+), 17 deletions(-) diff --git a/openvpn/middlewares/client/bytescount/middleware.go b/openvpn/middlewares/client/bytescount/middleware.go index 4e8166bdb..7ef91fda8 100644 --- a/openvpn/middlewares/client/bytescount/middleware.go +++ b/openvpn/middlewares/client/bytescount/middleware.go @@ -9,18 +9,22 @@ import ( "time" ) +// SessionStatsHandler is invoked when middleware receives statistics +type SessionStatsHandler func(bytesSent, bytesReceived int) error + type middleware struct { - sessionStatsSender SessionStatsSender - interval time.Duration + sessionStatsHandler SessionStatsHandler + interval time.Duration state openvpn.State connection net.Conn } -func NewMiddleware(sessionStatsSender SessionStatsSender, interval time.Duration) openvpn.ManagementMiddleware { +// NewMiddleware returns new bytescount middleware +func NewMiddleware(sessionStatsHandler SessionStatsHandler, interval time.Duration) openvpn.ManagementMiddleware { return &middleware{ - sessionStatsSender: sessionStatsSender, - interval: interval, + sessionStatsHandler: sessionStatsHandler, + interval: interval, connection: nil, } @@ -62,7 +66,7 @@ func (middleware *middleware) ConsumeLine(line string) (consumed bool, err error return } - err = middleware.sessionStatsSender(bytesOut, bytesIn) + err = middleware.sessionStatsHandler(bytesOut, bytesIn) return } diff --git a/openvpn/middlewares/client/bytescount/middleware_test.go b/openvpn/middlewares/client/bytescount/middleware_test.go index 594db0521..9a330db4b 100644 --- a/openvpn/middlewares/client/bytescount/middleware_test.go +++ b/openvpn/middlewares/client/bytescount/middleware_test.go @@ -45,25 +45,25 @@ func (conn *fakeConnection) SetWriteDeadline(t time.Time) error { return nil } -type fakeStatsSender struct { +type fakeStatsHandler struct { lastBytesSent, lastBytesReceived int } -func (sender *fakeStatsSender) send(bytesSent, bytesReceived int) error { +func (sender *fakeStatsHandler) save(bytesSent, bytesReceived int) error { sender.lastBytesSent = bytesSent sender.lastBytesReceived = bytesReceived return nil } func Test_Factory(t *testing.T) { - statsSender := fakeStatsSender{} - middleware := NewMiddleware(statsSender.send, 1*time.Minute) + statsHandler := fakeStatsHandler{} + middleware := NewMiddleware(statsHandler.save, 1*time.Minute) assert.NotNil(t, middleware) } func Test_Start(t *testing.T) { - statsSender := fakeStatsSender{} - middleware := NewMiddleware(statsSender.send, 1*time.Minute) + statsHandler := fakeStatsHandler{} + middleware := NewMiddleware(statsHandler.save, 1*time.Minute) connection := &fakeConnection{} middleware.Start(connection) assert.Equal(t, []byte("bytecount 60\n"), connection.lastDataWritten) @@ -89,8 +89,8 @@ func Test_ConsumeLine(t *testing.T) { } for _, test := range tests { - statsSender := &fakeStatsSender{} - middleware := NewMiddleware(statsSender.send, 1*time.Minute) + statsHandler := &fakeStatsHandler{} + middleware := NewMiddleware(statsHandler.save, 1*time.Minute) consumed, err := middleware.ConsumeLine(test.line) if test.expectedError != nil { assert.Error(t, test.expectedError, err.Error(), test.line) @@ -98,7 +98,7 @@ func Test_ConsumeLine(t *testing.T) { assert.NoError(t, err, test.line) } assert.Equal(t, test.expectedConsumed, consumed, test.line) - assert.Equal(t, test.expectedBytesReceived, statsSender.lastBytesReceived) - assert.Equal(t, test.expectedBytesSent, statsSender.lastBytesSent) + assert.Equal(t, test.expectedBytesReceived, statsHandler.lastBytesReceived) + assert.Equal(t, test.expectedBytesSent, statsHandler.lastBytesSent) } } diff --git a/openvpn/middlewares/client/bytescount/stats_sender.go b/openvpn/middlewares/client/bytescount/stats_sender.go index deb7973a4..269eba5e3 100644 --- a/openvpn/middlewares/client/bytescount/stats_sender.go +++ b/openvpn/middlewares/client/bytescount/stats_sender.go @@ -9,7 +9,8 @@ import ( type SessionStatsSender func(bytesSent, bytesReceived int) error -func NewSessionStatsSender(mysteriumClient server.Client, sessionID session.SessionID, signer identity.Signer) SessionStatsSender { +// NewSessionStatsSender returns new session stats handler, which sends statistics to server +func NewSessionStatsSender(mysteriumClient server.Client, sessionID session.SessionID, signer identity.Signer) SessionStatsHandler { sessionIDString := string(sessionID) return func(bytesSent, bytesReceived int) error { return mysteriumClient.SendSessionStats( From c871f302343d8589aa96c0de7ee2882d17b114e4 Mon Sep 17 00:00:00 2001 From: Donatas Kucinskas Date: Fri, 26 Jan 2018 10:46:06 +0200 Subject: [PATCH 2/8] Add `SessionStats` dto in bytescount middleware --- openvpn/middlewares/client/bytescount/dto.go | 6 ++++++ openvpn/middlewares/client/bytescount/middleware.go | 5 +++-- .../middlewares/client/bytescount/middleware_test.go | 11 +++++------ openvpn/middlewares/client/bytescount/stats_sender.go | 6 +++--- 4 files changed, 17 insertions(+), 11 deletions(-) create mode 100644 openvpn/middlewares/client/bytescount/dto.go diff --git a/openvpn/middlewares/client/bytescount/dto.go b/openvpn/middlewares/client/bytescount/dto.go new file mode 100644 index 000000000..902e807f1 --- /dev/null +++ b/openvpn/middlewares/client/bytescount/dto.go @@ -0,0 +1,6 @@ +package bytescount + +// SessionStats represents statistics, generated by bytescount middleware +type SessionStats struct { + BytesSent, BytesReceived int +} diff --git a/openvpn/middlewares/client/bytescount/middleware.go b/openvpn/middlewares/client/bytescount/middleware.go index 7ef91fda8..8c28d5986 100644 --- a/openvpn/middlewares/client/bytescount/middleware.go +++ b/openvpn/middlewares/client/bytescount/middleware.go @@ -10,7 +10,7 @@ import ( ) // SessionStatsHandler is invoked when middleware receives statistics -type SessionStatsHandler func(bytesSent, bytesReceived int) error +type SessionStatsHandler func(SessionStats) error type middleware struct { sessionStatsHandler SessionStatsHandler @@ -66,7 +66,8 @@ func (middleware *middleware) ConsumeLine(line string) (consumed bool, err error return } - err = middleware.sessionStatsHandler(bytesOut, bytesIn) + stats := SessionStats{BytesSent: bytesOut, BytesReceived: bytesIn} + err = middleware.sessionStatsHandler(stats) return } diff --git a/openvpn/middlewares/client/bytescount/middleware_test.go b/openvpn/middlewares/client/bytescount/middleware_test.go index 9a330db4b..49d47c9d5 100644 --- a/openvpn/middlewares/client/bytescount/middleware_test.go +++ b/openvpn/middlewares/client/bytescount/middleware_test.go @@ -46,12 +46,11 @@ func (conn *fakeConnection) SetWriteDeadline(t time.Time) error { } type fakeStatsHandler struct { - lastBytesSent, lastBytesReceived int + lastSessionStats SessionStats } -func (sender *fakeStatsHandler) save(bytesSent, bytesReceived int) error { - sender.lastBytesSent = bytesSent - sender.lastBytesReceived = bytesReceived +func (sender *fakeStatsHandler) save(sessionStats SessionStats) error { + sender.lastSessionStats = sessionStats return nil } @@ -98,7 +97,7 @@ func Test_ConsumeLine(t *testing.T) { assert.NoError(t, err, test.line) } assert.Equal(t, test.expectedConsumed, consumed, test.line) - assert.Equal(t, test.expectedBytesReceived, statsHandler.lastBytesReceived) - assert.Equal(t, test.expectedBytesSent, statsHandler.lastBytesSent) + assert.Equal(t, test.expectedBytesReceived, statsHandler.lastSessionStats.BytesReceived) + assert.Equal(t, test.expectedBytesSent, statsHandler.lastSessionStats.BytesSent) } } diff --git a/openvpn/middlewares/client/bytescount/stats_sender.go b/openvpn/middlewares/client/bytescount/stats_sender.go index 269eba5e3..b1f09a530 100644 --- a/openvpn/middlewares/client/bytescount/stats_sender.go +++ b/openvpn/middlewares/client/bytescount/stats_sender.go @@ -12,12 +12,12 @@ type SessionStatsSender func(bytesSent, bytesReceived int) error // NewSessionStatsSender returns new session stats handler, which sends statistics to server func NewSessionStatsSender(mysteriumClient server.Client, sessionID session.SessionID, signer identity.Signer) SessionStatsHandler { sessionIDString := string(sessionID) - return func(bytesSent, bytesReceived int) error { + return func(sessionStats SessionStats) error { return mysteriumClient.SendSessionStats( sessionIDString, dto.SessionStats{ - BytesSent: bytesSent, - BytesReceived: bytesReceived, + BytesSent: sessionStats.BytesSent, + BytesReceived: sessionStats.BytesReceived, }, signer, ) From df9f999cebee626f5847cb890ff411030224e94e Mon Sep 17 00:00:00 2001 From: Donatas Kucinskas Date: Fri, 26 Jan 2018 11:05:40 +0200 Subject: [PATCH 3/8] Add SessionStatsStore, SessionStatsSaver --- .../client/bytescount/stats_saver.go | 9 +++++++ .../client/bytescount/stats_saver_test.go | 15 ++++++++++++ .../client/bytescount/stats_store.go | 24 +++++++++++++++++++ .../client/bytescount/stats_store_test.go | 14 +++++++++++ 4 files changed, 62 insertions(+) create mode 100644 openvpn/middlewares/client/bytescount/stats_saver.go create mode 100644 openvpn/middlewares/client/bytescount/stats_saver_test.go create mode 100644 openvpn/middlewares/client/bytescount/stats_store.go create mode 100644 openvpn/middlewares/client/bytescount/stats_store_test.go diff --git a/openvpn/middlewares/client/bytescount/stats_saver.go b/openvpn/middlewares/client/bytescount/stats_saver.go new file mode 100644 index 000000000..bad4db908 --- /dev/null +++ b/openvpn/middlewares/client/bytescount/stats_saver.go @@ -0,0 +1,9 @@ +package bytescount + +// NewSessionStatsSaver returns stats handler, which saves stats to global stats store +func NewSessionStatsSaver() SessionStatsHandler { + return func(sessionStats SessionStats) error { + GetSessionStatsStore().Set(sessionStats) + return nil + } +} diff --git a/openvpn/middlewares/client/bytescount/stats_saver_test.go b/openvpn/middlewares/client/bytescount/stats_saver_test.go new file mode 100644 index 000000000..606ee21fd --- /dev/null +++ b/openvpn/middlewares/client/bytescount/stats_saver_test.go @@ -0,0 +1,15 @@ +package bytescount + +import ( + "github.com/stretchr/testify/assert" + "testing" +) + +func TestNewSessionStatsSaver(t *testing.T) { + GetSessionStatsStore().Clear() + + saver := NewSessionStatsSaver() + stats := SessionStats{BytesSent: 1, BytesReceived: 2} + saver(stats) + assert.Equal(t, stats, GetSessionStatsStore().Get()) +} diff --git a/openvpn/middlewares/client/bytescount/stats_store.go b/openvpn/middlewares/client/bytescount/stats_store.go new file mode 100644 index 000000000..3c22c1d22 --- /dev/null +++ b/openvpn/middlewares/client/bytescount/stats_store.go @@ -0,0 +1,24 @@ +package bytescount + +type sessionStatsStore struct { + sessionStats SessionStats +} + +func (store *sessionStatsStore) Clear() { + store.sessionStats = SessionStats{} +} + +func (store *sessionStatsStore) Set(stats SessionStats) { + store.sessionStats = stats +} + +func (store *sessionStatsStore) Get() SessionStats { + return store.sessionStats +} + +var globalStatsStore sessionStatsStore + +// GetSessionStatsStore returns singleton store, which keeps session stats +func GetSessionStatsStore() *sessionStatsStore { + return &globalStatsStore +} diff --git a/openvpn/middlewares/client/bytescount/stats_store_test.go b/openvpn/middlewares/client/bytescount/stats_store_test.go new file mode 100644 index 000000000..93b315b0c --- /dev/null +++ b/openvpn/middlewares/client/bytescount/stats_store_test.go @@ -0,0 +1,14 @@ +package bytescount + +import ( + "github.com/stretchr/testify/assert" + "testing" +) + +func TestGetSessionStatsStoreReturnsSameInstance(t *testing.T) { + GetSessionStatsStore().Clear() + + stats := SessionStats{BytesSent: 1, BytesReceived: 2} + GetSessionStatsStore().Set(stats) + assert.Equal(t, stats, GetSessionStatsStore().Get()) +} From bb07a369e12d45e7ba3b5eacd62075865f01eb13 Mon Sep 17 00:00:00 2001 From: Donatas Kucinskas Date: Fri, 26 Jan 2018 11:55:30 +0200 Subject: [PATCH 4/8] Add CompositeStatsHandler, save stats to stats store --- client_connection/manager.go | 5 ++- .../bytescount/composite_stats_handler.go | 13 ++++++ .../composite_stats_handler_test.go | 40 +++++++++++++++++++ .../client/bytescount/fake_stats_handler.go | 10 +++++ .../client/bytescount/middleware_test.go | 13 +----- 5 files changed, 69 insertions(+), 12 deletions(-) create mode 100644 openvpn/middlewares/client/bytescount/composite_stats_handler.go create mode 100644 openvpn/middlewares/client/bytescount/composite_stats_handler_test.go create mode 100644 openvpn/middlewares/client/bytescount/fake_stats_handler.go diff --git a/client_connection/manager.go b/client_connection/manager.go index 9598416d0..11d79fa9f 100644 --- a/client_connection/manager.go +++ b/client_connection/manager.go @@ -133,10 +133,13 @@ func ConfigureVpnClientFactory(mysteriumAPIClient server.Client, vpnClientRuntim return nil, err } + statsSaver := bytescount.NewSessionStatsSaver() statsSender := bytescount.NewSessionStatsSender(mysteriumAPIClient, vpnSession.ID, signerFactory(id)) + statsHandler := bytescount.NewCompositeStatsHandler(statsSaver, statsSender) + authenticator := auth.NewAuthenticatorFake() vpnMiddlewares := []openvpn.ManagementMiddleware{ - bytescount.NewMiddleware(statsSender, 1*time.Minute), + bytescount.NewMiddleware(statsHandler, 1*time.Minute), auth.NewMiddleware(authenticator), } return openvpn.NewClient( diff --git a/openvpn/middlewares/client/bytescount/composite_stats_handler.go b/openvpn/middlewares/client/bytescount/composite_stats_handler.go new file mode 100644 index 000000000..fcbf1e71e --- /dev/null +++ b/openvpn/middlewares/client/bytescount/composite_stats_handler.go @@ -0,0 +1,13 @@ +package bytescount + +func NewCompositeStatsHandler(statsHandlers ...SessionStatsHandler) SessionStatsHandler { + return func(stats SessionStats) error { + for _, handler := range statsHandlers { + err := handler(stats) + if err != nil { + return err + } + } + return nil + } +} diff --git a/openvpn/middlewares/client/bytescount/composite_stats_handler_test.go b/openvpn/middlewares/client/bytescount/composite_stats_handler_test.go new file mode 100644 index 000000000..377362e4f --- /dev/null +++ b/openvpn/middlewares/client/bytescount/composite_stats_handler_test.go @@ -0,0 +1,40 @@ +package bytescount + +import ( + "errors" + "github.com/stretchr/testify/assert" + "testing" +) + +var stats = SessionStats{BytesSent: 1, BytesReceived: 1} + +func TestCompositeHandlerWithNoHandlers(t *testing.T) { + stats := SessionStats{BytesSent: 1, BytesReceived: 1} + + compositeHandler := NewCompositeStatsHandler() + assert.NoError(t, compositeHandler(stats)) +} + +func TestCompositeHandlerWithSuccessfulHandler(t *testing.T) { + fakeHandler := fakeStatsHandler{} + compositeHandler := NewCompositeStatsHandler(fakeHandler.save) + assert.NoError(t, compositeHandler(stats)) + assert.Equal(t, stats, fakeHandler.LastSessionStats) +} + +func TestCompositeHandlerWithFailingHandler(t *testing.T) { + failingHandler := func(stats SessionStats) error { return errors.New("fake error") } + compositeHandler := NewCompositeStatsHandler(failingHandler) + assert.Error(t, compositeHandler(stats), "fake error") +} + +func TestCompositeHandlerWithMultipleHandlers(t *testing.T) { + fakeHandler1 := fakeStatsHandler{} + fakeHandler2 := fakeStatsHandler{} + + compositeHandler := NewCompositeStatsHandler(fakeHandler1.save, fakeHandler2.save) + assert.NoError(t, compositeHandler(stats)) + + assert.Equal(t, stats, fakeHandler1.LastSessionStats) + assert.Equal(t, stats, fakeHandler2.LastSessionStats) +} diff --git a/openvpn/middlewares/client/bytescount/fake_stats_handler.go b/openvpn/middlewares/client/bytescount/fake_stats_handler.go new file mode 100644 index 000000000..e0f4240c7 --- /dev/null +++ b/openvpn/middlewares/client/bytescount/fake_stats_handler.go @@ -0,0 +1,10 @@ +package bytescount + +type fakeStatsHandler struct { + LastSessionStats SessionStats +} + +func (sender *fakeStatsHandler) save(sessionStats SessionStats) error { + sender.LastSessionStats = sessionStats + return nil +} diff --git a/openvpn/middlewares/client/bytescount/middleware_test.go b/openvpn/middlewares/client/bytescount/middleware_test.go index 49d47c9d5..cfd1e9677 100644 --- a/openvpn/middlewares/client/bytescount/middleware_test.go +++ b/openvpn/middlewares/client/bytescount/middleware_test.go @@ -45,15 +45,6 @@ func (conn *fakeConnection) SetWriteDeadline(t time.Time) error { return nil } -type fakeStatsHandler struct { - lastSessionStats SessionStats -} - -func (sender *fakeStatsHandler) save(sessionStats SessionStats) error { - sender.lastSessionStats = sessionStats - return nil -} - func Test_Factory(t *testing.T) { statsHandler := fakeStatsHandler{} middleware := NewMiddleware(statsHandler.save, 1*time.Minute) @@ -97,7 +88,7 @@ func Test_ConsumeLine(t *testing.T) { assert.NoError(t, err, test.line) } assert.Equal(t, test.expectedConsumed, consumed, test.line) - assert.Equal(t, test.expectedBytesReceived, statsHandler.lastSessionStats.BytesReceived) - assert.Equal(t, test.expectedBytesSent, statsHandler.lastSessionStats.BytesSent) + assert.Equal(t, test.expectedBytesReceived, statsHandler.LastSessionStats.BytesReceived) + assert.Equal(t, test.expectedBytesSent, statsHandler.LastSessionStats.BytesSent) } } From 84b122f1b7cf277eee1b11ee5cad6b1ad6e823c2 Mon Sep 17 00:00:00 2001 From: Donatas Kucinskas Date: Fri, 26 Jan 2018 13:47:50 +0200 Subject: [PATCH 5/8] Add "GET /connection/statistics" endpoint --- tequilapi/endpoints/connection.go | 15 ++++++++++++++- tequilapi/endpoints/connection_test.go | 25 +++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/tequilapi/endpoints/connection.go b/tequilapi/endpoints/connection.go index 18079e7db..418eae13c 100644 --- a/tequilapi/endpoints/connection.go +++ b/tequilapi/endpoints/connection.go @@ -6,6 +6,7 @@ import ( "github.com/mysterium/node/client_connection" "github.com/mysterium/node/identity" "github.com/mysterium/node/ip" + "github.com/mysterium/node/openvpn/middlewares/client/bytescount" "github.com/mysterium/node/tequilapi/utils" "github.com/mysterium/node/tequilapi/validation" "net/http" @@ -81,13 +82,25 @@ func (ce *connectionEndpoint) GetIP(writer http.ResponseWriter, request *http.Re utils.WriteAsJSON(response, writer) } -// TODO: Uppercase IPResolver? +func (ce *connectionEndpoint) GetStatistics(writer http.ResponseWriter, request *http.Request, params httprouter.Params) { + stats := bytescount.GetSessionStatsStore().Get() + response := struct { + BytesSent int `json:"bytesSent"` + BytesReceived int `json:"bytesReceived"` + }{ + BytesSent: stats.BytesSent, + BytesReceived: stats.BytesReceived, + } + utils.WriteAsJSON(response, writer) +} + func AddRoutesForConnection(router *httprouter.Router, manager client_connection.Manager, ipResolver ip.Resolver) { connectionEndpoint := NewConnectionEndpoint(manager, ipResolver) router.GET("/connection", connectionEndpoint.Status) router.PUT("/connection", connectionEndpoint.Create) router.DELETE("/connection", connectionEndpoint.Kill) router.GET("/connection/ip", connectionEndpoint.GetIP) + router.GET("/connection/statistics", connectionEndpoint.GetStatistics) } func toConnectionRequest(req *http.Request) (*connectionRequest, error) { diff --git a/tequilapi/endpoints/connection_test.go b/tequilapi/endpoints/connection_test.go index 67ea74fbe..e36139f30 100644 --- a/tequilapi/endpoints/connection_test.go +++ b/tequilapi/endpoints/connection_test.go @@ -6,6 +6,7 @@ import ( "github.com/mysterium/node/client_connection" "github.com/mysterium/node/identity" "github.com/mysterium/node/ip" + "github.com/mysterium/node/openvpn/middlewares/client/bytescount" "github.com/stretchr/testify/assert" "net/http" "net/http/httptest" @@ -46,6 +47,7 @@ func TestAddRoutesForConnectionAddsRoutes(t *testing.T) { router := httprouter.New() fakeManager := fakeManager{} ipResolver := ip.NewFakeResolver("123.123.123.123") + bytescount.GetSessionStatsStore().Clear() AddRoutesForConnection(router, &fakeManager, ipResolver) @@ -72,6 +74,10 @@ func TestAddRoutesForConnectionAddsRoutes(t *testing.T) { http.MethodGet, "/connection/ip", "", http.StatusOK, `{"ip": "123.123.123.123"}`, }, + { + http.MethodGet, "/connection/statistics", "", + http.StatusOK, `{"bytesSent": 0, "bytesReceived": 0}`, + }, } for _, test := range tests { @@ -291,3 +297,22 @@ func TestGetIPEndpointReturnsErrorWhenIPDetectionFails(t *testing.T) { resp.Body.String(), ) } + +func TestGetStatisticsEndpointReturnsStatistics(t *testing.T) { + stats := bytescount.SessionStats{BytesSent: 1, BytesReceived: 2} + bytescount.GetSessionStatsStore().Set(stats) + + manager := fakeManager{} + connEndpoint := NewConnectionEndpoint(&manager, nil) + + resp := httptest.NewRecorder() + connEndpoint.GetStatistics(resp, nil, nil) + assert.JSONEq( + t, + `{ + "bytesSent": 1, + "bytesReceived": 2 + }`, + resp.Body.String(), + ) +} From 2c1beefe9807f882601bf8ab35ddb5ea93e7e0c4 Mon Sep 17 00:00:00 2001 From: Donatas Kucinskas Date: Fri, 26 Jan 2018 14:26:14 +0200 Subject: [PATCH 6/8] Refactor to pass around SessionStatsStore instead of keeping global state --- client_connection/manager.go | 5 ++-- cmd/mysterium_client/run/command.go | 7 +++-- .../bytescount/composite_stats_handler.go | 1 + .../client/bytescount/stats_saver.go | 4 +-- .../client/bytescount/stats_saver_test.go | 6 ++-- .../client/bytescount/stats_sender.go | 1 + .../client/bytescount/stats_store.go | 20 ++++--------- .../client/bytescount/stats_store_test.go | 10 +++---- tequilapi/endpoints/connection.go | 13 ++++++--- tequilapi/endpoints/connection_test.go | 29 ++++++++++--------- 10 files changed, 50 insertions(+), 46 deletions(-) diff --git a/client_connection/manager.go b/client_connection/manager.go index 11d79fa9f..11ea4fd1a 100644 --- a/client_connection/manager.go +++ b/client_connection/manager.go @@ -123,7 +123,8 @@ func statusDisconnecting() ConnectionStatus { return ConnectionStatus{Disconnecting, "", nil} } -func ConfigureVpnClientFactory(mysteriumAPIClient server.Client, vpnClientRuntimeDirectory string, signerFactory identity.SignerFactory) VpnClientFactory { +func ConfigureVpnClientFactory(mysteriumAPIClient server.Client, vpnClientRuntimeDirectory string, + signerFactory identity.SignerFactory, statsStore *bytescount.SessionStatsStore) VpnClientFactory { return func(vpnSession session.SessionDto, id identity.Identity) (openvpn.Client, error) { vpnConfig, err := openvpn.NewClientConfigFromString( vpnSession.Config, @@ -133,7 +134,7 @@ func ConfigureVpnClientFactory(mysteriumAPIClient server.Client, vpnClientRuntim return nil, err } - statsSaver := bytescount.NewSessionStatsSaver() + statsSaver := bytescount.NewSessionStatsSaver(statsStore) statsSender := bytescount.NewSessionStatsSender(mysteriumAPIClient, vpnSession.ID, signerFactory(id)) statsHandler := bytescount.NewCompositeStatsHandler(statsSaver, statsSender) diff --git a/cmd/mysterium_client/run/command.go b/cmd/mysterium_client/run/command.go index ada445c75..22a12b554 100644 --- a/cmd/mysterium_client/run/command.go +++ b/cmd/mysterium_client/run/command.go @@ -10,6 +10,7 @@ import ( "github.com/mysterium/node/identity" "github.com/mysterium/node/ip" "github.com/mysterium/node/openvpn" + "github.com/mysterium/node/openvpn/middlewares/client/bytescount" "github.com/mysterium/node/server" "github.com/mysterium/node/tequilapi" tequilapi_endpoints "github.com/mysterium/node/tequilapi/endpoints" @@ -43,14 +44,16 @@ func NewCommandWith( return identity.NewSigner(keystoreInstance, id) } - vpnClientFactory := client_connection.ConfigureVpnClientFactory(mysteriumClient, options.DirectoryRuntime, signerFactory) + statsStore := &bytescount.SessionStatsStore{} + + vpnClientFactory := client_connection.ConfigureVpnClientFactory(mysteriumClient, options.DirectoryRuntime, signerFactory, statsStore) connectionManager := client_connection.NewManager(mysteriumClient, dialogEstablisherFactory, vpnClientFactory) router := tequilapi.NewAPIRouter() tequilapi_endpoints.AddRoutesForIdentities(router, identityManager, mysteriumClient, signerFactory) ipResolver := ip.NewResolver() - tequilapi_endpoints.AddRoutesForConnection(router, connectionManager, ipResolver) + tequilapi_endpoints.AddRoutesForConnection(router, connectionManager, ipResolver, statsStore) tequilapi_endpoints.AddRoutesForProposals(router, mysteriumClient) httpAPIServer := tequilapi.NewServer(options.TequilapiAddress, options.TequilapiPort, router) diff --git a/openvpn/middlewares/client/bytescount/composite_stats_handler.go b/openvpn/middlewares/client/bytescount/composite_stats_handler.go index fcbf1e71e..f52038938 100644 --- a/openvpn/middlewares/client/bytescount/composite_stats_handler.go +++ b/openvpn/middlewares/client/bytescount/composite_stats_handler.go @@ -1,5 +1,6 @@ package bytescount +// NewCompositeStatsHandler composes multiple stats handlers into single one, which executes all handlers sequentially func NewCompositeStatsHandler(statsHandlers ...SessionStatsHandler) SessionStatsHandler { return func(stats SessionStats) error { for _, handler := range statsHandlers { diff --git a/openvpn/middlewares/client/bytescount/stats_saver.go b/openvpn/middlewares/client/bytescount/stats_saver.go index bad4db908..ee2be564c 100644 --- a/openvpn/middlewares/client/bytescount/stats_saver.go +++ b/openvpn/middlewares/client/bytescount/stats_saver.go @@ -1,9 +1,9 @@ package bytescount // NewSessionStatsSaver returns stats handler, which saves stats to global stats store -func NewSessionStatsSaver() SessionStatsHandler { +func NewSessionStatsSaver(statsStore *SessionStatsStore) SessionStatsHandler { return func(sessionStats SessionStats) error { - GetSessionStatsStore().Set(sessionStats) + statsStore.Save(sessionStats) return nil } } diff --git a/openvpn/middlewares/client/bytescount/stats_saver_test.go b/openvpn/middlewares/client/bytescount/stats_saver_test.go index 606ee21fd..ba21c1166 100644 --- a/openvpn/middlewares/client/bytescount/stats_saver_test.go +++ b/openvpn/middlewares/client/bytescount/stats_saver_test.go @@ -6,10 +6,10 @@ import ( ) func TestNewSessionStatsSaver(t *testing.T) { - GetSessionStatsStore().Clear() + statsStore := &SessionStatsStore{} - saver := NewSessionStatsSaver() + saver := NewSessionStatsSaver(statsStore) stats := SessionStats{BytesSent: 1, BytesReceived: 2} saver(stats) - assert.Equal(t, stats, GetSessionStatsStore().Get()) + assert.Equal(t, stats, statsStore.Retrieve()) } diff --git a/openvpn/middlewares/client/bytescount/stats_sender.go b/openvpn/middlewares/client/bytescount/stats_sender.go index b1f09a530..d034a959e 100644 --- a/openvpn/middlewares/client/bytescount/stats_sender.go +++ b/openvpn/middlewares/client/bytescount/stats_sender.go @@ -7,6 +7,7 @@ import ( "github.com/mysterium/node/session" ) +// SessionStatsSender sends statistics to server type SessionStatsSender func(bytesSent, bytesReceived int) error // NewSessionStatsSender returns new session stats handler, which sends statistics to server diff --git a/openvpn/middlewares/client/bytescount/stats_store.go b/openvpn/middlewares/client/bytescount/stats_store.go index 3c22c1d22..87ea3a9f7 100644 --- a/openvpn/middlewares/client/bytescount/stats_store.go +++ b/openvpn/middlewares/client/bytescount/stats_store.go @@ -1,24 +1,16 @@ package bytescount -type sessionStatsStore struct { +// SessionStatsStore keeps session stats +type SessionStatsStore struct { sessionStats SessionStats } -func (store *sessionStatsStore) Clear() { - store.sessionStats = SessionStats{} -} - -func (store *sessionStatsStore) Set(stats SessionStats) { +// Save saves session stats to store +func (store *SessionStatsStore) Save(stats SessionStats) { store.sessionStats = stats } -func (store *sessionStatsStore) Get() SessionStats { +// Retrieve retrieves session stats from store +func (store *SessionStatsStore) Retrieve() SessionStats { return store.sessionStats } - -var globalStatsStore sessionStatsStore - -// GetSessionStatsStore returns singleton store, which keeps session stats -func GetSessionStatsStore() *sessionStatsStore { - return &globalStatsStore -} diff --git a/openvpn/middlewares/client/bytescount/stats_store_test.go b/openvpn/middlewares/client/bytescount/stats_store_test.go index 93b315b0c..0bac13c74 100644 --- a/openvpn/middlewares/client/bytescount/stats_store_test.go +++ b/openvpn/middlewares/client/bytescount/stats_store_test.go @@ -5,10 +5,10 @@ import ( "testing" ) -func TestGetSessionStatsStoreReturnsSameInstance(t *testing.T) { - GetSessionStatsStore().Clear() - +func TestSessionStatsStoreWorks(t *testing.T) { + statsStore := &SessionStatsStore{} stats := SessionStats{BytesSent: 1, BytesReceived: 2} - GetSessionStatsStore().Set(stats) - assert.Equal(t, stats, GetSessionStatsStore().Get()) + + statsStore.Save(stats) + assert.Equal(t, stats, statsStore.Retrieve()) } diff --git a/tequilapi/endpoints/connection.go b/tequilapi/endpoints/connection.go index 418eae13c..3a6377da5 100644 --- a/tequilapi/endpoints/connection.go +++ b/tequilapi/endpoints/connection.go @@ -25,12 +25,14 @@ type statusResponse struct { type connectionEndpoint struct { manager client_connection.Manager ipResolver ip.Resolver + statsStore *bytescount.SessionStatsStore } -func NewConnectionEndpoint(manager client_connection.Manager, ipResolver ip.Resolver) *connectionEndpoint { +func NewConnectionEndpoint(manager client_connection.Manager, ipResolver ip.Resolver, statsStore *bytescount.SessionStatsStore) *connectionEndpoint { return &connectionEndpoint{ manager: manager, ipResolver: ipResolver, + statsStore: statsStore, } } @@ -82,8 +84,9 @@ func (ce *connectionEndpoint) GetIP(writer http.ResponseWriter, request *http.Re utils.WriteAsJSON(response, writer) } +// GetStatistics returns statistics about current connection func (ce *connectionEndpoint) GetStatistics(writer http.ResponseWriter, request *http.Request, params httprouter.Params) { - stats := bytescount.GetSessionStatsStore().Get() + stats := ce.statsStore.Retrieve() response := struct { BytesSent int `json:"bytesSent"` BytesReceived int `json:"bytesReceived"` @@ -94,8 +97,10 @@ func (ce *connectionEndpoint) GetStatistics(writer http.ResponseWriter, request utils.WriteAsJSON(response, writer) } -func AddRoutesForConnection(router *httprouter.Router, manager client_connection.Manager, ipResolver ip.Resolver) { - connectionEndpoint := NewConnectionEndpoint(manager, ipResolver) +// AddRoutesForConnection adds connections routes to given router +func AddRoutesForConnection(router *httprouter.Router, manager client_connection.Manager, ipResolver ip.Resolver, + statsStore *bytescount.SessionStatsStore) { + connectionEndpoint := NewConnectionEndpoint(manager, ipResolver, statsStore) router.GET("/connection", connectionEndpoint.Status) router.PUT("/connection", connectionEndpoint.Create) router.DELETE("/connection", connectionEndpoint.Kill) diff --git a/tequilapi/endpoints/connection_test.go b/tequilapi/endpoints/connection_test.go index e36139f30..ef70f1f97 100644 --- a/tequilapi/endpoints/connection_test.go +++ b/tequilapi/endpoints/connection_test.go @@ -47,9 +47,9 @@ func TestAddRoutesForConnectionAddsRoutes(t *testing.T) { router := httprouter.New() fakeManager := fakeManager{} ipResolver := ip.NewFakeResolver("123.123.123.123") - bytescount.GetSessionStatsStore().Clear() + statsStore := &bytescount.SessionStatsStore{} - AddRoutesForConnection(router, &fakeManager, ipResolver) + AddRoutesForConnection(router, &fakeManager, ipResolver, statsStore) tests := []struct { method string @@ -100,7 +100,7 @@ func TestDisconnectingState(t *testing.T) { SessionID: "", } - connEndpoint := NewConnectionEndpoint(&fakeManager, nil) + connEndpoint := NewConnectionEndpoint(&fakeManager, nil, nil) req := httptest.NewRequest(http.MethodGet, "/irrelevant", nil) resp := httptest.NewRecorder() @@ -122,7 +122,7 @@ func TestNotConnectedStateIsReturnedWhenNoConnection(t *testing.T) { SessionID: "", } - connEndpoint := NewConnectionEndpoint(&fakeManager, nil) + connEndpoint := NewConnectionEndpoint(&fakeManager, nil, nil) req := httptest.NewRequest(http.MethodGet, "/irrelevant", nil) resp := httptest.NewRecorder() @@ -144,7 +144,7 @@ func TestStateConnectingIsReturnedWhenIsConnectionInProgress(t *testing.T) { State: client_connection.Connecting, } - connEndpoint := NewConnectionEndpoint(&fakeManager, nil) + connEndpoint := NewConnectionEndpoint(&fakeManager, nil, nil) req := httptest.NewRequest(http.MethodGet, "/irrelevant", nil) resp := httptest.NewRecorder() @@ -167,7 +167,7 @@ func TestConnectedStateAndSessionIdIsReturnedWhenIsConnected(t *testing.T) { SessionID: "My-super-session", } - connEndpoint := NewConnectionEndpoint(&fakeManager, nil) + connEndpoint := NewConnectionEndpoint(&fakeManager, nil, nil) req := httptest.NewRequest(http.MethodGet, "/irrelevant", nil) resp := httptest.NewRecorder() @@ -187,7 +187,7 @@ func TestConnectedStateAndSessionIdIsReturnedWhenIsConnected(t *testing.T) { func TestPutReturns400ErrorIfRequestBodyIsNotJson(t *testing.T) { fakeManager := fakeManager{} - connEndpoint := NewConnectionEndpoint(&fakeManager, nil) + connEndpoint := NewConnectionEndpoint(&fakeManager, nil, nil) req := httptest.NewRequest(http.MethodPut, "/irrelevant", strings.NewReader("a")) resp := httptest.NewRecorder() @@ -206,7 +206,7 @@ func TestPutReturns400ErrorIfRequestBodyIsNotJson(t *testing.T) { func TestPutReturns422ErrorIfRequestBodyIsMissingFieldValues(t *testing.T) { fakeManager := fakeManager{} - connEndpoint := NewConnectionEndpoint(&fakeManager, nil) + connEndpoint := NewConnectionEndpoint(&fakeManager, nil, nil) req := httptest.NewRequest(http.MethodPut, "/irrelevant", strings.NewReader("{}")) resp := httptest.NewRecorder() @@ -228,7 +228,7 @@ func TestPutReturns422ErrorIfRequestBodyIsMissingFieldValues(t *testing.T) { func TestPutWithValidBodyCreatesConnection(t *testing.T) { fakeManager := fakeManager{} - connEndpoint := NewConnectionEndpoint(&fakeManager, nil) + connEndpoint := NewConnectionEndpoint(&fakeManager, nil, nil) req := httptest.NewRequest( http.MethodPut, "/irrelevant", @@ -251,7 +251,7 @@ func TestPutWithValidBodyCreatesConnection(t *testing.T) { func TestDeleteCallsDisconnect(t *testing.T) { fakeManager := fakeManager{} - connEndpoint := NewConnectionEndpoint(&fakeManager, nil) + connEndpoint := NewConnectionEndpoint(&fakeManager, nil, nil) req := httptest.NewRequest(http.MethodDelete, "/irrelevant", nil) resp := httptest.NewRecorder() @@ -265,7 +265,7 @@ func TestDeleteCallsDisconnect(t *testing.T) { func TestGetIPEndpointSucceeds(t *testing.T) { manager := fakeManager{} ipResolver := ip.NewFakeResolver("123.123.123.123") - connEndpoint := NewConnectionEndpoint(&manager, ipResolver) + connEndpoint := NewConnectionEndpoint(&manager, ipResolver, nil) resp := httptest.NewRecorder() connEndpoint.GetIP(resp, nil, nil) @@ -283,7 +283,7 @@ func TestGetIPEndpointSucceeds(t *testing.T) { func TestGetIPEndpointReturnsErrorWhenIPDetectionFails(t *testing.T) { manager := fakeManager{} ipResolver := ip.NewFailingFakeResolver(errors.New("fake error")) - connEndpoint := NewConnectionEndpoint(&manager, ipResolver) + connEndpoint := NewConnectionEndpoint(&manager, ipResolver, nil) resp := httptest.NewRecorder() connEndpoint.GetIP(resp, nil, nil) @@ -299,11 +299,12 @@ func TestGetIPEndpointReturnsErrorWhenIPDetectionFails(t *testing.T) { } func TestGetStatisticsEndpointReturnsStatistics(t *testing.T) { + statsStore := &bytescount.SessionStatsStore{} stats := bytescount.SessionStats{BytesSent: 1, BytesReceived: 2} - bytescount.GetSessionStatsStore().Set(stats) + statsStore.Save(stats) manager := fakeManager{} - connEndpoint := NewConnectionEndpoint(&manager, nil) + connEndpoint := NewConnectionEndpoint(&manager, nil, statsStore) resp := httptest.NewRecorder() connEndpoint.GetStatistics(resp, nil, nil) From b3486a200e90f7dedcd6969577609f33fb5eb654 Mon Sep 17 00:00:00 2001 From: Donatas Kucinskas Date: Fri, 26 Jan 2018 15:07:02 +0200 Subject: [PATCH 7/8] Refactor 'fakeStatsHandler' to 'fakeStatsRecorder' to clarify usage --- .../bytescount/composite_stats_handler_test.go | 16 ++++++++-------- .../client/bytescount/fake_stats_handler.go | 4 ++-- .../client/bytescount/middleware_test.go | 16 ++++++++-------- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/openvpn/middlewares/client/bytescount/composite_stats_handler_test.go b/openvpn/middlewares/client/bytescount/composite_stats_handler_test.go index 377362e4f..8074d9126 100644 --- a/openvpn/middlewares/client/bytescount/composite_stats_handler_test.go +++ b/openvpn/middlewares/client/bytescount/composite_stats_handler_test.go @@ -16,10 +16,10 @@ func TestCompositeHandlerWithNoHandlers(t *testing.T) { } func TestCompositeHandlerWithSuccessfulHandler(t *testing.T) { - fakeHandler := fakeStatsHandler{} - compositeHandler := NewCompositeStatsHandler(fakeHandler.save) + statsRecorder := fakeStatsRecorder{} + compositeHandler := NewCompositeStatsHandler(statsRecorder.record) assert.NoError(t, compositeHandler(stats)) - assert.Equal(t, stats, fakeHandler.LastSessionStats) + assert.Equal(t, stats, statsRecorder.LastSessionStats) } func TestCompositeHandlerWithFailingHandler(t *testing.T) { @@ -29,12 +29,12 @@ func TestCompositeHandlerWithFailingHandler(t *testing.T) { } func TestCompositeHandlerWithMultipleHandlers(t *testing.T) { - fakeHandler1 := fakeStatsHandler{} - fakeHandler2 := fakeStatsHandler{} + recorder1 := fakeStatsRecorder{} + recorder2 := fakeStatsRecorder{} - compositeHandler := NewCompositeStatsHandler(fakeHandler1.save, fakeHandler2.save) + compositeHandler := NewCompositeStatsHandler(recorder1.record, recorder2.record) assert.NoError(t, compositeHandler(stats)) - assert.Equal(t, stats, fakeHandler1.LastSessionStats) - assert.Equal(t, stats, fakeHandler2.LastSessionStats) + assert.Equal(t, stats, recorder1.LastSessionStats) + assert.Equal(t, stats, recorder2.LastSessionStats) } diff --git a/openvpn/middlewares/client/bytescount/fake_stats_handler.go b/openvpn/middlewares/client/bytescount/fake_stats_handler.go index e0f4240c7..c7eeb9b17 100644 --- a/openvpn/middlewares/client/bytescount/fake_stats_handler.go +++ b/openvpn/middlewares/client/bytescount/fake_stats_handler.go @@ -1,10 +1,10 @@ package bytescount -type fakeStatsHandler struct { +type fakeStatsRecorder struct { LastSessionStats SessionStats } -func (sender *fakeStatsHandler) save(sessionStats SessionStats) error { +func (sender *fakeStatsRecorder) record(sessionStats SessionStats) error { sender.LastSessionStats = sessionStats return nil } diff --git a/openvpn/middlewares/client/bytescount/middleware_test.go b/openvpn/middlewares/client/bytescount/middleware_test.go index cfd1e9677..58e7936be 100644 --- a/openvpn/middlewares/client/bytescount/middleware_test.go +++ b/openvpn/middlewares/client/bytescount/middleware_test.go @@ -46,14 +46,14 @@ func (conn *fakeConnection) SetWriteDeadline(t time.Time) error { } func Test_Factory(t *testing.T) { - statsHandler := fakeStatsHandler{} - middleware := NewMiddleware(statsHandler.save, 1*time.Minute) + statsRecorder := fakeStatsRecorder{} + middleware := NewMiddleware(statsRecorder.record, 1*time.Minute) assert.NotNil(t, middleware) } func Test_Start(t *testing.T) { - statsHandler := fakeStatsHandler{} - middleware := NewMiddleware(statsHandler.save, 1*time.Minute) + statsRecorder := fakeStatsRecorder{} + middleware := NewMiddleware(statsRecorder.record, 1*time.Minute) connection := &fakeConnection{} middleware.Start(connection) assert.Equal(t, []byte("bytecount 60\n"), connection.lastDataWritten) @@ -79,8 +79,8 @@ func Test_ConsumeLine(t *testing.T) { } for _, test := range tests { - statsHandler := &fakeStatsHandler{} - middleware := NewMiddleware(statsHandler.save, 1*time.Minute) + statsRecorder := &fakeStatsRecorder{} + middleware := NewMiddleware(statsRecorder.record, 1*time.Minute) consumed, err := middleware.ConsumeLine(test.line) if test.expectedError != nil { assert.Error(t, test.expectedError, err.Error(), test.line) @@ -88,7 +88,7 @@ func Test_ConsumeLine(t *testing.T) { assert.NoError(t, err, test.line) } assert.Equal(t, test.expectedConsumed, consumed, test.line) - assert.Equal(t, test.expectedBytesReceived, statsHandler.LastSessionStats.BytesReceived) - assert.Equal(t, test.expectedBytesSent, statsHandler.LastSessionStats.BytesSent) + assert.Equal(t, test.expectedBytesReceived, statsRecorder.LastSessionStats.BytesReceived) + assert.Equal(t, test.expectedBytesSent, statsRecorder.LastSessionStats.BytesSent) } } From d5f3270f06731e0c8cd6db332dd334f697e243bc Mon Sep 17 00:00:00 2001 From: Donatas Kucinskas Date: Fri, 26 Jan 2018 15:27:13 +0200 Subject: [PATCH 8/8] Rename SessionStatsStore to SessionStatsKeeper --- client_connection/manager.go | 4 ++-- cmd/mysterium_client/run/command.go | 6 +++--- .../client/bytescount/stats_keeper.go | 16 +++++++++++++++ ...ats_store_test.go => stats_keeper_test.go} | 6 +++--- .../client/bytescount/stats_saver.go | 6 +++--- .../client/bytescount/stats_saver_test.go | 6 +++--- .../client/bytescount/stats_store.go | 16 --------------- tequilapi/endpoints/connection.go | 20 +++++++++---------- tequilapi/endpoints/connection_test.go | 10 +++++----- 9 files changed, 45 insertions(+), 45 deletions(-) create mode 100644 openvpn/middlewares/client/bytescount/stats_keeper.go rename openvpn/middlewares/client/bytescount/{stats_store_test.go => stats_keeper_test.go} (62%) delete mode 100644 openvpn/middlewares/client/bytescount/stats_store.go diff --git a/client_connection/manager.go b/client_connection/manager.go index 11ea4fd1a..63a3c51cd 100644 --- a/client_connection/manager.go +++ b/client_connection/manager.go @@ -124,7 +124,7 @@ func statusDisconnecting() ConnectionStatus { } func ConfigureVpnClientFactory(mysteriumAPIClient server.Client, vpnClientRuntimeDirectory string, - signerFactory identity.SignerFactory, statsStore *bytescount.SessionStatsStore) VpnClientFactory { + signerFactory identity.SignerFactory, statsKeeper *bytescount.SessionStatsKeeper) VpnClientFactory { return func(vpnSession session.SessionDto, id identity.Identity) (openvpn.Client, error) { vpnConfig, err := openvpn.NewClientConfigFromString( vpnSession.Config, @@ -134,7 +134,7 @@ func ConfigureVpnClientFactory(mysteriumAPIClient server.Client, vpnClientRuntim return nil, err } - statsSaver := bytescount.NewSessionStatsSaver(statsStore) + statsSaver := bytescount.NewSessionStatsSaver(statsKeeper) statsSender := bytescount.NewSessionStatsSender(mysteriumAPIClient, vpnSession.ID, signerFactory(id)) statsHandler := bytescount.NewCompositeStatsHandler(statsSaver, statsSender) diff --git a/cmd/mysterium_client/run/command.go b/cmd/mysterium_client/run/command.go index 22a12b554..0f00187eb 100644 --- a/cmd/mysterium_client/run/command.go +++ b/cmd/mysterium_client/run/command.go @@ -44,16 +44,16 @@ func NewCommandWith( return identity.NewSigner(keystoreInstance, id) } - statsStore := &bytescount.SessionStatsStore{} + statsKeeper := &bytescount.SessionStatsKeeper{} - vpnClientFactory := client_connection.ConfigureVpnClientFactory(mysteriumClient, options.DirectoryRuntime, signerFactory, statsStore) + vpnClientFactory := client_connection.ConfigureVpnClientFactory(mysteriumClient, options.DirectoryRuntime, signerFactory, statsKeeper) connectionManager := client_connection.NewManager(mysteriumClient, dialogEstablisherFactory, vpnClientFactory) router := tequilapi.NewAPIRouter() tequilapi_endpoints.AddRoutesForIdentities(router, identityManager, mysteriumClient, signerFactory) ipResolver := ip.NewResolver() - tequilapi_endpoints.AddRoutesForConnection(router, connectionManager, ipResolver, statsStore) + tequilapi_endpoints.AddRoutesForConnection(router, connectionManager, ipResolver, statsKeeper) tequilapi_endpoints.AddRoutesForProposals(router, mysteriumClient) httpAPIServer := tequilapi.NewServer(options.TequilapiAddress, options.TequilapiPort, router) diff --git a/openvpn/middlewares/client/bytescount/stats_keeper.go b/openvpn/middlewares/client/bytescount/stats_keeper.go new file mode 100644 index 000000000..ccd363ed9 --- /dev/null +++ b/openvpn/middlewares/client/bytescount/stats_keeper.go @@ -0,0 +1,16 @@ +package bytescount + +// SessionStatsKeeper keeps session stats +type SessionStatsKeeper struct { + sessionStats SessionStats +} + +// Save saves session stats to keeper +func (keeper *SessionStatsKeeper) Save(stats SessionStats) { + keeper.sessionStats = stats +} + +// Retrieve retrieves session stats from keeper +func (keeper *SessionStatsKeeper) Retrieve() SessionStats { + return keeper.sessionStats +} diff --git a/openvpn/middlewares/client/bytescount/stats_store_test.go b/openvpn/middlewares/client/bytescount/stats_keeper_test.go similarity index 62% rename from openvpn/middlewares/client/bytescount/stats_store_test.go rename to openvpn/middlewares/client/bytescount/stats_keeper_test.go index 0bac13c74..1a5019292 100644 --- a/openvpn/middlewares/client/bytescount/stats_store_test.go +++ b/openvpn/middlewares/client/bytescount/stats_keeper_test.go @@ -6,9 +6,9 @@ import ( ) func TestSessionStatsStoreWorks(t *testing.T) { - statsStore := &SessionStatsStore{} + statsKeeper := &SessionStatsKeeper{} stats := SessionStats{BytesSent: 1, BytesReceived: 2} - statsStore.Save(stats) - assert.Equal(t, stats, statsStore.Retrieve()) + statsKeeper.Save(stats) + assert.Equal(t, stats, statsKeeper.Retrieve()) } diff --git a/openvpn/middlewares/client/bytescount/stats_saver.go b/openvpn/middlewares/client/bytescount/stats_saver.go index ee2be564c..37853a62a 100644 --- a/openvpn/middlewares/client/bytescount/stats_saver.go +++ b/openvpn/middlewares/client/bytescount/stats_saver.go @@ -1,9 +1,9 @@ package bytescount -// NewSessionStatsSaver returns stats handler, which saves stats to global stats store -func NewSessionStatsSaver(statsStore *SessionStatsStore) SessionStatsHandler { +// NewSessionStatsSaver returns stats handler, which saves stats stats keeper +func NewSessionStatsSaver(statsKeeper *SessionStatsKeeper) SessionStatsHandler { return func(sessionStats SessionStats) error { - statsStore.Save(sessionStats) + statsKeeper.Save(sessionStats) return nil } } diff --git a/openvpn/middlewares/client/bytescount/stats_saver_test.go b/openvpn/middlewares/client/bytescount/stats_saver_test.go index ba21c1166..6f5b1c06d 100644 --- a/openvpn/middlewares/client/bytescount/stats_saver_test.go +++ b/openvpn/middlewares/client/bytescount/stats_saver_test.go @@ -6,10 +6,10 @@ import ( ) func TestNewSessionStatsSaver(t *testing.T) { - statsStore := &SessionStatsStore{} + statsKeeper := &SessionStatsKeeper{} - saver := NewSessionStatsSaver(statsStore) + saver := NewSessionStatsSaver(statsKeeper) stats := SessionStats{BytesSent: 1, BytesReceived: 2} saver(stats) - assert.Equal(t, stats, statsStore.Retrieve()) + assert.Equal(t, stats, statsKeeper.Retrieve()) } diff --git a/openvpn/middlewares/client/bytescount/stats_store.go b/openvpn/middlewares/client/bytescount/stats_store.go deleted file mode 100644 index 87ea3a9f7..000000000 --- a/openvpn/middlewares/client/bytescount/stats_store.go +++ /dev/null @@ -1,16 +0,0 @@ -package bytescount - -// SessionStatsStore keeps session stats -type SessionStatsStore struct { - sessionStats SessionStats -} - -// Save saves session stats to store -func (store *SessionStatsStore) Save(stats SessionStats) { - store.sessionStats = stats -} - -// Retrieve retrieves session stats from store -func (store *SessionStatsStore) Retrieve() SessionStats { - return store.sessionStats -} diff --git a/tequilapi/endpoints/connection.go b/tequilapi/endpoints/connection.go index 3a6377da5..a66c9884b 100644 --- a/tequilapi/endpoints/connection.go +++ b/tequilapi/endpoints/connection.go @@ -23,16 +23,16 @@ type statusResponse struct { } type connectionEndpoint struct { - manager client_connection.Manager - ipResolver ip.Resolver - statsStore *bytescount.SessionStatsStore + manager client_connection.Manager + ipResolver ip.Resolver + statsKeeper *bytescount.SessionStatsKeeper } -func NewConnectionEndpoint(manager client_connection.Manager, ipResolver ip.Resolver, statsStore *bytescount.SessionStatsStore) *connectionEndpoint { +func NewConnectionEndpoint(manager client_connection.Manager, ipResolver ip.Resolver, statsKeeper *bytescount.SessionStatsKeeper) *connectionEndpoint { return &connectionEndpoint{ - manager: manager, - ipResolver: ipResolver, - statsStore: statsStore, + manager: manager, + ipResolver: ipResolver, + statsKeeper: statsKeeper, } } @@ -86,7 +86,7 @@ func (ce *connectionEndpoint) GetIP(writer http.ResponseWriter, request *http.Re // GetStatistics returns statistics about current connection func (ce *connectionEndpoint) GetStatistics(writer http.ResponseWriter, request *http.Request, params httprouter.Params) { - stats := ce.statsStore.Retrieve() + stats := ce.statsKeeper.Retrieve() response := struct { BytesSent int `json:"bytesSent"` BytesReceived int `json:"bytesReceived"` @@ -99,8 +99,8 @@ func (ce *connectionEndpoint) GetStatistics(writer http.ResponseWriter, request // AddRoutesForConnection adds connections routes to given router func AddRoutesForConnection(router *httprouter.Router, manager client_connection.Manager, ipResolver ip.Resolver, - statsStore *bytescount.SessionStatsStore) { - connectionEndpoint := NewConnectionEndpoint(manager, ipResolver, statsStore) + statsKeeper *bytescount.SessionStatsKeeper) { + connectionEndpoint := NewConnectionEndpoint(manager, ipResolver, statsKeeper) router.GET("/connection", connectionEndpoint.Status) router.PUT("/connection", connectionEndpoint.Create) router.DELETE("/connection", connectionEndpoint.Kill) diff --git a/tequilapi/endpoints/connection_test.go b/tequilapi/endpoints/connection_test.go index ef70f1f97..8d3965766 100644 --- a/tequilapi/endpoints/connection_test.go +++ b/tequilapi/endpoints/connection_test.go @@ -47,9 +47,9 @@ func TestAddRoutesForConnectionAddsRoutes(t *testing.T) { router := httprouter.New() fakeManager := fakeManager{} ipResolver := ip.NewFakeResolver("123.123.123.123") - statsStore := &bytescount.SessionStatsStore{} + statsKeeper := &bytescount.SessionStatsKeeper{} - AddRoutesForConnection(router, &fakeManager, ipResolver, statsStore) + AddRoutesForConnection(router, &fakeManager, ipResolver, statsKeeper) tests := []struct { method string @@ -299,12 +299,12 @@ func TestGetIPEndpointReturnsErrorWhenIPDetectionFails(t *testing.T) { } func TestGetStatisticsEndpointReturnsStatistics(t *testing.T) { - statsStore := &bytescount.SessionStatsStore{} + statsKeeper := &bytescount.SessionStatsKeeper{} stats := bytescount.SessionStats{BytesSent: 1, BytesReceived: 2} - statsStore.Save(stats) + statsKeeper.Save(stats) manager := fakeManager{} - connEndpoint := NewConnectionEndpoint(&manager, nil, statsStore) + connEndpoint := NewConnectionEndpoint(&manager, nil, statsKeeper) resp := httptest.NewRecorder() connEndpoint.GetStatistics(resp, nil, nil)