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
 }