[SEBA-854] Add new API and modify existing
Change-Id: Iea9fd003d122f58a4d45c79d806a2011087d1740
diff --git a/main.go b/main.go
index c0d7346..bc0e3ba 100644
--- a/main.go
+++ b/main.go
@@ -15,22 +15,24 @@
package main
import (
+ importer "./proto"
+ "crypto/tls"
+ "encoding/json"
"fmt"
+ "github.com/Shopify/sarama"
+ log "github.com/Sirupsen/logrus"
+ empty "github.com/golang/protobuf/ptypes/empty"
+ "golang.org/x/net/context"
+ "google.golang.org/grpc"
+ "google.golang.org/grpc/codes"
+ "google.golang.org/grpc/status"
+ "io/ioutil"
"net"
"net/http"
"os"
"os/signal"
- "io/ioutil"
- "github.com/Shopify/sarama"
- "google.golang.org/grpc"
- "golang.org/x/net/context"
- "crypto/tls"
- empty "github.com/golang/protobuf/ptypes/empty"
- importer "./proto"
- log "github.com/Sirupsen/logrus"
- "time"
- "encoding/json"
"path"
+ "time"
)
//globals
@@ -43,83 +45,156 @@
var DataProducer sarama.AsyncProducer
-var vendor_default_events = map[string][]string{
- "edgecore": {"ResourceAdded","ResourceRemoved","Alert"},
- }
-var redfish_services = [...]string{"/Chassis", "/Systems","/EthernetSwitches"}
+var vendor_default_events = map[string][]string{
+ "edgecore": {"ResourceAdded", "ResourceRemoved", "Alert"},
+}
+var redfish_services = [...]string{"/Chassis", "/Systems", "/EthernetSwitches"}
var pvmount = os.Getenv("DEVICE_MANAGEMENT_PVMOUNT")
var subscriptionListPath string
-type scheduler struct {
- getdata time.Ticker
- quit chan bool
+type scheduler struct {
+ getdata *time.Ticker
+ quit chan bool
}
-type device struct {
- Subscriptions map[string]string `json:"ss"`
- Freq uint32 `json:"freq"`
- Datacollector scheduler `json:"-"`
- Freqchan chan uint32 `json:"-"`
- Vendor string `json:"vendor"`
- Protocol string `json:"protocol"`
+type device struct {
+ Subscriptions map[string]string `json:"ss"`
+ Freq uint32 `json:"freq"`
+ Datacollector scheduler `json:"-"`
+ Freqchan chan uint32 `json:"-"`
+ Vendor string `json:"vendor"`
+ Protocol string `json:"protocol"`
}
type Server struct {
- devicemap map[string]*device
- gRPCserver *grpc.Server
- dataproducer sarama.AsyncProducer
- httpclient *http.Client
- devicechan chan *importer.DeviceInfo
+ devicemap map[string]*device
+ gRPCserver *grpc.Server
+ dataproducer sarama.AsyncProducer
+ httpclient *http.Client
+ devicechan chan *importer.DeviceInfo
}
-func (s *Server) GetEventList(c context.Context, info *importer.DeviceInfo) (*importer.SupportedEventList, error) {
+func (s *Server) ClearCurrentEventList(c context.Context, info *importer.Device) (*empty.Empty, error) {
+ fmt.Println("Received GetCurrentEventList\n")
+ ip_address := info.IpAddress
+ _, found := s.devicemap[ip_address]
+ if !found {
+ return nil, status.Errorf(codes.NotFound, "Device not registered")
+ }
+ f := get_subscription_list(ip_address)
+ for event, _ := range s.devicemap[ip_address].Subscriptions {
+ rtn := s.remove_subscription(ip_address, event, f)
+ if !rtn {
+ log.WithFields(log.Fields{
+ "Event": event,
+ }).Info("Error removing event")
+ }
+ }
+ if f != nil {
+ f.Close()
+ }
+ return &empty.Empty{}, nil
+}
+
+func (s *Server) GetCurrentEventList(c context.Context, info *importer.Device) (*importer.EventList, error) {
+ fmt.Println("Received ClearCurrentEventList\n")
+ _, found := s.devicemap[info.IpAddress]
+ if !found {
+ return nil, status.Errorf(codes.NotFound, "Device not registered")
+ }
+ currentevents := new(importer.EventList)
+ for event, _ := range s.devicemap[info.IpAddress].Subscriptions {
+ currentevents.Events = append(currentevents.Events, event)
+ }
+ return currentevents, nil
+}
+
+func (s *Server) GetEventList(c context.Context, info *importer.VendorInfo) (*importer.EventList, error) {
fmt.Println("Received GetEventList\n")
- eventstobesubscribed:= new(importer.SupportedEventList)
+ _, found := vendor_default_events[info.Vendor]
+ if !found {
+ return nil, status.Errorf(codes.NotFound, "Invalid Vendor Provided")
+ }
+ eventstobesubscribed := new(importer.EventList)
eventstobesubscribed.Events = vendor_default_events[info.Vendor]
return eventstobesubscribed, nil
}
-func (s *Server) SetFrequency(c context.Context, info *importer.DeviceInfo) (*empty.Empty, error) {
+func (s *Server) SetFrequency(c context.Context, info *importer.FreqInfo) (*empty.Empty, error) {
fmt.Println("Received SetFrequency")
+ _, found := s.devicemap[info.IpAddress]
+ if !found {
+ return nil, status.Errorf(codes.NotFound, "Device not registered")
+ }
+
s.devicemap[info.IpAddress].Freqchan <- info.Frequency
return &empty.Empty{}, nil
}
-func (s *Server) SubsrcribeGivenEvents(c context.Context, subeventlist *importer.EventList) (*empty.Empty, error) {
+func (s *Server) SubsrcribeGivenEvents(c context.Context, subeventlist *importer.GivenEventList) (*empty.Empty, error) {
fmt.Println("Received SubsrcribeEvents\n")
//Call API to subscribe events
ip_address := subeventlist.EventIpAddress
+ _, found := s.devicemap[ip_address]
+ if !found {
+ return nil, status.Errorf(codes.NotFound, "Device not registered")
+ }
+ if len(subeventlist.Events) <= 0 {
+ return nil, status.Errorf(codes.InvalidArgument, "Event list is empty")
+ }
f := get_subscription_list(ip_address)
for _, event := range subeventlist.Events {
if _, ok := s.devicemap[ip_address].Subscriptions[event]; !ok {
- s.add_subscription(ip_address, event, f)
+ rtn := s.add_subscription(ip_address, event, f)
+ if !rtn {
+ log.WithFields(log.Fields{
+ "Event": event,
+ }).Info("Error adding event")
+ }
} else {
log.WithFields(log.Fields{
"Event": event,
- }).Info("Already Subscribed")
+ }).Info("Already Subscribed")
}
}
- if f != nil { f.Close() }
+ if f != nil {
+ f.Close()
+ }
return &empty.Empty{}, nil
}
-func (s *Server) UnSubsrcribeGivenEvents(c context.Context, unsubeventlist *importer.EventList) (*empty.Empty, error) {
+func (s *Server) UnSubsrcribeGivenEvents(c context.Context, unsubeventlist *importer.GivenEventList) (*empty.Empty, error) {
fmt.Println("Received UnSubsrcribeEvents\n")
ip_address := unsubeventlist.EventIpAddress
+ _, found := s.devicemap[ip_address]
+ if !found {
+ return nil, status.Errorf(codes.NotFound, "Device not registered")
+ }
+
+ if len(unsubeventlist.Events) <= 0 {
+ return nil, status.Errorf(codes.InvalidArgument, "Event list is empty")
+ }
//Call API to unsubscribe events
f := get_subscription_list(ip_address)
for _, event := range unsubeventlist.Events {
if _, ok := s.devicemap[ip_address].Subscriptions[event]; ok {
- s.remove_subscription(ip_address, event, f)
- } else {
- log.WithFields(log.Fields{
- "Event": event,
- }).Info("was not Subscribed")
- }
- }
- if f != nil { f.Close() }
+ rtn := s.remove_subscription(ip_address, event, f)
+ if !rtn {
+ log.WithFields(log.Fields{
+ "Event": event,
+ }).Info("Error removing event")
+ }
+ } else {
+ log.WithFields(log.Fields{
+ "Event": event,
+ }).Info("was not Subscribed")
+ }
+ }
+ if f != nil {
+ f.Close()
+ }
- return &empty.Empty{}, nil
+ return &empty.Empty{}, nil
}
func (s *Server) collect_data(ip_address string) {
@@ -130,8 +205,10 @@
select {
case freq := <-freqchan:
ticker.Stop()
- ticker = *time.NewTicker(time.Duration(freq) * time.Second)
- case err := <-s.dataproducer.Errors():
+ if freq > 0 {
+ ticker = time.NewTicker(time.Duration(freq) * time.Second)
+ }
+ case err := <-s.dataproducer.Errors():
fmt.Println("Failed to produce message:", err)
case <-ticker.C:
for _, service := range redfish_services {
@@ -143,9 +220,9 @@
b := []byte(str)
msg := &sarama.ProducerMessage{Topic: importerTopic, Value: sarama.StringEncoder(b)}
select {
- // TODO: this is blocking, maybe a timer?
- case s.dataproducer.Input() <- msg:
+ case s.dataproducer.Input() <- msg:
fmt.Println("Produce message")
+ default:
}
}
}
@@ -158,22 +235,32 @@
}
}
-func (s *Server) SendDeviceInfo(c context.Context, info *importer.DeviceInfo) (*empty.Empty, error) {
- d := device {
+func (s *Server) SendDeviceInfo(c context.Context, info *importer.DeviceInfo) (*empty.Empty, error) {
+ d := device{
Subscriptions: make(map[string]string),
- Freq: info.Frequency,
+ Freq: info.Frequency,
Datacollector: scheduler{
- getdata: *time.NewTicker(time.Duration(info.Frequency) * time.Second),
- quit: make(chan bool),
+ getdata: time.NewTicker(time.Duration(info.Frequency) * time.Second),
+ quit: make(chan bool),
},
Freqchan: make(chan uint32),
- Vendor: info.Vendor,
+ Vendor: info.Vendor,
Protocol: info.Protocol,
}
- //default_events := [...]string{}
+ _, found := s.devicemap[info.IpAddress]
+ if found {
+ return nil, status.Errorf(codes.AlreadyExists, "Device Already registered")
+ }
+
+ _, vendorfound := vendor_default_events[info.Vendor]
+ if !vendorfound {
+ return nil, status.Errorf(codes.NotFound, "Vendor Not Found")
+ }
+
+ //default_events := [...]string{}
s.devicemap[info.IpAddress] = &d
fmt.Printf("size of devicemap %d\n", len(s.devicemap))
- ip_address:= info.IpAddress
+ ip_address := info.IpAddress
fmt.Printf("Configuring %s\n", ip_address)
// call subscription function with info.IpAddress
@@ -183,18 +270,20 @@
for _, event := range default_events {
s.add_subscription(ip_address, event, f)
}
- if f != nil { f.Close() }
+ if f != nil {
+ f.Close()
+ }
go s.collect_data(ip_address)
return &empty.Empty{}, nil
}
func NewGrpcServer(grpcport string) (l net.Listener, g *grpc.Server, e error) {
- fmt.Printf("Listening %s\n", grpcport)
- g = grpc.NewServer()
- l, e = net.Listen("tcp", grpcport)
- return
+ fmt.Printf("Listening %s\n", grpcport)
+ g = grpc.NewServer()
+ l, e = net.Listen("tcp", grpcport)
+ return
}
-func (s *Server) startgrpcserver()error {
+func (s *Server) startgrpcserver() error {
fmt.Println("starting gRPC Server")
grpcport := ":50051"
listener, gserver, err := NewGrpcServer(grpcport)
@@ -211,8 +300,8 @@
return nil
}
-func (s *Server) kafkaCloseProducer(){
- if err :=s.dataproducer.Close(); err != nil {
+func (s *Server) kafkaCloseProducer() {
+ if err := s.dataproducer.Close(); err != nil {
panic(err)
}
@@ -220,7 +309,7 @@
func (s *Server) kafkaInit() {
fmt.Println("Starting kafka init to Connect to broker: ")
config := sarama.NewConfig()
- config.Producer.RequiredAcks = sarama.WaitForAll
+ config.Producer.RequiredAcks = sarama.WaitForAll
config.Producer.Retry.Max = 10
producer, err := sarama.NewAsyncProducer([]string{"cord-kafka.default.svc.cluster.local:9092"}, config)
if err != nil {
@@ -233,19 +322,19 @@
signals := make(chan os.Signal, 1)
signal.Notify(signals, os.Interrupt)
- fmt.Println(" IN Handle Event ")
- if(r.Method == "POST"){
+ fmt.Println(" IN Handle Event ")
+ if r.Method == "POST" {
Body, err := ioutil.ReadAll(r.Body)
if err != nil {
- fmt.Println("Error getting HTTP data",err)
+ fmt.Println("Error getting HTTP data", err)
}
- defer r.Body.Close()
+ defer r.Body.Close()
fmt.Println("Received Event Message ")
- fmt.Printf("%s\n",Body)
- message :=&sarama.ProducerMessage{
- Topic: importerTopic,
- Value: sarama.StringEncoder(Body),
- }
+ fmt.Printf("%s\n", Body)
+ message := &sarama.ProducerMessage{
+ Topic: importerTopic,
+ Value: sarama.StringEncoder(Body),
+ }
s.dataproducer.Input() <- message
}
}
@@ -274,7 +363,7 @@
d := device{}
json.Unmarshal(b, &d)
s.devicemap[ip] = &d
- s.devicemap[ip].Datacollector.getdata = *time.NewTicker(time.Duration(s.devicemap[ip].Freq) * time.Second)
+ s.devicemap[ip].Datacollector.getdata = time.NewTicker(time.Duration(s.devicemap[ip].Freq) * time.Second)
s.devicemap[ip].Datacollector.quit = make(chan bool)
s.devicemap[ip].Freqchan = make(chan uint32)
go s.collect_data(ip)
@@ -285,14 +374,14 @@
}
func init() {
- Formatter := new(log.TextFormatter)
- Formatter.TimestampFormat = "02-01-2006 15:04:05"
- Formatter.FullTimestamp = true
- log.SetFormatter(Formatter)
+ Formatter := new(log.TextFormatter)
+ Formatter.TimestampFormat = "02-01-2006 15:04:05"
+ Formatter.FullTimestamp = true
+ log.SetFormatter(Formatter)
fmt.Println("Connecting to broker: ")
fmt.Println("Listening to http server")
- log.Info("log Connecting to broker:")
- log.Info("log Listening to http server ")
+ log.Info("log Connecting to broker:")
+ log.Info("log Listening to http server ")
//sarama.Logger = log.New()
}
@@ -300,7 +389,7 @@
if pvmount == "" {
return nil
}
- f, err := os.OpenFile(subscriptionListPath + "/" + ip, os.O_CREATE|os.O_RDWR, 0664)
+ f, err := os.OpenFile(subscriptionListPath+"/"+ip, os.O_CREATE|os.O_RDWR, 0664)
if err != nil {
fmt.Println(err)
}
@@ -313,16 +402,15 @@
http.DefaultTransport.(*http.Transport).TLSClientConfig = &tls.Config{InsecureSkipVerify: true}
client := &http.Client{
Timeout: 10 * time.Second,
- }
+ }
- s := Server {
- devicemap: make(map[string]*device),
- devicechan: make(chan *importer.DeviceInfo),
- httpclient: client,
+ s := Server{
+ devicemap: make(map[string]*device),
+ devicechan: make(chan *importer.DeviceInfo),
+ httpclient: client,
}
s.kafkaInit()
-//TODO: check if we should keep this as goroutines?
go s.runServer()
go s.startgrpcserver()