Newer
Older
* Copyright (c) 2019 InterDigital Communications, Inc
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
package server
import (
"context"
"encoding/json"
"errors"
"fmt"
"net/http"
"net/url"
Kevin Di Lallo
committed
"os"
"strconv"
"strings"
"time"
sbi "github.com/InterDigitalInc/AdvantEDGE/go-apps/meep-loc-serv/sbi"
Kevin Di Lallo
committed
dkm "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-data-key-mgr"
httpLog "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-http-logger"
Simon Pastor
committed
clientNotifOMA "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-loc-serv-notification-client"
log "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-logger"
redis "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-redis"
Simon Pastor
committed
"github.com/gorilla/mux"
)
Kevin Di Lallo
committed
const LocServBasePath = "/location/v1/"
Kevin Di Lallo
committed
const locServKey string = "loc-serv:"
const typeZone = "zone"
const typeAccessPoint = "accessPoint"
const typeUser = "user"
const typeZonalSubscription = "zonalsubs"
const typeUserSubscription = "usersubs"
const typeZoneStatusSubscription = "zonestatus"
const USER_TRACKING_AND_ZONAL_TRAFFIC = 1
const ZONE_STATUS = 2
var nextZonalSubscriptionIdAvailable int
var nextUserSubscriptionIdAvailable int
Simon Pastor
committed
var nextZoneStatusSubscriptionIdAvailable int
var zonalSubscriptionEnteringMap = map[int]string{}
var zonalSubscriptionLeavingMap = map[int]string{}
var zonalSubscriptionTransferringMap = map[int]string{}
var zonalSubscriptionMap = map[int]string{}
var userSubscriptionEnteringMap = map[int]string{}
var userSubscriptionLeavingMap = map[int]string{}
var userSubscriptionTransferringMap = map[int]string{}
var userSubscriptionMap = map[int]string{}
Simon Pastor
committed
var zoneStatusSubscriptionMap = map[int]*ZoneStatusCheck{}
type ZoneStatusCheck struct {
ZoneId string
Serviceable bool
Unserviceable bool
Unknown bool
NbUsersInZoneThreshold int
NbUsersInAPThreshold int
}
const redisAddr string = "meep-redis-master.default.svc.cluster.local:6379"
Kevin Di Lallo
committed
var hostUrl *url.URL
Kevin Di Lallo
committed
var sandboxName string
Kevin Di Lallo
committed
var basePath string
Kevin Di Lallo
committed
var baseKey string
Simon Pastor
committed
// Init - Location Service initialization
func Init() (err error) {
Kevin Di Lallo
committed
// Retrieve Sandbox name from environment variable
sandboxName = strings.TrimSpace(os.Getenv("MEEP_SANDBOX_NAME"))
if sandboxName == "" {
err = errors.New("MEEP_SANDBOX_NAME env variable not set")
log.Error(err.Error())
return err
}
log.Info("MEEP_SANDBOX_NAME: ", sandboxName)
Kevin Di Lallo
committed
// Retrieve Host URL from environment variable
hostUrl, err = url.Parse(strings.TrimSpace(os.Getenv("MEEP_HOST_URL")))
Kevin Di Lallo
committed
if err != nil {
Kevin Di Lallo
committed
hostUrl = new(url.URL)
Kevin Di Lallo
committed
}
Kevin Di Lallo
committed
log.Info("MEEP_HOST_URL: ", hostUrl)
// Set base path
basePath = "/" + sandboxName + LocServBasePath
Kevin Di Lallo
committed
Kevin Di Lallo
committed
// Get base storage key
baseKey = dkm.GetKeyRoot(sandboxName) + locServKey
Kevin Di Lallo
committed
// Connect to Redis DB
userTrackingReInit()
zonalTrafficReInit()
Simon Pastor
committed
zoneStatusReInit()
//sbi is the sole responsible of updating the userInfo, zoneInfo and apInfo structures
Kevin Di Lallo
committed
return sbi.Init(sandboxName, updateUserInfo, updateZoneInfo, updateAccessPointInfo, cleanUp)
Kevin Di Lallo
committed
}
Kevin Di Lallo
committed
func Run() (err error) {
return sbi.Run()
Simon Pastor
committed
func createClient(notifyPath string) (*clientNotifOMA.APIClient, error) {
// Create & store client for App REST API
Simon Pastor
committed
subsAppClientCfg := clientNotifOMA.NewConfiguration()
subsAppClientCfg.BasePath = notifyPath
Simon Pastor
committed
subsAppClient := clientNotifOMA.NewAPIClient(subsAppClientCfg)
if subsAppClient == nil {
log.Error("Failed to create Subscription App REST API client: ", subsAppClientCfg.BasePath)
err := errors.New("Failed to create Subscription App REST API client")
return nil, err
}
return subsAppClient, nil
}
Simon Pastor
committed
func deregisterZoneStatus(subsIdStr string) {
subsId, _ := strconv.Atoi(subsIdStr)
zonalSubscriptionMap[subsId] = ""
}
func registerZoneStatus(zoneId string, nbOfUsersZoneThreshold int32, nbOfUsersAPThreshold int32, opStatus []OperationStatus, subsIdStr string) {
Simon Pastor
committed
subsId, _ := strconv.Atoi(subsIdStr)
var zoneStatus ZoneStatusCheck
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 = (int)(nbOfUsersZoneThreshold)
zoneStatus.NbUsersInAPThreshold = (int)(nbOfUsersAPThreshold)
zoneStatus.ZoneId = zoneId
zoneStatusSubscriptionMap[subsId] = &zoneStatus
}
func deregisterZonal(subsIdStr string) {
subsId, _ := strconv.Atoi(subsIdStr)
zonalSubscriptionMap[subsId] = ""
zonalSubscriptionEnteringMap[subsId] = ""
zonalSubscriptionLeavingMap[subsId] = ""
zonalSubscriptionTransferringMap[subsId] = ""
func registerZonal(zoneId string, event []UserEventType, subsIdStr string) {
subsId, _ := strconv.Atoi(subsIdStr)
if event != nil {
for i := 0; i < len(event); i++ {
switch event[i] {
case ENTERING:
zonalSubscriptionEnteringMap[subsId] = zoneId
zonalSubscriptionLeavingMap[subsId] = zoneId
zonalSubscriptionTransferringMap[subsId] = zoneId
default:
}
}
} else {
zonalSubscriptionEnteringMap[subsId] = zoneId
zonalSubscriptionLeavingMap[subsId] = zoneId
zonalSubscriptionTransferringMap[subsId] = zoneId
}
zonalSubscriptionMap[subsId] = zoneId
}
func deregisterUser(subsIdStr string) {
subsId, _ := strconv.Atoi(subsIdStr)
userSubscriptionMap[subsId] = ""
userSubscriptionEnteringMap[subsId] = ""
userSubscriptionLeavingMap[subsId] = ""
userSubscriptionTransferringMap[subsId] = ""
func registerUser(userAddress string, event []UserEventType, subsIdStr string) {
subsId, _ := strconv.Atoi(subsIdStr)
if event != nil {
for i := 0; i < len(event); i++ {
switch event[i] {
case ENTERING:
userSubscriptionEnteringMap[subsId] = userAddress
userSubscriptionLeavingMap[subsId] = userAddress
userSubscriptionTransferringMap[subsId] = userAddress
default:
}
}
} else {
userSubscriptionEnteringMap[subsId] = userAddress
userSubscriptionLeavingMap[subsId] = userAddress
userSubscriptionTransferringMap[subsId] = userAddress
}
userSubscriptionMap[subsId] = userAddress
}
func checkNotificationRegistrations(checkType int, param1 string, param2 string, param3 string, param4 string, param5 string) {
switch checkType {
case USER_TRACKING_AND_ZONAL_TRAFFIC:
//params are the following => newZoneId:oldZoneId:newAccessPointId:oldAccessPointId:userAddress
checkNotificationRegisteredUsers(param1, param2, param3, param4, param5)
checkNotificationRegisteredZones(param1, param2, param3, param4, param5)
case ZONE_STATUS:
//params are the following => zoneId:accessPointId:nbUsersInAP:nbUsersInZone
checkNotificationRegisteredZoneStatus(param1, param2, param3, param4)
default:
Simon Pastor
committed
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
}
}
func checkNotificationRegisteredZoneStatus(zoneId string, apId string, nbUsersInAPStr string, nbUsersInZoneStr string) {
//check all that applies
for subsId, zoneStatus := range zoneStatusSubscriptionMap {
if zoneStatus.ZoneId == zoneId {
nbUsersInZone := 0
nbUsersInAP := -1
zoneWarning := false
apWarning := false
if nbUsersInZoneStr != "" {
nbUsersInZone, _ = strconv.Atoi(nbUsersInZoneStr)
if nbUsersInZone >= zoneStatus.NbUsersInZoneThreshold {
zoneWarning = true
}
}
if nbUsersInAPStr != "" {
nbUsersInAP, _ = strconv.Atoi(nbUsersInAPStr)
if nbUsersInAP >= zoneStatus.NbUsersInAPThreshold {
apWarning = true
}
}
if zoneWarning || apWarning {
subsIdStr := strconv.Itoa(subsId)
Kevin Di Lallo
committed
jsonInfo, _ := rc.JSONGetEntry(baseKey+typeZoneStatusSubscription+":"+subsIdStr, ".")
Simon Pastor
committed
if jsonInfo == "" {
return
}
subscription := convertJsonToZoneStatusSubscription(jsonInfo)
var zoneStatusNotif clientNotifOMA.ZoneStatusNotification
zoneStatusNotif.ZoneId = zoneId
if apWarning {
zoneStatusNotif.AccessPointId = apId
zoneStatusNotif.NumberOfUsersInAP = (int32)(nbUsersInAP)
Simon Pastor
committed
}
if zoneWarning {
zoneStatusNotif.NumberOfUsersInZone = (int32)(nbUsersInZone)
Simon Pastor
committed
}
Simon Pastor
committed
zoneStatusNotif.Timestamp = time.Now()
Simon Pastor
committed
go sendStatusNotification(subscription.CallbackReference.NotifyURL, context.TODO(), subsIdStr, zoneStatusNotif)
if apWarning {
log.Info("Zone Status Notification" + "(" + subsIdStr + "): " + "For event in zone " + zoneId + " which has " + nbUsersInAPStr + " users in AP " + apId)
} else {
log.Info("Zone Status Notification" + "(" + subsIdStr + "): " + "For event in zone " + zoneId + " which has " + nbUsersInZoneStr + " users in total")
}
}
}
}
}
func checkNotificationRegisteredUsers(oldZoneId string, newZoneId string, oldApId string, newApId string, userId string) {
//check all that applies
for subsId, value := range userSubscriptionMap {
subsIdStr := strconv.Itoa(subsId)
Kevin Di Lallo
committed
jsonInfo, _ := rc.JSONGetEntry(baseKey+typeUserSubscription+":"+subsIdStr, ".")
if jsonInfo == "" {
return
}
subscription := convertJsonToUserSubscription(jsonInfo)
Simon Pastor
committed
var zonal clientNotifOMA.TrackingNotification
Simon Pastor
committed
zonal.Timestamp = time.Now()
zonal.CallbackData = subscription.ClientCorrelator
if newZoneId != oldZoneId {
if userSubscriptionEnteringMap[subsId] != "" {
zonal.ZoneId = newZoneId
zonal.CurrentAccessPointId = newApId
Simon Pastor
committed
event := new(clientNotifOMA.UserEventType)
Simon Pastor
committed
zonal.UserEventType = event
go sendNotification(subscription.CallbackReference.NotifyURL, context.TODO(), subsIdStr, zonal)
log.Info("User Notification" + "(" + subsIdStr + "): " + "Entering event in zone " + newZoneId + " for user " + userId)
}
if oldZoneId != "" {
if userSubscriptionLeavingMap[subsId] != "" {
zonal.ZoneId = oldZoneId
zonal.CurrentAccessPointId = oldApId
Simon Pastor
committed
event := new(clientNotifOMA.UserEventType)
Simon Pastor
committed
zonal.UserEventType = event
go sendNotification(subscription.CallbackReference.NotifyURL, context.TODO(), subsIdStr, zonal)
log.Info("User Notification" + "(" + subsIdStr + "): " + "Leaving event in zone " + oldZoneId + " for user " + userId)
}
}
} else {
if newApId != oldApId {
if userSubscriptionTransferringMap[subsId] != "" {
zonal.ZoneId = newZoneId
zonal.CurrentAccessPointId = newApId
zonal.PreviousAccessPointId = oldApId
Simon Pastor
committed
event := new(clientNotifOMA.UserEventType)
Simon Pastor
committed
zonal.UserEventType = event
go sendNotification(subscription.CallbackReference.NotifyURL, context.TODO(), subsIdStr, zonal)
log.Info("User Notification" + "(" + subsIdStr + "): " + " Transferring event within zone " + newZoneId + " for user " + userId + " from Ap " + oldApId + " to " + newApId)
}
}
Simon Pastor
committed
func sendNotification(notifyUrl string, ctx context.Context, subscriptionId string, notification clientNotifOMA.TrackingNotification) {
client, err := createClient(notifyUrl)
if err != nil {
log.Error(err)
return
}
resp, err := client.NotificationsApi.PostTrackingNotification(ctx, subscriptionId, notification)
Kevin Di Lallo
committed
if err != nil {
log.Error(err)
return
}
defer resp.Body.Close()
jsonNotif, err := json.Marshal(notification)
if err != nil {
log.Error(err.Error())
}
_ = httpLog.LogTx(notifyUrl, "POST", string(jsonNotif), resp, startTime)
Simon Pastor
committed
func sendStatusNotification(notifyUrl string, ctx context.Context, subscriptionId string, notification clientNotifOMA.ZoneStatusNotification) {
Simon Pastor
committed
client, err := createClient(notifyUrl)
if err != nil {
log.Error(err)
return
}
resp, err := client.NotificationsApi.PostZoneStatusNotification(ctx, subscriptionId, notification)
Kevin Di Lallo
committed
if err != nil {
log.Error(err)
return
}
defer resp.Body.Close()
jsonNotif, err := json.Marshal(notification)
if err != nil {
log.Error(err.Error())
}
_ = httpLog.LogTx(notifyUrl, "POST", string(jsonNotif), resp, startTime)
Simon Pastor
committed
}
func checkNotificationRegisteredZones(oldZoneId string, newZoneId string, oldApId string, newApId string, userId string) {
//check all that applies
for subsId, value := range zonalSubscriptionMap {
if value == newZoneId {
if newZoneId != oldZoneId {
if zonalSubscriptionEnteringMap[subsId] != "" {
subsIdStr := strconv.Itoa(subsId)
Kevin Di Lallo
committed
jsonInfo, _ := rc.JSONGetEntry(baseKey+typeZonalSubscription+":"+subsIdStr, ".")
if jsonInfo != "" {
subscription := convertJsonToZonalSubscription(jsonInfo)
Simon Pastor
committed
var zonal clientNotifOMA.TrackingNotification
zonal.ZoneId = newZoneId
zonal.CurrentAccessPointId = newApId
zonal.Address = userId
Simon Pastor
committed
event := new(clientNotifOMA.UserEventType)
Simon Pastor
committed
zonal.UserEventType = event
zonal.Timestamp = time.Now()
zonal.CallbackData = subscription.ClientCorrelator
go sendNotification(subscription.CallbackReference.NotifyURL, context.TODO(), subsIdStr, zonal)
log.Info("Zonal Notify Entering event in zone " + newZoneId + " for user " + userId)
}
}
} else {
if newApId != oldApId {
if zonalSubscriptionTransferringMap[subsId] != "" {
subsIdStr := strconv.Itoa(subsId)
Kevin Di Lallo
committed
jsonInfo, _ := rc.JSONGetEntry(baseKey+typeZonalSubscription+":"+subsIdStr, ".")
if jsonInfo != "" {
subscription := convertJsonToZonalSubscription(jsonInfo)
Simon Pastor
committed
var zonal clientNotifOMA.TrackingNotification
zonal.ZoneId = newZoneId
zonal.CurrentAccessPointId = newApId
zonal.PreviousAccessPointId = oldApId
zonal.Address = userId
Simon Pastor
committed
event := new(clientNotifOMA.UserEventType)
Simon Pastor
committed
zonal.UserEventType = event
zonal.Timestamp = time.Now()
zonal.CallbackData = subscription.ClientCorrelator
go sendNotification(subscription.CallbackReference.NotifyURL, context.TODO(), subsIdStr, zonal)
log.Info("Zonal Notify Transferring event in zone " + newZoneId + " for user " + userId + " from Ap " + oldApId + " to " + newApId)
}
}
}
} else {
if value == oldZoneId {
if zonalSubscriptionLeavingMap[subsId] != "" {
subsIdStr := strconv.Itoa(subsId)
Kevin Di Lallo
committed
jsonInfo, _ := rc.JSONGetEntry(baseKey+typeZonalSubscription+":"+subsIdStr, ".")
if jsonInfo != "" {
subscription := convertJsonToZonalSubscription(jsonInfo)
Simon Pastor
committed
var zonal clientNotifOMA.TrackingNotification
zonal.ZoneId = oldZoneId
zonal.CurrentAccessPointId = oldApId
zonal.Address = userId
Simon Pastor
committed
event := new(clientNotifOMA.UserEventType)
Simon Pastor
committed
zonal.UserEventType = event
zonal.Timestamp = time.Now()
zonal.CallbackData = subscription.ClientCorrelator
go sendNotification(subscription.CallbackReference.NotifyURL, context.TODO(), subsIdStr, zonal)
log.Info("Zonal Notify Leaving event in zone " + oldZoneId + " for user " + userId)
}
}
}
}
}
}
func usersGet(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
u, _ := url.Parse(r.URL.String())
log.Info("url: ", u.RequestURI())
q := u.Query()
zoneIdVar := q.Get("zoneId")
accessPointIdVar := q.Get("accessPointId")
response.UserList = &userList
Kevin Di Lallo
committed
_ = rc.JSONGetList(zoneIdVar, accessPointIdVar, baseKey+typeUser+":", populateUserList, &userList)
Kevin Di Lallo
committed
userList.ResourceURL = hostUrl.String() + basePath + "users"
jsonResponse, err := json.Marshal(response)
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
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 populateUserList(key string, jsonInfo string, zoneId string, apId string, userData interface{}) error {
userList := userData.(*UserList)
var userInfo UserInfo
// Format response
err := json.Unmarshal([]byte(jsonInfo), &userInfo)
if err != nil {
return err
}
found1 := false
found2 := false
if zoneId != "" {
if userInfo.ZoneId == zoneId {
found1 = true
}
} else {
found1 = true
}
if apId != "" {
if userInfo.AccessPointId == apId {
found2 = true
}
} else {
found2 = true
}
if found1 && found2 {
userList.User = append(userList.User, userInfo)
}
return nil
}
func usersGetById(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
vars := mux.Vars(r)
var userInfo UserInfo
response.UserInfo = &userInfo
Kevin Di Lallo
committed
jsonUserInfo, _ := rc.JSONGetEntry(baseKey+typeUser+":"+vars["userId"], ".")
if jsonUserInfo == "" {
w.WriteHeader(http.StatusNotFound)
return
}
err := json.Unmarshal([]byte(jsonUserInfo), &userInfo)
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 zonesByIdGetAps(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
u, _ := url.Parse(r.URL.String())
log.Info("url: ", u.RequestURI())
q := u.Query()
interestRealm := q.Get("interestRealm")
var apList AccessPointList
response.AccessPointList = &apList
vars := mux.Vars(r)
Kevin Di Lallo
committed
_ = rc.JSONGetList(interestRealm, "", baseKey+typeZone+":"+vars["zoneId"], populateApList, &apList)
apList.ZoneId = vars["zoneId"]
Kevin Di Lallo
committed
apList.ResourceURL = hostUrl.String() + basePath + "zones/" + vars["zoneId"] + "/accessPoints"
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 zonesByIdGetApsById(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
vars := mux.Vars(r)
var apInfo AccessPointInfo
response.AccessPointInfo = &apInfo
Kevin Di Lallo
committed
jsonApInfo, _ := rc.JSONGetEntry(baseKey+typeZone+":"+vars["zoneId"]+":"+typeAccessPoint+":"+vars["accessPointId"], ".")
if jsonApInfo == "" {
w.WriteHeader(http.StatusNotFound)
return
}
err := json.Unmarshal([]byte(jsonApInfo), &apInfo)
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 zonesGet(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
response.ZoneList = &zoneList
Kevin Di Lallo
committed
_ = rc.JSONGetList("", "", baseKey+typeZone+":", populateZoneList, &zoneList)
Kevin Di Lallo
committed
zoneList.ResourceURL = hostUrl.String() + basePath + "zones"
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 zonesGetById(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
vars := mux.Vars(r)
var zoneInfo ZoneInfo
response.ZoneInfo = &zoneInfo
Kevin Di Lallo
committed
jsonZoneInfo, _ := rc.JSONGetEntry(baseKey+typeZone+":"+vars["zoneId"], ".")
if jsonZoneInfo == "" {
w.WriteHeader(http.StatusNotFound)
return
}
err := json.Unmarshal([]byte(jsonZoneInfo), &zoneInfo)
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))
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
}
func populateZoneList(key string, jsonInfo string, dummy1 string, dummy2 string, userData interface{}) error {
zoneList := userData.(*ZoneList)
var zoneInfo ZoneInfo
// Format response
err := json.Unmarshal([]byte(jsonInfo), &zoneInfo)
if err != nil {
return err
}
if zoneInfo.ZoneId != "" {
zoneList.Zone = append(zoneList.Zone, zoneInfo)
}
return nil
}
func populateApList(key string, jsonInfo string, interestRealm string, dummy string, userData interface{}) error {
apList := userData.(*AccessPointList)
var apInfo AccessPointInfo
// Format response
err := json.Unmarshal([]byte(jsonInfo), &apInfo)
if err != nil {
return err
}
if apInfo.AccessPointId != "" {
found := false
if interestRealm != "" {
if apInfo.InterestRealm == interestRealm {
found = true
}
} else {
found = true
}
if found {
apList.AccessPoint = append(apList.AccessPoint, apInfo)
}
}
return nil
}
func userTrackingSubDelById(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
vars := mux.Vars(r)
Kevin Di Lallo
committed
err := rc.JSONDelEntry(baseKey+typeUserSubscription+":"+vars["subscriptionId"], ".")
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
deregisterUser(vars["subscriptionId"])
w.WriteHeader(http.StatusNoContent)
}
func userTrackingSubGet(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
var response ResponseUserTrackingNotificationSubscriptionList
var userTrackingSubList UserTrackingNotificationSubscriptionList
response.NotificationSubscriptionList = &userTrackingSubList
Kevin Di Lallo
committed
_ = rc.JSONGetList("", "", baseKey+typeUserSubscription, populateUserTrackingList, &userTrackingSubList)
Kevin Di Lallo
committed
userTrackingSubList.ResourceURL = hostUrl.String() + basePath + "subscriptions/userTracking"
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 userTrackingSubGetById(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
vars := mux.Vars(r)
var userTrackingSub UserTrackingSubscription
response.UserTrackingSubscription = &userTrackingSub
Kevin Di Lallo
committed
jsonUserTrackingSub, _ := rc.JSONGetEntry(baseKey+typeUserSubscription+":"+vars["subscriptionId"], ".")
if jsonUserTrackingSub == "" {
w.WriteHeader(http.StatusNotFound)
return
}
err := json.Unmarshal([]byte(jsonUserTrackingSub), &userTrackingSub)
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 userTrackingSubPost(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
userTrackingSub := new(UserTrackingSubscription)
response.UserTrackingSubscription = userTrackingSub
decoder := json.NewDecoder(r.Body)
err := decoder.Decode(&userTrackingSub)
if err != nil {
log.Error(err.Error())
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
newSubsId := nextUserSubscriptionIdAvailable
nextUserSubscriptionIdAvailable++
subsIdStr := strconv.Itoa(newSubsId)
registerUser(userTrackingSub.Address, userTrackingSub.UserEventCriteria, subsIdStr)
Kevin Di Lallo
committed
userTrackingSub.ResourceURL = hostUrl.String() + basePath + "subscriptions/userTracking/" + subsIdStr
Kevin Di Lallo
committed
_ = rc.JSONSetEntry(baseKey+typeUserSubscription+":"+subsIdStr, ".", convertUserSubscriptionToJson(userTrackingSub))
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 userTrackingSubPutById(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
vars := mux.Vars(r)
userTrackingSub := new(UserTrackingSubscription)
response.UserTrackingSubscription = userTrackingSub
decoder := json.NewDecoder(r.Body)
err := decoder.Decode(&userTrackingSub)
if err != nil {
log.Error(err.Error())
http.Error(w, err.Error(), http.StatusInternalServerError)
}
subsIdStr := vars["subscriptionId"]
Kevin Di Lallo
committed
userTrackingSub.ResourceURL = hostUrl.String() + basePath + "subscriptions/userTracking/" + subsIdStr
Kevin Di Lallo
committed
_ = rc.JSONSetEntry(baseKey+typeUserSubscription+":"+subsIdStr, ".", convertUserSubscriptionToJson(userTrackingSub))
deregisterUser(subsIdStr)
registerUser(userTrackingSub.Address, userTrackingSub.UserEventCriteria, subsIdStr)
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, dummy1 string, dummy2 string, userData interface{}) error {
userList := userData.(*UserTrackingNotificationSubscriptionList)
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 zonalTrafficSubDelById(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
vars := mux.Vars(r)
Kevin Di Lallo
committed
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 zonalTrafficSubGet(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
var response ResponseZonalTrafficNotificationSubscriptionList
var zonalTrafficSubList ZonalTrafficNotificationSubscriptionList
response.NotificationSubscriptionList = &zonalTrafficSubList
Kevin Di Lallo
committed
_ = rc.JSONGetList("", "", baseKey+typeZonalSubscription, populateZonalTrafficList, &zonalTrafficSubList)
Kevin Di Lallo
committed
zonalTrafficSubList.ResourceURL = hostUrl.String() + basePath + "subscriptions/zonalTraffic"
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 zonalTrafficSubGetById(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
vars := mux.Vars(r)
var zonalTrafficSub ZonalTrafficSubscription
response.ZonalTrafficSubscription = &zonalTrafficSub
Kevin Di Lallo
committed
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")
zonalTrafficSub := new(ZonalTrafficSubscription)
response.ZonalTrafficSubscription = zonalTrafficSub
decoder := json.NewDecoder(r.Body)
err := decoder.Decode(&zonalTrafficSub)
if err != nil {
log.Error(err.Error())
http.Error(w, err.Error(), http.StatusInternalServerError)
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 != "" && 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)
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))
}