Commit b120c01b authored by Janoš Guljaš's avatar Janoš Guljaš Committed by GitHub

add debugapi /addresses endpoint to expose libp2p mutiaddresses (#44)

parent e67df738
...@@ -17,6 +17,7 @@ import ( ...@@ -17,6 +17,7 @@ import (
"github.com/ethersphere/bee/pkg/logging" "github.com/ethersphere/bee/pkg/logging"
"github.com/ethersphere/bee/pkg/p2p" "github.com/ethersphere/bee/pkg/p2p"
"github.com/ethersphere/bee/pkg/topology/mock" "github.com/ethersphere/bee/pkg/topology/mock"
"github.com/multiformats/go-multiaddr"
"resenje.org/web" "resenje.org/web"
) )
...@@ -61,3 +62,13 @@ func newTestServer(t *testing.T, o testServerOptions) *testServer { ...@@ -61,3 +62,13 @@ func newTestServer(t *testing.T, o testServerOptions) *testServer {
Cleanup: cleanup, Cleanup: cleanup,
} }
} }
func mustMultiaddr(t *testing.T, s string) multiaddr.Multiaddr {
t.Helper()
a, err := multiaddr.NewMultiaddr(s)
if err != nil {
t.Fatal(err)
}
return a
}
...@@ -8,4 +8,5 @@ type ( ...@@ -8,4 +8,5 @@ type (
StatusResponse = statusResponse StatusResponse = statusResponse
PeerConnectResponse = peerConnectResponse PeerConnectResponse = peerConnectResponse
PeersResponse = peersResponse PeersResponse = peersResponse
AddressesResponse = addressesResponse
) )
// Copyright 2020 The Swarm Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package debugapi
import (
"net/http"
"github.com/ethersphere/bee/pkg/jsonhttp"
"github.com/multiformats/go-multiaddr"
)
type addressesResponse struct {
Addresses []multiaddr.Multiaddr `json:"addresses"`
}
func (s *server) addressesHandler(w http.ResponseWriter, r *http.Request) {
addresses, err := s.P2P.Addresses()
if err != nil {
s.Logger.Debugf("debug api: p2p addresses: %v", err)
jsonhttp.InternalServerError(w, err)
return
}
jsonhttp.OK(w, addressesResponse{
Addresses: addresses,
})
}
// Copyright 2020 The Swarm Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package debugapi_test
import (
"errors"
"net/http"
"testing"
"github.com/ethersphere/bee/pkg/debugapi"
"github.com/ethersphere/bee/pkg/jsonhttp"
"github.com/ethersphere/bee/pkg/jsonhttp/jsonhttptest"
"github.com/ethersphere/bee/pkg/p2p/mock"
"github.com/multiformats/go-multiaddr"
)
func TestAddresses(t *testing.T) {
addresses := []multiaddr.Multiaddr{
mustMultiaddr(t, "/ip4/127.0.0.1/tcp/7071/p2p/16Uiu2HAmTBuJT9LvNmBiQiNoTsxE5mtNy6YG3paw79m94CRa9sRb"),
mustMultiaddr(t, "/ip4/192.168.0.101/tcp/7071/p2p/16Uiu2HAmTBuJT9LvNmBiQiNoTsxE5mtNy6YG3paw79m94CRa9sRb"),
mustMultiaddr(t, "/ip4/127.0.0.1/udp/7071/quic/p2p/16Uiu2HAmTBuJT9LvNmBiQiNoTsxE5mtNy6YG3paw79m94CRa9sRb"),
}
testServer := newTestServer(t, testServerOptions{
P2P: mock.New(mock.WithAddressesFunc(func() ([]multiaddr.Multiaddr, error) {
return addresses, nil
})),
})
defer testServer.Cleanup()
t.Run("ok", func(t *testing.T) {
jsonhttptest.ResponseDirect(t, testServer.Client, http.MethodGet, "/addresses", nil, http.StatusOK, debugapi.AddressesResponse{
Addresses: addresses,
})
})
t.Run("post method not allowed", func(t *testing.T) {
jsonhttptest.ResponseDirect(t, testServer.Client, http.MethodPost, "/addresses", nil, http.StatusMethodNotAllowed, jsonhttp.StatusResponse{
Code: http.StatusMethodNotAllowed,
Message: http.StatusText(http.StatusMethodNotAllowed),
})
})
}
func TestAddresses_error(t *testing.T) {
testErr := errors.New("test error")
testServer := newTestServer(t, testServerOptions{
P2P: mock.New(mock.WithAddressesFunc(func() ([]multiaddr.Multiaddr, error) {
return nil, testErr
})),
})
defer testServer.Cleanup()
jsonhttptest.ResponseDirect(t, testServer.Client, http.MethodGet, "/addresses", nil, http.StatusInternalServerError, jsonhttp.StatusResponse{
Code: http.StatusInternalServerError,
Message: testErr.Error(),
})
}
...@@ -40,6 +40,9 @@ func (s *server) setupRouting() { ...@@ -40,6 +40,9 @@ func (s *server) setupRouting() {
router.HandleFunc("/health", s.statusHandler) router.HandleFunc("/health", s.statusHandler)
router.HandleFunc("/readiness", s.statusHandler) router.HandleFunc("/readiness", s.statusHandler)
router.Handle("/addresses", jsonhttp.MethodHandler{
"GET": http.HandlerFunc(s.addressesHandler),
})
router.Handle("/connect/{multi-address:.+}", jsonhttp.MethodHandler{ router.Handle("/connect/{multi-address:.+}", jsonhttp.MethodHandler{
"POST": http.HandlerFunc(s.peerConnectHandler), "POST": http.HandlerFunc(s.peerConnectHandler),
}) })
......
...@@ -19,6 +19,7 @@ type Service struct { ...@@ -19,6 +19,7 @@ type Service struct {
disconnectFunc func(overlay swarm.Address) error disconnectFunc func(overlay swarm.Address) error
peersFunc func() []p2p.Peer peersFunc func() []p2p.Peer
setPeerAddedHandlerFunc func(func(context.Context, swarm.Address) error) setPeerAddedHandlerFunc func(func(context.Context, swarm.Address) error)
addressesFunc func() ([]ma.Multiaddr, error)
} }
func WithAddProtocolFunc(f func(p2p.ProtocolSpec) error) Option { func WithAddProtocolFunc(f func(p2p.ProtocolSpec) error) Option {
...@@ -51,6 +52,12 @@ func WithSetPeerAddedHandlerFunc(f func(func(context.Context, swarm.Address) err ...@@ -51,6 +52,12 @@ func WithSetPeerAddedHandlerFunc(f func(func(context.Context, swarm.Address) err
}) })
} }
func WithAddressesFunc(f func() ([]ma.Multiaddr, error)) Option {
return optionFunc(func(s *Service) {
s.addressesFunc = f
})
}
func New(opts ...Option) *Service { func New(opts ...Option) *Service {
s := new(Service) s := new(Service)
for _, o := range opts { for _, o := range opts {
...@@ -88,6 +95,13 @@ func (s *Service) SetPeerAddedHandler(f func(context.Context, swarm.Address) err ...@@ -88,6 +95,13 @@ func (s *Service) SetPeerAddedHandler(f func(context.Context, swarm.Address) err
s.setPeerAddedHandlerFunc(f) s.setPeerAddedHandlerFunc(f)
} }
func (s *Service) Addresses() ([]ma.Multiaddr, error) {
if s.addressesFunc == nil {
return nil, errors.New("function Addresses not configured")
}
return s.addressesFunc()
}
func (s *Service) Peers() []p2p.Peer { func (s *Service) Peers() []p2p.Peer {
if s.peersFunc == nil { if s.peersFunc == nil {
return nil return nil
......
...@@ -19,6 +19,7 @@ type Service interface { ...@@ -19,6 +19,7 @@ type Service interface {
Disconnect(overlay swarm.Address) error Disconnect(overlay swarm.Address) error
Peers() []Peer Peers() []Peer
SetPeerAddedHandler(func(context.Context, swarm.Address) error) SetPeerAddedHandler(func(context.Context, swarm.Address) error)
Addresses() ([]ma.Multiaddr, error)
} }
// Streamer is able to create a new Stream. // Streamer is able to create a new Stream.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment