OIntroduced POST and GET rest apis for adding and fetching OLT Information

Change-Id: I997093581c22cdfe8211caced804d327e29834c8
diff --git a/internal/pkg/application/application.go b/internal/pkg/application/application.go
index 1f31149..730be6c 100644
--- a/internal/pkg/application/application.go
+++ b/internal/pkg/application/application.go
@@ -454,7 +454,7 @@
 type DeviceConfig struct {
 	SerialNumber       string `json:"id"`
 	HardwareIdentifier string `json:"hardwareIdentifier"`
-	IPAddress          net.IP `json:"ipAddress"`
+	IPAddress          string `json:"ipAddress"`
 	UplinkPort         int    `json:"uplinkPort"`
 	NasID              string `json:"nasId"`
 	NniDhcpTrapVid     int    `json:"nniDhcpTrapVid"`
@@ -573,29 +573,31 @@
 	return nil
 }
 
-func (va *VoltApplication) AddDeviceConfig(cntx context.Context, serialNum, hardwareIdentifier, nasID string, ipAddress net.IP, uplinkPort, nniDhcpTrapId int) error {
+func (va *VoltApplication) AddDeviceConfig(cntx context.Context, serialNum, hardwareIdentifier, nasID, ipAddress string, uplinkPort, nniDhcpTrapId int) error {
 	var dc *DeviceConfig
 
-	d := va.GetDeviceConfig(serialNum)
-	if d == nil {
-		deviceConfig := &DeviceConfig{
-			SerialNumber:       serialNum,
-			HardwareIdentifier: hardwareIdentifier,
-			NasID:              nasID,
-			UplinkPort:         uplinkPort,
-			IPAddress:          ipAddress,
-			NniDhcpTrapVid:     nniDhcpTrapId,
-		}
-		va.DevicesConfig.Store(serialNum, deviceConfig)
-		err := dc.WriteDeviceConfigToDb(cntx, serialNum, deviceConfig)
-		if err != nil {
-			logger.Errorw(ctx, "DB update for device config failed", log.Fields{"err": err})
-			return err
-		}
-	} else {
-		logger.Errorw(ctx, "Device config already exist", log.Fields{"DeviceID": serialNum})
-		return errors.New("Device config already exist")
+	deviceConfig := &DeviceConfig{
+		SerialNumber:       serialNum,
+		HardwareIdentifier: hardwareIdentifier,
+		NasID:              nasID,
+		UplinkPort:         uplinkPort,
+		IPAddress:          ipAddress,
+		NniDhcpTrapVid:     nniDhcpTrapId,
 	}
+	va.DevicesConfig.Store(serialNum, deviceConfig)
+	err := dc.WriteDeviceConfigToDb(cntx, serialNum, deviceConfig)
+	if err != nil {
+		logger.Errorw(ctx, "DB update for device config failed", log.Fields{"err": err})
+		return err
+	}
+
+	// If device is already discovered update the VoltDevice structure
+	device, id := va.GetDeviceBySerialNo(serialNum)
+	if device != nil {
+		device.NniDhcpTrapVid = of.VlanType(nniDhcpTrapId)
+		va.DevicesDisc.Store(id, device)
+	}
+
 	return nil
 }
 
@@ -2145,24 +2147,18 @@
 	logger.Infow(ctx, "updated OltFlowServiceConfig from DB", log.Fields{"OltFlowServiceConfig": va.OltFlowServiceConfig})
 }
 
-func (va *VoltApplication) UpdateDeviceConfig(cntx context.Context, sn, mac, nasID string, port, dhcpVid int, ip net.IP) {
-	if d, ok := va.DevicesConfig.Load(sn); ok {
-		logger.Infow(ctx, "Device configuration already exists", log.Fields{"DeviceInfo": d})
+func (va *VoltApplication) UpdateDeviceConfig(cntx context.Context, deviceConfig *DeviceConfig) {
+	var dc *DeviceConfig
+	va.DevicesConfig.Store(deviceConfig.SerialNumber, deviceConfig)
+	err := dc.WriteDeviceConfigToDb(cntx, deviceConfig.SerialNumber, deviceConfig)
+	if err != nil {
+		logger.Errorw(ctx, "DB update for device config failed", log.Fields{"err": err})
 	}
-	d := DeviceConfig{
-		SerialNumber:       sn,
-		UplinkPort:         port,
-		HardwareIdentifier: mac,
-		IPAddress:          ip,
-		NasID:              nasID,
-		NniDhcpTrapVid:     dhcpVid,
-	}
-	logger.Infow(ctx, "Added OLT configurations", log.Fields{"DeviceInfo": d})
-	va.DevicesConfig.Store(sn, d)
+	logger.Infow(ctx, "Added OLT configurations", log.Fields{"DeviceInfo": deviceConfig})
 	// If device is already discovered update the VoltDevice structure
-	device, id := va.GetDeviceBySerialNo(sn)
+	device, id := va.GetDeviceBySerialNo(deviceConfig.SerialNumber)
 	if device != nil {
-		device.NniDhcpTrapVid = of.VlanType(dhcpVid)
+		device.NniDhcpTrapVid = of.VlanType(deviceConfig.NniDhcpTrapVid)
 		va.DevicesDisc.Store(id, device)
 	}
 }
diff --git a/voltha-go-controller/nbi/rest.go b/voltha-go-controller/nbi/rest.go
index e8a7e50..dff8549 100644
--- a/voltha-go-controller/nbi/rest.go
+++ b/voltha-go-controller/nbi/rest.go
@@ -30,6 +30,7 @@
 var ctx = context.TODO()
 
 const (
+	BasePath                          string = "/vgc/v1"
 	SubscribersPath                   string = "/subscribers/{id}"
 	ProfilesPath                      string = "/profiles/{id}"
 	IgmpProxyPath                     string = "/igmp-proxy"
@@ -59,41 +60,44 @@
 	GroupsByIdPath                    string = "/groups/{id}"
 	OltFlowServicePath                string = "/oltflowservice"
 	NetConfigPath                     string = "/network/configurations"
+	DeviceConfigPath                  string = "/olt/{serialNumber}"
 )
 
 // RestStart to execute for API
 func RestStart() {
 	mu := mux.NewRouter()
 	logger.Info(ctx, "Rest Server Starting...")
-	mu.HandleFunc(SubscribersPath, (&SubscriberHandle{}).ServeHTTP)
-	mu.HandleFunc(ProfilesPath, (&ProfileHandle{}).ServeHTTP)
-	mu.HandleFunc(IgmpProxyPath, (&IgmpProxyHandle{}).ServeHTTP)
-	mu.HandleFunc(IgmpProxyDeletePath, (&IgmpProxyHandle{}).ServeHTTP)
-	mu.HandleFunc(MulticastPath, (&MulticastHandle{}).ServeHTTP)
-	mu.HandleFunc(MulticastDeletePath, (&MulticastHandle{}).ServeHTTP)
-	mu.HandleFunc(FlowsPath, (&onos_nbi.FlowHandle{}).ServeHTTP)
-	mu.HandleFunc(FlowsPerDeviceIDPath, (&onos_nbi.FlowHandle{}).ServeHTTP)
-	mu.HandleFunc(FlowPerDeviceIDFlowIDPath, (&onos_nbi.FlowHandle{}).ServeHTTP)
-	mu.HandleFunc(PendingFlowsPath, (&onos_nbi.PendingFlowHandle{}).ServeHTTP)
-	mu.HandleFunc(ProgrammedSubscribersPath, (&onos_nbi.ServiceAdapter{}).ServeHTTP)
-	mu.HandleFunc(ServiceDevicePortPath, (&onos_nbi.ServiceAdapter{}).ServeHTTP)
-	mu.HandleFunc(ServicePortNamePath, (&onos_nbi.ServiceAdapter{}).ServeHTTPWithPortName)
-	mu.HandleFunc(ServicePortStagCtagTpIDPath, (&onos_nbi.ServiceAdapter{}).ServeHTTPWithPortName)
-	mu.HandleFunc(AllocationsPath, (&onos_nbi.DhcpRelayHandle{}).ServeHTTP)
-	mu.HandleFunc(AllocationsDeviceIDPath, (&onos_nbi.DhcpRelayHandle{}).ServeHTTP)
-	mu.HandleFunc(DevicesPath, (&onos_nbi.DeviceHandle{}).ServeHTTP)
-	mu.HandleFunc(PortsPath, (&onos_nbi.DevicePortHandle{}).ServeHTTP)
-	mu.HandleFunc(PortsPerDeviceIDPath, (&onos_nbi.DevicePortHandle{}).ServeHTTPWithDeviceID)
-	mu.HandleFunc(MecLearnerPath, (&onos_nbi.MacLearnerHandle{}).ServeHTTP)
-	mu.HandleFunc(MecLearnerDeviceIdAndPortNoPath, (&onos_nbi.MacLearnerHandle{}).ServeHTTP)
-	mu.HandleFunc(MecLearnerDevicePortAndVlanIdPath, (&onos_nbi.MacLearnerHandle{}).ServeHTTP)
-	mu.HandleFunc(PortIgnoredPath, (&onos_nbi.PortIgnoredHandle{}).PortsIgnoredServeHTTP)
-	mu.HandleFunc(MetersParh, (&onos_nbi.MetersHandle{}).MeterServeHTTP)
-	mu.HandleFunc(MetersByIdPath, (&onos_nbi.MetersHandle{}).MeterServeHTTP)
-	mu.HandleFunc(GroupsPath, (&onos_nbi.GroupsHandle{}).GroupServeHTTP)
-	mu.HandleFunc(GroupsByIdPath, (&onos_nbi.GroupsHandle{}).GroupServeHTTP)
-	mu.HandleFunc(OltFlowServicePath, (&onos_nbi.OltFlowServiceHandle{}).ServeHTTP)
-	mu.HandleFunc(NetConfigPath, (&NetConfigHandle{}).NetConfigServeHTTP)
+	mu.HandleFunc(BasePath+SubscribersPath, (&SubscriberHandle{}).ServeHTTP)
+	mu.HandleFunc(BasePath+ProfilesPath, (&ProfileHandle{}).ServeHTTP)
+	mu.HandleFunc(BasePath+IgmpProxyPath, (&IgmpProxyHandle{}).ServeHTTP)
+	mu.HandleFunc(BasePath+IgmpProxyDeletePath, (&IgmpProxyHandle{}).ServeHTTP)
+	mu.HandleFunc(BasePath+MulticastPath, (&MulticastHandle{}).ServeHTTP)
+	mu.HandleFunc(BasePath+MulticastDeletePath, (&MulticastHandle{}).ServeHTTP)
+	mu.HandleFunc(BasePath+FlowsPath, (&onos_nbi.FlowHandle{}).ServeHTTP)
+	mu.HandleFunc(BasePath+FlowsPerDeviceIDPath, (&onos_nbi.FlowHandle{}).ServeHTTP)
+	mu.HandleFunc(BasePath+FlowPerDeviceIDFlowIDPath, (&onos_nbi.FlowHandle{}).ServeHTTP)
+	mu.HandleFunc(BasePath+PendingFlowsPath, (&onos_nbi.PendingFlowHandle{}).ServeHTTP)
+	mu.HandleFunc(BasePath+ProgrammedSubscribersPath, (&onos_nbi.ServiceAdapter{}).ServeHTTP)
+	mu.HandleFunc(BasePath+ServiceDevicePortPath, (&onos_nbi.ServiceAdapter{}).ServeHTTP)
+	mu.HandleFunc(BasePath+ServicePortNamePath, (&onos_nbi.ServiceAdapter{}).ServeHTTPWithPortName)
+	mu.HandleFunc(BasePath+ServicePortStagCtagTpIDPath, (&onos_nbi.ServiceAdapter{}).ServeHTTPWithPortName)
+	mu.HandleFunc(BasePath+AllocationsPath, (&onos_nbi.DhcpRelayHandle{}).ServeHTTP)
+	mu.HandleFunc(BasePath+AllocationsDeviceIDPath, (&onos_nbi.DhcpRelayHandle{}).ServeHTTP)
+	mu.HandleFunc(BasePath+DevicesPath, (&onos_nbi.DeviceHandle{}).ServeHTTP)
+	mu.HandleFunc(BasePath+PortsPath, (&onos_nbi.DevicePortHandle{}).ServeHTTP)
+	mu.HandleFunc(BasePath+PortsPerDeviceIDPath, (&onos_nbi.DevicePortHandle{}).ServeHTTPWithDeviceID)
+	mu.HandleFunc(BasePath+MecLearnerPath, (&onos_nbi.MacLearnerHandle{}).ServeHTTP)
+	mu.HandleFunc(BasePath+MecLearnerDeviceIdAndPortNoPath, (&onos_nbi.MacLearnerHandle{}).ServeHTTP)
+	mu.HandleFunc(BasePath+MecLearnerDevicePortAndVlanIdPath, (&onos_nbi.MacLearnerHandle{}).ServeHTTP)
+	mu.HandleFunc(BasePath+PortIgnoredPath, (&onos_nbi.PortIgnoredHandle{}).PortsIgnoredServeHTTP)
+	mu.HandleFunc(BasePath+MetersParh, (&onos_nbi.MetersHandle{}).MeterServeHTTP)
+	mu.HandleFunc(BasePath+MetersByIdPath, (&onos_nbi.MetersHandle{}).MeterServeHTTP)
+	mu.HandleFunc(BasePath+GroupsPath, (&onos_nbi.GroupsHandle{}).GroupServeHTTP)
+	mu.HandleFunc(BasePath+GroupsByIdPath, (&onos_nbi.GroupsHandle{}).GroupServeHTTP)
+	mu.HandleFunc(BasePath+OltFlowServicePath, (&onos_nbi.OltFlowServiceHandle{}).ServeHTTP)
+	mu.HandleFunc(BasePath+NetConfigPath, (&NetConfigHandle{}).NetConfigServeHTTP)
+	mu.HandleFunc(BasePath+DeviceConfigPath, (&onos_nbi.DeviceConfigHandle{}).ServeHTTP)
+
 	err := http.ListenAndServe(":8181", mu)
 	logger.Infow(ctx, "Rest Server Started", log.Fields{"Error": err})
 }
diff --git a/voltha-go-controller/nbi/subscriber.go b/voltha-go-controller/nbi/subscriber.go
index b8feb67..8067306 100644
--- a/voltha-go-controller/nbi/subscriber.go
+++ b/voltha-go-controller/nbi/subscriber.go
@@ -39,7 +39,7 @@
 	UplinkPort         int                 `json:"uplinkPort"`
 	Slot               int                 `json:"slot"`
 	HardwareIdentifier string              `json:"hardwareIdentifier"`
-	IPAddress          net.IP              `json:"ipAddress"`
+	IPAddress          string              `json:"ipAddress"`
 	NasID              string              `json:"nasId"`
 	CircuitID          string              `json:"circuitId"`
 	RemoteID           string              `json:"remoteId"`
diff --git a/voltha-go-controller/onos_nbi/deviceconfig.go b/voltha-go-controller/onos_nbi/deviceconfig.go
new file mode 100644
index 0000000..e6d3eec
--- /dev/null
+++ b/voltha-go-controller/onos_nbi/deviceconfig.go
@@ -0,0 +1,86 @@
+/*
+* Copyright 2022-present Open Networking Foundation
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+ */
+
+package onos_nbi
+
+import (
+	"bytes"
+	"context"
+	"encoding/json"
+	"net/http"
+
+	app "voltha-go-controller/internal/pkg/application"
+	"voltha-go-controller/log"
+
+	"github.com/gorilla/mux"
+)
+
+// DeviceConfigHandle handles DeviceConfig Requests
+type DeviceConfigHandle struct {
+}
+
+// ServeHTTP to serve HTTP requests
+func (oh *DeviceConfigHandle) ServeHTTP(w http.ResponseWriter, r *http.Request) {
+	logger.Infow(ctx, "Received-northbound-request", log.Fields{"Method": r.Method, "URL": r.URL})
+	switch r.Method {
+	case "POST":
+		oh.AddDeviceConfig(context.Background(), w, r)
+	case "GET":
+		oh.FetchDeviceConfig(context.Background(), w, r)
+	default:
+		logger.Warnw(ctx, "Unsupported Method", log.Fields{"Method": r.Method})
+	}
+}
+
+func (oh *DeviceConfigHandle) AddDeviceConfig(cntx context.Context, w http.ResponseWriter, r *http.Request) {
+	logger.Info(cntx, "Inside AddDeviceConfig method")
+	// Get the payload to process the request
+	d := new(bytes.Buffer)
+	if _, err := d.ReadFrom(r.Body); err != nil {
+		logger.Warnw(ctx, "Error reading buffer", log.Fields{"Reason": err.Error()})
+		return
+	}
+	// Unmarshal the request into device configuration structure
+	req := &app.DeviceConfig{}
+	if err := json.Unmarshal(d.Bytes(), req); err != nil {
+		logger.Warnw(ctx, "Unmarshal Failed", log.Fields{"Reason": err.Error()})
+		http.Error(w, err.Error(), http.StatusConflict)
+		return
+	}
+	app.GetApplication().UpdateDeviceConfig(cntx, req)
+}
+
+func (oh *DeviceConfigHandle) FetchDeviceConfig(cntx context.Context, w http.ResponseWriter, r *http.Request) {
+	logger.Info(cntx, "Inside FetchDeviceConfig method")
+	vars := mux.Vars(r)
+	serialNum := vars["serialNumber"]
+	deviceInfo := DeviceConfigPayload{}
+	dc := app.GetApplication().GetDeviceConfig(serialNum)
+	deviceInfo.DeviceConfig = dc
+	oltInfoJSON, err := json.Marshal(deviceInfo)
+	if err != nil {
+		logger.Errorw(ctx, "Failed to marshal olt payload response", log.Fields{"Error": err})
+		w.WriteHeader(http.StatusInternalServerError)
+		return
+	}
+
+	w.Header().Add("Content-Type", "application/json")
+	_, err = w.Write(oltInfoJSON)
+	if err != nil {
+		logger.Errorw(ctx, "Failed to write olt payload response", log.Fields{"Error": err})
+		w.WriteHeader(http.StatusInternalServerError)
+	}
+
+}
diff --git a/voltha-go-controller/onos_nbi/models.go b/voltha-go-controller/onos_nbi/models.go
index ea9c19b..5f8f923 100644
--- a/voltha-go-controller/onos_nbi/models.go
+++ b/voltha-go-controller/onos_nbi/models.go
@@ -482,6 +482,14 @@
 	Subscribers []SubscriberInfo `json:"subscribers"`
 }
 
+type OltFlowServiceConfig struct {
+	OltFlowService app.OltFlowService `json:"oltFlowService"`
+}
+
+type DeviceConfigPayload struct {
+	DeviceConfig *app.DeviceConfig `json:"deviceConfig"`
+}
+
 func ConvertFlowToFlowEntry(subFlow *of.VoltSubFlow) FlowEntry {
 	var flowEntry FlowEntry
 	flowEntry.Flows = []Flow{}
@@ -688,10 +696,6 @@
 	Protocol          string `json:"protocol"`
 }
 
-type OltFlowServiceConfig struct {
-	OltFlowService app.OltFlowService `json:"oltflowservice"`
-}
-
 func convertVoltDeviceToDevice(voltDevice *app.VoltDevice) Device {
 	var device Device
 
diff --git a/voltha-go-controller/onos_nbi/oltflowservice.go b/voltha-go-controller/onos_nbi/oltflowservice.go
index d528aa8..c1bd6c2 100644
--- a/voltha-go-controller/onos_nbi/oltflowservice.go
+++ b/voltha-go-controller/onos_nbi/oltflowservice.go
@@ -64,12 +64,11 @@
 func (oh *OltFlowServiceHandle) fetchOltFlowService(cntx context.Context, w http.ResponseWriter, r *http.Request) {
 
 	logger.Info(cntx, "Inside fetchOltFlowService method")
-	oltFlowServiceList := OltFlowServiceConfig{}
-	oltFlowServiceList.OltFlowService = app.OltFlowService{}
+	oltFlowSer := OltFlowServiceConfig{}
 	va := app.GetApplication()
 
-	oltFlowServiceList.OltFlowService = va.OltFlowServiceConfig
-	OltFlowRespJSON, err := json.Marshal(oltFlowServiceList)
+	oltFlowSer.OltFlowService = va.OltFlowServiceConfig
+	OltFlowRespJSON, err := json.Marshal(oltFlowSer)
 	if err != nil {
 		logger.Errorw(ctx, "Error occurred while marshaling oltFlowService response", log.Fields{"Error": err})
 		w.WriteHeader(http.StatusInternalServerError)