From a19c070e37221a27dc94c8bcbb23f7e3faa0e180 Mon Sep 17 00:00:00 2001 From: Mudassar Khan Date: Tue, 25 Nov 2025 10:25:18 +0000 Subject: [PATCH 01/15] feat: update deployment handling for MEC services - Append MEC platform name to MEC service deployments - Allow same-named MEC services on different platforms on the website - Update admin panel (/alt) to support these changes - Fix conflict where identical service names were previously not permitted --- go-apps/meep-sandbox-ctrl/server/app-ctrl.go | 21 +-- go-apps/meep-virt-engine/go.mod | 1 + .../meep-virt-engine/server/chart-template.go | 34 ++--- go-packages/meep-model/model.go | 123 ++++++++++-------- go-packages/meep-model/nodeMap.go | 33 +++-- go-packages/meep-model/validator.go | 12 +- .../cfg/cfg-network-element-container.js | 38 +++--- .../js/containers/cfg/cfg-page-container.js | 92 ++++++++++--- .../src/js/containers/cfg/cfg-table.js | 20 ++- .../src/js/containers/idc-map.js | 118 +++++++++++++---- .../meep-frontend/src/js/meep-constants.js | 26 ++-- .../src/js/state/cfg/table-reducer.js | 2 +- .../src/js/util/scenario-utils.js | 12 +- 13 files changed, 356 insertions(+), 176 deletions(-) diff --git a/go-apps/meep-sandbox-ctrl/server/app-ctrl.go b/go-apps/meep-sandbox-ctrl/server/app-ctrl.go index a798cd513..0e9cdc894 100644 --- a/go-apps/meep-sandbox-ctrl/server/app-ctrl.go +++ b/go-apps/meep-sandbox-ctrl/server/app-ctrl.go @@ -250,18 +250,23 @@ func getScenarioAppInstanceList(activeModel *mod.Model) ([]*apps.Application, er var appList []*apps.Application if activeModel != nil { - // Get active scenario node names - appNames := activeModel.GetNodeNames(mod.NodeTypeEdgeApp) - for _, appName := range appNames { - // Get scenario Process & context - proc, ctx, err := getScenarioProcess(appName, activeModel) - if err != nil { - log.Error(err.Error()) + // Get all processes + processes := activeModel.GetProcesses(nil) + for _, proc := range processes.Processes { + // Only handle EDGE-APP for duplicates + if proc.Type_ != mod.NodeTypeEdgeApp { + continue + } + + // Get context by ID + ctx := activeModel.GetNodeContextById(proc.Id) + if ctx == nil { + log.Error("Failed to get context for process ID: " + proc.Id) continue } // Create app instance - app, err := createAppInstance(proc, ctx) + app, err := createAppInstance(&proc, ctx) if err != nil { log.Error(err.Error()) continue diff --git a/go-apps/meep-virt-engine/go.mod b/go-apps/meep-virt-engine/go.mod index e80bab808..88c118c87 100644 --- a/go-apps/meep-virt-engine/go.mod +++ b/go-apps/meep-virt-engine/go.mod @@ -8,6 +8,7 @@ require ( github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-model v0.0.0 github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-mq v0.0.0 github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-watchdog v0.0.0 + github.com/google/uuid v1.2.0 // indirect ) replace ( diff --git a/go-apps/meep-virt-engine/server/chart-template.go b/go-apps/meep-virt-engine/server/chart-template.go index 7681a9970..a8763b5db 100644 --- a/go-apps/meep-virt-engine/server/chart-template.go +++ b/go-apps/meep-virt-engine/server/chart-template.go @@ -182,29 +182,22 @@ func getAppEnablement(mepName string, model *mod.Model) string { func generateScenarioCharts(sandboxName string, procName string, model *mod.Model) (charts []helm.Chart, err error) { serviceMap := map[string]string{} - procNames := model.GetNodeNames("CLOUD-APP") - procNames = append(procNames, model.GetNodeNames("EDGE-APP")...) - procNames = append(procNames, model.GetNodeNames("UE-APP")...) - for _, name := range procNames { + processes := model.GetProcesses(nil) + for _, proc := range processes.Processes { // Check if single process is being added - if procName != "" && name != procName { + if procName != "" && proc.Name != procName { continue } // Retrieve node process information from model - node := model.GetNode(name) + node := model.GetNodeById(proc.Id) if node == nil { - err = errors.New("Error finding process: " + name) - return nil, err - } - proc, ok := node.(*dataModel.Process) - if !ok { - err = errors.New("Error casting process: " + name) + err = errors.New("Error finding process: " + proc.Name + " with ID: " + proc.Id) return nil, err } - ctx := model.GetNodeContext(name) + ctx := model.GetNodeContextById(proc.Id) if ctx == nil { - err = errors.New("Error finding context for process: " + name) + err = errors.New("Error finding context for process: " + proc.Name + " with ID: " + proc.Id) return nil, err } @@ -256,12 +249,13 @@ func generateScenarioCharts(sandboxName string, procName string, model *mod.Mode } } } - } else if mepService := getMepService(proc); mepService != "" { + } else if mepService := getMepService(&proc); mepService != "" { log.Debug("Processing MEP Service chart for element[", proc.Name, "]") // Get MEP Name mepName := ctx.Parents[mod.PhyLoc] + // Important part of code. // Create Sandbox template var sandboxTemplate SandboxTemplate sandboxTemplate.InstanceId = proc.Id @@ -291,7 +285,10 @@ func generateScenarioCharts(sandboxName string, procName string, model *mod.Mode } // Create chart - chartName := proc.Name + chartName := mepName + "-" + proc.Name + if len(chartName) > 53 { + chartName = chartName[:53] + } chartLocation, _, err := createChart(chartName, sandboxName, scenarioName, mepService, sandboxTemplate) if err != nil { log.Debug("yaml creation file process: ", err) @@ -572,6 +569,11 @@ func newChart(chartName string, sandboxName string, scenarioName string, chartLo chart.ReleaseName = "meep-" + scenarioName + "-" + chartName } + // Truncate release name to 53 characters to comply with Helm requirements + if len(chart.ReleaseName) > 53 { + chart.ReleaseName = chart.ReleaseName[:53] + } + chart.Name = chartName chart.Namespace = sandboxName chart.Location = chartLocation diff --git a/go-packages/meep-model/model.go b/go-packages/meep-model/model.go index 97c1030be..77633f414 100644 --- a/go-packages/meep-model/model.go +++ b/go-packages/meep-model/model.go @@ -19,6 +19,7 @@ package model import ( "encoding/json" "errors" + "fmt" "reflect" "strings" "sync" @@ -240,6 +241,7 @@ func (m *Model) SetScenario(j []byte) (err error) { m.scenario = scenario err = m.parseNodes() + // No Prob in Parsing Nodes if err != nil { log.Error(err.Error()) return err @@ -368,7 +370,7 @@ func (m *Model) GetServiceMaps() *[]dataModel.NodeServiceMaps { return &m.svcMap } -//UpdateNetChar - Update network characteristics for a node +// UpdateNetChar - Update network characteristics for a node func (m *Model) UpdateNetChar(nc *dataModel.EventNetworkCharacteristicsUpdate, userData interface{}) (err error) { m.lock.Lock() defer m.lock.Unlock() @@ -550,12 +552,6 @@ func (m *Model) addPhyLoc(node *dataModel.ScenarioNode, parentNode *Node) (err e return err } - // Make sure node Name is unique - n := m.nodeMap.FindByName(pl.Name) - if n != nil { - return errors.New("Element " + pl.Name + " already exists in scenario " + m.name) - } - // Ignore any configured processes pl.Processes = make([]dataModel.Process, 0) @@ -581,12 +577,6 @@ func (m *Model) addProcess(node *dataModel.ScenarioNode, parentNode *Node) (err return err } - // Make sure node Name is unique - n := m.nodeMap.FindByName(proc.Name) - if n != nil { - return errors.New("Element " + proc.Name + " already exists in scenario " + m.name) - } - // Add Proc to parent PhyLoc pl.Processes = append(pl.Processes, *proc) @@ -838,7 +828,7 @@ func (m *Model) removeProcess(node *dataModel.ScenarioNode) (err error) { return nil } -//GetScenarioName - Get the scenario name +// GetScenarioName - Get the scenario name func (m *Model) GetScenarioName() string { m.lock.RLock() defer m.lock.RUnlock() @@ -850,7 +840,7 @@ func (m *Model) GetScenarioName() string { return "" } -//GetNodeNames - Get the list of nodes of a certain type; "" or "ANY" returns all +// GetNodeNames - Get the list of nodes of a certain type; "" or "ANY" returns all func (m *Model) GetNodeNames(typ ...string) []string { m.lock.RLock() defer m.lock.RUnlock() @@ -858,11 +848,15 @@ func (m *Model) GetNodeNames(typ ...string) []string { nm := make(map[string]*Node) for _, t := range typ { if t == "" || t == "ANY" { - nm = m.nodeMap.nameMap + for name, nodes := range m.nodeMap.nameMap { + if len(nodes) > 0 { + nm[name] = nodes[0] + } + } break } - for k, v := range m.nodeMap.typeMap[t] { - nm[k] = v + for name, node := range m.nodeMap.FindAllByType(t) { + nm[name] = node } } @@ -873,41 +867,46 @@ func (m *Model) GetNodeNames(typ ...string) []string { return list } -//GetEdges - Get a map of node edges for the current scenario +// GetEdges - Get a map of node edges for the current scenario func (m *Model) GetEdges() (edgeMap map[string]string) { m.lock.RLock() defer m.lock.RUnlock() edgeMap = make(map[string]string) - for k, node := range m.nodeMap.nameMap { - p := reflect.ValueOf(node.parent) - pName := reflect.Indirect(p).FieldByName("Name") - if pName.IsValid() { - edgeMap[k] = pName.String() - // fmt.Printf("%s (%T) \t\t %s(%T)\n", k, node.object, pName, node.parent) + for k, nodes := range m.nodeMap.nameMap { + if len(nodes) > 0 { + node := nodes[0] + p := reflect.ValueOf(node.parent) + pName := reflect.Indirect(p).FieldByName("Name") + if pName.IsValid() { + edgeMap[k] = pName.String() + // fmt.Printf("%s (%T) \t\t %s(%T)\n", k, node.object, pName, node.parent) + } } } return edgeMap } // GetNode - Get a node by its name -// Returned value is of type interface{} -// Good practice: returned node should be type asserted with val,ok := node.(someType) to prevent panic +// +// Returned value is of type interface{} +// Good practice: returned node should be type asserted with val,ok := node.(someType) to prevent panic func (m *Model) GetNode(name string) (node interface{}) { m.lock.RLock() defer m.lock.RUnlock() node = nil n := m.nodeMap.nameMap[name] - if n != nil { - node = n.object + if len(n) > 0 { + node = n[0].object } return node } // GetNodeById - Get a node by its id -// Returned value is of type interface{} -// Returned node may be nil +// +// Returned value is of type interface{} +// Returned node may be nil func (m *Model) GetNodeById(id string) (node interface{}) { m.lock.RLock() defer m.lock.RUnlock() @@ -927,8 +926,8 @@ func (m *Model) GetNodeId(name string) (id string) { id = "" n := m.nodeMap.nameMap[name] - if n != nil { - id = n.id + if len(n) > 0 { + id = n[0].id } return id } @@ -940,8 +939,8 @@ func (m *Model) GetNodeType(name string) (typ string) { typ = "" n := m.nodeMap.nameMap[name] - if n != nil { - typ = n.nodeType + if len(n) > 0 { + typ = n[0].nodeType } return typ } @@ -953,8 +952,8 @@ func (m *Model) GetNodeParent(name string) (parent interface{}) { parent = nil n := m.nodeMap.nameMap[name] - if n != nil { - parent = n.parent + if len(n) > 0 { + parent = n[0].parent } return parent } @@ -966,8 +965,8 @@ func (m *Model) GetNodeChild(name string) (child interface{}) { child = nil n := m.nodeMap.nameMap[name] - if n != nil { - child = n.child + if len(n) > 0 { + child = n[0].child } return child } @@ -979,11 +978,30 @@ func (m *Model) GetNodeContext(name string) (ctx *NodeContext) { ctx = nil n := m.nodeMap.nameMap[name] + log.Debug("Node name: ", name, " Node: ", fmt.Sprintf("%+v", n)) + if len(n) > 0 { + nodeCtx := n[0].context + var ok bool + if ctx, ok = nodeCtx.(*NodeContext); !ok { + log.Error("Error casting node context for node: " + name) + return nil + } + } + return ctx +} + +// GetNodeContextById - Get a node context by ID +func (m *Model) GetNodeContextById(id string) (ctx *NodeContext) { + m.lock.RLock() + defer m.lock.RUnlock() + + ctx = nil + n := m.nodeMap.idMap[id] if n != nil { nodeCtx := n.context var ok bool if ctx, ok = nodeCtx.(*NodeContext); !ok { - log.Error("Error casting node context for node: " + name) + log.Error("Error casting node context for node ID: " + id) return nil } } @@ -1221,21 +1239,20 @@ func (m *Model) GetProcesses(filter *NodeFilter) dataModel.Processes { m.lock.RLock() defer m.lock.RUnlock() - // Get process nodes - nMap := make(map[string]*Node) - m.mergeNodeMap(nMap, m.nodeMap.FindAllByType(NodeTypeUEApp)) - m.mergeNodeMap(nMap, m.nodeMap.FindAllByType(NodeTypeEdgeApp)) - m.mergeNodeMap(nMap, m.nodeMap.FindAllByType(NodeTypeCloudApp)) - // Find nodes that match filter criteria var processes dataModel.Processes processes.Processes = []dataModel.Process{} - for _, node := range nMap { - if m.filterNode(node, Proc, filter) { - process := *(node.object.(*dataModel.Process)) - - // Append process to list - processes.Processes = append(processes.Processes, process) + types := []string{NodeTypeUEApp, NodeTypeEdgeApp, NodeTypeCloudApp} + for _, typ := range types { + for _, nodes := range m.nodeMap.typeMap[typ] { + for _, node := range nodes { + if m.filterNode(node, Proc, filter) { + process := *(node.object.(*dataModel.Process)) + + // Append process to list + processes.Processes = append(processes.Processes, process) + } + } } } return processes @@ -1316,7 +1333,7 @@ func (m *Model) parseNodes() (err error) { procCtx := NewNodeContext(m.scenario.Name, domain.Name, zone.Name, nl.Name, pl.Name) m.nodeMap.AddNode(NewNode(proc.Id, proc.Name, proc.Type_, proc, nil, pl, procCtx)) m.networkGraph.AddNode(proc.Name, pl.Name, false) - + log.Info("Model.go: Added process: ", proc.Name, " type: ", proc.Type_, " to physical location: ", pl.Name) // Update service map for external processes if proc.IsExternal { var nodeServiceMaps dataModel.NodeServiceMaps diff --git a/go-packages/meep-model/nodeMap.go b/go-packages/meep-model/nodeMap.go index 298fbb302..f8c897400 100644 --- a/go-packages/meep-model/nodeMap.go +++ b/go-packages/meep-model/nodeMap.go @@ -30,16 +30,16 @@ type Node struct { // NodeMap - Model node map type NodeMap struct { idMap map[string]*Node - nameMap map[string]*Node - typeMap map[string]map[string]*Node + nameMap map[string][]*Node + typeMap map[string]map[string][]*Node } // NewNodeMap - allocate a blank NodeMap func NewNodeMap() (nm *NodeMap) { nm = new(NodeMap) nm.idMap = make(map[string]*Node) - nm.nameMap = make(map[string]*Node) - nm.typeMap = make(map[string]map[string]*Node) + nm.nameMap = make(map[string][]*Node) + nm.typeMap = make(map[string]map[string][]*Node) return nm } @@ -59,11 +59,14 @@ func NewNode(id string, name string, nodeType string, object interface{}, child // AddNode - Add a node to the NodeMap func (nm *NodeMap) AddNode(n *Node) { nm.idMap[n.id] = n - nm.nameMap[n.name] = n + nm.nameMap[n.name] = []*Node{n} if nm.typeMap[n.nodeType] == nil { - nm.typeMap[n.nodeType] = make(map[string]*Node) + nm.typeMap[n.nodeType] = make(map[string][]*Node) } - nm.typeMap[n.nodeType][n.name] = n + if nm.typeMap[n.nodeType][n.name] == nil { + nm.typeMap[n.nodeType][n.name] = []*Node{} + } + nm.typeMap[n.nodeType][n.name] = append(nm.typeMap[n.nodeType][n.name], n) } // FindById - find a node using its name @@ -73,15 +76,25 @@ func (nm *NodeMap) FindById(id string) (n *Node) { // FindByName - find a node using its name func (nm *NodeMap) FindByName(name string) (n *Node) { - return nm.nameMap[name] + nodes := nm.nameMap[name] + if len(nodes) > 0 { + return nodes[0] + } + return nil } // FindByType - find a node using its type - NOT SURE WE NEED THIS -func (nm *NodeMap) FindByType(name string, nodeType string) (n *Node) { +func (nm *NodeMap) FindByType(name string, nodeType string) []*Node { return nm.typeMap[nodeType][name] } // FindAllByType - find a list of nodes using a type func (nm *NodeMap) FindAllByType(nodeType string) map[string]*Node { - return nm.typeMap[nodeType] + result := make(map[string]*Node) + for name, nodes := range nm.typeMap[nodeType] { + if len(nodes) > 0 { + result[name] = nodes[0] + } + } + return result } diff --git a/go-packages/meep-model/validator.go b/go-packages/meep-model/validator.go index a102fd465..67fdfeee4 100644 --- a/go-packages/meep-model/validator.go +++ b/go-packages/meep-model/validator.go @@ -502,6 +502,9 @@ func validateScenario(scenario *dataModel.Scenario) error { return err } + // Name map for elements within this domain + domainNameMap := make(map[string]bool) + // Validate zones for zoneIndex := range domain.Zones { zone := &domain.Zones[zoneIndex] @@ -509,7 +512,7 @@ func validateScenario(scenario *dataModel.Scenario) error { if err := validateUniqueId(zone.Id, idMap); err != nil { return err } - if err := validateUniqueName(zone.Name, nameMap); err != nil { + if err := validateUniqueName(zone.Name, domainNameMap); err != nil { return err } @@ -520,7 +523,7 @@ func validateScenario(scenario *dataModel.Scenario) error { if err := validateUniqueId(nl.Id, idMap); err != nil { return err } - if err := validateUniqueName(nl.Name, nameMap); err != nil { + if err := validateUniqueName(nl.Name, domainNameMap); err != nil { return err } @@ -533,7 +536,7 @@ func validateScenario(scenario *dataModel.Scenario) error { if err := validateUniqueId(pl.Id, idMap); err != nil { return err } - if err := validateUniqueName(pl.Name, nameMap); err != nil { + if err := validateUniqueName(pl.Name, domainNameMap); err != nil { return err } @@ -546,9 +549,6 @@ func validateScenario(scenario *dataModel.Scenario) error { if err := validateUniqueId(proc.Id, idMap); err != nil { return err } - if err := validateUniqueName(proc.Name, nameMap); err != nil { - return err - } } } } diff --git a/js-apps/meep-frontend/src/js/containers/cfg/cfg-network-element-container.js b/js-apps/meep-frontend/src/js/containers/cfg/cfg-network-element-container.js index 5ae54fdc2..4ed7e1f3d 100644 --- a/js-apps/meep-frontend/src/js/containers/cfg/cfg-network-element-container.js +++ b/js-apps/meep-frontend/src/js/containers/cfg/cfg-network-element-container.js @@ -1363,33 +1363,41 @@ const TypeRelatedFormFields = ({ onUpdate, onEditLocation, onEditPath, element } const cfgElementTypes = [ { label: 'Logical Domain', - options: [ELEMENT_TYPE_OPERATOR_GENERIC, ELEMENT_TYPE_OPERATOR_CELL] + options: [ + { label: 'Generic', value: ELEMENT_TYPE_OPERATOR_GENERIC }, + { label: 'Cellular', value: ELEMENT_TYPE_OPERATOR_CELL } + ] }, { label: 'Logical Zone', - options: [ELEMENT_TYPE_ZONE] + options: [{ label: 'Zone', value: ELEMENT_TYPE_ZONE }] }, { label: 'Network Location', - options: [ELEMENT_TYPE_POA_GENERIC, ELEMENT_TYPE_POA_4G, ELEMENT_TYPE_POA_5G, ELEMENT_TYPE_POA_WIFI] + options: [ + { label: 'Generic', value: ELEMENT_TYPE_POA_GENERIC }, + { label: '4G', value: ELEMENT_TYPE_POA_4G }, + { label: '5G', value: ELEMENT_TYPE_POA_5G }, + { label: 'WiFi', value: ELEMENT_TYPE_POA_WIFI } + ] }, { label: 'Physical Location', options: [ - ELEMENT_TYPE_UE, - ELEMENT_TYPE_FOG, - ELEMENT_TYPE_EDGE, - ELEMENT_TYPE_DC - // ELEMENT_TYPE_CN + { label: 'Terminal', value: ELEMENT_TYPE_UE }, + { label: 'Fog', value: ELEMENT_TYPE_FOG }, + { label: 'Edge', value: ELEMENT_TYPE_EDGE }, + { label: 'Distant Cloud', value: ELEMENT_TYPE_DC } + // { label: 'Core Network', value: ELEMENT_TYPE_CN } ] }, { label: 'Process', options: [ - ELEMENT_TYPE_UE_APP, - // ELEMENT_TYPE_MECSVC, - ELEMENT_TYPE_EDGE_APP, - ELEMENT_TYPE_CLOUD_APP + { label: 'Terminal Application', value: ELEMENT_TYPE_UE_APP }, + // { label: 'MEC Service', value: ELEMENT_TYPE_MECSVC }, + { label: 'Edge Application', value: ELEMENT_TYPE_EDGE_APP }, + { label: 'Cloud Application', value: ELEMENT_TYPE_CLOUD_APP } ] } ]; @@ -1398,9 +1406,9 @@ const execElementTypes = [ { label: 'Process', options: [ - ELEMENT_TYPE_UE_APP, - ELEMENT_TYPE_EDGE_APP, - ELEMENT_TYPE_CLOUD_APP + { label: 'Terminal Application', value: ELEMENT_TYPE_UE_APP }, + { label: 'Edge Application', value: ELEMENT_TYPE_EDGE_APP }, + { label: 'Cloud Application', value: ELEMENT_TYPE_CLOUD_APP } ] } ]; diff --git a/js-apps/meep-frontend/src/js/containers/cfg/cfg-page-container.js b/js-apps/meep-frontend/src/js/containers/cfg/cfg-page-container.js index 30a19d518..7e4e1b9bc 100644 --- a/js-apps/meep-frontend/src/js/containers/cfg/cfg-page-container.js +++ b/js-apps/meep-frontend/src/js/containers/cfg/cfg-page-container.js @@ -68,7 +68,19 @@ import { IDC_DIALOG_EXPORT_SCENARIO, ELEMENT_TYPE_POA_4G, ELEMENT_TYPE_POA_5G, - ELEMENT_TYPE_POA_WIFI + ELEMENT_TYPE_POA_WIFI, + ELEMENT_TYPE_UE, + ELEMENT_TYPE_FOG, + ELEMENT_TYPE_EDGE, + ELEMENT_TYPE_DC, + ELEMENT_TYPE_CN, + ELEMENT_TYPE_UE_APP, + ELEMENT_TYPE_EDGE_APP, + ELEMENT_TYPE_CLOUD_APP, + ELEMENT_TYPE_OPERATOR, + ELEMENT_TYPE_OPERATOR_CELL, + ELEMENT_TYPE_ZONE, + ELEMENT_TYPE_POA } from '../../meep-constants'; import { @@ -89,6 +101,7 @@ import { FIELD_MEMORY_MIN, FIELD_MEMORY_MAX } from '../../util/elem-utils'; +import { getElementFromScenario, updateElementInScenario } from '../../util/scenario-utils'; import { pipe, filter } from '../../util/functional'; @@ -137,6 +150,30 @@ export const validateNetworkElement = (element, entries, elemSetErrMsg) => { return false; } + // Check if type is valid + const validTypes = [ + ELEMENT_TYPE_SCENARIO, + ELEMENT_TYPE_OPERATOR, + ELEMENT_TYPE_OPERATOR_CELL, + ELEMENT_TYPE_ZONE, + ELEMENT_TYPE_POA, + ELEMENT_TYPE_POA_4G, + ELEMENT_TYPE_POA_5G, + ELEMENT_TYPE_POA_WIFI, + ELEMENT_TYPE_UE, + ELEMENT_TYPE_FOG, + ELEMENT_TYPE_EDGE, + ELEMENT_TYPE_DC, + ELEMENT_TYPE_CN, + ELEMENT_TYPE_UE_APP, + ELEMENT_TYPE_EDGE_APP, + ELEMENT_TYPE_CLOUD_APP + ]; + if (!validTypes.includes(type)) { + elemSetErrMsg('Invalid element type: ' + type); + return false; + } + // Check for valid & unique network element name (except if editing) var name = getElemFieldVal(element, FIELD_NAME); if (name === null || name === '') { @@ -144,10 +181,10 @@ export const validateNetworkElement = (element, entries, elemSetErrMsg) => { return false; } - if (data[name] && data[name].id !== element.id) { - elemSetErrMsg('Element name already exists'); - return false; - } + // if (data[name] && data[name].id !== element.id) { + // elemSetErrMsg('Element name already exists'); + // return false; + // } // Nothing else to validate for Scenario element if (type === ELEMENT_TYPE_SCENARIO) { @@ -155,9 +192,16 @@ export const validateNetworkElement = (element, entries, elemSetErrMsg) => { } // Make sure parent exists - if (!data[getElemFieldVal(element, FIELD_PARENT)]) { - elemSetErrMsg('Parent does not exist'); - return false; + var parentName = getElemFieldVal(element, FIELD_PARENT); + if (parentName) { + parentName = parentName.trim(); + if (!Object.values(data).some(e => { + const eName = getElemFieldVal(e, FIELD_NAME); + return eName && eName.trim() === parentName; + })) { + elemSetErrMsg('Parent does not exist'); + return false; + } } // If GPU requested, make sure type is set @@ -245,16 +289,16 @@ class CfgPageContainer extends Component { } // EDIT - onEditElement(element) { - if (element !== null) { - if (!this.props.configuredElement || (element.id !== this.props.configuredElement.id)) { - resetElem(element); + onEditElement(element) { + if (element !== null) { + // Always fetch the full element from the scenario by ID + // let element = getElementFromScenario(this.props.cfg.scenario, element.id); + //resetElem(element); this.props.cfgElemEdit(element); + } else { + this.props.cfgElemClear(); } - } else { - this.props.cfgElemClear(); } - } // SAVE onSaveElement(element) { @@ -270,6 +314,11 @@ class CfgPageContainer extends Component { this.props.updateScenarioElem(element); } + // Update scenario for canvas reflection + // let updatedScenario = JSON.parse(JSON.stringify(this.props.cfg.scenario)); + // updateElementInScenario(updatedScenario, element); + // this.props.changeScenario(updatedScenario); + // Reset Element configuration pane this.props.cfgElemClear(); } @@ -288,8 +337,10 @@ class CfgPageContainer extends Component { this.props.cloneScenarioElem(element); - //force update on the visual aspect of the scenario - //this.props.updateScenario(); + // Update scenario for canvas reflection + const updatedScenario = JSON.parse(JSON.stringify(this.props.cfg.scenario)); + updateElementInScenario(updatedScenario, element); + this.props.changeScenario(updatedScenario); this.props.cfgElemClear(); } @@ -467,6 +518,11 @@ class CfgPageContainer extends Component { const scenarioCopy = JSON.parse(JSON.stringify(cfg.scenario)); scenarioCopy.name = scenarioName; + // Update scenario with configured elements + Object.values(cfg.table.entries).forEach(element => { + updateElementInScenario(scenarioCopy, element); + }); + // Create new scenario if scenario is new if (cfg.state === CFG_STATE_NEW || scenarioName !== cfg.scenario.name) { this.props.api.createScenario( @@ -737,7 +793,7 @@ class CfgPageContainer extends Component { type={TYPE_CFG} onNewElement={() => this.onNewElement()} onEditElement={elem => this.onEditElement(elem)} - onDeleteElement={() => this.onDeleteElement()} + onDeleteElement={elem => this.onDeleteElement(elem)} onApplyCloneElement={elem => this.onApplyCloneElement(elem)} /> diff --git a/js-apps/meep-frontend/src/js/containers/cfg/cfg-table.js b/js-apps/meep-frontend/src/js/containers/cfg/cfg-table.js index 6ebb5f1ac..f000768bf 100644 --- a/js-apps/meep-frontend/src/js/containers/cfg/cfg-table.js +++ b/js-apps/meep-frontend/src/js/containers/cfg/cfg-table.js @@ -95,10 +95,15 @@ class CfgTable extends Component { this.props.changeTable(table); } - onClick(/*event, name*/) { - // var table = updateObject({}, this.props.table); - // handleClick(table, event, name); - // this.props.changeTable(table); + onClick(event, elem) { + // Select by unique id + var table = updateObject({}, this.props.table); + table.selected = [elem.id]; + this.props.changeTable(table); + // Call parent handler to open config panel for this element + if (this.props.onEditElement) { + this.props.onEditElement(elem); + } } onChangePage(event, page) { @@ -198,15 +203,16 @@ class CfgTable extends Component { const name = getElemFieldVal(elem, FIELD_NAME); const type = getElemFieldVal(elem, FIELD_TYPE); const parent = getElemFieldVal(elem, FIELD_PARENT); - const isSelected = isRowSelected(table, name); + const id = elem.id; + const isSelected = table.selected && table.selected[0] === id; return ( this.onClick(event, name)} + onClick={event => this.onClick(event, elem)} role='checkbox' aria-checked={isSelected} tabIndex={-1} - key={name} + key={id} selected={isSelected} > diff --git a/js-apps/meep-frontend/src/js/containers/idc-map.js b/js-apps/meep-frontend/src/js/containers/idc-map.js index 07aa0a222..525105500 100644 --- a/js-apps/meep-frontend/src/js/containers/idc-map.js +++ b/js-apps/meep-frontend/src/js/containers/idc-map.js @@ -173,6 +173,10 @@ class IDCMap extends Component { if (nextProps.cfgScenarioName !== this.props.cfgScenarioName) { return true; } + // Scenario content change + if (!deepEqual(nextProps.cfgScenario, this.props.cfgScenario)) { + return true; + } // Sandbox update if (nextProps.cfgView !== this.props.cfgView) { return true; @@ -200,6 +204,60 @@ class IDCMap extends Component { return (this.props.type === TYPE_CFG) ? this.props.cfgTable : this.props.execTable; } + buildMapFromScenario(scenario) { + var map = { + ueList: [], + poaList: [], + computeList: [] + }; + + if (!scenario || !scenario.deployment || !scenario.deployment.domains) { + return map; + } + + scenario.deployment.domains.forEach(domain => { + if (domain.zones) { + domain.zones.forEach(zone => { + if (zone.networkLocations) { + zone.networkLocations.forEach(nl => { + if (nl.physicalLocations) { + nl.physicalLocations.forEach(pl => { + if (pl.type === 'UE') { + map.ueList.push({ + assetName: pl.name, + id: pl.id, + radius: pl.geoData ? pl.geoData.radius : 0, + position: pl.geoData && pl.geoData.location ? pl.geoData.location.coordinates : [0,0], + path: pl.geoData && pl.geoData.path ? pl.geoData.path.coordinates : null, + eopMode: pl.geoData ? pl.geoData.eopMode : null, + velocity: pl.geoData ? pl.geoData.velocity : null + }); + } else if (pl.type === 'FOG' || pl.type === 'EDGE' || pl.type === 'DC') { + map.computeList.push({ + assetName: pl.name, + id: pl.id, + position: pl.geoData && pl.geoData.location ? pl.geoData.location.coordinates : [0,0] + }); + } + }); + } + // For POA + if (nl.type === 'POA' || nl.type === 'POA-4G' || nl.type === 'POA-5G' || nl.type === 'POA-WIFI') { + map.poaList.push({ + assetName: nl.name, + id: nl.id, + position: nl.geoData && nl.geoData.location ? nl.geoData.location.coordinates : [0,0] + }); + } + }); + } + }); + } + }); + + return map; + } + updateCfg(cfg) { switch (this.props.type) { case TYPE_CFG: @@ -230,10 +288,10 @@ class IDCMap extends Component { } } - editElement(name) { + editElement(id) { // Update selected nodes in table const table = updateObject({}, this.getTable()); - const elem = this.getElementByName(table.entries, name); + const elem = this.getElementById(table.entries, id); table.selected = elem ? [elem.id] : []; this.changeTable(table); @@ -241,8 +299,8 @@ class IDCMap extends Component { if (this.props.type === TYPE_CFG) { this.props.onEditElement(elem ? elem : this.props.configuredElement); - // Update target element name & reset controls on target change - if (name !== this.targetElemName) { + // Update target element & reset controls on target change + if (id !== this.targetElemId) { this.map.pm.disableDraw('Marker'); this.map.pm.disableDraw('Line'); if (this.map.pm.globalEditEnabled()) { @@ -255,12 +313,12 @@ class IDCMap extends Component { this.map.pm.toggleGlobalRemovalMode(); } } - this.targetElemName = name; + this.targetElemId = id; } } - getElementByName(entries, name) { - var element = entries[name]; + getElementById(entries, id) { + var element = entries[id]; return element ? element : null; } @@ -401,7 +459,7 @@ class IDCMap extends Component { var radius = 0; var table = this.getTable(); if (table && table.entries) { - radius = getElemFieldVal(table.entries[scenarioName], FIELD_D2D_RADIUS); + radius = getElemFieldVal(table.entries[scenarioName], FIELD_D2D_RADIUS); // scenarioName should be scenario ID if available } return radius; } @@ -416,7 +474,7 @@ class IDCMap extends Component { var poa = null; var table = this.getTable(); if (table && table.entries) { - poa = getElemFieldVal(table.entries[ue], FIELD_PARENT); + poa = getElemFieldVal(table.entries[ue], FIELD_PARENT); // ue should be ue ID } return poa; } @@ -788,23 +846,23 @@ class IDCMap extends Component { pmIgnore: true }); - var m = L.marker(latlng, { - meep: { - ue: { - id: ue.assetName, - path: p, - eopMode: ue.eopMode, - velocity: ue.velocity, - connected: true, - d2dInRange: ue.d2dInRange, - range: c - } - }, - icon: markerIcon, - opacity: UE_OPACITY, - draggable: (this.props.type === TYPE_CFG) ? true : false, - pmIgnore: (this.props.type === TYPE_CFG) ? false : true - }); + var m = L.marker(latlng, { + meep: { + ue: { + id: ue.assetName, + path: p, + eopMode: ue.eopMode, + velocity: ue.velocity, + connected: true, + d2dInRange: ue.d2dInRange, + range: c + } + }, + icon: markerIcon, + opacity: UE_OPACITY, + draggable: (this.props.type === TYPE_CFG && this.map.pm.globalDragModeEnabled()) ? true : false, + pmIgnore: (this.props.type === TYPE_CFG) ? false : true + }); m.bindTooltip(ue.assetName).openTooltip(); // Handlers @@ -1109,7 +1167,12 @@ class IDCMap extends Component { } // Get copy of map data - var map = deepCopy(this.getMap(this.props)); + var map; + if (this.props.type === TYPE_CFG) { + map = this.buildMapFromScenario(this.props.cfgScenario); + } else { + map = deepCopy(this.getMap(this.props)); + } if (!map) { return; } @@ -1393,6 +1456,7 @@ const mapStateToProps = state => { configuredElement: state.cfg.elementConfiguration.configuredElement, cfgView: state.ui.cfgView, cfgScenarioName: state.cfg.scenario.name, + cfgScenario: state.cfg.scenario, appInstanceTable: state.exec.appInstanceTable.data }; }; diff --git a/js-apps/meep-frontend/src/js/meep-constants.js b/js-apps/meep-frontend/src/js/meep-constants.js index 974cd7e3c..a8d086e6c 100644 --- a/js-apps/meep-frontend/src/js/meep-constants.js +++ b/js-apps/meep-frontend/src/js/meep-constants.js @@ -262,23 +262,23 @@ export const CLOUD_APP_TYPE_STR = 'CLOUD-APP'; export const ELEMENT_TYPE_SCENARIO = 'SCENARIO'; export const ELEMENT_TYPE_OPERATOR = 'OPERATOR'; -export const ELEMENT_TYPE_OPERATOR_GENERIC = 'OPERATOR GENERIC'; -export const ELEMENT_TYPE_OPERATOR_CELL = 'OPERATOR CELLULAR'; +export const ELEMENT_TYPE_OPERATOR_GENERIC = 'OPERATOR'; +export const ELEMENT_TYPE_OPERATOR_CELL = 'OPERATOR-CELLULAR'; export const ELEMENT_TYPE_ZONE = 'ZONE'; export const ELEMENT_TYPE_POA = 'POA'; -export const ELEMENT_TYPE_POA_GENERIC = 'POA GENERIC'; -export const ELEMENT_TYPE_POA_4G = 'POA CELLULAR 4G'; -export const ELEMENT_TYPE_POA_5G = 'POA CELLULAR 5G'; -export const ELEMENT_TYPE_POA_WIFI = 'POA WIFI'; -export const ELEMENT_TYPE_DC = 'DISTANT CLOUD'; -export const ELEMENT_TYPE_CN = 'CORE NETWORK'; +export const ELEMENT_TYPE_POA_GENERIC = 'POA'; +export const ELEMENT_TYPE_POA_4G = 'POA-4G'; +export const ELEMENT_TYPE_POA_5G = 'POA-5G'; +export const ELEMENT_TYPE_POA_WIFI = 'POA-WIFI'; +export const ELEMENT_TYPE_DC = 'DC'; +export const ELEMENT_TYPE_CN = 'CN'; export const ELEMENT_TYPE_EDGE = 'EDGE'; export const ELEMENT_TYPE_FOG = 'FOG'; -export const ELEMENT_TYPE_UE = 'TERMINAL'; -export const ELEMENT_TYPE_MECSVC = 'MEC SERVICE'; -export const ELEMENT_TYPE_UE_APP = 'TERMINAL APPLICATION'; -export const ELEMENT_TYPE_EDGE_APP = 'EDGE APPLICATION'; -export const ELEMENT_TYPE_CLOUD_APP = 'CLOUD APPLICATION'; +export const ELEMENT_TYPE_UE = 'UE'; +export const ELEMENT_TYPE_MECSVC = 'MEC-SVC'; +export const ELEMENT_TYPE_UE_APP = 'UE-APP'; +export const ELEMENT_TYPE_EDGE_APP = 'EDGE-APP'; +export const ELEMENT_TYPE_CLOUD_APP = 'CLOUD-APP'; // Default latencies per physical location type export const DEFAULT_LATENCY_INTER_DOMAIN = 50; diff --git a/js-apps/meep-frontend/src/js/state/cfg/table-reducer.js b/js-apps/meep-frontend/src/js/state/cfg/table-reducer.js index 3856315b6..61ae03a88 100644 --- a/js-apps/meep-frontend/src/js/state/cfg/table-reducer.js +++ b/js-apps/meep-frontend/src/js/state/cfg/table-reducer.js @@ -38,7 +38,7 @@ export function cfgChangeTable(table) { export function cfgTableReducer(state = initialState, action) { switch (action.type) { case CFG_CHANGE_TABLE: - var ret = updateObject({}, action.payload); + var ret = updateObject(state, action.payload); return ret; default: return state; diff --git a/js-apps/meep-frontend/src/js/util/scenario-utils.js b/js-apps/meep-frontend/src/js/util/scenario-utils.js index 896921fd7..8bbd72f8e 100644 --- a/js-apps/meep-frontend/src/js/util/scenario-utils.js +++ b/js-apps/meep-frontend/src/js/util/scenario-utils.js @@ -298,7 +298,7 @@ export function parseScenario(scenario, pduSessions) { var table = {}; table.data = { edges: edges, nodes: nodes }; table.entries = _.reduce(table.data.nodes, (nodeMap, node) => { - nodeMap[node.name] = updateObject(node, getElementFromScenario(scenario, node.id)); + nodeMap[node.id] = updateObject(node, getElementFromScenario(scenario, node.id)); return nodeMap; }, {}); @@ -306,7 +306,7 @@ export function parseScenario(scenario, pduSessions) { var visData = {}; visData.nodes = new visdata.DataSet(nodes); visData.edges = new visdata.DataSet(edges); - + // Update map data var mapData = {}; mapData.ueList = _.sortBy(ueList, ['assetName']); @@ -569,6 +569,8 @@ export function updateElementInScenario(scenario, element) { } domain.label = name; domain.name = name; + domain.type = getElemFieldVal(element, FIELD_TYPE); + domain.parent = getElemFieldVal(element, FIELD_PARENT); return; } @@ -601,6 +603,8 @@ export function updateElementInScenario(scenario, element) { zone.label = name; zone.name = name; + zone.type = getElemFieldVal(element, FIELD_TYPE); + zone.parent = getElemFieldVal(element, FIELD_PARENT); return; } @@ -649,6 +653,8 @@ export function updateElementInScenario(scenario, element) { nl.label = name; nl.name = name; + nl.type = getElemFieldVal(element, FIELD_TYPE); + nl.parent = getElemFieldVal(element, FIELD_PARENT); return; } @@ -698,6 +704,8 @@ export function updateElementInScenario(scenario, element) { pl.label = name; pl.name = name; + pl.type = getElemFieldVal(element, FIELD_TYPE); + pl.parent = getElemFieldVal(element, FIELD_PARENT); return; } -- GitLab From c3c12fa03829d5acdab074c701f217b2dcf01d23 Mon Sep 17 00:00:00 2001 From: Mudassar Khan Date: Wed, 26 Nov 2025 07:22:31 +0000 Subject: [PATCH 02/15] feat: optimize Docker build, implement POST endpoints, update MEC033 registration, and align CSE branches - Modified Dockerfile to reduce build time and final image size. - Implemented POST request handling for: 1) /applications/{appInstanceId}/confirm_ready 2) /applications/{appInstanceId}/services - Updated request bodies for MEC 033 registration endpoint. - Both ACME IN-cse and MN-cse now use the master branch. --- .../meep-iot-pltf/meep-acme-in-cse/Dockerfile | 37 +---- .../meep-acme-in-cse/entrypoint.sh | 32 +++-- .../meep-iot-pltf/meep-acme-mn-cse/Dockerfile | 35 +---- .../meep-acme-mn-cse/acme.ini.in | 2 + .../acme/protocols/MECClient.py | 108 ++++++++++++-- .../meep-acme-mn-cse/acme/runtime/CSE.py | 10 +- .../acme/runtime/Configuration.py | 4 + .../configurations/MECClientConfiguration.py | 6 + .../meep-acme-mn-cse/entrypoint.sh | 136 ++++++++++-------- 9 files changed, 219 insertions(+), 151 deletions(-) diff --git a/go-apps/meep-iot-pltf/meep-acme-in-cse/Dockerfile b/go-apps/meep-iot-pltf/meep-acme-in-cse/Dockerfile index 608b06b80..3d7e2705d 100644 --- a/go-apps/meep-iot-pltf/meep-acme-in-cse/Dockerfile +++ b/go-apps/meep-iot-pltf/meep-acme-in-cse/Dockerfile @@ -1,4 +1,5 @@ -FROM ubuntu:22.04 +FROM ubuntu:24.04 + ENV MQTT_ENABLE="" ENV MQTT_HOST="" ENV MQTT_PORT="" @@ -16,38 +17,17 @@ ENV MEC_SANDBOX_SERVER="" RUN echo "meep-acme-in-cse" > /etc/hostname \ && DEBIAN_FRONTEND=noninteractive apt-get update \ - && DEBIAN_FRONTEND=noninteractive apt-get install -y \ - autoconf \ - bison \ - build-essential \ - cmake \ + && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ curl \ - dos2unix \ - doxygen \ - emacs \ - expect \ - flex \ - g++ \ - gcc \ gettext \ git \ gnutls-bin \ iputils-ping \ jq \ libedit2 \ - libedit-dev \ libffi-dev \ libglib2.0-dev \ - libgcrypt-dev \ - libjsoncpp-dev \ - libncurses5-dev \ - libpcap-dev \ libssl-dev \ - libtool-bin \ - libtool \ - libxml2-dev \ - libxml2-utils \ - libyaml-dev \ lsof \ ntp \ pkg-config \ @@ -55,24 +35,21 @@ RUN echo "meep-acme-in-cse" > /etc/hostname \ python3-pip \ python3-setuptools \ sudo \ - sshpass \ - tcpdump \ tzdata \ && DEBIAN_FRONTEND=noninteractive apt-get autoremove --purge -y \ && DEBIAN_FRONTEND=noninteractive apt-get autoclean \ && DEBIAN_FRONTEND=noninteractive apt-get clean \ - && pip3 install --no-cache-dir --upgrade pip + && rm -rf /var/lib/apt/lists/* WORKDIR /usr/src/app -#RUN git clone --branch development https://github.com/ankraft/ACME-oneM2M-CSE.git ACME-oneM2M-CSE -RUN git clone https://github.com/ankraft/ACME-oneM2M-CSE.git ACME-oneM2M-CSE +RUN git clone --branch master https://github.com/ankraft/ACME-oneM2M-CSE.git ACME-oneM2M-CSE WORKDIR /usr/src/app/ACME-oneM2M-CSE COPY ./data /usr/src/app/ACME-oneM2M-CSE RUN chmod +x entrypoint.sh \ - && pip3 install --no-cache-dir -r requirements.txt + && pip3 install --no-cache-dir -r requirements.txt --break-system-packages -ENTRYPOINT ["./entrypoint.sh"] +ENTRYPOINT ["./entrypoint.sh"] \ No newline at end of file diff --git a/go-apps/meep-iot-pltf/meep-acme-in-cse/entrypoint.sh b/go-apps/meep-iot-pltf/meep-acme-in-cse/entrypoint.sh index 8bdd260bf..7edfcb949 100755 --- a/go-apps/meep-iot-pltf/meep-acme-in-cse/entrypoint.sh +++ b/go-apps/meep-iot-pltf/meep-acme-in-cse/entrypoint.sh @@ -2,7 +2,9 @@ set -e echo "MEEP_HOST_URL: ${MEEP_HOST_URL}" -SERVER_IP="${MEEP_HOST_URL#http://}"; MEEP_HOST_URL="${MEEP_HOST_URL#https://}" +# SERVER_IP="${MEEP_HOST_URL#http://}"; MEEP_HOST_URL="${MEEP_HOST_URL#https://}" +SERVER_IP="${MEEP_HOST_URL#http://}" +SERVER_IP="${SERVER_IP#https://}" echo "MEC_PLATFORM=$MEC_PLATFORM" echo "MEEP_SANDBOX_NAME=$MEEP_SANDBOX_NAME" @@ -21,21 +23,21 @@ echo "MQTT_USERNAME: ${MQTT_USERNAME}" echo "MQTT_PASSWORD: ${MQTT_PASSWORD}" # Retrieve the internal meep-mosquitto IP address -SERVICE_NAME="meep-cloud-mosquitto" +SERVICE_NAME="monaco-telecom-meep-cloud-mosquitto" NAMESPACE=$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace) TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) -MOSQUITTO_NODE_IP_ADDRESS=$(curl -sSk \ - -H "Authorization: Bearer $TOKEN" \ - https://kubernetes.default.svc/api/v1/namespaces/$NAMESPACE/services/$SERVICE_NAME \ - | jq -r '.spec.clusterIP') -echo "Internal IP exposed for service [$SERVICE_NAME] in namespace [$NAMESPACE] is: $MOSQUITTO_NODE_IP_ADDRESS" - -# Retrieve the internal meep-mosquitto port id -MOSQUITTO_NODE_PORT=$(curl -sSk \ - -H "Authorization: Bearer $TOKEN" \ - https://kubernetes.default.svc/api/v1/namespaces/$NAMESPACE/services/$SERVICE_NAME \ - | jq -r '.spec.ports[0].targetPort') -echo "Internal NodePort exposed for service [$SERVICE_NAME] in namespace [$NAMESPACE] is: $MOSQUITTO_NODE_PORT" +# MOSQUITTO_NODE_IP_ADDRESS=$(curl -sSk \ +# -H "Authorization: Bearer $TOKEN" \ +# https://kubernetes.default.svc/api/v1/namespaces/$NAMESPACE/services/$SERVICE_NAME \ +# | jq -r '.spec.clusterIP') +# echo "Internal IP exposed for service [$SERVICE_NAME] in namespace [$NAMESPACE] is: $MOSQUITTO_NODE_IP_ADDRESS" + +# # Retrieve the internal meep-mosquitto port id +# MOSQUITTO_NODE_PORT=$(curl -sSk \ +# -H "Authorization: Bearer $TOKEN" \ +# https://kubernetes.default.svc/api/v1/namespaces/$NAMESPACE/services/$SERVICE_NAME \ +# | jq -r '.spec.ports[0].targetPort') +# echo "Internal NodePort exposed for service [$SERVICE_NAME] in namespace [$NAMESPACE] is: $MOSQUITTO_NODE_PORT" if [[ ! -z "${MEEP_MEP_NAME}" ]]; then svcPath="${MEEP_SANDBOX_NAME}/${MEEP_MEP_NAME}" @@ -62,7 +64,7 @@ ENABLE_WS=${ENABLE_WS:-false} # MQTT Configuration MQTT_ENABLE=${MQTT_ENABLE:-true} -MQTT_HOST=${MOSQUITTO_NODE_IP_ADDRESS:-"meep-cloud-mosquito"} +MQTT_HOST=${MOSQUITTO_NODE_IP_ADDRESS:-"monaco-telecom-meep-cloud-mosquitto"} MQTT_PORT=${MOSQUITTO_NODE_PORT:-443} MQTT_USERNAME=${MQTT_USERNAME:-"acme-mn-cse"} MQTT_PASSWORD=${MQTT_PASSWORD:-"mqtt"} diff --git a/go-apps/meep-iot-pltf/meep-acme-mn-cse/Dockerfile b/go-apps/meep-iot-pltf/meep-acme-mn-cse/Dockerfile index f7ad8e980..63e52a625 100644 --- a/go-apps/meep-iot-pltf/meep-acme-mn-cse/Dockerfile +++ b/go-apps/meep-iot-pltf/meep-acme-mn-cse/Dockerfile @@ -1,4 +1,4 @@ -FROM ubuntu:22.04 +FROM ubuntu:24.04 ENV SERVER_TYPE="" ENV SERVER_IP="" @@ -24,40 +24,17 @@ ENV ACME_IN_SERVICE_NAME="" RUN echo "meep-acme-mn-cse" > /etc/hostname \ && DEBIAN_FRONTEND=noninteractive apt-get update \ - && DEBIAN_FRONTEND=noninteractive apt-get dist-upgrade -y \ - && DEBIAN_FRONTEND=noninteractive apt-get update \ - && DEBIAN_FRONTEND=noninteractive apt-get install -y \ - autoconf \ - bison \ - build-essential \ - cmake \ + && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ curl \ - dos2unix \ - doxygen \ - emacs \ - expect \ - flex \ - g++ \ - gcc \ gettext \ git \ gnutls-bin \ iputils-ping \ jq \ libedit2 \ - libedit-dev \ libffi-dev \ libglib2.0-dev \ - libgcrypt-dev \ - libjsoncpp-dev \ - libncurses5-dev \ - libpcap-dev \ libssl-dev \ - libtool-bin \ - libtool \ - libxml2-dev \ - libxml2-utils \ - libyaml-dev \ lsof \ ntp \ pkg-config \ @@ -65,24 +42,22 @@ RUN echo "meep-acme-mn-cse" > /etc/hostname \ python3-pip \ python3-setuptools \ sudo \ - sshpass \ - tcpdump \ tzdata \ && DEBIAN_FRONTEND=noninteractive apt-get autoremove --purge -y \ && DEBIAN_FRONTEND=noninteractive apt-get autoclean \ && DEBIAN_FRONTEND=noninteractive apt-get clean \ - && pip3 install --no-cache-dir --upgrade pip + && rm -rf /var/lib/apt/lists/* WORKDIR /usr/src/app -RUN git clone --branch development https://github.com/ankraft/ACME-oneM2M-CSE.git ACME-oneM2M-CSE +RUN git clone --branch master https://github.com/ankraft/ACME-oneM2M-CSE.git ACME-oneM2M-CSE WORKDIR /usr/src/app/ACME-oneM2M-CSE COPY ./data /usr/src/app/ACME-oneM2M-CSE RUN chmod +x entrypoint.sh \ - && pip3 install --no-cache-dir -r requirements.txt + && pip3 install --no-cache-dir -r requirements.txt --break-system-packages ENTRYPOINT ["./entrypoint.sh"] diff --git a/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme.ini.in b/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme.ini.in index 5ef1483a8..9c18c868f 100644 --- a/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme.ini.in +++ b/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme.ini.in @@ -79,3 +79,5 @@ mec_platform=$MEC_PLATFORM mec_sandbox_id=$MEC_SANDBOX_ID cse_external_ip=$CSE_EXTERNAL_IP cse_external_port=$CSE_EXTERNAL_PORT +fullAddress=$MN_CSE_FULL_ADDRESS +mec_app_instance_id=$MEC_APP_INSTANCE_ID \ No newline at end of file diff --git a/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme/protocols/MECClient.py b/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme/protocols/MECClient.py index 1eb812634..f13c8913e 100644 --- a/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme/protocols/MECClient.py +++ b/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme/protocols/MECClient.py @@ -48,7 +48,9 @@ class MECClient(object): 'mqtt_port', 'wss_path', 'cse_resourceID', + 'fullAddress', 'isStopped', + 'mec_app_instance_id', 'mecConnection', 'mecConnections', 'isInfo', @@ -59,7 +61,9 @@ class MECClient(object): # TODO move config handling to event handler - def __init__(self, p_http_address: str, p_http_port: str, p_cse_resourceID: str, p_cse_external_ip: str, p_cse_external_port: str, p_use_wss: bool, p_mqtt_address: str, p_mqtt_port: str, p_wss_path: str = "") -> None: + def __init__(self, p_http_address: str, p_http_port: str, p_cse_resourceID: str, + p_cse_external_ip: str, p_cse_external_port: str, p_use_wss: bool, p_mqtt_address: str, + p_mqtt_port: str, p_fullAddress: str, p_mec_app_instance_id: str , p_wss_path: str = "") -> None: """ Initialize the MEC client. """ self.http_address = p_http_address @@ -73,6 +77,8 @@ class MECClient(object): self.mqtt_address = p_mqtt_address self.mqtt_port = p_mqtt_port self.wss_path = p_wss_path + self.fullAddress = p_fullAddress + self.mec_app_instance_id = p_mec_app_instance_id self.isStopped = False """ Flag to indicate whether the MEC client is stopped. """ @@ -213,7 +219,7 @@ class MECClient(object): userTransportInfoList = [] userTransportInfo = {} userTransportInfo['id'] = str(uuid.uuid4()) - userTransportInfo['name'] = self.cse_resourceID + userTransportInfo['name'] = Configuration.cse_resourceName userTransportInfo['type'] = 'MB_TOPIC_BASED' if self.use_wss: userTransportInfo['description'] = 'MQTT over WS-Secured' @@ -223,6 +229,10 @@ class MECClient(object): userTransportInfo['protocol'] = 'MQTT' userTransportInfo['version'] = '2' userTransportInfo['endpoint'] = {} + # userTransportInfo['endpoint']['addresses'] = [] + # The MEC API expects an array of URIs for the endpoint 'uris' field. + # Previously this was set to a single string which caused the server + # to return: "cannot unmarshal string into Go struct field ... uris of type []string". if self.use_wss: userTransportInfo['endpoint']['uris'] = [] userTransportInfo['endpoint']['uris'].append('wss://' + self.mqtt_address + ':' + str(self.mqtt_port) + self.wss_path) @@ -231,11 +241,16 @@ class MECClient(object): address['port'] = self.mqtt_port userTransportInfo['endpoint']['addresses'].append(address) else: - userTransportInfo['endpoint']['addresses'] = [] - address = {} - address['host'] = self.mqtt_address - address['port'] = self.mqtt_port - userTransportInfo['endpoint']['addresses'].append(address) + # userTransportInfo['endpoint']['addresses'] = [] + # address = {} + # address['host'] = self.mqtt_address + # address['port'] = self.mqtt_port + # userTransportInfo['endpoint']['addresses'].append(address) + userTransportInfo['endpoint']['uris'] = [ self.fullAddress ] + # address = {} + # address['host'] = self.mqtt_address + # address['port'] = self.mqtt_port + # userTransportInfo['endpoint']['addresses'].append(address) userTransportInfo['security'] = {} userTransportInfo['implSpecificInfo'] = {} userTransportInfoList.append(userTransportInfo) @@ -262,7 +277,7 @@ class MECClient(object): tries = 0 while tries < 5: - response = requests.post(url, headers=self.headers, json=body_json) + response = requests.post(url, headers=self.headers, json=body_json, verify=False) L.isInfo and L.log(f'MECClient.registerToMec: response.content: ' + str(response.content)) if response.status_code == 201: self.register = Result() @@ -292,7 +307,7 @@ class MECClient(object): '/' + Configuration.mec_sandbox_id + \ '/' + Configuration.mec_platform + \ '/iots/v1/registered_iot_platforms/' + json_dict['iotPlatformId'] - response = requests.delete(url, headers=self.headers) + response = requests.delete(url, headers=self.headers, verify=False) self.register = None return Result(rsc = response.status_code) except Exception as e: @@ -300,3 +315,78 @@ class MECClient(object): self.register = None return Result(rsc = ResponseStatusCode.INTERNAL_SERVER_ERROR, dbg = 'MEC Deregistration failure') + + def confirm_readyToMec(self) -> Result: + """ Confirm readiness to MEC platform. + """ + if self.isStopped: + return Result(rsc = ResponseStatusCode.INTERNAL_SERVER_ERROR, dbg = 'MEC client is not running') + + try: + req_body = { + "indication": "READY" + } + url = \ + Configuration.mec_protocol + '://' +Configuration.mec_host + ':' + str(Configuration.mec_port) + \ + '/' + Configuration.mec_sandbox_id + \ + '/' + Configuration.mec_platform + \ + '/mec_app_support/v2/applications/' + self.mec_app_instance_id + '/confirm_ready' + L.log('MECClient.confirm_readyToMec: ' + str(req_body)) + L.log('MECClient.confirm_readyToMec: ' + str(url)) + response = requests.post(url, headers=self.headers, json=req_body, verify=False) + return Result(rsc = response.status_code) + except Exception as e: + L.logErr(f'MECClient.confirm_readyToMec: ' + str(e)) + return Result(rsc = ResponseStatusCode.INTERNAL_SERVER_ERROR, dbg = 'MEC Confirm readiness failure') + + def post_mec_service(self) -> Result: + """ + Declare MEC service to MEC platform. + This function declares MN-CSE as MEC service to the MEC platform. + """ + if self.isStopped: + return Result(rsc = ResponseStatusCode.INTERNAL_SERVER_ERROR, dbg = 'MEC client is not running') + + try: + req_body = { + "serName": Configuration.cse_resourceName, + "serCategory": { + "href": "catalogueHref", + "id": Configuration.cse_cseID, + "name": Configuration.cse_resourceName, + "version": "v1" + }, + "version": "v1.0.0", + "state": "ACTIVE", + "transportInfo": { + "id": "acme-mn-cse-transport", + "name": "REST", + "type": "REST_HTTP", + "protocol": "HTTPS", + "version": "4.0", + "endpoint": { + "uris": [ + self.fullAddress + ], + "fqdn": None, + "addresses": None, + "alternative": None + }, + "security": None + }, + "serializer": "JSON", + "scopeOfLocality": "MEC_SYSTEM", + "consumedLocalOnly": True + } + url = \ + Configuration.mec_protocol + '://' + Configuration.mec_host + ':' + str(Configuration.mec_port) + \ + '/' + Configuration.mec_sandbox_id + \ + '/' + Configuration.mec_platform + \ + '/mec_service_mgmt/v1/applications/' + self.mec_app_instance_id + '/services' + L.log('MECClient.POST_mec_service: ' + str(req_body)) + L.log('MECClient.POST_mec_service: ' + str(url)) + response = requests.post(url, headers=self.headers, json=req_body, verify=False) + return Result(rsc = response.status_code) + except Exception as e: + L.logErr(f'MECClient.POST_mec_service: ' + str(e)) + return Result(rsc = ResponseStatusCode.INTERNAL_SERVER_ERROR, dbg = 'MEC Declare MEC service failure') \ No newline at end of file diff --git a/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme/runtime/CSE.py b/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme/runtime/CSE.py index d4311f7a7..73de781ba 100644 --- a/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme/runtime/CSE.py +++ b/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme/runtime/CSE.py @@ -228,14 +228,12 @@ def startup(args:argparse.Namespace, **kwargs:Dict[str, Any]) -> bool: if Configuration.mec_enable: L.log('Initializing MEC client') - - # Initialize the MEC client if Configuration.mqtt_websocket_enable: - mecClient = MECClient(Configuration.http_address, Configuration.http_port, Configuration.cse_resourceID, Configuration.cse_external_ip, Configuration.cse_external_port, Configuration.mqtt_websocket_enable, Configuration.mqtt_address, Configuration.mqtt_websocket_port, Configuration.mec_platform+"/"+Configuration.mec_sandbox_id+"/"+) + mecClient = MECClient(Configuration.http_address, Configuration.http_port, Configuration.cse_resourceID, Configuration.cse_external_ip, Configuration.cse_external_port, Configuration.mqtt_websocket_enable, Configuration.mqtt_address, Configuration.mqtt_websocket_port, Configuration.fullAddress, Configuration.mec_app_instance_id, Configuration.mec_platform+"/"+Configuration.mec_sandbox_id+"/") else: - mecClient = MECClient(Configuration.http_address, Configuration.http_port, Configuration.cse_resourceID, Configuration.cse_external_ip, Configuration.cse_external_port, Configuration.mqtt_websocket_enable, Configuration.mqtt_address, Configuration.mqtt_port) + mecClient = MECClient(Configuration.http_address, Configuration.http_port, Configuration.cse_resourceID, Configuration.cse_external_ip, Configuration.cse_external_port, Configuration.mqtt_websocket_enable, Configuration.mqtt_address, Configuration.mqtt_port, Configuration.fullAddress, Configuration.mec_app_instance_id) if mecClient is None: - Configuration.mec_enable = False + Configuration.mec_enable = False # → Experimental late loading # @@ -481,6 +479,8 @@ def run() -> None: L.logDebug(f'MEC enable: {Configuration.mec_enable}') if Configuration.mec_enable: + mecClient.confirm_readyToMec() + mecClient.post_mec_service() mecClient.registerToMec() if waitFor(C.cseStartupDelay * 3, lambda: RC.cseStatus == CSEStatus.RUNNING): diff --git a/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme/runtime/Configuration.py b/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme/runtime/Configuration.py index a44cf2b7b..a344407de 100644 --- a/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme/runtime/Configuration.py +++ b/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme/runtime/Configuration.py @@ -265,6 +265,8 @@ class Configuration(object): database_postgresql_schema:str """ The schema of the PostgreSQL database. """ + fullAddress:str + """ The full address of the MN-CSE. """ http_address:str """ The address to listen on for HTTP the http server. """ @@ -375,6 +377,8 @@ class Configuration(object): logging_enableUTCTimezone:bool """ Enable or disable UTC timezone. """ + mec_app_instance_id:str + """ MEC application instance id. """ mqtt_address:str """ The address to listen on for the MQTT server. """ diff --git a/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme/runtime/configurations/MECClientConfiguration.py b/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme/runtime/configurations/MECClientConfiguration.py index be6bf4a1e..c94fb6bbe 100644 --- a/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme/runtime/configurations/MECClientConfiguration.py +++ b/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme/runtime/configurations/MECClientConfiguration.py @@ -35,6 +35,8 @@ class MECClientConfiguration(ModuleConfiguration): config.mec_protocol = parser.get('etsi_mec', 'mec_protocol', fallback = 'https') config.mec_platform = parser.get('etsi_mec', 'mec_platform', fallback = 'mep1') config.mec_sandbox_id = parser.get('etsi_mec', 'mec_sandbox_id', fallback = 'mec_sandbox_id') + config.fullAddress = parser.get('etsi_mec', 'fullAddress', fallback = None) + config.mec_app_instance_id = parser.get('etsi_mec', 'mec_app_instance_id', fallback = None) def validateConfiguration(self, config:Configuration, initial:Optional[bool] = False) -> None: """ Validate the configuration. @@ -61,5 +63,9 @@ class MECClientConfiguration(ModuleConfiguration): Configuration.cse_external_ip = Configuration._cse_external_ip if Configuration._cse_external_port is not None: Configuration.cse_external_port = Configuration._cse_external_port + if Configuration.fullAddress is not None: + Configuration.fullAddress = Configuration.fullAddress + if Configuration.mec_app_instance_id is not None: + Configuration.mec_app_instance_id = Configuration.mec_app_instance_id config.mec_host = normalizeURL(config.mec_host) diff --git a/go-apps/meep-iot-pltf/meep-acme-mn-cse/entrypoint.sh b/go-apps/meep-iot-pltf/meep-acme-mn-cse/entrypoint.sh index c1fce9fb1..b7393f130 100755 --- a/go-apps/meep-iot-pltf/meep-acme-mn-cse/entrypoint.sh +++ b/go-apps/meep-iot-pltf/meep-acme-mn-cse/entrypoint.sh @@ -2,9 +2,12 @@ set -e echo "MEEP_HOST_URL: ${MEEP_HOST_URL}" -SERVER_IP="${MEEP_HOST_URL#http://}"; MEEP_HOST_URL="${MEEP_HOST_URL#https://}" +# SERVER_IP="${MEEP_HOST_URL#http://}"; MEEP_HOST_URL="${MEEP_HOST_URL#https://}" +SERVER_IP="${MEEP_HOST_URL#http://}" +SERVER_IP="${SERVER_IP#https://}" -echo "MEC_PLATFORM=$MEC_PLATFORM" +echo "MEEP_HOST_URL: ${MEEP_HOST_URL}" +echo "MEC_PLATFORM=$MEEP_MEP_NAME" echo "MEEP_SANDBOX_NAME=$MEEP_SANDBOX_NAME" # Other environment variables @@ -19,6 +22,7 @@ echo "MQTT_HOST: ${MQTT_HOST}" echo "MQTT_PORT: ${MQTT_PORT}" echo "MQTT_USERNAME: ${MQTT_USERNAME}" echo "MQTT_PASSWORD: ${MQTT_PASSWORD}" +echo "APP_INSTANCE_ID: ${MEEP_INSTANCE_ID}" sleep 10 # Wait for the MEC platform to stablize and acme in cse to be ready @@ -26,62 +30,62 @@ sleep 10 # Wait for the MEC platform to stablize and acme in cse to be ready SERVICE_NAME="meep-mosquitto" NAMESPACE=$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace) TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) -MOSQUITTO_NODE_IP_ADDRESS=$(curl -sSk \ - -H "Authorization: Bearer $TOKEN" \ - https://kubernetes.default.svc/api/v1/namespaces/$NAMESPACE/services/$SERVICE_NAME \ - | jq -r '.spec.clusterIP') -echo "Internal IP exposed for service [$SERVICE_NAME] in namespace [$NAMESPACE] is: $MOSQUITTO_NODE_IP_ADDRESS" - -# Retrieve the internal meep-mosquitto port id -MOSQUITTO_NODE_PORT=$(curl -sSk \ - -H "Authorization: Bearer $TOKEN" \ - https://kubernetes.default.svc/api/v1/namespaces/$NAMESPACE/services/$SERVICE_NAME \ - | jq -r '.spec.ports[0].targetPort') -echo "Internal NodePort exposed for service [$SERVICE_NAME] in namespace [$NAMESPACE] is: $MOSQUITTO_NODE_PORT" - -# Retrieve the internal meep-acme-in-cse IP address -SERVICE_NAME="meep-acme-in-cse" -REMOTE_CSE_IP_ADDRESS=$(curl -sSk \ - -H "Authorization: Bearer $TOKEN" \ - https://kubernetes.default.svc/api/v1/namespaces/$NAMESPACE/services/$SERVICE_NAME \ - | jq -r '.spec.clusterIP') -echo "Internal IP exposed for service [$SERVICE_NAME] in namespace [$NAMESPACE] is: $REMOTE_CSE_IP_ADDRESS" - -# Retrieve the internal meep-acme-in-cse port id -SERVICE_NAME="meep-acme-in-cse" -NODE_PORT_IN_CSE=$(curl -sSk \ - -H "Authorization: Bearer $TOKEN" \ - https://kubernetes.default.svc/api/v1/namespaces/$NAMESPACE/services/$SERVICE_NAME \ - | jq -r '.spec.ports[0].targetPort') -echo "Internal NodePort exposed for service [$SERVICE_NAME] in namespace [$NAMESPACE] is: $NODE_PORT_IN_CSE" - -SERVICE_NAME="meep-acme-mn-cse" -NODE_IP=$(curl -sSk \ - -H "Authorization: Bearer $TOKEN" \ - https://kubernetes.default.svc/api/v1/namespaces/$NAMESPACE/services/$SERVICE_NAME \ - | jq -r '.spec.clusterIP') -echo "External NodePort exposed for service [$SERVICE_NAME] in namespace [$NAMESPACE] is: $NODE_IP" -NODE_PORT=$(curl -sSk \ - -H "Authorization: Bearer $TOKEN" \ - https://kubernetes.default.svc/api/v1/namespaces/$NAMESPACE/services/$SERVICE_NAME \ - | jq -r '.spec.ports[0].nodePort') -echo "External NodePort exposed for service [$SERVICE_NAME] in namespace [$NAMESPACE] is: $NODE_PORT" +# MOSQUITTO_NODE_IP_ADDRESS=$(curl -sSk \ +# -H "Authorization: Bearer $TOKEN" \ +# https://kubernetes.default.svc/api/v1/namespaces/$NAMESPACE/services/$SERVICE_NAME \ +# | jq -r '.spec.clusterIP') +# echo "Internal IP exposed for service [$SERVICE_NAME] in namespace [$NAMESPACE] is: $MOSQUITTO_NODE_IP_ADDRESS" + +# # Retrieve the internal meep-mosquitto port id +# MOSQUITTO_NODE_PORT=$(curl -sSk \ +# -H "Authorization: Bearer $TOKEN" \ +# https://kubernetes.default.svc/api/v1/namespaces/$NAMESPACE/services/$SERVICE_NAME \ +# | jq -r '.spec.ports[0].targetPort') +# echo "Internal NodePort exposed for service [$SERVICE_NAME] in namespace [$NAMESPACE] is: $MOSQUITTO_NODE_PORT" + +# # Retrieve the internal meep-acme-in-cse IP address +# SERVICE_NAME="meep-acme-in-cse" +# REMOTE_CSE_IP_ADDRESS=$(curl -sSk \ +# -H "Authorization: Bearer $TOKEN" \ +# https://kubernetes.default.svc/api/v1/namespaces/$NAMESPACE/services/$SERVICE_NAME \ +# | jq -r '.spec.clusterIP') +# echo "Internal IP exposed for service [$SERVICE_NAME] in namespace [$NAMESPACE] is: $REMOTE_CSE_IP_ADDRESS" + +# # Retrieve the internal meep-acme-in-cse port id +# SERVICE_NAME="meep-acme-in-cse" +# NODE_PORT_IN_CSE=$(curl -sSk \ +# -H "Authorization: Bearer $TOKEN" \ +# https://kubernetes.default.svc/api/v1/namespaces/$NAMESPACE/services/$SERVICE_NAME \ +# | jq -r '.spec.ports[0].targetPort') +# echo "Internal NodePort exposed for service [$SERVICE_NAME] in namespace [$NAMESPACE] is: $NODE_PORT_IN_CSE" + +# SERVICE_NAME="meep-acme-mn-cse" +# NODE_IP=$(curl -sSk \ +# -H "Authorization: Bearer $TOKEN" \ +# https://kubernetes.default.svc/api/v1/namespaces/$NAMESPACE/services/$SERVICE_NAME \ +# | jq -r '.spec.clusterIP') +# echo "External NodePort exposed for service [$SERVICE_NAME] in namespace [$NAMESPACE] is: $NODE_IP" +# NODE_PORT=$(curl -sSk \ +# -H "Authorization: Bearer $TOKEN" \ +# https://kubernetes.default.svc/api/v1/namespaces/$NAMESPACE/services/$SERVICE_NAME \ +# | jq -r '.spec.ports[0].nodePort') +# echo "External NodePort exposed for service [$SERVICE_NAME] in namespace [$NAMESPACE] is: $NODE_PORT" # The following name is the one name used to represent its block in scenario at endpoint /alt -ACME_IN_SERVICE_NAME=${ACME_IN_SERVICE_NAME:-"om2m-acme-in-cse"} -# Fetch pod name acme in cse -POD_NAME=$(curl -sSk \ - -H "Authorization: Bearer $TOKEN" \ - https://kubernetes.default.svc/api/v1/namespaces/$NAMESPACE/pods \ - | jq -r --arg svc "$ACME_IN_SERVICE_NAME" '.items[] | select(.metadata.labels.app == $svc) | .metadata.name' | head -n 1) -echo "Pod name for service [$ACME_IN_SERVICE_NAME] in namespace [$NAMESPACE] is: $POD_NAME" - -# Step 2: Get the MEEP_MEP_NAME of ACME IN CSE environment variable from the pod -ACME_MEEP_MEP_NAME=$(curl -sSk \ - -H "Authorization: Bearer $TOKEN" \ - https://kubernetes.default.svc/api/v1/namespaces/$NAMESPACE/pods/$POD_NAME \ - | jq -r '.spec.containers[0].env[] | select(.name=="MEEP_MEP_NAME") | .value') -echo "MEEP_MEP_NAME for service [$ACME_IN_SERVICE_NAME] in namespace [$NAMESPACE] is: $ACME_MEEP_MEP_NAME" +# ACME_IN_SERVICE_NAME=${ACME_IN_SERVICE_NAME:-"monaco-telecom-meep-acme-in-cse"} +# # Fetch pod name acme in cse +# POD_NAME=$(curl -sSk \ +# -H "Authorization: Bearer $TOKEN" \ +# https://kubernetes.default.svc/api/v1/namespaces/$NAMESPACE/pods \ +# | jq -r --arg svc "$ACME_IN_SERVICE_NAME" '.items[] | select(.metadata.labels.app == $svc) | .metadata.name' | head -n 1) +# echo "Pod name for service [$ACME_IN_SERVICE_NAME] in namespace [$NAMESPACE] is: $POD_NAME" + +# # Step 2: Get the MEEP_MEP_NAME of ACME IN CSE environment variable from the pod +# ACME_MEEP_MEP_NAME=$(curl -sSk \ +# -H "Authorization: Bearer $TOKEN" \ +# https://kubernetes.default.svc/api/v1/namespaces/$NAMESPACE/pods/$POD_NAME \ +# | jq -r '.spec.containers[0].env[] | select(.name=="MEEP_MEP_NAME") | .value') +# echo "MEEP_MEP_NAME for service [$ACME_IN_SERVICE_NAME] in namespace [$NAMESPACE] is: $ACME_MEEP_MEP_NAME" if [[ ! -z "${MEEP_MEP_NAME}" ]]; then svcPath="${MEEP_SANDBOX_NAME}/${MEEP_MEP_NAME}" @@ -99,30 +103,34 @@ SERVER_IP=`echo $SERVER_IP | sed -e "s/https:\/\///g"` # Remove https:// SERVER_TYPE=${SERVER_TYPE:-"MN"} SERVER_PORT=${SERVER_PORT:-3004} +# MN-CSE Address + CSE_BASE_NAME=${CSE_BASE_NAME:-"mep-cse-mn"} CSE_BASE_RI=${CSE_BASE_RI:-"acme-mep-id-mn-cse"} +MN_CSE_FULL_ADDRESS="https://${SERVER_IP}/${svcPath}/meep-acme-mn-cse" # REMOTE_CSE_HOST="${REMOTE_CSE_IP_ADDRESS:-"meep-acme-in-cse"}" # REMOTE_CSE_PORT=${NODE_PORT_IN_CSE:-3003} REMOTE_CSE_HOST=${SERVER_IP:-"meep-acme-in-cse"} -REMOTE_CSE_PORT=80/${MEEP_SANDBOX_NAME}/${ACME_MEEP_MEP_NAME:-"mep1"}/meep-acme-in-cse +REMOTE_CSE_PORT=443/${MEEP_SANDBOX_NAME}/${ACME_MEEP_MEP_NAME:-"monaco-telecom"}/meep-acme-in-cse REMOTE_CSE_ID=${REMOTE_CSE_ID:-"laboai-id-in"} REMOTE_CSE_NAME=${REMOTE_CSE_NAME:-"laboai-cse-in"} ENABLE_COAP=${ENABLE_COAP:-false} ENABLE_WS=${ENABLE_WS:-false} -CSE_EXTERNAL_IP=${NODE_IP} -CSE_EXTERNAL_PORT=${NODE_PORT} +CSE_EXTERNAL_IP=${SERVER_IP} +CSE_EXTERNAL_PORT=${NODE_PORT:-443} # MEC Configuration MEC_ENABLE=${MEC_ENABLE:-true} MEC_HOST_URL=${SERVER_IP} -MEC_PLATFORM=${MEC_PLATFORM:-"mep1"} +MEC_PLATFORM=${MEEP_MEP_NAME:-"mep1"} MEC_SANDBOX_ID=${MEEP_SANDBOX_NAME:-"meep-sandbox"} +MEC_APP_INSTANCE_ID=${MEEP_INSTANCE_ID:-"meep-acme-mn-cse-instance"} # MQTT Configuration MQTT_ENABLE=${MQTT_ENABLE:-true} MQTT_HOST=${MOSQUITTO_NODE_IP_ADDRESS:-"meep-mosquito"} -MQTT_PORT=${MOSQUITTO_NODE_PORT:-443} +MQTT_PORT=443 MQTT_USERNAME=${MQTT_USERNAME:-"acme-mn-cse"} MQTT_PASSWORD=${MQTT_PASSWORD:-"mqtt"} @@ -147,15 +155,19 @@ echo "MQTT_USERNAME: ${MQTT_USERNAME}" echo "MQTT_PASSWORD: ${MQTT_PASSWORD}" echo "MEC_ENABLE: ${MEC_ENABLE}" echo "MEC_HOST_URL: ${MEC_HOST_URL}" -echo "MEC_PLATFORM: ${MEC_PLATFORM}" +echo "MEC_PLATFORM: ${MEEP_MEP_NAME}" echo "MEC_SANDBOX_ID: ${MEC_SANDBOX_ID}" echo "ENABLE_COAP: ${ENABLE_COAP}" echo "ENABLE_WS: ${ENABLE_WS}" echo "WEBSOCK_ETPATH: ${WEBSOCK_ETPATH}" +echo "MN_CSE_FULL_ADDRESS: ${MN_CSE_FULL_ADDRESS}" +echo "MEC_APP_INSTANCE_ID: ${MEC_APP_INSTANCE_ID}" export SERVER_TYPE export SERVER_IP export SERVER_PORT +export MN_CSE_FULL_ADDRESS +export MEC_APP_INSTANCE_ID export CSE_BASE_NAME export CSE_BASE_RI -- GitLab From c5f70510db02fbbde0c5776e22a8a91df7292662 Mon Sep 17 00:00:00 2001 From: Mudassar Khan Date: Mon, 1 Dec 2025 07:06:41 +0000 Subject: [PATCH 03/15] delete debug logs which were added for scenario debugging during scenario updates, fix map view which was not visible after update, ToDo: location pinpoint remaining --- go-packages/meep-model/model.go | 3 --- js-apps/meep-frontend/src/js/containers/idc-map.js | 11 ++++++----- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/go-packages/meep-model/model.go b/go-packages/meep-model/model.go index 77633f414..b22a9cd8a 100644 --- a/go-packages/meep-model/model.go +++ b/go-packages/meep-model/model.go @@ -19,7 +19,6 @@ package model import ( "encoding/json" "errors" - "fmt" "reflect" "strings" "sync" @@ -978,7 +977,6 @@ func (m *Model) GetNodeContext(name string) (ctx *NodeContext) { ctx = nil n := m.nodeMap.nameMap[name] - log.Debug("Node name: ", name, " Node: ", fmt.Sprintf("%+v", n)) if len(n) > 0 { nodeCtx := n[0].context var ok bool @@ -1333,7 +1331,6 @@ func (m *Model) parseNodes() (err error) { procCtx := NewNodeContext(m.scenario.Name, domain.Name, zone.Name, nl.Name, pl.Name) m.nodeMap.AddNode(NewNode(proc.Id, proc.Name, proc.Type_, proc, nil, pl, procCtx)) m.networkGraph.AddNode(proc.Name, pl.Name, false) - log.Info("Model.go: Added process: ", proc.Name, " type: ", proc.Type_, " to physical location: ", pl.Name) // Update service map for external processes if proc.IsExternal { var nodeServiceMaps dataModel.NodeServiceMaps diff --git a/js-apps/meep-frontend/src/js/containers/idc-map.js b/js-apps/meep-frontend/src/js/containers/idc-map.js index 525105500..5bca9d50f 100644 --- a/js-apps/meep-frontend/src/js/containers/idc-map.js +++ b/js-apps/meep-frontend/src/js/containers/idc-map.js @@ -227,8 +227,8 @@ class IDCMap extends Component { assetName: pl.name, id: pl.id, radius: pl.geoData ? pl.geoData.radius : 0, - position: pl.geoData && pl.geoData.location ? pl.geoData.location.coordinates : [0,0], - path: pl.geoData && pl.geoData.path ? pl.geoData.path.coordinates : null, + location: pl.geoData && pl.geoData.location ? pl.geoData.location : {type: 'Point', coordinates: [0,0]}, + path: pl.geoData && pl.geoData.path ? pl.geoData.path : null, eopMode: pl.geoData ? pl.geoData.eopMode : null, velocity: pl.geoData ? pl.geoData.velocity : null }); @@ -236,7 +236,7 @@ class IDCMap extends Component { map.computeList.push({ assetName: pl.name, id: pl.id, - position: pl.geoData && pl.geoData.location ? pl.geoData.location.coordinates : [0,0] + location: pl.geoData && pl.geoData.location ? pl.geoData.location : {type: 'Point', coordinates: [0,0]} }); } }); @@ -246,7 +246,8 @@ class IDCMap extends Component { map.poaList.push({ assetName: nl.name, id: nl.id, - position: nl.geoData && nl.geoData.location ? nl.geoData.location.coordinates : [0,0] + location: nl.geoData && nl.geoData.location ? nl.geoData.location : {type: 'Point', coordinates: [0,0]}, + radius: nl.geoData ? nl.geoData.radius : 0 }); } }); @@ -802,7 +803,7 @@ class IDCMap extends Component { setUeMarker(ue) { var latlng = L.latLng(L.GeoJSON.coordsToLatLng(ue.location.coordinates)); - var pathLatLngs = ue.path ? L.GeoJSON.coordsToLatLngs(ue.path.coordinates) : null; + var pathLatLngs = (ue.path && ue.path.coordinates) ? L.GeoJSON.coordsToLatLngs(ue.path.coordinates) : null; // Find existing UE marker var existingMarker; -- GitLab From 7fc913202ad76665d7bd1e386c2856b29db4325e Mon Sep 17 00:00:00 2001 From: Mudassar Khan Date: Mon, 1 Dec 2025 07:52:39 +0000 Subject: [PATCH 04/15] fix view map in configuration mode in admin panel. --- .../src/js/containers/idc-map.js | 65 ++++++++++++------- 1 file changed, 41 insertions(+), 24 deletions(-) diff --git a/js-apps/meep-frontend/src/js/containers/idc-map.js b/js-apps/meep-frontend/src/js/containers/idc-map.js index 5bca9d50f..456a5a880 100644 --- a/js-apps/meep-frontend/src/js/containers/idc-map.js +++ b/js-apps/meep-frontend/src/js/containers/idc-map.js @@ -225,7 +225,7 @@ class IDCMap extends Component { if (pl.type === 'UE') { map.ueList.push({ assetName: pl.name, - id: pl.id, + id: (this.props.type === TYPE_CFG) ? pl.name : (pl.id || pl.name), radius: pl.geoData ? pl.geoData.radius : 0, location: pl.geoData && pl.geoData.location ? pl.geoData.location : {type: 'Point', coordinates: [0,0]}, path: pl.geoData && pl.geoData.path ? pl.geoData.path : null, @@ -235,7 +235,7 @@ class IDCMap extends Component { } else if (pl.type === 'FOG' || pl.type === 'EDGE' || pl.type === 'DC') { map.computeList.push({ assetName: pl.name, - id: pl.id, + id: (this.props.type === TYPE_CFG) ? pl.name : (pl.id || pl.name), location: pl.geoData && pl.geoData.location ? pl.geoData.location : {type: 'Point', coordinates: [0,0]} }); } @@ -245,7 +245,7 @@ class IDCMap extends Component { if (nl.type === 'POA' || nl.type === 'POA-4G' || nl.type === 'POA-5G' || nl.type === 'POA-WIFI') { map.poaList.push({ assetName: nl.name, - id: nl.id, + id: (this.props.type === TYPE_CFG) ? nl.name : (nl.id || nl.name), location: nl.geoData && nl.geoData.location ? nl.geoData.location : {type: 'Point', coordinates: [0,0]}, radius: nl.geoData ? nl.geoData.radius : 0 }); @@ -808,7 +808,7 @@ class IDCMap extends Component { // Find existing UE marker var existingMarker; this.ueOverlay.eachLayer((marker) => { - if (marker.options.meep.ue.id === ue.assetName){ + if (marker.options.meep.ue.id === (ue.id || ue.assetName)){ existingMarker = marker; return; } @@ -850,7 +850,8 @@ class IDCMap extends Component { var m = L.marker(latlng, { meep: { ue: { - id: ue.assetName, + id: ue.id || ue.assetName, + name: ue.assetName, path: p, eopMode: ue.eopMode, velocity: ue.velocity, @@ -943,7 +944,7 @@ class IDCMap extends Component { // Find existing POA marker var existingMarker; this.poaOverlay.eachLayer((marker) => { - if (marker.options.meep.poa.id === poa.assetName){ + if (marker.options.meep.poa.id === (poa.id || poa.assetName)){ existingMarker = marker; return; } @@ -974,7 +975,8 @@ class IDCMap extends Component { var m = L.marker(latlng, { meep: { poa: { - id: poa.assetName, + id: poa.id || poa.assetName, + name: poa.assetName, range: c } }, @@ -1024,7 +1026,7 @@ class IDCMap extends Component { // Find existing COMPUTE marker var existingMarker; this.computeOverlay.eachLayer((marker) => { - if (marker.options.meep.compute.id === compute.assetName){ + if (marker.options.meep.compute.id === (compute.id || compute.assetName)){ existingMarker = marker; return; } @@ -1044,7 +1046,8 @@ class IDCMap extends Component { var m = L.marker(latlng, { meep: { compute: { - id: compute.assetName, + id: compute.id || compute.assetName, + name: compute.assetName, connected: true } }, @@ -1241,20 +1244,20 @@ class IDCMap extends Component { } onEditModeToggle(e) { - var targetElemName = getElemFieldVal(this.props.configuredElement, FIELD_NAME); + var targetElemId = this.props.configuredElement ? this.props.configuredElement.id : null; if (e.enabled) { - this.setTarget(targetElemName); + this.setTarget(targetElemId); } else { - this.updateTargetGeoData(targetElemName, '', ''); + this.updateTargetGeoData(targetElemId, '', ''); } } onDragModeToggle(e) { - var targetElemName = getElemFieldVal(this.props.configuredElement, FIELD_NAME); + var targetElemId = this.props.configuredElement ? this.props.configuredElement.id : null; if (e.enabled) { - this.setTarget(targetElemName); + this.setTarget(targetElemId); } else { - this.updateTargetGeoData(targetElemName, '', ''); + this.updateTargetGeoData(targetElemId, '', ''); } } @@ -1274,8 +1277,8 @@ class IDCMap extends Component { } // Update configured element & refresh map to create the new marker or path - var targetElemName = getElemFieldVal(this.props.configuredElement, FIELD_NAME); - this.updateTargetGeoData(targetElemName, location, path); + var targetElemId = this.props.configuredElement ? this.props.configuredElement.id : null; + this.updateTargetGeoData(targetElemId, location, path); } onPoaMoved(e) { @@ -1289,14 +1292,14 @@ class IDCMap extends Component { this.props.cfgElemUpdate(updatedElem); } - updateTargetGeoData(targetElemName, location, path) { - if (!targetElemName) { + updateTargetGeoData(targetElemId, location, path) { + if (!targetElemId) { return; } // Get latest geoData from map, if any if (!location) { - var markerInfo = this.getMarkerInfo(targetElemName); + var markerInfo = this.getMarkerInfo(targetElemId); if (markerInfo && markerInfo.marker) { location = JSON.stringify(L.GeoJSON.latLngToCoords(markerInfo.marker.getLatLng())); if (!path && markerInfo.type === TYPE_UE && markerInfo.marker.options.meep.ue.path) { @@ -1332,6 +1335,8 @@ class IDCMap extends Component { setTarget(target) { // Disable changes on all markers except target + var isDragModeEnabled = this.map.pm.globalDragModeEnabled(); + this.ueOverlay.eachLayer((marker) => { var path = marker.options.meep.ue.path; if (marker.pm && (!target || marker.options.meep.ue.id !== target)) { @@ -1343,8 +1348,14 @@ class IDCMap extends Component { } } else { marker.setOpacity(OPACITY_TARGET); + if (marker.pm && isDragModeEnabled) { + marker.pm.enable(); + } if (path) { path.setStyle({opacity: OPACITY_TARGET}); + if (path.pm && this.map.pm.globalEditEnabled()) { + path.pm.enable(); + } } } }); @@ -1355,6 +1366,9 @@ class IDCMap extends Component { marker.options.meep.poa.range.setStyle({opacity: target ? POA_RANGE_OPACITY_BACKGROUND : POA_RANGE_OPACITY}); } else { marker.setOpacity(OPACITY_TARGET); + if (marker.pm && isDragModeEnabled) { + marker.pm.enable(); + } marker.options.meep.poa.range.setStyle({opacity: OPACITY_TARGET}); } }); @@ -1364,6 +1378,9 @@ class IDCMap extends Component { marker.setOpacity(target ? COMPUTE_OPACITY_BACKGROUND : COMPUTE_OPACITY); } else { marker.setOpacity(OPACITY_TARGET); + if (marker.pm && isDragModeEnabled) { + marker.pm.enable(); + } } }); } @@ -1380,11 +1397,11 @@ class IDCMap extends Component { var removalModeEnabled = false; // Update target element name & reset controls on target change - var targetElemName = getElemFieldVal(this.props.configuredElement, FIELD_NAME); + var targetElemId = this.props.configuredElement ? this.props.configuredElement.id : null; // Determine which controls to enable - if (targetElemName) { - var markerInfo = this.getMarkerInfo(targetElemName); + if (targetElemId) { + var markerInfo = this.getMarkerInfo(targetElemId); if (markerInfo && markerInfo.marker) { // Enable path create/edit for UE only if (markerInfo.type === TYPE_UE) { @@ -1429,7 +1446,7 @@ class IDCMap extends Component { } // Set target element & disable edit on all other markers - this.setTarget(targetElemName); + this.setTarget(targetElemId); } render() { -- GitLab From 69ed825bff7d78ef1f7272a069a586ab081776a3 Mon Sep 17 00:00:00 2001 From: Mudassar Khan Date: Mon, 1 Dec 2025 09:03:02 +0000 Subject: [PATCH 05/15] updated ACME MN CSE as per latest changes --- go-apps/meep-iot-pltf/meep-acme-mn-cse/Dockerfile | 2 +- go-apps/meep-iot-pltf/meep-acme-mn-cse/acme.ini.in | 11 +++++++++-- go-apps/meep-iot-pltf/meep-acme-mn-cse/entrypoint.sh | 5 +++++ 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/go-apps/meep-iot-pltf/meep-acme-mn-cse/Dockerfile b/go-apps/meep-iot-pltf/meep-acme-mn-cse/Dockerfile index 63e52a625..7ef8c3035 100644 --- a/go-apps/meep-iot-pltf/meep-acme-mn-cse/Dockerfile +++ b/go-apps/meep-iot-pltf/meep-acme-mn-cse/Dockerfile @@ -50,7 +50,7 @@ RUN echo "meep-acme-mn-cse" > /etc/hostname \ WORKDIR /usr/src/app -RUN git clone --branch master https://github.com/ankraft/ACME-oneM2M-CSE.git ACME-oneM2M-CSE +RUN git clone --branch development https://github.com/ankraft/ACME-oneM2M-CSE.git ACME-oneM2M-CSE WORKDIR /usr/src/app/ACME-oneM2M-CSE diff --git a/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme.ini.in b/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme.ini.in index 9c18c868f..d500ceafb 100644 --- a/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme.ini.in +++ b/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme.ini.in @@ -48,8 +48,15 @@ startWithTUI=false enable=true [http] -enableUpperTesterEndpoint=true -enableStructureEndpoint=true +enableUpperTesterEndpoint = true +enableStructureEndpoint = true +enableManagementEndpoint = true +;address=https://$SERVER_IP +;path=$SVC_PATH +externalPath=$SVC_PATH + +[webui] +;root=$SVC_PATH/webui [mqtt] enable=$MQTT_ENABLE diff --git a/go-apps/meep-iot-pltf/meep-acme-mn-cse/entrypoint.sh b/go-apps/meep-iot-pltf/meep-acme-mn-cse/entrypoint.sh index b7393f130..035403c76 100755 --- a/go-apps/meep-iot-pltf/meep-acme-mn-cse/entrypoint.sh +++ b/go-apps/meep-iot-pltf/meep-acme-mn-cse/entrypoint.sh @@ -136,6 +136,8 @@ MQTT_PASSWORD=${MQTT_PASSWORD:-"mqtt"} WEBSOCK_ETPATH="/$MEC_SANDBOX_ID"${WEBSOCK_ETPATH:-"/monaco-telecom/meep-cloud-mosquitto"} +SVC_PATH="/${svcPath}/meep-acme-mn-cse" + echo "Environment variables set:" echo "SERVER_TYPE: ${SERVER_TYPE}" echo "SERVER_IP: ${SERVER_IP}" @@ -162,6 +164,7 @@ echo "ENABLE_WS: ${ENABLE_WS}" echo "WEBSOCK_ETPATH: ${WEBSOCK_ETPATH}" echo "MN_CSE_FULL_ADDRESS: ${MN_CSE_FULL_ADDRESS}" echo "MEC_APP_INSTANCE_ID: ${MEC_APP_INSTANCE_ID}" +echo "SVC_PATH: ${SVC_PATH}" export SERVER_TYPE export SERVER_IP @@ -192,6 +195,8 @@ export MEC_HOST_URL export MEC_PLATFORM export MEC_SANDBOX_ID +export SVC_PATH + workdir="/usr/src/app/ACME-oneM2M-CSE" cd "$workdir" || { echo "Directory $workdir not found"; exit 1; } envsubst < acme.ini.in > acme.ini -- GitLab From 2b8cb4b623b8d3eade8b2900f6eb688c3451a628 Mon Sep 17 00:00:00 2001 From: Mudassar Khan Date: Wed, 10 Dec 2025 13:10:50 +0000 Subject: [PATCH 06/15] ACME MQTT Connection issue resolved --- go-apps/meep-iot-pltf/meep-acme-in-cse/acme.ini.in | 5 ++++- go-apps/meep-iot-pltf/meep-acme-in-cse/entrypoint.sh | 4 ++-- go-apps/meep-iot-pltf/meep-acme-mn-cse/acme.ini.in | 5 ++++- go-apps/meep-iot-pltf/meep-acme-mn-cse/entrypoint.sh | 4 ++-- 4 files changed, 12 insertions(+), 6 deletions(-) diff --git a/go-apps/meep-iot-pltf/meep-acme-in-cse/acme.ini.in b/go-apps/meep-iot-pltf/meep-acme-in-cse/acme.ini.in index a2dbd1964..8c5cb07da 100644 --- a/go-apps/meep-iot-pltf/meep-acme-in-cse/acme.ini.in +++ b/go-apps/meep-iot-pltf/meep-acme-in-cse/acme.ini.in @@ -37,9 +37,12 @@ keepalive=45 [mqtt.websocket] enable=$MQTT_ENABLE port=$MQTT_PORT -transport=websockets +;transport=websockets path=$WEBSOCK_ETPATH +[mqtt.security] +useTLS=true + [cse.registration] ; Edit this to add more allowed originators. allowedCSROriginators=/$CSE_BASE_RI,/acme-mep-id-mn-cse,/id-in,/id-mn,/id-asn diff --git a/go-apps/meep-iot-pltf/meep-acme-in-cse/entrypoint.sh b/go-apps/meep-iot-pltf/meep-acme-in-cse/entrypoint.sh index 7edfcb949..837cbeaf5 100755 --- a/go-apps/meep-iot-pltf/meep-acme-in-cse/entrypoint.sh +++ b/go-apps/meep-iot-pltf/meep-acme-in-cse/entrypoint.sh @@ -64,12 +64,12 @@ ENABLE_WS=${ENABLE_WS:-false} # MQTT Configuration MQTT_ENABLE=${MQTT_ENABLE:-true} -MQTT_HOST=${MOSQUITTO_NODE_IP_ADDRESS:-"monaco-telecom-meep-cloud-mosquitto"} +MQTT_HOST=${SERVER_IP:-"monaco-telecom-meep-cloud-mosquitto"} MQTT_PORT=${MOSQUITTO_NODE_PORT:-443} MQTT_USERNAME=${MQTT_USERNAME:-"acme-mn-cse"} MQTT_PASSWORD=${MQTT_PASSWORD:-"mqtt"} -WEBSOCK_ETPATH="/$MEC_SANDBOX_ID"${WEBSOCK_ETPATH:-"/monaco-telecom/meep-cloud-mosquitto"} +WEBSOCK_ETPATH="/$MEC_SANDBOX_ID"${WEBSOCK_ETPATH:-"/monaco-telecom/meep-mosquitto"} echo "Environment variables set:" echo "SERVER_TYPE: ${SERVER_TYPE}" diff --git a/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme.ini.in b/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme.ini.in index d500ceafb..28e75f84b 100644 --- a/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme.ini.in +++ b/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme.ini.in @@ -66,9 +66,12 @@ keepalive=45 [mqtt.websocket] enable=$MQTT_ENABLE port=$MQTT_PORT -transport=websockets +;transport=websockets path=$WEBSOCK_ETPATH +[mqtt.security] +useTLS=true + [coap] enable=$ENABLE_COAP port=5683 diff --git a/go-apps/meep-iot-pltf/meep-acme-mn-cse/entrypoint.sh b/go-apps/meep-iot-pltf/meep-acme-mn-cse/entrypoint.sh index 035403c76..37e37389c 100755 --- a/go-apps/meep-iot-pltf/meep-acme-mn-cse/entrypoint.sh +++ b/go-apps/meep-iot-pltf/meep-acme-mn-cse/entrypoint.sh @@ -129,12 +129,12 @@ MEC_APP_INSTANCE_ID=${MEEP_INSTANCE_ID:-"meep-acme-mn-cse-instance"} # MQTT Configuration MQTT_ENABLE=${MQTT_ENABLE:-true} -MQTT_HOST=${MOSQUITTO_NODE_IP_ADDRESS:-"meep-mosquito"} +MQTT_HOST=${SERVER_IP:-"meep-mosquito"} MQTT_PORT=443 MQTT_USERNAME=${MQTT_USERNAME:-"acme-mn-cse"} MQTT_PASSWORD=${MQTT_PASSWORD:-"mqtt"} -WEBSOCK_ETPATH="/$MEC_SANDBOX_ID"${WEBSOCK_ETPATH:-"/monaco-telecom/meep-cloud-mosquitto"} +WEBSOCK_ETPATH="/$MEC_SANDBOX_ID"${WEBSOCK_ETPATH:-"/monaco-telecom/meep-mosquitto"} SVC_PATH="/${svcPath}/meep-acme-mn-cse" -- GitLab From 1465488e28816e960a33cb76203ecd51b93e2f51 Mon Sep 17 00:00:00 2001 From: garciay Date: Wed, 10 Dec 2025 14:55:55 +0100 Subject: [PATCH 07/15] Add support of MQTT+WSS in meep-iot (CR needed) --- go-apps/meep-iot/server/meep-iot.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/go-apps/meep-iot/server/meep-iot.go b/go-apps/meep-iot/server/meep-iot.go index cb1c1f27c..9ebf3a1ee 100644 --- a/go-apps/meep-iot/server/meep-iot.go +++ b/go-apps/meep-iot/server/meep-iot.go @@ -755,9 +755,9 @@ func registerediotplatformsPOST(w http.ResponseWriter, r *http.Request) { errHandlerProblemDetails(w, "Mandatory attribute Type_ shall be set to MB_TOPIC_BASED in the request body.", http.StatusBadRequest) return } - if v.Protocol != "MQTT" && v.Protocol != "AMQP" { - log.Error("Mandatory Protocol parameter shall be set to MQTT or AMQP") - errHandlerProblemDetails(w, "Mandatory attribute Protocol shall be set to MQTT or AMQP in the request body.", http.StatusBadRequest) + if v.Protocol != "MQTT" && v.Protocol != "MQTT+WSS" && v.Protocol != "AMQP" { + log.Error("Mandatory Protocol parameter shall be set to MQTT, MQTT+WSS or AMQP") + errHandlerProblemDetails(w, "Mandatory attribute Protocol shall be set to MQTT, MQTT+WSS or AMQP in the request body.", http.StatusBadRequest) return } if v.Version == "" { -- GitLab From 45e467a3087a9e37622138c2fdca1fff96c8c7a7 Mon Sep 17 00:00:00 2001 From: Mudassar Khan Date: Thu, 11 Dec 2025 07:43:46 +0000 Subject: [PATCH 08/15] update acme code to connect with mec sandbox and corrected request bodies for registering with mec 033 --- .../acme/protocols/MECClient.py | 21 +++++++------------ .../meep-acme-mn-cse/acme/runtime/CSE.py | 2 +- 2 files changed, 9 insertions(+), 14 deletions(-) diff --git a/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme/protocols/MECClient.py b/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme/protocols/MECClient.py index f13c8913e..207bb9adb 100644 --- a/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme/protocols/MECClient.py +++ b/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme/protocols/MECClient.py @@ -236,17 +236,13 @@ class MECClient(object): if self.use_wss: userTransportInfo['endpoint']['uris'] = [] userTransportInfo['endpoint']['uris'].append('wss://' + self.mqtt_address + ':' + str(self.mqtt_port) + self.wss_path) + else: + userTransportInfo['endpoint']['addresses'] = [] address = {} address['host'] = self.mqtt_address address['port'] = self.mqtt_port userTransportInfo['endpoint']['addresses'].append(address) - else: - # userTransportInfo['endpoint']['addresses'] = [] - # address = {} - # address['host'] = self.mqtt_address - # address['port'] = self.mqtt_port - # userTransportInfo['endpoint']['addresses'].append(address) - userTransportInfo['endpoint']['uris'] = [ self.fullAddress ] + # userTransportInfo['endpoint']['uris'] = [ self.fullAddress ] # address = {} # address['host'] = self.mqtt_address # address['port'] = self.mqtt_port @@ -258,17 +254,16 @@ class MECClient(object): customServicesTransportInfoList = [] customServicesTransportInfo = {} customServicesTransportInfo['id'] = str(uuid.uuid4()) - customServicesTransportInfo['name'] = self.cse_resourceID + customServicesTransportInfo['name'] = Configuration.cse_resourceName customServicesTransportInfo['description'] = 'ACME oneM2M CSE' customServicesTransportInfo['type'] = 'REST_HTTP' customServicesTransportInfo['protocol'] = 'REST_HTTP' customServicesTransportInfo['version'] = '4' customServicesTransportInfo['endpoint'] = {} - customServicesTransportInfo['endpoint']['addresses'] = [] - address = {} - address['host'] = self.cse_external_ip - address['port'] = int(self.http_port) #int(self.cse_external_port) - customServicesTransportInfo['endpoint']['addresses'].append(address) + if self.fullAddress == '': + customServicesTransportInfo['endpoint']['uris'] = [ 'https://' + self.cse_external_ip + ':' + str(self.http_port) ] + else: + customServicesTransportInfo['endpoint']['uris'] = [ self.fullAddress ] customServicesTransportInfo['security'] = {} customServicesTransportInfoList.append(customServicesTransportInfo) body_json['customServicesTransportInfo'] = customServicesTransportInfoList diff --git a/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme/runtime/CSE.py b/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme/runtime/CSE.py index 73de781ba..d966099da 100644 --- a/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme/runtime/CSE.py +++ b/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme/runtime/CSE.py @@ -229,7 +229,7 @@ def startup(args:argparse.Namespace, **kwargs:Dict[str, Any]) -> bool: if Configuration.mec_enable: L.log('Initializing MEC client') if Configuration.mqtt_websocket_enable: - mecClient = MECClient(Configuration.http_address, Configuration.http_port, Configuration.cse_resourceID, Configuration.cse_external_ip, Configuration.cse_external_port, Configuration.mqtt_websocket_enable, Configuration.mqtt_address, Configuration.mqtt_websocket_port, Configuration.fullAddress, Configuration.mec_app_instance_id, Configuration.mec_platform+"/"+Configuration.mec_sandbox_id+"/") + mecClient = MECClient(Configuration.http_address, Configuration.http_port, Configuration.cse_resourceID, Configuration.cse_external_ip, Configuration.cse_external_port, Configuration.mqtt_websocket_enable, Configuration.mqtt_address, Configuration.mqtt_websocket_port, Configuration.fullAddress, Configuration.mec_app_instance_id, Configuration.mqtt_websocket_path) else: mecClient = MECClient(Configuration.http_address, Configuration.http_port, Configuration.cse_resourceID, Configuration.cse_external_ip, Configuration.cse_external_port, Configuration.mqtt_websocket_enable, Configuration.mqtt_address, Configuration.mqtt_port, Configuration.fullAddress, Configuration.mec_app_instance_id) if mecClient is None: -- GitLab From 428488407bd91dd312249f5b897041d911548080 Mon Sep 17 00:00:00 2001 From: Mudassar Khan Date: Tue, 6 Jan 2026 09:31:18 +0000 Subject: [PATCH 09/15] update ACME configurations to connect MN and IN CSEs so that announce functionality of ACME could be utilized. --- .../meep-acme-in-cse/acme.ini.in | 11 ++++++++-- .../meep-acme-in-cse/entrypoint.sh | 5 +++++ .../meep-acme-mn-cse/acme.ini.in | 20 ++++++++++++------- .../meep-acme-mn-cse/entrypoint.sh | 8 ++++++-- 4 files changed, 33 insertions(+), 11 deletions(-) diff --git a/go-apps/meep-iot-pltf/meep-acme-in-cse/acme.ini.in b/go-apps/meep-iot-pltf/meep-acme-in-cse/acme.ini.in index 8c5cb07da..fa94fcee9 100644 --- a/go-apps/meep-iot-pltf/meep-acme-in-cse/acme.ini.in +++ b/go-apps/meep-iot-pltf/meep-acme-in-cse/acme.ini.in @@ -29,6 +29,9 @@ databaseType=memory logLevel=debug consoleTheme=dark +[cse] +poa=https://$SERVER_IP:443/$SVC_PATH + [mqtt] enable=$MQTT_ENABLE address=$MQTT_HOST @@ -45,7 +48,9 @@ useTLS=true [cse.registration] ; Edit this to add more allowed originators. -allowedCSROriginators=/$CSE_BASE_RI,/acme-mep-id-mn-cse,/id-in,/id-mn,/id-asn +;allowedCSROriginators=/$CSE_BASE_RI,/acme-mep-id-mn-cse,/id-in,/id-mn,/id-asn,/mep-id-mn-cse +allowedCSROriginators=/* +;address=https://${basic.config:registrarCseHost}:${basic.config:registrarCsePort} [textui] startWithTUI=false @@ -56,11 +61,13 @@ enable=true [http] enableUpperTesterEndpoint=true enableStructureEndpoint=true +;root=/$SVC_PATH/ +address=https://${basic.config:cseHost}:${basic.config:httpPort}${http:root} [coap] enable=$ENABLE_COAP port=5683 [websocket] -enable=$ENABLE_WS +enable=false port=8180 diff --git a/go-apps/meep-iot-pltf/meep-acme-in-cse/entrypoint.sh b/go-apps/meep-iot-pltf/meep-acme-in-cse/entrypoint.sh index 837cbeaf5..b6a407171 100755 --- a/go-apps/meep-iot-pltf/meep-acme-in-cse/entrypoint.sh +++ b/go-apps/meep-iot-pltf/meep-acme-in-cse/entrypoint.sh @@ -53,6 +53,8 @@ fi sleep 5 # Wait for ETSI MEC Platform up and stable +SVC_PATH="${svcPath}/meep-acme-in-cse" + SERVER_IP=`echo $SERVER_IP | sed -e "s/https:\/\///g"` # Remove https:// SERVER_PORT=${SERVER_PORT:-3003} MEC_SANDBOX_ID=${MEEP_SANDBOX_NAME:-"meep-sandbox"} @@ -85,6 +87,7 @@ echo "MQTT_PORT: ${MQTT_PORT}" echo "MQTT_USERNAME: ${MQTT_USERNAME}" echo "MQTT_PASSWORD: ${MQTT_PASSWORD}" echo "WEBSOCK_ETPATH: ${WEBSOCK_ETPATH}" +echo "SVC_PATH: ${SVC_PATH}" export SERVER_TYPE export SERVER_IP @@ -102,6 +105,8 @@ export MQTT_USERNAME export MQTT_PASSWORD export WEBSOCK_ETPATH +export SVC_PATH + workdir="/usr/src/app/ACME-oneM2M-CSE" cd "$workdir" || { echo "Directory $workdir not found"; exit 1; } envsubst < acme.ini.in > acme.ini diff --git a/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme.ini.in b/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme.ini.in index 28e75f84b..710c1be7d 100644 --- a/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme.ini.in +++ b/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme.ini.in @@ -34,12 +34,18 @@ databaseType=memory logLevel=debug consoleTheme=dark +[cse] +poa=https://SERVER_IP/SVC_PATH + [cse.registration] ; Edit this to add more allowed originators. -allowedCSROriginators=/id-in,/id-mn,/id-asn +;allowedCSROriginators=/$REMOTE_CSE_ID,/laboai-id-in,/laboai-cse-in,/acme-mep-id-mn-cse,/id-in,/id-mn,/id-asn,/mep-id-mn-cse +allowedCSROriginators=/* [cse.registrar] INCSEcseID=/$REMOTE_CSE_ID +address=https://${basic.config:registrarCseHost}:${basic.config:registrarCsePort}/ +root=$REMOTE_SVC_PATH [textui] startWithTUI=false @@ -50,13 +56,10 @@ enable=true [http] enableUpperTesterEndpoint = true enableStructureEndpoint = true -enableManagementEndpoint = true -;address=https://$SERVER_IP -;path=$SVC_PATH -externalPath=$SVC_PATH +address=https://${basic.config:cseHost}:${basic.config:httpPort}${http:root} [webui] -;root=$SVC_PATH/webui +;root=/$SVC_PATH/webui [mqtt] enable=$MQTT_ENABLE @@ -77,9 +80,12 @@ enable=$ENABLE_COAP port=5683 [websocket] -enable=$ENABLE_WS +enable=false port=8180 +[logging] +enableBindingsLogging = true + [etsi_mec] mec_enable=$MEC_ENABLE mec_host=$MEC_HOST_URL diff --git a/go-apps/meep-iot-pltf/meep-acme-mn-cse/entrypoint.sh b/go-apps/meep-iot-pltf/meep-acme-mn-cse/entrypoint.sh index 37e37389c..feba66c51 100755 --- a/go-apps/meep-iot-pltf/meep-acme-mn-cse/entrypoint.sh +++ b/go-apps/meep-iot-pltf/meep-acme-mn-cse/entrypoint.sh @@ -111,7 +111,9 @@ MN_CSE_FULL_ADDRESS="https://${SERVER_IP}/${svcPath}/meep-acme-mn-cse" # REMOTE_CSE_HOST="${REMOTE_CSE_IP_ADDRESS:-"meep-acme-in-cse"}" # REMOTE_CSE_PORT=${NODE_PORT_IN_CSE:-3003} REMOTE_CSE_HOST=${SERVER_IP:-"meep-acme-in-cse"} -REMOTE_CSE_PORT=443/${MEEP_SANDBOX_NAME}/${ACME_MEEP_MEP_NAME:-"monaco-telecom"}/meep-acme-in-cse +# REMOTE_CSE_PORT=443/${MEEP_SANDBOX_NAME}/${ACME_MEEP_MEP_NAME:-"monaco-telecom"}/meep-acme-in-cse +REMOTE_CSE_PORT=443 +REMOTE_SVC_PATH=${MEEP_SANDBOX_NAME}/${ACME_MEEP_MEP_NAME:-"monaco-telecom"}/meep-acme-in-cse REMOTE_CSE_ID=${REMOTE_CSE_ID:-"laboai-id-in"} REMOTE_CSE_NAME=${REMOTE_CSE_NAME:-"laboai-cse-in"} ENABLE_COAP=${ENABLE_COAP:-false} @@ -136,7 +138,7 @@ MQTT_PASSWORD=${MQTT_PASSWORD:-"mqtt"} WEBSOCK_ETPATH="/$MEC_SANDBOX_ID"${WEBSOCK_ETPATH:-"/monaco-telecom/meep-mosquitto"} -SVC_PATH="/${svcPath}/meep-acme-mn-cse" +SVC_PATH="${svcPath}/meep-acme-mn-cse" echo "Environment variables set:" echo "SERVER_TYPE: ${SERVER_TYPE}" @@ -165,6 +167,7 @@ echo "WEBSOCK_ETPATH: ${WEBSOCK_ETPATH}" echo "MN_CSE_FULL_ADDRESS: ${MN_CSE_FULL_ADDRESS}" echo "MEC_APP_INSTANCE_ID: ${MEC_APP_INSTANCE_ID}" echo "SVC_PATH: ${SVC_PATH}" +echo "REMOTE_SVC_PATH: ${REMOTE_SVC_PATH}" export SERVER_TYPE export SERVER_IP @@ -178,6 +181,7 @@ export REMOTE_CSE_ID export REMOTE_CSE_NAME export REMOTE_CSE_HOST export REMOTE_CSE_PORT +export REMOTE_SVC_PATH export CSE_EXTERNAL_IP export CSE_EXTERNAL_PORT export ENABLE_COAP -- GitLab From 4b6e4fec5fac6deefe1e3108b0383b2bbbb9882a Mon Sep 17 00:00:00 2001 From: Mudassar Khan Date: Tue, 6 Jan 2026 10:56:28 +0000 Subject: [PATCH 10/15] small fix in ACME configurations --- go-apps/meep-iot-pltf/meep-acme-mn-cse/acme.ini.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme.ini.in b/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme.ini.in index 710c1be7d..5c54139ca 100644 --- a/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme.ini.in +++ b/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme.ini.in @@ -35,7 +35,7 @@ logLevel=debug consoleTheme=dark [cse] -poa=https://SERVER_IP/SVC_PATH +poa=https://$SERVER_IP:443/$SVC_PATH [cse.registration] ; Edit this to add more allowed originators. -- GitLab From 541a56dac2042c21ea809512baa33684e853ed72 Mon Sep 17 00:00:00 2001 From: Mudassar Khan Date: Tue, 6 Jan 2026 10:57:28 +0000 Subject: [PATCH 11/15] updated request body for ACME registration using MEC IoT API --- .../meep-acme-mn-cse/acme/protocols/MECClient.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme/protocols/MECClient.py b/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme/protocols/MECClient.py index 207bb9adb..10424bcdf 100644 --- a/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme/protocols/MECClient.py +++ b/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme/protocols/MECClient.py @@ -219,7 +219,7 @@ class MECClient(object): userTransportInfoList = [] userTransportInfo = {} userTransportInfo['id'] = str(uuid.uuid4()) - userTransportInfo['name'] = Configuration.cse_resourceName + userTransportInfo['name'] = Configuration.cse_cseID userTransportInfo['type'] = 'MB_TOPIC_BASED' if self.use_wss: userTransportInfo['description'] = 'MQTT over WS-Secured' @@ -254,8 +254,8 @@ class MECClient(object): customServicesTransportInfoList = [] customServicesTransportInfo = {} customServicesTransportInfo['id'] = str(uuid.uuid4()) - customServicesTransportInfo['name'] = Configuration.cse_resourceName - customServicesTransportInfo['description'] = 'ACME oneM2M CSE' + customServicesTransportInfo['name'] = Configuration.cse_cseID + customServicesTransportInfo['description'] = 'ACME oneM2M CSE ID' customServicesTransportInfo['type'] = 'REST_HTTP' customServicesTransportInfo['protocol'] = 'REST_HTTP' customServicesTransportInfo['version'] = '4' -- GitLab From 92660cda8a8ca44aec9b4311813d89a53b179322 Mon Sep 17 00:00:00 2001 From: Mudassar Khan Date: Thu, 8 Jan 2026 11:17:40 +0000 Subject: [PATCH 12/15] fix(webui): fix configuration blocking ACME Web UI access --- .../meep-iot-pltf/meep-acme-in-cse/Dockerfile | 2 +- .../meep-acme-in-cse/acme.ini.in | 8 ++- .../meep-acme-mn-cse/acme.ini.in | 8 +-- .../acme/protocols/MECClient.py | 5 +- .../meep-acme-mn-cse/acme/runtime/CSE.py | 25 +++++++-- .../acme/runtime/Configuration.py | 54 +++++++++++++------ 6 files changed, 74 insertions(+), 28 deletions(-) diff --git a/go-apps/meep-iot-pltf/meep-acme-in-cse/Dockerfile b/go-apps/meep-iot-pltf/meep-acme-in-cse/Dockerfile index 3d7e2705d..1eab6208e 100644 --- a/go-apps/meep-iot-pltf/meep-acme-in-cse/Dockerfile +++ b/go-apps/meep-iot-pltf/meep-acme-in-cse/Dockerfile @@ -43,7 +43,7 @@ RUN echo "meep-acme-in-cse" > /etc/hostname \ WORKDIR /usr/src/app -RUN git clone --branch master https://github.com/ankraft/ACME-oneM2M-CSE.git ACME-oneM2M-CSE +RUN git clone --branch development https://github.com/ankraft/ACME-oneM2M-CSE.git ACME-oneM2M-CSE WORKDIR /usr/src/app/ACME-oneM2M-CSE diff --git a/go-apps/meep-iot-pltf/meep-acme-in-cse/acme.ini.in b/go-apps/meep-iot-pltf/meep-acme-in-cse/acme.ini.in index fa94fcee9..c434ab0ce 100644 --- a/go-apps/meep-iot-pltf/meep-acme-in-cse/acme.ini.in +++ b/go-apps/meep-iot-pltf/meep-acme-in-cse/acme.ini.in @@ -61,8 +61,12 @@ enable=true [http] enableUpperTesterEndpoint=true enableStructureEndpoint=true -;root=/$SVC_PATH/ -address=https://${basic.config:cseHost}:${basic.config:httpPort}${http:root} +root=/ +address=https://${basic.config:cseHost}:${basic.config:httpPort}${http:externalRoot} +externalRoot=/$SVC_PATH/ + +[webui] +root=/webui [coap] enable=$ENABLE_COAP diff --git a/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme.ini.in b/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme.ini.in index 5c54139ca..5115ca606 100644 --- a/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme.ini.in +++ b/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme.ini.in @@ -56,10 +56,12 @@ enable=true [http] enableUpperTesterEndpoint = true enableStructureEndpoint = true -address=https://${basic.config:cseHost}:${basic.config:httpPort}${http:root} +root=/ +address=https://${basic.config:cseHost}:${basic.config:httpPort}${http:externalRoot} +externalRoot=/$SVC_PATH/ [webui] -;root=/$SVC_PATH/webui +root=/webui [mqtt] enable=$MQTT_ENABLE @@ -84,7 +86,7 @@ enable=false port=8180 [logging] -enableBindingsLogging = true +enableBindingsLogging = false [etsi_mec] mec_enable=$MEC_ENABLE diff --git a/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme/protocols/MECClient.py b/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme/protocols/MECClient.py index 10424bcdf..08008b053 100644 --- a/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme/protocols/MECClient.py +++ b/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme/protocols/MECClient.py @@ -253,8 +253,9 @@ class MECClient(object): body_json['userTransportInfo'] = userTransportInfoList customServicesTransportInfoList = [] customServicesTransportInfo = {} - customServicesTransportInfo['id'] = str(uuid.uuid4()) - customServicesTransportInfo['name'] = Configuration.cse_cseID + # customServicesTransportInfo['id'] = str(uuid.uuid4()) + customServicesTransportInfo['id'] = Configuration.cse_cseID + customServicesTransportInfo['name'] = Configuration.cse_resourceName customServicesTransportInfo['description'] = 'ACME oneM2M CSE ID' customServicesTransportInfo['type'] = 'REST_HTTP' customServicesTransportInfo['protocol'] = 'REST_HTTP' diff --git a/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme/runtime/CSE.py b/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme/runtime/CSE.py index d966099da..b1b0ad018 100644 --- a/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme/runtime/CSE.py +++ b/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme/runtime/CSE.py @@ -37,6 +37,7 @@ from ..services.GroupManager import GroupManager from ..runtime.Importer import Importer from ..services.LocationManager import LocationManager from ..services.NotificationManager import NotificationManager +from ..runtime.PluginManager import PluginManager from ..services.RegistrationManager import RegistrationManager from ..services.RemoteCSEManager import RemoteCSEManager from ..runtime.ScriptManager import ScriptManager @@ -97,6 +98,9 @@ mqttClient:MQTTClient = None notification:NotificationManager = None """ Runtime instance of the `NotificationManager`. """ +pluginManager:PluginManager = None +""" Runtime instance of the `PluginManager`. """ + registration:RegistrationManager = None """ Runtime instance of the `RegistrationManager`. """ @@ -159,7 +163,7 @@ def startup(args:argparse.Namespace, **kwargs:Dict[str, Any]) -> bool: False if the CSE couldn't initialized and started. """ global action, announce, coapServer, console, dispatcher, event, groupResource, httpServer, importer, location, mqttClient, mecClient - global notification, registration, remote, request, script, security, semantic, statistics, storage, textUI, time + global notification, pluginManager, registration, remote, request, script, security, semantic, statistics, storage, textUI, time global timeSeries, validator, webSocketServer # Set status @@ -254,6 +258,11 @@ def startup(args:argparse.Namespace, **kwargs:Dict[str, Any]) -> bool: RC.cseStatus = CSEStatus.STOPPED return False + # Initialize the plugin manager + # This loads, configures and runs the plugins as well + pluginManager = PluginManager() + + # Start the HTTP server if not httpServer.run(): # This does return (!) L.logErr('Terminating', showStackTrace = False) @@ -282,8 +291,13 @@ def startup(args:argparse.Namespace, **kwargs:Dict[str, Any]) -> bool: L.logErr(f'Error during startup: {e.dbg}') RC.cseStatus = CSEStatus.STOPPED return False + except KeyError as e: + L.logErr(f'Error during startup: {e}') + RC.cseStatus = CSEStatus.STOPPED + return False + except Exception as e: - L.logErr(f'Error during startup: {e}', exc = e) + L.logErr(f'Error during startup: {e}', exc=e) RC.cseStatus = CSEStatus.STOPPED return False @@ -309,7 +323,7 @@ def startup(args:argparse.Namespace, **kwargs:Dict[str, Any]) -> bool: def shutdown() -> None: - """ Gracefully shutdown the CSE programmatically. This will end the mail console loop + """ Gracefully shutdown the CSE programmatically. This will end the main console loop to terminate. The actual shutdown happens in the _shutdown() method. @@ -349,6 +363,7 @@ def _shutdown() -> None: event.cseShutdown() # type: ignore # shutdown the services + pluginManager and pluginManager.shutdown() textUI and textUI.shutdown() console and console.shutdown() time and time.shutdown() @@ -451,7 +466,7 @@ def resetCSE() -> None: # Enable log queuing again L.queueOn() - # Send restart event + # Send restarted event event.cseRestarted() # type: ignore [attr-defined] RC.cseStatus = CSEStatus.RUNNING @@ -483,7 +498,7 @@ def run() -> None: mecClient.post_mec_service() mecClient.registerToMec() - if waitFor(C.cseStartupDelay * 3, lambda: RC.cseStatus == CSEStatus.RUNNING): + if waitFor(C.cseStartupDelay * 3, lambda: RC.cseStatus==CSEStatus.RUNNING): console.run() else: raise TimeoutError(L.logErr(f'CSE did not start within {C.cseStartupDelay * 3} seconds')) diff --git a/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme/runtime/Configuration.py b/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme/runtime/Configuration.py index a344407de..36b613214 100644 --- a/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme/runtime/Configuration.py +++ b/go-apps/meep-iot-pltf/meep-acme-mn-cse/acme/runtime/Configuration.py @@ -16,6 +16,7 @@ from typing import Any, Dict, Tuple, Optional, cast, Set import configparser, argparse, os, os.path, pathlib from copy import deepcopy from inspect import getmembers +from dotenv import load_dotenv, find_dotenv from rich.console import Console @@ -53,6 +54,9 @@ class Configuration(object): """ + configParser:ACMEConfiguration = None + """ The ACMEConfiguration instance holding the configuration values. """ + coap_enable:bool """ Enable or disable the CoAP server. """ @@ -200,6 +204,14 @@ class Configuration(object): """ The size of the operation requests. """ + cse_operation_plugins_disabledPlugins:list[str] + """ A list of disabled plugins. """ + + cse_operation_plugins_replace:bool + """ Replace existing plugins with the same name. """ + + + cse_registrars:dict[str, CSERegistrar] = {} """ A dictionary of CSE or service provider CSEs registrars. The keys are the CSE IDs, the values are dictionaries with the registrar information. """ @@ -292,6 +304,9 @@ class Configuration(object): http_root:str """ The root of the HTTP path. """ + http_externalRoot:str + """ The non-local root path of the HTTP path. This is used when the CSE is accessed from non-local addresses, e.g. in a Kubernetes cluster. """ + http_timeout:float """ The timeout for HTTP requests. """ @@ -860,7 +875,7 @@ class Configuration(object): zk.disconnect() # Read and parse the configuration file - config = ACMEConfiguration() + Configuration.configParser = ACMEConfiguration() # Construct the default values that are used for interpolation _defaults = { 'basic.config': { @@ -881,35 +896,45 @@ class Configuration(object): 'secret' : os.getenv('ACME_SECURITY_SECRET', 'acme'), # The main secret key for the CSE. } } + # Load environment variables from .env file from the base directory, if it exists + load_dotenv(dotenv_path=f'{Configuration.baseDirectory}{os.path.sep}.env') + # Add environment variables to the defaults _defaults.update({ 'DEFAULT': {k: v.replace('$', '$$') for k,v in os.environ.items()} }) # Add (empty) default for supported environment variables to the defaults dictionary for the interpolation during reading the configuration file _envVariables = { e: os.getenv(e, '') if e not in _defaults else _defaults[e] for e in ( - 'ACME_MQTT_SECURITY_PASSWORD', 'ACME_MQTT_SECURITY_USERNAME', + 'ACME_MQTT_SECURITY_PASSWORD', + 'ACME_MQTT_SECURITY_USERNAME', 'ACME_DATABASE_POSTGRESQL_PASSWORD', - 'ACME_CSE_REGISTRAR_SECURITY_HTTPUSERNAME', 'ACME_CSE_REGISTRAR_SECURITY_HTTPPASSWORD', 'ACME_CSE_REGISTRAR_SECURITY_HTTPBEARERTOKEN', - 'ACME_CSE_REGISTRAR_SECURITY_WSUSERNAME', 'ACME_CSE_REGISTRAR_SECURITY_WSPASSWORD', 'ACME_CSE_REGISTRAR_SECURITY_WSBEARERTOKEN', - 'ACME_CSE_REGISTRAR_SECURITY_SELFHTTPUSERNAME', 'ACME_CSE_REGISTRAR_SECURITY_SELFHTTPPASSWORD', - 'ACME_CSE_REGISTRAR_SECURITY_SELFWSUSERNAME', 'ACME_CSE_REGISTRAR_SECURITY_SELFWSPASSWORD', + 'ACME_CSE_REGISTRAR_SECURITY_HTTPUSERNAME', + 'ACME_CSE_REGISTRAR_SECURITY_HTTPPASSWORD', + 'ACME_CSE_REGISTRAR_SECURITY_HTTPBEARERTOKEN', + 'ACME_CSE_REGISTRAR_SECURITY_WSUSERNAME', + 'ACME_CSE_REGISTRAR_SECURITY_WSPASSWORD', + 'ACME_CSE_REGISTRAR_SECURITY_WSBEARERTOKEN', + 'ACME_CSE_REGISTRAR_SECURITY_SELFHTTPUSERNAME', + 'ACME_CSE_REGISTRAR_SECURITY_SELFHTTPPASSWORD', + 'ACME_CSE_REGISTRAR_SECURITY_SELFWSUSERNAME', + 'ACME_CSE_REGISTRAR_SECURITY_SELFWSPASSWORD', ) } _defaults['DEFAULT'].update(_envVariables) # Set the defaults - config.read_dict(_defaults) + Configuration.configParser.read_dict(_defaults) try: # Read the configuration files # if len(config.read( [Configuration._defaultConfigFile, Configuration.configfile])) == 0 and Configuration._args_configfile != C.defaultUserConfigFile: # Allow - if len(config.read(configurationFiles)) == 0 and Configuration._args_configfile != C.defaultUserConfigFile: # Allow + if len(Configuration.configParser.read(configurationFiles)) == 0 and Configuration._args_configfile != C.defaultUserConfigFile: # Allow Configuration._print(f'[red]Configuration file missing or not readable: {Configuration._args_configfile}') return False # Read the extra configuration strings (e.g. from Zookeeper) for cs in configurationStrings: - config.read_string(cs) + Configuration.configParser.read_string(cs) except configparser.Error as e: Configuration._print('[red]Error in configuration file') @@ -920,7 +945,7 @@ class Configuration(object): # Look for deprecated and renamed sections and print an error message if _deprecatedSections: for o, n in _deprecatedSections: - if config.has_section(o): + if Configuration.configParser.has_section(o): Configuration._print(fr'[red]Found old section name in configuration file. Please rename "\[{o}]" to "\[{n}]".') return False @@ -932,7 +957,7 @@ class Configuration(object): # and to set the respective attributes in the Configuration class. # Validations are done later below. for m in _moduleConfigs: - m.readConfiguration(config, Configuration) # type:ignore [arg-type] + m.readConfiguration(Configuration.configParser, Configuration) # type:ignore [arg-type] except configparser.InterpolationMissingOptionError as e: Configuration._print(f'[red]Error in configuration file: {Configuration.configfile}\n{str(e)}') @@ -983,8 +1008,8 @@ class Configuration(object): attr = getattr(Configuration, k) match attr: case pathlib.Path(): - # Convert pathlib.Path to string - attr = str(attr) + # Don't change the original dict, so make a copy + attr = deepcopy(attr) case dict(): # Convert dict elements to instances dict, if necessary for k2,v2 in attr.items(): @@ -994,8 +1019,7 @@ class Configuration(object): # Replace underscores with dots in the key names result[k.replace('_', '.')] = attr - result = deepcopy(result) # make sure that the result is a deep copy of the configuration - return result + return deepcopy(result) # make sure that the result is a deep copy of the configuration @staticmethod -- GitLab From 10aee56002fb783cb94e472e10e4e362f0a58272 Mon Sep 17 00:00:00 2001 From: Muhammad Umair Khan Date: Thu, 15 Jan 2026 15:40:16 +0500 Subject: [PATCH 13/15] update ansible playbook readme.md file --- playbooks/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/playbooks/README.md b/playbooks/README.md index 0080bd986..91a9b22cd 100644 --- a/playbooks/README.md +++ b/playbooks/README.md @@ -133,7 +133,7 @@ ansible-playbook -i inventories/dev/hosts.ini site.yml -K You can run just parts of the setup with `--tags` or skip parts with `--skip-tags`. (The roles here are intentionally simple and do not define custom tags; feel free to add them if you want finer control.) -## 📖 Notes +## Notes * Ensure worker nodes have SSH access configured before running. * Use `--tags` if you want to run specific roles (e.g. `--tags kubernetes,helm`). -- GitLab From bf6211a0607abe417ef6284453421d2798218740 Mon Sep 17 00:00:00 2001 From: Mudassar Khan Date: Wed, 28 Jan 2026 12:23:21 +0000 Subject: [PATCH 14/15] add demo10 which is to be presented in sns 2026 --- examples/demo10/MEC/Get_App_Instances.go | 35 ++ examples/demo10/MEC/ams.go | 337 ++++++++++++++++++ examples/demo10/MEC/iot_api.go | 26 ++ .../MEC/match_for_target_app_instance.go | 33 ++ examples/demo10/Model/app_instance_id.go | 7 + .../model_adjacent_app_info_notification.go | 35 ++ ...app_info_notification_adjacent_app_info.go | 32 ++ .../model_adjacent_app_info_subscription.go | 37 ++ ...t_app_info_subscription_filter_criteria.go | 30 ++ ...el_adjacent_app_info_subscription_links.go | 30 ++ .../Model/model_adjacent_app_instance_info.go | 37 ++ .../Model/model_app_mobility_service_level.go | 35 ++ .../model_app_termination_notification.go | 35 ++ ...del_app_termination_notification__links.go | 30 ++ examples/demo10/Model/model_associate_id.go | 31 ++ .../demo10/Model/model_associate_id_type.go | 36 ++ .../Model/model_communication_interface.go | 29 ++ ...el_communication_interface_ip_addresses.go | 30 ++ .../Model/model_context_transfer_state.go | 34 ++ .../demo10/Model/model_expiry_notification.go | 33 ++ .../demo10/Model/model_inline_notification.go | 29 ++ .../demo10/Model/model_inline_subscription.go | 44 +++ examples/demo10/Model/model_link.go | 30 ++ examples/demo10/Model/model_link_type.go | 31 ++ .../Model/model_mec_host_information.go | 31 ++ .../model_mobility_procedure_notification.go | 36 ++ ..._procedure_notification_target_app_info.go | 31 ++ .../model_mobility_procedure_subscription.go | 37 ++ ..._procedure_subscription_filter_criteria.go | 35 ++ ...l_mobility_procedure_subscription_links.go | 29 ++ .../demo10/Model/model_mobility_status.go | 35 ++ .../Model/model_one_of_inline_notification.go | 30 ++ .../Model/model_one_of_inline_subscription.go | 30 ++ .../Model/model_operation_action_type.go | 34 ++ .../demo10/Model/model_problem_details.go | 38 ++ .../demo10/Model/model_registration_info.go | 35 ++ ...el_registration_info_device_information.go | 31 ++ ...l_registration_info_service_consumer_id.go | 33 ++ .../Model/model_subscription_link_list.go | 29 ++ .../model_subscription_link_list_links.go | 32 ++ ...del_subscription_link_list_subscription.go | 31 ++ .../demo10/Model/model_subscription_type.go | 33 ++ .../demo10/Model/model_test_notification.go | 31 ++ .../Model/model_test_notification__links.go | 30 ++ examples/demo10/Model/model_time_stamp.go | 33 ++ .../Model/model_websock_notif_config.go | 32 ++ examples/demo10/Model/platform_info.go | 8 + examples/demo10/go.mod | 7 + examples/demo10/go.sum | 2 + examples/demo10/main.go | 268 ++++++++++++++ examples/demo10/oneM2M/createAE.go | 44 +++ .../demo10/oneM2M/createContentInstance.go | 43 +++ examples/demo10/oneM2M/createSubscription.go | 64 ++++ examples/demo10/oneM2M/createcontainer.go | 44 +++ examples/demo10/oneM2M/deregister.go | 27 ++ examples/demo10/oneM2M/oneM2m_init.go | 31 ++ examples/demo10/oneM2M/retrieveContainer.go | 28 ++ examples/demo10/oneM2M/retrieveLatestData.go | 30 ++ examples/demo10/utils/mec_req.go | 50 +++ examples/demo10/utils/onem2m_req.go | 53 +++ 60 files changed, 2481 insertions(+) create mode 100644 examples/demo10/MEC/Get_App_Instances.go create mode 100644 examples/demo10/MEC/ams.go create mode 100644 examples/demo10/MEC/iot_api.go create mode 100644 examples/demo10/MEC/match_for_target_app_instance.go create mode 100644 examples/demo10/Model/app_instance_id.go create mode 100644 examples/demo10/Model/model_adjacent_app_info_notification.go create mode 100644 examples/demo10/Model/model_adjacent_app_info_notification_adjacent_app_info.go create mode 100644 examples/demo10/Model/model_adjacent_app_info_subscription.go create mode 100644 examples/demo10/Model/model_adjacent_app_info_subscription_filter_criteria.go create mode 100644 examples/demo10/Model/model_adjacent_app_info_subscription_links.go create mode 100644 examples/demo10/Model/model_adjacent_app_instance_info.go create mode 100644 examples/demo10/Model/model_app_mobility_service_level.go create mode 100644 examples/demo10/Model/model_app_termination_notification.go create mode 100644 examples/demo10/Model/model_app_termination_notification__links.go create mode 100644 examples/demo10/Model/model_associate_id.go create mode 100644 examples/demo10/Model/model_associate_id_type.go create mode 100644 examples/demo10/Model/model_communication_interface.go create mode 100644 examples/demo10/Model/model_communication_interface_ip_addresses.go create mode 100644 examples/demo10/Model/model_context_transfer_state.go create mode 100644 examples/demo10/Model/model_expiry_notification.go create mode 100644 examples/demo10/Model/model_inline_notification.go create mode 100644 examples/demo10/Model/model_inline_subscription.go create mode 100644 examples/demo10/Model/model_link.go create mode 100644 examples/demo10/Model/model_link_type.go create mode 100644 examples/demo10/Model/model_mec_host_information.go create mode 100644 examples/demo10/Model/model_mobility_procedure_notification.go create mode 100644 examples/demo10/Model/model_mobility_procedure_notification_target_app_info.go create mode 100644 examples/demo10/Model/model_mobility_procedure_subscription.go create mode 100644 examples/demo10/Model/model_mobility_procedure_subscription_filter_criteria.go create mode 100644 examples/demo10/Model/model_mobility_procedure_subscription_links.go create mode 100644 examples/demo10/Model/model_mobility_status.go create mode 100644 examples/demo10/Model/model_one_of_inline_notification.go create mode 100644 examples/demo10/Model/model_one_of_inline_subscription.go create mode 100644 examples/demo10/Model/model_operation_action_type.go create mode 100644 examples/demo10/Model/model_problem_details.go create mode 100644 examples/demo10/Model/model_registration_info.go create mode 100644 examples/demo10/Model/model_registration_info_device_information.go create mode 100644 examples/demo10/Model/model_registration_info_service_consumer_id.go create mode 100644 examples/demo10/Model/model_subscription_link_list.go create mode 100644 examples/demo10/Model/model_subscription_link_list_links.go create mode 100644 examples/demo10/Model/model_subscription_link_list_subscription.go create mode 100644 examples/demo10/Model/model_subscription_type.go create mode 100644 examples/demo10/Model/model_test_notification.go create mode 100644 examples/demo10/Model/model_test_notification__links.go create mode 100644 examples/demo10/Model/model_time_stamp.go create mode 100644 examples/demo10/Model/model_websock_notif_config.go create mode 100644 examples/demo10/Model/platform_info.go create mode 100644 examples/demo10/go.mod create mode 100644 examples/demo10/go.sum create mode 100644 examples/demo10/main.go create mode 100644 examples/demo10/oneM2M/createAE.go create mode 100644 examples/demo10/oneM2M/createContentInstance.go create mode 100644 examples/demo10/oneM2M/createSubscription.go create mode 100644 examples/demo10/oneM2M/createcontainer.go create mode 100644 examples/demo10/oneM2M/deregister.go create mode 100644 examples/demo10/oneM2M/oneM2m_init.go create mode 100644 examples/demo10/oneM2M/retrieveContainer.go create mode 100644 examples/demo10/oneM2M/retrieveLatestData.go create mode 100644 examples/demo10/utils/mec_req.go create mode 100644 examples/demo10/utils/onem2m_req.go diff --git a/examples/demo10/MEC/Get_App_Instances.go b/examples/demo10/MEC/Get_App_Instances.go new file mode 100644 index 000000000..5a3f7dc79 --- /dev/null +++ b/examples/demo10/MEC/Get_App_Instances.go @@ -0,0 +1,35 @@ +package mec + +import ( + "fmt" + "net/http" + model "estimed_demo/Model" + utils "estimed_demo/utils" + "io" + "encoding/json" +) + +// Get MEC APP instances +func GetAppInstances(url string) ([]model.AppInstanceID, error) { + resp, err := utils.SendMECRequest("GET", url, nil) + if err != nil { + return nil, fmt.Errorf("failed to get MEC app instances: %v", err) + } + defer resp.Body.Close() + if resp.StatusCode != http.StatusOK { + return nil, fmt.Errorf("failed to get MEC App Instance ID: received status code %d", resp.StatusCode) + } + + // From the response body, extract all App Instance IDs + body, err := io.ReadAll(resp.Body) + if err != nil { + return nil, fmt.Errorf("failed to read response body: %v", err) + } + //log.Println("Response body:", string(body)) + + var allAppInstances []model.AppInstanceID + if err := json.Unmarshal(body, &allAppInstances); err != nil { + return nil, fmt.Errorf("failed to unmarshal response body: %v", err) + } + return allAppInstances, nil +} \ No newline at end of file diff --git a/examples/demo10/MEC/ams.go b/examples/demo10/MEC/ams.go new file mode 100644 index 000000000..d12de37a3 --- /dev/null +++ b/examples/demo10/MEC/ams.go @@ -0,0 +1,337 @@ +package mec + +import ( + "encoding/json" + model "estimed_demo/Model" + utils "estimed_demo/utils" + "fmt" + "log" + "net/http" + "regexp" +) + +// Create MEC AMS service registration +func CreateAMSRegistration(url string, app_instance_id string, device_info *model.RegistrationInfoDeviceInformation) (*model.RegistrationInfo, error) { + payload := &model.RegistrationInfo{} + if device_info != nil { + payload = &model.RegistrationInfo{ + ServiceConsumerId: &model.RegistrationInfoServiceConsumerId{ + AppInstanceId: app_instance_id, + }, + DeviceInformation: []model.RegistrationInfoDeviceInformation{*device_info}, + } + } else { + payload = &model.RegistrationInfo{ + ServiceConsumerId: &model.RegistrationInfoServiceConsumerId{ + AppInstanceId: app_instance_id, + }, + } + } + resp, err := utils.SendMECRequest("POST", url, payload) + if err != nil { + return nil, fmt.Errorf("failed to create AMS registration: %v", err) + } + defer resp.Body.Close() + if resp.StatusCode != http.StatusCreated { + return nil, fmt.Errorf("failed to create AMS registration: received status code %d", resp.StatusCode) + } + + var registrationInfo model.RegistrationInfo + if err := json.NewDecoder(resp.Body).Decode(®istrationInfo); err != nil { + return nil, fmt.Errorf("failed to decode AMS registration response: %v", err) + } + + return ®istrationInfo, nil +} + +// Create MEC AMS subscription + +func CreateAMSSubscription(url string, app_instance_id string, callbackURL string, associateId *model.AssociateId) (*model.InlineSubscription, error) { + payload := &model.InlineSubscription{} + if associateId != nil { + payload = &model.InlineSubscription{ + SubscriptionType: "MobilityProcedureSubscription", + FilterCriteria: &model.MobilityProcedureSubscriptionFilterCriteria{ + AppInstanceId: app_instance_id, + AssociateId: []model.AssociateId{*associateId}, + }, + CallbackReference: callbackURL, + } + } else { + payload = &model.InlineSubscription{ + SubscriptionType: "MobilityProcedureSubscription", + FilterCriteria: &model.MobilityProcedureSubscriptionFilterCriteria{ + AppInstanceId: app_instance_id, + }, + // TODO: Update callback reference URL as needed + CallbackReference: callbackURL, + } + } + + resp, err := utils.SendMECRequest("POST", url, payload) + if err != nil { + return nil, fmt.Errorf("failed to create AMS subscription: %v", err) + } + defer resp.Body.Close() + if resp.StatusCode != http.StatusCreated { + return nil, fmt.Errorf("failed to create AMS subscription: received status code %d", resp.StatusCode) + } + + var subscriptionInfo model.InlineSubscription + if err := json.NewDecoder(resp.Body).Decode(&subscriptionInfo); err != nil { + return nil, fmt.Errorf("failed to decode AMS subscription response: %v", err) + } + + return &subscriptionInfo, nil +} + +// AMSNotificationHandler handles incoming AMS notifications +func AMSNotificationHandler(w http.ResponseWriter, r *http.Request) (string, error) { + if r.Method != http.MethodPost { + http.Error(w, "Invalid request method", http.StatusMethodNotAllowed) + return "", fmt.Errorf("invalid request method") + } + + var notification map[string]interface{} + err := json.NewDecoder(r.Body).Decode(¬ification) + if err != nil { + http.Error(w, "Failed to decode request body", http.StatusBadRequest) + return "", fmt.Errorf("failed to decode request body: %w", err) + } + log.Printf("Received AMS notification: %+v", notification) + w.WriteHeader(http.StatusNoContent) + // Extract target app instance ID from the notification + var targetAppInstanceID string + if targetAppInfo, ok := notification["targetAppInfo"].(map[string]interface{}); ok { + if appInstanceID, ok := targetAppInfo["appInstanceId"].(string); ok { + targetAppInstanceID = appInstanceID + log.Printf("Target App Instance ID: %s", targetAppInstanceID) + } + } + if targetAppInstanceID == "" { + log.Println("Target App Instance ID not found in notification") + } + return targetAppInstanceID, nil +} + +func RegistrationAndSubscriptionHandler(matchingAppInstances []model.AppInstanceID, platformURL string, + sandbox_name string, callbackURL string, currentAppInstanceId *string, + deviceInfo *model.RegistrationInfoDeviceInformation, associateId *model.AssociateId) ([]map[string]model.PlatformInfo, error) { + var platformDetails []map[string]model.PlatformInfo + + for i, appInstance := range matchingAppInstances { + log.Printf("Creating AMS registration for App Instance ID: %s, Name: %s", appInstance.ID, appInstance.Name) + amsURL := fmt.Sprintf("%s/%s/mep1/amsi/v1/app_mobility_services", platformURL, sandbox_name) + var resp *model.RegistrationInfo + var err error + if i == 0 { + *currentAppInstanceId = appInstance.ID + resp, err = CreateAMSRegistration(amsURL, appInstance.ID, deviceInfo) + if err != nil { + return nil, fmt.Errorf("failed to create AMS registration: %v", err) + } else { + log.Printf("AMS registration created successfully: %v", resp) + } + } else { + resp, err = CreateAMSRegistration(amsURL, appInstance.ID, nil) + if err != nil { + return nil, fmt.Errorf("failed to create AMS registration: %v", err) + } else { + log.Printf("AMS registration created successfully: %v", resp) + } + } + amsSubURL := fmt.Sprintf("%s/%s/mep1/amsi/v1/subscriptions", platformURL, sandbox_name) + sub_resp := &model.InlineSubscription{} + if i == 0 { + sub_resp, err = CreateAMSSubscription(amsSubURL, appInstance.ID, callbackURL, associateId) + if err != nil { + return nil, fmt.Errorf("failed to create AMS subscription: %v", err) + } else { + log.Printf("AMS subscription created successfully: %v", sub_resp) + } + } else { + sub_resp, err = CreateAMSSubscription(amsSubURL, appInstance.ID, callbackURL, nil) + if err != nil { + return nil, fmt.Errorf("failed to create AMS subscription: %v", err) + } else { + log.Printf("AMS subscription created successfully: %v", sub_resp) + } + } + // Extract subscription ID from href using regex + subID := "" + if sub_resp.Links.Self.Href != "" { + re := regexp.MustCompile(`subscriptions/(.*)`) + matches := re.FindStringSubmatch(sub_resp.Links.Self.Href) + if len(matches) > 1 { + subID = matches[1] + } + } + platformInfo := model.PlatformInfo{ + AmsServiceID: resp.AppMobilityServiceId, + AppInstanceID: appInstance.ID, + AmsSubscriptionID: subID, + NodeName: appInstance.NodeName, + } + platformDetails = append(platformDetails, map[string]model.PlatformInfo{ + appInstance.ID: platformInfo, + }) + } + + return platformDetails, nil +} + +// TODO: Complete the function to update AMS registration info +func PutAMSRegistrationInfo(url string, targetappinstance string, platformDetails []map[string]model.PlatformInfo, + current_app_instance *string, associateID *model.AssociateId) error { + if len(platformDetails) == 0 { + return fmt.Errorf("platformDetails is empty") + } + if targetappinstance == "" { + log.Println("Initializing AMS registration info...") + } + + // Find the PlatformInfo for the current app instance by iterating through the slice + var currentPlatformInfo *model.PlatformInfo + for _, detail := range platformDetails { + if info, exists := detail[*current_app_instance]; exists { + currentPlatformInfo = &info + break // Found it, no need to continue + } + } + payload := model.RegistrationInfo{ + AppMobilityServiceId: currentPlatformInfo.AmsServiceID, + DeviceInformation: []model.RegistrationInfoDeviceInformation{ + { + AssociateId: associateID, + AppMobilityServiceLevel: &[]model.AppMobilityServiceLevel{"APP_MOBILITY_WITHOUT_CONFIRMATION"}[0], + ContextTransferState: &[]model.ContextTransferState{"USER_CONTEXT_TRANSFER_COMPLETED"}[0], + }, + }, + ServiceConsumerId: &model.RegistrationInfoServiceConsumerId{ + AppInstanceId: *current_app_instance, + }, + } + req_url := fmt.Sprintf("%s/%s", url, currentPlatformInfo.AmsServiceID) + resp, err := utils.SendMECRequest("PUT", req_url, payload) + if err != nil { + return fmt.Errorf("failed to update AMS registration info: %v", err) + } + defer resp.Body.Close() + if resp.StatusCode != http.StatusOK { + return fmt.Errorf("failed to update AMS registration info: received status code %d", resp.StatusCode) + } + log.Println("AMS registration info updated successfully") + + // find the PlatformInfo for the target app instance + var targetPlatformInfo *model.PlatformInfo + for _, detail := range platformDetails { + if info, exists := detail[targetappinstance]; exists { + targetPlatformInfo = &info + break // Found it, no need to continue + } + } + payload = model.RegistrationInfo{ + AppMobilityServiceId: targetPlatformInfo.AmsServiceID, + DeviceInformation: []model.RegistrationInfoDeviceInformation{ + { + AssociateId: associateID, + AppMobilityServiceLevel: &[]model.AppMobilityServiceLevel{"APP_MOBILITY_WITHOUT_CONFIRMATION"}[0], + ContextTransferState: &[]model.ContextTransferState{"NOT_TRANSFERRED"}[0], + }, + }, + ServiceConsumerId: &model.RegistrationInfoServiceConsumerId{ + AppInstanceId: targetappinstance, + }, + } + req_url = fmt.Sprintf("%s/%s", url, targetPlatformInfo.AmsServiceID) + resp, err = utils.SendMECRequest("PUT", req_url, payload) + if err != nil { + return fmt.Errorf("failed to update AMS registration info for target app instance: %v", err) + } + defer resp.Body.Close() + if resp.StatusCode != http.StatusOK { + return fmt.Errorf("failed to update AMS registration info for target app instance: received status code %d", resp.StatusCode) + } + + log.Println("AMS registration info for target app instance updated successfully") + + return nil +} + +func PUTAMSSubscriptionInfo(url string, targetappinstance string, platformDetails []map[string]model.PlatformInfo, + current_app_instance *string, call_back_url string, associateid *model.AssociateId) error { + if len(platformDetails) == 0 { + return fmt.Errorf("platformDetails is empty") + } + if targetappinstance == "" { + log.Println("Initializing AMS subscription info...") + } + + // Find the PlatformInfo for the current app instance by iterating through the slice + var currentPlatformInfo *model.PlatformInfo + for _, detail := range platformDetails { + if info, exists := detail[*current_app_instance]; exists { + currentPlatformInfo = &info + break // Found it, no need to continue + } + } + + payload := model.InlineSubscription{ + SubscriptionType: "MobilityProcedureSubscription", + Links: &model.MobilityProcedureSubscriptionLinks{ + Self: &model.LinkType{ + Href: fmt.Sprintf("%s/%s", url, currentPlatformInfo.AmsSubscriptionID), + }, + }, + CallbackReference: call_back_url, + FilterCriteria: &model.MobilityProcedureSubscriptionFilterCriteria{ + AppInstanceId: *current_app_instance, + AssociateId: []model.AssociateId{*associateid}, + MobilityStatus: []model.MobilityStatus{"INTERHOST_MOVEOUT_COMPLETED"}, + }, + } + resp, err := utils.SendMECRequest("PUT", fmt.Sprintf("%s/%s", url, currentPlatformInfo.AmsSubscriptionID), payload) + if err != nil { + return fmt.Errorf("failed to update AMS subscription info: %v", err) + } + defer resp.Body.Close() + if resp.StatusCode != http.StatusOK { + return fmt.Errorf("failed to update AMS subscription info: received status code %d", resp.StatusCode) + } + log.Println("AMS subscription info updated successfully") + + // find the PlatformInfo for the target app instance + var targetPlatformInfo *model.PlatformInfo + for _, detail := range platformDetails { + if info, exists := detail[targetappinstance]; exists { + targetPlatformInfo = &info + break // Found it, no need to continue + } + } + + payload = model.InlineSubscription{ + SubscriptionType: "MobilityProcedureSubscription", + Links: &model.MobilityProcedureSubscriptionLinks{ + Self: &model.LinkType{ + Href: fmt.Sprintf("%s/%s", url, targetPlatformInfo.AmsSubscriptionID), + }, + }, + CallbackReference: call_back_url, + FilterCriteria: &model.MobilityProcedureSubscriptionFilterCriteria{ + AppInstanceId: targetappinstance, + AssociateId: []model.AssociateId{*associateid}, + MobilityStatus: []model.MobilityStatus{"INTERHOST_MOVEOUT_TRIGGERED"}, + }, + } + resp, err = utils.SendMECRequest("PUT", fmt.Sprintf("%s/%s", url, targetPlatformInfo.AmsSubscriptionID), payload) + if err != nil { + return fmt.Errorf("failed to update AMS subscription info for target app instance: %v", err) + } + defer resp.Body.Close() + if resp.StatusCode != http.StatusOK { + return fmt.Errorf("failed to update AMS subscription info for target app instance: received status code %d", resp.StatusCode) + } + + log.Println("AMS subscription info for target app instance updated successfully") + return nil +} diff --git a/examples/demo10/MEC/iot_api.go b/examples/demo10/MEC/iot_api.go new file mode 100644 index 000000000..f643a703b --- /dev/null +++ b/examples/demo10/MEC/iot_api.go @@ -0,0 +1,26 @@ +package mec + +import ( + "encoding/json" + utils "estimed_demo/utils" + "fmt" + "net/http" +) + +// Fetch for platform info +func GETIotPlatformInfo(url string) ([]map[string]interface{}, error) { + resp, err := utils.SendMECRequest("GET", url, nil) + if err != nil { + return nil, fmt.Errorf("failed to get IoT platform info: %v", err) + } + defer resp.Body.Close() + if resp.StatusCode != http.StatusOK { + return nil, fmt.Errorf("failed to get IoT platform info: received status code %d", resp.StatusCode) + } + + var platformInfo []map[string]interface{} + if err := json.NewDecoder(resp.Body).Decode(&platformInfo); err != nil { + return nil, fmt.Errorf("failed to decode IoT platform info: %v", err) + } + return platformInfo, nil +} \ No newline at end of file diff --git a/examples/demo10/MEC/match_for_target_app_instance.go b/examples/demo10/MEC/match_for_target_app_instance.go new file mode 100644 index 000000000..76576432f --- /dev/null +++ b/examples/demo10/MEC/match_for_target_app_instance.go @@ -0,0 +1,33 @@ +package mec + +import ( + model "estimed_demo/Model" + "fmt" + "regexp" +) + +// Match for target App Instance ID +func MatchForTargetAppInstance(allAppInstances []model.AppInstanceID, cse_name string) ([]model.AppInstanceID, error) { + // Compile regex for cse_name once + reCSE, err := regexp.Compile(cse_name) + if err != nil { + return nil, fmt.Errorf("invalid regex for cse_name: %v", err) + } + var matchingAppInstances []model.AppInstanceID + for _, appInstance := range allAppInstances { + // If name matches cse_name using compiled regex, store it in our array + if reCSE.MatchString(appInstance.Name) { + matchingAppInstance := model.AppInstanceID{ + ID: appInstance.ID, + Name: appInstance.Name, + NodeName: appInstance.NodeName, + } + matchingAppInstances = append(matchingAppInstances, matchingAppInstance) + } + } + + if len(matchingAppInstances) == 0 { + return nil, fmt.Errorf("MEC App Instance with name %s not found", cse_name) + } + return matchingAppInstances, nil +} diff --git a/examples/demo10/Model/app_instance_id.go b/examples/demo10/Model/app_instance_id.go new file mode 100644 index 000000000..713464f21 --- /dev/null +++ b/examples/demo10/Model/app_instance_id.go @@ -0,0 +1,7 @@ +package model + +type AppInstanceID struct { + ID string `json:"id"` + Name string `json:"name"` + NodeName string `json:"nodeName"` +} \ No newline at end of file diff --git a/examples/demo10/Model/model_adjacent_app_info_notification.go b/examples/demo10/Model/model_adjacent_app_info_notification.go new file mode 100644 index 000000000..2e50f5781 --- /dev/null +++ b/examples/demo10/Model/model_adjacent_app_info_notification.go @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2022 The AdvantEDGE Authors + * + * 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. + * + * AdvantEDGE Application Mobility API + * + * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)

[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)

**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)

**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network

**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below). + * + * API version: 2.2.1 + * Contact: AdvantEDGE@InterDigital.com + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package model + +type AdjacentAppInfoNotification struct { + // Shall be set to \"AdjacentAppInfoNotification\". + NotificationType string `json:"notificationType"` + TimeStamp *TimeStamp `json:"timeStamp,omitempty"` + // 1 to N identifiers to associate the information for specific + AssociateId []AssociateId `json:"associateId,omitempty"` + AdjacentAppInfo []AdjacentAppInfoNotificationAdjacentAppInfo `json:"adjacentAppInfo,omitempty"` + Links *Link `json:"_links"` +} diff --git a/examples/demo10/Model/model_adjacent_app_info_notification_adjacent_app_info.go b/examples/demo10/Model/model_adjacent_app_info_notification_adjacent_app_info.go new file mode 100644 index 000000000..c3e710bdd --- /dev/null +++ b/examples/demo10/Model/model_adjacent_app_info_notification_adjacent_app_info.go @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2022 The AdvantEDGE Authors + * + * 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. + * + * AdvantEDGE Application Mobility API + * + * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)

[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)

**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)

**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network

**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below). + * + * API version: 2.2.1 + * Contact: AdvantEDGE@InterDigital.com + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package model + +type AdjacentAppInfoNotificationAdjacentAppInfo struct { + // Identifier of the adjacent application instance. + AppInstanceId string `json:"appInstanceId"` + // If present, it represents the communication interface(s) information of the application instance. + CommInterface []CommunicationInterface `json:"commInterface"` +} diff --git a/examples/demo10/Model/model_adjacent_app_info_subscription.go b/examples/demo10/Model/model_adjacent_app_info_subscription.go new file mode 100644 index 000000000..9c502c972 --- /dev/null +++ b/examples/demo10/Model/model_adjacent_app_info_subscription.go @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2022 The AdvantEDGE Authors + * + * 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. + * + * AdvantEDGE Application Mobility API + * + * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)

[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)

**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)

**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network

**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below). + * + * API version: 2.2.1 + * Contact: AdvantEDGE@InterDigital.com + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package model + +type AdjacentAppInfoSubscription struct { + Links *AdjacentAppInfoSubscriptionLinks `json:"_links,omitempty"` + // URI selected by the service consumer to receive notifications on the subscribed Application Mobility Service. This shall be included both in the request and in response. + CallbackReference string `json:"callbackReference"` + // Shall be set to TRUE by the service consumer to request a test notification via HTTP on the callbackReference URI, specified in ETSI GS MEC 009, as described in clause 6.12a. + RequestTestNotification bool `json:"requestTestNotification,omitempty"` + WebsockNotifConfig *WebsockNotifConfig `json:"websockNotifConfig,omitempty"` + ExpiryDeadline *TimeStamp `json:"expiryDeadline,omitempty"` + FilterCriteria *AdjacentAppInfoSubscriptionFilterCriteria `json:"filterCriteria"` + SubscriptionType *SubscriptionType `json:"subscriptionType"` +} diff --git a/examples/demo10/Model/model_adjacent_app_info_subscription_filter_criteria.go b/examples/demo10/Model/model_adjacent_app_info_subscription_filter_criteria.go new file mode 100644 index 000000000..63c6ff090 --- /dev/null +++ b/examples/demo10/Model/model_adjacent_app_info_subscription_filter_criteria.go @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2022 The AdvantEDGE Authors + * + * 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. + * + * AdvantEDGE Application Mobility API + * + * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)

[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)

**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)

**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network

**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below). + * + * API version: 2.2.1 + * Contact: AdvantEDGE@InterDigital.com + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package model + +// List of filtering criteria for the subscription. Any filtering criteria from below, which is included in the request, shall also be included in the response. +type AdjacentAppInfoSubscriptionFilterCriteria struct { + AppInstanceId string `json:"appInstanceId,omitempty"` +} diff --git a/examples/demo10/Model/model_adjacent_app_info_subscription_links.go b/examples/demo10/Model/model_adjacent_app_info_subscription_links.go new file mode 100644 index 000000000..6c0a38296 --- /dev/null +++ b/examples/demo10/Model/model_adjacent_app_info_subscription_links.go @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2022 The AdvantEDGE Authors + * + * 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. + * + * AdvantEDGE Application Mobility API + * + * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)

[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)

**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)

**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network

**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below). + * + * API version: 2.2.1 + * Contact: AdvantEDGE@InterDigital.com + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package model + +// Hyperlink related to the resource. This shall be only included in the HTTP responses and in HTTP PUT requests. +type AdjacentAppInfoSubscriptionLinks struct { + Self *LinkType `json:"self"` +} diff --git a/examples/demo10/Model/model_adjacent_app_instance_info.go b/examples/demo10/Model/model_adjacent_app_instance_info.go new file mode 100644 index 000000000..13366bad1 --- /dev/null +++ b/examples/demo10/Model/model_adjacent_app_instance_info.go @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2022 The AdvantEDGE Authors + * + * 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. + * + * AdvantEDGE Application Mobility API + * + * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)

[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)

**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)

**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network

**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below). + * + * API version: 2.2.1 + * Contact: AdvantEDGE@InterDigital.com + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package model + +type AdjacentAppInstanceInfo struct { + // Identifier of the application descriptor. + AppDId string `json:"appDId"` + // It specifies the communication interface of application instance. + AppInstanceCommLink []CommunicationInterface `json:"appInstanceCommLink"` + // Identifier of the application instance. + AppInstanceId string `json:"appInstanceId"` + MecHostInformation *MecHostInformation `json:"mecHostInformation,omitempty"` + // dentifier of the application instance that registers to the AMS, which is instantiated from the application descriptor identified by the attribute \"appDId\". + RegisteredInstanceId string `json:"registeredInstanceId,omitempty"` +} diff --git a/examples/demo10/Model/model_app_mobility_service_level.go b/examples/demo10/Model/model_app_mobility_service_level.go new file mode 100644 index 000000000..12e07a763 --- /dev/null +++ b/examples/demo10/Model/model_app_mobility_service_level.go @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2022 The AdvantEDGE Authors + * + * 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. + * + * AdvantEDGE Application Mobility API + * + * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)

[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)

**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)

**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network

**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below). + * + * API version: 2.2.1 + * Contact: AdvantEDGE@InterDigital.com + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package model + +// AppMobilityServiceLevel : This attribute provides an option for the application instance (server) to communicate with the application client before relocating this application instance to another MEC host. +type AppMobilityServiceLevel string + +// List of AppMobilityServiceLevel +const ( + NOT_ALLOWED_AppMobilityServiceLevel AppMobilityServiceLevel = "APP_MOBILITY_NOT_ALLOWED" + WITH_CONFIRMATION_AppMobilityServiceLevel AppMobilityServiceLevel = "APP_MOBILITY_WITH_CONFIRMATION" + WITHOUT_CONFIRMATION_AppMobilityServiceLevel AppMobilityServiceLevel = "APP_MOBILITY_WITHOUT_CONFIRMATION" +) diff --git a/examples/demo10/Model/model_app_termination_notification.go b/examples/demo10/Model/model_app_termination_notification.go new file mode 100644 index 000000000..c6e436e10 --- /dev/null +++ b/examples/demo10/Model/model_app_termination_notification.go @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2022 The AdvantEDGE Authors + * + * 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. + * + * AdvantEDGE Application Mobility API + * + * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)

[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)

**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)

**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network

**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below). + * + * API version: 2.2.1 + * Contact: AdvantEDGE@InterDigital.com + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package model + +// This type represents the information that the MEC platform notifies the subscribed application instance about the corresponding application instance termination/stop. +type AppTerminationNotification struct { + // Shall be set to AppTerminationNotification. + NotificationType string `json:"notificationType"` + OperationAction *OperationActionType `json:"operationAction"` + // Maximum timeout value in seconds for graceful termination or graceful stop of an application instance. + MaxGracefulTimeout int32 `json:"maxGracefulTimeout"` + Links *AppTerminationNotificationLinks `json:"_links"` +} diff --git a/examples/demo10/Model/model_app_termination_notification__links.go b/examples/demo10/Model/model_app_termination_notification__links.go new file mode 100644 index 000000000..74d1af76f --- /dev/null +++ b/examples/demo10/Model/model_app_termination_notification__links.go @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2022 The AdvantEDGE Authors + * + * 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. + * + * AdvantEDGE Application Mobility API + * + * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)

[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)

**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)

**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network

**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below). + * + * API version: 2.2.1 + * Contact: AdvantEDGE@InterDigital.com + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package model + +type AppTerminationNotificationLinks struct { + Subscription *LinkType `json:"subscription"` + ConfirmTermination *LinkType `json:"confirmTermination,omitempty"` +} diff --git a/examples/demo10/Model/model_associate_id.go b/examples/demo10/Model/model_associate_id.go new file mode 100644 index 000000000..cfa501c94 --- /dev/null +++ b/examples/demo10/Model/model_associate_id.go @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2022 The AdvantEDGE Authors + * + * 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. + * + * AdvantEDGE Application Mobility API + * + * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)

[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)

**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)

**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network

**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below). + * + * API version: 2.2.1 + * Contact: AdvantEDGE@InterDigital.com + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package model + +type AssociateId struct { + Type_ *AssociateIdType `json:"type,omitempty"` + // Value for the identifier. + Value string `json:"value,omitempty"` +} diff --git a/examples/demo10/Model/model_associate_id_type.go b/examples/demo10/Model/model_associate_id_type.go new file mode 100644 index 000000000..82d58b758 --- /dev/null +++ b/examples/demo10/Model/model_associate_id_type.go @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2022 The AdvantEDGE Authors + * + * 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. + * + * AdvantEDGE Application Mobility API + * + * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)

[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)

**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)

**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network

**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below). + * + * API version: 2.2.1 + * Contact: AdvantEDGE@InterDigital.com + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package model + +// AssociateIdType : Numeric value (0-255) corresponding to specified type of identifier +type AssociateIdType string + +// List of AssociateIdType +const ( + UE_I_PV4_ADDRESS_AssociateIdType AssociateIdType = "UE_IPv4_ADDRESS" + UE_IPV6_ADDRESS_AssociateIdType AssociateIdType = "UE_IPV6_ADDRESS" + NATED_IP_ADDRESS_AssociateIdType AssociateIdType = "NATED_IP_ADDRESS" + GTP_TEID_AssociateIdType AssociateIdType = "GTP_TEID" +) diff --git a/examples/demo10/Model/model_communication_interface.go b/examples/demo10/Model/model_communication_interface.go new file mode 100644 index 000000000..524da89f6 --- /dev/null +++ b/examples/demo10/Model/model_communication_interface.go @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2022 The AdvantEDGE Authors + * + * 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. + * + * AdvantEDGE Application Mobility API + * + * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)

[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)

**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)

**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network

**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below). + * + * API version: 2.2.1 + * Contact: AdvantEDGE@InterDigital.com + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package model + +type CommunicationInterface struct { + IpAddresses []CommunicationInterfaceIpAddresses `json:"ipAddresses,omitempty"` +} diff --git a/examples/demo10/Model/model_communication_interface_ip_addresses.go b/examples/demo10/Model/model_communication_interface_ip_addresses.go new file mode 100644 index 000000000..cdde1a179 --- /dev/null +++ b/examples/demo10/Model/model_communication_interface_ip_addresses.go @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2022 The AdvantEDGE Authors + * + * 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. + * + * AdvantEDGE Application Mobility API + * + * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)

[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)

**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)

**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network

**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below). + * + * API version: 2.2.1 + * Contact: AdvantEDGE@InterDigital.com + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package model + +type CommunicationInterfaceIpAddresses struct { + Host string `json:"host"` + Port int32 `json:"port"` +} diff --git a/examples/demo10/Model/model_context_transfer_state.go b/examples/demo10/Model/model_context_transfer_state.go new file mode 100644 index 000000000..8f0b7ccad --- /dev/null +++ b/examples/demo10/Model/model_context_transfer_state.go @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2022 The AdvantEDGE Authors + * + * 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. + * + * AdvantEDGE Application Mobility API + * + * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)

[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)

**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)

**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network

**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below). + * + * API version: 2.2.1 + * Contact: AdvantEDGE@InterDigital.com + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package model + +// ContextTransferState : If present, it represents the state of transferring the user context to another application instance. +type ContextTransferState string + +// List of ContextTransferState +const ( + NOT_TRANSFERRED_ContextTransferState ContextTransferState = "NOT_TRANSFERRED" + USER_CONTEXT_TRANSFER_COMPLETED_ContextTransferState ContextTransferState = "USER_CONTEXT_TRANSFER_COMPLETED" +) diff --git a/examples/demo10/Model/model_expiry_notification.go b/examples/demo10/Model/model_expiry_notification.go new file mode 100644 index 000000000..99d86842e --- /dev/null +++ b/examples/demo10/Model/model_expiry_notification.go @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2022 The AdvantEDGE Authors + * + * 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. + * + * AdvantEDGE Application Mobility API + * + * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)

[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)

**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)

**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network

**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below). + * + * API version: 2.2.1 + * Contact: AdvantEDGE@InterDigital.com + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package model + +type ExpiryNotification struct { + // Shall be set to \"ExpiryNotification\". + NotificationType string `json:"notificationType"` + TimeStamp *TimeStamp `json:"timeStamp,omitempty"` + Links *Link `json:"_links"` + ExpiryDeadline *TimeStamp `json:"expiryDeadline"` +} diff --git a/examples/demo10/Model/model_inline_notification.go b/examples/demo10/Model/model_inline_notification.go new file mode 100644 index 000000000..8c5b31de0 --- /dev/null +++ b/examples/demo10/Model/model_inline_notification.go @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2022 The AdvantEDGE Authors + * + * 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. + * + * AdvantEDGE Application Mobility API + * + * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)

[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)

**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)

**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network

**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below). + * + * API version: 2.2.1 + * Contact: AdvantEDGE@InterDigital.com + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package model + +type InlineNotification struct { + // Not used in client +} diff --git a/examples/demo10/Model/model_inline_subscription.go b/examples/demo10/Model/model_inline_subscription.go new file mode 100644 index 000000000..12296a6f0 --- /dev/null +++ b/examples/demo10/Model/model_inline_subscription.go @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2022 The AdvantEDGE Authors + * + * 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. + * + * AdvantEDGE Application Mobility API + * + * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)

[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)

**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)

**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network

**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below). + * + * API version: 2.2.1 + * Contact: AdvantEDGE@InterDigital.com + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package model + +type InlineSubscription struct { + /* Discriminator */ + SubscriptionType string `json:"subscriptionType"` + + /* Common */ + Links *MobilityProcedureSubscriptionLinks `json:"_links,omitempty"` + CallbackReference string `json:"callbackReference"` + RequestTestNotification bool `json:"requestTestNotification,omitempty"` + WebsockNotifConfig *WebsockNotifConfig `json:"websockNotifConfig,omitempty"` + ExpiryDeadline *TimeStamp `json:"expiryDeadline,omitempty"` + + /* MobilityProcedureSubscription */ + FilterCriteria *MobilityProcedureSubscriptionFilterCriteria `json:"filterCriteria"` + + /* AdjacentAppInfoSubscription */ + // NOTE: to avoid json parameter conflict, use superset filterCriteria from MobilityProcedure + // FilterCriteria *AdjacentAppInfoSubscriptionFilterCriteria `json:"filterCriteria"` +} diff --git a/examples/demo10/Model/model_link.go b/examples/demo10/Model/model_link.go new file mode 100644 index 000000000..656146a5c --- /dev/null +++ b/examples/demo10/Model/model_link.go @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2022 The AdvantEDGE Authors + * + * 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. + * + * AdvantEDGE Application Mobility API + * + * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)

[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)

**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)

**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network

**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below). + * + * API version: 2.2.1 + * Contact: AdvantEDGE@InterDigital.com + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package model + +// Object containing hyperlinks related to the resource. +type Link struct { + Subscription *LinkType `json:"subscription"` +} diff --git a/examples/demo10/Model/model_link_type.go b/examples/demo10/Model/model_link_type.go new file mode 100644 index 000000000..d9471e227 --- /dev/null +++ b/examples/demo10/Model/model_link_type.go @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2022 The AdvantEDGE Authors + * + * 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. + * + * AdvantEDGE Application Mobility API + * + * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)

[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)

**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)

**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network

**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below). + * + * API version: 2.2.1 + * Contact: AdvantEDGE@InterDigital.com + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package model + +// 'This data type represents a type of link' +type LinkType struct { + // The URI referring to the subscription. + Href string `json:"href"` +} diff --git a/examples/demo10/Model/model_mec_host_information.go b/examples/demo10/Model/model_mec_host_information.go new file mode 100644 index 000000000..b36a4c435 --- /dev/null +++ b/examples/demo10/Model/model_mec_host_information.go @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2022 The AdvantEDGE Authors + * + * 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. + * + * AdvantEDGE Application Mobility API + * + * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)

[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)

**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)

**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network

**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below). + * + * API version: 2.2.1 + * Contact: AdvantEDGE@InterDigital.com + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package model + +type MecHostInformation struct { + // Human-readable name of MEC host. + HostName string `json:"hostName,omitempty"` + HostId *map[string]interface{} `json:"hostId"` +} diff --git a/examples/demo10/Model/model_mobility_procedure_notification.go b/examples/demo10/Model/model_mobility_procedure_notification.go new file mode 100644 index 000000000..c2c4a2471 --- /dev/null +++ b/examples/demo10/Model/model_mobility_procedure_notification.go @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2022 The AdvantEDGE Authors + * + * 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. + * + * AdvantEDGE Application Mobility API + * + * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)

[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)

**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)

**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network

**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below). + * + * API version: 2.2.1 + * Contact: AdvantEDGE@InterDigital.com + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package model + +type MobilityProcedureNotification struct { + // Shall be set to \"MobilityProcedureNotification\". + NotificationType string `json:"notificationType"` + TimeStamp *TimeStamp `json:"timeStamp,omitempty"` + // 1 to N identifiers to associate the information for specific + AssociateId []AssociateId `json:"associateId"` + MobilityStatus *MobilityStatus `json:"mobilityStatus"` + TargetAppInfo *MobilityProcedureNotificationTargetAppInfo `json:"targetAppInfo,omitempty"` + Links *Link `json:"_links"` +} diff --git a/examples/demo10/Model/model_mobility_procedure_notification_target_app_info.go b/examples/demo10/Model/model_mobility_procedure_notification_target_app_info.go new file mode 100644 index 000000000..6630bfe1c --- /dev/null +++ b/examples/demo10/Model/model_mobility_procedure_notification_target_app_info.go @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2022 The AdvantEDGE Authors + * + * 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. + * + * AdvantEDGE Application Mobility API + * + * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)

[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)

**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)

**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network

**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below). + * + * API version: 2.2.1 + * Contact: AdvantEDGE@InterDigital.com + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package model + +type MobilityProcedureNotificationTargetAppInfo struct { + // Identifiers of the target application instance. + AppInstanceId string `json:"appInstanceId"` + CommInterface *CommunicationInterface `json:"commInterface,omitempty"` +} diff --git a/examples/demo10/Model/model_mobility_procedure_subscription.go b/examples/demo10/Model/model_mobility_procedure_subscription.go new file mode 100644 index 000000000..c36b0b3a6 --- /dev/null +++ b/examples/demo10/Model/model_mobility_procedure_subscription.go @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2022 The AdvantEDGE Authors + * + * 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. + * + * AdvantEDGE Application Mobility API + * + * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)

[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)

**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)

**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network

**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below). + * + * API version: 2.2.1 + * Contact: AdvantEDGE@InterDigital.com + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package model + +type MobilityProcedureSubscription struct { + Links *MobilityProcedureSubscriptionLinks `json:"_links,omitempty"` + // URI selected by the service consumer to receive notifications on the subscribed Application Mobility Service. This shall be included both in the request and in response. + CallbackReference string `json:"callbackReference,omitempty"` + // Shall be set to TRUE by the service consumer to request a test notification via HTTP on the callbackReference URI, specified in ETSI GS MEC 009, as described in clause 6.12a. + RequestTestNotification bool `json:"requestTestNotification,omitempty"` + WebsockNotifConfig *WebsockNotifConfig `json:"websockNotifConfig,omitempty"` + ExpiryDeadline *TimeStamp `json:"expiryDeadline,omitempty"` + FilterCriteria *MobilityProcedureSubscriptionFilterCriteria `json:"filterCriteria"` + SubscriptionType *SubscriptionType `json:"subscriptionType"` +} diff --git a/examples/demo10/Model/model_mobility_procedure_subscription_filter_criteria.go b/examples/demo10/Model/model_mobility_procedure_subscription_filter_criteria.go new file mode 100644 index 000000000..16e7ce163 --- /dev/null +++ b/examples/demo10/Model/model_mobility_procedure_subscription_filter_criteria.go @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2022 The AdvantEDGE Authors + * + * 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. + * + * AdvantEDGE Application Mobility API + * + * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)

[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)

**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)

**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network

**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below). + * + * API version: 2.2.1 + * Contact: AdvantEDGE@InterDigital.com + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package model + +// List of filtering criteria for the subscription. Any filtering criteria from below, which is included in the request, shall also be included in the response. +type MobilityProcedureSubscriptionFilterCriteria struct { + // Identifier of the application instance that registers the Application Mobility Service. + AppInstanceId string `json:"appInstanceId,omitempty"` + // 0 to N identifiers to associate the information for specific UE(s) and flow(s). + AssociateId []AssociateId `json:"associateId,omitempty"` + // In case mobilityStatus is not included in the subscription request, the default value 1 = INTER_HOST_MOBILITY_TRIGGERED shall be used and included in the response. + MobilityStatus []MobilityStatus `json:"mobilityStatus,omitempty"` +} diff --git a/examples/demo10/Model/model_mobility_procedure_subscription_links.go b/examples/demo10/Model/model_mobility_procedure_subscription_links.go new file mode 100644 index 000000000..937f5450c --- /dev/null +++ b/examples/demo10/Model/model_mobility_procedure_subscription_links.go @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2022 The AdvantEDGE Authors + * + * 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. + * + * AdvantEDGE Application Mobility API + * + * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)

[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)

**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)

**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network

**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below). + * + * API version: 2.2.1 + * Contact: AdvantEDGE@InterDigital.com + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package model + +type MobilityProcedureSubscriptionLinks struct { + Self *LinkType `json:"self"` +} diff --git a/examples/demo10/Model/model_mobility_status.go b/examples/demo10/Model/model_mobility_status.go new file mode 100644 index 000000000..a8b628691 --- /dev/null +++ b/examples/demo10/Model/model_mobility_status.go @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2022 The AdvantEDGE Authors + * + * 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. + * + * AdvantEDGE Application Mobility API + * + * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)

[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)

**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)

**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network

**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below). + * + * API version: 2.2.1 + * Contact: AdvantEDGE@InterDigital.com + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package model + +// MobilityStatus : Indicate the status of the UE mobility +type MobilityStatus string + +// List of MobilityStatus +const ( + TRIGGERED_MobilityStatus MobilityStatus = "INTERHOST_MOVEOUT_TRIGGERED" + COMPLETED_MobilityStatus MobilityStatus = "INTERHOST_MOVEOUT_COMPLETED" + FAILED_MobilityStatus MobilityStatus = "INTERHOST_MOVEOUT_FAILED" +) diff --git a/examples/demo10/Model/model_one_of_inline_notification.go b/examples/demo10/Model/model_one_of_inline_notification.go new file mode 100644 index 000000000..49ae7e4f9 --- /dev/null +++ b/examples/demo10/Model/model_one_of_inline_notification.go @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2022 The AdvantEDGE Authors + * + * 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. + * + * AdvantEDGE Application Mobility API + * + * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)

[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)

**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)

**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network

**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below). + * + * API version: 2.2.1 + * Contact: AdvantEDGE@InterDigital.com + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package model + +type OneOfInlineNotification struct { + /* Discriminator */ + NotificationType string `json:"notificationType"` +} diff --git a/examples/demo10/Model/model_one_of_inline_subscription.go b/examples/demo10/Model/model_one_of_inline_subscription.go new file mode 100644 index 000000000..2c68e86a9 --- /dev/null +++ b/examples/demo10/Model/model_one_of_inline_subscription.go @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2022 The AdvantEDGE Authors + * + * 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. + * + * AdvantEDGE Application Mobility API + * + * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)

[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)

**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)

**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network

**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below). + * + * API version: 2.2.1 + * Contact: AdvantEDGE@InterDigital.com + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package model + +type OneOfInlineSubscription struct { + /* Discriminator */ + SubscriptionType string `json:"subscriptionType"` +} diff --git a/examples/demo10/Model/model_operation_action_type.go b/examples/demo10/Model/model_operation_action_type.go new file mode 100644 index 000000000..d934d5fc4 --- /dev/null +++ b/examples/demo10/Model/model_operation_action_type.go @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2022 The AdvantEDGE Authors + * + * 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. + * + * AdvantEDGE Application Mobility API + * + * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)

[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)

**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)

**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network

**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below). + * + * API version: 2.2.1 + * Contact: AdvantEDGE@InterDigital.com + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package model + +// OperationActionType : Operation that is being performed on the MEC application instance. +type OperationActionType string + +// List of OperationActionType +const ( + STOPPING_OperationActionType OperationActionType = "STOPPING" + TERMINATING_OperationActionType OperationActionType = "TERMINATING" +) diff --git a/examples/demo10/Model/model_problem_details.go b/examples/demo10/Model/model_problem_details.go new file mode 100644 index 000000000..7d5596870 --- /dev/null +++ b/examples/demo10/Model/model_problem_details.go @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2022 The AdvantEDGE Authors + * + * 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. + * + * AdvantEDGE Application Mobility API + * + * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)

[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)

**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)

**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network

**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below). + * + * API version: 2.2.1 + * Contact: AdvantEDGE@InterDigital.com + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package model + +type ProblemDetails struct { + // A human-readable explanation specific to this occurrence of the problem + Detail string `json:"detail,omitempty"` + // A URI reference that identifies the specific occurrence of the problem + Instance string `json:"instance,omitempty"` + // The HTTP status code for this occurrence of the problem + Status int32 `json:"status,omitempty"` + // A short, human-readable summary of the problem type + Title string `json:"title,omitempty"` + // A URI reference according to IETF RFC 3986 that identifies the problem type + Type_ string `json:"type,omitempty"` +} diff --git a/examples/demo10/Model/model_registration_info.go b/examples/demo10/Model/model_registration_info.go new file mode 100644 index 000000000..ad45f4a52 --- /dev/null +++ b/examples/demo10/Model/model_registration_info.go @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2022 The AdvantEDGE Authors + * + * 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. + * + * AdvantEDGE Application Mobility API + * + * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)

[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)

**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)

**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network

**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below). + * + * API version: 2.2.1 + * Contact: AdvantEDGE@InterDigital.com + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package model + +type RegistrationInfo struct { + // The identifier of registered application mobility service. Shall be absent in POST requests, and present otherwise. + AppMobilityServiceId string `json:"appMobilityServiceId,omitempty"` + // If present, it specifies the device served by the application instance which is registering is registering the Application Mobility Service. + DeviceInformation []RegistrationInfoDeviceInformation `json:"deviceInformation,omitempty"` + // If present, it indicates the time of Application Mobility Service expiration from the time of registration accepted.The value \"0\" means infinite time, i.e. no expiration.The unit of expiry time is one second. + ExpiryTime int32 `json:"expiryTime,omitempty"` + ServiceConsumerId *RegistrationInfoServiceConsumerId `json:"serviceConsumerId"` +} diff --git a/examples/demo10/Model/model_registration_info_device_information.go b/examples/demo10/Model/model_registration_info_device_information.go new file mode 100644 index 000000000..9e3885bce --- /dev/null +++ b/examples/demo10/Model/model_registration_info_device_information.go @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2022 The AdvantEDGE Authors + * + * 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. + * + * AdvantEDGE Application Mobility API + * + * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)

[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)

**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)

**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network

**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below). + * + * API version: 2.2.1 + * Contact: AdvantEDGE@InterDigital.com + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package model + +type RegistrationInfoDeviceInformation struct { + AssociateId *AssociateId `json:"associateId"` + AppMobilityServiceLevel *AppMobilityServiceLevel `json:"appMobilityServiceLevel,omitempty"` + ContextTransferState *ContextTransferState `json:"contextTransferState,omitempty"` +} diff --git a/examples/demo10/Model/model_registration_info_service_consumer_id.go b/examples/demo10/Model/model_registration_info_service_consumer_id.go new file mode 100644 index 000000000..41437ba61 --- /dev/null +++ b/examples/demo10/Model/model_registration_info_service_consumer_id.go @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2022 The AdvantEDGE Authors + * + * 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. + * + * AdvantEDGE Application Mobility API + * + * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)

[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)

**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)

**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network

**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below). + * + * API version: 2.2.1 + * Contact: AdvantEDGE@InterDigital.com + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package model + +// The identifier of service consumer requesting the application mobility service, i.e. either the application instance ID or the MEC platform ID. +type RegistrationInfoServiceConsumerId struct { + // If present, it represents the identifier of the application instance registering the Application Mobility Service. + AppInstanceId string `json:"appInstanceId,omitempty"` + // If present, it represents the identifier of the MEC platform registering the Application Mobility Service. + MepId string `json:"mepId,omitempty"` +} diff --git a/examples/demo10/Model/model_subscription_link_list.go b/examples/demo10/Model/model_subscription_link_list.go new file mode 100644 index 000000000..ae7493d37 --- /dev/null +++ b/examples/demo10/Model/model_subscription_link_list.go @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2022 The AdvantEDGE Authors + * + * 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. + * + * AdvantEDGE Application Mobility API + * + * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)

[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)

**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)

**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network

**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below). + * + * API version: 2.2.1 + * Contact: AdvantEDGE@InterDigital.com + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package model + +type SubscriptionLinkList struct { + Links *SubscriptionLinkListLinks `json:"_links"` +} diff --git a/examples/demo10/Model/model_subscription_link_list_links.go b/examples/demo10/Model/model_subscription_link_list_links.go new file mode 100644 index 000000000..76b7813e2 --- /dev/null +++ b/examples/demo10/Model/model_subscription_link_list_links.go @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2022 The AdvantEDGE Authors + * + * 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. + * + * AdvantEDGE Application Mobility API + * + * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)

[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)

**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)

**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network

**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below). + * + * API version: 2.2.1 + * Contact: AdvantEDGE@InterDigital.com + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package model + +// List of hyperlinks related to the resource. +type SubscriptionLinkListLinks struct { + Self *LinkType `json:"self"` + // The service consumer’s subscriptions. + Subscription []SubscriptionLinkListSubscription `json:"subscription,omitempty"` +} diff --git a/examples/demo10/Model/model_subscription_link_list_subscription.go b/examples/demo10/Model/model_subscription_link_list_subscription.go new file mode 100644 index 000000000..e23d56e8e --- /dev/null +++ b/examples/demo10/Model/model_subscription_link_list_subscription.go @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2022 The AdvantEDGE Authors + * + * 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. + * + * AdvantEDGE Application Mobility API + * + * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)

[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)

**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)

**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network

**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below). + * + * API version: 2.2.1 + * Contact: AdvantEDGE@InterDigital.com + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package model + +type SubscriptionLinkListSubscription struct { + // The URI referring to the subscription. + Href string `json:"href"` + SubscriptionType *SubscriptionType `json:"subscriptionType"` +} diff --git a/examples/demo10/Model/model_subscription_type.go b/examples/demo10/Model/model_subscription_type.go new file mode 100644 index 000000000..ca4da6f8c --- /dev/null +++ b/examples/demo10/Model/model_subscription_type.go @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2022 The AdvantEDGE Authors + * + * 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. + * + * AdvantEDGE Application Mobility API + * + * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)

[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)

**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)

**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network

**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below). + * + * API version: 2.2.1 + * Contact: AdvantEDGE@InterDigital.com + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package model + +type SubscriptionType string + +// List of SubscriptionType +const ( + MOBILITY_PROCEDURE_SUBSCRIPTION_SubscriptionType SubscriptionType = "MobilityProcedureSubscription" + ADJACENT_APP_INFO_SUBSCRIPTION_SubscriptionType SubscriptionType = "AdjacentAppInfoSubscription" +) diff --git a/examples/demo10/Model/model_test_notification.go b/examples/demo10/Model/model_test_notification.go new file mode 100644 index 000000000..c2cafc46d --- /dev/null +++ b/examples/demo10/Model/model_test_notification.go @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2022 The AdvantEDGE Authors + * + * 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. + * + * AdvantEDGE Application Mobility API + * + * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)

[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)

**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)

**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network

**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below). + * + * API version: 2.2.1 + * Contact: AdvantEDGE@InterDigital.com + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package model + +type TestNotification struct { + // Shall be set to \"TestNotification\". + NotificationType string `json:"notificationType"` + Links *TestNotificationLinks `json:"_links"` +} diff --git a/examples/demo10/Model/model_test_notification__links.go b/examples/demo10/Model/model_test_notification__links.go new file mode 100644 index 000000000..e77f868bb --- /dev/null +++ b/examples/demo10/Model/model_test_notification__links.go @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2022 The AdvantEDGE Authors + * + * 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. + * + * AdvantEDGE Application Mobility API + * + * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)

[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)

**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)

**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network

**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below). + * + * API version: 2.2.1 + * Contact: AdvantEDGE@InterDigital.com + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package model + +// Hyperlink related to the resource. +type TestNotificationLinks struct { + Subscription *LinkType `json:"subscription"` +} diff --git a/examples/demo10/Model/model_time_stamp.go b/examples/demo10/Model/model_time_stamp.go new file mode 100644 index 000000000..84e953c5c --- /dev/null +++ b/examples/demo10/Model/model_time_stamp.go @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2022 The AdvantEDGE Authors + * + * 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. + * + * AdvantEDGE Application Mobility API + * + * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)

[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)

**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)

**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network

**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below). + * + * API version: 2.2.1 + * Contact: AdvantEDGE@InterDigital.com + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package model + +// 'This data type represents the time stamp as Unix-time since January 1, 1970, 00:00:00 UTC' +type TimeStamp struct { + // 'The seconds part of the Time. Time is defined as Unix-time since January 1, 1970, 00:00:00 UTC.' + Seconds int32 `json:"seconds"` + // 'The nanoseconds part of the Time. Time is defined as Unix-time since January 1, 1970, 00:00:00 UTC.' + NanoSeconds int32 `json:"nanoSeconds"` +} diff --git a/examples/demo10/Model/model_websock_notif_config.go b/examples/demo10/Model/model_websock_notif_config.go new file mode 100644 index 000000000..8776daae6 --- /dev/null +++ b/examples/demo10/Model/model_websock_notif_config.go @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2022 The AdvantEDGE Authors + * + * 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. + * + * AdvantEDGE Application Mobility API + * + * Application Mobility Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC021 Application Mobility API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/021/02.02.01_60/gs_MEC021v020201p.pdf)

[Copyright (c) ETSI 2017](https://forge.etsi.org/etsi-forge-copyright-notice.txt)

**Micro-service**
[meep-ams](https://github.com/InterDigitalInc/AdvantEDGE/tree/master/go-apps/meep-ams)

**Type & Usage**
Edge Service used by edge applications that want to get information about application mobility in the network

**Note**
AdvantEDGE supports a selected subset of Application Mobility API endpoints (see below). + * + * API version: 2.2.1 + * Contact: AdvantEDGE@InterDigital.com + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package model + +type WebsockNotifConfig struct { + // Set by AMS to indicate to the service consumer the Websocket URI to be used for delivering notifications. + WebsocketUri string `json:"websocketUri,omitempty"` + // Set to true by the service consumer to indicate that Websocket delivery is requested. + RequestWebsocketUri bool `json:"requestWebsocketUri,omitempty"` +} diff --git a/examples/demo10/Model/platform_info.go b/examples/demo10/Model/platform_info.go new file mode 100644 index 000000000..e35d52a2b --- /dev/null +++ b/examples/demo10/Model/platform_info.go @@ -0,0 +1,8 @@ +package model + +type PlatformInfo struct { + AmsServiceID string `json:"ams_service_id,omitempty"` + AppInstanceID string `json:"app_instance_id,omitempty"` + AmsSubscriptionID string `json:"ams_subscription_id,omitempty"` + NodeName string `json:"node_name,omitempty"` +} diff --git a/examples/demo10/go.mod b/examples/demo10/go.mod new file mode 100644 index 000000000..9196c4824 --- /dev/null +++ b/examples/demo10/go.mod @@ -0,0 +1,7 @@ +module estimed_demo + +go 1.17 + +require ( + github.com/google/uuid v1.6.0 // indirect +) diff --git a/examples/demo10/go.sum b/examples/demo10/go.sum new file mode 100644 index 000000000..40e65d629 --- /dev/null +++ b/examples/demo10/go.sum @@ -0,0 +1,2 @@ +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= \ No newline at end of file diff --git a/examples/demo10/main.go b/examples/demo10/main.go new file mode 100644 index 000000000..8e4a870a3 --- /dev/null +++ b/examples/demo10/main.go @@ -0,0 +1,268 @@ +package main + +import ( + mec "estimed_demo/MEC" + model "estimed_demo/Model" + onem2m "estimed_demo/oneM2M" + "fmt" + "log" + "math/rand" + "net/http" + "os" + "os/signal" + "syscall" + "time" +) + +// MN-CSE platform details +var platformURL = "" +var sandboxURL = "mec-platform2.etsi.org" // Site that hosts MEC Sandbox + + +var cse_id = "" // CSE Structured ID +var cse_name = "mep-cse-mn" // CSE Name (for some API calls) +var AE_ID = "CSmartCar" // Application Entity ID +var App_Name = "SmartCar" // Application Resource Name +var App_Id = "N-Smart_Car_Application" +var appVersion = "1.0.0" +var containerName = "SmartCarContainer" +var remote_cse_id = "/laboai-id-in" + +// MEC platform details +var sandbox_name = "sbxt8mvfg1" // Namespace allocated to the user upon login +var DeviceId = "10.100.0.1" // This is the IP of UE moving on map in Sandbox +var ams_pltf = "mep1" + +// Endpoints for recieving notifications from MEC platform +var server_port = "{Server_Port}" // Port to listen on for notifications +var ams_notification_endpoint = "/ams/notify" +var server_ip = "{Server_IP}" // IP address to listen on for notifications + +var notificationChan = make(chan string, 10) +var currentAppInstanceId = "" +var platformDetails = []map[string]model.PlatformInfo{} +var associateId = &model.AssociateId{ + Type_: &[]model.AssociateIdType{"UE_IPv4_ADDRESS"}[0], + Value: DeviceId, +} +var deviceInfo = &model.RegistrationInfoDeviceInformation{ + AssociateId: associateId, + AppMobilityServiceLevel: &[]model.AppMobilityServiceLevel{"APP_MOBILITY_WITHOUT_CONFIRMATION"}[0], + ContextTransferState: &[]model.ContextTransferState{"NOT_TRANSFERRED"}[0], +} + +// initApp initializes the application and connects to the oneM2M platform +func initApp() error { + // Start HTTP server to listen for sensor connections + log.Println("Starting HTTP server on port 9876 to listen for sensor connections...") + server := &http.Server{Addr: fmt.Sprintf("%s:%s", server_ip, server_port)} + // Set up HTTP routes + http.HandleFunc(ams_notification_endpoint, func(w http.ResponseWriter, r *http.Request) { + id, err := mec.AMSNotificationHandler(w, r) + if err != nil { + log.Printf("Error handling AMS notification: %v", err) + } else if id != "" { + notificationChan <- id + } + }) + + // Start server in a goroutine so it doesn't block + go func() { + log.Println("Server goroutine starting...") + if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed { + log.Printf("Server error: %v", err) + log.Printf("ERROR: Could not start server: %v", err) + } + }() + + // Give the server a moment to start and check if it's running + time.Sleep(1 * time.Second) + + // log.Println("✓ HTTP server started and listening on 0.0.0.0:9876") + + log.Printf("Initializing %s (version %s)", App_Id, appVersion) + log.Println("Obtaining MEC App Instance ID of mn-cse") + + // Fetch MEC App Instance ID to find the correct App Instance for mn-cse + // Construct MEC App Instance URL + url := fmt.Sprintf("%s/%s/sandbox-ctrl/v1/applications", sandboxURL, sandbox_name) + + // Get all MEC App Instance ID + allAppInstances, err := mec.GetAppInstances(url) + if err != nil { + return fmt.Errorf("failed to get MEC App Instance IDs: %v", err) + } + log.Printf("Total MEC App Instances retrieved: %d", len(allAppInstances)) + log.Printf("MEC App Instances: %+v", allAppInstances) + + // Array to store matching app instances + matchingAppInstances, err := mec.MatchForTargetAppInstance(allAppInstances, cse_name) + if err != nil { + return fmt.Errorf("failed to match MEC App Instances: %v", err) + } + + // Create AMS registration and subscription for each matching App Instance + callbackURL := fmt.Sprintf("http://%s:%s%s", server_ip, server_port, ams_notification_endpoint) + platformDetails, err = mec.RegistrationAndSubscriptionHandler(matchingAppInstances, sandboxURL, + sandbox_name, callbackURL, ¤tAppInstanceId, deviceInfo, associateId) + if err != nil { + return fmt.Errorf("failed to create AMS registration and subscription: %v", err) + } + + // Request IoT API for IoT platform urls + log.Println("Fetching IoT platform information from MEC...") + + // Current App Instance ID must be set from previous step + var current_pltf_details model.PlatformInfo + for _, pltf := range platformDetails { + if platformInfo, exists := pltf[currentAppInstanceId]; exists { + current_pltf_details = platformInfo + break + } + } + log.Printf("Current platform details: %v", current_pltf_details) + + iot_url := fmt.Sprintf("%s/%s/%s/iots/v1/registered_iot_platforms", sandboxURL, sandbox_name, current_pltf_details.NodeName) + iot_platforms, err := mec.GETIotPlatformInfo(iot_url) + if err != nil { + return fmt.Errorf("failed to get IoT platform info: %v", err) + } + + platformURL = iot_platforms[0]["customServicesTransportInfo"].([]interface{})[0].(map[string]interface{})["endpoint"].(map[string]interface{})["uris"].([]interface{})[0].(string) + log.Printf("IoT platform URL: %s", platformURL) + cse_id = iot_platforms[0]["customServicesTransportInfo"].([]interface{})[0].(map[string]interface{})["id"].(string) + log.Printf("CSE ID: %s", cse_id) + cse_name = iot_platforms[0]["customServicesTransportInfo"].([]interface{})[0].(map[string]interface{})["name"].(string) + log.Printf("CSE Name: %s", cse_name) + + // Initialize oneM2M application + err = onem2m.InitOneM2MApp(platformURL, cse_name, cse_id, App_Name, App_Id, AE_ID, containerName, remote_cse_id) + if err != nil { + return fmt.Errorf("failed to initialize oneM2M application: %v", err) + } + // Create subscription for notification server + // err = onem2m.CreateSubscription(platformURL, cse_name, App_Name, containerName) + // if err != nil { + // return fmt.Errorf("failed to create oneM2M subscription: %v", err) + // } + return nil +} + +func main() { + log.SetFlags(log.LstdFlags | log.Lshortfile) + // Handle graceful shutdown on system kill signals + sigs := make(chan os.Signal, 1) + signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM) + go func() { + <-sigs + latestData, err := onem2m.RetrieveLatestData(platformURL, cse_name, App_Name, AE_ID, containerName) + if err != nil { + log.Printf("Failed to retrieve latest data: %v", err) + } else { + log.Printf("Latest data: %s", latestData) + } + if err := onem2m.DeregisterAE(platformURL, cse_name, cse_id, App_Name, AE_ID); err != nil { + log.Printf("Failed to deregister AE: %v", err) + } + log.Println("\nReceived shutdown signal, exiting...") + os.Exit(0) + }() + + // Initialize the application + if err := initApp(); err != nil { + log.Fatalf("Failed to initialize application: %v", err) + os.Exit(1) + } + + // Start goroutine to handle received target app instance IDs + go func() { + for targetAppInstanceID := range notificationChan { + // Get platform details for the received ID + var targetPltfDetails model.PlatformInfo + for _, pltf := range platformDetails { + if platformInfo, exists := pltf[targetAppInstanceID]; exists { + targetPltfDetails = platformInfo + break + } + } + log.Printf("Target platform details: %v", targetPltfDetails) + + // Connect to new IoT platform + iot_url := fmt.Sprintf("%s/%s/%s/iots/v1/registered_iot_platforms", sandboxURL, sandbox_name, targetPltfDetails.NodeName) + iot_platforms, err := mec.GETIotPlatformInfo(iot_url) + if err != nil { + log.Printf("Failed to get IoT platform info for target app instance %s: %v", targetAppInstanceID, err) + continue + } + // Temporarily store old platform URL + old_platformURL := platformURL + old_cse_id := cse_id + old_cse_name := cse_name + + platformURL = iot_platforms[0]["customServicesTransportInfo"].([]interface{})[0].(map[string]interface{})["endpoint"].(map[string]interface{})["uris"].([]interface{})[0].(string) + log.Printf("New IoT platform URL after mobility: %s", platformURL) + + cse_name = iot_platforms[0]["customServicesTransportInfo"].([]interface{})[0].(map[string]interface{})["name"].(string) + cse_id = iot_platforms[0]["customServicesTransportInfo"].([]interface{})[0].(map[string]interface{})["id"].(string) + + // Re-initialize oneM2M application on the new platform + err = onem2m.InitOneM2MApp(platformURL, cse_name, cse_id, App_Name, App_Id, AE_ID, containerName, remote_cse_id) + if err != nil { + log.Printf("Failed to re-initialize oneM2M application after mobility: %v", err) + continue + } else { + log.Printf("Successfully re-initialized oneM2M application on new platform after mobility") + } + + // Disconnect from previous platform + log.Printf("Disconnecting from previous platform: %s", old_platformURL) + if err := onem2m.DeregisterAE(old_platformURL, old_cse_name, old_cse_id, App_Name, AE_ID); err != nil { + log.Printf("Failed to deregister AE from old platform: %v", err) + } else { + log.Printf("Successfully deregistered AE from old platform") + } + + // Update AMS registration to reflect new platform connection + log.Printf("Updating AMS registration to reflect new platform connection...") + + // PUT request to AMS for currentAppInstanceId to switch + ams_url := fmt.Sprintf("%s/%s/%s/amsi/v1/app_mobility_services", sandboxURL, sandbox_name, ams_pltf) + err = mec.PutAMSRegistrationInfo(ams_url, targetAppInstanceID, platformDetails, ¤tAppInstanceId, associateId) + if err != nil { + log.Printf("Failed to update AMS registration info for target app instance %s: %v", targetAppInstanceID, err) + continue + } else { + log.Printf("Successfully updated AMS registration info for target app instance %s", targetAppInstanceID) + } + + // Update AMS subscription to reflect new platform connection + log.Printf("Updating AMS subscription to reflect new platform connection...") + ams_url = fmt.Sprintf("%s/%s/%s/amsi/v1/subscriptions", sandboxURL, sandbox_name, ams_pltf) + err = mec.PUTAMSSubscriptionInfo(ams_url, targetAppInstanceID, platformDetails, ¤tAppInstanceId, + fmt.Sprintf("http://%s:%s%s", server_ip, server_port, ams_notification_endpoint), associateId) + if err != nil { + log.Printf("Failed to update AMS subscription info for target app instance %s: %v", targetAppInstanceID, err) + continue + } else { + log.Printf("Successfully updated AMS subscription info for target app instance %s", targetAppInstanceID) + } + currentAppInstanceId = targetAppInstanceID + } + }() + + // Example: Send telemetry data + speed := []int{60, 62, 58, 65, 68} + temperature := []float64{25.5, 26.0, 24.8, 25.2, 25.9} + fuel := []int{75, 74, 73, 72, 71} + // For only terminates on system kill signal + for { + telemetryData := fmt.Sprintf(`{"temperature": %f, "speed": %d, "fuel": %d}`, + temperature[rand.Intn(len(temperature))], + speed[rand.Intn(len(speed))], + fuel[rand.Intn(len(fuel))]) + if err := onem2m.CreateContentInstance(platformURL, cse_name, App_Name, AE_ID, containerName, remote_cse_id, telemetryData); err != nil { + log.Printf("Failed to send telemetry: %v", err) + } + time.Sleep(5 * time.Second) + } +} diff --git a/examples/demo10/oneM2M/createAE.go b/examples/demo10/oneM2M/createAE.go new file mode 100644 index 000000000..01904b9f8 --- /dev/null +++ b/examples/demo10/oneM2M/createAE.go @@ -0,0 +1,44 @@ +package onem2m +import ( + "estimed_demo/utils" + "fmt" + "io" + "log" + "net/http" +) + +// CreateAE creates an Application Entity on the oneM2M platform +func CreateAE(platformURL, cse_name, cse_id, App_Name, App_Id, AE_ID, remote_cse_id string) error { + log.Println("Creating Application Entity (AE)...") + + reqBody := fmt.Sprintf(`{ + "m2m:ae": { + "rn": "%s", + "api": "%s", + "rr": true, + "lbl": ["Type/SmartCar", "Category/Vehicle"], + "srv": ["5"], + "at": ["%s"] + } + }`, App_Name, App_Id, remote_cse_id) + + url := fmt.Sprintf("%s/~%s/%s", platformURL, cse_id, cse_name) + log.Println("url (Create AE):", url) + resp, err := utils.MakeOneM2MRequest("POST", url, reqBody, 2, AE_ID) + if err != nil { + return err + } + defer resp.Body.Close() + + body, _ := io.ReadAll(resp.Body) + + if resp.StatusCode == http.StatusCreated { + log.Println("✓ Application Entity (AE) created successfully") + return nil + } else if resp.StatusCode == http.StatusConflict || resp.StatusCode == http.StatusForbidden { + log.Println("⚠ AE already exists") + return nil + } + + return fmt.Errorf("failed to create AE: status %d, body: %s", resp.StatusCode, string(body)) +} \ No newline at end of file diff --git a/examples/demo10/oneM2M/createContentInstance.go b/examples/demo10/oneM2M/createContentInstance.go new file mode 100644 index 000000000..b072ad222 --- /dev/null +++ b/examples/demo10/oneM2M/createContentInstance.go @@ -0,0 +1,43 @@ +package onem2m +import ( + "estimed_demo/utils" + "fmt" + "io" + "log" + "net/http" + "strings" +) + +// CreateContentInstance creates a ContentInstance (data) in the container +func CreateContentInstance(platformURL, cse_name, App_Name, AE_ID, containerName, remote_cse_id, data string) error { + log.Printf("Creating ContentInstance with data: %s", data) + + // Escape JSON quotes in the content field + escapedData := strings.ReplaceAll(data, `"`, `\"`) + + reqBody := fmt.Sprintf(`{ + "m2m:cin": { + "con": "%s", + "lbl": ["telemetry"], + "at": ["%s"], + "aa": ["lbl", "con"] + } + }`, escapedData, remote_cse_id) + + url := fmt.Sprintf("%s/%s/%s/%s", platformURL, cse_name, App_Name, containerName) + + resp, err := utils.MakeOneM2MRequest("POST", url, reqBody, 4, AE_ID) + if err != nil { + return fmt.Errorf("request error: %v", err) + } + defer resp.Body.Close() + + body, _ := io.ReadAll(resp.Body) + + if resp.StatusCode == http.StatusCreated { + log.Println("✓ ContentInstance created successfully") + return nil + } + + return fmt.Errorf("failed to create content instance: status %d, body: %s", resp.StatusCode, string(body)) +} \ No newline at end of file diff --git a/examples/demo10/oneM2M/createSubscription.go b/examples/demo10/oneM2M/createSubscription.go new file mode 100644 index 000000000..51141de9b --- /dev/null +++ b/examples/demo10/oneM2M/createSubscription.go @@ -0,0 +1,64 @@ +package onem2m + +import ( + "bytes" + "crypto/tls" + "encoding/base64" + "encoding/json" + "fmt" + "io/ioutil" + "net/http" +) + +// CreateSubscription creates a subscription on the specified container for the notification server endpoint +func CreateSubscription(platformURL, cseName, appName, containerName string) error { + subscriptionURL := fmt.Sprintf("%s/%s/%s/%s", platformURL, cseName, appName, containerName) + + target := subscriptionURL + // Subscription resource body + body := map[string]interface{}{ + "m2m:sub": map[string]interface{}{ + "rn": "DataSyncSub", + "nu": []string{"https://192.168.20.163:9999/notifications"}, + "nct": 1, + "enc": map[string]interface{}{ + "net": []int{3}, + }, + }, + } + jsonBody, err := json.Marshal(body) + if err != nil { + return fmt.Errorf("failed to marshal subscription body: %v", err) + } + + adminUser := "CAdmin" + adminSecret := "ikram123" + authString := fmt.Sprintf("%s:%s", adminUser, adminSecret) + authHeader := "Basic " + base64.StdEncoding.EncodeToString([]byte(authString)) + + req, err := http.NewRequest("POST", target, bytes.NewBuffer(jsonBody)) + if err != nil { + return fmt.Errorf("failed to create subscription request: %v", err) + } + req.Header.Set("X-M2M-Origin", adminUser) + req.Header.Set("X-M2M-RI", "req-admin") + req.Header.Set("Authorization", authHeader) + req.Header.Set("X-M2M-RVI", "5") + req.Header.Set("Content-Type", "application/json;ty=23") + + // Skip TLS verification for development/testing + tr := &http.Transport{ + TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, + } + client := &http.Client{Transport: tr} + resp, err := client.Do(req) + if err != nil { + return fmt.Errorf("failed to send subscription request: %v", err) + } + defer resp.Body.Close() + respBody, _ := ioutil.ReadAll(resp.Body) + if resp.StatusCode != 201 && resp.StatusCode != 409 { // 409: Already exists + return fmt.Errorf("subscription creation failed: %s", string(respBody)) + } + return nil +} diff --git a/examples/demo10/oneM2M/createcontainer.go b/examples/demo10/oneM2M/createcontainer.go new file mode 100644 index 000000000..a3745f522 --- /dev/null +++ b/examples/demo10/oneM2M/createcontainer.go @@ -0,0 +1,44 @@ +package onem2m + +import ( + "estimed_demo/utils" + "fmt" + "io" + "log" + "net/http" +) + +// CreateContainer creates a container under the AE +func CreateContainer(platformURL, cse_name, cse_id, App_Name, AE_ID, containerName, remote_cse_id string) error { + log.Println("Creating Container...") + + reqBody := fmt.Sprintf(`{ + "m2m:cnt": { + "rn": "%s", + "mni": 10, + "at": ["%s"], + "lbl": ["Data/Telemetry"], + "aa": ["lbl"] + } + }`, containerName, remote_cse_id) + + url := fmt.Sprintf("%s/~/%s/%s/%s", platformURL, cse_id, cse_name, App_Name) + log.Println("url (Create Container):", url) + resp, err := utils.MakeOneM2MRequest("POST", url, reqBody, 3, AE_ID) + if err != nil { + return fmt.Errorf("request error: %v", err) + } + defer resp.Body.Close() + + body, _ := io.ReadAll(resp.Body) + + if resp.StatusCode == http.StatusCreated { + log.Println("✓ Container created successfully") + return nil + } else if resp.StatusCode == http.StatusConflict { + log.Println("⚠ Container already exists") + return nil + } + + return fmt.Errorf("failed to create container: status %d, body: %s", resp.StatusCode, string(body)) +} \ No newline at end of file diff --git a/examples/demo10/oneM2M/deregister.go b/examples/demo10/oneM2M/deregister.go new file mode 100644 index 000000000..ac04d0917 --- /dev/null +++ b/examples/demo10/oneM2M/deregister.go @@ -0,0 +1,27 @@ +package onem2m + +import ( + "estimed_demo/utils" + "fmt" + "io" + "log" + "net/http" +) + +// DeregisterAE deregisters the AE from the oneM2M platform +func DeregisterAE(platformURL, cseName, cse_id, appName, aeID string) error { + aeResource := fmt.Sprintf("%s/~%s/%s/%s", platformURL, cse_id, cseName, appName) + resp, err := utils.MakeOneM2MRequest("DELETE", aeResource, "", 2, aeID) + if err != nil { + return fmt.Errorf("failed to deregister AE: %v", err) + } + defer resp.Body.Close() + + body, _ := io.ReadAll(resp.Body) + if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusNoContent { + return fmt.Errorf("failed to deregister AE, status: %s, response: %s", resp.Status, string(body)) + } + + log.Printf("✓ AE deregistered successfully, response: %s", string(body)) + return nil +} diff --git a/examples/demo10/oneM2M/oneM2m_init.go b/examples/demo10/oneM2M/oneM2m_init.go new file mode 100644 index 000000000..3f9b92204 --- /dev/null +++ b/examples/demo10/oneM2M/oneM2m_init.go @@ -0,0 +1,31 @@ +package onem2m + +import ( + "log" + "time" +) + +// Initialize oneM2M application +func InitOneM2MApp(platformURL, cse_name, cse_id, App_Name, + App_Id, AE_ID, containerName, remote_cse_id string) error { + log.Printf("Connecting to MN-CSE: %s", platformURL) + // Create AE + if err := CreateAE(platformURL, cse_name, cse_id, App_Name, App_Id, AE_ID, remote_cse_id); err != nil { + return err + } + // Wait briefly to ensure AE is registered + time.Sleep(2 * time.Second) + + // Create Container + if err := CreateContainer(platformURL, cse_name, cse_id, App_Name, AE_ID, containerName, remote_cse_id); err != nil { + return err + } + + // Verify container + if err := RetrieveContainer(platformURL, cse_name, cse_id, App_Name, AE_ID, containerName); err != nil { + log.Printf("Warning: Could not verify container: %v", err) + } + + log.Println("✓ Application initialized successfully") + return nil +} diff --git a/examples/demo10/oneM2M/retrieveContainer.go b/examples/demo10/oneM2M/retrieveContainer.go new file mode 100644 index 000000000..a6d4dc211 --- /dev/null +++ b/examples/demo10/oneM2M/retrieveContainer.go @@ -0,0 +1,28 @@ +package onem2m +import ( + "estimed_demo/utils" + "fmt" + "io" + "log" + "net/http" +) + +// RetrieveContainer retrieves container details +func RetrieveContainer(platformURL, cse_name, cse_id, App_Name, AE_ID, containerName string) error { + url := fmt.Sprintf("%s/~%s/%s/%s/%s", platformURL, cse_id, cse_name, App_Name, containerName) + + resp, err := utils.MakeOneM2MRequest("GET", url, "", 0, AE_ID) + if err != nil { + return fmt.Errorf("error retrieving container: %v", err) + } + defer resp.Body.Close() + + body, _ := io.ReadAll(resp.Body) + + if resp.StatusCode == http.StatusOK { + log.Println("✓ Container exists and is accessible") + return nil + } + + return fmt.Errorf("container not found: status %d, body: %s", resp.StatusCode, string(body)) +} \ No newline at end of file diff --git a/examples/demo10/oneM2M/retrieveLatestData.go b/examples/demo10/oneM2M/retrieveLatestData.go new file mode 100644 index 000000000..9208f5812 --- /dev/null +++ b/examples/demo10/oneM2M/retrieveLatestData.go @@ -0,0 +1,30 @@ +package onem2m +import ( + "estimed_demo/utils" + "fmt" + "io" + "log" + "net/http" +) + +// RetrieveLatestData retrieves the latest ContentInstance from the container +func RetrieveLatestData(platformURL, cse_name, App_Name, AE_ID, containerName string) (string, error) { + // Use 'la' (latest) to get the most recent ContentInstance + // ToDo: Fix variable name cse_id to cse_name // check this file + url := fmt.Sprintf("%s/%s/%s/%s/la", platformURL, cse_name, App_Name, containerName) + + resp, err := utils.MakeOneM2MRequest("GET", url, "", 0, AE_ID) + if err != nil { + return "", fmt.Errorf("error retrieving data: %v", err) + } + defer resp.Body.Close() + + body, _ := io.ReadAll(resp.Body) + + if resp.StatusCode == http.StatusOK { + log.Println("✓ Latest data retrieved successfully") + return string(body), nil + } + + return "", fmt.Errorf("failed to retrieve data: status %d", resp.StatusCode) +} \ No newline at end of file diff --git a/examples/demo10/utils/mec_req.go b/examples/demo10/utils/mec_req.go new file mode 100644 index 000000000..f4f32e155 --- /dev/null +++ b/examples/demo10/utils/mec_req.go @@ -0,0 +1,50 @@ +package utils + +import ( + "bytes" + "context" + "crypto/tls" + "encoding/json" + "fmt" + "log" + "net/http" + "time" +) + +func SendMECRequest(method, url string, payload interface{}) (*http.Response, error) { + client := &http.Client{ + Timeout: 10 * time.Second, + Transport: &http.Transport{ + TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, + }, + } + + var req *http.Request + var err error + + // Handle GET requests with no payload + if method == "GET" && payload == nil { + req, err = http.NewRequestWithContext(context.Background(), method, url, nil) + if err != nil { + return nil, fmt.Errorf("failed to create request: %v", err) + } + } else { + // Handle requests with payload + reqBody, err := json.Marshal(payload) + if err != nil { + return nil, fmt.Errorf("failed to marshal payload: %v", err) + } + log.Println("Request body:", string(reqBody)) + + req, err = http.NewRequestWithContext(context.Background(), method, url, bytes.NewBuffer(reqBody)) + if err != nil { + return nil, fmt.Errorf("failed to create request: %v", err) + } + req.Header.Set("Content-Type", "application/json") + } + + req.Header.Set("Accept", "application/json") + req.Header.Set("User-Agent", "Go-http-client/1.1") + + return client.Do(req) +} diff --git a/examples/demo10/utils/onem2m_req.go b/examples/demo10/utils/onem2m_req.go new file mode 100644 index 000000000..7295ebcd0 --- /dev/null +++ b/examples/demo10/utils/onem2m_req.go @@ -0,0 +1,53 @@ +package utils + +import ( + "crypto/tls" + "encoding/base64" + "fmt" + "net/http" + "strings" + "time" + + "github.com/google/uuid" +) + +// MakeOneM2MRequest creates and sends a oneM2M HTTP request +func MakeOneM2MRequest(method, url, body string, ty int, originator string) (*http.Response, error) { + client := &http.Client{Transport: &http.Transport{ + TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, + }, + Timeout: 10 * time.Second} + reqID := uuid.New().String() + + // if originator == "" { + // originator = AE_ID + // } + + headers := map[string]string{ + "X-M2M-Origin": originator, + "X-M2M-RI": reqID, + "X-M2M-RVI": "5", + "Accept": "application/json", + "Authorization": "Basic " + base64.StdEncoding.EncodeToString([]byte("CAdmin:ikram123")), + } + + if method == "POST" { + headers["Content-Type"] = fmt.Sprintf("application/json;ty=%d", ty) + } + + req, err := http.NewRequest(method, url, strings.NewReader(body)) + if err != nil { + return nil, fmt.Errorf("failed to create request: %v", err) + } + + for key, value := range headers { + req.Header.Set(key, value) + } + + resp, err := client.Do(req) + if err != nil { + return nil, fmt.Errorf("failed to send request: %v", err) + } + + return resp, nil +} -- GitLab From 4f041623621d6f5f673f7a77d1d596b70c14ee9e Mon Sep 17 00:00:00 2001 From: Mudassar Khan Date: Thu, 19 Feb 2026 06:41:19 +0000 Subject: [PATCH 15/15] fix(frontend): fix multiple map view bugs in CFG configurator - Use element UUID (not name) as marker id so table lookups work correctly - Only create markers for elements that have a real geo location - Prevent stale configuredElement UUID from dimming all map markers - Add cfgTable to shouldComponentUpdate to keep zone colors in sync - Add console.log debug statements for easier diagnostics --- .../src/js/containers/idc-map.js | 64 +++++++++++++------ 1 file changed, 43 insertions(+), 21 deletions(-) diff --git a/js-apps/meep-frontend/src/js/containers/idc-map.js b/js-apps/meep-frontend/src/js/containers/idc-map.js index 456a5a880..95d8ff787 100644 --- a/js-apps/meep-frontend/src/js/containers/idc-map.js +++ b/js-apps/meep-frontend/src/js/containers/idc-map.js @@ -167,22 +167,32 @@ class IDCMap extends Component { if (this.props.type === TYPE_CFG) { // Target element update if (nextProps.configuredElement !== this.props.configuredElement) { + console.log('[IDCMap] shouldComponentUpdate: configuredElement changed', nextProps.configuredElement); return true; } // Scenario change if (nextProps.cfgScenarioName !== this.props.cfgScenarioName) { + console.log('[IDCMap] shouldComponentUpdate: cfgScenarioName changed', nextProps.cfgScenarioName); return true; } // Scenario content change if (!deepEqual(nextProps.cfgScenario, this.props.cfgScenario)) { + console.log('[IDCMap] shouldComponentUpdate: cfgScenario content changed'); + return true; + } + // Table change (needed for zone color lookups) + if (!deepEqual(nextProps.cfgTable, this.props.cfgTable)) { + console.log('[IDCMap] shouldComponentUpdate: cfgTable changed'); return true; } // Sandbox update if (nextProps.cfgView !== this.props.cfgView) { + console.log('[IDCMap] shouldComponentUpdate: cfgView changed', nextProps.cfgView); return true; } // Map asset change if (!deepEqual(this.getMap(nextProps), this.getMap(this.props))) { + console.log('[IDCMap] shouldComponentUpdate: map data changed'); return true; } return false; @@ -222,32 +232,32 @@ class IDCMap extends Component { zone.networkLocations.forEach(nl => { if (nl.physicalLocations) { nl.physicalLocations.forEach(pl => { - if (pl.type === 'UE') { + if (pl.type === 'UE' && pl.geoData && pl.geoData.location) { map.ueList.push({ assetName: pl.name, - id: (this.props.type === TYPE_CFG) ? pl.name : (pl.id || pl.name), - radius: pl.geoData ? pl.geoData.radius : 0, - location: pl.geoData && pl.geoData.location ? pl.geoData.location : {type: 'Point', coordinates: [0,0]}, - path: pl.geoData && pl.geoData.path ? pl.geoData.path : null, - eopMode: pl.geoData ? pl.geoData.eopMode : null, - velocity: pl.geoData ? pl.geoData.velocity : null + id: pl.id || pl.name, + radius: pl.geoData.radius || 0, + location: pl.geoData.location, + path: pl.geoData.path || null, + eopMode: pl.geoData.eopMode || null, + velocity: pl.geoData.velocity || null }); - } else if (pl.type === 'FOG' || pl.type === 'EDGE' || pl.type === 'DC') { + } else if ((pl.type === 'FOG' || pl.type === 'EDGE' || pl.type === 'DC') && pl.geoData && pl.geoData.location) { map.computeList.push({ assetName: pl.name, - id: (this.props.type === TYPE_CFG) ? pl.name : (pl.id || pl.name), - location: pl.geoData && pl.geoData.location ? pl.geoData.location : {type: 'Point', coordinates: [0,0]} + id: pl.id || pl.name, + location: pl.geoData.location }); } }); } // For POA - if (nl.type === 'POA' || nl.type === 'POA-4G' || nl.type === 'POA-5G' || nl.type === 'POA-WIFI') { + if ((nl.type === 'POA' || nl.type === 'POA-4G' || nl.type === 'POA-5G' || nl.type === 'POA-WIFI') && nl.geoData && nl.geoData.location) { map.poaList.push({ assetName: nl.name, - id: (this.props.type === TYPE_CFG) ? nl.name : (nl.id || nl.name), - location: nl.geoData && nl.geoData.location ? nl.geoData.location : {type: 'Point', coordinates: [0,0]}, - radius: nl.geoData ? nl.geoData.radius : 0 + id: nl.id || nl.name, + location: nl.geoData.location, + radius: nl.geoData.radius || 0 }); } }); @@ -1174,6 +1184,7 @@ class IDCMap extends Component { var map; if (this.props.type === TYPE_CFG) { map = this.buildMapFromScenario(this.props.cfgScenario); + console.log('[IDCMap] updateMarkers (CFG): ues=', map.ueList.length, 'poas=', map.poaList.length, 'computes=', map.computeList.length); } else { map = deepCopy(this.getMap(this.props)); } @@ -1192,7 +1203,7 @@ class IDCMap extends Component { for (let i = 0; i < map.computeList.length; i++) { let compute = map.computeList[i]; this.setComputeMarker(compute); - computeMap[compute.assetName] = true; + computeMap[compute.id || compute.assetName] = true; } } @@ -1209,7 +1220,7 @@ class IDCMap extends Component { for (let i = 0; i < map.poaList.length; i++) { let poa = map.poaList[i]; this.setPoaMarker(poa); - poaMap[poa.assetName] = true; + poaMap[poa.id || poa.assetName] = true; } } @@ -1227,7 +1238,7 @@ class IDCMap extends Component { for (let i = 0; i < map.ueList.length; i++) { let ue = map.ueList[i]; this.setUeMarker(ue); - ueMap[ue.assetName] = true; + ueMap[ue.id || ue.assetName] = true; } } @@ -1335,6 +1346,7 @@ class IDCMap extends Component { setTarget(target) { // Disable changes on all markers except target + console.log('[IDCMap] setTarget:', target); var isDragModeEnabled = this.map.pm.globalDragModeEnabled(); this.ueOverlay.eachLayer((marker) => { @@ -1398,10 +1410,15 @@ class IDCMap extends Component { // Update target element name & reset controls on target change var targetElemId = this.props.configuredElement ? this.props.configuredElement.id : null; + console.log('[IDCMap] updateEditControls: targetElemId =', targetElemId); // Determine which controls to enable + // Only look up a marker if we have a target id; treat a stale/unmatched id the + // same as "no target" so all markers remain interactive instead of being dimmed. + var markerInfo = targetElemId ? this.getMarkerInfo(targetElemId) : null; + var markerTarget = (markerInfo && markerInfo.marker) ? targetElemId : null; + if (targetElemId) { - var markerInfo = this.getMarkerInfo(targetElemId); if (markerInfo && markerInfo.marker) { // Enable path create/edit for UE only if (markerInfo.type === TYPE_UE) { @@ -1411,10 +1428,12 @@ class IDCMap extends Component { editModeEnabled = true; } dragModeEnabled = true; + console.log('[IDCMap] updateEditControls: found marker for target, dragMode =', dragModeEnabled); // removalModeEnabled = true; } else { - // Enable marker creation + // Element is configured but has no map marker yet — enable placement drawMarkerEnabled = true; + console.log('[IDCMap] updateEditControls: no marker for target (unplaced/stale elem), drawMarker enabled'); } } @@ -1445,8 +1464,11 @@ class IDCMap extends Component { } } - // Set target element & disable edit on all other markers - this.setTarget(targetElemId); + // Only focus (dim others) when the configured element actually has a marker on + // the map. If it doesn't (element not yet placed, or stale id from a previous + // scenario), pass null so all markers remain fully interactive. + console.log('[IDCMap] updateEditControls: setTarget with', markerTarget); + this.setTarget(markerTarget); } render() { -- GitLab