Newer
Older
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{}
periodicSubscriptionMap = map[int]*PeriodicCheck{}
updateStoreName("")
}
func updateStoreName(storeName string) {
if currentStoreName != storeName {
currentStoreName = storeName
Kevin Di Lallo
committed
logComponent := logModuleLocServ
if mepName != defaultMepName {
logComponent = logModuleLocServ + "-" + mepName
}
_ = httpLog.ReInit(logComponent, 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
//dtermine if ue is connected or not based on POA connectivity
if accessPointId != "" {
addressConnectedMap[address] = true
} else {
addressConnectedMap[address] = false
}
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)
}
//Accuracy supported for shape 4, 5, 6 only, so ignoring it in our case (only support shape == 2)
//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
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
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
}
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
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
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
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
}
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
func periodicReInit() {
//reusing the object response for the get multiple zonalSubscription
var periodicList NotificationSubscriptionList
keyName := baseKey + typePeriodicSubscription + "*"
_ = rc.ForEachJSONEntry(keyName, populatePeriodicList, &periodicList)
maxPeriodicSubscriptionId := 0
mutex.Lock()
defer mutex.Unlock()
for _, periodicSub := range periodicList.PeriodicNotificationSubscription {
resourceUrl := strings.Split(periodicSub.ResourceURL, "/")
subscriptionId, err := strconv.Atoi(resourceUrl[len(resourceUrl)-1])
if err != nil {
log.Error(err)
} else {
if subscriptionId > maxPeriodicSubscriptionId {
maxPeriodicSubscriptionId = subscriptionId
}
var periodicCheck PeriodicCheck
periodicCheck.Subscription = &periodicSub
periodicCheck.NextTts = periodicSub.Frequency
periodicSubscriptionMap[subscriptionId] = &periodicCheck
}
}
nextPeriodicSubscriptionIdAvailable = maxPeriodicSubscriptionId + 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) == 0 {
log.Error("Query should have at least 1 'address' parameter")
http.Error(w, "Query should have at least 1 'address' parameter", http.StatusBadRequest)
return
}
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)
return
}
if len(address) == 2 && (latitudeStr != "" || longitudeStr != "") {
log.Error("Query cannot have 2 'address' parameters and 'latitude'/'longitude' parameters")
http.Error(w, "Query cannot have 2 'address' parameters and 'latitude'/'longitude' parameters", http.StatusBadRequest)
return
}
if (latitudeStr != "" && longitudeStr == "") || (latitudeStr == "" && longitudeStr != "") {
log.Error("Query must provide a latitude and a longitude for a point to be valid")
http.Error(w, "Query must provide a latitude and a longitude for a point to be valid", http.StatusBadRequest)
return
}
if len(address) == 1 && latitudeStr == "" && longitudeStr == "" {
log.Error("Query must provide either 2 'address' parameters or 1 'address' parameter and 'latitude'/'longitude' parameters")
http.Error(w, "Query must provide either 2 'address' parameters or 1 'address' parameter and 'latitude'/'longitude' parameters", http.StatusBadRequest)
return
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
}
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]
}
// Verify address validity
if !addressConnectedMap[srcAddress] || (dstAddress != "" && !addressConnectedMap[dstAddress]) {
log.Error("Invalid address")
w.WriteHeader(http.StatusBadRequest)
return
}
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
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))
}