Newer
Older
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
if userTrackingSub.Address == "" {
log.Error("Mandatory Address parameter not present")
http.Error(w, "Mandatory Address parameter not present", http.StatusBadRequest)
return
}
if userTrackingSub.ResourceURL == "" {
log.Error("Mandatory ResourceURL parameter not present")
http.Error(w, "Mandatory ResourceURL parameter not present", http.StatusBadRequest)
return
}
subsIdParamStr := vars["subscriptionId"]
selfUrl := strings.Split(userTrackingSub.ResourceURL, "/")
subsIdStr := selfUrl[len(selfUrl)-1]
//Body content not matching parameters
if subsIdStr != subsIdParamStr {
log.Error("SubscriptionId in endpoint and in body not matching")
http.Error(w, "SubscriptionId in endpoint and in body not matching", http.StatusBadRequest)
return
}
userTrackingSub.ResourceURL = hostUrl.String() + basePath + "subscriptions/userTracking/" + subsIdStr
subsId, err := strconv.Atoi(subsIdStr)
if err != nil {
log.Error(err)
w.WriteHeader(http.StatusBadRequest)
return
}
if userSubscriptionMap[subsId] == "" {
w.WriteHeader(http.StatusNotFound)
return
}
_ = rc.JSONSetEntry(baseKey+typeUserSubscription+":"+subsIdStr, ".", convertUserSubscriptionToJson(userTrackingSub))
deregisterUser(subsIdStr)
registerUser(userTrackingSub.Address, userTrackingSub.UserEventCriteria, subsIdStr)
response.UserTrackingSubscription = userTrackingSub
jsonResponse, err := json.Marshal(response)
if err != nil {
log.Error(err.Error())
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.WriteHeader(http.StatusOK)
fmt.Fprintf(w, string(jsonResponse))
}
func populateUserTrackingList(key string, jsonInfo string, userData interface{}) error {
userList := userData.(*NotificationSubscriptionList)
var userInfo UserTrackingSubscription
// Format response
err := json.Unmarshal([]byte(jsonInfo), &userInfo)
if err != nil {
return err
}
userList.UserTrackingSubscription = append(userList.UserTrackingSubscription, userInfo)
return nil
}
func zonalTrafficSubDelete(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
vars := mux.Vars(r)
present, _ := rc.JSONGetEntry(baseKey+typeZonalSubscription+":"+vars["subscriptionId"], ".")
if present == "" {
w.WriteHeader(http.StatusNotFound)
return
}
err := rc.JSONDelEntry(baseKey+typeZonalSubscription+":"+vars["subscriptionId"], ".")
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
deregisterZonal(vars["subscriptionId"])
w.WriteHeader(http.StatusNoContent)
}
func zonalTrafficSubListGet(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
var response InlineNotificationSubscriptionList
var zonalTrafficSubList NotificationSubscriptionList
zonalTrafficSubList.ResourceURL = hostUrl.String() + basePath + "subscriptions/zonalTraffic"
response.NotificationSubscriptionList = &zonalTrafficSubList
keyName := baseKey + typeZonalSubscription + "*"
err := rc.ForEachJSONEntry(keyName, populateZonalTrafficList, &zonalTrafficSubList)
if err != nil {
log.Error(err.Error())
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
jsonResponse, err := json.Marshal(response)
if err != nil {
log.Error(err.Error())
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.WriteHeader(http.StatusOK)
fmt.Fprintf(w, string(jsonResponse))
}
func zonalTrafficSubGet(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
vars := mux.Vars(r)
var response InlineZonalTrafficSubscription
var zonalTrafficSub ZonalTrafficSubscription
response.ZonalTrafficSubscription = &zonalTrafficSub
jsonZonalTrafficSub, _ := rc.JSONGetEntry(baseKey+typeZonalSubscription+":"+vars["subscriptionId"], ".")
if jsonZonalTrafficSub == "" {
w.WriteHeader(http.StatusNotFound)
return
}
err := json.Unmarshal([]byte(jsonZonalTrafficSub), &zonalTrafficSub)
if err != nil {
log.Error(err.Error())
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
jsonResponse, err := json.Marshal(response)
if err != nil {
log.Error(err.Error())
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.WriteHeader(http.StatusOK)
fmt.Fprintf(w, string(jsonResponse))
}
func zonalTrafficSubPost(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
var response InlineZonalTrafficSubscription
var body InlineZonalTrafficSubscription
decoder := json.NewDecoder(r.Body)
err := decoder.Decode(&body)
if err != nil {
log.Error(err.Error())
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
zonalTrafficSub := body.ZonalTrafficSubscription
if zonalTrafficSub == nil {
log.Error("Body not present")
http.Error(w, "Body not present", http.StatusBadRequest)
return
}
//checking for mandatory properties
if zonalTrafficSub.CallbackReference == nil || zonalTrafficSub.CallbackReference.NotifyURL == "" {
log.Error("Mandatory CallbackReference parameter not present")
http.Error(w, "Mandatory CallbackReference parameter not present", http.StatusBadRequest)
return
}
if zonalTrafficSub.ZoneId == "" {
log.Error("Mandatory ZoneId parameter not present")
http.Error(w, "Mandatory ZoneId parameter not present", http.StatusBadRequest)
return
}
newSubsId := nextZonalSubscriptionIdAvailable
nextZonalSubscriptionIdAvailable++
subsIdStr := strconv.Itoa(newSubsId)
/*
if zonalTrafficSub.Duration > 0 {
//TODO start a timer mecanism and expire subscription
}
//else, lasts forever or until subscription is deleted
*/
if zonalTrafficSub.Duration != 0 { //used to be string -> zonalTrafficSub.Duration != "" && zonalTrafficSub.Duration != "0" {
//TODO start a timer mecanism and expire subscription
log.Info("Non zero duration")
}
//else, lasts forever or until subscription is deleted
Kevin Di Lallo
committed
zonalTrafficSub.ResourceURL = hostUrl.String() + basePath + "subscriptions/zonalTraffic/" + subsIdStr
Kevin Di Lallo
committed
_ = rc.JSONSetEntry(baseKey+typeZonalSubscription+":"+subsIdStr, ".", convertZonalSubscriptionToJson(zonalTrafficSub))
registerZonal(zonalTrafficSub.ZoneId, zonalTrafficSub.UserEventCriteria, subsIdStr)
response.ZonalTrafficSubscription = zonalTrafficSub
jsonResponse, err := json.Marshal(response)
if err != nil {
log.Error(err.Error())
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.WriteHeader(http.StatusCreated)
fmt.Fprintf(w, string(jsonResponse))
}
func zonalTrafficSubPut(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
vars := mux.Vars(r)
var response InlineZonalTrafficSubscription
var body InlineZonalTrafficSubscription
decoder := json.NewDecoder(r.Body)
if err != nil {
log.Error(err.Error())
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
zonalTrafficSub := body.ZonalTrafficSubscription
if zonalTrafficSub == nil {
log.Error("Body not present")
http.Error(w, "Body not present", http.StatusBadRequest)
Simon Pastor
committed
//checking for mandatory properties
if zonalTrafficSub.CallbackReference == nil || zonalTrafficSub.CallbackReference.NotifyURL == "" {
log.Error("Mandatory CallbackReference parameter not present")
http.Error(w, "Mandatory CallbackReference parameter not present", http.StatusBadRequest)
Simon Pastor
committed
return
}
if zonalTrafficSub.ZoneId == "" {
log.Error("Mandatory ZoneId parameter not present")
http.Error(w, "Mandatory ZoneId parameter not present", http.StatusBadRequest)
Simon Pastor
committed
return
}
if zonalTrafficSub.ResourceURL == "" {
log.Error("Mandatory ResourceURL parameter not present")
http.Error(w, "Mandatory ResourceURL parameter not present", http.StatusBadRequest)
subsIdParamStr := vars["subscriptionId"]
selfUrl := strings.Split(zonalTrafficSub.ResourceURL, "/")
subsIdStr := selfUrl[len(selfUrl)-1]
log.Error("SubscriptionId in endpoint and in body not matching")
http.Error(w, "SubscriptionId in endpoint and in body not matching", http.StatusBadRequest)
Kevin Di Lallo
committed
zonalTrafficSub.ResourceURL = hostUrl.String() + basePath + "subscriptions/zonalTraffic/" + subsIdStr
if err != nil {
log.Error(err)
w.WriteHeader(http.StatusBadRequest)
return
}
if zonalSubscriptionMap[subsId] == "" {
w.WriteHeader(http.StatusNotFound)
return
}
Kevin Di Lallo
committed
_ = rc.JSONSetEntry(baseKey+typeZonalSubscription+":"+subsIdStr, ".", convertZonalSubscriptionToJson(zonalTrafficSub))
deregisterZonal(subsIdStr)
registerZonal(zonalTrafficSub.ZoneId, zonalTrafficSub.UserEventCriteria, subsIdStr)
response.ZonalTrafficSubscription = zonalTrafficSub
jsonResponse, err := json.Marshal(response)
if err != nil {
log.Error(err.Error())
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.WriteHeader(http.StatusOK)
fmt.Fprintf(w, string(jsonResponse))
Kevin Di Lallo
committed
func populateZonalTrafficList(key string, jsonInfo string, userData interface{}) error {
var zoneInfo ZonalTrafficSubscription
// Format response
err := json.Unmarshal([]byte(jsonInfo), &zoneInfo)
if err != nil {
return err
}
zoneList.ZonalTrafficSubscription = append(zoneList.ZonalTrafficSubscription, zoneInfo)
return nil
}
func zoneStatusSubDelete(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
Simon Pastor
committed
vars := mux.Vars(r)
present, _ := rc.JSONGetEntry(baseKey+typeZoneStatusSubscription+":"+vars["subscriptionId"], ".")
if present == "" {
w.WriteHeader(http.StatusNotFound)
return
}
Kevin Di Lallo
committed
err := rc.JSONDelEntry(baseKey+typeZoneStatusSubscription+":"+vars["subscriptionId"], ".")
Simon Pastor
committed
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
deregisterZoneStatus(vars["subscriptionId"])
w.WriteHeader(http.StatusNoContent)
func zoneStatusSubListGet(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
var response InlineNotificationSubscriptionList
Kevin Di Lallo
committed
zoneStatusSubList.ResourceURL = hostUrl.String() + basePath + "subscriptions/zoneStatus"
response.NotificationSubscriptionList = &zoneStatusSubList
Kevin Di Lallo
committed
keyName := baseKey + typeZoneStatusSubscription + "*"
err := rc.ForEachJSONEntry(keyName, populateZoneStatusList, &zoneStatusSubList)
if err != nil {
log.Error(err.Error())
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
jsonResponse, err := json.Marshal(response)
if err != nil {
log.Error(err.Error())
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.WriteHeader(http.StatusOK)
fmt.Fprintf(w, string(jsonResponse))
}
func zoneStatusSubGet(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
Simon Pastor
committed
vars := mux.Vars(r)
var response InlineZoneStatusSubscription
var zoneStatusSub ZoneStatusSubscription
response.ZoneStatusSubscription = &zoneStatusSub
Simon Pastor
committed
Kevin Di Lallo
committed
jsonZoneStatusSub, _ := rc.JSONGetEntry(baseKey+typeZoneStatusSubscription+":"+vars["subscriptionId"], ".")
if jsonZoneStatusSub == "" {
Simon Pastor
committed
w.WriteHeader(http.StatusNotFound)
return
}
err := json.Unmarshal([]byte(jsonZoneStatusSub), &zoneStatusSub)
if err != nil {
log.Error(err.Error())
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
jsonResponse, err := json.Marshal(response)
if err != nil {
log.Error(err.Error())
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.WriteHeader(http.StatusOK)
fmt.Fprintf(w, string(jsonResponse))
func zoneStatusSubPost(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
Simon Pastor
committed
var response InlineZoneStatusSubscription
Simon Pastor
committed
var body InlineZoneStatusSubscription
decoder := json.NewDecoder(r.Body)
Simon Pastor
committed
if err != nil {
log.Error(err.Error())
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
zoneStatusSub := body.ZoneStatusSubscription
if zoneStatusSub == nil {
log.Error("Body not present")
http.Error(w, "Body not present", http.StatusBadRequest)
Simon Pastor
committed
Simon Pastor
committed
//checking for mandatory properties
if zoneStatusSub.CallbackReference == nil || zoneStatusSub.CallbackReference.NotifyURL == "" {
log.Error("Mandatory CallbackReference parameter not present")
http.Error(w, "Mandatory CallbackReference parameter not present", http.StatusBadRequest)
Simon Pastor
committed
return
}
if zoneStatusSub.ZoneId == "" {
log.Error("Mandatory ZoneId parameter not present")
http.Error(w, "Mandatory ZoneId parameter not present", http.StatusBadRequest)
Simon Pastor
committed
return
}
Simon Pastor
committed
newSubsId := nextZoneStatusSubscriptionIdAvailable
nextZoneStatusSubscriptionIdAvailable++
subsIdStr := strconv.Itoa(newSubsId)
Kevin Di Lallo
committed
zoneStatusSub.ResourceURL = hostUrl.String() + basePath + "subscriptions/zoneStatus/" + subsIdStr
Simon Pastor
committed
Kevin Di Lallo
committed
_ = rc.JSONSetEntry(baseKey+typeZoneStatusSubscription+":"+subsIdStr, ".", convertZoneStatusSubscriptionToJson(zoneStatusSub))
Simon Pastor
committed
registerZoneStatus(zoneStatusSub.ZoneId, zoneStatusSub.NumberOfUsersZoneThreshold, zoneStatusSub.NumberOfUsersAPThreshold,
zoneStatusSub.OperationStatus, subsIdStr)
Simon Pastor
committed
response.ZoneStatusSubscription = zoneStatusSub
jsonResponse, err := json.Marshal(response)
Simon Pastor
committed
if err != nil {
log.Error(err.Error())
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.WriteHeader(http.StatusCreated)
Simon Pastor
committed
fmt.Fprintf(w, string(jsonResponse))
func zoneStatusSubPut(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
Simon Pastor
committed
vars := mux.Vars(r)
var response InlineZoneStatusSubscription
Simon Pastor
committed
var body InlineZoneStatusSubscription
Simon Pastor
committed
decoder := json.NewDecoder(r.Body)
Simon Pastor
committed
if err != nil {
log.Error(err.Error())
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
zoneStatusSub := body.ZoneStatusSubscription
if zoneStatusSub == nil {
log.Error("Body not present")
http.Error(w, "Body not present", http.StatusBadRequest)
Simon Pastor
committed
//checking for mandatory properties
if zoneStatusSub.CallbackReference == nil || zoneStatusSub.CallbackReference.NotifyURL == "" {
log.Error("Mandatory CallbackReference parameter not present")
http.Error(w, "Mandatory CallbackReference parameter not present", http.StatusBadRequest)
Simon Pastor
committed
return
}
if zoneStatusSub.ZoneId == "" {
log.Error("Mandatory ZoneId parameter not present")
http.Error(w, "Mandatory ZoneId parameter not present", http.StatusBadRequest)
Simon Pastor
committed
return
}
if zoneStatusSub.ResourceURL == "" {
log.Error("Mandatory ResourceURL parameter not present")
http.Error(w, "Mandatory ResourceURL parameter not present", http.StatusBadRequest)
subsIdParamStr := vars["subscriptionId"]
selfUrl := strings.Split(zoneStatusSub.ResourceURL, "/")
subsIdStr := selfUrl[len(selfUrl)-1]
log.Error("SubscriptionId in endpoint and in body not matching")
http.Error(w, "SubscriptionId in endpoint and in body not matching", http.StatusBadRequest)
Simon Pastor
committed
Kevin Di Lallo
committed
zoneStatusSub.ResourceURL = hostUrl.String() + basePath + "subscriptions/zoneStatus/" + subsIdStr
Simon Pastor
committed
subsId, err := strconv.Atoi(subsIdStr)
if err != nil {
log.Error(err)
w.WriteHeader(http.StatusBadRequest)
if zoneStatusSubscriptionMap[subsId] == nil {
w.WriteHeader(http.StatusNotFound)
return
}
Kevin Di Lallo
committed
_ = rc.JSONSetEntry(baseKey+typeZoneStatusSubscription+":"+subsIdStr, ".", convertZoneStatusSubscriptionToJson(zoneStatusSub))
Simon Pastor
committed
deregisterZoneStatus(subsIdStr)
registerZoneStatus(zoneStatusSub.ZoneId, zoneStatusSub.NumberOfUsersZoneThreshold, zoneStatusSub.NumberOfUsersAPThreshold,
zoneStatusSub.OperationStatus, subsIdStr)
Simon Pastor
committed
response.ZoneStatusSubscription = zoneStatusSub
jsonResponse, err := json.Marshal(response)
if err != nil {
log.Error(err.Error())
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.WriteHeader(http.StatusOK)
fmt.Fprintf(w, string(jsonResponse))
Kevin Di Lallo
committed
func populateZoneStatusList(key string, jsonInfo string, userData interface{}) error {
var zoneInfo ZoneStatusSubscription
// Format response
err := json.Unmarshal([]byte(jsonInfo), &zoneInfo)
if err != nil {
return err
}
zoneList.ZoneStatusSubscription = append(zoneList.ZoneStatusSubscription, zoneInfo)
return nil
}
Kevin Di Lallo
committed
rc.DBFlush(baseKey)
nextZonalSubscriptionIdAvailable = 1
nextUserSubscriptionIdAvailable = 1
nextZoneStatusSubscriptionIdAvailable = 1
nextDistanceSubscriptionIdAvailable = 1
nextAreaCircleSubscriptionIdAvailable = 1
zonalSubscriptionEnteringMap = map[int]string{}
zonalSubscriptionLeavingMap = map[int]string{}
zonalSubscriptionTransferringMap = map[int]string{}
zonalSubscriptionMap = map[int]string{}
userSubscriptionEnteringMap = map[int]string{}
userSubscriptionLeavingMap = map[int]string{}
userSubscriptionTransferringMap = map[int]string{}
userSubscriptionMap = map[int]string{}
zoneStatusSubscriptionMap = map[int]*ZoneStatusCheck{}
distanceSubscriptionMap = map[int]*DistanceCheck{}
areaCircleSubscriptionMap = map[int]*AreaCircleCheck{}
updateStoreName("")
}
func updateStoreName(storeName string) {
if currentStoreName != storeName {
currentStoreName = storeName
_ = httpLog.ReInit(logModuleLocServ, sandboxName, storeName, redisAddr, influxAddr)
}
Kevin Di Lallo
committed
func updateUserInfo(address string, zoneId string, accessPointId string, longitude *float32, latitude *float32) {
Kevin Di Lallo
committed
var oldZoneId string
var oldApId string
Kevin Di Lallo
committed
// Get User Info from DB
Kevin Di Lallo
committed
jsonUserInfo, _ := rc.JSONGetEntry(baseKey+typeUser+":"+address, ".")
Kevin Di Lallo
committed
userInfo := convertJsonToUserInfo(jsonUserInfo)
Kevin Di Lallo
committed
// Create new user info if necessary
if userInfo == nil {
userInfo = new(UserInfo)
userInfo.Address = address
userInfo.ResourceURL = hostUrl.String() + basePath + "queries/users?address=" + address
Kevin Di Lallo
committed
} else {
// Get old zone & AP IDs
oldZoneId = userInfo.ZoneId
oldApId = userInfo.AccessPointId
Kevin Di Lallo
committed
}
userInfo.ZoneId = zoneId
userInfo.AccessPointId = accessPointId
seconds := time.Now().Unix()
var timeStamp TimeStamp
timeStamp.Seconds = int32(seconds)
userInfo.Timestamp = &timeStamp
Kevin Di Lallo
committed
// Update position
if longitude == nil || latitude == nil {
userInfo.LocationInfo = nil
} else {
if userInfo.LocationInfo == nil {
userInfo.LocationInfo = new(LocationInfo)
}
//we only support shape == 2 in locationInfo, so we ignore any conditional parameters based on shape
userInfo.LocationInfo.Shape = 2
userInfo.LocationInfo.Longitude = nil
userInfo.LocationInfo.Longitude = append(userInfo.LocationInfo.Longitude, *longitude)
userInfo.LocationInfo.Latitude = nil
userInfo.LocationInfo.Latitude = append(userInfo.LocationInfo.Latitude, *latitude)
userInfo.LocationInfo.Timestamp = &timeStamp
Kevin Di Lallo
committed
}
Kevin Di Lallo
committed
// Update User info in DB & Send notifications
_ = rc.JSONSetEntry(baseKey+typeUser+":"+address, ".", convertUserInfoToJson(userInfo))
checkNotificationRegisteredUsers(oldZoneId, zoneId, oldApId, accessPointId, address)
checkNotificationRegisteredZones(oldZoneId, zoneId, oldApId, accessPointId, address)
func updateZoneInfo(zoneId string, nbAccessPoints int, nbUnsrvAccessPoints int, nbUsers int) {
Kevin Di Lallo
committed
// Get Zone Info from DB
Kevin Di Lallo
committed
jsonZoneInfo, _ := rc.JSONGetEntry(baseKey+typeZone+":"+zoneId, ".")
Kevin Di Lallo
committed
zoneInfo := convertJsonToZoneInfo(jsonZoneInfo)
Kevin Di Lallo
committed
// Create new zone info if necessary
if zoneInfo == nil {
zoneInfo = new(ZoneInfo)
zoneInfo.ZoneId = zoneId
zoneInfo.ResourceURL = hostUrl.String() + basePath + "queries/zones/" + zoneId
Kevin Di Lallo
committed
}
Kevin Di Lallo
committed
// Update info
if nbAccessPoints != -1 {
zoneInfo.NumberOfAccessPoints = int32(nbAccessPoints)
Kevin Di Lallo
committed
}
if nbUnsrvAccessPoints != -1 {
zoneInfo.NumberOfUnserviceableAccessPoints = int32(nbUnsrvAccessPoints)
Kevin Di Lallo
committed
}
if nbUsers != -1 {
zoneInfo.NumberOfUsers = int32(nbUsers)
Kevin Di Lallo
committed
// Update Zone info in DB & Send notifications
_ = rc.JSONSetEntry(baseKey+typeZone+":"+zoneId, ".", convertZoneInfoToJson(zoneInfo))
checkNotificationRegisteredZoneStatus(zoneId, "", int32(-1), int32(nbUsers), int32(-1), previousNbUsers)
Kevin Di Lallo
committed
func updateAccessPointInfo(zoneId string, apId string, conTypeStr string, opStatusStr string, nbUsers int, longitude *float32, latitude *float32) {
Kevin Di Lallo
committed
// Get AP Info from DB
Kevin Di Lallo
committed
jsonApInfo, _ := rc.JSONGetEntry(baseKey+typeZone+":"+zoneId+":"+typeAccessPoint+":"+apId, ".")
Kevin Di Lallo
committed
apInfo := convertJsonToAccessPointInfo(jsonApInfo)
Kevin Di Lallo
committed
// Create new AP info if necessary
if apInfo == nil {
apInfo = new(AccessPointInfo)
apInfo.AccessPointId = apId
apInfo.ResourceURL = hostUrl.String() + basePath + "queries/zones/" + zoneId + "/accessPoints/" + apId
Kevin Di Lallo
committed
}
Kevin Di Lallo
committed
// Update info
if opStatusStr != "" {
opStatus := convertStringToOperationStatus(opStatusStr)
apInfo.OperationStatus = &opStatus
Kevin Di Lallo
committed
}
if conTypeStr != "" {
conType := convertStringToConnectionType(conTypeStr)
apInfo.ConnectionType = &conType
}
Kevin Di Lallo
committed
if nbUsers != -1 {
apInfo.NumberOfUsers = int32(nbUsers)
Kevin Di Lallo
committed
Kevin Di Lallo
committed
// Update position
if longitude == nil || latitude == nil {
apInfo.LocationInfo = nil
} else {
if apInfo.LocationInfo == nil {
apInfo.LocationInfo = new(LocationInfo)
apInfo.LocationInfo.Accuracy = 1
}
apInfo.LocationInfo.Longitude = nil
apInfo.LocationInfo.Longitude = append(apInfo.LocationInfo.Longitude, *longitude)
apInfo.LocationInfo.Latitude = nil
apInfo.LocationInfo.Latitude = append(apInfo.LocationInfo.Latitude, *latitude)
seconds := time.Now().Unix()
var timeStamp TimeStamp
timeStamp.Seconds = int32(seconds)
apInfo.LocationInfo.Timestamp = &timeStamp
Kevin Di Lallo
committed
}
Kevin Di Lallo
committed
// Update AP info in DB & Send notifications
_ = rc.JSONSetEntry(baseKey+typeZone+":"+zoneId+":"+typeAccessPoint+":"+apId, ".", convertAccessPointInfoToJson(apInfo))
checkNotificationRegisteredZoneStatus(zoneId, apId, int32(nbUsers), int32(-1), previousNbUsers, int32(-1))
Simon Pastor
committed
func zoneStatusReInit() {
//reusing the object response for the get multiple zoneStatusSubscription
Simon Pastor
committed
Kevin Di Lallo
committed
keyName := baseKey + typeZoneStatusSubscription + "*"
_ = rc.ForEachJSONEntry(keyName, populateZoneStatusList, &zoneList)
Simon Pastor
committed
maxZoneStatusSubscriptionId := 0
Simon Pastor
committed
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
for _, zone := range zoneList.ZoneStatusSubscription {
resourceUrl := strings.Split(zone.ResourceURL, "/")
subscriptionId, err := strconv.Atoi(resourceUrl[len(resourceUrl)-1])
if err != nil {
log.Error(err)
} else {
if subscriptionId > maxZoneStatusSubscriptionId {
maxZoneStatusSubscriptionId = subscriptionId
}
var zoneStatus ZoneStatusCheck
opStatus := zone.OperationStatus
if opStatus != nil {
for i := 0; i < len(opStatus); i++ {
switch opStatus[i] {
case SERVICEABLE:
zoneStatus.Serviceable = true
case UNSERVICEABLE:
zoneStatus.Unserviceable = true
case OPSTATUS_UNKNOWN:
zoneStatus.Unknown = true
default:
}
}
}
zoneStatus.NbUsersInZoneThreshold = zone.NumberOfUsersZoneThreshold
zoneStatus.NbUsersInAPThreshold = zone.NumberOfUsersAPThreshold
Simon Pastor
committed
zoneStatus.ZoneId = zone.ZoneId
zoneStatusSubscriptionMap[subscriptionId] = &zoneStatus
}
}
nextZoneStatusSubscriptionIdAvailable = maxZoneStatusSubscriptionId + 1
}
func zonalTrafficReInit() {
//reusing the object response for the get multiple zonalSubscription
Kevin Di Lallo
committed
keyName := baseKey + typeZonalSubscription + "*"
_ = rc.ForEachJSONEntry(keyName, populateZonalTrafficList, &zoneList)
maxZonalSubscriptionId := 0
for _, zone := range zoneList.ZonalTrafficSubscription {
resourceUrl := strings.Split(zone.ResourceURL, "/")
subscriptionId, err := strconv.Atoi(resourceUrl[len(resourceUrl)-1])
if err != nil {
log.Error(err)
} else {
if subscriptionId > maxZonalSubscriptionId {
maxZonalSubscriptionId = subscriptionId
}
for i := 0; i < len(zone.UserEventCriteria); i++ {
switch zone.UserEventCriteria[i] {
zonalSubscriptionEnteringMap[subscriptionId] = zone.ZoneId
zonalSubscriptionLeavingMap[subscriptionId] = zone.ZoneId
zonalSubscriptionTransferringMap[subscriptionId] = zone.ZoneId
zonalSubscriptionMap[subscriptionId] = zone.ZoneId
}
}
nextZonalSubscriptionIdAvailable = maxZonalSubscriptionId + 1
}
func userTrackingReInit() {
//reusing the object response for the get multiple zonalSubscription
Kevin Di Lallo
committed
keyName := baseKey + typeUserSubscription + "*"
_ = rc.ForEachJSONEntry(keyName, populateUserTrackingList, &userList)
maxUserSubscriptionId := 0
for _, user := range userList.UserTrackingSubscription {
resourceUrl := strings.Split(user.ResourceURL, "/")
subscriptionId, err := strconv.Atoi(resourceUrl[len(resourceUrl)-1])
if err != nil {
log.Error(err)
} else {
if subscriptionId > maxUserSubscriptionId {
maxUserSubscriptionId = subscriptionId
}
for i := 0; i < len(user.UserEventCriteria); i++ {
switch user.UserEventCriteria[i] {
userSubscriptionEnteringMap[subscriptionId] = user.Address
userSubscriptionLeavingMap[subscriptionId] = user.Address
userSubscriptionTransferringMap[subscriptionId] = user.Address
userSubscriptionMap[subscriptionId] = user.Address
}
}
nextUserSubscriptionIdAvailable = maxUserSubscriptionId + 1
}
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
func distanceReInit() {
//reusing the object response for the get multiple zonalSubscription
var distanceList NotificationSubscriptionList
keyName := baseKey + typeDistanceSubscription + "*"
_ = rc.ForEachJSONEntry(keyName, populateDistanceList, &distanceList)
maxDistanceSubscriptionId := 0
mutex.Lock()
defer mutex.Unlock()
for _, distanceSub := range distanceList.DistanceNotificationSubscription {
resourceUrl := strings.Split(distanceSub.ResourceURL, "/")
subscriptionId, err := strconv.Atoi(resourceUrl[len(resourceUrl)-1])
if err != nil {
log.Error(err)
} else {
if subscriptionId > maxDistanceSubscriptionId {
maxDistanceSubscriptionId = subscriptionId
}
var distanceCheck DistanceCheck
distanceCheck.Subscription = &distanceSub
if distanceSub.CheckImmediate {
distanceCheck.NextTts = 0 //next time periodic trigger hits, will be forced to trigger
} else {
distanceCheck.NextTts = distanceSub.Frequency
}
distanceSubscriptionMap[subscriptionId] = &distanceCheck
}
}
nextDistanceSubscriptionIdAvailable = maxDistanceSubscriptionId + 1
}
func areaCircleReInit() {
//reusing the object response for the get multiple zonalSubscription
var areaCircleList NotificationSubscriptionList
keyName := baseKey + typeAreaCircleSubscription + "*"
_ = rc.ForEachJSONEntry(keyName, populateAreaCircleList, &areaCircleList)
maxAreaCircleSubscriptionId := 0
mutex.Lock()
defer mutex.Unlock()
for _, areaCircleSub := range areaCircleList.CircleNotificationSubscription {
resourceUrl := strings.Split(areaCircleSub.ResourceURL, "/")
subscriptionId, err := strconv.Atoi(resourceUrl[len(resourceUrl)-1])
if err != nil {
log.Error(err)
} else {
if subscriptionId > maxAreaCircleSubscriptionId {
maxAreaCircleSubscriptionId = subscriptionId
}
var areaCircleCheck AreaCircleCheck
areaCircleCheck.Subscription = &areaCircleSub
areaCircleCheck.AddrInArea = map[string]bool{}
if areaCircleSub.CheckImmediate {
areaCircleCheck.NextTts = 0 //next time periodic trigger hits, will be forced to trigger
} else {
areaCircleCheck.NextTts = areaCircleSub.Frequency
}
areaCircleSubscriptionMap[subscriptionId] = &areaCircleCheck
}
}
nextAreaCircleSubscriptionIdAvailable = maxAreaCircleSubscriptionId + 1
}
func distanceGet(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
// Retrieve query parameters
u, _ := url.Parse(r.URL.String())
log.Info("url: ", u.RequestURI())
q := u.Query()
//requester := q.Get("requester")
latitudeStr := q.Get("latitude")
longitudeStr := q.Get("longitude")
address := q["address"]
if len(address) > 2 {
log.Error("Query cannot have more than 2 'address' parameters")
http.Error(w, "Query cannot have more than 2 'address' parameters", http.StatusBadRequest)
}
validQueryParams := []string{"requester", "address", "latitude", "longitude"}
//look for all query parameters to reject if any invalid ones
found := false
for queryParam := range q {
found = false
for _, validQueryParam := range validQueryParams {
if queryParam == validQueryParam {
found = true
break
}
}
if !found {
log.Error("Query param not valid: ", queryParam)
w.WriteHeader(http.StatusBadRequest)
return
}
}
srcAddress := address[0]
dstAddress := ""
if len(address) > 1 {
dstAddress = address[1]
}
var distParam gisClient.TargetPoint
distParam.AssetName = dstAddress
if longitudeStr != "" {
longitude, err := strconv.ParseFloat(longitudeStr, 32)
if err != nil {
log.Error(err.Error())
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
distParam.Longitude = float32(longitude)
}
if latitudeStr != "" {
latitude, err := strconv.ParseFloat(latitudeStr, 32)
if err != nil {
log.Error(err.Error())
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
distParam.Latitude = float32(latitude)
}
distResp, _, err := gisAppClient.GeospatialDataApi.GetDistanceGeoDataByName(context.TODO(), srcAddress, distParam)
if err != nil {
errCodeStr := strings.Split(err.Error(), " ")
if len(errCodeStr) > 0 {
errCode, errStr := strconv.Atoi(errCodeStr[0])
if errStr == nil {
log.Error("Error code from gis-engine API : ", err)
http.Error(w, err.Error(), errCode)
} else {
log.Error("Failed to communicate with gis engine: ", err)
http.Error(w, err.Error(), http.StatusInternalServerError)
}
} else {
log.Error("Failed to communicate with gis engine: ", err)
http.Error(w, err.Error(), http.StatusInternalServerError)
}
return
}
var response InlineTerminalDistance
var terminalDistance TerminalDistance
terminalDistance.Distance = int32(distResp.Distance)
seconds := time.Now().Unix()
var timestamp TimeStamp
timestamp.Seconds = int32(seconds)
terminalDistance.Timestamp = ×tamp
response.TerminalDistance = &terminalDistance
// Send response
jsonResponse, err := json.Marshal(response)
if err != nil {
log.Error(err.Error())
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
w.WriteHeader(http.StatusOK)
fmt.Fprintf(w, string(jsonResponse))
}