VOL-2408 - Refactor / Use voltha-lib-go Logging
Change-Id: I6e7d9eaba49c104cd50bb5692a2ff9733014fac4
diff --git a/openflow/openflowClient.go b/openflow/openflowClient.go
index 29cd423..4925f4f 100644
--- a/openflow/openflowClient.go
+++ b/openflow/openflowClient.go
@@ -23,67 +23,91 @@
"github.com/donNewtonAlpha/goloxi"
ofp "github.com/donNewtonAlpha/goloxi/of13"
+ "github.com/opencord/ofagent-go/settings"
+ l "github.com/opencord/voltha-lib-go/v2/pkg/log"
pb "github.com/opencord/voltha-protos/v2/go/voltha"
- "log"
"net"
)
-var conn net.Conn
var volthaClient *pb.VolthaServiceClient
var packetOutChannel chan pb.PacketOut
+var logger, _ = l.AddPackage(l.JSON, l.DebugLevel, nil)
+//Client structure to hold fields of Openflow Client
type Client struct {
OfServerAddress string
Port uint16
- DeviceId string
+ DeviceID string
KeepRunning bool
+ conn net.Conn
}
-func NewClient(ofServerAddress string, port uint16, deviceId string, keepRunning bool) *Client {
- client := Client{OfServerAddress: ofServerAddress, Port: port, DeviceId: deviceId, KeepRunning: keepRunning}
- go client.Start()
- return &client
-}
+//NewClient contstructs a new Openflow Client and then starts up
+func NewClient(ofServerAddress string, port uint16, deviceID string, keepRunning bool) *Client {
-func (client *Client) End() {
- client.KeepRunning = false
-}
-func (client *Client) Start() {
+ client := Client{OfServerAddress: ofServerAddress, Port: port, DeviceID: deviceID, KeepRunning: keepRunning}
addressLine := fmt.Sprintf("%s:%d", client.OfServerAddress, client.Port)
raddr, e := net.ResolveTCPAddr("tcp", addressLine)
if e != nil {
- errMessage := fmt.Errorf("Unable to resolve %s", addressLine)
- fmt.Println(errMessage)
- return
+ logger.Fatalw("openflowClient Start unable to resolve address", l.Fields{"Address": addressLine})
}
+ connection, e := net.DialTCP("tcp", nil, raddr)
+ client.conn = connection
+ if e != nil {
+ logger.Fatalf("openflowClient Unable to connect to voltha @ %v exiting", raddr)
+ }
+ client.sayHello()
+ return &client
+}
+
+//End - set keepRunning to false so start loop exits
+func (client *Client) End() {
+ client.KeepRunning = false
+}
+
+//Start run loop for the openflow client
+func (client *Client) Start() {
+
for {
if client.KeepRunning {
- connection, e := net.DialTCP("tcp", nil, raddr)
- conn = connection
- if e != nil {
- log.Fatalf("unable to connect to %v", raddr)
- }
- defer conn.Close()
- client.sayHello()
+ defer client.conn.Close()
for {
+ defer func() {
+
+ if r := recover(); r != nil {
+ err := r.(error)
+ fmt.Printf("Caught error in client.Start() %v \n ", err)
+ }
+ }()
+
if !client.KeepRunning {
return
}
buf := make([]byte, 1500)
- read, e := conn.Read(buf)
+ read, e := client.conn.Read(buf)
+ if settings.GetDebug(client.DeviceID) {
+ fmt.Printf("conn.Read read %d bytes\n", read)
+ }
+ if read < 8 {
+ continue
+ }
+
if e != nil {
- log.Printf("Connection has died %v", e)
+ logger.Errorw("Voltha connection has died", l.Fields{"DeviceID": client.DeviceID, "Error": e})
break
}
decoder := goloxi.NewDecoder(buf)
header, e := ofp.DecodeHeader(decoder)
if e != nil {
- log.Printf("decodeheader threw error %v", e)
+ js, _ := json.Marshal(decoder)
+ logger.Errorw("DecodeHeader threw error", l.Fields{"DeviceID": client.DeviceID, "Decoder": js, "Error": e})
}
- message, _ := json.Marshal(header)
- log.Printf("message %s\n", message)
+ if settings.GetDebug(client.DeviceID) {
+ js, _ := json.Marshal(header)
+ logger.Debugw("Header Decode", l.Fields{"DeviceID": client.DeviceID, "Header": js})
+ }
client.parseHeader(header, buf) //first one is ready
len := header.GetLength()
if len < uint16(read) {
@@ -92,48 +116,51 @@
newBuf := buf[len:]
decoder = goloxi.NewDecoder(newBuf)
newHeader, e := ofp.DecodeHeader(decoder)
- message, _ := json.Marshal(newHeader)
- log.Printf("message %s\n", message)
if e != nil {
-
+ js, _ := json.Marshal(decoder)
+ logger.Errorw("DecodeHeader threw error", l.Fields{"DeviceID": client.DeviceID, "Decoder": js, "Error": e})
+ }
+ if e != nil {
+ js, _ := json.Marshal(decoder)
+ logger.Errorw("DecodeHeader threw error", l.Fields{"DeviceID": client.DeviceID, "Decoder": js, "Error": e})
+ }
+ if settings.GetDebug(client.DeviceID) {
+ js, _ := json.Marshal(header)
+ logger.Debugw("Header Decode", l.Fields{"DeviceID": client.DeviceID, "Header": js})
}
len = newHeader.GetLength()
client.parseHeader(newHeader, newBuf)
if read == int(len) {
break
- } else {
}
buf = newBuf
}
}
- if e != nil {
- log.Println("Decode Header error ", e)
- }
}
}
break
}
}
func (client *Client) sayHello() {
-
hello := ofp.NewHello()
hello.Xid = uint32(GetXid())
var elements []ofp.IHelloElem
-
elem := ofp.NewHelloElemVersionbitmap()
elem.SetType(ofp.OFPHETVersionbitmap)
elem.SetLength(8)
var bitmap = ofp.Uint32{Value: 16}
bitmaps := []*ofp.Uint32{&bitmap}
-
elem.SetBitmaps(bitmaps)
-
elements = append(elements, elem)
-
hello.SetElements(elements)
+ if settings.GetDebug(client.DeviceID) {
+ js, _ := json.Marshal(hello)
+ logger.Debugw("sayHello Called", l.Fields{"DeviceID": client.DeviceID, "HelloMessage": js})
+ }
e := client.SendMessage(hello)
if e != nil {
- log.Fatal(e)
+ logger.Fatalw("Failed saying hello to Openflow Server, unable to proceed",
+ l.Fields{"DeviceID": client.DeviceID, "Error": e})
}
}
func (client *Client) parseHeader(header ofp.IHeader, buf []byte) {
@@ -142,105 +169,104 @@
//x := header.(*ofp.Hello)
case ofp.OFPTError:
errMsg := header.(*ofp.ErrorMsg)
- go handleErrMsg(errMsg)
+ go handleErrMsg(errMsg, client.DeviceID)
case ofp.OFPTEchoRequest:
echoReq := header.(*ofp.EchoRequest)
- go handleEchoRequest(echoReq, client)
+ go handleEchoRequest(echoReq, client.DeviceID, client)
case ofp.OFPTEchoReply:
case ofp.OFPTExperimenter:
case ofp.OFPTFeaturesRequest:
featReq := header.(*ofp.FeaturesRequest)
- go handleFeatureRequest(featReq, client.DeviceId, client)
+ go handleFeatureRequest(featReq, client.DeviceID, client)
case ofp.OFPTFeaturesReply:
case ofp.OFPTGetConfigRequest:
configReq := header.(*ofp.GetConfigRequest)
- go handleGetConfigRequest(configReq, client)
+ go handleGetConfigRequest(configReq, client.DeviceID, client)
case ofp.OFPTGetConfigReply:
case ofp.OFPTSetConfig:
setConf := header.(*ofp.SetConfig)
- go handleSetConfig(setConf)
+ go handleSetConfig(setConf, client.DeviceID)
case ofp.OFPTPacketIn:
case ofp.OFPTFlowRemoved:
case ofp.OFPTPortStatus:
case ofp.OFPTPacketOut:
packetOut := header.(*ofp.PacketOut)
- go handlePacketOut(packetOut, client.DeviceId)
+ go handlePacketOut(packetOut, client.DeviceID)
case ofp.OFPTFlowMod:
flowModType := uint8(buf[25])
switch flowModType {
case ofp.OFPFCAdd:
flowAdd := header.(*ofp.FlowAdd)
- go handleFlowAdd(flowAdd, client.DeviceId)
+ go handleFlowAdd(flowAdd, client.DeviceID)
case ofp.OFPFCModify:
flowMod := header.(*ofp.FlowMod)
- go handleFlowMod(flowMod, client.DeviceId)
+ go handleFlowMod(flowMod, client.DeviceID)
case ofp.OFPFCModifyStrict:
flowModStrict := header.(*ofp.FlowModifyStrict)
- go handleFlowModStrict(flowModStrict, client.DeviceId)
+ go handleFlowModStrict(flowModStrict, client.DeviceID)
case ofp.OFPFCDelete:
flowDelete := header.(*ofp.FlowDelete)
- go handleFlowDelete(flowDelete, client.DeviceId)
+ go handleFlowDelete(flowDelete, client.DeviceID)
case ofp.OFPFCDeleteStrict:
flowDeleteStrict := header.(*ofp.FlowDeleteStrict)
- go handleFlowDeleteStrict(flowDeleteStrict, client.DeviceId)
+ go handleFlowDeleteStrict(flowDeleteStrict, client.DeviceID)
}
case ofp.OFPTStatsRequest:
var statType = uint16(buf[8])<<8 + uint16(buf[9])
- log.Println("statsType", statType)
- go handleStatsRequest(header, statType, client.DeviceId, client)
+ go handleStatsRequest(header, statType, client.DeviceID, client)
case ofp.OFPTBarrierRequest:
barRequest := header.(*ofp.BarrierRequest)
- go handleBarrierRequest(barRequest, client)
+ go handleBarrierRequest(barRequest, client.DeviceID, client)
case ofp.OFPTRoleRequest:
roleReq := header.(*ofp.RoleRequest)
- go handleRoleRequest(roleReq, client)
+ go handleRoleRequest(roleReq, client.DeviceID, client)
case ofp.OFPTMeterMod:
meterMod := header.(*ofp.MeterMod)
- go handleMeterModRequest(meterMod, client)
+ go handleMeterModRequest(meterMod, client.DeviceID, client)
}
}
-//openFlowMessage created to allow for a single SendMessage
-type OpenFlowMessage interface {
+//Message created to allow for a single SendMessage
+type Message interface {
Serialize(encoder *goloxi.Encoder) error
}
-func (client *Client) SendMessage(message OpenFlowMessage) error {
- jsonMessage, _ := json.Marshal(message)
- log.Printf("send message called %s\n", jsonMessage)
+//SendMessage sends message to openflow server
+func (client *Client) SendMessage(message Message) error {
+ if settings.GetDebug(client.DeviceID) {
+ js, _ := json.Marshal(message)
+ logger.Debugw("SendMessage called", l.Fields{"DeviceID": client.DeviceID, "Message": js})
+ }
enc := goloxi.NewEncoder()
message.Serialize(enc)
- jMessage, _ := json.Marshal(message)
- bytes := enc.Bytes()
- log.Printf("message after serialize %d for message %s", bytes, jMessage)
-
for {
- if conn == nil {
- log.Println("CONN IS NIL")
+ if client.conn == nil {
+ logger.Warnln("SendMessage Connection is Nil sleeping for 10 milliseconds")
time.Sleep(10 * time.Millisecond)
} else {
break
}
}
- _, err := conn.Write(bytes)
+ bytes := enc.Bytes()
+ _, err := client.conn.Write(bytes)
if err != nil {
- log.Printf("SendMessage had error %v \n %s\n********", err, jMessage)
+ jMessage, _ := json.Marshal(message)
+ logger.Errorw("SendMessage failed sending message", l.Fields{"DeviceID": client.DeviceID, "Error": err, "Message": jMessage})
return err
- } else {
- log.Printf("message after send %s", jMessage)
}
return nil
}
+
+//SetGrpcClient store a reference to the grpc client connection
func SetGrpcClient(client *pb.VolthaServiceClient) {
volthaClient = client
}
func getGrpcClient() *pb.VolthaServiceClient {
return volthaClient
}
-func test(hello ofp.IHello) {
- fmt.Println("works")
-}
+
+//SetPacketOutChannel - store the channel to send packet outs to grpc connection
func SetPacketOutChannel(pktOutChan chan pb.PacketOut) {
packetOutChannel = pktOutChan
}