Skip to content
Snippets Groups Projects
Commit 9963ba27 authored by Jono Wenger's avatar Jono Wenger Committed by Jonah Husson
Browse files

XX-3179 / Add notification data sending/receiving

parent 831ae6c8
No related branches found
No related tags found
No related merge requests found
......@@ -14,8 +14,8 @@ require (
github.com/spf13/jwalterweatherman v1.1.0
github.com/spf13/viper v1.7.0
gitlab.com/elixxir/comms v0.0.4-0.20210415184807-048b79d6a7b9
gitlab.com/elixxir/crypto v0.0.7-0.20210412231025-6f75c577f803
gitlab.com/elixxir/comms v0.0.4-0.20210416163032-7741665bdac1
gitlab.com/elixxir/crypto v0.0.7-0.20210413184512-e41c09223958
gitlab.com/xx_network/comms v0.0.4-0.20210409202820-eb3dca6571d3
gitlab.com/xx_network/crypto v0.0.5-0.20210405224157-2b1f387b42c1
gitlab.com/xx_network/primitives v0.0.4-0.20210409143523-eab7863f84bf
......
......@@ -375,10 +375,14 @@ gitlab.com/elixxir/comms v0.0.4-0.20210414204605-30cbeab25aaa h1:W2jV8mgiPdKnUAY
gitlab.com/elixxir/comms v0.0.4-0.20210414204605-30cbeab25aaa/go.mod h1:0XsJ63n7knUeSX9BDKQG7xGtX6w0l5WsfplSsMbP9iM=
gitlab.com/elixxir/comms v0.0.4-0.20210415184807-048b79d6a7b9 h1:mRmXopubJBQ/cBYipVLgj6jYH+5fMtA6WnXhAyaL0EI=
gitlab.com/elixxir/comms v0.0.4-0.20210415184807-048b79d6a7b9/go.mod h1:0XsJ63n7knUeSX9BDKQG7xGtX6w0l5WsfplSsMbP9iM=
gitlab.com/elixxir/comms v0.0.4-0.20210416163032-7741665bdac1 h1:txSEU+wNZFURV/7WmUJJFGCUOzQs/BStjPsHsw9lXp4=
gitlab.com/elixxir/comms v0.0.4-0.20210416163032-7741665bdac1/go.mod h1:ld2cWRyYD9jxAFRR1FYAZce7FV25YMIjKUdCJF7Of44=
gitlab.com/elixxir/crypto v0.0.0-20200804182833-984246dea2c4/go.mod h1:ucm9SFKJo+K0N2GwRRpaNr+tKXMIOVWzmyUD0SbOu2c=
gitlab.com/elixxir/crypto v0.0.3/go.mod h1:ZNgBOblhYToR4m8tj4cMvJ9UsJAUKq+p0gCp07WQmhA=
gitlab.com/elixxir/crypto v0.0.7-0.20210412231025-6f75c577f803 h1:8sLODlAYRT0Y9NA+uoMoF1qBrBRrW5TikyKAOvyCd+E=
gitlab.com/elixxir/crypto v0.0.7-0.20210412231025-6f75c577f803/go.mod h1:HMMRBuv/yMqB5c31G9OPlOAifOOqGypCyD5v6py+4vo=
gitlab.com/elixxir/crypto v0.0.7-0.20210413184512-e41c09223958 h1:tjEWlRieizWKnHFV1Q0nNegHT5QJJf9hECiM7nJSbik=
gitlab.com/elixxir/crypto v0.0.7-0.20210413184512-e41c09223958/go.mod h1:HMMRBuv/yMqB5c31G9OPlOAifOOqGypCyD5v6py+4vo=
gitlab.com/elixxir/primitives v0.0.0-20200731184040-494269b53b4d/go.mod h1:OQgUZq7SjnE0b+8+iIAT2eqQF+2IFHn73tOo+aV11mg=
gitlab.com/elixxir/primitives v0.0.0-20200804170709-a1896d262cd9/go.mod h1:p0VelQda72OzoUckr1O+vPW0AiFe0nyKQ6gYcmFSuF8=
gitlab.com/elixxir/primitives v0.0.0-20200804182913-788f47bded40/go.mod h1:tzdFFvb1ESmuTCOl1z6+yf6oAICDxH2NPUemVgoNLxc=
......
......@@ -32,6 +32,7 @@ import (
// Function type definitions for the main operations (poll and notify)
type PollFunc func(*Impl) ([][]byte, error)
type NotifyFunc func(*messaging.Client, []byte, *firebase.FirebaseComm, *storage.Storage) (string, error)
type NotifySendFunc func(*pb.NotificationData, *firebase.FirebaseComm, *storage.Storage) error
// Params struct holds info passed in for configuration
type Params struct {
......@@ -51,6 +52,7 @@ type Impl struct {
ndf *ndf.NetworkDefinition
pollFunc PollFunc
notifyFunc NotifyFunc
notifySendFunc NotifySendFunc
fcm *messaging.Client
gwId *id.ID
......@@ -61,7 +63,7 @@ type Impl struct {
type NotificationComms interface {
GetHost(hostId *id.ID) (*connect.Host, bool)
AddHost(hid *id.ID, address string, cert []byte, params connect.HostParams) (host *connect.Host, err error)
RequestNotifications(host *connect.Host) (*pb.UserIdList, error)
// RequestNotifications(host *connect.Host) (*pb.UserIdList, error)
RequestNdf(host *connect.Host, message *pb.NDFHash) (*pb.NDF, error)
}
......@@ -131,7 +133,7 @@ func StartNotifications(params Params, noTLS, noFirebase bool) (*Impl, error) {
}
// set up stored functions
impl.pollFunc = pollForNotifications
// impl.pollFunc = pollForNotifications
impl.notifyFunc = notifyUser
// Start notification comms server
......@@ -162,6 +164,10 @@ func NewImplementation(instance *Impl) *notificationBot.Implementation {
return instance.UnregisterForNotifications(request, auth)
}
impl.Functions.ReceiveNotificationBatch = func(data *pb.NotificationBatch, auth *connect.Auth) error {
return instance.ReceiveNotificationBatch(data, auth)
}
return impl
}
......@@ -194,21 +200,21 @@ func notifyUser(fcm *messaging.Client, uid []byte, fc *firebase.FirebaseComm, db
return resp, nil
}
// pollForNotifications accepts a gateway host and a RequestInterface (a comms object)
// It retrieves a list of user ids to be notified from the gateway
func pollForNotifications(nb *Impl) (uids [][]byte, e error) {
h, ok := nb.Comms.GetHost(nb.gwId)
if !ok {
return nil, errors.New("Could not find gateway host")
}
users, err := nb.Comms.RequestNotifications(h)
if err != nil {
return nil, errors.Wrap(err, "Failed to retrieve notifications from gateway")
}
return users.IDs, nil
}
// // pollForNotifications accepts a gateway host and a RequestInterface (a comms object)
// // It retrieves a list of user ids to be notified from the gateway
// func pollForNotifications(nb *Impl) (uids [][]byte, e error) {
// h, ok := nb.Comms.GetHost(nb.gwId)
// if !ok {
// return nil, errors.New("Could not find gateway host")
// }
//
// users, err := nb.Comms.RequestNotifications(h)
// if err != nil {
// return nil, errors.Wrap(err, "Failed to retrieve notifications from gateway")
// }
//
// return users.IDs, nil
// }
// RegisterForNotifications is called by the client, and adds a user registration to our database
func (nb *Impl) RegisterForNotifications(request *pb.NotificationRegisterRequest, auth *connect.Auth) error {
......@@ -292,3 +298,20 @@ func (nb *Impl) UpdateNdf(ndf *ndf.NetworkDefinition) error {
nb.ndf = ndf
return nil
}
// ReceiveNotificationBatch receives the batch of notification data from gateway.
func (nb *Impl) ReceiveNotificationBatch(notifBatch *pb.NotificationBatch, auth *connect.Auth) error {
if !auth.IsAuthenticated {
return errors.New("Cannot receive notification data: client is not authenticated")
}
fbComm := firebase.NewFirebaseComm()
for _, notifData := range notifBatch.GetNotifications() {
err := nb.notifySendFunc(notifData, fbComm, nb.Storage)
if err != nil {
return err
}
}
return nil
}
......@@ -21,6 +21,7 @@ import (
"gitlab.com/xx_network/primitives/ndf"
"gitlab.com/xx_network/primitives/utils"
"os"
"reflect"
"strings"
"testing"
"time"
......@@ -179,26 +180,26 @@ func (m mockPollErrComm) RetrieveNdf(currentDef *ndf.NetworkDefinition) (*ndf.Ne
return nil, nil
}
// Unit test for PollForNotifications
func TestPollForNotifications(t *testing.T) {
impl := &Impl{
Comms: mockPollComm{},
gwId: id.NewIdFromString("test", id.Gateway, t),
}
errImpl := &Impl{
Comms: mockPollErrComm{},
gwId: id.NewIdFromString("test", id.Gateway, t),
}
_, err := pollForNotifications(errImpl)
if err == nil {
t.Errorf("Failed to poll for notifications: %+v", err)
}
_, err = pollForNotifications(impl)
if err != nil {
t.Errorf("Failed to poll for notifications: %+v", err)
}
}
// // Unit test for PollForNotifications
// func TestPollForNotifications(t *testing.T) {
// impl := &Impl{
// Comms: mockPollComm{},
// gwId: id.NewIdFromString("test", id.Gateway, t),
// }
// errImpl := &Impl{
// Comms: mockPollErrComm{},
// gwId: id.NewIdFromString("test", id.Gateway, t),
// }
// _, err := pollForNotifications(errImpl)
// if err == nil {
// t.Errorf("Failed to poll for notifications: %+v", err)
// }
//
// _, err = pollForNotifications(impl)
// if err != nil {
// t.Errorf("Failed to poll for notifications: %+v", err)
// }
// }
// Unit test for RegisterForNotifications
func TestImpl_RegisterForNotifications(t *testing.T) {
......@@ -334,6 +335,46 @@ func TestImpl_UnregisterForNotifications(t *testing.T) {
}
}
// Happy path.
func TestImpl_ReceiveNotificationBatch(t *testing.T) {
impl := getNewImpl()
dataChan := make(chan *pb.NotificationData)
impl.notifySendFunc = func(data *pb.NotificationData, comm *firebase.FirebaseComm, s *storage.Storage) error {
go func() { dataChan <- data }()
return nil
}
notifBatch := &pb.NotificationBatch{
RoundID: 42,
Notifications: []*pb.NotificationData{
{
EphemeralID: 5,
IdentityFP: []byte("IdentityFP"),
MessageHash: []byte("MessageHash"),
},
},
}
auth := &connect.Auth{
IsAuthenticated: true,
}
err := impl.ReceiveNotificationBatch(notifBatch, auth)
if err != nil {
t.Errorf("ReceiveNotificationBatch() returned an error: %+v", err)
}
select {
case result := <-dataChan:
if !reflect.DeepEqual(notifBatch.Notifications[0], result) {
t.Errorf("Failed to receive expected NotificationData."+
"\nexpected: %s\nreceived: %s", notifBatch.Notifications[0], result)
}
case <-time.NewTimer(50 * time.Millisecond).C:
t.Error("Timed out while waiting for NotificationData.")
}
}
// func to get a quick new impl using test creds
func getNewImpl() *Impl {
wd, _ := os.Getwd()
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment