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 (
"encoding/json"
"errors"
"fmt"
"net/http"
"net/url"
Kevin Di Lallo
committed
"os"
"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"
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 locServKey string = "loc-serv:"
const typeZone = "zone"
const typeAccessPoint = "accessPoint"
const typeUser = "user"
const typeZonalSubscription = "zonalsubs"
const typeUserSubscription = "usersubs"
const typeZoneStatusSubscription = "zonestatus"
Kevin Di Lallo
committed
type UeUserData struct {
queryZoneId []string
queryApId []string
queryAddress []string
Kevin Di Lallo
committed
}
type ApUserData struct {
queryInterestRealm string
apList *AccessPointList
}
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
Simon Pastor
committed
}
Kevin Di Lallo
committed
var LOC_SERV_DB = 0
var redisAddr string = "meep-redis-master.default.svc.cluster.local:6379"
var influxAddr string = "http://meep-influxdb.default.svc.cluster.local:8086"
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
func notImplemented(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
w.WriteHeader(http.StatusNotImplemented)
}
// Init - Location Service initialization
func Init() (err error) {
sandboxNameEnv := strings.TrimSpace(os.Getenv("MEEP_SANDBOX_NAME"))
if sandboxNameEnv != "" {
sandboxName = sandboxNameEnv
}
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
// hostUrl is the url of the node serving the resourceURL
// Retrieve public url address where service is reachable, if not present, use Host URL environment variable
hostUrl, err = url.Parse(strings.TrimSpace(os.Getenv("MEEP_PUBLIC_URL")))
if err != nil || hostUrl == nil || hostUrl.String() == "" {
hostUrl, err = url.Parse(strings.TrimSpace(os.Getenv("MEEP_HOST_URL")))
if err != nil {
hostUrl = new(url.URL)
}
Kevin Di Lallo
committed
}
Kevin Di Lallo
committed
// 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
_ = rc.DBFlush(baseKey)
userTrackingReInit()
zonalTrafficReInit()
Simon Pastor
committed
zoneStatusReInit()
Kevin Di Lallo
committed
// Initialize SBI
sbiCfg := sbi.SbiCfg{
SandboxName: sandboxName,
RedisAddr: redisAddr,
UserInfoCb: updateUserInfo,
ZoneInfoCb: updateZoneInfo,
ApInfoCb: updateAccessPointInfo,
ScenarioNameCb: updateStoreName,
CleanUpCb: cleanUp,
}
err = sbi.Init(sbiCfg)
if err != nil {
log.Error("Failed initialize SBI. Error: ", err)
return err
}
log.Info("SBI Initialized")
return nil
Kevin Di Lallo
committed
}
Kevin Di Lallo
committed
func Run() (err error) {
return sbi.Run()
Simon Pastor
committed
func deregisterZoneStatus(subsIdStr string) {
if err != nil {
log.Error(err)
}
Simon Pastor
committed
}
func registerZoneStatus(zoneId string, nbOfUsersZoneThreshold int32, nbOfUsersAPThreshold int32, opStatus []OperationStatus, subsIdStr string) {
Simon Pastor
committed
if err != nil {
log.Error(err)
}
Simon Pastor
committed
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 = nbOfUsersZoneThreshold
zoneStatus.NbUsersInAPThreshold = nbOfUsersAPThreshold
Simon Pastor
committed
zoneStatus.ZoneId = zoneId
Simon Pastor
committed
zoneStatusSubscriptionMap[subsId] = &zoneStatus
}
func deregisterZonal(subsIdStr string) {
subsId, err := strconv.Atoi(subsIdStr)
if err != nil {
log.Error(err)
}
zonalSubscriptionMap[subsId] = ""
zonalSubscriptionEnteringMap[subsId] = ""
zonalSubscriptionLeavingMap[subsId] = ""
zonalSubscriptionTransferringMap[subsId] = ""
func registerZonal(zoneId string, event []UserEventType, subsIdStr string) {
if err != nil {
log.Error(err)
}
if event != nil {
for i := 0; i < len(event); i++ {
switch event[i] {
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) {
if err != nil {
log.Error(err)
}
userSubscriptionMap[subsId] = ""
userSubscriptionEnteringMap[subsId] = ""
userSubscriptionLeavingMap[subsId] = ""
userSubscriptionTransferringMap[subsId] = ""
func registerUser(userAddress string, event []UserEventType, subsIdStr string) {
if err != nil {
log.Error(err)
}
if event != nil {
for i := 0; i < len(event); i++ {
switch event[i] {
userSubscriptionEnteringMap[subsId] = userAddress
userSubscriptionLeavingMap[subsId] = userAddress
userSubscriptionTransferringMap[subsId] = userAddress
default:
}
}
} else {
userSubscriptionEnteringMap[subsId] = userAddress
userSubscriptionLeavingMap[subsId] = userAddress
userSubscriptionTransferringMap[subsId] = userAddress
}
userSubscriptionMap[subsId] = userAddress
}
func checkNotificationRegisteredZoneStatus(zoneId string, apId string, nbUsersInAP int32, nbUsersInZone int32, previousNbUsersInAP int32, previousNbUsersInZone int32) {
Simon Pastor
committed
Simon Pastor
committed
//check all that applies
for subsId, zoneStatus := range zoneStatusSubscriptionMap {
Kevin Di Lallo
committed
if zoneStatus == nil {
continue
}
Simon Pastor
committed
Kevin Di Lallo
committed
if zoneStatus.ZoneId == zoneId {
Simon Pastor
committed
zoneWarning := false
apWarning := false
if nbUsersInZone != -1 {
if previousNbUsersInZone != nbUsersInZone && nbUsersInZone >= zoneStatus.NbUsersInZoneThreshold {
Simon Pastor
committed
zoneWarning = true
}
Simon Pastor
committed
}
if nbUsersInAP != -1 {
if previousNbUsersInAP != nbUsersInAP && nbUsersInAP >= zoneStatus.NbUsersInAPThreshold {
Simon Pastor
committed
apWarning = true
}
}
Simon Pastor
committed
Simon Pastor
committed
if zoneWarning || apWarning {
subsIdStr := strconv.Itoa(subsId)
jsonInfo, _ := rc.JSONGetEntry(baseKey+typeZoneStatusSubscription+":"+subsIdStr, ".")
if jsonInfo == "" {
return
}
Simon Pastor
committed
subscription := convertJsonToZoneStatusSubscription(jsonInfo)
Simon Pastor
committed
var zoneStatusNotif ZoneStatusNotification
zoneStatusNotif.ZoneId = zoneId
if apWarning {
zoneStatusNotif.AccessPointId = apId
Simon Pastor
committed
}
if zoneWarning {
Simon Pastor
committed
}
seconds := time.Now().Unix()
var timestamp TimeStamp
timestamp.Seconds = int32(seconds)
zoneStatusNotif.Timestamp = ×tamp
var inlineZoneStatusNotification InlineZoneStatusNotification
inlineZoneStatusNotification.ZoneStatusNotification = &zoneStatusNotif
sendStatusNotification(subscription.CallbackReference.NotifyURL, inlineZoneStatusNotification)
if apWarning {
log.Info("Zone Status Notification" + "(" + subsIdStr + "): " + "For event in zone " + zoneId + " which has " + strconv.Itoa(int(nbUsersInAP)) + " users in AP " + apId)
Simon Pastor
committed
} else {
log.Info("Zone Status Notification" + "(" + subsIdStr + "): " + "For event in zone " + zoneId + " which has " + strconv.Itoa(int(nbUsersInZone)) + " users in total")
Simon Pastor
committed
}
}
}
}
}
func checkNotificationRegisteredUsers(oldZoneId string, newZoneId string, oldApId string, newApId string, userId string) {
//check all that applies
for subsId, value := range userSubscriptionMap {
if value == userId {
subsIdStr := strconv.Itoa(subsId)
Kevin Di Lallo
committed
jsonInfo, _ := rc.JSONGetEntry(baseKey+typeUserSubscription+":"+subsIdStr, ".")
if jsonInfo == "" {
return
}
subscription := convertJsonToUserSubscription(jsonInfo)
var zonal ZonalPresenceNotification
seconds := time.Now().Unix()
var timestamp TimeStamp
timestamp.Seconds = int32(seconds)
zonal.Timestamp = ×tamp
zonal.CallbackData = subscription.ClientCorrelator
if newZoneId != oldZoneId {
if oldZoneId != "" {
if userSubscriptionLeavingMap[subsId] != "" {
zonal.ZoneId = oldZoneId
zonal.CurrentAccessPointId = oldApId
event := new(UserEventType)
*event = LEAVING_EVENT
zonal.UserEventType = event
var inlineZonal InlineZonalPresenceNotification
inlineZonal.ZonalPresenceNotification = &zonal
sendZonalPresenceNotification(subscription.CallbackReference.NotifyURL, inlineZonal)
log.Info("User Notification" + "(" + subsIdStr + "): " + "Leaving event in zone " + oldZoneId + " for user " + userId)
}
if userSubscriptionEnteringMap[subsId] != "" && newZoneId != "" {
zonal.ZoneId = newZoneId
zonal.CurrentAccessPointId = newApId
event := new(UserEventType)
*event = ENTERING_EVENT
var inlineZonal InlineZonalPresenceNotification
inlineZonal.ZonalPresenceNotification = &zonal
sendZonalPresenceNotification(subscription.CallbackReference.NotifyURL, inlineZonal)
log.Info("User Notification" + "(" + subsIdStr + "): " + "Entering event in zone " + newZoneId + " for user " + userId)
}
} else {
if newApId != oldApId {
if userSubscriptionTransferringMap[subsId] != "" {
zonal.ZoneId = newZoneId
zonal.CurrentAccessPointId = newApId
zonal.PreviousAccessPointId = oldApId
event := new(UserEventType)
*event = TRANSFERRING_EVENT
Simon Pastor
committed
zonal.UserEventType = event
var inlineZonal InlineZonalPresenceNotification
inlineZonal.ZonalPresenceNotification = &zonal
sendZonalPresenceNotification(subscription.CallbackReference.NotifyURL, inlineZonal)
log.Info("User Notification" + "(" + subsIdStr + "): " + " Transferring event within zone " + newZoneId + " for user " + userId + " from Ap " + oldApId + " to " + newApId)
}
}
func sendZonalPresenceNotification(notifyUrl string, notification InlineZonalPresenceNotification) {
jsonNotif, err := json.Marshal(notification)
if err != nil {
log.Error(err)
return
}
resp, err := http.Post(notifyUrl, "application/json", bytes.NewBuffer(jsonNotif))
_ = httpLog.LogTx(notifyUrl, "POST", string(jsonNotif), resp, startTime)
Kevin Di Lallo
committed
if err != nil {
log.Error(err)
return
}
func sendStatusNotification(notifyUrl string, notification InlineZoneStatusNotification) {
jsonNotif, err := json.Marshal(notification)
Simon Pastor
committed
if err != nil {
log.Error(err)
return
}
resp, err := http.Post(notifyUrl, "application/json", bytes.NewBuffer(jsonNotif))
_ = httpLog.LogTx(notifyUrl, "POST", string(jsonNotif), resp, startTime)
Kevin Di Lallo
committed
if err != nil {
log.Error(err)
return
}
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)
var zonal ZonalPresenceNotification
zonal.ZoneId = newZoneId
zonal.CurrentAccessPointId = newApId
zonal.Address = userId
event := new(UserEventType)
*event = ENTERING_EVENT
Simon Pastor
committed
zonal.UserEventType = event
seconds := time.Now().Unix()
var timestamp TimeStamp
timestamp.Seconds = int32(seconds)
zonal.Timestamp = ×tamp
zonal.CallbackData = subscription.ClientCorrelator
var inlineZonal InlineZonalPresenceNotification
inlineZonal.ZonalPresenceNotification = &zonal
sendZonalPresenceNotification(subscription.CallbackReference.NotifyURL, inlineZonal)
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)
var zonal ZonalPresenceNotification
zonal.ZoneId = newZoneId
zonal.CurrentAccessPointId = newApId
zonal.PreviousAccessPointId = oldApId
zonal.Address = userId
event := new(UserEventType)
*event = TRANSFERRING_EVENT
Simon Pastor
committed
zonal.UserEventType = event
seconds := time.Now().Unix()
var timestamp TimeStamp
timestamp.Seconds = int32(seconds)
zonal.Timestamp = ×tamp
zonal.CallbackData = subscription.ClientCorrelator
var inlineZonal InlineZonalPresenceNotification
inlineZonal.ZonalPresenceNotification = &zonal
sendZonalPresenceNotification(subscription.CallbackReference.NotifyURL, inlineZonal)
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)
var zonal ZonalPresenceNotification
zonal.ZoneId = oldZoneId
zonal.CurrentAccessPointId = oldApId
zonal.Address = userId
event := new(UserEventType)
*event = LEAVING_EVENT
Simon Pastor
committed
zonal.UserEventType = event
seconds := time.Now().Unix()
var timestamp TimeStamp
timestamp.Seconds = int32(seconds)
zonal.Timestamp = ×tamp
zonal.CallbackData = subscription.ClientCorrelator
var inlineZonal InlineZonalPresenceNotification
inlineZonal.ZonalPresenceNotification = &zonal
sendZonalPresenceNotification(subscription.CallbackReference.NotifyURL, inlineZonal)
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")
Kevin Di Lallo
committed
var userData UeUserData
Kevin Di Lallo
committed
// Retrieve query parameters
u, _ := url.Parse(r.URL.String())
log.Info("url: ", u.RequestURI())
q := u.Query()
userData.queryZoneId = q["zoneId"]
userData.queryApId = q["accessPointId"]
userData.queryAddress = q["address"]
validQueryParams := []string{"zoneId", "accessPointId", "address"}
//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
}
}
Kevin Di Lallo
committed
// Get user list from DB
userList.ResourceURL = hostUrl.String() + basePath + "queries/users"
response.UserList = &userList
Kevin Di Lallo
committed
userData.userList = &userList
Kevin Di Lallo
committed
keyName := baseKey + typeUser + ":*"
err := rc.ForEachJSONEntry(keyName, populateUserList, &userData)
if err != nil {
log.Error(err.Error())
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
Kevin Di Lallo
committed
// 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))
}
Kevin Di Lallo
committed
func populateUserList(key string, jsonInfo string, userData interface{}) error {
// Get query params & userlist from user data
data := userData.(*UeUserData)
if data == nil || data.userList == nil {
return errors.New("userList not found in userData")
}
Kevin Di Lallo
committed
// Retrieve user info from DB
var userInfo UserInfo
err := json.Unmarshal([]byte(jsonInfo), &userInfo)
if err != nil {
return err
}
Kevin Di Lallo
committed
// Ignore entries with no zoneID or AP ID
if userInfo.ZoneId == "" || userInfo.AccessPointId == "" {
return nil
Kevin Di Lallo
committed
//query parameters looked through using OR within same query parameter and AND between different query parameters
//example returning users matching zoneId : (zone01 OR zone02) AND accessPointId : (ap1 OR ap2 OR ap3) AND address: (ipAddress1 OR ipAddress2)
foundAMatch := false
Kevin Di Lallo
committed
// Filter using query params
if len(data.queryZoneId) > 0 {
foundAMatch = false
for _, queryZoneId := range data.queryZoneId {
if userInfo.ZoneId == queryZoneId {
foundAMatch = true
}
}
if !foundAMatch {
return nil
}
if len(data.queryApId) > 0 {
foundAMatch = false
for _, queryApId := range data.queryApId {
if userInfo.AccessPointId == queryApId {
foundAMatch = true
}
}
if !foundAMatch {
return nil
}
Kevin Di Lallo
committed
if len(data.queryAddress) > 0 {
foundAMatch = false
for _, queryAddress := range data.queryAddress {
if userInfo.Address == queryAddress {
foundAMatch = true
}
}
if !foundAMatch {
return nil
}
Kevin Di Lallo
committed
// Add user info to list
data.userList.User = append(data.userList.User, userInfo)
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
Kevin Di Lallo
committed
var userData ApUserData
vars := mux.Vars(r)
// Retrieve query parameters
u, _ := url.Parse(r.URL.String())
log.Info("url: ", u.RequestURI())
q := u.Query()
Kevin Di Lallo
committed
userData.queryInterestRealm = q.Get("interestRealm")
validQueryParams := []string{"interestRealm"}
//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
}
}
Kevin Di Lallo
committed
// Get user list from DB
var apList AccessPointList
apList.ZoneId = vars["zoneId"]
apList.ResourceURL = hostUrl.String() + basePath + "queries/zones/" + vars["zoneId"] + "/accessPoints"
Kevin Di Lallo
committed
response.AccessPointList = &apList
userData.apList = &apList
//make sure the zone exists first
jsonZoneInfo, _ := rc.JSONGetEntry(baseKey+typeZone+":"+vars["zoneId"], ".")
if jsonZoneInfo == "" {
w.WriteHeader(http.StatusNotFound)
return
}
Kevin Di Lallo
committed
keyName := baseKey + typeZone + ":" + vars["zoneId"] + ":*"
err := rc.ForEachJSONEntry(keyName, populateApList, &userData)
if err != nil {
log.Error(err.Error())
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
Kevin Di Lallo
committed
// 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))
}
func apByIdGet(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")
zoneList.ResourceURL = hostUrl.String() + basePath + "queries/zones"
response.ZoneList = &zoneList
Kevin Di Lallo
committed
keyName := baseKey + typeZone + ":*"
err := rc.ForEachJSONEntry(keyName, populateZoneList, &zoneList)
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 zonesByIdGet(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))
Kevin Di Lallo
committed
func populateZoneList(key string, jsonInfo 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
}
Kevin Di Lallo
committed
func populateApList(key string, jsonInfo string, userData interface{}) error {
// Get query params & aplist from user data
data := userData.(*ApUserData)
if data == nil || data.apList == nil {
return errors.New("apList not found in userData")
}
Kevin Di Lallo
committed
// Retrieve AP info from DB
var apInfo AccessPointInfo
err := json.Unmarshal([]byte(jsonInfo), &apInfo)
if err != nil {
return err
}
Kevin Di Lallo
committed
// Ignore entries with no AP ID
if apInfo.AccessPointId == "" {
return nil
}
// Filter using query params
if data.queryInterestRealm != "" && apInfo.InterestRealm != data.queryInterestRealm {
return nil
Kevin Di Lallo
committed
// Add AP info to list
data.apList.AccessPoint = append(data.apList.AccessPoint, apInfo)
func userTrackingSubDelete(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
vars := mux.Vars(r)
present, _ := rc.JSONGetEntry(baseKey+typeUserSubscription+":"+vars["subscriptionId"], ".")
if present == "" {
w.WriteHeader(http.StatusNotFound)
return
}
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 userTrackingSubListGet(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
var response InlineNotificationSubscriptionList
Kevin Di Lallo
committed
userTrackingSubList.ResourceURL = hostUrl.String() + basePath + "subscriptions/userTracking"
response.NotificationSubscriptionList = &userTrackingSubList
Kevin Di Lallo
committed
keyName := baseKey + typeUserSubscription + "*"
err := rc.ForEachJSONEntry(keyName, populateUserTrackingList, &userTrackingSubList)
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 userTrackingSubGet(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
vars := mux.Vars(r)
var response InlineUserTrackingSubscription
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")
var response InlineUserTrackingSubscription
var body InlineUserTrackingSubscription
decoder := json.NewDecoder(r.Body)
if err != nil {
log.Error(err.Error())
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
userTrackingSub := body.UserTrackingSubscription
if userTrackingSub == nil {
log.Error("Body not present")
http.Error(w, "Body not present", http.StatusBadRequest)
Simon Pastor
committed
//checking for mandatory properties
if userTrackingSub.CallbackReference == nil || userTrackingSub.CallbackReference.NotifyURL == "" {
log.Error("Mandatory CallbackReference parameter not present")
http.Error(w, "Mandatory CallbackReference parameter not present", http.StatusBadRequest)
Simon Pastor
committed
return
}
if userTrackingSub.Address == "" {
log.Error("Mandatory Address parameter not present")
http.Error(w, "Mandatory Address parameter not present", http.StatusBadRequest)