diff --git a/go-apps/meep-iot/sbi/iot-sbi.go b/go-apps/meep-iot/sbi/iot-sbi.go index 9157b58853a70f0aff5c44a7fb8461a3c9094125..0362479aafc6e531ac371cceaa66f6e7769047ea 100644 --- a/go-apps/meep-iot/sbi/iot-sbi.go +++ b/go-apps/meep-iot/sbi/iot-sbi.go @@ -123,18 +123,57 @@ type ImplSpecificInfo struct { DownlinkTopics []string } +type TrafficRuleDescriptor struct { + TrafficRuleId string + FilterType string + Priority int32 + TrafficFilter []TrafficFilter + Action string + DstInterface *InterfaceDescriptor +} + +type InterfaceDescriptor struct { + InterfaceType string + //TunnelInfo *TunnelInfo FSCOM Not supported + SrcMACAddress string + DstMACAddress string + DstIPAddress string +} + +type TrafficFilter struct { + SrcAddress []string + DstAddress []string + SrcPort []string + DstPort []string + Protocol []string + Tag []string + Uri []string + PacketLabel []string + SrcTunnelAddress []string + TgtTunnelAddress []string + SrcTunnelPort []string + DstTunnelPort []string + QCI int32 + TC int32 +} + +type KeyValuePair struct { + Key string + Value string +} + type DeviceInfo struct { DeviceAuthenticationInfo string - //DeviceMetadata []KeyValuePair - Gpsi string - Pei string - Supi string - Msisdn string - Imei string - Imsi string - Iccid string - DeviceId string - //RequestedMecTrafficRule []TrafficRuleDescriptor + DeviceMetadata []KeyValuePair + Gpsi string + Pei string + Supi string + Msisdn string + Imei string + Imsi string + Iccid string + DeviceId string + RequestedMecTrafficRule []TrafficRuleDescriptor RequestedIotPlatformId string RequestedUserTransportId string //DeviceSpecificMessageFormats *DeviceSpecificMessageFormats @@ -380,6 +419,27 @@ func GetDevice(deviceId string) (device DeviceInfo, err error) { return device, nil } +func CreateDevice(device DeviceInfo) (deviceResp DeviceInfo, err error) { + log.Info(">>> sbi.CreateDevice: ", device) + + d := convertDeviceInfoToIotMgr(device) + dev, err := sbi.iotMgr.CreateDevice(d) + if err != nil { + return deviceResp, err + } + deviceResp = convertDeviceInfoFromIotMgr(dev) + + return deviceResp, nil +} + +func DeleteDevice(deviceId string) (err error) { + log.Info(">>> sbi.DeleteDevice: ", deviceId) + + err = sbi.iotMgr.DeleteDevice(deviceId) + + return err +} + func convertIotPlatformInfoToIotMgr(val IotPlatformInfo) (item tm.IotPlatformInfo) { item.IotPlatformId = val.IotPlatformId item.Enabled = val.Enabled @@ -479,6 +539,13 @@ func convertDeviceInfoFromIotMgr(dev tm.DeviceInfo) (device DeviceInfo) { ClientCertificate: dev.ClientCertificate, Enabled: dev.Enabled, } + if len(dev.DeviceMetadata) != 0 { + device.DeviceMetadata = make([]KeyValuePair, len(dev.DeviceMetadata)) + for i, k := range dev.DeviceMetadata { + device.DeviceMetadata[i] = KeyValuePair{Key: k.Key, Value: k.Value} + } // End of 'for' statement + } + // FIXME FSCOM Add missing fileds (pointers & arrays) //log.Debug("convertDeviceInfoFromIotMgr: device: ", device) return device @@ -489,25 +556,33 @@ func convertDeviceInfosFromIotMgr(devicesList []tm.DeviceInfo) (devices []Device devices = make([]DeviceInfo, len(devicesList)) for idx, item := range devicesList { // FIXME FSCOM Add Filter - var device = DeviceInfo{ - DeviceAuthenticationInfo: item.DeviceAuthenticationInfo, - Gpsi: item.Gpsi, - Pei: item.Pei, - Supi: item.Supi, - Msisdn: item.Msisdn, - Imei: item.Imei, - Imsi: item.Imsi, - Iccid: item.Iccid, - DeviceId: item.DeviceId, - RequestedIotPlatformId: item.RequestedIotPlatformId, - RequestedUserTransportId: item.RequestedUserTransportId, - ClientCertificate: item.ClientCertificate, - Enabled: item.Enabled, - } - // FIXME FSCOM Add missing fileds (pointers & arrays) - devices[idx] = device + devices[idx] = convertDeviceInfoFromIotMgr(item) } // End of 'for' statement //log.Debug("convertDeviceInfosFromIotMgr: devices: ", devices) return devices, nil } + +func convertDeviceInfoToIotMgr(dev DeviceInfo) (device tm.DeviceInfo) { + //log.Debug(">>> convertDeviceInfoToIotMgr") + + device = tm.DeviceInfo{ + DeviceAuthenticationInfo: dev.DeviceAuthenticationInfo, + Gpsi: dev.Gpsi, + Pei: dev.Pei, + Supi: dev.Supi, + Msisdn: dev.Msisdn, + Imei: dev.Imei, + Imsi: dev.Imsi, + Iccid: dev.Iccid, + DeviceId: dev.DeviceId, + RequestedIotPlatformId: dev.RequestedIotPlatformId, + RequestedUserTransportId: dev.RequestedUserTransportId, + ClientCertificate: dev.ClientCertificate, + Enabled: dev.Enabled, + } + // FIXME FSCOM Add missing fileds (pointers & arrays) + //log.Debug("convertDeviceInfoToIotMgr: device: ", device) + + return device +} diff --git a/go-apps/meep-iot/server/meep-iot.go b/go-apps/meep-iot/server/meep-iot.go index 2b403d0271bfc3aee7cc8eff072b865f2d438370..ab97eba47c09affcbdc0a315b9e34500d34272bc 100644 --- a/go-apps/meep-iot/server/meep-iot.go +++ b/go-apps/meep-iot/server/meep-iot.go @@ -21,6 +21,7 @@ import ( "encoding/json" "errors" "fmt" + "io/ioutil" "net/http" "net/url" "os" @@ -810,7 +811,21 @@ func registerediotplatformsPOST(w http.ResponseWriter, r *http.Request) { func registereddevicesByIdDELETE(w http.ResponseWriter, r *http.Request) { log.Debug(">>> registereddevicesByIdDELETE: ", r) - errHandlerProblemDetails(w, "Not implemented yet", http.StatusBadRequest) + w.Header().Set("Content-Type", "application/json; charset=UTF-8") + + vars := mux.Vars(r) + log.Debug("registereddevicesByIdDELETE: vars: ", vars) + + registeredDeviceIdParamStr := vars["registeredDeviceId"] + log.Debug("registereddevicesByIdDELETE: registeredDeviceIdParamStr: ", registeredDeviceIdParamStr) + + err := sbi.DeleteDevice(registeredDeviceIdParamStr) + if err != nil { + errHandlerProblemDetails(w, err.Error(), http.StatusNotFound) + return + } + + w.WriteHeader(http.StatusNoContent) } func registereddevicesByIdGET(w http.ResponseWriter, r *http.Request) { @@ -916,7 +931,58 @@ func applyFiltering(devicesList []sbi.DeviceInfo, filter []string) (devices []De func registereddevicesPOST(w http.ResponseWriter, r *http.Request) { log.Debug(">>> registereddevicesPOST: ", r) - errHandlerProblemDetails(w, "Not implemented yet", http.StatusBadRequest) + // Read JSON input stream provided in the Request, and stores it in the bodyBytes as bytes + var registeredDevicesRegisteredDeviceIdBody RegisteredDevicesRegisteredDeviceIdBody + bodyBytes, _ := ioutil.ReadAll(r.Body) + // Unmarshal function to converts a JSON-formatted string into a SubscriptionCommon struct and store it in extractSubType + err := json.Unmarshal(bodyBytes, ®isteredDevicesRegisteredDeviceIdBody) + if err != nil { + log.Error(err.Error()) + errHandlerProblemDetails(w, err.Error(), http.StatusInternalServerError) + return + } else if registeredDevicesRegisteredDeviceIdBody.DeviceInfo == nil { + err = errors.New("Failed to decode body") + errHandlerProblemDetails(w, err.Error(), http.StatusInternalServerError) + return + } + deviceInfo := *registeredDevicesRegisteredDeviceIdBody.DeviceInfo + log.Info("registereddevicesPOST: ", deviceInfo) + + // Sanity checks + if len(deviceInfo.DeviceId) == 0 { + err = errors.New("DeviceId field shall be present") + errHandlerProblemDetails(w, err.Error(), http.StatusBadRequest) + return + } + if len(deviceInfo.RequestedMecTrafficRule) == 0 { + if len(deviceInfo.RequestedIotPlatformId) == 0 && len(deviceInfo.RequestedUserTransportId) == 0 { + err = errors.New("Invalid traffic rule provided") + errHandlerProblemDetails(w, err.Error(), http.StatusBadRequest) + return + } + // Traffic rule provided by either RequestedIotPlatformId or RequestedUserTransportId + } // else Traffic rule provided by RequestedMecTrafficRule + + // Process the request + dev := convertDeviceInfoToSbi(deviceInfo) + deviceInfoResp, err := sbi.CreateDevice(dev) + if err != nil { + log.Error(err.Error()) + errHandlerProblemDetails(w, err.Error(), http.StatusInternalServerError) + return + } + log.Info("registereddevicesPOST: deviceInfoResp: ", deviceInfoResp) + + jsonResponse, err := json.Marshal(deviceInfoResp) + if err != nil { + log.Error(err.Error()) + errHandlerProblemDetails(w, err.Error(), http.StatusInternalServerError) + return + } + log.Info("registereddevicesPOST: jsonResponse: ", string(jsonResponse)) + + w.WriteHeader(http.StatusOK) + fmt.Fprint(w, string(jsonResponse)) } func validateQueryParams(params url.Values, validParams []string) error { @@ -1137,6 +1203,13 @@ func convertDeviceInfoFromSbi(dev sbi.DeviceInfo) (device DeviceInfo) { ClientCertificate: dev.ClientCertificate, Enabled: dev.Enabled, } + if len(dev.DeviceMetadata) != 0 { + device.DeviceMetadata = make([]KeyValuePair, len(dev.DeviceMetadata)) + for i, k := range dev.DeviceMetadata { + device.DeviceMetadata[i] = KeyValuePair{Key: k.Key, Value: k.Value} + } // End of 'for' statement + } + // FIXME FSCOM Add missing fileds (pointers & arrays) //log.Debug("convertDeviceInfosFromSbi: devices: ", devices) return device @@ -1145,23 +1218,7 @@ func convertDeviceInfoFromSbi(dev sbi.DeviceInfo) (device DeviceInfo) { func convertDeviceInfosFromSbi(devicesList []sbi.DeviceInfo) (devices []DeviceInfo, err error) { devices = make([]DeviceInfo, len(devicesList)) for idx, item := range devicesList { // FIXME FSCOM Add Filter - var device = DeviceInfo{ - DeviceAuthenticationInfo: item.DeviceAuthenticationInfo, - Gpsi: item.Gpsi, - Pei: item.Pei, - Supi: item.Supi, - Msisdn: item.Msisdn, - Imei: item.Imei, - Imsi: item.Imsi, - Iccid: item.Iccid, - DeviceId: item.DeviceId, - RequestedIotPlatformId: item.RequestedIotPlatformId, - RequestedUserTransportId: item.RequestedUserTransportId, - ClientCertificate: item.ClientCertificate, - Enabled: item.Enabled, - } - // FIXME FSCOM Add missing fileds (pointers & arrays) - devices[idx] = device + devices[idx] = convertDeviceInfoFromSbi(item) } // End of 'for' statement //log.Debug("convertDeviceInfosFromSbi: devices: ", devices) @@ -1213,3 +1270,25 @@ func convertDeviceInfosFromSbi_with_filter(devicesList []sbi.DeviceInfo, filter return devices, nil } + +func convertDeviceInfoToSbi(dev DeviceInfo) (device sbi.DeviceInfo) { + device = sbi.DeviceInfo{ + DeviceAuthenticationInfo: dev.DeviceAuthenticationInfo, + Gpsi: dev.Gpsi, + Pei: dev.Pei, + Supi: dev.Supi, + Msisdn: dev.Msisdn, + Imei: dev.Imei, + Imsi: dev.Imsi, + Iccid: dev.Iccid, + DeviceId: dev.DeviceId, + RequestedIotPlatformId: dev.RequestedIotPlatformId, + RequestedUserTransportId: dev.RequestedUserTransportId, + ClientCertificate: dev.ClientCertificate, + Enabled: dev.Enabled, + } + // FIXME FSCOM Add missing fileds (pointers & arrays) + //log.Debug("convertDeviceInfosFromSbi: devices: ", devices) + + return device +} diff --git a/go-packages/meep-iot-mgr/iot-mgr.go b/go-packages/meep-iot-mgr/iot-mgr.go index 913af8812d0320c372efcb15b5bc6a6cc304c7ec..601c463fd3bf407f6a6d441cd64d3c04a19b9fbe 100644 --- a/go-packages/meep-iot-mgr/iot-mgr.go +++ b/go-packages/meep-iot-mgr/iot-mgr.go @@ -17,28 +17,16 @@ package iotmgr import ( - "encoding/json" "errors" - "fmt" - "io" - "io/ioutil" - "net/http" - "strconv" - "strings" - "sync" "time" log "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-logger" - - uuid "github.com/google/uuid" - "github.com/gorilla/mux" ) // IOT Manager type IotMgr struct { name string namespace string - mutex sync.Mutex } type IotPlatformInfo struct { @@ -107,40 +95,72 @@ type SensorCharacteristic struct { CharacteristicUnitOfMeasure *string } +type TrafficRuleDescriptor struct { + TrafficRuleId string + FilterType string + Priority int32 + TrafficFilter []TrafficFilter + Action string + DstInterface *InterfaceDescriptor +} + +type InterfaceDescriptor struct { + InterfaceType string + //TunnelInfo *TunnelInfo FSCOM Not supported + SrcMACAddress string + DstMACAddress string + DstIPAddress string +} + +type TrafficFilter struct { + SrcAddress []string + DstAddress []string + SrcPort []string + DstPort []string + Protocol []string + Tag []string + Uri []string + PacketLabel []string + SrcTunnelAddress []string + TgtTunnelAddress []string + SrcTunnelPort []string + DstTunnelPort []string + QCI int32 + TC int32 +} + +type KeyValuePair struct { + Key string + Value string +} + type DeviceInfo struct { DeviceAuthenticationInfo string - //DeviceMetadata []KeyValuePair - Gpsi string - Pei string - Supi string - Msisdn string - Imei string - Imsi string - Iccid string - DeviceId string - //RequestedMecTrafficRule []TrafficRuleDescriptor + DeviceMetadata []KeyValuePair + Gpsi string + Pei string + Supi string + Msisdn string + Imei string + Imsi string + Iccid string + DeviceId string + RequestedMecTrafficRule []TrafficRuleDescriptor RequestedIotPlatformId string RequestedUserTransportId string //DeviceSpecificMessageFormats *DeviceSpecificMessageFormats //DownlinkInfo *DownlinkInfo - ClientCertificate string - Enabled bool - SensorIdentifier string - SensorStatusType string - SensorPropertyList []string - SensorCharacteristicList []SensorCharacteristic + ClientCertificate string + Enabled bool } var registeredIotPlatformsMap = map[string]IotPlatformInfo{} // List of discovered IOT Plateform var devicesMap = map[string]DeviceInfo{} // Map device by deviceId var devicesPerPlatformMap = map[string][]string{} // Map deviceIds per platform +var platformPerUserTransportIdMap = map[string][]string{} // Map userTransportId per platform // Timer to refresh devices list for all IoT platform -const refreshTickerExpeary = 10 // 10 seconds - -var mutex sync.Mutex -var wg sync.WaitGroup -var refreshTicker *time.Ticker = nil +const refreshTickerExpeary = 10 // In seconds // Enable profiling const profiling = false @@ -152,13 +172,6 @@ const ( headerContentType = "application/json" ) -// Profiling init -func init() { - if profiling { - profilingTimers = make(map[string]time.Time) - } -} - // NewIotMgr - Creates and initializes a new IOT Traffic Manager func NewIotMgr(name string, namespace string) (tm *IotMgr, err error) { if name == "" { @@ -175,44 +188,26 @@ func NewIotMgr(name string, namespace string) (tm *IotMgr, err error) { tm.namespace = "default" } + tm.init() + return tm, nil } -// DeleteIotMgr - -func (tm *IotMgr) DeleteIotMgr() (err error) { - stopRefreshTicker() - - return nil -} +// Profiling init +func (tm *IotMgr) init() { + if profiling { + profilingTimers = make(map[string]time.Time) + } -func startRefreshTicker() { - log.Debug("Starting refresh loop") - refreshTicker = time.NewTicker(refreshTickerExpeary * time.Second) - go func() { - for range refreshTicker.C { - // Refresh the list of devices - wg.Add(1) - err := populateDevicesPerIotPlatforms() - if err != nil { - log.Error(err) - } - wg.Done() - } - }() + registeredIotPlatformsMap = make(map[string]IotPlatformInfo, 0) + devicesMap = make(map[string]DeviceInfo, 0) + devicesPerPlatformMap = make(map[string][]string, 0) + platformPerUserTransportIdMap = make(map[string][]string, 0) } -func stopRefreshTicker() { - if refreshTicker != nil { - // Refresh the list of devices - wg.Add(1) - refreshTicker.Stop() - refreshTicker = nil - registeredIotPlatformsMap = nil - devicesMap = nil - devicesPerPlatformMap = nil - wg.Done() - log.Debug("Refresh loop stopped") - } +// DeleteIotMgr - +func (tm *IotMgr) DeleteIotMgr() (err error) { + return nil } func (tm *IotMgr) RegisterIotPlatformInfo(iotPlatformInfo IotPlatformInfo) (err error) { @@ -225,10 +220,6 @@ func (tm *IotMgr) RegisterIotPlatformInfo(iotPlatformInfo IotPlatformInfo) (err registeredIotPlatformsMap[iotPlatformInfo.IotPlatformId] = iotPlatformInfo } // else, Skip disabled platform - if len(registeredIotPlatformsMap) == 1 { - startRefreshTicker() - } - if profiling { now := time.Now() log.Debug("RegisterIotPlatformInfo: ", now.Sub(profilingTimers["RegisterIotPlatformInfo"])) @@ -249,12 +240,18 @@ func (tm *IotMgr) DeregisterIotPlatformInfo(iotPlatformId string) (err error) { delete(devicesMap, dev) } // End of 'for' statement delete(devicesPerPlatformMap, iotPlatformId) + log.Info("DeregisterIotPlatformInfo: platformPerUserTransportIdMap (before): ", iotPlatformId) + for _, rule := range platformPerUserTransportIdMap { + for idx, pltf := range rule { + if pltf == iotPlatformId { + rule = append(rule[:idx], rule[idx+1:]...) + } + } // End of 'for' statement + } // End of 'for' statement + log.Info("DeregisterIotPlatformInfo: platformPerUserTransportIdMap (after): ", iotPlatformId) } if _, ok := registeredIotPlatformsMap[iotPlatformId]; ok { delete(registeredIotPlatformsMap, iotPlatformId) - if len(registeredIotPlatformsMap) == 0 { - stopRefreshTicker() - } } if profiling { @@ -271,9 +268,6 @@ func (tm *IotMgr) GetDevices() (devices []DeviceInfo, err error) { log.Info(">>> GetDevices") - wg.Wait() - log.Info("GetDevices: After Synchro") - devices = make([]DeviceInfo, 0) if len(registeredIotPlatformsMap) == 0 { return devices, nil @@ -300,9 +294,6 @@ func (tm *IotMgr) GetDevice(deviceId string) (device DeviceInfo, err error) { log.Info(">>> GetDevice: deviceId: ", deviceId) - wg.Wait() - log.Info("GetDevice: After Synchro") - if val, ok := devicesMap[deviceId]; !ok { err = errors.New("Wrong Device identifier") return device, err @@ -319,235 +310,104 @@ func (tm *IotMgr) GetDevice(deviceId string) (device DeviceInfo, err error) { return device, nil } -/* - * func populateDevicesPerIotPlatforms IoT devices for all registered Iot platform - * @return {struct} nil on success, error otherwise - */ -func populateDevicesPerIotPlatforms() error { - - mutex.Lock() - defer mutex.Unlock() +func (tm *IotMgr) CreateDevice(device DeviceInfo) (deviceResp DeviceInfo, err error) { + log.Info(">>> CreateDevice: ", device) - if profiling { - profilingTimers["populateDevicesPerIotPlatforms"] = time.Now() + // RequestedMecTrafficRule is not supported yet + if len(device.RequestedMecTrafficRule) != 0 { + err = errors.New("Unsupported traffic rule provided") + log.Error(err.Error()) + return deviceResp, err } - - if len(registeredIotPlatformsMap) == 0 { - return nil + if len(device.RequestedIotPlatformId) != 0 { + deviceResp, err = tm.createDeviceWithIotPlatformId(device, device.RequestedIotPlatformId) + } else { + deviceResp, err = tm.createDeviceWithRequestedUserTransportId(device, device.RequestedUserTransportId) } - - // Refresh the list of devices for all registered Iot platform - for _, iotPlatform := range registeredIotPlatformsMap { - //log.Debug("populateDevicesPerIotPlatforms: processing: ", iotPlatform.IotPlatformId) - err := populateDevices(iotPlatform) - if err != nil { - log.Error("populateDevicesPerIotPlatforms: ", err) - continue - } - } // End of 'for' statement - - if profiling { - now := time.Now() - log.Debug("populateDevicesPerIotPlatforms: ", now.Sub(profilingTimers["populateDevicesPerIotPlatforms"])) + if err != nil { + log.Error(err.Error()) + return deviceResp, err } + log.Info("CreateDevice: deviceResp: ", deviceResp) - return nil + return deviceResp, nil } -/* - * func PopulateDevices IoT devices for the specified Iot platform - * @param {string} iotPlatformId contains the IoT platform identifier - * @return {struct} nil on success, error otherwise - */ -func populateDevices(iotPlatformInfo IotPlatformInfo) error { +func (tm *IotMgr) DeleteDevice(deviceId string) (err error) { if profiling { - profilingTimers["populateDevices"] = time.Now() + profilingTimers["DeleteDevice"] = time.Now() } - log.Info(">>> populateDevices: iotPlatformId=", iotPlatformInfo.IotPlatformId) - - // 1. Get the list of the AE - // Build the URL - t := registeredIotPlatformsMap[iotPlatformInfo.IotPlatformId].CustomServicesTransportInfo[0] - //log.Debug("populateDevices: t.Endpoint.Addresses[0]=", t.Endpoint.Addresses[0]) - url := "http://" + t.Endpoint.Addresses[0].Host + ":" + strconv.Itoa(int(t.Endpoint.Addresses[0].Port)) + "/" + t.Name - //log.Debug("populateDevices: url=", url) - // Build the headers - var headers = http.Header{} - headers["Accept"] = []string{headerAccept} - headers["ContentType"] = []string{headerContentType} - headers["X-M2M-Origin"] = []string{"CAdmin"} - headers["X-M2M-RI"] = []string{uuid.New().String()} - headers["X-M2M-RVI"] = []string{t.Version} - // Build the queries - queries := map[string]string{} - queries["fu"] = "1" // Filter usage - queries["ty"] = "4" // Filter on oneM2M CIN for device - // Send the request - response, err := sendRequest("GET", url, headers, nil, nil, queries, 200) - if err != nil { - log.Error("populateDevices: ", err.Error()) - return err - } - //log.Debug("populateDevices: response: ", string(response)) + log.Info(">>> DeleteDevice: device: ", deviceId) - var oneM2M_uril map[string][]string - err = json.Unmarshal(response, &oneM2M_uril) - if err != nil { - log.Error("populateDevices: ", err.Error()) - return err - } - //log.Debug("populateDevices: oneM2M_uril: ", len(oneM2M_uril)) - //log.Debug(oneM2M_uril) - if _, ok := oneM2M_uril["m2m:uril"]; !ok { - err := errors.New("populateDevices: Key not found: m2m:uril") + if _, ok := devicesMap[deviceId]; !ok { + err = errors.New("Invalid device identifier") log.Error(err.Error()) return err } - // Loop for each CIN and build the device list - for _, v := range oneM2M_uril["m2m:uril"] { - //log.Debug("populateDevices: Processing key: ", v) - - url := "http://" + t.Endpoint.Addresses[0].Host + ":" + strconv.Itoa(int(t.Endpoint.Addresses[0].Port)) + "/" + v - //log.Debug("populateDevices: url=", url) - // Build the headers - var headers = http.Header{} - headers["Accept"] = []string{headerAccept} - headers["ContentType"] = []string{headerContentType} - headers["X-M2M-Origin"] = []string{"CAdmin"} - headers["X-M2M-RI"] = []string{uuid.New().String()} - headers["X-M2M-RVI"] = []string{t.Version} - // Build the queries - queries := map[string]string{} - queries["fu"] = "2" // Filter usage - // Send the request - response, err := sendRequest("GET", url, headers, nil, nil, queries, 200) - if err != nil { - log.Error("populateDevices: ", err.Error()) - return err - } - //log.Debug("populateDevices: response: ", string(response)) - var oneM2M_cin map[string]map[string]interface{} - err = json.Unmarshal(response, &oneM2M_cin) - if err != nil { - log.Error("populateDevices: ", err.Error()) - continue - } - //log.Debug("populateDevices: type(oneM2M_cin): ", reflect.TypeOf(oneM2M_cin)) - //log.Debug("populateDevices: len(oneM2M_cin): ", len(oneM2M_cin)) - //log.Debug("populateDevices: oneM2M_cin: ", oneM2M_cin) - for _, m := range oneM2M_cin { - ////log.Debug("==> ", i, " value is ", m) - var device = DeviceInfo{} - device.RequestedIotPlatformId = iotPlatformInfo.IotPlatformId - device.RequestedUserTransportId = registeredIotPlatformsMap[iotPlatformInfo.IotPlatformId].UserTransportInfo[0].Id - device.Enabled = true - - // m is a map[string]interface. - // loop over keys and values in the map. - for k, v := range m { - //log.Debug(k, " value is ", v) - //log.Debug("populateDevices: type(v): ", reflect.TypeOf(v)) - if k == "rn" { - if item, ok := v.(string); ok { - device.DeviceId = item - } else { - log.Error("populateDevices: Failed to process ", k) - } - } else if k == "ri" { - if item, ok := v.(string); ok { - device.SensorIdentifier = item - } else { - log.Error("populateDevices: Failed to process ", k) - } - } else if k == "ty" { - if item, ok := v.(float64); ok { - device.SensorStatusType = strconv.FormatFloat(item, 'f', -1, 64) - } else { - log.Error("populateDevices: Failed to process ", k) - } - } else { // default: if k == "lt" || k == "et" || k == "ct" || k == "st" || k == "pi" || k == "lbl" { - if item, ok := v.(string); ok { - device.SensorCharacteristicList = append( - device.SensorCharacteristicList, - SensorCharacteristic{ - CharacteristicName: k, - CharacteristicValue: string(item), - CharacteristicUnitOfMeasure: nil, - }) - } else if item, ok := v.(float64); ok { - device.SensorCharacteristicList = append( - device.SensorCharacteristicList, - SensorCharacteristic{ - CharacteristicName: k, - CharacteristicValue: strconv.FormatFloat(item, 'f', -1, 64), - CharacteristicUnitOfMeasure: nil, - }) - } else if item, ok := v.([]string); ok { - device.SensorCharacteristicList = append( - device.SensorCharacteristicList, - SensorCharacteristic{ - CharacteristicName: k, - CharacteristicValue: strings.Join(item, ","), - CharacteristicUnitOfMeasure: nil, - }) - } else { - log.Error("populateDevices: Failed to process ", k) - } - } - } // End of 'for' loop - log.Info("populateDevices: device: ", device) - devicesMap[device.DeviceId] = device - devicesPerPlatformMap[device.RequestedIotPlatformId] = append(devicesPerPlatformMap[device.RequestedIotPlatformId], device.DeviceId) - } // End of 'for' loop - } // End of 'for' statement - log.Info("populateDevices: devicesMap: ", devicesMap) - log.Info("populateDevices: devicesPerPlatformMap: ", devicesPerPlatformMap) + device := devicesMap[deviceId] + // Remove the list of the devices for this IoT platform + if val, ok := devicesPerPlatformMap[device.RequestedIotPlatformId]; ok { + // Free resource from devicesMap map + log.Info("DeleteDevice: devicesPerPlatformMap (before): ", devicesPerPlatformMap) + for idx, devId := range val { + if devId == device.DeviceId { + val = append(val[:idx], val[idx+1:]...) + break + } + } // End of 'for' statement + } + log.Info("DeleteDevice: devicesPerPlatformMap (after): ", devicesPerPlatformMap) + // Free resource from devicesMap map + log.Info("DeleteDevice: devicesMap (before): ", devicesMap) + delete(devicesMap, device.DeviceId) + log.Info("DeleteDevice: devicesMap (after): ", devicesMap) if profiling { now := time.Now() - log.Debug("populateDevices: ", now.Sub(profilingTimers["populateDevices"])) + log.Debug("DeleteDevice: ", now.Sub(profilingTimers["DeleteDevice"])) } return nil } -func sendRequest(method string, url string, headers http.Header, body io.Reader, vars map[string]string, query map[string]string, code int) ([]byte, error) { - log.Debug(">>> sendRequest: url: ", url) - log.Debug(">>> sendRequest: headers: ", headers) +func (tm *IotMgr) createDeviceWithIotPlatformId(device DeviceInfo, requestedIotPlatformId string) (deviceResp DeviceInfo, err error) { + log.Info(">>> createDeviceWithIotPlatformId: ", device) - req, err := http.NewRequest(method, url, body) - if err != nil || req == nil { - return nil, err - } - if vars != nil { - req = mux.SetURLVars(req, vars) + // Sanity checks + if _, ok := registeredIotPlatformsMap[requestedIotPlatformId]; !ok { + err = errors.New("Invalid IotPlatform identifier") + return deviceResp, err } - if query != nil { - q := req.URL.Query() - for k, v := range query { - q.Add(k, v) - } - req.URL.RawQuery = q.Encode() + if _, ok := devicesMap[device.DeviceId]; ok { + err = errors.New("Device already exist") + return deviceResp, err } - req.Header = headers - req.Close = true - rr, err := http.DefaultClient.Do(req) - if err != nil { - return nil, err - } + devicesMap[device.DeviceId] = device + devicesPerPlatformMap[device.DeviceId] = append(devicesPerPlatformMap[device.DeviceId], requestedIotPlatformId) + platformPerUserTransportIdMap[requestedIotPlatformId] = append(platformPerUserTransportIdMap[requestedIotPlatformId], device.RequestedUserTransportId) - // Check the status code is what we expect. - if status := rr.StatusCode; status != code { - s := fmt.Sprintf("Wrong status code - got %v want %v", status, code) - return nil, errors.New(s) + deviceResp = device + log.Debug("createDeviceWithIotPlatformId: deviceResp: ", deviceResp) + + return deviceResp, nil +} + +func (tm *IotMgr) createDeviceWithRequestedUserTransportId(device DeviceInfo, requestedUserTransportId string) (deviceResp DeviceInfo, err error) { + log.Info(">>> createDeviceWithRequestedUserTransportId: ", device) + + if val, ok := platformPerUserTransportIdMap[requestedUserTransportId]; ok { + deviceResp, err = tm.createDeviceWithIotPlatformId(device, val[0]) + } else { + err = errors.New("Invalid UserTransportId") } - responseData, err := ioutil.ReadAll(rr.Body) if err != nil { - return nil, err + log.Error("createDeviceWithIotPlatformId: ", err.Error()) + return deviceResp, err } + log.Info("createDeviceWithIotPlatformId: deviceResp: ", deviceResp) - return responseData, nil + return deviceResp, nil } diff --git a/go-packages/meep-iot-mgr/iot-mgr_test.go b/go-packages/meep-iot-mgr/iot-mgr_test.go new file mode 100644 index 0000000000000000000000000000000000000000..84ca215aa4d2d3c1ae0bff247d0b87452313fda6 --- /dev/null +++ b/go-packages/meep-iot-mgr/iot-mgr_test.go @@ -0,0 +1,615 @@ +/* + * Copyright (c) 2025 The AdvantEDGE Authors + * + * 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 ance "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 iotmgr + +import ( + "fmt" + "testing" + + log "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-logger" +) + +const tmName = "meep-iot" +const tmNamespace = "sandboxtest" + +func TestNewIotMgr(t *testing.T) { + fmt.Println("--- ", t.Name()) + log.MeepTextLogInit(t.Name()) + + // Invalid Connector + fmt.Println("Invalid IOT Asset Manager") + tm, err := NewIotMgr("", tmNamespace) + if err == nil || tm != nil { + t.Fatalf("DB connection should have failed") + } + + // Valid Connector + fmt.Println("Create valid IOT Asset Manager") + tm, err = NewIotMgr(tmName, tmNamespace) + if err != nil || tm == nil { + t.Fatalf("Failed to create IOT Asset Manager") + } + + // Cleanup + err = tm.DeleteIotMgr() + if err != nil { + t.Fatalf("Failed to cleanup IOT Asset Manager") + } +} + +func TestRegisterIotPlatformInfo(t *testing.T) { + fmt.Println("--- ", t.Name()) + log.MeepTextLogInit(t.Name()) + + // Valid Connector + fmt.Println("Create valid IOT Asset Manager") + tm, err := NewIotMgr(tmName, tmNamespace) + if err != nil || tm == nil { + t.Fatalf("Failed to create IOT Asset Manager") + } + + // Set a valid platform + var adresses = []Addresses{} + adresses = append(adresses, Addresses{ + Host: "172.29.10.56", + Port: 1883, + }) + var endpoint = EndPointInfo{ + Addresses: adresses, + } + var userTransportInfo = []MbTransportInfo{} + userTransportInfo = append(userTransportInfo, MbTransportInfo{ + Id: "d5673793-c55c-4969-b5bc-2121f84b9f8d", + Name: "MQTT", + Description: "MQTT", + Protocol: "MQTT", + Version: "2", + Endpoint: &endpoint, + }) + var adresses_1 = []Addresses{} + adresses_1 = append(adresses_1, Addresses{ + Host: "172.29.10.20", + Port: 31110, + }) + var customServicesTransportInfo = []TransportInfo{} + var endPointInfo_1 = EndPointInfo{ + Addresses: adresses_1, + } + customServicesTransportInfo = append(customServicesTransportInfo, TransportInfo{ + Id: "2ddb713c-2b41-4ded-a7ad-a5a047c5df13", + Name: "/laboai-acme-ic-cse", + Description: "ACME oneM2M CSE", + Protocol: "REST_HTTP", + Version: "4", + Endpoint: &endPointInfo_1, + }) + var iotPlatformInfo = IotPlatformInfo{ + IotPlatformId: "523f2df1-8927-429f-906c-56ba92d13762", + UserTransportInfo: userTransportInfo, + CustomServicesTransportInfo: customServicesTransportInfo, + Enabled: true, + } + fmt.Println("Create an IotPlatformInfo: ", iotPlatformInfo) + err = tm.RegisterIotPlatformInfo(iotPlatformInfo) + if err != nil { + t.Fatalf("Failed to register new IoT platform") + } + + // Cleanup + err = tm.DeregisterIotPlatformInfo(iotPlatformInfo.IotPlatformId) + if err != nil { + t.Fatalf("Failed to register new IoT platform") + } + err = tm.DeleteIotMgr() + if err != nil { + t.Fatalf("Failed to cleanup IOT Asset Manager") + } + + // t.Fatalf("DONE") +} + +func TestCreateDeviceInfo(t *testing.T) { + fmt.Println("--- ", t.Name()) + log.MeepTextLogInit(t.Name()) + + // Valid Connector + fmt.Println("Create valid IOT Asset Manager") + tm, err := NewIotMgr(tmName, tmNamespace) + if err != nil || tm == nil { + t.Fatalf("Failed to create IOT Asset Manager") + } + + // Set a valid platform + fmt.Println("Create an IotPlatformInfo") + iotPlatformInfo, err := registerIotPltf(tm) + if err != nil { + t.Fatalf("Failed to register new IoT platform") + } + + // Create a new basic device + fmt.Println("Create a new device") + requestedIotPlatformId := iotPlatformInfo.IotPlatformId + var device = DeviceInfo{ + RequestedIotPlatformId: requestedIotPlatformId, + DeviceId: requestedIotPlatformId, + Enabled: true, + } + device, err = tm.CreateDevice(device) + if err != nil { + t.Fatalf("Failed to create a new device") + } + + // Cleanup + _ = tm.DeleteDevice(device.DeviceId) + err = tm.DeregisterIotPlatformInfo(iotPlatformInfo.IotPlatformId) + if err != nil { + t.Fatalf("Failed to register new IoT platform") + } + err = tm.DeleteIotMgr() + if err != nil { + t.Fatalf("Failed to cleanup IOT Asset Manager") + } + + // t.Fatalf("DONE") +} + +func TestCreateDeviceInfoFail(t *testing.T) { + fmt.Println("--- ", t.Name()) + log.MeepTextLogInit(t.Name()) + + // Valid Connector + fmt.Println("Create valid IOT Asset Manager") + tm, err := NewIotMgr(tmName, tmNamespace) + if err != nil || tm == nil { + t.Fatalf("Failed to create IOT Asset Manager") + } + + // Set a valid platform + fmt.Println("Create an IotPlatformInfo") + iotPlatformInfo, err := registerIotPltf(tm) + if err != nil { + t.Fatalf("Failed to register new IoT platform") + } + + // Create an invalid new basic device + fmt.Println("Create an IotPlatformInfo: ", iotPlatformInfo) + requestedIotPlatformId := iotPlatformInfo.IotPlatformId + var device = DeviceInfo{ + RequestedIotPlatformId: "12345", // Invalid IotPlatformId + DeviceId: requestedIotPlatformId, + Enabled: true, + } + device, err = tm.CreateDevice(device) + if err == nil { + t.Fatalf("Creation of an invalid new device shall fail") + } + + // Cleanup + err = tm.DeregisterIotPlatformInfo(iotPlatformInfo.IotPlatformId) + if err != nil { + t.Fatalf("Failed to register new IoT platform") + } + err = tm.DeleteIotMgr() + if err != nil { + t.Fatalf("Failed to cleanup IOT Asset Manager") + } + + // t.Fatalf("DONE") +} + +func TestDeleteDeviceInfo(t *testing.T) { + fmt.Println("--- ", t.Name()) + log.MeepTextLogInit(t.Name()) + + // Valid Connector + fmt.Println("Create valid IOT Asset Manager") + tm, err := NewIotMgr(tmName, tmNamespace) + if err != nil || tm == nil { + t.Fatalf("Failed to create IOT Asset Manager") + } + + // Set a valid platform + fmt.Println("Create an IotPlatformInfo") + iotPlatformInfo, err := registerIotPltf(tm) + if err != nil { + t.Fatalf("Failed to register new IoT platform") + } + + // Create a new basic device + fmt.Println("Create a new device") + requestedIotPlatformId := iotPlatformInfo.IotPlatformId + var device = DeviceInfo{ + RequestedIotPlatformId: requestedIotPlatformId, + DeviceId: requestedIotPlatformId, + Enabled: true, + } + device, err = tm.CreateDevice(device) + if err != nil { + t.Fatalf("Failed to create a new device") + } + + err = tm.DeleteDevice(device.DeviceId) + if err != nil { + t.Fatalf("Failed to delete a device") + } + + // Cleanup + err = tm.DeregisterIotPlatformInfo(iotPlatformInfo.IotPlatformId) + if err != nil { + t.Fatalf("Failed to register new IoT platform") + } + err = tm.DeleteIotMgr() + if err != nil { + t.Fatalf("Failed to cleanup IOT Asset Manager") + } + + // t.Fatalf("DONE") +} + +func TestDeleteDeviceInfoFail(t *testing.T) { + fmt.Println("--- ", t.Name()) + log.MeepTextLogInit(t.Name()) + + // Valid Connector + fmt.Println("Create valid IOT Asset Manager") + tm, err := NewIotMgr(tmName, tmNamespace) + if err != nil || tm == nil { + t.Fatalf("Failed to create IOT Asset Manager") + } + + // Set a valid platform + fmt.Println("Create an IotPlatformInfo") + iotPlatformInfo, err := registerIotPltf(tm) + if err != nil { + t.Fatalf("Failed to register new IoT platform") + } + + err = tm.DeleteDevice("12345") + if err == nil { + t.Fatalf("Deletion of an invalide device shall fail") + } + + // Cleanup + err = tm.DeregisterIotPlatformInfo(iotPlatformInfo.IotPlatformId) + if err != nil { + t.Fatalf("Failed to register new IoT platform") + } + err = tm.DeleteIotMgr() + if err != nil { + t.Fatalf("Failed to cleanup IOT Asset Manager") + } + + // t.Fatalf("DONE") +} + +func TestGetDeviceInfo(t *testing.T) { + fmt.Println("--- ", t.Name()) + log.MeepTextLogInit(t.Name()) + + // Valid Connector + fmt.Println("Create valid IOT Asset Manager") + tm, err := NewIotMgr(tmName, tmNamespace) + if err != nil || tm == nil { + t.Fatalf("Failed to create IOT Asset Manager") + } + + // Set a valid platform and create a device + fmt.Println("Create an IotPlatformInfo") + iotPlatformInfo, device, err := registerIotPltfAndCreateDevice(tm) + if err != nil { + t.Fatalf("Failed to register new IoT platform or to create a new device") + } + + // Get a device + fmt.Println("Get a device") + device_rsp, err := tm.GetDevice(device.DeviceId) + if err != nil { + t.Fatalf("GetDevice failed") + } + + // Check the response + if !validate_device_info(device, device_rsp) { + t.Fatalf("Devices mismatch") + } + + fmt.Println("Get a devices") + devices_rsp, err := tm.GetDevices() + if err != nil { + t.Fatalf("GetDevices failed") + } + if len(devices_rsp) != 1 { + t.Fatalf("GetDevices: Unexpected response") + } + + // Check the response + if !validate_device_info(device, devices_rsp[0]) { + t.Fatalf("Devices mismatch") + } + + // Cleanup + _ = tm.DeleteDevice(device.DeviceId) + + _ = tm.DeleteDevice(device.DeviceId) + err = tm.DeregisterIotPlatformInfo(iotPlatformInfo.IotPlatformId) + if err != nil { + t.Fatalf("Failed to register new IoT platform") + } + err = tm.DeleteIotMgr() + if err != nil { + t.Fatalf("Failed to cleanup IOT Asset Manager") + } + + // t.Fatalf("DONE") +} + +func TestGetDeviceInfoFail(t *testing.T) { + fmt.Println("--- ", t.Name()) + log.MeepTextLogInit(t.Name()) + + // Valid Connector + fmt.Println("Create valid IOT Asset Manager") + tm, err := NewIotMgr(tmName, tmNamespace) + if err != nil || tm == nil { + t.Fatalf("Failed to create IOT Asset Manager") + } + + // Get a device + fmt.Println("Get a device") + _, err = tm.GetDevice("12345") + if err == nil { + t.Fatalf("GetDevice shall failed") + } + + // Set a valid platform and create a device + fmt.Println("Create an IotPlatformInfo") + iotPlatformInfo, device, err := registerIotPltfAndCreateDevice(tm) + if err != nil { + t.Fatalf("Failed to register new IoT platform or to create a new device") + } + + // Get a device + fmt.Println("Get a device") + _, err = tm.GetDevice("12345") + if err == nil { + t.Fatalf("GetDevice shall failed") + } + + // Get a device + fmt.Println("Get a device") + device_rsp, err := tm.GetDevice(device.DeviceId) + if err != nil { + t.Fatalf("Failed to create a new device") + } + + // Check the response + if !validate_device_info(device, device_rsp) { + t.Fatalf("Devices mismatch") + } + + // Cleanup + _ = tm.DeleteDevice(device.DeviceId) + + _ = tm.DeleteDevice(device.DeviceId) + err = tm.DeregisterIotPlatformInfo(iotPlatformInfo.IotPlatformId) + if err != nil { + t.Fatalf("Failed to register new IoT platform") + } + err = tm.DeleteIotMgr() + if err != nil { + t.Fatalf("Failed to cleanup IOT Asset Manager") + } + + // t.Fatalf("DONE") +} + +func registerIotPltf(tm *IotMgr) (iotPlatformInfo IotPlatformInfo, err error) { + + // Set a valid platform + var adresses = []Addresses{} + adresses = append(adresses, Addresses{ + Host: "172.29.10.56", + Port: 1883, + }) + var endpoint = EndPointInfo{ + Addresses: adresses, + } + var userTransportInfo = []MbTransportInfo{} + userTransportInfo = append(userTransportInfo, MbTransportInfo{ + Id: "d5673793-c55c-4969-b5bc-2121f84b9f8d", + Name: "MQTT", + Description: "MQTT", + Protocol: "MQTT", + Version: "2", + Endpoint: &endpoint, + }) + var adresses_1 = []Addresses{} + adresses_1 = append(adresses_1, Addresses{ + Host: "172.29.10.20", + Port: 31110, + }) + var customServicesTransportInfo = []TransportInfo{} + var endPointInfo_1 = EndPointInfo{ + Addresses: adresses_1, + } + customServicesTransportInfo = append(customServicesTransportInfo, TransportInfo{ + Id: "2ddb713c-2b41-4ded-a7ad-a5a047c5df13", + Name: "/laboai-acme-ic-cse", + Description: "ACME oneM2M CSE", + Protocol: "REST_HTTP", + Version: "4", + Endpoint: &endPointInfo_1, + }) + iotPlatformInfo = IotPlatformInfo{ + IotPlatformId: "523f2df1-8927-429f-906c-56ba92d13762", + UserTransportInfo: userTransportInfo, + CustomServicesTransportInfo: customServicesTransportInfo, + Enabled: true, + } + err = tm.RegisterIotPlatformInfo(iotPlatformInfo) + if err != nil { + return iotPlatformInfo, err + } + + return iotPlatformInfo, nil +} + +func registerIotPltfAndCreateDevice(tm *IotMgr) (iotPlatformInfo IotPlatformInfo, device DeviceInfo, err error) { + + // Set a valid platform + var adresses = []Addresses{} + adresses = append(adresses, Addresses{ + Host: "172.29.10.56", + Port: 1883, + }) + var endpoint = EndPointInfo{ + Addresses: adresses, + } + var userTransportInfo = []MbTransportInfo{} + userTransportInfo = append(userTransportInfo, MbTransportInfo{ + Id: "d5673793-c55c-4969-b5bc-2121f84b9f8d", + Name: "MQTT", + Description: "MQTT", + Protocol: "MQTT", + Version: "2", + Endpoint: &endpoint, + }) + var adresses_1 = []Addresses{} + adresses_1 = append(adresses_1, Addresses{ + Host: "172.29.10.20", + Port: 31110, + }) + var customServicesTransportInfo = []TransportInfo{} + var endPointInfo_1 = EndPointInfo{ + Addresses: adresses_1, + } + customServicesTransportInfo = append(customServicesTransportInfo, TransportInfo{ + Id: "2ddb713c-2b41-4ded-a7ad-a5a047c5df13", + Name: "/laboai-acme-ic-cse", + Description: "ACME oneM2M CSE", + Protocol: "REST_HTTP", + Version: "4", + Endpoint: &endPointInfo_1, + }) + iotPlatformInfo = IotPlatformInfo{ + IotPlatformId: "523f2df1-8927-429f-906c-56ba92d13762", + UserTransportInfo: userTransportInfo, + CustomServicesTransportInfo: customServicesTransportInfo, + Enabled: true, + } + err = tm.RegisterIotPlatformInfo(iotPlatformInfo) + if err != nil { + return iotPlatformInfo, device, err + } + + // Create a new basic device + fmt.Println("Create a new device") + requestedIotPlatformId := iotPlatformInfo.IotPlatformId + device = DeviceInfo{ + RequestedIotPlatformId: requestedIotPlatformId, + DeviceId: requestedIotPlatformId, + Enabled: true, + } + device, err = tm.CreateDevice(device) + if err != nil { + return iotPlatformInfo, device, err + } + + return iotPlatformInfo, device, nil +} + +func validate_device_info(expected_device DeviceInfo, received_deviceResp DeviceInfo) bool { + if expected_device.DeviceId != received_deviceResp.DeviceId { + fmt.Println("received_deviceResp.DeviceId != DeviceId") + return false + } + if expected_device.Enabled != received_deviceResp.Enabled { + fmt.Println("received_deviceResp.Enabled != Enabled") + return false + } + if expected_device.DeviceAuthenticationInfo != received_deviceResp.DeviceAuthenticationInfo { + fmt.Println("received_deviceResp.DeviceAuthenticationInfo != DeviceAuthenticationInfo") + return false + } + if expected_device.Gpsi != received_deviceResp.Gpsi { + fmt.Println("received_deviceResp.Gpsi != Gpsi") + return false + } + if expected_device.Pei != received_deviceResp.Pei { + fmt.Println("received_deviceResp.Pei != Pei") + return false + } + if expected_device.Supi != received_deviceResp.Supi { + fmt.Println("received_deviceResp.Supi != Supi") + return false + } + if expected_device.Msisdn != received_deviceResp.Msisdn { + fmt.Println("received_deviceResp.Msisdn != Msisdn") + return false + } + if expected_device.Imei != received_deviceResp.Imei { + fmt.Println("received_deviceResp.Imei != Imei") + return false + } + if expected_device.Imsi != received_deviceResp.Imsi { + fmt.Println("received_deviceResp.Imsi != Imsi") + return false + } + if expected_device.Iccid != received_deviceResp.Iccid { + fmt.Println("received_deviceResp.Iccid != Iccid") + return false + } + if expected_device.RequestedIotPlatformId != received_deviceResp.RequestedIotPlatformId { + fmt.Println("received_deviceResp.RequestedIotPlatformId != RequestedIotPlatformId") + return false + } + if expected_device.RequestedUserTransportId != received_deviceResp.RequestedUserTransportId { + fmt.Println("received_deviceResp.RequestedUserTransportId != RequestedUserTransportId") + return false + } + if expected_device.ClientCertificate != received_deviceResp.ClientCertificate { + fmt.Println("received_deviceResp.ClientCertificate != ClientCertificate") + return false + } + if len(expected_device.DeviceMetadata) != len(received_deviceResp.DeviceMetadata) { + fmt.Println("received_deviceResp.DeviceMetadata != DeviceMetadata") + return false + } else { + for i, val := range expected_device.DeviceMetadata { + if val.Key != received_deviceResp.DeviceMetadata[i].Key { + fmt.Println("item #", i, ":received_deviceResp.DeviceMetadata.Key != DeviceMetadata.Key") + return false + } + if val.Value != received_deviceResp.DeviceMetadata[i].Value { + fmt.Println("item #", i, ":received_deviceResp.DeviceMetadata.Value != DeviceMetadata.Value") + return false + + } + } // End of 'for' statement + } + if len(expected_device.RequestedMecTrafficRule) != len(received_deviceResp.RequestedMecTrafficRule) { + fmt.Println("received_deviceResp.RequestedMecTrafficRule != RequestedMecTrafficRule") + return false + } else { + // for i, val := range expected_device.RequestedMecTrafficRule { + // } // End of 'for' statement + // TODO To be continued + //RequestedMecTrafficRule []TrafficRuleDescriptor + } + // TODO To be continued + + return true +}