Newer
Older
/*
* Copyright (c) 2019 InterDigital Communications, Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use algo 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 netchar
import (
"errors"
"fmt"
"strconv"
"strings"
"time"
Kevin Di Lallo
committed
dkm "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-data-key-mgr"
dataModel "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-data-model"
log "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-logger"
mod "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-model"
redis "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-redis"
)
const MAX_THROUGHPUT = 9999999999
const THROUGHPUT_UNIT = 1000000 //convert from Mbps to bps
const DEFAULT_THROUGHPUT_LINK = 1000.0
const metricsDb = 0
Kevin Di Lallo
committed
const metricsKey string = "metrics:"
// SegAlgoConfig - Segment Algorithm Config
type SegAlgoConfig struct {
// Segment config
MaxBwPerInactiveFlow float64
MaxBwPerInactiveFlowFloor float64
MinActivityThreshold float64
IncrementalStep float64
InactivityIncrementalStep float64
TolerationThreshold float64
ActionUpperThreshold float64
// Debug Config
IsPercentage bool
LogVerbose bool
}
// SegAlgoSegment -
type SegAlgoSegment struct {
Name string
ConfiguredNetChar NetChar
MaxFairShareBwPerFlow float64
CurrentThroughput float64
MaxBwPerInactiveFlow float64
MinActivityThreshold float64
IncrementalStep float64
InactivityIncrementalStep float64
TolerationThreshold float64
ActionUpperThreshold float64
Flows []*SegAlgoFlow
}
// SegAlgoFlow -
type SegAlgoFlow struct {
Name string
SrcNetElem string
DstNetElem string
ConfiguredNetChar NetChar
AppliedNetChar NetChar
ComputedLatency float64
ComputedJitter float64
ComputedPacketLoss float64
AllocatedThroughput float64 //allocated
AllocatedThroughputLowerBound float64 //allocated
AllocatedThroughputUpperBound float64 //allocated
MaxPlannedThroughput float64
MaxPlannedLowerBound float64
MaxPlannedUpperBound float64
PlannedThroughput float64
PlannedLowerBound float64
PlannedUpperBound float64
CurrentThroughput float64 //measured
CurrentThroughputEgress float64 //measured
Path *SegAlgoPath
}
// SegAlgoPath -
type SegAlgoPath struct {
Name string
Segments []*SegAlgoSegment
}
// SegAlgoNetElem -
type SegAlgoNetElem struct {
Name string
Type string
PhyLocName string
PoaName string
ZoneName string
DomainName string
ConfiguredNetChar NetChar
}
// SegmentAlgorithm -
type SegmentAlgorithm struct {
Kevin Di Lallo
committed
Namespace string
BaseKey string
FlowMap map[string]*SegAlgoFlow
SegmentMap map[string]*SegAlgoSegment
Config SegAlgoConfig
rc *redis.Connector
}
// NewSegmentAlgorithm - Create, Initialize and connect
Kevin Di Lallo
committed
func NewSegmentAlgorithm(name string, namespace string, redisAddr string) (*SegmentAlgorithm, error) {
// Create new instance & set default config
var err error
var algo SegmentAlgorithm
Kevin Di Lallo
committed
algo.Namespace = namespace
algo.BaseKey = dkm.GetKeyRoot(namespace) + metricsKey
algo.FlowMap = make(map[string]*SegAlgoFlow)
algo.SegmentMap = make(map[string]*SegAlgoSegment)
algo.Config.MaxBwPerInactiveFlow = 20.0
algo.Config.MaxBwPerInactiveFlowFloor = 6.0
algo.Config.MinActivityThreshold = 0.3
algo.Config.IncrementalStep = 3.0
algo.Config.InactivityIncrementalStep = 1.0
algo.Config.ActionUpperThreshold = 1.0
algo.Config.TolerationThreshold = 4.0
algo.Config.IsPercentage = true
// Create connection to Metrics Redis DB & flush entries
algo.rc, err = redis.NewConnector(redisAddr, metricsDb)
if err != nil {
log.Error("Failed connection to Metrics redis DB. Error: ", err)
return nil, err
}
Kevin Di Lallo
committed
_ = algo.rc.DBFlush(algo.BaseKey)
log.Info("Connected to Metrics redis DB")
return &algo, nil
}
// ProcessScenario -
func (algo *SegmentAlgorithm) ProcessScenario(model *mod.Model) error {
var netElemList []SegAlgoNetElem
// Process empty scenario
if model.GetScenarioName() == "" {
// Remove any existing metrics
algo.deleteMetricsEntries()
//reset the map
algo.FlowMap = make(map[string]*SegAlgoFlow)
}
// Clear segment & flow maps
algo.SegmentMap = make(map[string]*SegAlgoSegment)
// Process active scenario
procNames := model.GetNodeNames("CLOUD-APP", "EDGE-APP", "UE-APP")
// Create NetElem for each scenario process
for _, name := range procNames {
// Retrieve node & context from model
node := model.GetNode(name)
if node == nil {
err := errors.New("Error finding process: " + name)
return err
}
proc, ok := node.(*dataModel.Process)
if !ok {
err := errors.New("Error casting process: " + name)
return err
}
ctx := model.GetNodeContext(name)
if ctx == nil {
err := errors.New("Error getting context for process: " + name)
return err
}
Kevin Di Lallo
committed
nodeCtx, ok := ctx.(*mod.NodeContext)
if !ok {
err := errors.New("Error casting context for process: " + name)
return err
}
// Create & populate new element
element := new(SegAlgoNetElem)
element.Name = proc.Name
Kevin Di Lallo
committed
element.PhyLocName = nodeCtx.Parents[mod.PhyLoc]
element.DomainName = nodeCtx.Parents[mod.Domain]
Loading
Loading full blame…