# Simulate MEC devices using Pandas database import pandas as pd from datetime import datetime, time class mec_database: """ Private properties """ __path__ = "/Users/yanng/Documents/workspace_titan/STF569_Mec/simu/data/" # To be updated according to the local settings __subscribers__ = None __registered_list__ = None __zones__ = None __ue_information_list__ = None __access_point_list__ = None __location_info__ = None __cells__ = None __associated__ = None __subscribions__ = None def __init__(self): """ Default ctor: Open Pandas database. """ self.__zones__ = pd.DataFrame(pd.read_csv(self.__path__ + 'zones.csv', index_col = 'zoneId')) self.__subscribers__ = pd.DataFrame(pd.read_csv(self.__path__ + 'subscribers.csv', index_col = 'address')) self.__ue_information_list__ = pd.DataFrame(pd.read_csv(self.__path__ + 'ue_information_list.csv', index_col = ['appInst', 'ueTag'])) self.__access_point_list__ = pd.DataFrame(pd.read_csv(self.__path__ + 'access_point_list.csv', index_col = 'accessPointId')) self.__location_info__ = pd.DataFrame(pd.read_csv(self.__path__ + 'location_info.csv', index_col = 'accessPointId')) self.__cells__ = pd.DataFrame(pd.read_csv(self.__path__ + 'cells.csv', encoding = 'utf-8', index_col = 'cellId')) self.__associated__ = pd.DataFrame(pd.read_csv(self.__path__ + 'associated.csv', encoding = 'utf-8', index_col = 'cellId')) self.__subscriptions__ = pd.DataFrame(pd.read_csv(self.__path__ + 'subscriptions.csv', encoding = 'utf-8', index_col = 'subscription_id')) #self.dump() # End of __init__ def dump(self): """ Dump database contents. For debug purpose only. """ print("Subscribers: ", self.__subscribers__.head()) print("Zones: ", self.__zones__.head()) print("UEinformation", self.__ue_information_list__.head()) print("AccessPoint: ", self.__access_point_list__.head()) print("LocationInfo: ", self.__location_info__.head()) print("Cells: ", self.__cells__.head()) print("Associated: ", self.__associated__.head()) print("subscriptions: ", self.__subscribions__.head()) # End of dump def __to_accessPoint__(self, p_access_point, p_location): """ Build an AccessPointLocation Json message. Keyword arguments: -- p_access_point: Access point identifier -- p_location : Access point geographical location """ print(">>> __to_accessPoint__: ", p_access_point) print("__to_accessPoint__: location= ", p_location['latitude'][0]) i = 0.0 resp = "{\"accessPointId\": \"" + p_access_point[0] + \ "\",\"locationInfo\": {\"latitude\": " + str(p_location['latitude'][0]) + ",\"longitude\": " + str(p_location['longitude'][0]) + ",\"altitude\": " + str(p_location['altitude'][0]) + ",\"accuracy\": " + str(p_location['accuracy'][0]) + "}," \ "\"connectionType\": \"" + p_access_point[2] + "\"," \ "\"operationStatus\": \"" + p_access_point[3] + "\"," \ "\"numberOfUsers\": " + str(p_access_point[4]) + "," \ "\"interestRealm\": \"" + p_access_point[5] + "\"," \ "\"resourceURL\": \"" + p_access_point[6] + "\"" \ "}" print("__to_accessPoint__: ", resp) return resp # End of __to_accessPoint__ def __to_zone__(self, p_zone): """ Build a Zones Json message. Keyword arguments: -- p_zone: Zone description """ print(">>> __to_zone__: ", p_zone) resp = "{\t\"zoneId\": \"" + p_zone[0] + "\",\t\"numberOfAccessPoints\": \"" + str(p_zone[1]) + "\",\t\"numberOfUnserviceableAccessPoints\": \"" + str(p_zone[2]) + "\",\t\"numberOfUsers\": \"" + str(p_zone[3]) + "\",\t\"resourceURL\": \"" + p_zone[4] + "\"}" print("__to_zone__: ", resp) return resp # End of __to_zone__ def __to_userInfo__(self, p_subscriber, p_location = None, p_contextLocationInfo = None): """ Build a UserInfo Json message. """ print(">>> __to_userInfo__: ", p_subscriber) resp = "{\t\"address\": \"" + p_subscriber[0] + "\",\t\"accessPointId\": \"" + p_subscriber[2] + "\",\t\"zoneId\": \"" + p_subscriber[3] + "\",\t\"resourceURL\": \"" + p_subscriber[4] + "\"}" print("__to_userInfo__: ", resp) return resp # End of __to_userInfo__ def __to_ueIdentityTagInfo__(self, p_ue_identity_tag, p_ue): """ Build a ueIdentityTagInfo Json message. """ print(">>> __to_ueIdentityTagInfo__: ", p_ue_identity_tag, ", ", p_ue) resp = "{\t\"ueIdentityTagInfo\": {\t\"ueIdentityTags\": [{\t\"ueIdentityTag\": \"" + p_ue_identity_tag + "\",\t\"state\": \"" + p_ue[1] + "\"}]}}" print("__to_ueIdentityTagInfo__: ", resp) return resp # End of __to_ueIdentityTagInfo__ def __to_subscriptions__(self, p_subscription): """ Build the userTrackingSubscription response """ print(">>> __to_subscriptions__: ", p_subscription) resp = "\t{\"userTrackingSubscription\": {\t\"clientCorrelator\": \"" + p_subscription[1] + "\",\t\"callbackReference\": {\"notifyURL\": \"" + p_subscription[3] + "\"},\t\"address\": \"" + p_subscription[2] + "\",\t\"userEventCriteria\" : [" resp += "\"" + p_subscription[4][0] + "\"" i = 1 while i < len(p_subscription[4]): resp += ",\"" + p_subscription[4][i] + "\"" i += 1 # End of 'while' statement resp += "],\t\"resourceURL\":\"" + p_subscription[5] + "\"\t}}" print("__to_subscriptions__: ", resp) return resp # End of __to_subscriptions__ def getSubscriberList(self, p_uri): """ Build a SubscriberList Json message. """ print(">>> getSubscriberList") resp = None try: resp = "{\"userList\": {\t\"user\": [\t" for r in self.__subscribers__.itertuples(): t = tuple(r) resp += self.__to_userInfo__(t) + "," # En of 'for' statement resp = resp[: len(resp) - 1] resp += "\t],\"resourceURL\": \"http://example.com" + p_uri + "\"}}" print("getSubscriberList: ", resp) except KeyError: print("getSubscriberList: No subscriber list") return resp # End of getSubscriberList def getZoneList(self, p_uri): print(">>> getZoneList") resp = None try: resp = "{\"zoneList\": {\t\"zone\": [\t" for r in self.__zones__.itertuples(): t = tuple(r) resp += self.__to_zone__(t) + "," # En of 'for' statement resp = resp[: len(resp) - 1] resp += "\t],\"resourceURL\": \"http://example.com" + p_uri + "\"}}" print("getZoneList: ", resp) except KeyError: print("getZoneList: No zones list") return resp # End of getZoneList def getAccessPointList(self, p_zone_id, p_uri): print(">>> getAccessPointList") resp = None try: r = self.__access_point_list__.loc[self.__access_point_list__['zoneId'] == p_zone_id] print("getAccessPointList: r= ", r) resp = "{\"accessPointList\": {\t\"zoneId\": \"" + p_zone_id + "\",\t\"accessPoint\": [\t" for i in r.itertuples(): t = tuple(i) location = self.__location_info__.loc[[t[0]]] resp += self.__to_accessPoint__(t, location) + "," # En of 'for' statement resp = resp[: len(resp) - 1] resp += "\t],\"resourceURL\": \"http://example.com" + p_uri + "\"}}" print("getAccessPointList: ", resp) except KeyError: print("getAccessPointList: No access point list") return resp # End of method getAccessPointList def getSubscriptionLinkList(self, p_uri): return "{\"SubscriptionLinkList\": {\"_links\": {\"self\": \"http://example.com" + p_uri + "\"},\"subscription\": [{\"href\": \"http://meAppClient.example.com/rni/v1/notifications/cell_change/77777\",\"subscriptionType\": \"CELL_CHANGE\"},{\"href\": \"http://meAppClient.example.com/rni/v1/notifications/MeasTa/77777\",\"subscriptionType\": \"MEAS_TIMING_ADVANCE\"}]}}" # End of method getSubscriptionLinkList def getSubscriberFromAddress(self, p_ue_address): print(">>> getSubscriberFromAddress: ", p_ue_address) result = None try: r = tuple(self.__subscribers__.loc[[p_ue_address]].itertuples(index=True, name=''))[0] print("getSubscriberFromAddress: Find subscriber with address ", p_ue_address, ": ", r) result = "{\"userInfo\": " + self.__to_userInfo__(r) + "}" except KeyError: print("getSubscriberFromAddress: No subscriber with address ", p_ue_address) return result # End of method getSubscriberFromAddress def getSubscriberFromZoneId(self, p_zone_id, p_uri): print(">>> getSubscriberFromZoneId: ", p_zone_id) resp = None try: r = self.__subscribers__.loc[self.__subscribers__['zoneId'] == p_zone_id] resp = "{\"userList\": {\t\"user\": [\t" for i in r.itertuples(): t = tuple(i) resp += self.__to_userInfo__(t) + "," # En of 'for' statement resp = resp[: len(resp) - 1] resp += "\t],\"resourceURL\": \"http://example.com" + p_uri + "\"}}" print("getSubscriberFromZoneId: ", resp) except KeyError: print("getSubscriberFromZoneId: No subscriber in zone ", p_zone_id) return resp # End of method getSubscriberFromAddress def getUEidentityTagInfo(self, p_app_inst, p_ue_identity_tag): print(">>> getUEidentityTagInfo: ", p_app_inst, ", ", p_ue_identity_tag) resp = None try: r = tuple(self.__ue_information_list__.loc[p_app_inst, p_ue_identity_tag]) print("getUEidentityTagInfo: Find zoneId for appInst: ", p_app_inst, ", r= ", r) resp = self.__to_ueIdentityTagInfo__(p_ue_identity_tag, r) print("getUEidentityTagInfo: ", resp) except KeyError: print("getUEidentityTagInfo: No UE for appInst ", p_app_inst) return resp # End of method getUEidentityTagInfo def registerUEidentity(self, p_app_inst, p_json_msg): print(">>> registerUEidentity", p_json_msg) if p_json_msg["state"] != "REGISTERED" and p_json_msg["state"] != "UNREGISTERED": return None resp = None try: # Check the record exists r = tuple(self.__ue_information_list__.loc[p_app_inst, p_json_msg["ueIdentityTag"]]) print("registerUEidentity: Find zoneId for appInst: ", p_app_inst, ", r= ", r) self.__ue_information_list__.loc[p_app_inst, p_json_msg["ueIdentityTag"]]['state'] = p_json_msg["state"] l = (p_json_msg["ueIdentityTag"], p_json_msg["state"]) resp = self.__to_ueIdentityTagInfo__(p_json_msg["ueIdentityTag"], l) except KeyError: print("registerUEidentity: No appInst/UE ", p_app_inst, "/", p_ue_identity_tag) return resp # End of method registerUEidentity def registerSubscription(self, p_json_msg, p_uri): print(">>> registerSubscription: ", p_json_msg, "/", p_uri) resp = None subscription_id = "subscription" + p_json_msg["clientCorrelator"] try: # Check the record does not exist self.__subscriptions__.loc[self.__subscriptions__['subscription_id'] == subscription_id] print("registerSubscription: There is a subscription for ", subscription_id) except KeyError: #print("registerSubscription: Add new row in subscription") resource_url = "http://example.com" + p_uri + "/" + subscription_id row = pd.Series({ 'subscription_id': subscription_id, 'corr_id': p_json_msg["clientCorrelator"], 'address': p_json_msg["address"], 'callback': p_json_msg["callbackReference"]["notifyURL"], 'ue_event_criteria': p_json_msg["userEventCriteria"], 'resourceURL': resource_url }) #print("registerSubscription: row: ", row) self.__subscriptions__ = self.__subscriptions__.append(row, ignore_index=True).reindex() #print("registerSubscription: ", self.__subscriptions__.head()) r = tuple(self.__subscriptions__.loc[self.__subscriptions__['subscription_id'] == subscription_id].to_records()) #print("registerSubscription: New added row: ", r[0]) resp = self.__to_subscriptions__(r[0]) return resp # End of registerSubscription def unregisterSubscription(self, p_subscription_id): print(">>> unregisterSubscription: ", p_subscription_id) resp = None try: # Check the record exists r = self.__subscriptions__.loc[self.__subscriptions__['subscription_id'] == p_subscription_id] t = tuple(r.to_records()) print("unregisterSubscription: Find row: ", t) resp = self.__to_subscriptions__(t[0]) # Remove it self.__subscriptions__.drop(r.index) except KeyError: print("unregisterSubscription: No subscription for ", p_subscription_id) return resp # End of unregisterSubscription def getBwAllocationAppInst(self, p_app_inst, p_ue_identity_tag): print(">>> getBwAllocationAppInst: ", p_app_inst, ", ", p_ue_identity_tag) resp = None resp = "{\"bwInfo\": {\"timeStamp\": {\"seconds\": 0,\"nanoSeconds\": 0},\"appInsId\": \"string\",\"requestType\": \"APPLICATION_SPECIFIC_BW_ALLOCATION\",\"sessionFilter\": [{\"sourceIp\": \"string\",\"sourcePort\": [\"string\"],\"dstAddress\": \"string\",\"dstPort\": [\"string\"],\"protocol\": \"string\"}],\"fixedBWPriority\": \"not defined in the present document\",\"fixedAllocation\": \"string\",\"allocationDirection\": \"00 = Downlink (towards the UE)\"}}" print("getBwAllocationAppInst: ", resp) return resp # End of method getBwAllocationAppInst # End of class mec_database