Skip to content
Snippets Groups Projects
Commit 25a8834b authored by Jake Taylor's avatar Jake Taylor
Browse files

re-add requestndf to client package

parent bce804ea
No related branches found
No related tags found
1 merge request!58Revert "Modify waiting lock"
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
package client package client
import ( import (
"crypto/sha256"
"github.com/golang/protobuf/ptypes" "github.com/golang/protobuf/ptypes"
"github.com/golang/protobuf/ptypes/any" "github.com/golang/protobuf/ptypes/any"
"github.com/pkg/errors" "github.com/pkg/errors"
...@@ -17,7 +18,11 @@ import ( ...@@ -17,7 +18,11 @@ import (
pb "gitlab.com/elixxir/comms/mixmessages" pb "gitlab.com/elixxir/comms/mixmessages"
"gitlab.com/xx_network/comms/connect" "gitlab.com/xx_network/comms/connect"
"gitlab.com/xx_network/comms/messages" "gitlab.com/xx_network/comms/messages"
"gitlab.com/xx_network/primitives/id"
"gitlab.com/xx_network/primitives/ndf"
"google.golang.org/grpc" "google.golang.org/grpc"
"strings"
"time"
) )
// Client -> Registration Send Function // Client -> Registration Send Function
...@@ -81,3 +86,95 @@ func (c *Comms) SendGetCurrentClientVersionMessage( ...@@ -81,3 +86,95 @@ func (c *Comms) SendGetCurrentClientVersionMessage(
result := &pb.ClientVersion{} result := &pb.ClientVersion{}
return result, ptypes.UnmarshalAny(resultMsg, result) return result, ptypes.UnmarshalAny(resultMsg, result)
} }
// RequestNdf is used to Request an ndf from permissioning
// Used by gateway, client, nodes and gateways
func (c *Comms) RequestNdf(host *connect.Host,
message *pb.NDFHash) (*pb.NDF, error) {
// Create the Send Function
f := func(conn *grpc.ClientConn) (*any.Any, error) {
// Set up the context
ctx, cancel := connect.MessagingContext()
defer cancel()
// Send the message
resultMsg, err := pb.NewRegistrationClient(
conn).PollNdf(ctx, message)
if err != nil {
return nil, errors.New(err.Error())
}
return ptypes.MarshalAny(resultMsg)
}
// Execute the Send function
jww.TRACE.Printf("Sending Request Ndf message: %+v", message)
resultMsg, err := c.Send(host, f)
if err != nil {
return nil, err
}
result := &pb.NDF{}
return result, ptypes.UnmarshalAny(resultMsg, result)
}
// RetrieveNdf, attempts to connect to the permissioning server to retrieve the latest ndf for the notifications bot
func (c *Comms) RetrieveNdf(currentDef *ndf.NetworkDefinition) (*ndf.NetworkDefinition, error) {
//Hash the notifications bot ndf for comparison with registration's ndf
var ndfHash []byte
// If the ndf passed not nil, serialize and hash it
if currentDef != nil {
//Hash the notifications bot ndf for comparison with registration's ndf
hash := sha256.New()
ndfBytes, err := currentDef.Marshal()
if err != nil {
return nil, err
}
hash.Write(ndfBytes)
ndfHash = hash.Sum(nil)
}
//Put the hash in a message
msg := &pb.NDFHash{Hash: ndfHash}
regHost, ok := c.Manager.GetHost(&id.Permissioning)
if !ok {
return nil, errors.New("Failed to find permissioning host")
}
//Send the hash to registration
response, err := c.RequestNdf(regHost, msg)
// Keep going until we get a grpc error or we get an ndf
for err != nil {
// If there is an unexpected error
if !strings.Contains(err.Error(), ndf.NO_NDF) {
// If it is not an issue with no ndf, return the error up the stack
errMsg := errors.Errorf("Failed to get ndf from permissioning: %v", err)
return nil, errMsg
}
// If the error is that the permissioning server is not ready, ask again
jww.WARN.Println("Failed to get an ndf, possibly not ready yet. Retying now...")
time.Sleep(250 * time.Millisecond)
response, err = c.RequestNdf(regHost, msg)
}
//If there was no error and the response is nil, client's ndf is up-to-date
if response == nil || response.Ndf == nil {
jww.DEBUG.Printf("Our NDF is up-to-date")
return nil, nil
}
jww.INFO.Printf("Remote NDF: %s", string(response.Ndf))
//Otherwise pull the ndf out of the response
updatedNdf, _, err := ndf.DecodeNDF(string(response.Ndf))
if err != nil {
//If there was an error decoding ndf
errMsg := errors.Errorf("Failed to decode response to ndf: %v", err)
return nil, errMsg
}
return updatedNdf, nil
}
...@@ -10,8 +10,10 @@ package client ...@@ -10,8 +10,10 @@ package client
import ( import (
pb "gitlab.com/elixxir/comms/mixmessages" pb "gitlab.com/elixxir/comms/mixmessages"
"gitlab.com/elixxir/comms/registration" "gitlab.com/elixxir/comms/registration"
"gitlab.com/elixxir/comms/testutils"
"gitlab.com/xx_network/comms/connect" "gitlab.com/xx_network/comms/connect"
"gitlab.com/xx_network/primitives/id" "gitlab.com/xx_network/primitives/id"
"gitlab.com/xx_network/primitives/ndf"
"testing" "testing"
) )
...@@ -70,3 +72,120 @@ func TestSendCheckClientVersionMessage(t *testing.T) { ...@@ -70,3 +72,120 @@ func TestSendCheckClientVersionMessage(t *testing.T) {
t.Errorf("CheckClientVersion: Error received: %s", err) t.Errorf("CheckClientVersion: Error received: %s", err)
} }
} }
//Smoke test RequestNdf
func TestSendGetUpdatedNDF(t *testing.T) {
GatewayAddress := getNextAddress()
testId := id.NewIdFromString("test", id.Generic, t)
clientId := id.NewIdFromString("client", id.Generic, t)
rg := registration.StartRegistrationServer(testId, GatewayAddress,
registration.NewImplementation(), nil, nil)
defer rg.Shutdown()
c, err := NewClientComms(clientId, nil, nil, nil)
if err != nil {
t.Errorf("Can't create client comms: %+v", err)
}
manager := connect.NewManagerTesting(t)
params := connect.GetDefaultHostParams()
params.AuthEnabled = false
host, err := manager.AddHost(testId, GatewayAddress, nil, params)
if err != nil {
t.Errorf("Unable to call NewHost: %+v", err)
}
_, err = c.RequestNdf(host, &pb.NDFHash{})
if err != nil {
t.Errorf("RequestNdf: Error received: %s", err)
}
}
// Test that Poll NDF handles all comms errors returned properly, and that it decodes and successfully returns an ndf
func TestProtoComms_PollNdf(t *testing.T) {
// Define a client object
clientId := id.NewIdFromString("client", id.Generic, t)
c, err := NewClientComms(clientId, nil, nil, nil)
if err != nil {
t.Errorf("Can't create client comms: %+v", err)
}
mockPermServer := registration.StartRegistrationServer(&id.Permissioning, RegistrationAddr, RegistrationHandler, nil, nil)
defer mockPermServer.Shutdown()
newNdf := &ndf.NetworkDefinition{}
// Test that poll ndf fails if getHost returns an error
GetHostErrBool = false
RequestNdfErr = nil
_, err = c.RetrieveNdf(newNdf)
if err == nil {
t.Errorf("GetHost should have failed but it didnt't: %+v", err)
t.Fail()
}
// Test that pollNdf returns an error in this case
// This enters an infinite loop is there a way to fix this test?
// Test that pollNdf Fails if it cant decode the request msg
RequestNdfErr = nil
GetHostErrBool = true
NdfToreturn.Ndf = []byte(ExampleBadNdfJSON)
_, err = c.RetrieveNdf(newNdf)
if err == nil {
t.Logf("RequestNdf should have failed to parse bad ndf: %+v", err)
t.Fail()
}
params := connect.GetDefaultHostParams()
params.AuthEnabled = false
_, err = c.ProtoComms.AddHost(&id.Permissioning, RegistrationAddr, nil, params)
if err != nil {
t.Errorf("Failed to add permissioning as a host: %+v", err)
}
// Test that pollNDf Is successful with expected result
RequestNdfErr = nil
GetHostErrBool = true
NdfToreturn.Ndf = []byte(testutils.ExampleJSON)
_, err = c.RetrieveNdf(newNdf)
//comms.mockManager.AddHost()
if err != nil {
t.Logf("Ndf failed to parse: %+v", err)
t.Fail()
}
}
// Happy path
func TestProtoComms_PollNdfRepeatedly(t *testing.T) {
// Define a client object
clientId := id.NewIdFromString("client", id.Generic, t)
c, err := NewClientComms(clientId, nil, nil, nil)
if err != nil {
t.Errorf("Can't create client comms: %+v", err)
}
// Start up the mock reg server
mockPermServer := registration.StartRegistrationServer(&id.Permissioning, RegistrationAddrErr, RegistrationError, nil, nil)
defer mockPermServer.Shutdown()
// Add the host to the comms object
params := connect.GetDefaultHostParams()
params.AuthEnabled = false
_, err = c.ProtoComms.AddHost(&id.Permissioning, RegistrationAddrErr, nil, params)
if err != nil {
t.Errorf("Failed to add permissioning as a host: %+v", err)
}
newNdf := &ndf.NetworkDefinition{}
// This should hit the loop until the number of retries is satisfied in the error handler
_, err = c.RetrieveNdf(newNdf)
if err != nil {
t.Errorf("Expected error case, should not return non-error until attempt #5")
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment