github.com/simpleiot/simpleiot@v0.18.3/client/example_manager_test.go (about)

     1  package client_test
     2  
     3  import (
     4  	"log"
     5  
     6  	"github.com/nats-io/nats.go"
     7  	"github.com/simpleiot/simpleiot/client"
     8  	"github.com/simpleiot/simpleiot/data"
     9  	"github.com/simpleiot/simpleiot/server"
    10  )
    11  
    12  // exNode is decoded data from the client node
    13  type exNode struct {
    14  	ID          string `node:"id"`
    15  	Parent      string `node:"parent"`
    16  	Description string `point:"description"`
    17  	Port        int    `point:"port"`
    18  	Role        string `edgepoint:"role"`
    19  }
    20  
    21  // exNodeClient contains the logic for this client
    22  type exNodeClient struct {
    23  	nc            *nats.Conn
    24  	config        exNode
    25  	stop          chan struct{}
    26  	stopped       chan struct{}
    27  	newPoints     chan client.NewPoints
    28  	newEdgePoints chan client.NewPoints
    29  	chGetConfig   chan chan exNode
    30  }
    31  
    32  // newExNodeClient is passed to the NewManager() function call -- when
    33  // a new node is detected, the Manager will call this function to construct
    34  // a new client.
    35  func newExNodeClient(nc *nats.Conn, config exNode) client.Client {
    36  	return &exNodeClient{
    37  		nc:            nc,
    38  		config:        config,
    39  		stop:          make(chan struct{}),
    40  		newPoints:     make(chan client.NewPoints),
    41  		newEdgePoints: make(chan client.NewPoints),
    42  	}
    43  }
    44  
    45  // Run the main logic for this client and blocks until stopped
    46  func (tnc *exNodeClient) Run() error {
    47  	for {
    48  		select {
    49  		case <-tnc.stop:
    50  			close(tnc.stopped)
    51  			return nil
    52  		case pts := <-tnc.newPoints:
    53  			err := data.MergePoints(pts.ID, pts.Points, &tnc.config)
    54  			if err != nil {
    55  				log.Println("error merging new points:", err)
    56  			}
    57  			log.Printf("New config: %+v\n", tnc.config)
    58  		case pts := <-tnc.newEdgePoints:
    59  			err := data.MergeEdgePoints(pts.ID, pts.Parent, pts.Points, &tnc.config)
    60  			if err != nil {
    61  				log.Println("error merging new points:", err)
    62  			}
    63  		case ch := <-tnc.chGetConfig:
    64  			ch <- tnc.config
    65  		}
    66  	}
    67  }
    68  
    69  // Stop sends a signal to the Run function to exit
    70  func (tnc *exNodeClient) Stop(_ error) {
    71  	close(tnc.stop)
    72  }
    73  
    74  // Points is called by the Manager when new points for this
    75  // node are received.
    76  func (tnc *exNodeClient) Points(id string, points []data.Point) {
    77  	tnc.newPoints <- client.NewPoints{id, "", points}
    78  }
    79  
    80  // EdgePoints is called by the Manager when new edge points for this
    81  // node are received.
    82  func (tnc *exNodeClient) EdgePoints(id, parent string, points []data.Point) {
    83  	tnc.newEdgePoints <- client.NewPoints{id, parent, points}
    84  }
    85  
    86  func ExampleNewManager() {
    87  	nc, root, stop, err := server.TestServer()
    88  
    89  	if err != nil {
    90  		log.Println("Error starting test server:", err)
    91  	}
    92  
    93  	defer stop()
    94  
    95  	testConfig := testNode{"", "", "fancy test node", 8118, "admin"}
    96  
    97  	// Convert our custom struct to a data.NodeEdge struct
    98  	ne, err := data.Encode(testConfig)
    99  	if err != nil {
   100  		log.Println("Error encoding node:", err)
   101  	}
   102  
   103  	ne.Parent = root.ID
   104  
   105  	// hydrate database with test node
   106  	err = client.SendNode(nc, ne, "test")
   107  
   108  	if err != nil {
   109  		log.Println("Error sending node:", err)
   110  	}
   111  
   112  	// Create a new manager for nodes of type "testNode". The manager looks for new nodes under the
   113  	// root and if it finds any, it instantiates a new client, and sends point updates to it
   114  	m := client.NewManager(nc, newExNodeClient, nil)
   115  	err = m.Run()
   116  
   117  	if err != nil {
   118  		log.Println("Error running:", err)
   119  	}
   120  
   121  	// Now any updates to the node will trigger Points/EdgePoints callbacks in the above client
   122  }