diff --git a/charts/meep-vis/values-template.yaml b/charts/meep-vis/values-template.yaml index 1e5663fa3..3202d5d43 100644 --- a/charts/meep-vis/values-template.yaml +++ b/charts/meep-vis/values-template.yaml @@ -22,6 +22,8 @@ image: MEEP_SANDBOX_NAME: {{.SandboxName}} MEEP_SVC_PATH: /vis/v2 MEEP_HOST_URL: {{.HostUrl}} + MEEP_BROKER: mqtt://test.mosquito.org:1338 + MEEP_POA_LIST: poa-5g1 {{- if .IsMepService }} MEEP_MEP_NAME: {{.MepName}} {{- end }} diff --git a/examples/demo4-ue/README.md b/examples/demo4-ue/README.md new file mode 100644 index 000000000..3cde8bce5 --- /dev/null +++ b/examples/demo4-ue/README.md @@ -0,0 +1,537 @@ +# Demo4 +Demo4 scenario showcases the _Edge Platform Application Enablement_ and _Application Mobility_ edge services. + +For more details, check out the [Demo4 Documentation](https://interdigitalinc.github.io/AdvantEDGE/docs/usage/usage-demo4/) + + + +Demo4 scenario showcases the _Edge Platform Application Enablement_ and _Application Mobility_ edge services. + +Demo4 includes: +- A Terminal application, named [demo4-ue](#demo4-ue), that can be deployed either as a container using the provided AdvantEDGE scenario, or as an external application that interacts with private or public AdvantEDGE deployments such as the ETSI MEC Sandbox. +- An onboarded MEC application, named [onboarded-demo4](#onboarded-demo4) , that is deploy on the MEC platform. It can be instantiated using MEC-016 Service APIs + +Demo4 Terminal application does not provide a dashboard GUI, tools such as cUrl or Postman can be used (see clause [demo4-ue](#demo4-ue)) + +## Demo4 Scenario Overview + +The Demo4 scenario consists of one or more instances of a single Terminal application running one or more fixed or mobile terminal equipment. +MEC-016 Service APIs "/dev_app/v1/context" and "/dev_app/v1/context/{instance}" provide the capability to instantiate one or more MEC applications. +By default, there is one onboarded MEC application named onboarded-demo4, described below (see file ~/AdvantDEGE/examples/demo4-ue/src/onboarded-demo4.yaml): + +```yaml +{ + "appList": + [ + { + "appInfoList": + [ + { + "appDId": "onboarded-demo4", + "appName": "onboarded-demo4", + "appProvider": "ETSI", + "appSoftVersion": "v0.1.0", + "appDVersion": "v0.1.0", + "appDescription": "Basic HTTP Ping Pong", + "appLocation": + [ + { + "area": null, + "civicAddressElement": null, + "countryCode": "33" + } + ], + "appCharcs": + [ + { + "memory": 1024, + "storage": 1024, + "latency": 1024, + "bandwidth": 1024, + "serviceCont": 0 + } + ], + "cmd": "/onboardedapp/onboarded-demo/onboarded-demo4", + "args":null + } + ], + "vendorSpecificExt": { + "vendorId": "ETSI" + } + } + ] +} +``` + +### demo4-ue + +The Terminal application demo4-ue provide a simply HTTP REST APIs for MEC-016 in order to validate quickly MEC-016 support. + +#### Check that the demo4-ue is up + +The request `GET /info/application` provides a description of the demo4-ue application. +```sh +$ curl "http://mec-platform.etsi.org:31111/info/application" -H "accept: application/json" +{"config":"app_instance.yaml","ip":"http://demo4-ue1:80","id":"ce454f4c-16f8-4542-83d8-c8afd45bcfea","mecReady":true,"subscriptions":{"AppTerminationSubscription":{"subId":"sub-LzNr62ED50GbZL_S"},"SerAvailabilitySubscription:":{"subId":"sub-Ec2tT-tKAe_qLxI7"}},"offeredService":{"serName":"demo4","id":"2ad0e566-2054-4550-ba97-1fe1f100fff0","state":"ACTIVE","scopeOfLocality":"MEC_SYSTEM","consumedLocalOnly":true},"discoveredServices":[{"serName":"meep-dai","serInstanceId":"70bb83a5-7ec7-4ab4-b889-ca7033a5be2b","consumedLocalOnly":true,"link":"http://mec-platform.etsi.org/usersb/dev_app/v1/","version":"2.0"},{"serName":"meep-rnis","serInstanceId":"3e72aa67-ff20-4e7e-bf21-aea928a1743b","consumedLocalOnly":true,"link":"http://mec-platform.etsi.org/usersb/rni/v2/","version":"2.0"},{"serName":"meep-ams","serInstanceId":"99e8a85d-5f87-48ed-be5e-1302c18e4664","consumedLocalOnly":true,"link":"http://mec-platform.etsi.org/usersb/amsi/v1/","version":"2.0"},{"serName":"meep-loc-serv","serInstanceId":"85ddf74d-d5e7-4d6f-beb5-25e97f8b57c9","consumedLocalOnly":true,"link":"http://mec-platform.etsi.org/usersb/location/v2/","version":"2.0"},{"serName":"meep-vis","serInstanceId":"3e23a210-8b1a-4a01-bc0c-1df7d1ad6be3","consumedLocalOnly":true,"link":"http://mec-platform.etsi.org/usersb/vis/v2/","version":"2.0"},{"serName":"meep-wais","serInstanceId":"a22f614e-a5c1-4902-84d3-4361ac9e3425","consumedLocalOnly":true,"link":"http://mec-platform.etsi.org/usersb/wai/v2/","version":"2.0"}]} +``` + +The request `GET /info/logs` provides some executon logs for the demo4-ue application. +```sh +$ curl "http://mec-platform.etsi.org:31111/info/logs" -H "accept: application/json" +["5. demo4DaiAppListGET: applicationList succeed, len= 1","4. daiClient instance created","3. Subscribe to service-availability notification [201]","2. Subscribe to app-termination notification [201]","1. === Register Demo4 MEC Application [200]","0. Send confirm ready [204]"] +``` + +#### Retrieve the list of existing onboarded MEC applications + +The request `GET /dai/apps` provides the list of the onboarded MEC application. +```sh +$ curl "http://mec-platform.etsi.org:31111/dai/apps" -H "accept: application/json" +{"appList":[{"appInfo":{"appCharcs":{"bandwidth":1024,"latency":1024,"memory":1024,"storage":1024},"appDId":"onboarded-demo4","appDVersion":"v0.1.0","appDescription":"Basic HTTP Ping Pong","appLocation":[{"countryCode":"33"}],"appName":"onboarded-demo4","appProvider":"ETSI","appSoftVersion":"v0.1.0"}}]} +``` + +#### Instantiate an onboarded MEC application + +The request `POST /dai/instantiate` is used to create a new AppContext and instantiate the specified onboarded MEC application. +```sh +$ curl -X POST "http://mec-platform.etsi.org:31111/dai/instantiate" -H "accept: application/json" +{"appAutoInstantiation":true,"appInfo":{"appDId":"onboarded-demo4","appDVersion":"v0.1.0","appDescription":"Basic HTTP Ping Pong","appName":"onboarded-demo4","appProvider":"ETSI","appSoftVersion":"v0.1.0","appPackageSource":"appPackageSource1","userAppInstanceInfo":[{"appInstanceId":"20","appLocation":{"countryCode":"33"},"referenceURI":"https://mec-platform.etsi.org/usersb/onboarded-demo4"}]},"appLocationUpdates":true,"associateDevAppId":"04e71585-87c7-4d2e-b913-538cf1ef","callbackReference":"http://demo4-ue1:80","contextId":"20"} +``` + +Note that, in the response: +- The field "contextId" indicates the identifier to be used to [terminate the instance](#terminate-an-existing-instance-of-onboarded-mec-application). +- The field "referenceURI" indicates the URL to the new instance of the onboarded MEC application, see clause [Ping request](#ping-request]). + +#### Ping request + +The request `GET /onboarded-demo4/ping/{appcontextid}` is the ping/pong request to send to the instance of the onboarded MEC application [onboarded-demo4](#onboarded-demo4). +```sh +$ curl "http://mec-platform.etsi.org/usersb/onboarded-demo4/ping/20" -H "accept: application/json" +"pong" +``` + +#### Terminate an existing instance of onboarded MEC application + +The request `DELETE /dai/delete/{appcontextid}` terminates the instance of the specified onboarded MEC application. + +```sh +$ curl -X DELETE "http://mec-platform.etsi.org:31111/dai/delete/20" -H "accept: application/json" +``` + +#### application location availability task + +The request `POST /dai/availability/{appcontextid}` provides the location availability for the specified instance of the onboarded MEC application. + +```sh +$ curl -X POST "http://mec-platform.etsi.org:31111/dai/availability/20" -H "accept: application/json" +``` + +#### Postman workspace + +The code below is the the Postman workspace equivalent to the curl requests above. + +```json +{ + "info": { + "_postman_id": "e8a79bf9-aeba-4869-91a1-45fb6f7320a7", + "name": "demo4-ue", + "description": "This collection provides all Curl command supported by the UE appliction demo4-ue", + "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json", + "_exporter_id": "3317208" + }, + "item": [ + { + "name": "/info/application", + "protocolProfileBehavior": { + "disabledSystemHeaders": { + "accept": true + } + }, + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "url": { + "raw": "try-mec.etsi.org:31111/info/application", + "host": [ + "try-mec", + "etsi", + "org" + ], + "port": "31111", + "path": [ + "info", + "application" + ], + "query": [ + { + "key": "", + "value": null, + "disabled": true + } + ] + } + }, + "response": [] + }, + { + "name": "/info/logs", + "protocolProfileBehavior": { + "disabledSystemHeaders": { + "accept": true + } + }, + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "url": { + "raw": "try-mec.etsi.org:31111/info/logs", + "host": [ + "try-mec", + "etsi", + "org" + ], + "port": "31111", + "path": [ + "info", + "logs" + ], + "query": [ + { + "key": "", + "value": null, + "disabled": true + } + ] + } + }, + "response": [] + }, + { + "name": "/dai/apps", + "protocolProfileBehavior": { + "disabledSystemHeaders": { + "accept": true + } + }, + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "application/json", + "type": "text" + } + ], + "url": { + "raw": "try-mec.etsi.org:31111/dai/apps", + "host": [ + "try-mec", + "etsi", + "org" + ], + "port": "31111", + "path": [ + "dai", + "apps" + ], + "query": [ + { + "key": "", + "value": null, + "disabled": true + } + ] + } + }, + "response": [] + }, + { + "name": "/dai/instantiate", + "protocolProfileBehavior": { + "disabledSystemHeaders": { + "accept": true + } + }, + "request": { + "method": "POST", + "header": [ + { + "key": "Accept", + "value": "accept: application/json", + "type": "text" + } + ], + "url": { + "raw": "try-mec.etsi.org:31111/dai/instantiate", + "host": [ + "try-mec", + "etsi", + "org" + ], + "port": "31111", + "path": [ + "dai", + "instantiate" + ] + } + }, + "response": [] + }, + { + "name": "/usersb/onboarded-demo4/ping", + "protocolProfileBehavior": { + "disabledSystemHeaders": { + "accept": true + } + }, + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "accept: application/json", + "type": "text" + } + ], + "url": { + "raw": "https://195.238.226.94/usersb/onboarded-demo4/ping", + "protocol": "https", + "host": [ + "195", + "238", + "226", + "94" + ], + "path": [ + "usersb", + "onboarded-demo4", + "ping" + ] + } + }, + "response": [] + }, + { + "name": "/usersb/onboarded-demo4/terminate", + "protocolProfileBehavior": { + "disabledSystemHeaders": { + "accept": true + } + }, + "request": { + "method": "DELETE", + "header": [ + { + "key": "Accept", + "value": "accept: application/json", + "type": "text" + } + ], + "url": { + "raw": "https://try-mec.etsi.org/usersb/onboarded-demo4/ping", + "protocol": "https", + "host": [ + "try-mec", + "etsi", + "org" + ], + "path": [ + "usersb", + "onboarded-demo4", + "ping" + ] + } + }, + "response": [] + }, + { + "name": "/dai/doping", + "protocolProfileBehavior": { + "disabledSystemHeaders": { + "accept": true + } + }, + "request": { + "method": "GET", + "header": [ + { + "key": "Accept", + "value": "accept: application/json", + "type": "text" + } + ], + "url": { + "raw": "try-mec.etsi.org:31111/dai/doping/25", + "host": [ + "try-mec", + "etsi", + "org" + ], + "port": "31111", + "path": [ + "dai", + "doping", + "25" + ] + } + }, + "response": [] + }, + { + "name": "/dai/delete", + "protocolProfileBehavior": { + "disabledSystemHeaders": { + "accept": true + } + }, + "request": { + "method": "DELETE", + "header": [ + { + "key": "Accept", + "value": "accept: application/json", + "type": "text" + } + ], + "url": { + "raw": "try-mec.etsi.org:31111/dai/delete/25", + "host": [ + "try-mec", + "etsi", + "org" + ], + "port": "31111", + "path": [ + "dai", + "delete", + "25" + ] + } + }, + "response": [] + }, + { + "name": "/dai/availability", + "protocolProfileBehavior": { + "disabledSystemHeaders": { + "accept": true + } + }, + "request": { + "method": "POST", + "header": [ + { + "key": "Accept", + "value": "accept: application/json", + "type": "text" + } + ], + "url": { + "raw": "try-mec.etsi.org:31111/dai/availability/25", + "host": [ + "try-mec", + "etsi", + "org" + ], + "port": "31111", + "path": [ + "dai", + "availability", + "25" + ] + } + }, + "response": [] + } + ] +} +``` + +### onboarded-demo4 + +The MEC application onboarded-demo4 is a basic HTTP REST API "Ping/Pong" application. When it recieves an HTTP GET /ping request, it replies with 200 OK "pong". +The goal of this application is just to validate the support of MEC-016 Service APIs. + +## Using Demo4 + +### Preamble (reserved to MEC Sandbox administrator) + +Before using Demo4, the configuration files '~/AdvantDEGE/examples/demo4-ue/src/onboarded-demo4.yaml' and '~/AdvantEDGE/examples/demo4-ue/src/onboarded-demo/onboarded-demo-test1.json' and the binariy folders shall be copied into the folder /var/lib/docker/volumes/meep-dai/_data/ (required to use sudo command). This is the descriptor of the onboarded MEC application [onboarded-demo4](#onboarded-demo4). + +**_Note_** For the MEC Sandbox platform, the configuration files and the binariy folders shall be copied into the folder /var/lib/docker/volumes//_data (e.g. /var/lib/docker/volumes/meep-4g-5g-wifi-macro-mec016-1/_data) + +### Using Demo4 with AdvantEDGE + +To use Demo4 as an AdvantEDGE scenario container: + +- Build & dockerize Demo4 server & frontend +- Import the provided scenario demo4-scenario.yaml +- Create a sandbox & deploy Demo4 scenario +- Start Demo4 application frontend in browser + +#### Build from source +To build demo4-ue & onboarded-demo4 from source code: +```sh +$ cd ~/AdvantEDGE/examples/demo4-ue +$ ./build-demo4-ue.sh --rebuild_dai +``` + +NOTE: Binary files are created in ./bin/ folder. + +#### Dockerize demo applications +Demo Application binaries must be dockerized (containerized) as container images in the Docker registry. This step is necessary every time the demo binaries are updated. + +NOTE: Make sure you have deployed the AdvantEDGE dependencies (e.g. docker registry) before dockerizing the demo binaries. + +To generate docker images from demo binary files: + +```sh +$ cd ~/AdvantEDGE/examples/demo4-ue +$ ./dockerize.sh +``` + +### Using Demo4 with ETSI MEC Sandbox + +To use Demo4 as an external application that interacts with the ETSI MEC Sandbox + +- Build Demo4 server & frontend +- Log in to the [ETSI MEC Sandbox](https://try-mec.etsi.org) +- Deploy either of the dual-mep scenarios +- Configure Demo4 application instances +- Start Demo4 application instances +- Demo4 does not have prior knowledge or configuration information of the MEC services offered by the MEC platform. + +Therefore, the following steps need to be done prior to running Demo4 application instances. + +#### Obtain demo binaries +- Use the same procedure described above for Demo4 with AdvantEDGE. + +#### Create work directory for demo4-ue instance +- Create a work directory of your choice on the system (e.g. ~/tmp/demo4) and copy the files ~/AdvantEDGE/examples/demo4-ue/src/demo-server/demo4-ue-config.yaml and ~/AdvantEDGE/examples/demo4-ue/bin/demo-server/demo-server. + + The structure should look like this: + + ``` + ~/tmp/demo4 + | + \____ demo4-ue-config.yaml + | + \____ demo-server + ``` + +Update the configuration file demo4-ue-config.yaml accordingly and launch the demo application: + +```sh +$ ./demo-server ./demo4-ue-config.yaml +``` \ No newline at end of file diff --git a/examples/demo4-ue/build-demo4-ue.sh b/examples/demo4-ue/build-demo4-ue.sh new file mode 100644 index 000000000..19809505e --- /dev/null +++ b/examples/demo4-ue/build-demo4-ue.sh @@ -0,0 +1,58 @@ +#!/bin/bash + +#set -vx + +function usage() { + echo "Usage: $0 {--rebuild_dai}" >&2 + echo " --rebuild_dai To force MEEP-DAI micor-service to be rebuilt" + exit 1 +} + +# Get full path to script directory +SCRIPT=$(readlink -f "$0") +BASEDIR=$(dirname "$SCRIPT") + +# Get Arguments +REBUILD_DAI=$1 +if [ "$REBUILD_DAI" != "" ]; then + if [ "$REBUILD_DAI" != "--rebuild_dai" ]; then + usage + fi +fi + +echo "" +echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" +echo ">>> onboarded-demo" +echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" +echo "" +DEMOBIN=$BASEDIR/bin/onboarded-demo + +$BASEDIR/src/onboarded-demo/build.sh $DEMOBIN + +# Update meep-dai binary folder with the MEC application +MEEPDAI_ONBOARDEDAPP_PATH=../../bin/meep-dai/onboardedapp +echo ">>> Updating DAI micro-service with onboarded MEC applications" +if [ -d $MEEPDAI_ONBOARDEDAPP_PATH ]; then + rm -fr $MEEPDAI_ONBOARDEDAPP_PATH +fi +mkdir -p $MEEPDAI_ONBOARDEDAPP_PATH +cp -Rp $DEMOBIN $MEEPDAI_ONBOARDEDAPP_PATH + +if [ "$REBUILD_DAI" != "" ]; then + echo ">>> Building DAI micro-service" + meepctl build meep-dai #--nolint + echo ">>> Dockerizing DAI micro-service with new onboarded MEC applications" + meepctl dockerize meep-dai +fi + +echo "" +echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" +echo ">>> Building Demo 4 UE application Go Server" +echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" +echo "" +DEMOBIN=$BASEDIR/bin/demo-server + +$BASEDIR/src/demo-server/backend/build.sh $DEMOBIN + +echo "" +echo ">>> Demo4-ue Service build completed" diff --git a/examples/demo4-ue/dockerize.sh b/examples/demo4-ue/dockerize.sh new file mode 100644 index 000000000..3e3f9a1fc --- /dev/null +++ b/examples/demo4-ue/dockerize.sh @@ -0,0 +1,52 @@ +#!/bin/bash + +#set -vx + +# Get full path to script directory +SCRIPT=$(readlink -f "$0") +BASEDIR=$(dirname "$SCRIPT") + +echo "" +echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" +echo ">>> Dockerizing onboarded-demo4 Server" +echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" +echo "" + +DEMOBIN=$BASEDIR/bin/onboarded-demo + +# Copy Dockerfile & config to bin folder +cp $BASEDIR/src/onboarded-demo/Dockerfile $DEMOBIN +cp $BASEDIR/src/onboarded-demo/entrypoint.sh $DEMOBIN +# cp $BASEDIR/src/onboarded-demo/onboarded-demo.yaml $DEMOBIN + +echo ">>> Dockerizing" +cd $DEMOBIN +docker build --no-cache --rm -t meep-docker-registry:30001/onboarded-demo4 . +docker push meep-docker-registry:30001/onboarded-demo4 +cd $BASEDIR + +echo "" +echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" +echo ">>> Dockerizing demo4-ue Server" +echo ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" +echo "" + +DEMOBIN=$BASEDIR/bin/demo-server + +# Copy frontend to static folder +#echo ">>> Copying Demo Server" +#cp -Rf $BASEDIR/bin/demo-frontend/* $DEMOBIN/static + +# Copy Dockerfile & config to bin folder +cp $BASEDIR/src/demo-server/backend/Dockerfile $DEMOBIN +# cp $BASEDIR/src/demo-server/backend/app_instance.yaml $DEMOBIN +cp $BASEDIR/src/demo-server/entrypoint.sh $DEMOBIN + +echo ">>> Dockerizing" +cd $DEMOBIN +docker build --no-cache --rm -t meep-docker-registry:30001/demo4-ue . +docker push meep-docker-registry:30001/demo4-ue +cd $BASEDIR + +echo "" +echo ">>> Done" diff --git a/examples/demo4-ue/src/demo-server/backend/.swagger-codegen-ignore b/examples/demo4-ue/src/demo-server/backend/.swagger-codegen-ignore new file mode 100644 index 000000000..c5fa491b4 --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/.swagger-codegen-ignore @@ -0,0 +1,23 @@ +# Swagger Codegen Ignore +# Generated by swagger-codegen https://github.com/swagger-api/swagger-codegen + +# Use this file to prevent files from being overwritten by the generator. +# The patterns follow closely to .gitignore or .dockerignore. + +# As an example, the C# client generator defines ApiClient.cs. +# You can make changes and tell Swagger Codgen to ignore just this file by uncommenting the following line: +#ApiClient.cs + +# You can match any string of characters against a directory, file or extension with a single asterisk (*): +#foo/*/qux +# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux + +# You can recursively match patterns against a directory, file or extension with a double asterisk (**): +#foo/**/qux +# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux + +# You can also negate patterns with an exclamation (!). +# For example, you can ignore all files in a docs folder with the file extension .md: +#docs/*.md +# Then explicitly reverse the ignore rule for a single file: +#!docs/README.md diff --git a/examples/demo4-ue/src/demo-server/backend/.swagger-codegen/VERSION b/examples/demo4-ue/src/demo-server/backend/.swagger-codegen/VERSION new file mode 100644 index 000000000..0667b5ffc --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/.swagger-codegen/VERSION @@ -0,0 +1 @@ +3.0.29 \ No newline at end of file diff --git a/examples/demo4-ue/src/demo-server/backend/.travis.yml b/examples/demo4-ue/src/demo-server/backend/.travis.yml new file mode 100644 index 000000000..f5cb2ce9a --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/.travis.yml @@ -0,0 +1,8 @@ +language: go + +install: + - go get -d -v . + +script: + - go build -v ./ + diff --git a/examples/demo4-ue/src/demo-server/backend/Dockerfile b/examples/demo4-ue/src/demo-server/backend/Dockerfile new file mode 100644 index 000000000..b236976b2 --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/Dockerfile @@ -0,0 +1,29 @@ +# Copyright (c) 2022 InterDigital Communications, Inc +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +FROM debian:9.6-slim + + +# Some ENV variables +ENV SERVICE_NAME = "demo4-ue" + +COPY ./demo-server /demo-server +COPY ./api /api +COPY ./user-api /user-api +#COPY ./static /static +COPY entrypoint.sh / + +RUN chmod +x /entrypoint.sh + +ENTRYPOINT ["/entrypoint.sh"] diff --git a/examples/demo4-ue/src/demo-server/backend/README.md b/examples/demo4-ue/src/demo-server/backend/README.md new file mode 100644 index 000000000..ba5768d09 --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/README.md @@ -0,0 +1,90 @@ +# Go API client for swagger + +Demo 4 is an edge application that can be used with AdvantEDGE or ETSI MEC Sandbox to demonstrate EU application and MEC016 usage + +## Overview +This API client was generated by the [swagger-codegen](https://github.com/swagger-api/swagger-codegen) project. By using the [swagger-spec](https://github.com/swagger-api/swagger-spec) from a remote server, you can easily generate an API client. + +- API version: 0.0.1 +- Package version: 1.0.0 +- Build package: io.swagger.codegen.v3.generators.go.GoClientCodegen + +## Installation +Put the package under your project folder and add the following in import: +```golang +import "./swagger" +``` + +## Documentation for API Endpoints + +All URIs are relative to *http://10.190.115.162:8094* + +Class | Method | HTTP request | Description +------------ | ------------- | ------------- | ------------- +*DAIApi* | [**DaiAppListGET**](docs/DAIApi.md#daiapplistget) | **Get** /dai/apps | Returns onboarded-demo4 User Application AppContext +*DAIApi* | [**DaiAppLocationAvailabilityPOST**](docs/DAIApi.md#daiapplocationavailabilitypost) | **Post** /dai/availability/{appcontextid} | Obtain the location constraints for a new application context. +*DAIApi* | [**DaiDoPingDELETE**](docs/DAIApi.md#daidopingdelete) | **Delete** /dai/delete/{appcontextid} | Returns onboarded-demo4 User Application AppContext +*DAIApi* | [**DaiDoPingGET**](docs/DAIApi.md#daidopingget) | **Get** /dai/doping/{appcontextid} | Returns onboarded-demo4 User Application activity +*DAIApi* | [**DaiDoPingPOST**](docs/DAIApi.md#daidopingpost) | **Post** /dai/instantiate | Returns onboarded-demo4 User Application AppContext +*FrontendApi* | [**GetActivityLogs**](docs/FrontendApi.md#getactivitylogs) | **Get** /info/logs | Returns activity logs +*FrontendApi* | [**GetPlatformInfo**](docs/FrontendApi.md#getplatforminfo) | **Get** /info/application | Returns the application dynamic information +*NotificationApi* | [**AppTerminationNotificationCallback**](docs/NotificationApi.md#appterminationnotificationcallback) | **Post** /application/termination | Callback endpoint for MEC011 app-termination notifications +*NotificationApi* | [**ApplicationContextDeleteNotificationCallback**](docs/NotificationApi.md#applicationcontextdeletenotificationcallback) | **Post** /dai/callback/ApplicationContextDeleteNotification | Callback endpoint for MEC016 Notifications +*NotificationApi* | [**ServiceAvailNotificationCallback**](docs/NotificationApi.md#serviceavailnotificationcallback) | **Post** /services/callback/service-availability | Callback endpoint for MEC011 Notifications + +## Documentation For Models + + - [AddressChangeNotification](docs/AddressChangeNotification.md) + - [AppContext](docs/AppContext.md) + - [AppContextAppInfo](docs/AppContextAppInfo.md) + - [AppContextAppInfoUserAppInstanceInfo](docs/AppContextAppInfoUserAppInstanceInfo.md) + - [AppTerminationSubscription](docs/AppTerminationSubscription.md) + - [AppTerminationSubscriptionLinks](docs/AppTerminationSubscriptionLinks.md) + - [ApplicationContextDeleteNotification](docs/ApplicationContextDeleteNotification.md) + - [ApplicationContextState](docs/ApplicationContextState.md) + - [ApplicationContextUpdateNotification](docs/ApplicationContextUpdateNotification.md) + - [ApplicationContextUpdateNotificationUserAppInstanceInfo](docs/ApplicationContextUpdateNotificationUserAppInstanceInfo.md) + - [ApplicationInstance](docs/ApplicationInstance.md) + - [ApplicationInstanceAmsLinkListSubscription](docs/ApplicationInstanceAmsLinkListSubscription.md) + - [ApplicationInstanceAppTerminationSubscription](docs/ApplicationInstanceAppTerminationSubscription.md) + - [ApplicationInstanceDiscoveredServices](docs/ApplicationInstanceDiscoveredServices.md) + - [ApplicationInstanceOfferedService](docs/ApplicationInstanceOfferedService.md) + - [ApplicationInstanceSerAvailabilitySubscription](docs/ApplicationInstanceSerAvailabilitySubscription.md) + - [ApplicationInstanceSubscriptions](docs/ApplicationInstanceSubscriptions.md) + - [ApplicationList](docs/ApplicationList.md) + - [ApplicationListAppInfo](docs/ApplicationListAppInfo.md) + - [ApplicationListAppInfoAppCharcs](docs/ApplicationListAppInfoAppCharcs.md) + - [ApplicationListAppList](docs/ApplicationListAppList.md) + - [ApplicationListVendorSpecificExt](docs/ApplicationListVendorSpecificExt.md) + - [ApplicationLocationAvailability](docs/ApplicationLocationAvailability.md) + - [ApplicationLocationAvailabilityAppInfo](docs/ApplicationLocationAvailabilityAppInfo.md) + - [ApplicationLocationAvailabilityAppInfoAvailableLocations](docs/ApplicationLocationAvailabilityAppInfoAvailableLocations.md) + - [ApplicationLocationAvailabilityNotification](docs/ApplicationLocationAvailabilityNotification.md) + - [AssociateId](docs/AssociateId.md) + - [CommunicationInterface](docs/CommunicationInterface.md) + - [InlineNotification](docs/InlineNotification.md) + - [LinkType](docs/LinkType.md) + - [LocalityType](docs/LocalityType.md) + - [LocationConstraints](docs/LocationConstraints.md) + - [LocationConstraintsCivicAddressElement](docs/LocationConstraintsCivicAddressElement.md) + - [ModelType](docs/ModelType.md) + - [OneOfInlineNotification](docs/OneOfInlineNotification.md) + - [Polygon](docs/Polygon.md) + - [ProblemDetails](docs/ProblemDetails.md) + - [ServiceAvailabilityNotification](docs/ServiceAvailabilityNotification.md) + - [ServiceAvailabilityNotificationServiceReferences](docs/ServiceAvailabilityNotificationServiceReferences.md) + - [ServiceState](docs/ServiceState.md) + - [Subscription](docs/Subscription.md) + - [TimeStamp](docs/TimeStamp.md) + +## Documentation For Authorization + Endpoints do not require authorization. + + +## Author +AdvantEDGE@InterDigital.com +xFlow Research (Pvt.) Inc. +FSCOM + + + diff --git a/examples/demo4-ue/src/demo-server/backend/api/swagger.yaml b/examples/demo4-ue/src/demo-server/backend/api/swagger.yaml new file mode 100644 index 000000000..345ccded7 --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/api/swagger.yaml @@ -0,0 +1,1676 @@ +openapi: 3.0.2 +info: + title: MEC Demo 4 API + description: Demo 4 is an edge application that can be used with AdvantEDGE or ETSI + MEC Sandbox to demonstrate EU application and MEC016 usage + license: + name: Apache 2.0 + url: http://www.apache.org/licenses/LICENSE-2.0 + version: 0.0.1 +servers: +- url: http://10.190.115.162:8094 +paths: + /info/application: + get: + tags: + - frontend + summary: Returns the application dynamic information + description: Returns the application dynamic information + operationId: GetPlatformInfo + responses: + "200": + description: "Upon success, a response body containing the app instance\ + \ info is returned" + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ApplicationInstance' + "400": + description: Bad request. It is used to indicate that incorrect parameters + were passed to the request. + "404": + description: Not found + /info/logs: + get: + tags: + - frontend + summary: Returns activity logs + description: Returns activity logs + operationId: GetActivityLogs + responses: + "200": + description: "Uppon success, a response body containing logs of demo activities\ + \ stored as strings will be returned" + "400": + description: Bad request. It is used to indicate that incorrect parameters + were passed to the request. + "404": + description: Not found + /dai/apps: + get: + tags: + - DAI + summary: Returns onboarded-demo4 User Application AppContext + description: Get available application information + operationId: daiAppListGET + responses: + "200": + description: "Uppon success, a response body containing AppList will be\ + \ returned" + content: + application/json: + schema: + $ref: '#/components/schemas/ApplicationList' + "400": + description: Bad request. It is used to indicate that incorrect parameters + were passed to the request. + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ProblemDetails' + "404": + description: Not found + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ProblemDetails' + /dai/instantiate: + post: + tags: + - DAI + summary: Returns onboarded-demo4 User Application AppContext + description: Instanciate the onboarded-demo4 User Application + operationId: daiDoPingPOST + responses: + "201": + description: "Uppon success, a response body containing AppContext will\ + \ be returned" + content: + application/json: + schema: + $ref: '#/components/schemas/AppContext' + "400": + description: Bad request. It is used to indicate that incorrect parameters + were passed to the request. + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ProblemDetails' + "404": + description: Not found + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ProblemDetails' + /dai/delete/{appcontextid}: + delete: + tags: + - DAI + summary: Returns onboarded-demo4 User Application AppContext + description: Delete the onboarded-demo4 User Application + operationId: daiDoPingDELETE + responses: + "204": + description: "Uppon success, No Content will be returned" + "400": + description: Bad request. It is used to indicate that incorrect parameters + were passed to the request. + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ProblemDetails' + "404": + description: Not found + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ProblemDetails' + /dai/doping/{appcontextid}: + get: + tags: + - DAI + summary: Returns onboarded-demo4 User Application activity + description: Send a ping to the onboarded-demo4 User Application + operationId: daiDoPingGET + responses: + "200": + description: "Uppon success, a response body containing pong will be returned" + "400": + description: Bad request. It is used to indicate that incorrect parameters + were passed to the request. + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ProblemDetails' + "404": + description: Not found + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ProblemDetails' + /dai/availability/{appcontextid}: + post: + tags: + - DAI + summary: Obtain the location constraints for a new application context. + description: Used to obtain the locations available for instantiation of a specific + user application in the MEC system. + operationId: daiAppLocationAvailabilityPOST + responses: + "200": + description: "Uppon success, a response body containing pong will be returned" + content: + application/json: + schema: + $ref: '#/components/schemas/AppLocationAvailability' + "400": + description: Bad request. It is used to indicate that incorrect parameters + were passed to the request. + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ProblemDetails' + "404": + description: Not found + content: + application/problem+json: + schema: + $ref: '#/components/schemas/ProblemDetails' + /dai/callback/ApplicationContextDeleteNotification: + post: + tags: + - notification + summary: Callback endpoint for MEC016 Notifications + description: Callback endpoint for MEC016 Notifications + operationId: ApplicationContextDeleteNotificationCallback + requestBody: + description: MEC application termination + content: + application/json: + schema: + $ref: '#/components/schemas/ApplicationContextDeleteNotification' + required: true + responses: + "200": + description: OK + "400": + description: Bad request + "404": + description: Not found + /services/callback/service-availability: + post: + tags: + - notification + summary: Callback endpoint for MEC011 Notifications + description: Callback endpoint for MEC011 Notifications + operationId: ServiceAvailNotificationCallback + requestBody: + description: service availability notification details + content: + application/json: + schema: + $ref: '#/components/schemas/ServiceAvailabilityNotification' + required: true + responses: + "200": + description: OK + "400": + description: Bad request + "404": + description: Not found + /application/termination: + post: + tags: + - notification + summary: Callback endpoint for MEC011 app-termination notifications + description: Callback endpoint for MEC011 app-termination notifications + operationId: AppTerminationNotificationCallback + requestBody: + description: app termination notification details + content: + application/json: + schema: + $ref: '#/components/schemas/AppTerminationSubscription' + required: true + responses: + "200": + description: OK + "400": + description: Bad request + "404": + description: Not found +components: + schemas: + ApplicationInstance: + type: object + properties: + name: + type: string + example: MEP Name + url: + type: string + config: + type: string + example: app_instance1.yaml + ip: + type: string + example: + id: + type: string + mecReady: + type: boolean + description: Confirm if app instance is ready + mecTerminated: + type: boolean + description: Confirm the application level termination of application instance + amsResource: + type: boolean + description: Confirm if app instance has an ams service resource + subscriptions: + $ref: '#/components/schemas/ApplicationInstance_subscriptions' + offeredService: + $ref: '#/components/schemas/ApplicationInstance_offeredService' + discoveredServices: + type: array + items: + $ref: '#/components/schemas/ApplicationInstance_discoveredServices' + description: This type represent information to display on frontend app instance + text field + example: + mecReady: true + subscriptions: + 'SerAvailabilitySubscription:': + subId: subId + AmsLinkListSubscription: + subId: subId + associateId: + - type: 0 + value: value + - type: 0 + value: value + AppTerminationSubscription: + subId: subId + amsResource: true + ip: + name: MEP Name + id: id + discoveredServices: + - link: link + serName: null + consumedLocalOnly: true + version: version + serInstanceId: serInstanceId + - link: link + serName: null + consumedLocalOnly: true + version: version + serInstanceId: serInstanceId + config: app_instance1.yaml + offeredService: + scopeOfLocality: MEC_SYSTEM + serName: serName + id: id + state: ACTIVE + consumedLocalOnly: true + url: url + mecTerminated: true + ApplicationInstance_AppTerminationSubscription: + type: object + properties: + subId: + type: string + description: This type represents the information that the MEC platform notifies + the subscribed application instance about the corresponding application instance + termination/stop. + example: + subId: subId + ApplicationInstance_SerAvailabilitySubscription: + type: object + properties: + subId: + type: string + description: This type represents a subscription to the notifications from the + MEC platform regarding the availability of a MEC service or a list of MEC + services. + example: + subId: subId + ApplicationInstance_AmsLinkListSubscription: + type: object + properties: + subId: + type: string + associateId: + minItems: 0 + type: array + description: 0 to N identifiers to associate the information for specific + UE(s) and flow(s). + items: + $ref: '#/components/schemas/AssociateId' + description: This type represents the information that the MEC platform notifies + the subscribed application instance about app mobility support + example: + subId: subId + associateId: + - type: 0 + value: value + - type: 0 + value: value + ApplicationInstance_subscriptions: + type: object + properties: + AppTerminationSubscription: + $ref: '#/components/schemas/ApplicationInstance_AppTerminationSubscription' + 'SerAvailabilitySubscription:': + $ref: '#/components/schemas/ApplicationInstance_SerAvailabilitySubscription' + AmsLinkListSubscription: + $ref: '#/components/schemas/ApplicationInstance_AmsLinkListSubscription' + description: List of ams subscription unique to device and their id + example: + 'SerAvailabilitySubscription:': + subId: subId + AmsLinkListSubscription: + subId: subId + associateId: + - type: 0 + value: value + - type: 0 + value: value + AppTerminationSubscription: + subId: subId + ApplicationInstance_offeredService: + type: object + properties: + serName: + type: string + description: The name of the service. This is how the service producing + MEC application identifies the service instance it produces. + id: + type: string + state: + $ref: '#/components/schemas/ServiceState' + scopeOfLocality: + $ref: '#/components/schemas/LocalityType' + consumedLocalOnly: + type: boolean + description: Indicate whether the service can only be consumed by the MEC + applications located in the same locality (as defined by scopeOfLocality) + as this service instance. + description: service offering + example: + scopeOfLocality: MEC_SYSTEM + serName: serName + id: id + state: ACTIVE + consumedLocalOnly: true + ApplicationInstance_discoveredServices: + type: object + properties: + serName: + type: string + description: The name of the service. This is how the service producing + MEC application identifies the service instance it produces. + serInstanceId: + type: string + description: Identifier of the service instance assigned by the MEC platform. + readOnly: true + consumedLocalOnly: + type: boolean + description: Indicate whether the service can only be consumed by the MEC + applications located in the same locality (as defined by scopeOfLocality) + as this service instance. + link: + type: string + version: + type: string + description: Service version + description: List of service name and their status + example: + link: link + serName: null + consumedLocalOnly: true + version: version + serInstanceId: serInstanceId + ApplicationContextState: + type: object + properties: + Counter: + type: integer + description: Integer representing state of device being tracked + AppId: + type: string + description: Application UUID + Mep: + type: string + description: MEC platform name + Device: + type: string + description: Terminal device application is tracking + LocalityType: + type: string + description: "The scope of locality as expressed by \"consumedLocalOnly\" and\ + \ \"isLocal\". If absent, defaults to MEC_HOST" + enum: + - MEC_SYSTEM + - MEC_HOST + - NFVI_POP + - ZONE + - ZONE_GROUP + - NFVI_NODE + ServiceAvailabilityNotification: + required: + - _links + - notificationType + - serviceReferences + type: object + properties: + notificationType: + type: string + description: Shall be set to SerAvailabilityNotification + example: SerAvailabilityNotification + serviceReferences: + type: array + items: + $ref: '#/components/schemas/ServiceAvailabilityNotification_serviceReferences' + _links: + $ref: '#/components/schemas/Subscription' + description: This type represents the service availability information. + AppTerminationSubscription: + required: + - _links + - appInstanceId + - callbackReference + - subscriptionType + type: object + properties: + subscriptionType: + type: string + description: Shall be set to AppTerminationSubscription. + callbackReference: + type: string + description: URI selected by the MEC application instance to receive notifications + on the subscribed MEC application instance management information. This + shall be included in both the request and the response. + format: uri + _links: + $ref: '#/components/schemas/AppTerminationSubscription__links' + appInstanceId: + type: string + description: It is used as the filtering criterion for the subscribed events. + description: This type represents the information that the MEC platform notifies + the subscribed application instance about the corresponding application instance + termination/stop. + example: + appInstanceId: appInstanceId + subscriptionType: subscriptionType + _links: + self: + href: http://example.com/aeiou + callbackReference: http://example.com/aeiou + TimeStamp: + required: + - nanoSeconds + - seconds + type: object + properties: + nanoSeconds: + type: integer + description: "The nanoseconds part of the time. Time is defined as Unix-time\ + \ since January 1, 1970, 00:00:00 UTC." + format: int32 + x-etsi-mec-cardinality: "1" + x-etsi-mec-origin-type: Uint32 + seconds: + type: integer + description: "The seconds part of the time. Time is defined as Unixtime\ + \ since January 1, 1970, 00:00:00 UTC." + format: int32 + x-etsi-mec-cardinality: "1" + x-etsi-mec-origin-type: Uint32 + CommunicationInterface: + properties: + ipAddresses: + type: string + AssociateId: + title: AssociateId + required: + - type + - value + type: object + properties: + type: + $ref: '#/components/schemas/Type' + value: + type: string + description: Value for the identifier. + example: + type: UE_IPv4_ADDRESS + value: value + Type: + title: Type + type: string + description: Numeric value (0-255) corresponding to specified type of identifier + enum: + - UE_IPv4_ADDRESS + - UE_IPV6_ADDRESS + - NATED_IP_ADDRESS + - GTP_TEID + AppTerminationSubscription__links: + required: + - self + type: object + properties: + self: + $ref: '#/components/schemas/LinkType' + description: Self-referring URI. + example: + self: + href: http://example.com/aeiou + LinkType: + type: object + properties: + href: + type: string + description: URI referring to a resource + format: uri + example: /mecSerMgmtApi/example + description: This type represents a type of link and may be referenced from + data structures + SerName: + type: string + description: The name of the service. This is how the service producing MEC + application identifies the service instance it produces. + SerInstanceId: + type: string + description: Identifier of the service instance assigned by the MEC platform. + readOnly: true + ServiceState: + type: string + description: This enumeration defines the possible states of a service. + enum: + - ACTIVE + - INACTIVE + Subscription: + required: + - subscription + type: object + properties: + subscription: + $ref: '#/components/schemas/LinkType' + description: A link to the related subscription + ServiceAvailabilityNotification_serviceReferences: + required: + - changeType + - serInstanceId + - serName + - state + type: object + properties: + link: + $ref: '#/components/schemas/LinkType' + serName: + type: string + description: The name of the service. This is how the service producing + MEC application identifies the service instance it produces. + state: + $ref: '#/components/schemas/ServiceState' + changeType: + type: string + description: "Type of the change. Valid values:\n ADDED: The service was\ + \ newly added.\n REMOVED: The service was removed.\n STATE_CHANGED:\ + \ Only the state of the service was changed. \n ATTRIBUTES_CHANGED: At\ + \ least one attribute of the service other than state was changed. The\ + \ change may or may not include changing the state." + enum: + - ADDED + - REMOVED + - STATE_CHANGED + - ATTRIBUTES_CHANGED + description: List of links to services whose availability has changed. + AddressChangeNotification: + required: + - appInstanceId + - contextId + - notificationType + - referenceURI + type: object + properties: + appInstanceId: + type: string + description: Identifier of the user application instance. + x-etsi-mec-cardinality: "1" + x-etsi-mec-origin-type: String + contextId: + type: string + description: Uniquely identifies the application context in the MEC system. + x-etsi-mec-cardinality: "1" + x-etsi-mec-origin-type: String + notificationType: + type: string + description: Shall be set to "AddressChangeNotification". + x-etsi-mec-cardinality: "1" + x-etsi-mec-origin-type: String + referenceURI: + type: string + description: Address of the user application. Used as the reference URI + for the application. Assigned by the MEC system. + format: uri + x-etsi-mec-cardinality: "1" + x-etsi-mec-origin-type: URI + x-etsi-ref: 6.4.2 + AppContext: + required: + - appInfo + - associateDevAppId + type: object + properties: + appAutoInstantiation: + type: boolean + description: Provides indication to the MEC system that instantiation of + the requested application is desired should a requested appLocation become + available that was not at the time of the request. + x-etsi-mec-cardinality: 0..1 + x-etsi-mec-origin-type: Boolean + appInfo: + $ref: '#/components/schemas/AppContext_appInfo' + appLocationUpdates: + type: boolean + description: Used by the device application to request to receive notifications + at the callbackReference URI relating to location availability for user + application instantiation. + x-etsi-mec-cardinality: 0..1 + x-etsi-mec-origin-type: Boolean + associateDevAppId: + maxLength: 32 + type: string + description: Uniquely identifies the device application. The length of the + value shall not exceed 32 characters. + x-etsi-mec-cardinality: "1" + x-etsi-mec-origin-type: String + callbackReference: + type: string + description: URI assigned by the device application to receive application + lifecycle related notifications. Inclusion in the request implies the + client supports the pub/sub mechanism and is capable of receiving notifications. + This endpoint shall be maintained for the lifetime of the application + context. + format: uri + x-etsi-mec-cardinality: 0..1 + x-etsi-mec-origin-type: URI + contextId: + maxLength: 32 + type: string + description: Uniquely identifies the application context in the MEC system. + Assigned by the MEC system and shall be present other than in a create + request. The length of the value shall not exceed 32 characters. + x-etsi-mec-cardinality: 0..1 + x-etsi-mec-origin-type: String + example: + callbackReference: http://example.com/aeiou + appInfo: + appSoftVersion: appSoftVersion + appDVersion: appDVersion + appPackageSource: http://example.com/aeiou + appName: appName + appDescription: appDescription + userAppInstanceInfo: + - appInstanceId: appInstanceId + appLocation: + area: + coordinates: + - - - 2.302136 + - 2.302136 + - - 2.302136 + - 2.302136 + - - - 2.302136 + - 2.302136 + - - 2.302136 + - 2.302136 + countryCode: countryCode + civicAddressElement: + - caType: 7 + caValue: caValue + - caType: 7 + caValue: caValue + referenceURI: http://example.com/aeiou + - appInstanceId: appInstanceId + appLocation: + area: + coordinates: + - - - 2.302136 + - 2.302136 + - - 2.302136 + - 2.302136 + - - - 2.302136 + - 2.302136 + - - 2.302136 + - 2.302136 + countryCode: countryCode + civicAddressElement: + - caType: 7 + caValue: caValue + - caType: 7 + caValue: caValue + referenceURI: http://example.com/aeiou + appDId: appDId + appProvider: appProvider + associateDevAppId: associateDevAppId + contextId: contextId + appLocationUpdates: true + appAutoInstantiation: true + x-etsi-notes: "NOTE 1:\tIf a value of the attribute is included in the request,\ + \ the same value shall be included in the response.\nNOTE 2:\tThe design of\ + \ the current operation with callback reference assumes no web proxy between\ + \ the entity that originates the notification and the entity that receives\ + \ it.\nNOTE 3:\tThe language support for the application description may be\ + \ limited.\nNOTE 4:\tAttribute appLocationUpdates and appAutoInstantiation\ + \ shall not both be set to TRUE." + x-etsi-ref: 6.2.3 + ApplicationContextDeleteNotification: + required: + - contextId + - notificationType + type: object + properties: + contextId: + type: string + description: Uniquely identifies the application context that has been deleted + from the MEC system. + x-etsi-mec-cardinality: "1" + x-etsi-mec-origin-type: String + notificationType: + type: string + description: Shall be set to "ApplicationContextDeleteNotification". + x-etsi-mec-cardinality: "1" + x-etsi-mec-origin-type: String + x-etsi-ref: 6.4.3 + ApplicationContextUpdateNotification: + required: + - contextId + - notificationType + - userAppInstanceInfo + type: object + properties: + contextId: + type: string + description: Uniquely identifies the application context in the MEC system. + x-etsi-mec-cardinality: "1" + x-etsi-mec-origin-type: String + notificationType: + type: string + description: Shall be set to "ApplicationContextUpdateNotification". + x-etsi-mec-cardinality: "1" + x-etsi-mec-origin-type: String + userAppInstanceInfo: + minItems: 1 + required: + - appInstanceId + - referenceURI + type: array + description: List of user application instance information. + items: + $ref: '#/components/schemas/ApplicationContextUpdateNotification_userAppInstanceInfo' + x-etsi-mec-cardinality: 1..N + x-etsi-mec-origin-type: array (Structure inlined) + x-etsi-ref: 6.4.4 + ApplicationList: + type: object + properties: + appList: + minItems: 0 + required: + - appInfo + type: array + description: List of user applications available to the device application. + As defined below. + items: + $ref: '#/components/schemas/ApplicationList_appList' + x-etsi-mec-cardinality: 0..N + x-etsi-mec-origin-type: Array (Structure (inlined)) + example: + appList: + - appInfo: + appCharcs: + serviceCont: 5 + memory: 1 + bandwidth: 0 + latency: 6 + storage: 5 + appSoftVersion: appSoftVersion + appDVersion: appDVersion + appLocation: + - area: + coordinates: + - - - 2.302136 + - 2.302136 + - - 2.302136 + - 2.302136 + - - - 2.302136 + - 2.302136 + - - 2.302136 + - 2.302136 + countryCode: countryCode + civicAddressElement: + - caType: 7 + caValue: caValue + - caType: 7 + caValue: caValue + - area: + coordinates: + - - - 2.302136 + - 2.302136 + - - 2.302136 + - 2.302136 + - - - 2.302136 + - 2.302136 + - - 2.302136 + - 2.302136 + countryCode: countryCode + civicAddressElement: + - caType: 7 + caValue: caValue + - caType: 7 + caValue: caValue + appName: appName + appDescription: appDescription + appDId: appDId + appProvider: appProvider + vendorSpecificExt: + vendorId: vendorId + - appInfo: + appCharcs: + serviceCont: 5 + memory: 1 + bandwidth: 0 + latency: 6 + storage: 5 + appSoftVersion: appSoftVersion + appDVersion: appDVersion + appLocation: + - area: + coordinates: + - - - 2.302136 + - 2.302136 + - - 2.302136 + - 2.302136 + - - - 2.302136 + - 2.302136 + - - 2.302136 + - 2.302136 + countryCode: countryCode + civicAddressElement: + - caType: 7 + caValue: caValue + - caType: 7 + caValue: caValue + - area: + coordinates: + - - - 2.302136 + - 2.302136 + - - 2.302136 + - 2.302136 + - - - 2.302136 + - 2.302136 + - - 2.302136 + - 2.302136 + countryCode: countryCode + civicAddressElement: + - caType: 7 + caValue: caValue + - caType: 7 + caValue: caValue + appName: appName + appDescription: appDescription + appDId: appDId + appProvider: appProvider + vendorSpecificExt: + vendorId: vendorId + x-etsi-notes: "NOTE 1:\tThe vendor specific extension allows submitting information\ + \ on the application lists that have been made available to the device application\ + \ of the corresponding vendor.\nNOTE 2:\tThe language support may be limited.\ + \ The length of the value shall not exceed 128 characters." + x-etsi-ref: 6.2.2 + ApplicationLocationAvailability: + required: + - appInfo + - associateDevAppId + type: object + properties: + appInfo: + $ref: '#/components/schemas/ApplicationLocationAvailability_appInfo' + associateDevAppId: + maxLength: 32 + type: string + description: Uniquely identifies the device application. The length of the + value shall not exceed 32 characters. + x-etsi-mec-cardinality: "1" + x-etsi-mec-origin-type: String + example: + appInfo: + appSoftVersion: appSoftVersion + appDVersion: appDVersion + appPackageSource: http://example.com/aeiou + appName: appName + appDescription: appDescription + appProvider: appProvider + availableLocations: + - appLocation: + area: + coordinates: + - - - 2.302136 + - 2.302136 + - - 2.302136 + - 2.302136 + - - - 2.302136 + - 2.302136 + - - 2.302136 + - 2.302136 + countryCode: countryCode + civicAddressElement: + - caType: 7 + caValue: caValue + - caType: 7 + caValue: caValue + - appLocation: + area: + coordinates: + - - - 2.302136 + - 2.302136 + - - 2.302136 + - 2.302136 + - - - 2.302136 + - 2.302136 + - - 2.302136 + - 2.302136 + countryCode: countryCode + civicAddressElement: + - caType: 7 + caValue: caValue + - caType: 7 + caValue: caValue + associateDevAppId: associateDevAppId + x-etsi-ref: 6.2.4 + ApplicationLocationAvailabilityNotification: + required: + - availableLocations + - notificationType + type: object + properties: + availableLocations: + minItems: 1 + required: + - appLocation + type: array + description: Locations available to the MEC application. + items: + $ref: '#/components/schemas/ApplicationLocationAvailability_appInfo_availableLocations' + x-etsi-mec-cardinality: 1..N + x-etsi-mec-origin-type: array (Structure (inline)) + contextId: + type: string + description: Uniquely identifies the application context in the MEC system. + x-etsi-mec-cardinality: 0..1 + x-etsi-mec-origin-type: String + notificationType: + type: string + description: Shall be set to "ApplicationLocationAvailabilityNotification". + x-etsi-mec-cardinality: "1" + x-etsi-mec-origin-type: String + x-etsi-ref: 6.4.5 + InlineNotification: + discriminator: + propertyName: NotificationType + oneOf: + - $ref: '#/components/schemas/AddressChangeNotification' + - $ref: '#/components/schemas/ApplicationContextDeleteNotification' + - $ref: '#/components/schemas/ApplicationContextUpdateNotification' + - $ref: '#/components/schemas/ApplicationLocationAvailabilityNotification' + LocationConstraints: + type: object + properties: + area: + $ref: '#/components/schemas/Polygon' + civicAddressElement: + minItems: 0 + required: + - caType + - caValue + type: array + description: Zero or more elements comprising the civic address. Shall be + absent if the "area" attribute is present. + items: + $ref: '#/components/schemas/LocationConstraints_civicAddressElement' + x-etsi-mec-cardinality: 0..N + x-etsi-mec-origin-type: array (Structure inlined) + countryCode: + maxLength: 2 + type: string + description: "The two-letter ISO 3166 [7] country code in capital letters.\ + \ Shall be present in case the \"area\" attribute is absent. May be absent\ + \ if the \"area\" attribute is present (see note)." + x-etsi-mec-cardinality: 0..1 + x-etsi-mec-origin-type: String + example: + area: + coordinates: + - - - 2.302136 + - 2.302136 + - - 2.302136 + - 2.302136 + - - - 2.302136 + - 2.302136 + - - 2.302136 + - 2.302136 + countryCode: countryCode + civicAddressElement: + - caType: 7 + caValue: caValue + - caType: 7 + caValue: caValue + x-etsi-notes: "NOTE:\tIf both \"countryCode\" and \"area\" are present, no conflicts\ + \ should exist between the values of these two attributes. In case of conflicts,\ + \ the API producer (e.g. MEO, MEAO) shall disregard parts of the geographic\ + \ area signalled by \"area\" that are outside the boundaries of the country\ + \ signalled by \"countryCode\". If \"countryCode\" is absent, it is solely\ + \ the \"area\" attribute that defines the location constraint." + x-etsi-ref: 6.5.2 + Polygon: + type: object + properties: + coordinates: + minItems: 1 + type: array + items: + type: array + items: + type: array + items: + type: number + format: float + x-etsi-mec-cardinality: 1 + x-etsi-mec-origin-type: array + example: + coordinates: + - - - 2.302136 + - 2.302136 + - - 2.302136 + - 2.302136 + - - - 2.302136 + - 2.302136 + - - 2.302136 + - 2.302136 + ProblemDetails: + type: object + properties: + detail: + type: string + description: A human-readable explanation specific to this occurrence of + the problem + x-etsi-mec-cardinality: 0..1 + x-etsi-mec-origin-type: String + instance: + type: string + description: A URI reference that identifies the specific occurrence of + the problem + format: uri + x-etsi-mec-cardinality: 0..1 + x-etsi-mec-origin-type: URI + status: + type: integer + description: The HTTP status code for this occurrence of the problem + format: uint32 + x-etsi-mec-cardinality: 0..1 + x-etsi-mec-origin-type: Uint32 + title: + type: string + description: "A short, human-readable summary of the problem type" + x-etsi-mec-cardinality: 0..1 + x-etsi-mec-origin-type: String + type: + type: string + description: A URI reference according to IETF RFC 3986 that identifies + the problem type + format: uri + x-etsi-mec-cardinality: 0..1 + x-etsi-mec-origin-type: URI + AppContext_appInfo_userAppInstanceInfo: + type: object + properties: + appInstanceId: + type: string + description: Identifier of the user application instance. It shall only + be included in the response. + x-etsi-mec-cardinality: 0..1 + x-etsi-mec-origin-type: String + appLocation: + $ref: '#/components/schemas/LocationConstraints' + referenceURI: + type: string + description: Address of the user application instance. It shall only be + included in the response. + format: uri + x-etsi-mec-cardinality: 0..1 + x-etsi-mec-origin-type: URI + example: + appInstanceId: appInstanceId + appLocation: + area: + coordinates: + - - - 2.302136 + - 2.302136 + - - 2.302136 + - 2.302136 + - - - 2.302136 + - 2.302136 + - - 2.302136 + - 2.302136 + countryCode: countryCode + civicAddressElement: + - caType: 7 + caValue: caValue + - caType: 7 + caValue: caValue + referenceURI: http://example.com/aeiou + AppContext_appInfo: + required: + - appDVersion + - appName + - appProvider + - userAppInstanceInfo + type: object + properties: + appDId: + type: string + description: "Identifier of this MEC application descriptor. This attribute\ + \ shall be globally unique. It is equivalent to the appDId defined in\ + \ clause 6.2.1.2 of ETSI GS MEC 0102 [1]. It shall be present if the application\ + \ is one in the ApplicationList." + x-etsi-mec-cardinality: 0..1 + x-etsi-mec-origin-type: String + appDVersion: + type: string + description: "Identifies the version of the application descriptor. It is\ + \ equivalent to the appDVersion defined in clause 6.2.1.2 of ETSI GS MEC\ + \ 0102 [1]." + x-etsi-mec-cardinality: "1" + x-etsi-mec-origin-type: String + appDescription: + maxLength: 128 + type: string + description: Human readable description of the MEC application. The length + of the value shall not exceed 128 characters. + x-etsi-mec-cardinality: 0..1 + x-etsi-mec-origin-type: String + appName: + maxLength: 32 + type: string + description: Name of the MEC application. The length of the value shall + not exceed 32 characters. + x-etsi-mec-cardinality: "1" + x-etsi-mec-origin-type: String + appProvider: + maxLength: 32 + type: string + description: |- + Provider of the MEC application. + The length of the value shall not exceed 32 characters. + x-etsi-mec-cardinality: "1" + x-etsi-mec-origin-type: String + appSoftVersion: + maxLength: 32 + type: string + description: Software version of the MEC application. The length of the + value shall not exceed 32 characters. + x-etsi-mec-cardinality: 0..1 + x-etsi-mec-origin-type: String + appPackageSource: + type: string + description: "URI of the application package.\nIncluded in the request if\ + \ the application is not one in the ApplicationList. appPackageSource\ + \ enables on-boarding of the application package into the MEC system.\ + \ The application package shall comply with the definitions in clause\ + \ 6.2.1.2 of ETSI GS MEC 0102 [1]." + format: uri + x-etsi-mec-cardinality: 0..1 + x-etsi-mec-origin-type: URI + userAppInstanceInfo: + minItems: 1 + type: array + description: List of user application instance information. + items: + $ref: '#/components/schemas/AppContext_appInfo_userAppInstanceInfo' + x-etsi-mec-cardinality: 1..N + x-etsi-mec-origin-type: array (Structure inlined) + example: + appSoftVersion: appSoftVersion + appDVersion: appDVersion + appPackageSource: http://example.com/aeiou + appName: appName + appDescription: appDescription + userAppInstanceInfo: + - appInstanceId: appInstanceId + appLocation: + area: + coordinates: + - - - 2.302136 + - 2.302136 + - - 2.302136 + - 2.302136 + - - - 2.302136 + - 2.302136 + - - 2.302136 + - 2.302136 + countryCode: countryCode + civicAddressElement: + - caType: 7 + caValue: caValue + - caType: 7 + caValue: caValue + referenceURI: http://example.com/aeiou + - appInstanceId: appInstanceId + appLocation: + area: + coordinates: + - - - 2.302136 + - 2.302136 + - - 2.302136 + - 2.302136 + - - - 2.302136 + - 2.302136 + - - 2.302136 + - 2.302136 + countryCode: countryCode + civicAddressElement: + - caType: 7 + caValue: caValue + - caType: 7 + caValue: caValue + referenceURI: http://example.com/aeiou + appDId: appDId + appProvider: appProvider + ApplicationContextUpdateNotification_userAppInstanceInfo: + type: object + properties: + appInstanceId: + type: string + description: Identifier of the user application instance. + x-etsi-mec-cardinality: "1" + x-etsi-mec-origin-type: String + appLocation: + $ref: '#/components/schemas/LocationConstraints' + referenceURI: + type: string + description: Address of the user application instance. + format: uri + x-etsi-mec-cardinality: "1" + x-etsi-mec-origin-type: URI + ApplicationList_appInfo_appCharcs: + type: object + properties: + bandwidth: + type: integer + description: 'The required connection bandwidth in kbit/s for the use of + the MEC application instance. ' + format: uint32 + x-etsi-mec-cardinality: 0..1 + x-etsi-mec-origin-type: uint32 + latency: + type: integer + description: The target round trip time in milliseconds supported by the + MEC system for the MEC application instance. + format: uint32 + x-etsi-mec-cardinality: 0..1 + x-etsi-mec-origin-type: uint32 + memory: + type: integer + description: The maximum size in Mbytes of the memory resource expected + to be used by the MEC application instance in the MEC system. + format: uint32 + x-etsi-mec-cardinality: 0..1 + x-etsi-mec-origin-type: uint32 + serviceCont: + type: integer + description: "Required service continuity mode for this application. Permitted\ + \ values: 0 = SERVICE_CONTINUITY_NOT_REQUIRED. 1 = SERVICE_CONTINUITY_REQUIRED." + enum: + - 0 + - 1 + x-etsi-mec-cardinality: 0..1 + x-etsi-mec-origin-type: Enum + storage: + type: integer + description: The maximum size in Mbytes of the storage resource expected + to be used by the MEC application instance in the MEC system. + format: uint32 + x-etsi-mec-cardinality: 0..1 + x-etsi-mec-origin-type: uint32 + description: Characteristics of the application. As defined below. The application + characteristics relate to the system resources consumed by the application. + A device application can use this information e.g. for estimating the cost + of use of the application or for the expected user experience. + example: + serviceCont: 5 + memory: 1 + bandwidth: 0 + latency: 6 + storage: 5 + ApplicationList_appInfo: + required: + - appDId + - appDVersion + - appDescription + - appName + - appProvider + - appSoftVersion + type: object + properties: + appCharcs: + $ref: '#/components/schemas/ApplicationList_appInfo_appCharcs' + appDId: + type: string + description: "Identifier of this MEC application descriptor. It is equivalent\ + \ to the appDId defined in clause 6.2.1.2 of ETSI GS MEC 0102 [1]. This\ + \ attribute shall be globally unique." + x-etsi-mec-cardinality: "1" + x-etsi-mec-origin-type: String + appDVersion: + type: string + description: "Identifies the version of the application descriptor. It is\ + \ equivalent to the appDVersion defined in clause 6.2.1.2 of ETSI GS MEC\ + \ 0102 [1]." + x-etsi-mec-cardinality: "1" + x-etsi-mec-origin-type: String + appDescription: + maxLength: 128 + type: string + description: Human readable description of the MEC application (see note + 2). + x-etsi-mec-cardinality: "1" + x-etsi-mec-origin-type: String + appLocation: + minItems: 0 + type: array + description: Identifies the locations of the MEC application. + items: + $ref: '#/components/schemas/LocationConstraints' + x-etsi-mec-cardinality: 0..N + x-etsi-mec-origin-type: LocationConstraints + appName: + maxLength: 32 + type: string + description: Name of the MEC application. The length of the value shall + not exceed 32 characters. + x-etsi-mec-cardinality: "1" + x-etsi-mec-origin-type: String + appProvider: + maxLength: 32 + type: string + description: Provider of the MEC application. The length of the value shall + not exceed 32 characters. + x-etsi-mec-cardinality: "1" + x-etsi-mec-origin-type: String + appSoftVersion: + maxLength: 32 + type: string + description: Software version of the MEC application. The length of the + value shall not exceed 32 characters. + x-etsi-mec-cardinality: "1" + x-etsi-mec-origin-type: String + example: + appCharcs: + serviceCont: 5 + memory: 1 + bandwidth: 0 + latency: 6 + storage: 5 + appSoftVersion: appSoftVersion + appDVersion: appDVersion + appLocation: + - area: + coordinates: + - - - 2.302136 + - 2.302136 + - - 2.302136 + - 2.302136 + - - - 2.302136 + - 2.302136 + - - 2.302136 + - 2.302136 + countryCode: countryCode + civicAddressElement: + - caType: 7 + caValue: caValue + - caType: 7 + caValue: caValue + - area: + coordinates: + - - - 2.302136 + - 2.302136 + - - 2.302136 + - 2.302136 + - - - 2.302136 + - 2.302136 + - - 2.302136 + - 2.302136 + countryCode: countryCode + civicAddressElement: + - caType: 7 + caValue: caValue + - caType: 7 + caValue: caValue + appName: appName + appDescription: appDescription + appDId: appDId + appProvider: appProvider + ApplicationList_vendorSpecificExt: + required: + - vendorId + type: object + properties: + vendorId: + maxLength: 32 + type: string + description: Vendor identifier. The length of the value shall not exceed + 32 characters. The rest of the structure of vendor specific extension + is not defined. + x-etsi-mec-cardinality: "1" + x-etsi-mec-origin-type: String + description: Extension for vendor specific information (see note 1). + example: + vendorId: vendorId + ApplicationList_appList: + type: object + properties: + appInfo: + $ref: '#/components/schemas/ApplicationList_appInfo' + vendorSpecificExt: + $ref: '#/components/schemas/ApplicationList_vendorSpecificExt' + example: + appInfo: + appCharcs: + serviceCont: 5 + memory: 1 + bandwidth: 0 + latency: 6 + storage: 5 + appSoftVersion: appSoftVersion + appDVersion: appDVersion + appLocation: + - area: + coordinates: + - - - 2.302136 + - 2.302136 + - - 2.302136 + - 2.302136 + - - - 2.302136 + - 2.302136 + - - 2.302136 + - 2.302136 + countryCode: countryCode + civicAddressElement: + - caType: 7 + caValue: caValue + - caType: 7 + caValue: caValue + - area: + coordinates: + - - - 2.302136 + - 2.302136 + - - 2.302136 + - 2.302136 + - - - 2.302136 + - 2.302136 + - - 2.302136 + - 2.302136 + countryCode: countryCode + civicAddressElement: + - caType: 7 + caValue: caValue + - caType: 7 + caValue: caValue + appName: appName + appDescription: appDescription + appDId: appDId + appProvider: appProvider + vendorSpecificExt: + vendorId: vendorId + ApplicationLocationAvailability_appInfo_availableLocations: + type: object + properties: + appLocation: + $ref: '#/components/schemas/LocationConstraints' + example: + appLocation: + area: + coordinates: + - - - 2.302136 + - 2.302136 + - - 2.302136 + - 2.302136 + - - - 2.302136 + - 2.302136 + - - 2.302136 + - 2.302136 + countryCode: countryCode + civicAddressElement: + - caType: 7 + caValue: caValue + - caType: 7 + caValue: caValue + ApplicationLocationAvailability_appInfo: + required: + - appDVersion + - appName + - appProvider + type: object + properties: + appDVersion: + type: string + description: "Identifies the version of the application descriptor. It is\ + \ equivalent to the appDVersion defined in clause 6.2.1.2 of ETSI GS MEC\ + \ 0102 [1]." + x-etsi-mec-cardinality: "1" + x-etsi-mec-origin-type: String + appDescription: + maxLength: 128 + type: string + description: Human readable description of the MEC application. The length + of the value shall not exceed 128 characters. + x-etsi-mec-cardinality: 0..1 + x-etsi-mec-origin-type: String + appName: + maxLength: 32 + type: string + description: Name of the MEC application. The length of the value shall + not exceed 32 characters. + x-etsi-mec-cardinality: "1" + x-etsi-mec-origin-type: String + appPackageSource: + type: string + description: "URI of the application package. Shall be included in the request.\ + \ The application package shall comply with the definitions in clause\ + \ 6.2.1.2 of ETSI GS MEC 0102 [1]." + format: uri + x-etsi-mec-cardinality: 0..1 + x-etsi-mec-origin-type: URI + appProvider: + maxLength: 32 + type: string + description: Provider of the MEC application. The length of the value shall + not exceed 32 characters. + x-etsi-mec-cardinality: "1" + x-etsi-mec-origin-type: String + appSoftVersion: + maxLength: 32 + type: string + description: Software version of the MEC application. The length of the + value shall not exceed 32 characters. + x-etsi-mec-cardinality: 0..1 + x-etsi-mec-origin-type: String + availableLocations: + minItems: 0 + type: array + description: 'MEC application location constraints. ' + items: + $ref: '#/components/schemas/ApplicationLocationAvailability_appInfo_availableLocations' + x-etsi-mec-cardinality: 0..N + x-etsi-mec-origin-type: array (Structure (inline)) + example: + appSoftVersion: appSoftVersion + appDVersion: appDVersion + appPackageSource: http://example.com/aeiou + appName: appName + appDescription: appDescription + appProvider: appProvider + availableLocations: + - appLocation: + area: + coordinates: + - - - 2.302136 + - 2.302136 + - - 2.302136 + - 2.302136 + - - - 2.302136 + - 2.302136 + - - 2.302136 + - 2.302136 + countryCode: countryCode + civicAddressElement: + - caType: 7 + caValue: caValue + - caType: 7 + caValue: caValue + - appLocation: + area: + coordinates: + - - - 2.302136 + - 2.302136 + - - 2.302136 + - 2.302136 + - - - 2.302136 + - 2.302136 + - - 2.302136 + - 2.302136 + countryCode: countryCode + civicAddressElement: + - caType: 7 + caValue: caValue + - caType: 7 + caValue: caValue + LocationConstraints_civicAddressElement: + type: object + properties: + caType: + type: integer + description: "Describe the content type of caValue. The value of caType\ + \ shall comply with section 3.4 of IETF RFC 4776 [6]. " + x-etsi-mec-cardinality: "1" + x-etsi-mec-origin-type: Integer + caValue: + type: string + description: "Content of civic address element corresponding to the caType.\ + \ The format caValue shall comply with section 3.4 of IETF RFC 4776 [6]." + x-etsi-mec-cardinality: "1" + x-etsi-mec-origin-type: String + example: + caType: 7 + caValue: caValue diff --git a/examples/demo4-ue/src/demo-server/backend/build.sh b/examples/demo4-ue/src/demo-server/backend/build.sh new file mode 100644 index 000000000..d11f77bc9 --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/build.sh @@ -0,0 +1,25 @@ +#!/bin/sh + +#set -vx + +# Get full path to script directory +SCRIPT=$(readlink -f "$0") +BASEDIR=$(dirname "$SCRIPT") + +# Create build directory +if [ "$#" -ne 1 ]; then + echo "Missing bin directory" + exit +fi +BINDIR=$1 +mkdir -p $BINDIR $BINDIR/user-api + +# Build demo App server +cd $BASEDIR + +#find . -name "*.go" -type f -exec golangci-lint run {} \; +go build -o $BINDIR/demo-server . + +cp -Rp ./api/ $BINDIR +mv $BINDIR/api/swagger.yaml $BINDIR/api/MEC\ Demo\ 4\ API +cp $BINDIR/api/* $BINDIR/user-api \ No newline at end of file diff --git a/examples/demo4-ue/src/demo-server/backend/docs/AddressChangeNotification.md b/examples/demo4-ue/src/demo-server/backend/docs/AddressChangeNotification.md new file mode 100644 index 000000000..2ffbd0ec0 --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/docs/AddressChangeNotification.md @@ -0,0 +1,12 @@ +# AddressChangeNotification + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**AppInstanceId** | **string** | Identifier of the user application instance. | [default to null] +**ContextId** | **string** | Uniquely identifies the application context in the MEC system. | [default to null] +**NotificationType** | **string** | Shall be set to \"AddressChangeNotification\". | [default to null] +**ReferenceURI** | **string** | Address of the user application. Used as the reference URI for the application. Assigned by the MEC system. | [default to null] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/examples/demo4-ue/src/demo-server/backend/docs/AppContext.md b/examples/demo4-ue/src/demo-server/backend/docs/AppContext.md new file mode 100644 index 000000000..df07f8052 --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/docs/AppContext.md @@ -0,0 +1,14 @@ +# AppContext + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**AppAutoInstantiation** | **bool** | Provides indication to the MEC system that instantiation of the requested application is desired should a requested appLocation become available that was not at the time of the request. | [optional] [default to null] +**AppInfo** | [***AppContextAppInfo**](AppContext_appInfo.md) | | [default to null] +**AppLocationUpdates** | **bool** | Used by the device application to request to receive notifications at the callbackReference URI relating to location availability for user application instantiation. | [optional] [default to null] +**AssociateDevAppId** | **string** | Uniquely identifies the device application. The length of the value shall not exceed 32 characters. | [default to null] +**CallbackReference** | **string** | URI assigned by the device application to receive application lifecycle related notifications. Inclusion in the request implies the client supports the pub/sub mechanism and is capable of receiving notifications. This endpoint shall be maintained for the lifetime of the application context. | [optional] [default to null] +**ContextId** | **string** | Uniquely identifies the application context in the MEC system. Assigned by the MEC system and shall be present other than in a create request. The length of the value shall not exceed 32 characters. | [optional] [default to null] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/examples/demo4-ue/src/demo-server/backend/docs/AppContextAppInfo.md b/examples/demo4-ue/src/demo-server/backend/docs/AppContextAppInfo.md new file mode 100644 index 000000000..1039a8008 --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/docs/AppContextAppInfo.md @@ -0,0 +1,16 @@ +# AppContextAppInfo + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**AppDId** | **string** | Identifier of this MEC application descriptor. This attribute shall be globally unique. It is equivalent to the appDId defined in clause 6.2.1.2 of ETSI GS MEC 0102 [1]. It shall be present if the application is one in the ApplicationList. | [optional] [default to null] +**AppDVersion** | **string** | Identifies the version of the application descriptor. It is equivalent to the appDVersion defined in clause 6.2.1.2 of ETSI GS MEC 0102 [1]. | [default to null] +**AppDescription** | **string** | Human readable description of the MEC application. The length of the value shall not exceed 128 characters. | [optional] [default to null] +**AppName** | **string** | Name of the MEC application. The length of the value shall not exceed 32 characters. | [default to null] +**AppProvider** | **string** | Provider of the MEC application. The length of the value shall not exceed 32 characters. | [default to null] +**AppSoftVersion** | **string** | Software version of the MEC application. The length of the value shall not exceed 32 characters. | [optional] [default to null] +**AppPackageSource** | **string** | URI of the application package. Included in the request if the application is not one in the ApplicationList. appPackageSource enables on-boarding of the application package into the MEC system. The application package shall comply with the definitions in clause 6.2.1.2 of ETSI GS MEC 0102 [1]. | [optional] [default to null] +**UserAppInstanceInfo** | [**[]AppContextAppInfoUserAppInstanceInfo**](AppContext_appInfo_userAppInstanceInfo.md) | List of user application instance information. | [default to null] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/examples/demo4-ue/src/demo-server/backend/docs/AppContextAppInfoUserAppInstanceInfo.md b/examples/demo4-ue/src/demo-server/backend/docs/AppContextAppInfoUserAppInstanceInfo.md new file mode 100644 index 000000000..9c860343a --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/docs/AppContextAppInfoUserAppInstanceInfo.md @@ -0,0 +1,11 @@ +# AppContextAppInfoUserAppInstanceInfo + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**AppInstanceId** | **string** | Identifier of the user application instance. It shall only be included in the response. | [optional] [default to null] +**AppLocation** | [***LocationConstraints**](LocationConstraints.md) | | [optional] [default to null] +**ReferenceURI** | **string** | Address of the user application instance. It shall only be included in the response. | [optional] [default to null] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/examples/demo4-ue/src/demo-server/backend/docs/AppTerminationSubscription.md b/examples/demo4-ue/src/demo-server/backend/docs/AppTerminationSubscription.md new file mode 100644 index 000000000..8c23a2692 --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/docs/AppTerminationSubscription.md @@ -0,0 +1,12 @@ +# AppTerminationSubscription + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**SubscriptionType** | **string** | Shall be set to AppTerminationSubscription. | [default to null] +**CallbackReference** | **string** | URI selected by the MEC application instance to receive notifications on the subscribed MEC application instance management information. This shall be included in both the request and the response. | [default to null] +**Links** | [***AppTerminationSubscriptionLinks**](AppTerminationSubscription__links.md) | | [default to null] +**AppInstanceId** | **string** | It is used as the filtering criterion for the subscribed events. | [default to null] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/examples/demo4-ue/src/demo-server/backend/docs/AppTerminationSubscriptionLinks.md b/examples/demo4-ue/src/demo-server/backend/docs/AppTerminationSubscriptionLinks.md new file mode 100644 index 000000000..69887cc76 --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/docs/AppTerminationSubscriptionLinks.md @@ -0,0 +1,9 @@ +# AppTerminationSubscriptionLinks + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**Self** | [***LinkType**](LinkType.md) | | [default to null] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/examples/demo4-ue/src/demo-server/backend/docs/ApplicationContextDeleteNotification.md b/examples/demo4-ue/src/demo-server/backend/docs/ApplicationContextDeleteNotification.md new file mode 100644 index 000000000..1b1bdce5b --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/docs/ApplicationContextDeleteNotification.md @@ -0,0 +1,10 @@ +# ApplicationContextDeleteNotification + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**ContextId** | **string** | Uniquely identifies the application context that has been deleted from the MEC system. | [default to null] +**NotificationType** | **string** | Shall be set to \"ApplicationContextDeleteNotification\". | [default to null] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/examples/demo4-ue/src/demo-server/backend/docs/ApplicationContextState.md b/examples/demo4-ue/src/demo-server/backend/docs/ApplicationContextState.md new file mode 100644 index 000000000..98cda18aa --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/docs/ApplicationContextState.md @@ -0,0 +1,12 @@ +# ApplicationContextState + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**Counter** | **int32** | Integer representing state of device being tracked | [optional] [default to null] +**AppId** | **string** | Application UUID | [optional] [default to null] +**Mep** | **string** | MEC platform name | [optional] [default to null] +**Device** | **string** | Terminal device application is tracking | [optional] [default to null] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/examples/demo4-ue/src/demo-server/backend/docs/ApplicationContextUpdateNotification.md b/examples/demo4-ue/src/demo-server/backend/docs/ApplicationContextUpdateNotification.md new file mode 100644 index 000000000..3fadb94b0 --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/docs/ApplicationContextUpdateNotification.md @@ -0,0 +1,11 @@ +# ApplicationContextUpdateNotification + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**ContextId** | **string** | Uniquely identifies the application context in the MEC system. | [default to null] +**NotificationType** | **string** | Shall be set to \"ApplicationContextUpdateNotification\". | [default to null] +**UserAppInstanceInfo** | [**[]ApplicationContextUpdateNotificationUserAppInstanceInfo**](ApplicationContextUpdateNotification_userAppInstanceInfo.md) | List of user application instance information. | [default to null] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/examples/demo4-ue/src/demo-server/backend/docs/ApplicationContextUpdateNotificationUserAppInstanceInfo.md b/examples/demo4-ue/src/demo-server/backend/docs/ApplicationContextUpdateNotificationUserAppInstanceInfo.md new file mode 100644 index 000000000..d754d83ca --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/docs/ApplicationContextUpdateNotificationUserAppInstanceInfo.md @@ -0,0 +1,11 @@ +# ApplicationContextUpdateNotificationUserAppInstanceInfo + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**AppInstanceId** | **string** | Identifier of the user application instance. | [optional] [default to null] +**AppLocation** | [***LocationConstraints**](LocationConstraints.md) | | [optional] [default to null] +**ReferenceURI** | **string** | Address of the user application instance. | [optional] [default to null] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/examples/demo4-ue/src/demo-server/backend/docs/ApplicationInstance.md b/examples/demo4-ue/src/demo-server/backend/docs/ApplicationInstance.md new file mode 100644 index 000000000..bd747b61e --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/docs/ApplicationInstance.md @@ -0,0 +1,19 @@ +# ApplicationInstance + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**Name** | **string** | | [optional] [default to null] +**Url** | **string** | | [optional] [default to null] +**Config** | **string** | | [optional] [default to null] +**Ip** | **string** | | [optional] [default to null] +**Id** | **string** | | [optional] [default to null] +**MecReady** | **bool** | Confirm if app instance is ready | [optional] [default to null] +**MecTerminated** | **bool** | Confirm the application level termination of application instance | [optional] [default to null] +**AmsResource** | **bool** | Confirm if app instance has an ams service resource | [optional] [default to null] +**Subscriptions** | [***ApplicationInstanceSubscriptions**](ApplicationInstance_subscriptions.md) | | [optional] [default to null] +**OfferedService** | [***ApplicationInstanceOfferedService**](ApplicationInstance_offeredService.md) | | [optional] [default to null] +**DiscoveredServices** | [**[]ApplicationInstanceDiscoveredServices**](ApplicationInstance_discoveredServices.md) | | [optional] [default to null] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/examples/demo4-ue/src/demo-server/backend/docs/ApplicationInstanceAmsLinkListSubscription.md b/examples/demo4-ue/src/demo-server/backend/docs/ApplicationInstanceAmsLinkListSubscription.md new file mode 100644 index 000000000..8cc4e6c27 --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/docs/ApplicationInstanceAmsLinkListSubscription.md @@ -0,0 +1,10 @@ +# ApplicationInstanceAmsLinkListSubscription + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**SubId** | **string** | | [optional] [default to null] +**AssociateId** | [**[]AssociateId**](AssociateId.md) | 0 to N identifiers to associate the information for specific UE(s) and flow(s). | [optional] [default to null] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/examples/demo4-ue/src/demo-server/backend/docs/ApplicationInstanceAppTerminationSubscription.md b/examples/demo4-ue/src/demo-server/backend/docs/ApplicationInstanceAppTerminationSubscription.md new file mode 100644 index 000000000..a92c74571 --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/docs/ApplicationInstanceAppTerminationSubscription.md @@ -0,0 +1,9 @@ +# ApplicationInstanceAppTerminationSubscription + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**SubId** | **string** | | [optional] [default to null] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/examples/demo4-ue/src/demo-server/backend/docs/ApplicationInstanceDiscoveredServices.md b/examples/demo4-ue/src/demo-server/backend/docs/ApplicationInstanceDiscoveredServices.md new file mode 100644 index 000000000..13683479f --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/docs/ApplicationInstanceDiscoveredServices.md @@ -0,0 +1,13 @@ +# ApplicationInstanceDiscoveredServices + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**SerName** | **string** | The name of the service. This is how the service producing MEC application identifies the service instance it produces. | [optional] [default to null] +**SerInstanceId** | **string** | Identifier of the service instance assigned by the MEC platform. | [optional] [default to null] +**ConsumedLocalOnly** | **bool** | Indicate whether the service can only be consumed by the MEC applications located in the same locality (as defined by scopeOfLocality) as this service instance. | [optional] [default to null] +**Link** | **string** | | [optional] [default to null] +**Version** | **string** | Service version | [optional] [default to null] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/examples/demo4-ue/src/demo-server/backend/docs/ApplicationInstanceOfferedService.md b/examples/demo4-ue/src/demo-server/backend/docs/ApplicationInstanceOfferedService.md new file mode 100644 index 000000000..7ba2b0e7d --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/docs/ApplicationInstanceOfferedService.md @@ -0,0 +1,13 @@ +# ApplicationInstanceOfferedService + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**SerName** | **string** | The name of the service. This is how the service producing MEC application identifies the service instance it produces. | [optional] [default to null] +**Id** | **string** | | [optional] [default to null] +**State** | [***ServiceState**](ServiceState.md) | | [optional] [default to null] +**ScopeOfLocality** | [***LocalityType**](LocalityType.md) | | [optional] [default to null] +**ConsumedLocalOnly** | **bool** | Indicate whether the service can only be consumed by the MEC applications located in the same locality (as defined by scopeOfLocality) as this service instance. | [optional] [default to null] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/examples/demo4-ue/src/demo-server/backend/docs/ApplicationInstanceSerAvailabilitySubscription.md b/examples/demo4-ue/src/demo-server/backend/docs/ApplicationInstanceSerAvailabilitySubscription.md new file mode 100644 index 000000000..66ca094e7 --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/docs/ApplicationInstanceSerAvailabilitySubscription.md @@ -0,0 +1,9 @@ +# ApplicationInstanceSerAvailabilitySubscription + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**SubId** | **string** | | [optional] [default to null] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/examples/demo4-ue/src/demo-server/backend/docs/ApplicationInstanceSubscriptions.md b/examples/demo4-ue/src/demo-server/backend/docs/ApplicationInstanceSubscriptions.md new file mode 100644 index 000000000..652f2b7da --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/docs/ApplicationInstanceSubscriptions.md @@ -0,0 +1,11 @@ +# ApplicationInstanceSubscriptions + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**AppTerminationSubscription** | [***ApplicationInstanceAppTerminationSubscription**](ApplicationInstance_AppTerminationSubscription.md) | | [optional] [default to null] +**SerAvailabilitySubscription** | [***ApplicationInstanceSerAvailabilitySubscription**](ApplicationInstance_SerAvailabilitySubscription.md) | | [optional] [default to null] +**AmsLinkListSubscription** | [***ApplicationInstanceAmsLinkListSubscription**](ApplicationInstance_AmsLinkListSubscription.md) | | [optional] [default to null] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/examples/demo4-ue/src/demo-server/backend/docs/ApplicationList.md b/examples/demo4-ue/src/demo-server/backend/docs/ApplicationList.md new file mode 100644 index 000000000..113b273da --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/docs/ApplicationList.md @@ -0,0 +1,9 @@ +# ApplicationList + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**AppList** | [**[]ApplicationListAppList**](ApplicationList_appList.md) | List of user applications available to the device application. As defined below. | [optional] [default to null] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/examples/demo4-ue/src/demo-server/backend/docs/ApplicationListAppInfo.md b/examples/demo4-ue/src/demo-server/backend/docs/ApplicationListAppInfo.md new file mode 100644 index 000000000..7bc421b1b --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/docs/ApplicationListAppInfo.md @@ -0,0 +1,16 @@ +# ApplicationListAppInfo + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**AppCharcs** | [***ApplicationListAppInfoAppCharcs**](ApplicationList_appInfo_appCharcs.md) | | [optional] [default to null] +**AppDId** | **string** | Identifier of this MEC application descriptor. It is equivalent to the appDId defined in clause 6.2.1.2 of ETSI GS MEC 0102 [1]. This attribute shall be globally unique. | [default to null] +**AppDVersion** | **string** | Identifies the version of the application descriptor. It is equivalent to the appDVersion defined in clause 6.2.1.2 of ETSI GS MEC 0102 [1]. | [default to null] +**AppDescription** | **string** | Human readable description of the MEC application (see note 2). | [default to null] +**AppLocation** | [**[]LocationConstraints**](LocationConstraints.md) | Identifies the locations of the MEC application. | [optional] [default to null] +**AppName** | **string** | Name of the MEC application. The length of the value shall not exceed 32 characters. | [default to null] +**AppProvider** | **string** | Provider of the MEC application. The length of the value shall not exceed 32 characters. | [default to null] +**AppSoftVersion** | **string** | Software version of the MEC application. The length of the value shall not exceed 32 characters. | [default to null] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/examples/demo4-ue/src/demo-server/backend/docs/ApplicationListAppInfoAppCharcs.md b/examples/demo4-ue/src/demo-server/backend/docs/ApplicationListAppInfoAppCharcs.md new file mode 100644 index 000000000..59e4ed4fa --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/docs/ApplicationListAppInfoAppCharcs.md @@ -0,0 +1,13 @@ +# ApplicationListAppInfoAppCharcs + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**Bandwidth** | **int32** | The required connection bandwidth in kbit/s for the use of the MEC application instance. | [optional] [default to null] +**Latency** | **int32** | The target round trip time in milliseconds supported by the MEC system for the MEC application instance. | [optional] [default to null] +**Memory** | **int32** | The maximum size in Mbytes of the memory resource expected to be used by the MEC application instance in the MEC system. | [optional] [default to null] +**ServiceCont** | **int32** | Required service continuity mode for this application. Permitted values: 0 = SERVICE_CONTINUITY_NOT_REQUIRED. 1 = SERVICE_CONTINUITY_REQUIRED. | [optional] [default to null] +**Storage** | **int32** | The maximum size in Mbytes of the storage resource expected to be used by the MEC application instance in the MEC system. | [optional] [default to null] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/examples/demo4-ue/src/demo-server/backend/docs/ApplicationListAppList.md b/examples/demo4-ue/src/demo-server/backend/docs/ApplicationListAppList.md new file mode 100644 index 000000000..b167df336 --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/docs/ApplicationListAppList.md @@ -0,0 +1,10 @@ +# ApplicationListAppList + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**AppInfo** | [***ApplicationListAppInfo**](ApplicationList_appInfo.md) | | [optional] [default to null] +**VendorSpecificExt** | [***ApplicationListVendorSpecificExt**](ApplicationList_vendorSpecificExt.md) | | [optional] [default to null] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/examples/demo4-ue/src/demo-server/backend/docs/ApplicationListVendorSpecificExt.md b/examples/demo4-ue/src/demo-server/backend/docs/ApplicationListVendorSpecificExt.md new file mode 100644 index 000000000..961a995c7 --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/docs/ApplicationListVendorSpecificExt.md @@ -0,0 +1,9 @@ +# ApplicationListVendorSpecificExt + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**VendorId** | **string** | Vendor identifier. The length of the value shall not exceed 32 characters. The rest of the structure of vendor specific extension is not defined. | [default to null] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/examples/demo4-ue/src/demo-server/backend/docs/ApplicationLocationAvailability.md b/examples/demo4-ue/src/demo-server/backend/docs/ApplicationLocationAvailability.md new file mode 100644 index 000000000..a22113959 --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/docs/ApplicationLocationAvailability.md @@ -0,0 +1,10 @@ +# ApplicationLocationAvailability + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**AppInfo** | [***ApplicationLocationAvailabilityAppInfo**](ApplicationLocationAvailability_appInfo.md) | | [default to null] +**AssociateDevAppId** | **string** | Uniquely identifies the device application. The length of the value shall not exceed 32 characters. | [default to null] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/examples/demo4-ue/src/demo-server/backend/docs/ApplicationLocationAvailabilityAppInfo.md b/examples/demo4-ue/src/demo-server/backend/docs/ApplicationLocationAvailabilityAppInfo.md new file mode 100644 index 000000000..25afd4bee --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/docs/ApplicationLocationAvailabilityAppInfo.md @@ -0,0 +1,15 @@ +# ApplicationLocationAvailabilityAppInfo + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**AppDVersion** | **string** | Identifies the version of the application descriptor. It is equivalent to the appDVersion defined in clause 6.2.1.2 of ETSI GS MEC 0102 [1]. | [default to null] +**AppDescription** | **string** | Human readable description of the MEC application. The length of the value shall not exceed 128 characters. | [optional] [default to null] +**AppName** | **string** | Name of the MEC application. The length of the value shall not exceed 32 characters. | [default to null] +**AppPackageSource** | **string** | URI of the application package. Shall be included in the request. The application package shall comply with the definitions in clause 6.2.1.2 of ETSI GS MEC 0102 [1]. | [optional] [default to null] +**AppProvider** | **string** | Provider of the MEC application. The length of the value shall not exceed 32 characters. | [default to null] +**AppSoftVersion** | **string** | Software version of the MEC application. The length of the value shall not exceed 32 characters. | [optional] [default to null] +**AvailableLocations** | [**[]ApplicationLocationAvailabilityAppInfoAvailableLocations**](ApplicationLocationAvailability_appInfo_availableLocations.md) | MEC application location constraints. | [optional] [default to null] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/examples/demo4-ue/src/demo-server/backend/docs/ApplicationLocationAvailabilityAppInfoAvailableLocations.md b/examples/demo4-ue/src/demo-server/backend/docs/ApplicationLocationAvailabilityAppInfoAvailableLocations.md new file mode 100644 index 000000000..6e48bd031 --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/docs/ApplicationLocationAvailabilityAppInfoAvailableLocations.md @@ -0,0 +1,9 @@ +# ApplicationLocationAvailabilityAppInfoAvailableLocations + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**AppLocation** | [***LocationConstraints**](LocationConstraints.md) | | [optional] [default to null] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/examples/demo4-ue/src/demo-server/backend/docs/ApplicationLocationAvailabilityNotification.md b/examples/demo4-ue/src/demo-server/backend/docs/ApplicationLocationAvailabilityNotification.md new file mode 100644 index 000000000..3850feb48 --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/docs/ApplicationLocationAvailabilityNotification.md @@ -0,0 +1,11 @@ +# ApplicationLocationAvailabilityNotification + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**AvailableLocations** | [**[]ApplicationLocationAvailabilityAppInfoAvailableLocations**](ApplicationLocationAvailability_appInfo_availableLocations.md) | Locations available to the MEC application. | [default to null] +**ContextId** | **string** | Uniquely identifies the application context in the MEC system. | [optional] [default to null] +**NotificationType** | **string** | Shall be set to \"ApplicationLocationAvailabilityNotification\". | [default to null] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/examples/demo4-ue/src/demo-server/backend/docs/AssociateId.md b/examples/demo4-ue/src/demo-server/backend/docs/AssociateId.md new file mode 100644 index 000000000..05e993577 --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/docs/AssociateId.md @@ -0,0 +1,10 @@ +# AssociateId + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**Type_** | [***ModelType**](Type.md) | | [default to null] +**Value** | **string** | Value for the identifier. | [default to null] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/examples/demo4-ue/src/demo-server/backend/docs/CommunicationInterface.md b/examples/demo4-ue/src/demo-server/backend/docs/CommunicationInterface.md new file mode 100644 index 000000000..46c77339f --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/docs/CommunicationInterface.md @@ -0,0 +1,9 @@ +# CommunicationInterface + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**IpAddresses** | **string** | | [optional] [default to null] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/examples/demo4-ue/src/demo-server/backend/docs/DAIApi.md b/examples/demo4-ue/src/demo-server/backend/docs/DAIApi.md new file mode 100644 index 000000000..f487c8f91 --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/docs/DAIApi.md @@ -0,0 +1,132 @@ +# {{classname}} + +All URIs are relative to *http://10.190.115.162:8094* + +Method | HTTP request | Description +------------- | ------------- | ------------- +[**DaiAppListGET**](DAIApi.md#DaiAppListGET) | **Get** /dai/apps | Returns onboarded-demo4 User Application AppContext +[**DaiAppLocationAvailabilityPOST**](DAIApi.md#DaiAppLocationAvailabilityPOST) | **Post** /dai/availability/{appcontextid} | Obtain the location constraints for a new application context. +[**DaiDoPingDELETE**](DAIApi.md#DaiDoPingDELETE) | **Delete** /dai/delete/{appcontextid} | Returns onboarded-demo4 User Application AppContext +[**DaiDoPingGET**](DAIApi.md#DaiDoPingGET) | **Get** /dai/doping/{appcontextid} | Returns onboarded-demo4 User Application activity +[**DaiDoPingPOST**](DAIApi.md#DaiDoPingPOST) | **Post** /dai/instantiate | Returns onboarded-demo4 User Application AppContext + +# **DaiAppListGET** +> ApplicationList DaiAppListGET(ctx, ) +Returns onboarded-demo4 User Application AppContext + +Get available application information + +### Required Parameters +This endpoint does not need any parameter. + +### Return type + +[**ApplicationList**](ApplicationList.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json, application/problem+json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **DaiAppLocationAvailabilityPOST** +> AppLocationAvailability DaiAppLocationAvailabilityPOST(ctx, ) +Obtain the location constraints for a new application context. + +Used to obtain the locations available for instantiation of a specific user application in the MEC system. + +### Required Parameters +This endpoint does not need any parameter. + +### Return type + +[**AppLocationAvailability**](AppLocationAvailability.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json, application/problem+json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **DaiDoPingDELETE** +> DaiDoPingDELETE(ctx, ) +Returns onboarded-demo4 User Application AppContext + +Delete the onboarded-demo4 User Application + +### Required Parameters +This endpoint does not need any parameter. + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/problem+json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **DaiDoPingGET** +> DaiDoPingGET(ctx, ) +Returns onboarded-demo4 User Application activity + +Send a ping to the onboarded-demo4 User Application + +### Required Parameters +This endpoint does not need any parameter. + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/problem+json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **DaiDoPingPOST** +> AppContext DaiDoPingPOST(ctx, ) +Returns onboarded-demo4 User Application AppContext + +Instanciate the onboarded-demo4 User Application + +### Required Parameters +This endpoint does not need any parameter. + +### Return type + +[**AppContext**](AppContext.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/json, application/problem+json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + diff --git a/examples/demo4-ue/src/demo-server/backend/docs/FrontendApi.md b/examples/demo4-ue/src/demo-server/backend/docs/FrontendApi.md new file mode 100644 index 000000000..528b69822 --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/docs/FrontendApi.md @@ -0,0 +1,57 @@ +# {{classname}} + +All URIs are relative to *http://10.190.115.162:8094* + +Method | HTTP request | Description +------------- | ------------- | ------------- +[**GetActivityLogs**](FrontendApi.md#GetActivityLogs) | **Get** /info/logs | Returns activity logs +[**GetPlatformInfo**](FrontendApi.md#GetPlatformInfo) | **Get** /info/application | Returns the application dynamic information + +# **GetActivityLogs** +> GetActivityLogs(ctx, ) +Returns activity logs + +Returns activity logs + +### Required Parameters +This endpoint does not need any parameter. + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **GetPlatformInfo** +> ApplicationInstance GetPlatformInfo(ctx, ) +Returns the application dynamic information + +Returns the application dynamic information + +### Required Parameters +This endpoint does not need any parameter. + +### Return type + +[**ApplicationInstance**](ApplicationInstance.md) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: application/problem+json + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + diff --git a/examples/demo4-ue/src/demo-server/backend/docs/InlineNotification.md b/examples/demo4-ue/src/demo-server/backend/docs/InlineNotification.md new file mode 100644 index 000000000..f268cd077 --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/docs/InlineNotification.md @@ -0,0 +1,8 @@ +# InlineNotification + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/examples/demo4-ue/src/demo-server/backend/docs/LinkType.md b/examples/demo4-ue/src/demo-server/backend/docs/LinkType.md new file mode 100644 index 000000000..a46a8096c --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/docs/LinkType.md @@ -0,0 +1,9 @@ +# LinkType + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**Href** | **string** | URI referring to a resource | [optional] [default to null] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/examples/demo4-ue/src/demo-server/backend/docs/LocalityType.md b/examples/demo4-ue/src/demo-server/backend/docs/LocalityType.md new file mode 100644 index 000000000..ebfe404b7 --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/docs/LocalityType.md @@ -0,0 +1,8 @@ +# LocalityType + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/examples/demo4-ue/src/demo-server/backend/docs/LocationConstraints.md b/examples/demo4-ue/src/demo-server/backend/docs/LocationConstraints.md new file mode 100644 index 000000000..c7d4e73f9 --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/docs/LocationConstraints.md @@ -0,0 +1,11 @@ +# LocationConstraints + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**Area** | [***Polygon**](Polygon.md) | | [optional] [default to null] +**CivicAddressElement** | [**[]LocationConstraintsCivicAddressElement**](LocationConstraints_civicAddressElement.md) | Zero or more elements comprising the civic address. Shall be absent if the \"area\" attribute is present. | [optional] [default to null] +**CountryCode** | **string** | The two-letter ISO 3166 [7] country code in capital letters. Shall be present in case the \"area\" attribute is absent. May be absent if the \"area\" attribute is present (see note). | [optional] [default to null] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/examples/demo4-ue/src/demo-server/backend/docs/LocationConstraintsCivicAddressElement.md b/examples/demo4-ue/src/demo-server/backend/docs/LocationConstraintsCivicAddressElement.md new file mode 100644 index 000000000..70e2d83be --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/docs/LocationConstraintsCivicAddressElement.md @@ -0,0 +1,10 @@ +# LocationConstraintsCivicAddressElement + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**CaType** | **int32** | Describe the content type of caValue. The value of caType shall comply with section 3.4 of IETF RFC 4776 [6]. | [optional] [default to null] +**CaValue** | **string** | Content of civic address element corresponding to the caType. The format caValue shall comply with section 3.4 of IETF RFC 4776 [6]. | [optional] [default to null] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/examples/demo4-ue/src/demo-server/backend/docs/ModelType.md b/examples/demo4-ue/src/demo-server/backend/docs/ModelType.md new file mode 100644 index 000000000..dd4d07d89 --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/docs/ModelType.md @@ -0,0 +1,8 @@ +# ModelType + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/examples/demo4-ue/src/demo-server/backend/docs/NotificationApi.md b/examples/demo4-ue/src/demo-server/backend/docs/NotificationApi.md new file mode 100644 index 000000000..c7c769339 --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/docs/NotificationApi.md @@ -0,0 +1,94 @@ +# {{classname}} + +All URIs are relative to *http://10.190.115.162:8094* + +Method | HTTP request | Description +------------- | ------------- | ------------- +[**AppTerminationNotificationCallback**](NotificationApi.md#AppTerminationNotificationCallback) | **Post** /application/termination | Callback endpoint for MEC011 app-termination notifications +[**ApplicationContextDeleteNotificationCallback**](NotificationApi.md#ApplicationContextDeleteNotificationCallback) | **Post** /dai/callback/ApplicationContextDeleteNotification | Callback endpoint for MEC016 Notifications +[**ServiceAvailNotificationCallback**](NotificationApi.md#ServiceAvailNotificationCallback) | **Post** /services/callback/service-availability | Callback endpoint for MEC011 Notifications + +# **AppTerminationNotificationCallback** +> AppTerminationNotificationCallback(ctx, body) +Callback endpoint for MEC011 app-termination notifications + +Callback endpoint for MEC011 app-termination notifications + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. + **body** | [**AppTerminationSubscription**](AppTerminationSubscription.md)| app termination notification details | + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **ApplicationContextDeleteNotificationCallback** +> ApplicationContextDeleteNotificationCallback(ctx, body) +Callback endpoint for MEC016 Notifications + +Callback endpoint for MEC016 Notifications + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. + **body** | [**ApplicationContextDeleteNotification**](ApplicationContextDeleteNotification.md)| MEC application termination | + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **ServiceAvailNotificationCallback** +> ServiceAvailNotificationCallback(ctx, body) +Callback endpoint for MEC011 Notifications + +Callback endpoint for MEC011 Notifications + +### Required Parameters + +Name | Type | Description | Notes +------------- | ------------- | ------------- | ------------- + **ctx** | **context.Context** | context for authentication, logging, cancellation, deadlines, tracing, etc. + **body** | [**ServiceAvailabilityNotification**](ServiceAvailabilityNotification.md)| service availability notification details | + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: application/json + - **Accept**: Not defined + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + diff --git a/examples/demo4-ue/src/demo-server/backend/docs/OneOfInlineNotification.md b/examples/demo4-ue/src/demo-server/backend/docs/OneOfInlineNotification.md new file mode 100644 index 000000000..442884e24 --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/docs/OneOfInlineNotification.md @@ -0,0 +1,8 @@ +# OneOfInlineNotification + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/examples/demo4-ue/src/demo-server/backend/docs/Polygon.md b/examples/demo4-ue/src/demo-server/backend/docs/Polygon.md new file mode 100644 index 000000000..f4cb2c96a --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/docs/Polygon.md @@ -0,0 +1,9 @@ +# Polygon + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**Coordinates** | [**[][][]float32**](array.md) | | [optional] [default to null] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/examples/demo4-ue/src/demo-server/backend/docs/ProblemDetails.md b/examples/demo4-ue/src/demo-server/backend/docs/ProblemDetails.md new file mode 100644 index 000000000..d6f1dfeb6 --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/docs/ProblemDetails.md @@ -0,0 +1,13 @@ +# ProblemDetails + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**Detail** | **string** | A human-readable explanation specific to this occurrence of the problem | [optional] [default to null] +**Instance** | **string** | A URI reference that identifies the specific occurrence of the problem | [optional] [default to null] +**Status** | **int32** | The HTTP status code for this occurrence of the problem | [optional] [default to null] +**Title** | **string** | A short, human-readable summary of the problem type | [optional] [default to null] +**Type_** | **string** | A URI reference according to IETF RFC 3986 that identifies the problem type | [optional] [default to null] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/examples/demo4-ue/src/demo-server/backend/docs/ServiceAvailabilityNotification.md b/examples/demo4-ue/src/demo-server/backend/docs/ServiceAvailabilityNotification.md new file mode 100644 index 000000000..fbe84c7ca --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/docs/ServiceAvailabilityNotification.md @@ -0,0 +1,11 @@ +# ServiceAvailabilityNotification + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**NotificationType** | **string** | Shall be set to SerAvailabilityNotification | [default to null] +**ServiceReferences** | [**[]ServiceAvailabilityNotificationServiceReferences**](ServiceAvailabilityNotification_serviceReferences.md) | | [default to null] +**Links** | [***Subscription**](Subscription.md) | | [default to null] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/examples/demo4-ue/src/demo-server/backend/docs/ServiceAvailabilityNotificationServiceReferences.md b/examples/demo4-ue/src/demo-server/backend/docs/ServiceAvailabilityNotificationServiceReferences.md new file mode 100644 index 000000000..a6c8ddc6e --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/docs/ServiceAvailabilityNotificationServiceReferences.md @@ -0,0 +1,12 @@ +# ServiceAvailabilityNotificationServiceReferences + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**Link** | [***LinkType**](LinkType.md) | | [optional] [default to null] +**SerName** | **string** | The name of the service. This is how the service producing MEC application identifies the service instance it produces. | [default to null] +**State** | [***ServiceState**](ServiceState.md) | | [default to null] +**ChangeType** | **string** | Type of the change. Valid values: ADDED: The service was newly added. REMOVED: The service was removed. STATE_CHANGED: Only the state of the service was changed. ATTRIBUTES_CHANGED: At least one attribute of the service other than state was changed. The change may or may not include changing the state. | [default to null] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/examples/demo4-ue/src/demo-server/backend/docs/ServiceState.md b/examples/demo4-ue/src/demo-server/backend/docs/ServiceState.md new file mode 100644 index 000000000..b6b4bfc9e --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/docs/ServiceState.md @@ -0,0 +1,8 @@ +# ServiceState + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/examples/demo4-ue/src/demo-server/backend/docs/Subscription.md b/examples/demo4-ue/src/demo-server/backend/docs/Subscription.md new file mode 100644 index 000000000..7430bf1b2 --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/docs/Subscription.md @@ -0,0 +1,9 @@ +# Subscription + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**Subscription** | [***LinkType**](LinkType.md) | | [default to null] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/examples/demo4-ue/src/demo-server/backend/docs/TimeStamp.md b/examples/demo4-ue/src/demo-server/backend/docs/TimeStamp.md new file mode 100644 index 000000000..0646af8f6 --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/docs/TimeStamp.md @@ -0,0 +1,10 @@ +# TimeStamp + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**NanoSeconds** | **int32** | The nanoseconds part of the time. Time is defined as Unix-time since January 1, 1970, 00:00:00 UTC. | [default to null] +**Seconds** | **int32** | The seconds part of the time. Time is defined as Unixtime since January 1, 1970, 00:00:00 UTC. | [default to null] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + diff --git a/examples/demo4-ue/src/demo-server/backend/git_push.sh b/examples/demo4-ue/src/demo-server/backend/git_push.sh new file mode 100644 index 000000000..ae01b182a --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/git_push.sh @@ -0,0 +1,52 @@ +#!/bin/sh +# ref: https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/ +# +# Usage example: /bin/sh ./git_push.sh wing328 swagger-petstore-perl "minor update" + +git_user_id=$1 +git_repo_id=$2 +release_note=$3 + +if [ "$git_user_id" = "" ]; then + git_user_id="GIT_USER_ID" + echo "[INFO] No command line input provided. Set \$git_user_id to $git_user_id" +fi + +if [ "$git_repo_id" = "" ]; then + git_repo_id="GIT_REPO_ID" + echo "[INFO] No command line input provided. Set \$git_repo_id to $git_repo_id" +fi + +if [ "$release_note" = "" ]; then + release_note="Minor update" + echo "[INFO] No command line input provided. Set \$release_note to $release_note" +fi + +# Initialize the local directory as a Git repository +git init + +# Adds the files in the local repository and stages them for commit. +git add . + +# Commits the tracked changes and prepares them to be pushed to a remote repository. +git commit -m "$release_note" + +# Sets the new remote +git_remote=`git remote` +if [ "$git_remote" = "" ]; then # git remote not defined + + if [ "$GIT_TOKEN" = "" ]; then + echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git credential in your environment." + git remote add origin https://github.com/${git_user_id}/${git_repo_id}.git + else + git remote add origin https://${git_user_id}:${GIT_TOKEN}@github.com/${git_user_id}/${git_repo_id}.git + fi + +fi + +git pull origin master + +# Pushes (Forces) the changes in the local repository up to the remote repository +echo "Git pushing to https://github.com/${git_user_id}/${git_repo_id}.git" +git push origin master 2>&1 | grep -v 'To https' + diff --git a/examples/demo4-ue/src/demo-server/backend/go.mod b/examples/demo4-ue/src/demo-server/backend/go.mod new file mode 100644 index 000000000..6d365a193 --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/go.mod @@ -0,0 +1,34 @@ +module github.com/AdvantEDGE/examples/demo4-ue/src/demo-server/backend + +go 1.13 + +require ( + github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-app-support-client v0.0.0-20211214133749-f203f7ab4f1c + github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-dai-client v0.0.0 + github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-data-key-mgr v0.0.0 + github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-http-logger v0.0.0 + github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-loc-serv-client v0.0.0-20211214133749-f203f7ab4f1c + github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-logger v0.0.0 + github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-metrics v0.0.0 + github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-redis v0.0.0 + github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-sandbox-ctrl-client v0.0.0-20211214133749-f203f7ab4f1c + github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-service-mgmt-client v0.0.0-20211214133749-f203f7ab4f1c + github.com/antihax/optional v1.0.0 + github.com/google/uuid v1.1.2 + github.com/gorilla/handlers v1.5.1 + github.com/gorilla/mux v1.8.0 + github.com/spf13/viper v1.12.0 +) + +replace ( + github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-app-support-client => ../../../../../go-packages/meep-app-support-client + github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-dai-client => ../../../../../go-packages/meep-dai-client + github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-data-key-mgr => ../../../../../go-packages/meep-data-key-mgr + github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-http-logger => ../../../../../go-packages/meep-http-logger + github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-loc-serv-client => ../../../../../go-packages/meep-loc-serv-client + github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-logger => ../../../../../go-packages/meep-logger + github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-metrics => ../../../../../go-packages/meep-metrics + github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-redis => ../../../../../go-packages/meep-redis + github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-sandbox-ctrl-client => ../../../../../go-packages/meep-sandbox-ctrl-client + github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-service-mgmt-client => ../../../../../go-packages/meep-service-mgmt-client +) diff --git a/examples/demo4-ue/src/demo-server/backend/go.sum b/examples/demo4-ue/src/demo-server/backend/go.sum new file mode 100644 index 000000000..c3f12adaa --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/go.sum @@ -0,0 +1,1075 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= +cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= +cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= +cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= +cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= +cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= +cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= +cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= +cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= +cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= +cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= +cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= +cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= +cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= +cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY= +cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM= +cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY= +cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ= +cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= +cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4= +cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= +cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA= +cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A= +cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= +cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= +cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= +cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= +cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow= +cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM= +cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M= +cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s= +cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/firestore v1.6.1/go.mod h1:asNXNOzBdyVQmEU+ggO8UPodTkEVFW5Qx+rwHnAz+EY= +cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= +cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= +cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= +cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= +cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= +github.com/InterDigitalInc/AdvantEDGE v1.8.1 h1:2jZJ/Hu6IDweJifEpbOD8PP9pX03AQlZGNnrhv1Die8= +github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-ams-client v0.0.0-20211214133749-f203f7ab4f1c h1:+EEA6CagO3PXUJNrwNPw1wJ62wQCzOZe4o4x+l1UJ9A= +github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-ams-client v0.0.0-20211214133749-f203f7ab4f1c/go.mod h1:Ta4RAT/qLKzo9Af4GGN1BOMX0wztCZsrh4oKH0L2ocY= +github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-app-support-client v0.0.0-20211214133749-f203f7ab4f1c h1:CXskqbuVzeLxp3A6qOncIsfPAi/oqaQxrrCbsW1Gjc0= +github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-app-support-client v0.0.0-20211214133749-f203f7ab4f1c/go.mod h1:0jCjKp2Xs2jwb8/+UnSBwunaCDAPsbarEGJg0d6QRtI= +github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-logger v0.0.0-20211012135439-29644864b026/go.mod h1:Xy2Z6nc9m0DRQRj9g0+/4E6OkDlCkFYySa65JoQ2d8g= +github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-logger v0.0.0-20211214133749-f203f7ab4f1c h1:pNyzqkE702/quz8AGVznklRAwW764WZSwK0izIWlTOY= +github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-logger v0.0.0-20211214133749-f203f7ab4f1c/go.mod h1:Xy2Z6nc9m0DRQRj9g0+/4E6OkDlCkFYySa65JoQ2d8g= +github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-sandbox-ctrl-client v0.0.0-20211214133749-f203f7ab4f1c h1:A63lWl3Tgh0XjVmulBpGON5G3hGfy2jpRoZfwl79RN4= +github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-sandbox-ctrl-client v0.0.0-20211214133749-f203f7ab4f1c/go.mod h1:RlTJLiOIOlQ1IRl/un3Ut1tch5NqxNdIaV4HMuFOdr0= +github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-service-mgmt-client v0.0.0-20211214133749-f203f7ab4f1c h1:4UuaBC5bYlhBR87FgqN7r1rmDxbgcUPWbM+aDWaQFEg= +github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-service-mgmt-client v0.0.0-20211214133749-f203f7ab4f1c/go.mod h1:PBVKB8iRvq7E3VQvmVaqf2LDKP0IZXJwNN7CAJ/tWi8= +github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= +github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= +github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= +github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= +github.com/antihax/optional v1.0.0 h1:xK2lYat7ZLaVVcIuj82J8kIro4V6kDe0AUDFboUCwcg= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= +github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= +github.com/armon/go-metrics v0.3.10/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc= +github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= +github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= +github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= +github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= +github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= +github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= +github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= +github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= +github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= +github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= +github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= +github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= +github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= +github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= +github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= +github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= +github.com/felixge/httpsnoop v1.0.1 h1:lvB5Jl89CsZtGIWuTcDM1E/vkVs49/Ml7JJe07l8SPQ= +github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= +github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= +github.com/frankban/quicktest v1.14.3/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI= +github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= +github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/go-redis/redis v6.15.2+incompatible h1:9SpNVG76gr6InJGxoZ6IuuxaCOQwDAhzyXg+Bs+0Sb4= +github.com/go-redis/redis v6.15.2+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA= +github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= +github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= +github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= +github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM= +github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM= +github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c= +github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/context v1.1.1 h1:AWwleXJkX/nhcU9bZSnZoi3h/qGYqQAGhq6zZe/aQW8= +github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= +github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4= +github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q= +github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.7.3 h1:gnP5JzjVOuiZD07fKKToCAOjS0yOpj/qPETTXCCS6hw= +github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= +github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= +github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= +github.com/hashicorp/consul/api v1.12.0/go.mod h1:6pVBMo0ebnYdt2S3H87XhekM/HHrUoTD2XXb/VrZVy0= +github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= +github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= +github.com/hashicorp/go-hclog v1.2.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= +github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= +github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= +github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= +github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= +github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= +github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= +github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc= +github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= +github.com/hashicorp/memberlist v0.3.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= +github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= +github.com/hashicorp/serf v0.9.6/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4= +github.com/hashicorp/serf v0.9.7/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= +github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d h1:/WZQPMZNsjZ7IlCpsLGdQBINg5bxKQ1K1sh6awxLtkA= +github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= +github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= +github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= +github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= +github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo= +github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= +github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= +github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= +github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= +github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= +github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= +github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= +github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= +github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= +github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= +github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= +github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k= +github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= +github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= +github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= +github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= +github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= +github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= +github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= +github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= +github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= +github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA= +github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= +github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= +github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= +github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= +github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= +github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= +github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= +github.com/pelletier/go-toml/v2 v2.0.1 h1:8e3L2cCQzLFi2CR4g7vGFuFxX7Jl1kKX8gW+iV0GUKU= +github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo= +github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= +github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= +github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= +github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= +github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= +github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= +github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= +github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= +github.com/prometheus/client_golang v1.9.0/go.mod h1:FqZLKOZnGdFAhOK4nqGHa7D66IdsO+O441Eve7ptJDU= +github.com/prometheus/client_golang v1.11.1 h1:+4eQaD7vAZ6DsfsxB15hbE0odUjGI5ARs9yskGu1v4s= +github.com/prometheus/client_golang v1.11.1/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= +github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= +github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= +github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= +github.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= +github.com/prometheus/common v0.26.0 h1:iMAkS2TDoNWnKM+Kopnx/8tnEStIfpYA0ur0xQzzhMQ= +github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= +github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4= +github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/sagikazarmark/crypt v0.6.0/go.mod h1:U8+INwJo3nBv1m6A/8OBXAq7Jnpspk5AxSgDyEQcea8= +github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I= +github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spf13/afero v1.8.2 h1:xehSyVa0YnHWsJ49JFljMpg1HX19V6NDZ1fkm1Xznbo= +github.com/spf13/afero v1.8.2/go.mod h1:CtAatgMJh6bJEIs48Ay/FOnkljP3WeGUG0MC1RfAqwo= +github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w= +github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU= +github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= +github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= +github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= +github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.12.0 h1:CZ7eSOd3kZoaYDLbXnmzgQI5RlciuXBMA+18HwHRfZQ= +github.com/spf13/viper v1.12.0/go.mod h1:b6COn30jlNxbm/V2IqWiNWkJ+vZNiMNksliPCiuKtSI= +github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= +github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= +github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/subosito/gotenv v1.3.0 h1:mjC+YW8QpAdXibNi+vNWgzmgBH4+5l5dCXv8cNysBLI= +github.com/subosito/gotenv v1.3.0/go.mod h1:YzJjq/33h7nrwdY+iHMhEOEEbW0ovIz0tB6t6PwAXzs= +github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= +github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= +github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= +go.etcd.io/etcd/api/v3 v3.5.4/go.mod h1:5GB2vv4A4AOn3yk7MftYGHkUfGtDHnEraIjym4dYz5A= +go.etcd.io/etcd/client/pkg/v3 v3.5.4/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= +go.etcd.io/etcd/client/v2 v2.305.4/go.mod h1:Ud+VUwIi9/uQHOMA+4ekToJ12lTxlv0zB/+DHwTGEbU= +go.etcd.io/etcd/client/v3 v3.5.4/go.mod h1:ZaRkVgBZC+L+dLCjTcF1hRXpgZXQPOvnA/Ak/gq3kiY= +go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= +go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= +go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= +go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= +go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= +go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= +go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= +golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= +golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220520000938-2e3eb7b945c2 h1:NWy5+hlRbC7HK+PmcXVUmW1IMyFce7to56IUvhUFm7Y= +golang.org/x/net v0.0.0-20220520000938-2e3eb7b945c2/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 h1:OSnWWcOd/CtWQC2cYSBgbTSJv3ciqd8r54ySIW2y3RE= +golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220513210516-0976fa681c29/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201214210602-f9fddec55a1e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= +golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= +google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= +google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= +google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= +google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= +google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= +google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= +google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= +google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4= +google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw= +google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU= +google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k= +google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= +google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= +google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI= +google.golang.org/api v0.59.0/go.mod h1:sT2boj7M9YJxZzgeZqXogmhfmRWDtPzT31xkieUbuZU= +google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I= +google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo= +google.golang.org/api v0.67.0/go.mod h1:ShHKP8E60yPsKNw/w8w+VYaj9H6buA5UqDp8dhbQZ6g= +google.golang.org/api v0.70.0/go.mod h1:Bs4ZM2HGifEvXwd50TtW70ovgJffJYw2oRCOFU/SkfA= +google.golang.org/api v0.71.0/go.mod h1:4PyU6e6JogV1f9eA4voyrTY2batOLdgZ5qZ5HOCc4j8= +google.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRRyDs= +google.golang.org/api v0.75.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA= +google.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw= +google.golang.org/api v0.81.0/go.mod h1:FA6Mb/bZxj706H2j+j2d6mHEEaHBmbbWnkfvmorOCko= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= +google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= +google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= +google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= +google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= +google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= +google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= +google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= +google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= +google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w= +google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211008145708-270636b82663/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211028162531-8db9c33dc351/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211221195035-429b39de9b1c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220126215142-9970aeb2e350/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220207164111-0872dc986b00/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220304144024-325a89244dc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= +google.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220413183235-5e96e2839df9/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220414192740-2d67ff6cf2b4/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220429170224-98d788798c3e/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220519153652-3a47de7e79bd/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= +google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= +google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= +google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= +google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= +google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= +google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= +google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= +gopkg.in/ini.v1 v1.66.4 h1:SsAcf+mM7mRZo2nJNGt8mZCjG8ZRaNGMURJw7BsIST4= +gopkg.in/ini.v1 v1.66.4/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= +gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0 h1:hjy8E9ON/egN1tAYqKb61G10WtihqetD4sz2H+8nIeA= +gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= +sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= +sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= diff --git a/examples/demo4-ue/src/demo-server/backend/main.go b/examples/demo4-ue/src/demo-server/backend/main.go new file mode 100644 index 000000000..c355f3021 --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/main.go @@ -0,0 +1,100 @@ +/* + * 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. + */ + +package main + +import ( + "net/http" + "os" + "os/signal" + "path/filepath" + "syscall" + "time" + + server "github.com/AdvantEDGE/examples/demo4-ue/src/demo-server/backend/server" + log "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-logger" + "github.com/gorilla/handlers" +) + +// Initalize customized logger +func init() { + log.MeepTextLogInit("demo4-ue") +} + +func main() { + var ( + dir string + fileName string + run bool = true + done chan bool + ) + + if len(os.Args) < 2 { + // no config argument + log.Fatal("Missing parameter, require file path to configurations!") + } + + // Read configuration file path in command line arugments + configPath := os.Args[1] + dir = filepath.Dir(configPath) + fileName = filepath.Base(configPath) + + go func() { + + port, err := server.Init(dir, fileName) + if err != nil { + log.Fatal("Failed to initalize Demo 4 ", err) + } + log.Info("main: server.Init done") + + // Channel sync pass channel listen for app termination + server.Run(done) + + // Start demo 4 server + router := server.NewRouter() + methods := handlers.AllowedMethods([]string{"OPTIONS", "DELETE", "GET", "HEAD", "POST", "PUT"}) + header := handlers.AllowedHeaders([]string{"content-type"}) + log.Info("main: Starting listener on port ", port) + log.Fatal(http.ListenAndServe(port, handlers.CORS(methods, header)(router))) + run = false + }() + + // Listen for SIGKILL + go func() { + sigchan := make(chan os.Signal, 10) + signal.Notify(sigchan, syscall.SIGINT, syscall.SIGTERM) + <-sigchan + log.Info("Waiting to shut down program !") + run = false + }() + + // Listen for demo 4 error exit program + go func() { + <-done + log.Info("Waiting to shut down program !") + run = false + }() + + for { + // Invoke graceful termination upon program kill + if !run { + log.Info("Invoking demo 4 graceful termination") + server.Terminate() + break + } + time.Sleep(time.Second) + } +} diff --git a/examples/demo4-ue/src/demo-server/backend/server/api_dai.go b/examples/demo4-ue/src/demo-server/backend/server/api_dai.go new file mode 100644 index 000000000..ea98c3fe4 --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/server/api_dai.go @@ -0,0 +1,48 @@ +/* + * 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. + * + * MEEP Demo 4 API + * Demo 4 is an edge application that can be used with AdvantEDGE or ETSI MEC Sandbox to demonstrate MEC016 usage + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 0.0.1 + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ +package server + +import ( + "net/http" +) + +func DaiAppListGET(w http.ResponseWriter, r *http.Request) { + demo4DaiAppListGET(w, r) +} + +func DaiDoPingGET(w http.ResponseWriter, r *http.Request) { + demo4DaiDoPingGET(w, r) +} + +func DaiDoPingPOST(w http.ResponseWriter, r *http.Request) { + demo4DaiDoPingPOST(w, r) +} + +func DaiDoPingDELETE(w http.ResponseWriter, r *http.Request) { + demo4DaiDoPingDELETE(w, r) +} + +func DaiAppLocationAvailabilityPOST(w http.ResponseWriter, r *http.Request) { + demo4DaiAppLocationAvailabilityPOST(w, r) +} diff --git a/examples/demo4-ue/src/demo-server/backend/server/api_frontend.go b/examples/demo4-ue/src/demo-server/backend/server/api_frontend.go new file mode 100644 index 000000000..46094bb8f --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/server/api_frontend.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. + * + * MEEP Demo 4 API + * Demo 4 is an edge application that can be used with AdvantEDGE or ETSI MEC Sandbox to demonstrate MEC016 usage + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 0.0.1 + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ +package server + +import ( + "net/http" +) + +func GetActivityLogs(w http.ResponseWriter, r *http.Request) { + demo4GetActivityLogs(w, r) +} + +func GetPlatformInfo(w http.ResponseWriter, r *http.Request) { + demo4GetPlatformInfo(w, r) +} diff --git a/examples/demo4-ue/src/demo-server/backend/server/api_notification.go b/examples/demo4-ue/src/demo-server/backend/server/api_notification.go new file mode 100644 index 000000000..14c898764 --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/server/api_notification.go @@ -0,0 +1,41 @@ +/* + * 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. + * + * MEEP Demo 4 API + * Demo 4 is an edge application that can be used with AdvantEDGE or ETSI MEC Sandbox to demonstrate MEC016 usage + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 0.0.1 + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package server + +import ( + "net/http" +) + +func AppTerminationNotificationCallback(w http.ResponseWriter, r *http.Request) { + appTerminationNotificationCallback(w, r) +} + +func ServiceAvailNotificationCallback(w http.ResponseWriter, r *http.Request) { + serviceAvailNotificationCallback(w, r) +} + +func ApplicationContextDeleteNotificationCallback(w http.ResponseWriter, r *http.Request) { + applicationContextDeleteNotificationCallback(w, r) +} diff --git a/examples/demo4-ue/src/demo-server/backend/server/demo4_service.go b/examples/demo4-ue/src/demo-server/backend/server/demo4_service.go new file mode 100644 index 000000000..6aad000da --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/server/demo4_service.go @@ -0,0 +1,1141 @@ +/* + * 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. + * + * MEEP Demo 4 API + * Demo 4 is an edge application that can be used with AdvantEDGE or ETSI MEC Sandbox to demonstrate MEC016 usage + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 0.0.1 + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ +package server + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "io/ioutil" + "net/http" + "strconv" + "strings" + "sync" + "time" + + "github.com/AdvantEDGE/examples/demo4-ue/src/demo-server/backend/util" + asc "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-app-support-client" + dai "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-dai-client" + loc "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-loc-serv-client" + log "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-logger" + sbx "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-sandbox-ctrl-client" + smc "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-service-mgmt-client" + + "github.com/antihax/optional" + uuid "github.com/google/uuid" + "github.com/gorilla/mux" +) + +const ( + moduleName = "demo4-ue" + mepName = "" +) + +var mutex sync.Mutex + +var done chan bool + +// App-enablement client +var srvMgmtClient *smc.APIClient +var srvMgmtClientPath string +var appSupportClient *asc.APIClient +var appSupportClientPath string + +// Sandbox controller client +var sandBoxClient *sbx.APIClient +var sbxCtrlUrl string = "http://meep-sandbox-ctrl" + +// Location client +var locServ *loc.APIClient +var locExpiry time.Duration = 5 * time.Second +var locTicker *time.Ticker + +// DAI client +var daiClient *dai.APIClient +var daiServiceName string + +var svcSubscriptionSent bool +var appTerminationSent bool +var serviceRegistered bool +var terminated bool +var terminateNotification bool +var appEnabled bool + +// Config fields +var mecUrl string +var localPort string +var localUrl string +var environment string +var callBackUrl string +var nodeName string +var userInfo loc.UserInfo + +// App service & discovered service +var mecServicesMap = make(map[string]string) +var instanceName string +var serviceCategory string = "demo4" +var mep string +var serviceAppVersion string = "v2.2.1" +var scopeOfLocality string = defaultScopeOfLocality +var consumedLocalOnly bool = defaultConsumedLocalOnly + +const defaultScopeOfLocality = "MEC_SYSTEM" +const defaultConsumedLocalOnly = true + +// Demo models +var demoAppInfo ApplicationInstance +var appActivityLogs []string = []string{} +var subscriptions ApplicationInstanceSubscriptions +var appEnablementServiceId string +var amsSubscriptionId string +var terminationSubscriptionId string + +// Creating context state +type AppContextState struct { + app dai.AppContext +} + +var appContexts = make(map[string]AppContextState) + +// Init - Config & Client Package initialization +func Init(envPath string, envName string) (port string, err error) { + + // Retrieve environmental variable + var config util.Config + // trim file extension + envName = strings.TrimSuffix(envName, ".yaml") + log.Info("Using config values from ", envPath, "/", envName) + config, err = util.LoadConfig(envPath, envName) + if err != nil { + log.Fatal("Failed to load configuration file: ", err.Error()) + } + log.Info("Config.Mode: ", config.Mode) + log.Info("Config.SandboxUrl: ", config.SandboxUrl) + log.Info("Config.NodeName: ", config.NodeName) + log.Info("Config.HttpsOnly: ", config.HttpsOnly) + log.Info("Config.MecPlatform: ", config.MecPlatform) + log.Info("Config.AppInstanceId: ", config.AppInstanceId) + log.Info("Config.Localurl: ", config.Localurl) + log.Info("Config.Port: ", config.Port) + log.Info("Config.AppName: ", config.AppName) + + // Retrieve environment + // Sandbox config is set by user + // AdvantEDGE config is set by default + if config.Mode == "sandbox" { + environment = "sandbox" + // mecUrl is url of the sandbox system + mecUrl = config.SandboxUrl + // Check mecUrl if uses https + if config.HttpsOnly { + if !strings.HasPrefix(mecUrl, "https://") { + mecUrl = "https://" + mecUrl + } + } else if !config.HttpsOnly { + if !strings.HasPrefix(mecUrl, "http://") { + mecUrl = "http://" + mecUrl + } + } else { + // Throw err + log.Fatal("Missing field for https in config") + } + + if strings.HasSuffix(mecUrl, "/") { + mecUrl = strings.TrimSuffix(mecUrl, "/") + } + + localPort = config.Port + localUrl = config.Localurl + } else if config.Mode == "advantedge" { + environment = "advantedge" + localPort = ":80" + localUrl = config.Localurl + } else { + log.Fatal("Missing field for mode, should be set to advantedge or sandbox") + } + + // Retrieve mec demo3 url & port + if !strings.HasPrefix(localPort, ":") { + localPort = ":" + localPort + } + if !strings.HasPrefix(localUrl, "http://") { + localUrl = "http://" + localUrl + } + if strings.HasSuffix(localUrl, "/") { + localUrl = strings.TrimSuffix(localUrl, "/") + } + + // Retrieve UE application instance/node name + instanceName = config.AppInstanceId + nodeName = config.NodeName + log.Info("Init: environment= ", environment, "- localPort= ", localPort, "- localUrl= ", localUrl) + log.Info("Init: nodeName= ", nodeName, " - instanceName= ", instanceName) + log.Info("Init: mecUrl= ", mecUrl, "- mep= ", mep) + + // Prepend url & mapped port into callbackurl + callBackUrl = localUrl + localPort + log.Info("callBackUrl: ", callBackUrl) + + // If demo4-ue starts on advantedge then get resource node name from sbx controller + if environment == "advantedge" { + sandBoxClientCfg := sbx.NewConfiguration() + sandBoxClientCfg.BasePath = sbxCtrlUrl + "/sandbox-ctrl/v1" + sandBoxClient = sbx.NewAPIClient(sandBoxClientCfg) + if sandBoxClient == nil { + return "", errors.New("Failed to create Sandbox Controller REST API client") + } + appInfo, err := getApplicationInfo(instanceName) + if err != nil { + return "", errors.New("Failed to retrieve mec application resource") + } + mep = appInfo.NodeName + log.Info("Init: mep: ", mep) + } + + // Setup application support client & service management client + appSupportClientCfg := asc.NewConfiguration() + srvMgmtClientCfg := smc.NewConfiguration() + locServerCfg := loc.NewConfiguration() + if environment == "advantedge" { + if config.MecPlatform != "" { + appSupportClientCfg.BasePath = "http://" + mep + "-meep-app-enablement" + "/mec_app_support/v1" + srvMgmtClientCfg.BasePath = "http://" + mep + "-meep-app-enablement" + "/mec_service_mgmt/v1" + locServerCfg.BasePath = "http://" + mep + "-meep-loc-serv" + "/location/v2" + } else { + appSupportClientCfg.BasePath = "http://meep-app-enablement/mec_app_support/v1" + srvMgmtClientCfg.BasePath = "http://meep-app-enablement/mec_service_mgmt/v1" + locServerCfg.BasePath = "http://meep-loc-serv" + "/location/v2" + } + } else { + appSupportClientCfg.BasePath = mecUrl + "/mec_app_support/v1" + srvMgmtClientCfg.BasePath = mecUrl + "/mec_service_mgmt/v1" + locServerCfg.BasePath = mecUrl + "/location/v2" + } + + // Create app enablement client + appSupportClient = asc.NewAPIClient(appSupportClientCfg) + appSupportClientPath = appSupportClientCfg.BasePath + if appSupportClient == nil { + return "", errors.New("Failed to create App Enablement App Support REST API client") + } + // Create service management client + srvMgmtClient = smc.NewAPIClient(srvMgmtClientCfg) + srvMgmtClientPath = srvMgmtClientCfg.BasePath + if srvMgmtClient == nil { + return "", errors.New("Failed to create App Enablement Service Management REST API client") + } + + // Initialize demo4 app info + demoAppInfo.Config = envName + demoAppInfo.Url = mecUrl + demoAppInfo.Name = config.AppName + demoAppInfo.Id = instanceName + demoAppInfo.Ip = callBackUrl + + // Register to LocationServer + locServ = loc.NewAPIClient(locServerCfg) + if locServ == nil { + return "", errors.New("Failed to create LocationServer REST API client") + } + + log.Info("Starting Demo 4 instance on Port=", localPort, " using app instance id=", instanceName, " mec platform=", mep) + return localPort, nil +} + +func getApplicationInfo(appId string) (appInfo sbx.ApplicationInfo, err error) { + appInfo, resp, err := sandBoxClient.ApplicationsApi.ApplicationsAppInstanceIdGET(context.TODO(), appId) + if err != nil { + log.Info("Failed to retrieve mec application resource ", err) + return appInfo, err + } + log.Debug("getApplicationInfo: Receive confirmation acknowlegement ", resp.Status) + log.Debug("getApplicationInfo: appInfo: ", appInfo) + + return appInfo, nil +} + +func demo4Register() (err error) { + + mutex.Lock() + defer mutex.Unlock() + + // Start app registeration + if !appEnabled { + + // If app is restarted, clean app activity, discovered services + appActivityLogs = []string{} + //terminalDevices = make(map[string]string) + demoAppInfo.DiscoveredServices = []ApplicationInstanceDiscoveredServices{} + + // Send confirm ready + err = sendReadyConfirmation(instanceName) + if err != nil { + // Add to activity log for error indicator + appActivityLogs = append(appActivityLogs, "=== Register Demo4 MEC Application [501]") + log.Fatal(err.Error()) + return err + } + appActivityLogs = append(appActivityLogs, "=== Register Demo4 MEC Application [200]") + demoAppInfo.MecReady = true + + // Retrieve mec services + discoveredServices, err := getMecServices() + if err != nil { + log.Fatal(err.Error()) + return err + } + + // Store discovered service name into app info model + // Store service as a map using service name as key and url as value + // to lookup url using service name in O(1) + mecServicesMap = make(map[string]string) + var tempService ApplicationInstanceDiscoveredServices + for _, e := range discoveredServices { + tempService.SerName = e.SerName + tempService.SerInstanceId = e.SerInstanceId + tempService.ConsumedLocalOnly = e.ConsumedLocalOnly + tempService.Link = e.TransportInfo.Endpoint.Uris[0] + tempService.Version = e.TransportInfo.Version + demoAppInfo.DiscoveredServices = append(demoAppInfo.DiscoveredServices, tempService) + mecServicesMap[tempService.SerName] = tempService.Link + } + + // Subscribe to app termination + appTerminationReference := localUrl + localPort + "/application/termination" + appTerminationId, err := subscribeAppTermination(instanceName, appTerminationReference) + if err == nil { + appTerminationSent = true + } + + // Store app termination subscription id + var appSubscription ApplicationInstanceAppTerminationSubscription + appSubscription.SubId = appTerminationId + subscriptions.AppTerminationSubscription = &appSubscription + + // Subscribe to service availability + svcCallBackReference := callBackUrl + "/services/callback/service-availability" + + svcSubscriptionId, err := subscribeAvailability(instanceName, svcCallBackReference) + if err == nil { + svcSubscriptionSent = true + } + + // Store service subcription id + var serSubscription ApplicationInstanceSerAvailabilitySubscription + serSubscription.SubId = svcSubscriptionId + subscriptions.SerAvailabilitySubscription = &serSubscription + + // Register demo app service + registeredService, err := registerService(instanceName, callBackUrl) + if err != nil { + appActivityLogs = append(appActivityLogs, "Failed to register service") + err := errors.New("Failed to register service") + return err + } else { + serviceRegistered = true + } + + // Store demo app service into app info model + var serviceLocality = LocalityType(scopeOfLocality) + var state = ServiceState("ACTIVE") + demoAppInfo.OfferedService = &ApplicationInstanceOfferedService{ + Id: registeredService.SerInstanceId, + SerName: serviceCategory, + ScopeOfLocality: &serviceLocality, + State: &state, + ConsumedLocalOnly: true, + } + + if environment == "advantedge" { + daiServiceName = "meep-dai" + } else { + daiServiceName = "mec016-1" + } + var daiUrl = mecServicesMap[daiServiceName] + daiClientcfg := dai.NewConfiguration() + daiClientcfg.BasePath = daiUrl + log.Debug("daiUrl: ", daiUrl) + daiClient = dai.NewAPIClient(daiClientcfg) + if daiClient == nil { + appActivityLogs = append(appActivityLogs, "Failed to get daiClient instance") + err := errors.New("Failed to get daiClient instance") + return err + } + log.Debug("daiClient instance: ", daiClient) + appActivityLogs = append(appActivityLogs, "daiClient instance created") + + demoAppInfo.Subscriptions = &subscriptions + + appEnabled = true + } + + return nil +} + +// Channel sync consume channel listen for app termination +func Run(msg chan bool) { + + err := demo4Register() + if err != nil { + log.Fatal("Failed to register demo4-ue: ", err.Error()) + } + startProcessLocTicker() + log.Info("ProcessLocTicker successfully started") + + done = msg +} + +// Terminate by deleting all resources allocated on MEC platform & mec app +func Terminate() { + + // Only invoke graceful termination if not terminated (triggerd by mec platform) + if !terminated { + + stopProcessLocTicker() + + if appEnabled { + //intervalTicker.Stop() + log.Info("De-register Demo4 MEC Application") + appActivityLogs = append(appActivityLogs, "=== De-register Demo4 MEC Application [200]") + } + + if appTerminationSent { + //Delete app subscriptions + if demoAppInfo.Subscriptions != nil { + if demoAppInfo.Subscriptions.AppTerminationSubscription != nil { + err := delAppTerminationSubscription(instanceName, demoAppInfo.Subscriptions.AppTerminationSubscription.SubId) + if err == nil { + log.Info("Deleted App-termination subscription") + demoAppInfo.Subscriptions.AppTerminationSubscription.SubId = "" + appTerminationSent = false + } + } + + // Delete service subscriptions + if svcSubscriptionSent { + err := delsubscribeAvailability(instanceName, demoAppInfo.Subscriptions.SerAvailabilitySubscription.SubId) + if err == nil { + log.Info("Deleted Service-avail subscription") + svcSubscriptionSent = false + demoAppInfo.Subscriptions.SerAvailabilitySubscription.SubId = "" + } + } + } + + // Delete service + if serviceRegistered { + err := unregisterService(instanceName, appEnablementServiceId) + if err == nil { + + log.Info("Deleted Demo4 service") + serviceRegistered = false + demoAppInfo.OfferedService = nil + } + } + + //Send Confirm Terminate if received notification + if terminateNotification { + confirmTerminate(instanceName) + terminated = true + } + + log.Debug("Terminate: instanceName= ", instanceName) + _, err := sandBoxClient.ApplicationsApi.ApplicationsAppInstanceIdDELETE(context.TODO(), instanceName) + if err != nil { + log.Info("Failed to delete UE application resource") + } + + // Clean app info state + // Update app info + demoAppInfo.MecReady = false + demoAppInfo.MecTerminated = true + demoAppInfo.DiscoveredServices = nil + + } + + } + +} + +// REST API handle service subscription callback notification +func applicationContextDeleteNotificationCallback(w http.ResponseWriter, r *http.Request) { + log.Info(">>> applicationContextDeleteNotificationCallback: ", r.Body) + + // Decode request body + var notification ApplicationContextDeleteNotification + decoder := json.NewDecoder(r.Body) + err := decoder.Decode(¬ification) + if err != nil { + log.Error(err) + w.WriteHeader(http.StatusInternalServerError) + fmt.Fprintf(w, "Error Decoding Notification") + } + log.Info("Application Context Delete notification: notification: ", notification) + + // Remove AppContext entry + delete(appContexts, notification.ContextId) + log.Debug("Application Context Delete notification, contextId: " + notification.ContextId + " [200]") + appActivityLogs = append(appActivityLogs, mep+" Application Context Delete notification, contextId: "+notification.ContextId+" [200]") + + w.WriteHeader(http.StatusOK) +} + +// REST API handle service subscription callback notification +func serviceAvailNotificationCallback(w http.ResponseWriter, r *http.Request) { + + // Decode request body + var notification smc.ServiceAvailabilityNotification + decoder := json.NewDecoder(r.Body) + err := decoder.Decode(¬ification) + if err != nil { + log.Error(err) + w.WriteHeader(http.StatusInternalServerError) + fmt.Fprintf(w, "Error Decoding Notification") + } + log.Info("Received service availability notification") + + msg := "" + if *notification.ServiceReferences[0].ChangeType == "ADDED" { + msg = "Available" + } else { + msg = "Unavailable" + } + + if msg == "Available" { + // Retrieve MEC service by serviceId + serviceId := notification.ServiceReferences[0].SerInstanceId + svcInfo, _, err := srvMgmtClient.MecServiceMgmtApi.ServicesServiceIdGET(context.TODO(), serviceId) + if err != nil { + log.Error(err) + w.WriteHeader(http.StatusInternalServerError) + fmt.Fprintf(w, "Error Retrieving MEC Services") + appActivityLogs = append(appActivityLogs, mep+" Event: Service Availability change, "+notification.ServiceReferences[0].SerName+" service "+msg+" [500]") + } + + // Update Discovered Service + tempService := ApplicationInstanceDiscoveredServices{ + SerName: svcInfo.SerName, + SerInstanceId: svcInfo.SerInstanceId, + ConsumedLocalOnly: svcInfo.ConsumedLocalOnly, + Link: svcInfo.TransportInfo.Endpoint.Uris[0], + Version: svcInfo.TransportInfo.Version, + } + demoAppInfo.DiscoveredServices = append(demoAppInfo.DiscoveredServices, tempService) + mecServicesMap[tempService.SerName] = tempService.Link + } else { + // Remove Service from Discovered Service + for i, e := range demoAppInfo.DiscoveredServices { + if e.SerName == notification.ServiceReferences[0].SerName && e.SerInstanceId == notification.ServiceReferences[0].SerInstanceId { + + if i < len(demoAppInfo.DiscoveredServices)-1 { + demoAppInfo.DiscoveredServices = append(demoAppInfo.DiscoveredServices[:i], demoAppInfo.DiscoveredServices[i+1:]...) + } + demoAppInfo.DiscoveredServices = demoAppInfo.DiscoveredServices[:len(demoAppInfo.DiscoveredServices)-1] + } + } + delete(mecServicesMap, notification.ServiceReferences[0].SerName) + } + + state := "" + if *notification.ServiceReferences[0].State == smc.ACTIVE_ServiceState { + state = "ACTIVE" + } else { + state = "UNACTIVE" + } + log.Info(notification.ServiceReferences[0].SerName + " " + msg + " (" + state + ")") + appActivityLogs = append(appActivityLogs, mep+" Event: Service Availability change, "+notification.ServiceReferences[0].SerName+" service "+msg+" [200]") + w.WriteHeader(http.StatusOK) + +} + +// Client request to notify mec platform of mec app +func sendReadyConfirmation(appInstanceId string) error { + + var appReady asc.AppReadyConfirmation + appReady.Indication = "READY" + log.Info(appSupportClientPath) + resp, err := appSupportClient.MecAppSupportApi.ApplicationsConfirmReadyPOST(context.TODO(), appReady, appInstanceId) + if err != nil { + log.Error(err.Error()) + //log.Error("Failed to receive confirmation acknowlegement ", resp.Status) + appActivityLogs = append(appActivityLogs, "Send confirm ready ["+err.Error()+"]") + return err + } + status := strconv.Itoa(resp.StatusCode) + + appActivityLogs = append(appActivityLogs, "Send confirm ready ["+status+"]") + return nil +} + +// Client request to retrieve list of mec service resources on sandbox +func getMecServices() ([]smc.ServiceInfo, error) { + + appServicesResponse, _, err := srvMgmtClient.MecServiceMgmtApi.ServicesGET(context.TODO(), nil) + if err != nil { + log.Error("Failed to retrieve mec services on platform ", err) + return nil, err + } + + return appServicesResponse, nil +} + +// Client request to create a mec-service resource +func registerService(appInstanceId string, callBackUrl string) (smc.ServiceInfo, error) { + var srvInfo smc.ServiceInfoPost + srvInfo.SerName = serviceCategory + srvInfo.Version = serviceAppVersion + state := smc.ACTIVE_ServiceState + srvInfo.State = &state + serializer := smc.JSON_SerializerType + srvInfo.Serializer = &serializer + + var transportInfo smc.TransportInfo + transportInfo.Id = "transport" + transportInfo.Name = "REST" + transportType := smc.REST_HTTP_TransportType + transportInfo.Type_ = &transportType + transportInfo.Protocol = "HTTP" + transportInfo.Version = "2.0" + var endpoint smc.OneOfTransportInfoEndpoint + + endpointPath := callBackUrl + "/application/transfer" + endpoint.Uris = append(endpoint.Uris, endpointPath) + transportInfo.Endpoint = &endpoint + srvInfo.TransportInfo = &transportInfo + + var category smc.CategoryRef + category.Href = "catalogueHref" + category.Id = "amsId" + category.Name = "AMSI" + category.Version = "v1" + srvInfo.SerCategory = &category + + localityType := smc.LocalityType(scopeOfLocality) + srvInfo.ScopeOfLocality = &localityType + srvInfo.ConsumedLocalOnly = consumedLocalOnly + appServicesPostResponse, _, err := srvMgmtClient.MecServiceMgmtApi.AppServicesPOST(context.TODO(), srvInfo, appInstanceId) + if err != nil { + log.Error("Failed to register service resource on mec app enablement registry: ", err) + return appServicesPostResponse, err + } + appEnablementServiceId = appServicesPostResponse.SerInstanceId + return appServicesPostResponse, nil +} + +// Client request to sent confirm terminate +func confirmTerminate(appInstanceId string) { + operationAction := asc.TERMINATING_OperationActionType + var terminationBody asc.AppTerminationConfirmation + terminationBody.OperationAction = &operationAction + resp, err := appSupportClient.MecAppSupportApi.ApplicationsConfirmTerminationPOST(context.TODO(), terminationBody, appInstanceId) + status := strconv.Itoa(resp.StatusCode) + if err != nil { + log.Error("Failed to send confirm termination ", err) + } else { + log.Info("Confirm Terminated") + } + log.Debug("confirmTerminate: ", status) + appActivityLogs = append(appActivityLogs, "Confirm Terminated ["+status+"]") +} + +// Client request to subscribe app-termination notifications +func subscribeAppTermination(appInstanceId string, callBackReference string) (string, error) { + log.Debug("Sending request to mec platform add app terminate subscription api") + var appTerminationBody asc.AppTerminationNotificationSubscription + appTerminationBody.SubscriptionType = "AppTerminationNotificationSubscription" + appTerminationBody.CallbackReference = callBackReference + appTerminationBody.AppInstanceId = appInstanceId + appTerminationResponse, _, err := appSupportClient.MecAppSupportApi.ApplicationsSubscriptionsPOST(context.TODO(), appTerminationBody, appInstanceId) + + if err != nil { + log.Error("Failed to send termination subscription: ", err) + appActivityLogs = append(appActivityLogs, "Subscribe to app-termination notification [501]") + return "", err + } + + hRefLink := appTerminationResponse.Links.Self.Href + + // Find subscription id from response + idPosition := strings.LastIndex(hRefLink, "/") + if idPosition == -1 { + log.Error("Error parsing subscription id for subscription") + } + + terminationSubscriptionId = hRefLink[idPosition+1:] + + log.Debug("subscribeAppTermination: Subscribe to app-termination notification [201]: ", terminationSubscriptionId) + appActivityLogs = append(appActivityLogs, "Subscribe to app-termination notification [201]") + return terminationSubscriptionId, nil +} + +// Client request to subscribe service-availability notifications +func subscribeAvailability(appInstanceId string, callbackReference string) (string, error) { + log.Debug("Sending request to mec platform add service-avail subscription api") + var filter smc.SerAvailabilityNotificationSubscriptionFilteringCriteria + filter.SerNames = nil + filter.IsLocal = true + subscription := smc.SerAvailabilityNotificationSubscription{"SerAvailabilityNotificationSubscription", callbackReference, nil, &filter} + serAvailabilityNotificationSubscription, resp, err := srvMgmtClient.MecServiceMgmtApi.ApplicationsSubscriptionsPOST(context.TODO(), subscription, appInstanceId) + status := strconv.Itoa(resp.StatusCode) + if err != nil { + log.Error("Failed to send service subscription: ", err) + appActivityLogs = append(appActivityLogs, "Subscribe to service-availability notification ["+status+"]") + return "", err + } + hRefLink := serAvailabilityNotificationSubscription.Links.Self.Href + + // Find subscription id from response + idPosition := strings.LastIndex(hRefLink, "/") + if idPosition == -1 { + log.Error("Error parsing subscription id for subscription") + } + subscriptionId := hRefLink[idPosition+1:] + + log.Info("Subscribed to service availibility notification on mec platform: ", status) + appActivityLogs = append(appActivityLogs, "Subscribe to service-availability notification ["+status+"]") + + return subscriptionId, nil +} + +// Client request to delete a mec-service resource +func unregisterService(appInstanceId string, serviceId string) error { + resp, err := srvMgmtClient.MecServiceMgmtApi.AppServicesServiceIdDELETE(context.TODO(), appInstanceId, serviceId) + status := strconv.Itoa(resp.StatusCode) + if err != nil { + log.Error("Failed to send request to delete service resource on mec platform ", err) + + appActivityLogs = append(appActivityLogs, "Delete Demo4 service ["+status+"]") + + return err + } + + appActivityLogs = append(appActivityLogs, "Delete Demo4 service ["+status+"]") + return nil +} + +// Client request to delete app-termination subscriptions +func delAppTerminationSubscription(appInstanceId string, subscriptionId string) error { + + resp, err := appSupportClient.MecAppSupportApi.ApplicationsSubscriptionDELETE(context.TODO(), appInstanceId, subscriptionId) + status := strconv.Itoa(resp.StatusCode) + if err != nil { + log.Error("Failed to clear app termination subscription ", resp.Status) + appActivityLogs = append(appActivityLogs, "Delete App-termination subscription ["+status+"]") + return err + } + + appActivityLogs = append(appActivityLogs, "Delete App-termination subscription ["+status+"]") + return nil +} + +// Client request to delete subscription of service-availability notifications +func delsubscribeAvailability(appInstanceId string, subscriptionId string) error { + + resp, err := srvMgmtClient.MecServiceMgmtApi.ApplicationsSubscriptionDELETE(context.TODO(), appInstanceId, subscriptionId) + status := strconv.Itoa(resp.StatusCode) + if err != nil { + log.Error("Failed to clear service availability subscriptions: ", resp.Status) + appActivityLogs = append(appActivityLogs, "Delete Service-avail subscription ["+status+"]") + return err + } + appActivityLogs = append(appActivityLogs, "Delete Service-avail subscription ["+status+"]") + return nil +} + +// REST API retrieve app instance info +func demo4GetPlatformInfo(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json; charset=UTF-8") + // Send resp + jsonResponse, err := json.Marshal(demoAppInfo) + if err != nil { + log.Error(err.Error()) + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + w.WriteHeader(http.StatusOK) + fmt.Fprintf(w, string(jsonResponse)) +} + +// REST API retrieve activity logs +func demo4GetActivityLogs(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json; charset=UTF-8") + var resp []string + for i := len(appActivityLogs) - 1; i >= 0; i-- { + lineNumber := strconv.Itoa(i) + resp = append(resp, lineNumber+". "+appActivityLogs[i]) + } + + jsonResponse, err := json.Marshal(resp) + if err != nil { + log.Error(err.Error()) + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + w.WriteHeader(http.StatusOK) + fmt.Fprintf(w, string(jsonResponse)) +} + +// REST API retrieve activity logs +func demo4DaiAppListGET(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json; charset=UTF-8") + + applicationList, response, err := daiClient.DevAppApi.MeAppListGET(context.TODO(), nil) + if err != nil { + log.Error("Failed to get ApplicationList: ", err) + appActivityLogs = append(appActivityLogs, "Failed to get ApplicationList ["+err.Error()+"]") + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + appActivityLogs = append(appActivityLogs, "demo4DaiAppListGET: applicationList succeed, len= "+strconv.Itoa(len(applicationList.AppList))) + log.Debug("demo4DaiAppListGET: len(appInfoList.AppList): ", len(applicationList.AppList)) + + // TODO Add Logic + //var applicationList ApplicationList + + // Send resp + log.Debug("demo4DaiAppListGET: response.Body: ", response.Body) + jsonResponse, err := json.Marshal(applicationList) + if err != nil { + log.Error(err.Error()) + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + w.WriteHeader(http.StatusOK) + fmt.Fprintf(w, string(jsonResponse)) +} + +// REST API retrieve activity logs +const ( + simu_appName = "onboarded-demo4" + simu_appDId = "onboarded-demo4" + simu_appProvider = "ETSI" + simu_appDVersion = "v0.1.0" + simu_appSoftVersion = "v0.1.0" + simu_appDescription = "Basic HTTP Ping Pong" + //simu_area = Coordinates{[][][]float32{{{7.43166, 43.736156}, {7.431723, 43.736115}, {7.431162, 43.735607}, {7.430685, 43.73518}}}} + simu_countryCode = "33" + simu_appPackageSource = "appPackageSource1" +) + +// REST API sends ping request and get response +func demo4DaiDoPingGET(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json; charset=UTF-8") + + // Check if a MEC application context is existing + log.Debug("demo4DaiDoPingGET: appContexts= ", appContexts) + if len(appContexts) == 0 { + err := errors.New("No context created, please use POST /dai/instantiate") + log.Error(err.Error()) + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + vars := mux.Vars(r) + contextId := vars["appcontextid"] + log.Info("demo4DaiDoPingGET: contextId: ", contextId) + + // Retrieve the appContextId + var appContextId string + for k := range appContexts { + if k == contextId { + log.Debug("demo4DaiDoPingGET: Set appContextId to ", k) + appContextId = k + break + } + } // End of 'for' statement + log.Debug("demo4DaiDoPingGET: appContextId: ", appContextId) + if appContextId == "" { // Not found + err := errors.New("demo4DaiDoPingGET: Invalid AppContext identifier") + appActivityLogs = append(appActivityLogs, "demo4DaiDoPingGET: Invalid AppContext identifier") + log.Error(err.Error()) + http.Error(w, err.Error(), http.StatusNotFound) + return + } + + // Send the ping request + appActivityLogs = append(appActivityLogs, "demo4DaiDoPingGET: Send ping request: ", strings.TrimSuffix(appContexts[appContextId].app.AppInfo.UserAppInstanceInfo[0].ReferenceURI, "/")+"/ping") + resp, err := http.Get(strings.TrimSuffix(appContexts[appContextId].app.AppInfo.UserAppInstanceInfo[0].ReferenceURI, "/") + "/ping") + if err != nil { + log.Error(err.Error()) + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + log.Debug("demo4DaiDoPingGET: Sent: ", resp.Body) + bodyBytes, _ := ioutil.ReadAll(resp.Body) + log.Debug("demo4DaiDoPingGET: resp: ", string(bodyBytes)) + + // Send resp + statusCode, err := strconv.Atoi(strings.Split(resp.Status, " ")[0]) + if err != nil { + log.Error(err.Error()) + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + w.WriteHeader(statusCode) + fmt.Fprintf(w, string(bodyBytes)) +} + +// REST API creates a new instance of an onboarded MEC application +func demo4DaiDoPingPOST(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json; charset=UTF-8") + + // Check if a MEC application context is existing + var appContextId string + log.Debug("demo4DaiDoPingPOST: appContexts= ", appContexts) + if len(appContexts) == 0 { + // Create a new context + userAppInstanceInfo := make([]dai.AppContextAppInfoUserAppInstanceInfo, 1) + userAppInstanceInfo[0].AppLocation = new(dai.LocationConstraints) + userAppInstanceInfo[0].AppLocation.CountryCode = simu_countryCode + appInfo := dai.AppContextAppInfo{simu_appDId, simu_appDVersion, simu_appDescription, simu_appName, simu_appProvider, simu_appSoftVersion, simu_appPackageSource, userAppInstanceInfo} + appContext := dai.AppContext{true, &appInfo, true, uuid.New().String()[0:32], callBackUrl, ""} + log.Debug("demo4DaiDoPingPOST: appContext: ", appContext) + appContext, response, err := daiClient.DevAppApi.DevAppContextsPOST(context.TODO(), appContext) + if err != nil { + log.Error("Failed to create new AppContext: ", err) + appActivityLogs = append(appActivityLogs, "Failed to create new AppContext ["+err.Error()+"]") + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + log.Debug("demo4DaiDoPingPOST: appContext.ContextId: ", appContext.ContextId) + log.Debug("demo4DaiDoPingPOST: aappContextpp.AppInfo: ", appContext.AppInfo) + log.Debug("demo4DaiDoPingPOST: appContext.AppInfo.UserAppInstanceInfo: ", appContext.AppInfo.UserAppInstanceInfo) + appActivityLogs = append(appActivityLogs, "demo4DaiDoPingPOST: AppContext creation succeed, "+string(response.StatusCode)) + log.Debug("demo4DaiDoPingPOST: AppContext creation succeed, response= ", response.StatusCode) + // Update appContext + appContexts[appContext.ContextId] = AppContextState{appContext} + appContextId = appContext.ContextId + } else { + for k := range appContexts { + log.Debug("demo4DaiDoPingPOST: Set appContextId to ", k) + appContextId = k + } // End of 'for' statement + err := errors.New("MEC Application already instanciated: " + appContextId) + appActivityLogs = append(appActivityLogs, "demo4DaiDoPingPOST: "+err.Error()) + log.Error(err.Error()) + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + appActivityLogs = append(appActivityLogs, "demo4DaiDoPingPOST: appContextId: "+appContextId) + log.Debug("demo4DaiDoPingPOST: appContextId: ", appContextId) + + // Send resp + jsonResponse, err := json.Marshal(appContexts[appContextId].app) + if err != nil { + log.Error(err.Error()) + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + w.WriteHeader(http.StatusCreated) + fmt.Fprintf(w, string(jsonResponse)) +} + +// REST API creates an existing instance of an onboarded MEC application +func demo4DaiDoPingDELETE(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json; charset=UTF-8") + + log.Debug("demo4DaiDoPingDELETE: appContexts= ", appContexts) + if len(appContexts) == 0 { + err := errors.New("No context created, please use POST /dai/instantiate") + appActivityLogs = append(appActivityLogs, "demo4DaiDoPingDELETE: "+err.Error()) + log.Error(err.Error()) + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + vars := mux.Vars(r) + contextId := vars["appcontextid"] + log.Info("demo4DaiDoPingDELETE: contextId: ", contextId) + + // Retrieve the appContextId + var appContextId string + for k := range appContexts { + if k == contextId { + log.Debug("demo4DaiDoPingDELETE: Set appContextId to ", k) + appContextId = k + break + } + } // End of 'for' statement + log.Debug("demo4DaiDoPingDELETE: appContextId: ", appContextId) + if appContextId == "" { // Not found + err := errors.New("demo4DaiDoPingDELETE: Invalid AppContext identifier") + appActivityLogs = append(appActivityLogs, "demo4DaiDoPingDELETE: Invalid AppContext identifier") + log.Error(err.Error()) + http.Error(w, err.Error(), http.StatusNotFound) + return + } + + _ /*resp*/, err := daiClient.DevAppApi.DevAppContextDELETE(context.TODO(), appContextId) + if err != nil { + err := errors.New("Failed to delete appContextId: " + appContextId) + appActivityLogs = append(appActivityLogs, "demo4DaiDoPingDELETE: Failed to delete appContextId ["+err.Error()+"]") + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + // Remove it from appContexts + delete(appContexts, appContextId) + log.Debug("demo4DaiDoPingDELETE: Updated appContexts= ", appContexts) + + // Send resp + w.WriteHeader(http.StatusNoContent) +} + +// REST API retrieve location constraints of an existing instance of an onboarded MEC application +func demo4DaiAppLocationAvailabilityPOST(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json; charset=UTF-8") + + // Check if a MEC application context is existing + log.Debug("demo4DaiAppLocationAvailabilityPOST: appContexts= ", appContexts) + if len(appContexts) == 0 { + err := errors.New("No context created, please use POST /dai/instantiate") + appActivityLogs = append(appActivityLogs, "demo4DaiDoPingDELETE: "+err.Error()) + log.Error(err.Error()) + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + vars := mux.Vars(r) + contextId := vars["appcontextid"] + log.Info("demo4DaiAppLocationAvailabilityPOST: contextId: ", contextId) + + // Retrieve the appContextId + var appContextId string + for k := range appContexts { + if k == contextId { + log.Debug("demo4DaiAppLocationAvailabilityPOST: Set appContextId to ", k) + appContextId = k + break + } + } // End of 'for' statement + log.Debug("demo4DaiAppLocationAvailabilityPOST: appContextId: ", appContextId) + if appContextId == "" { // Not found + err := errors.New("demo4DaiAppLocationAvailabilityPOST: Invalid AppContext identifier") + appActivityLogs = append(appActivityLogs, "demo4DaiAppLocationAvailabilityPOST: Invalid AppContext identifier") + log.Error(err.Error()) + http.Error(w, err.Error(), http.StatusNotFound) + return + } + + // Create a ApplicationLocationAvailability + var appInfo dai.ApplicationLocationAvailabilityAppInfo + appInfo.AppDVersion = appContexts[appContextId].app.AppInfo.AppDVersion + appInfo.AppDescription = appContexts[appContextId].app.AppInfo.AppDescription + appInfo.AppName = appContexts[appContextId].app.AppInfo.AppName + appInfo.AppPackageSource = appContexts[appContextId].app.AppInfo.AppPackageSource + appInfo.AppProvider = appContexts[appContextId].app.AppInfo.AppProvider + appInfo.AppSoftVersion = appContexts[appContextId].app.AppInfo.AppSoftVersion + var applicationLocationAvailability dai.ApplicationLocationAvailability + applicationLocationAvailability.AppInfo = &appInfo + applicationLocationAvailability.AssociateDevAppId = appContexts[appContextId].app.AssociateDevAppId + + appLocAv, response, err := daiClient.DevAppApi.AppLocationAvailabilityPOST(context.TODO(), applicationLocationAvailability) + if err != nil { + log.Error(err.Error()) + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + log.Debug("demo4DaiAppLocationAvailabilityPOST: Status: ", response.Status) + + // Send resp + jsonResponse, err := json.Marshal(appLocAv) + if err != nil { + log.Error(err.Error()) + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + w.WriteHeader(http.StatusOK) + fmt.Fprintf(w, string(jsonResponse)) +} + +// Rest API handle user-app termination call-back notification +func appTerminationNotificationCallback(w http.ResponseWriter, r *http.Request) { + var notification asc.AppTerminationNotification + decoder := json.NewDecoder(r.Body) + err := decoder.Decode(¬ification) + if err != nil { + log.Error(err.Error()) + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + log.Info("Received user-app termination notification") + appActivityLogs = append(appActivityLogs, "Received user-app termination notification") + w.WriteHeader(http.StatusOK) + terminateNotification = true + demoAppInfo.MecTerminated = true + Terminate() +} + +func startProcessLocTicker() { + // Make sure ticker is not running + if locTicker != nil { + log.Warn("Registration ticker already running") + return + } + + // Start registration ticker + locTicker = time.NewTicker(locExpiry) + go func() { + + for range locTicker.C { + + // Get UI position + s := make([]string, 1) + s[0] = nodeName + var localVarOptionals loc.UsersGETOpts + localVarOptionals.Address = optional.NewInterface(s) + log.Debug("startProcessLocTicker: Call UsersGet with: ", localVarOptionals) + usersList, _, err := locServ.LocationApi.UsersGET(context.TODO(), &localVarOptionals) + if err != nil { + log.Error("UsersGet: Failed: ", err) + continue // Infinite loop till stopProcessCheckTicker is call + } + if usersList.UserList != nil { + log.Debug("startProcessLocTicker: usersList: ", usersList.UserList) + log.Debug("startProcessLocTicker: usersList: ", len(usersList.UserList.User)) + if len(usersList.UserList.User) != 0 { + for _, u := range usersList.UserList.User { + if u.Address == nodeName && u.LocationInfo != nil { + userInfo = u + log.Debug("startProcessLocTicker: New position: ", userInfo.LocationInfo) + break + } + } // End of 'for' statement + } + } + + continue // Infinite loop till stopProcessCheckTicker is call + } // End of 'for' statement + }() +} + +func stopProcessLocTicker() { + if locTicker != nil { + log.Info("Stopping App Enablement registration ticker") + locTicker.Stop() + locTicker = nil + } +} diff --git a/examples/demo4-ue/src/demo-server/backend/server/logger.go b/examples/demo4-ue/src/demo-server/backend/server/logger.go new file mode 100644 index 000000000..6f4168e04 --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/server/logger.go @@ -0,0 +1,47 @@ +/* + * 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. + * + * MEEP Demo 4 API + * Demo 4 is an edge application that can be used with AdvantEDGE or ETSI MEC Sandbox to demonstrate MEC016 usage + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 0.0.1 + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package server + +import ( + "log" + "net/http" + "time" +) + +func Logger(inner http.Handler, name string) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + start := time.Now() + + inner.ServeHTTP(w, r) + + log.Printf( + "%s %s %s %s", + r.Method, + r.RequestURI, + name, + time.Since(start), + ) + }) +} diff --git a/examples/demo4-ue/src/demo-server/backend/server/model_address_change_notification.go b/examples/demo4-ue/src/demo-server/backend/server/model_address_change_notification.go new file mode 100644 index 000000000..05ee3a2d2 --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/server/model_address_change_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. + * + * MEEP Demo 4 API + * Demo 4 is an edge application that can be used with AdvantEDGE or ETSI MEC Sandbox to demonstrate MEC016 usage + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 0.0.1 + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package server + +type AddressChangeNotification struct { + // Identifier of the user application instance. + AppInstanceId string `json:"appInstanceId"` + // Uniquely identifies the application context in the MEC system. + ContextId string `json:"contextId"` + // Shall be set to \"AddressChangeNotification\". + NotificationType string `json:"notificationType"` + // Address of the user application. Used as the reference URI for the application. Assigned by the MEC system. + ReferenceURI string `json:"referenceURI"` +} diff --git a/examples/demo4-ue/src/demo-server/backend/server/model_app_context.go b/examples/demo4-ue/src/demo-server/backend/server/model_app_context.go new file mode 100644 index 000000000..e2a84dd8a --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/server/model_app_context.go @@ -0,0 +1,39 @@ +/* + * 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. + * + * MEEP Demo 4 API + * Demo 4 is an edge application that can be used with AdvantEDGE or ETSI MEC Sandbox to demonstrate MEC016 usage + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 0.0.1 + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package server + +type AppContext struct { + // Provides indication to the MEC system that instantiation of the requested application is desired should a requested appLocation become available that was not at the time of the request. + AppAutoInstantiation bool `json:"appAutoInstantiation,omitempty"` + AppInfo *AppContextAppInfo `json:"appInfo"` + // Used by the device application to request to receive notifications at the callbackReference URI relating to location availability for user application instantiation. + AppLocationUpdates bool `json:"appLocationUpdates,omitempty"` + // Uniquely identifies the device application. The length of the value shall not exceed 32 characters. + AssociateDevAppId string `json:"associateDevAppId"` + // URI assigned by the device application to receive application lifecycle related notifications. Inclusion in the request implies the client supports the pub/sub mechanism and is capable of receiving notifications. This endpoint shall be maintained for the lifetime of the application context. + CallbackReference string `json:"callbackReference,omitempty"` + // Uniquely identifies the application context in the MEC system. Assigned by the MEC system and shall be present other than in a create request. The length of the value shall not exceed 32 characters. + ContextId string `json:"contextId,omitempty"` +} diff --git a/examples/demo4-ue/src/demo-server/backend/server/model_app_context_app_info.go b/examples/demo4-ue/src/demo-server/backend/server/model_app_context_app_info.go new file mode 100644 index 000000000..6691a2d0a --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/server/model_app_context_app_info.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. + * + * MEEP Demo 4 API + * Demo 4 is an edge application that can be used with AdvantEDGE or ETSI MEC Sandbox to demonstrate MEC016 usage + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 0.0.1 + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package server + +type AppContextAppInfo struct { + // Identifier of this MEC application descriptor. This attribute shall be globally unique. It is equivalent to the appDId defined in clause 6.2.1.2 of ETSI GS MEC 0102 [1]. It shall be present if the application is one in the ApplicationList. + AppDId string `json:"appDId,omitempty"` + // Identifies the version of the application descriptor. It is equivalent to the appDVersion defined in clause 6.2.1.2 of ETSI GS MEC 0102 [1]. + AppDVersion string `json:"appDVersion"` + // Human readable description of the MEC application. The length of the value shall not exceed 128 characters. + AppDescription string `json:"appDescription,omitempty"` + // Name of the MEC application. The length of the value shall not exceed 32 characters. + AppName string `json:"appName"` + // Provider of the MEC application. The length of the value shall not exceed 32 characters. + AppProvider string `json:"appProvider"` + // Software version of the MEC application. The length of the value shall not exceed 32 characters. + AppSoftVersion string `json:"appSoftVersion,omitempty"` + // URI of the application package. Included in the request if the application is not one in the ApplicationList. appPackageSource enables on-boarding of the application package into the MEC system. The application package shall comply with the definitions in clause 6.2.1.2 of ETSI GS MEC 0102 [1]. + AppPackageSource string `json:"appPackageSource,omitempty"` + // List of user application instance information. + UserAppInstanceInfo []AppContextAppInfoUserAppInstanceInfo `json:"userAppInstanceInfo"` +} diff --git a/examples/demo4-ue/src/demo-server/backend/server/model_app_context_app_info_user_app_instance_info.go b/examples/demo4-ue/src/demo-server/backend/server/model_app_context_app_info_user_app_instance_info.go new file mode 100644 index 000000000..28615a5d5 --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/server/model_app_context_app_info_user_app_instance_info.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. + * + * MEEP Demo 4 API + * Demo 4 is an edge application that can be used with AdvantEDGE or ETSI MEC Sandbox to demonstrate MEC016 usage + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 0.0.1 + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package server + +type AppContextAppInfoUserAppInstanceInfo struct { + // Identifier of the user application instance. It shall only be included in the response. + AppInstanceId string `json:"appInstanceId,omitempty"` + AppLocation *LocationConstraints `json:"appLocation,omitempty"` + // Address of the user application instance. It shall only be included in the response. + ReferenceURI string `json:"referenceURI,omitempty"` +} diff --git a/examples/demo4-ue/src/demo-server/backend/server/model_app_termination_subscription.go b/examples/demo4-ue/src/demo-server/backend/server/model_app_termination_subscription.go new file mode 100644 index 000000000..65a764bce --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/server/model_app_termination_subscription.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. + * + * MEEP Demo 4 API + * Demo 4 is an edge application that can be used with AdvantEDGE or ETSI MEC Sandbox to demonstrate MEC016 usage + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 0.0.1 + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package server + +// This type represents the information that the MEC platform notifies the subscribed application instance about the corresponding application instance termination/stop. +type AppTerminationSubscription struct { + // Shall be set to AppTerminationSubscription. + SubscriptionType string `json:"subscriptionType"` + // URI selected by the MEC application instance to receive notifications on the subscribed MEC application instance management information. This shall be included in both the request and the response. + CallbackReference string `json:"callbackReference"` + Links *AppTerminationSubscriptionLinks `json:"_links"` + // It is used as the filtering criterion for the subscribed events. + AppInstanceId string `json:"appInstanceId"` +} diff --git a/examples/demo4-ue/src/demo-server/backend/server/model_app_termination_subscription__links.go b/examples/demo4-ue/src/demo-server/backend/server/model_app_termination_subscription__links.go new file mode 100644 index 000000000..1d35448ea --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/server/model_app_termination_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. + * + * MEEP Demo 4 API + * Demo 4 is an edge application that can be used with AdvantEDGE or ETSI MEC Sandbox to demonstrate MEC016 usage + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 0.0.1 + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package server + +// Self-referring URI. +type AppTerminationSubscriptionLinks struct { + Self *LinkType `json:"self"` +} diff --git a/examples/demo4-ue/src/demo-server/backend/server/model_application_context_delete_notification.go b/examples/demo4-ue/src/demo-server/backend/server/model_application_context_delete_notification.go new file mode 100644 index 000000000..1b3d6a51b --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/server/model_application_context_delete_notification.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. + * + * MEEP Demo 4 API + * Demo 4 is an edge application that can be used with AdvantEDGE or ETSI MEC Sandbox to demonstrate MEC016 usage + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 0.0.1 + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package server + +type ApplicationContextDeleteNotification struct { + // Uniquely identifies the application context that has been deleted from the MEC system. + ContextId string `json:"contextId"` + // Shall be set to \"ApplicationContextDeleteNotification\". + NotificationType string `json:"notificationType"` +} diff --git a/examples/demo4-ue/src/demo-server/backend/server/model_application_context_state.go b/examples/demo4-ue/src/demo-server/backend/server/model_application_context_state.go new file mode 100644 index 000000000..bf1e4d74c --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/server/model_application_context_state.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. + * + * MEEP Demo 4 API + * Demo 4 is an edge application that can be used with AdvantEDGE or ETSI MEC Sandbox to demonstrate MEC016 usage + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 0.0.1 + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package server + +type ApplicationContextState struct { + // Integer representing state of device being tracked + Counter int32 `json:"Counter,omitempty"` + // Application UUID + AppId string `json:"AppId,omitempty"` + // MEC platform name + Mep string `json:"Mep,omitempty"` + // Terminal device application is tracking + Device string `json:"Device,omitempty"` +} diff --git a/examples/demo4-ue/src/demo-server/backend/server/model_application_context_update_notification.go b/examples/demo4-ue/src/demo-server/backend/server/model_application_context_update_notification.go new file mode 100644 index 000000000..246ff7b13 --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/server/model_application_context_update_notification.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. + * + * MEEP Demo 4 API + * Demo 4 is an edge application that can be used with AdvantEDGE or ETSI MEC Sandbox to demonstrate MEC016 usage + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 0.0.1 + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package server + +type ApplicationContextUpdateNotification struct { + // Uniquely identifies the application context in the MEC system. + ContextId string `json:"contextId"` + // Shall be set to \"ApplicationContextUpdateNotification\". + NotificationType string `json:"notificationType"` + // List of user application instance information. + UserAppInstanceInfo []ApplicationContextUpdateNotificationUserAppInstanceInfo `json:"userAppInstanceInfo"` +} diff --git a/examples/demo4-ue/src/demo-server/backend/server/model_application_context_update_notification_user_app_instance_info.go b/examples/demo4-ue/src/demo-server/backend/server/model_application_context_update_notification_user_app_instance_info.go new file mode 100644 index 000000000..46787a387 --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/server/model_application_context_update_notification_user_app_instance_info.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. + * + * MEEP Demo 4 API + * Demo 4 is an edge application that can be used with AdvantEDGE or ETSI MEC Sandbox to demonstrate MEC016 usage + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 0.0.1 + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package server + +type ApplicationContextUpdateNotificationUserAppInstanceInfo struct { + // Identifier of the user application instance. + AppInstanceId string `json:"appInstanceId,omitempty"` + AppLocation *LocationConstraints `json:"appLocation,omitempty"` + // Address of the user application instance. + ReferenceURI string `json:"referenceURI,omitempty"` +} diff --git a/examples/demo4-ue/src/demo-server/backend/server/model_application_instance.go b/examples/demo4-ue/src/demo-server/backend/server/model_application_instance.go new file mode 100644 index 000000000..7da2ceea7 --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/server/model_application_instance.go @@ -0,0 +1,43 @@ +/* + * 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. + * + * MEEP Demo 4 API + * Demo 4 is an edge application that can be used with AdvantEDGE or ETSI MEC Sandbox to demonstrate MEC016 usage + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 0.0.1 + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package server + +// This type represent information to display on frontend app instance text field +type ApplicationInstance struct { + Name string `json:"name,omitempty"` + Url string `json:"url,omitempty"` + Config string `json:"config,omitempty"` + Ip string `json:"ip,omitempty"` + Id string `json:"id,omitempty"` + // Confirm if app instance is ready + MecReady bool `json:"mecReady,omitempty"` + // Confirm the application level termination of application instance + MecTerminated bool `json:"mecTerminated,omitempty"` + // Confirm if app instance has an ams service resource + AmsResource bool `json:"amsResource,omitempty"` + Subscriptions *ApplicationInstanceSubscriptions `json:"subscriptions,omitempty"` + OfferedService *ApplicationInstanceOfferedService `json:"offeredService,omitempty"` + DiscoveredServices []ApplicationInstanceDiscoveredServices `json:"discoveredServices,omitempty"` +} diff --git a/examples/demo4-ue/src/demo-server/backend/server/model_application_instance_ams_link_list_subscription.go b/examples/demo4-ue/src/demo-server/backend/server/model_application_instance_ams_link_list_subscription.go new file mode 100644 index 000000000..80f60b035 --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/server/model_application_instance_ams_link_list_subscription.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. + * + * MEEP Demo 4 API + * Demo 4 is an edge application that can be used with AdvantEDGE or ETSI MEC Sandbox to demonstrate MEC016 usage + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 0.0.1 + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package server + +// This type represents the information that the MEC platform notifies the subscribed application instance about app mobility support +type ApplicationInstanceAmsLinkListSubscription struct { + SubId string `json:"subId,omitempty"` + // 0 to N identifiers to associate the information for specific UE(s) and flow(s). + AssociateId []AssociateId `json:"associateId,omitempty"` +} diff --git a/examples/demo4-ue/src/demo-server/backend/server/model_application_instance_app_termination_subscription.go b/examples/demo4-ue/src/demo-server/backend/server/model_application_instance_app_termination_subscription.go new file mode 100644 index 000000000..99305056c --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/server/model_application_instance_app_termination_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. + * + * MEEP Demo 4 API + * Demo 4 is an edge application that can be used with AdvantEDGE or ETSI MEC Sandbox to demonstrate MEC016 usage + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 0.0.1 + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package server + +// This type represents the information that the MEC platform notifies the subscribed application instance about the corresponding application instance termination/stop. +type ApplicationInstanceAppTerminationSubscription struct { + SubId string `json:"subId,omitempty"` +} diff --git a/examples/demo4-ue/src/demo-server/backend/server/model_application_instance_discovered_services.go b/examples/demo4-ue/src/demo-server/backend/server/model_application_instance_discovered_services.go new file mode 100644 index 000000000..6295dcbc7 --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/server/model_application_instance_discovered_services.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. + * + * MEEP Demo 4 API + * Demo 4 is an edge application that can be used with AdvantEDGE or ETSI MEC Sandbox to demonstrate MEC016 usage + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 0.0.1 + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package server + +// List of service name and their status +type ApplicationInstanceDiscoveredServices struct { + // The name of the service. This is how the service producing MEC application identifies the service instance it produces. + SerName string `json:"serName,omitempty"` + // Identifier of the service instance assigned by the MEC platform. + SerInstanceId string `json:"serInstanceId,omitempty"` + // Indicate whether the service can only be consumed by the MEC applications located in the same locality (as defined by scopeOfLocality) as this service instance. + ConsumedLocalOnly bool `json:"consumedLocalOnly,omitempty"` + Link string `json:"link,omitempty"` + // Service version + Version string `json:"version,omitempty"` +} diff --git a/examples/demo4-ue/src/demo-server/backend/server/model_application_instance_offered_service.go b/examples/demo4-ue/src/demo-server/backend/server/model_application_instance_offered_service.go new file mode 100644 index 000000000..f076b2004 --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/server/model_application_instance_offered_service.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. + * + * MEEP Demo 4 API + * Demo 4 is an edge application that can be used with AdvantEDGE or ETSI MEC Sandbox to demonstrate MEC016 usage + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 0.0.1 + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package server + +// service offering +type ApplicationInstanceOfferedService struct { + // The name of the service. This is how the service producing MEC application identifies the service instance it produces. + SerName string `json:"serName,omitempty"` + Id string `json:"id,omitempty"` + State *ServiceState `json:"state,omitempty"` + ScopeOfLocality *LocalityType `json:"scopeOfLocality,omitempty"` + // Indicate whether the service can only be consumed by the MEC applications located in the same locality (as defined by scopeOfLocality) as this service instance. + ConsumedLocalOnly bool `json:"consumedLocalOnly,omitempty"` +} diff --git a/examples/demo4-ue/src/demo-server/backend/server/model_application_instance_ser_availability_subscription.go b/examples/demo4-ue/src/demo-server/backend/server/model_application_instance_ser_availability_subscription.go new file mode 100644 index 000000000..422746e24 --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/server/model_application_instance_ser_availability_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. + * + * MEEP Demo 4 API + * Demo 4 is an edge application that can be used with AdvantEDGE or ETSI MEC Sandbox to demonstrate MEC016 usage + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 0.0.1 + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package server + +// This type represents a subscription to the notifications from the MEC platform regarding the availability of a MEC service or a list of MEC services. +type ApplicationInstanceSerAvailabilitySubscription struct { + SubId string `json:"subId,omitempty"` +} diff --git a/examples/demo4-ue/src/demo-server/backend/server/model_application_instance_subscriptions.go b/examples/demo4-ue/src/demo-server/backend/server/model_application_instance_subscriptions.go new file mode 100644 index 000000000..c5357f57c --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/server/model_application_instance_subscriptions.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. + * + * MEEP Demo 4 API + * Demo 4 is an edge application that can be used with AdvantEDGE or ETSI MEC Sandbox to demonstrate MEC016 usage + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 0.0.1 + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package server + +// List of ams subscription unique to device and their id +type ApplicationInstanceSubscriptions struct { + AppTerminationSubscription *ApplicationInstanceAppTerminationSubscription `json:"AppTerminationSubscription,omitempty"` + SerAvailabilitySubscription *ApplicationInstanceSerAvailabilitySubscription `json:"SerAvailabilitySubscription:,omitempty"` + AmsLinkListSubscription *ApplicationInstanceAmsLinkListSubscription `json:"AmsLinkListSubscription,omitempty"` +} diff --git a/examples/demo4-ue/src/demo-server/backend/server/model_application_list.go b/examples/demo4-ue/src/demo-server/backend/server/model_application_list.go new file mode 100644 index 000000000..844b3eb6b --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/server/model_application_list.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. + * + * MEEP Demo 4 API + * Demo 4 is an edge application that can be used with AdvantEDGE or ETSI MEC Sandbox to demonstrate MEC016 usage + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 0.0.1 + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package server + +type ApplicationList struct { + // List of user applications available to the device application. As defined below. + AppList []ApplicationListAppList `json:"appList,omitempty"` +} diff --git a/examples/demo4-ue/src/demo-server/backend/server/model_application_list_app_info.go b/examples/demo4-ue/src/demo-server/backend/server/model_application_list_app_info.go new file mode 100644 index 000000000..6e5d14147 --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/server/model_application_list_app_info.go @@ -0,0 +1,43 @@ +/* + * 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. + * + * MEEP Demo 4 API + * Demo 4 is an edge application that can be used with AdvantEDGE or ETSI MEC Sandbox to demonstrate MEC016 usage + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 0.0.1 + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package server + +type ApplicationListAppInfo struct { + AppCharcs *ApplicationListAppInfoAppCharcs `json:"appCharcs,omitempty"` + // Identifier of this MEC application descriptor. It is equivalent to the appDId defined in clause 6.2.1.2 of ETSI GS MEC 0102 [1]. This attribute shall be globally unique. + AppDId string `json:"appDId"` + // Identifies the version of the application descriptor. It is equivalent to the appDVersion defined in clause 6.2.1.2 of ETSI GS MEC 0102 [1]. + AppDVersion string `json:"appDVersion"` + // Human readable description of the MEC application (see note 2). + AppDescription string `json:"appDescription"` + // Identifies the locations of the MEC application. + AppLocation []LocationConstraints `json:"appLocation,omitempty"` + // Name of the MEC application. The length of the value shall not exceed 32 characters. + AppName string `json:"appName"` + // Provider of the MEC application. The length of the value shall not exceed 32 characters. + AppProvider string `json:"appProvider"` + // Software version of the MEC application. The length of the value shall not exceed 32 characters. + AppSoftVersion string `json:"appSoftVersion"` +} diff --git a/examples/demo4-ue/src/demo-server/backend/server/model_application_list_app_info_app_charcs.go b/examples/demo4-ue/src/demo-server/backend/server/model_application_list_app_info_app_charcs.go new file mode 100644 index 000000000..61a1a62d0 --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/server/model_application_list_app_info_app_charcs.go @@ -0,0 +1,39 @@ +/* + * 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. + * + * MEEP Demo 4 API + * Demo 4 is an edge application that can be used with AdvantEDGE or ETSI MEC Sandbox to demonstrate MEC016 usage + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 0.0.1 + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package server + +// Characteristics of the application. As defined below. The application characteristics relate to the system resources consumed by the application. A device application can use this information e.g. for estimating the cost of use of the application or for the expected user experience. +type ApplicationListAppInfoAppCharcs struct { + // The required connection bandwidth in kbit/s for the use of the MEC application instance. + Bandwidth int32 `json:"bandwidth,omitempty"` + // The target round trip time in milliseconds supported by the MEC system for the MEC application instance. + Latency int32 `json:"latency,omitempty"` + // The maximum size in Mbytes of the memory resource expected to be used by the MEC application instance in the MEC system. + Memory int32 `json:"memory,omitempty"` + // Required service continuity mode for this application. Permitted values: 0 = SERVICE_CONTINUITY_NOT_REQUIRED. 1 = SERVICE_CONTINUITY_REQUIRED. + ServiceCont int32 `json:"serviceCont,omitempty"` + // The maximum size in Mbytes of the storage resource expected to be used by the MEC application instance in the MEC system. + Storage int32 `json:"storage,omitempty"` +} diff --git a/examples/demo4-ue/src/demo-server/backend/server/model_application_list_app_list.go b/examples/demo4-ue/src/demo-server/backend/server/model_application_list_app_list.go new file mode 100644 index 000000000..349e769d5 --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/server/model_application_list_app_list.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. + * + * MEEP Demo 4 API + * Demo 4 is an edge application that can be used with AdvantEDGE or ETSI MEC Sandbox to demonstrate MEC016 usage + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 0.0.1 + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package server + +type ApplicationListAppList struct { + AppInfo *ApplicationListAppInfo `json:"appInfo,omitempty"` + VendorSpecificExt *ApplicationListVendorSpecificExt `json:"vendorSpecificExt,omitempty"` +} diff --git a/examples/demo4-ue/src/demo-server/backend/server/model_application_list_vendor_specific_ext.go b/examples/demo4-ue/src/demo-server/backend/server/model_application_list_vendor_specific_ext.go new file mode 100644 index 000000000..f7bc6121b --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/server/model_application_list_vendor_specific_ext.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. + * + * MEEP Demo 4 API + * Demo 4 is an edge application that can be used with AdvantEDGE or ETSI MEC Sandbox to demonstrate MEC016 usage + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 0.0.1 + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package server + +// Extension for vendor specific information (see note 1). +type ApplicationListVendorSpecificExt struct { + // Vendor identifier. The length of the value shall not exceed 32 characters. The rest of the structure of vendor specific extension is not defined. + VendorId string `json:"vendorId"` +} diff --git a/examples/demo4-ue/src/demo-server/backend/server/model_application_location_availability.go b/examples/demo4-ue/src/demo-server/backend/server/model_application_location_availability.go new file mode 100644 index 000000000..c20ee8907 --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/server/model_application_location_availability.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. + * + * MEEP Demo 4 API + * Demo 4 is an edge application that can be used with AdvantEDGE or ETSI MEC Sandbox to demonstrate MEC016 usage + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 0.0.1 + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package server + +type ApplicationLocationAvailability struct { + AppInfo *ApplicationLocationAvailabilityAppInfo `json:"appInfo"` + // Uniquely identifies the device application. The length of the value shall not exceed 32 characters. + AssociateDevAppId string `json:"associateDevAppId"` +} diff --git a/examples/demo4-ue/src/demo-server/backend/server/model_application_location_availability_app_info.go b/examples/demo4-ue/src/demo-server/backend/server/model_application_location_availability_app_info.go new file mode 100644 index 000000000..171c37a03 --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/server/model_application_location_availability_app_info.go @@ -0,0 +1,42 @@ +/* + * 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. + * + * MEEP Demo 4 API + * Demo 4 is an edge application that can be used with AdvantEDGE or ETSI MEC Sandbox to demonstrate MEC016 usage + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 0.0.1 + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package server + +type ApplicationLocationAvailabilityAppInfo struct { + // Identifies the version of the application descriptor. It is equivalent to the appDVersion defined in clause 6.2.1.2 of ETSI GS MEC 0102 [1]. + AppDVersion string `json:"appDVersion"` + // Human readable description of the MEC application. The length of the value shall not exceed 128 characters. + AppDescription string `json:"appDescription,omitempty"` + // Name of the MEC application. The length of the value shall not exceed 32 characters. + AppName string `json:"appName"` + // URI of the application package. Shall be included in the request. The application package shall comply with the definitions in clause 6.2.1.2 of ETSI GS MEC 0102 [1]. + AppPackageSource string `json:"appPackageSource,omitempty"` + // Provider of the MEC application. The length of the value shall not exceed 32 characters. + AppProvider string `json:"appProvider"` + // Software version of the MEC application. The length of the value shall not exceed 32 characters. + AppSoftVersion string `json:"appSoftVersion,omitempty"` + // MEC application location constraints. + AvailableLocations []ApplicationLocationAvailabilityAppInfoAvailableLocations `json:"availableLocations,omitempty"` +} diff --git a/examples/demo4-ue/src/demo-server/backend/server/model_application_location_availability_app_info_available_locations.go b/examples/demo4-ue/src/demo-server/backend/server/model_application_location_availability_app_info_available_locations.go new file mode 100644 index 000000000..1cf956174 --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/server/model_application_location_availability_app_info_available_locations.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. + * + * MEEP Demo 4 API + * Demo 4 is an edge application that can be used with AdvantEDGE or ETSI MEC Sandbox to demonstrate MEC016 usage + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 0.0.1 + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package server + +type ApplicationLocationAvailabilityAppInfoAvailableLocations struct { + AppLocation *LocationConstraints `json:"appLocation,omitempty"` +} diff --git a/examples/demo4-ue/src/demo-server/backend/server/model_application_location_availability_notification.go b/examples/demo4-ue/src/demo-server/backend/server/model_application_location_availability_notification.go new file mode 100644 index 000000000..50252f2ef --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/server/model_application_location_availability_notification.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. + * + * MEEP Demo 4 API + * Demo 4 is an edge application that can be used with AdvantEDGE or ETSI MEC Sandbox to demonstrate MEC016 usage + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 0.0.1 + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package server + +type ApplicationLocationAvailabilityNotification struct { + // Locations available to the MEC application. + AvailableLocations []ApplicationLocationAvailabilityAppInfoAvailableLocations `json:"availableLocations"` + // Uniquely identifies the application context in the MEC system. + ContextId string `json:"contextId,omitempty"` + // Shall be set to \"ApplicationLocationAvailabilityNotification\". + NotificationType string `json:"notificationType"` +} diff --git a/examples/demo4-ue/src/demo-server/backend/server/model_associate_id.go b/examples/demo4-ue/src/demo-server/backend/server/model_associate_id.go new file mode 100644 index 000000000..980c005c3 --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/server/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. + * + * MEEP Demo 4 API + * Demo 4 is an edge application that can be used with AdvantEDGE or ETSI MEC Sandbox to demonstrate MEC016 usage + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 0.0.1 + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package server + +type AssociateId struct { + Type_ *ModelType `json:"type"` + // Value for the identifier. + Value string `json:"value"` +} diff --git a/examples/demo4-ue/src/demo-server/backend/server/model_communication_interface.go b/examples/demo4-ue/src/demo-server/backend/server/model_communication_interface.go new file mode 100644 index 000000000..9b627608f --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/server/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. + * + * MEEP Demo 4 API + * Demo 4 is an edge application that can be used with AdvantEDGE or ETSI MEC Sandbox to demonstrate MEC016 usage + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 0.0.1 + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package server + +type CommunicationInterface struct { + IpAddresses string `json:"ipAddresses,omitempty"` +} diff --git a/examples/demo4-ue/src/demo-server/backend/server/model_inline_notification.go b/examples/demo4-ue/src/demo-server/backend/server/model_inline_notification.go new file mode 100644 index 000000000..b8bddb7da --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/server/model_inline_notification.go @@ -0,0 +1,28 @@ +/* + * 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. + * + * MEEP Demo 4 API + * Demo 4 is an edge application that can be used with AdvantEDGE or ETSI MEC Sandbox to demonstrate MEC016 usage + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 0.0.1 + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package server + +type InlineNotification struct { +} diff --git a/examples/demo4-ue/src/demo-server/backend/server/model_link_type.go b/examples/demo4-ue/src/demo-server/backend/server/model_link_type.go new file mode 100644 index 000000000..8c7651af3 --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/server/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. + * + * MEEP Demo 4 API + * Demo 4 is an edge application that can be used with AdvantEDGE or ETSI MEC Sandbox to demonstrate MEC016 usage + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 0.0.1 + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package server + +// This type represents a type of link and may be referenced from data structures +type LinkType struct { + // URI referring to a resource + Href string `json:"href,omitempty"` +} diff --git a/examples/demo4-ue/src/demo-server/backend/server/model_locality_type.go b/examples/demo4-ue/src/demo-server/backend/server/model_locality_type.go new file mode 100644 index 000000000..660be169d --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/server/model_locality_type.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. + * + * MEEP Demo 4 API + * Demo 4 is an edge application that can be used with AdvantEDGE or ETSI MEC Sandbox to demonstrate MEC016 usage + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 0.0.1 + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package server + +// LocalityType : The scope of locality as expressed by \"consumedLocalOnly\" and \"isLocal\". If absent, defaults to MEC_HOST +type LocalityType string + +// List of LocalityType +const ( + MEC_SYSTEM_LocalityType LocalityType = "MEC_SYSTEM" + MEC_HOST_LocalityType LocalityType = "MEC_HOST" + NFVI_POP_LocalityType LocalityType = "NFVI_POP" + ZONE_LocalityType LocalityType = "ZONE" + ZONE_GROUP_LocalityType LocalityType = "ZONE_GROUP" + NFVI_NODE_LocalityType LocalityType = "NFVI_NODE" +) diff --git a/examples/demo4-ue/src/demo-server/backend/server/model_location_constraints.go b/examples/demo4-ue/src/demo-server/backend/server/model_location_constraints.go new file mode 100644 index 000000000..85642868d --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/server/model_location_constraints.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. + * + * MEEP Demo 4 API + * Demo 4 is an edge application that can be used with AdvantEDGE or ETSI MEC Sandbox to demonstrate MEC016 usage + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 0.0.1 + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package server + +type LocationConstraints struct { + Area *Polygon `json:"area,omitempty"` + // Zero or more elements comprising the civic address. Shall be absent if the \"area\" attribute is present. + CivicAddressElement []LocationConstraintsCivicAddressElement `json:"civicAddressElement,omitempty"` + // The two-letter ISO 3166 [7] country code in capital letters. Shall be present in case the \"area\" attribute is absent. May be absent if the \"area\" attribute is present (see note). + CountryCode string `json:"countryCode,omitempty"` +} diff --git a/examples/demo4-ue/src/demo-server/backend/server/model_location_constraints_civic_address_element.go b/examples/demo4-ue/src/demo-server/backend/server/model_location_constraints_civic_address_element.go new file mode 100644 index 000000000..f72664fc9 --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/server/model_location_constraints_civic_address_element.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. + * + * MEEP Demo 4 API + * Demo 4 is an edge application that can be used with AdvantEDGE or ETSI MEC Sandbox to demonstrate MEC016 usage + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 0.0.1 + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package server + +type LocationConstraintsCivicAddressElement struct { + // Describe the content type of caValue. The value of caType shall comply with section 3.4 of IETF RFC 4776 [6]. + CaType int32 `json:"caType,omitempty"` + // Content of civic address element corresponding to the caType. The format caValue shall comply with section 3.4 of IETF RFC 4776 [6]. + CaValue string `json:"caValue,omitempty"` +} diff --git a/examples/demo4-ue/src/demo-server/backend/server/model_one_of_inline_notification.go b/examples/demo4-ue/src/demo-server/backend/server/model_one_of_inline_notification.go new file mode 100644 index 000000000..d0558df04 --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/server/model_one_of_inline_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. + * + * MEEP Demo 4 API + * Demo 4 is an edge application that can be used with AdvantEDGE or ETSI MEC Sandbox to demonstrate MEC016 usage + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 0.0.1 + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package server + +type OneOfInlineNotification struct { + NotificationType string `json:"notificationType"` + /*AddressChangeNotification + ApplicationContextDeleteNotification + ApplicationContextUpdateNotification + ApplicationLocationAvailabilityNotification*/ +} diff --git a/examples/demo4-ue/src/demo-server/backend/server/model_polygon.go b/examples/demo4-ue/src/demo-server/backend/server/model_polygon.go new file mode 100644 index 000000000..cfcda7950 --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/server/model_polygon.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. + * + * MEEP Demo 4 API + * Demo 4 is an edge application that can be used with AdvantEDGE or ETSI MEC Sandbox to demonstrate MEC016 usage + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 0.0.1 + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package server + +type Polygon struct { + Coordinates [][][]float32 `json:"coordinates,omitempty"` +} diff --git a/examples/demo4-ue/src/demo-server/backend/server/model_problem_details.go b/examples/demo4-ue/src/demo-server/backend/server/model_problem_details.go new file mode 100644 index 000000000..7e6836312 --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/server/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. + * + * MEEP Demo 4 API + * Demo 4 is an edge application that can be used with AdvantEDGE or ETSI MEC Sandbox to demonstrate MEC016 usage + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 0.0.1 + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package server + +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/demo4-ue/src/demo-server/backend/server/model_service_availability_notification.go b/examples/demo4-ue/src/demo-server/backend/server/model_service_availability_notification.go new file mode 100644 index 000000000..1f361faf7 --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/server/model_service_availability_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. + * + * MEEP Demo 4 API + * Demo 4 is an edge application that can be used with AdvantEDGE or ETSI MEC Sandbox to demonstrate MEC016 usage + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 0.0.1 + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package server + +// This type represents the service availability information. +type ServiceAvailabilityNotification struct { + // Shall be set to SerAvailabilityNotification + NotificationType string `json:"notificationType"` + ServiceReferences []ServiceAvailabilityNotificationServiceReferences `json:"serviceReferences"` + Links *Subscription `json:"_links"` +} diff --git a/examples/demo4-ue/src/demo-server/backend/server/model_service_availability_notification_service_references.go b/examples/demo4-ue/src/demo-server/backend/server/model_service_availability_notification_service_references.go new file mode 100644 index 000000000..39cc7ebaf --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/server/model_service_availability_notification_service_references.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. + * + * MEEP Demo 4 API + * Demo 4 is an edge application that can be used with AdvantEDGE or ETSI MEC Sandbox to demonstrate MEC016 usage + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 0.0.1 + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package server + +// List of links to services whose availability has changed. +type ServiceAvailabilityNotificationServiceReferences struct { + Link *LinkType `json:"link,omitempty"` + // The name of the service. This is how the service producing MEC application identifies the service instance it produces. + SerName string `json:"serName"` + State *ServiceState `json:"state"` + // Type of the change. Valid values: ADDED: The service was newly added. REMOVED: The service was removed. STATE_CHANGED: Only the state of the service was changed. ATTRIBUTES_CHANGED: At least one attribute of the service other than state was changed. The change may or may not include changing the state. + ChangeType string `json:"changeType"` +} diff --git a/examples/demo4-ue/src/demo-server/backend/server/model_service_state.go b/examples/demo4-ue/src/demo-server/backend/server/model_service_state.go new file mode 100644 index 000000000..e01dd4980 --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/server/model_service_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. + * + * MEEP Demo 4 API + * Demo 4 is an edge application that can be used with AdvantEDGE or ETSI MEC Sandbox to demonstrate MEC016 usage + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 0.0.1 + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package server + +// ServiceState : This enumeration defines the possible states of a service. +type ServiceState string + +// List of ServiceState +const ( + ACTIVE_ServiceState ServiceState = "ACTIVE" + INACTIVE_ServiceState ServiceState = "INACTIVE" +) diff --git a/examples/demo4-ue/src/demo-server/backend/server/model_subscription.go b/examples/demo4-ue/src/demo-server/backend/server/model_subscription.go new file mode 100644 index 000000000..5a81c1186 --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/server/model_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. + * + * MEEP Demo 4 API + * Demo 4 is an edge application that can be used with AdvantEDGE or ETSI MEC Sandbox to demonstrate MEC016 usage + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 0.0.1 + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package server + +// A link to the related subscription +type Subscription struct { + Subscription *LinkType `json:"subscription"` +} diff --git a/examples/demo4-ue/src/demo-server/backend/server/model_time_stamp.go b/examples/demo4-ue/src/demo-server/backend/server/model_time_stamp.go new file mode 100644 index 000000000..fb0f6e1ac --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/server/model_time_stamp.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. + * + * MEEP Demo 4 API + * Demo 4 is an edge application that can be used with AdvantEDGE or ETSI MEC Sandbox to demonstrate MEC016 usage + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 0.0.1 + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package server + +type TimeStamp struct { + // The nanoseconds part of the time. Time is defined as Unix-time since January 1, 1970, 00:00:00 UTC. + NanoSeconds int32 `json:"nanoSeconds"` + // The seconds part of the time. Time is defined as Unixtime since January 1, 1970, 00:00:00 UTC. + Seconds int32 `json:"seconds"` +} diff --git a/examples/demo4-ue/src/demo-server/backend/server/model_type.go b/examples/demo4-ue/src/demo-server/backend/server/model_type.go new file mode 100644 index 000000000..b9ae9328f --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/server/model_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. + * + * MEEP Demo 4 API + * Demo 4 is an edge application that can be used with AdvantEDGE or ETSI MEC Sandbox to demonstrate MEC016 usage + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 0.0.1 + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package server + +// ModelType : Numeric value (0-255) corresponding to specified type of identifier +type ModelType string + +// List of Type +const ( + UE_I_PV4_ADDRESS_ModelType ModelType = "UE_IPv4_ADDRESS" + UE_IPV6_ADDRESS_ModelType ModelType = "UE_IPV6_ADDRESS" + NATED_IP_ADDRESS_ModelType ModelType = "NATED_IP_ADDRESS" + GTP_TEID_ModelType ModelType = "GTP_TEID" +) diff --git a/examples/demo4-ue/src/demo-server/backend/server/routers.go b/examples/demo4-ue/src/demo-server/backend/server/routers.go new file mode 100644 index 000000000..6af026c46 --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/server/routers.go @@ -0,0 +1,150 @@ +/* + * 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. + * + * MEEP Demo 4 API + * Demo 4 is an edge application that can be used with AdvantEDGE or ETSI MEC Sandbox to demonstrate MEC016 usage + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 0.0.1 + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ + +package server + +import ( + "net/http" + "strings" + + httpLog "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-http-logger" + met "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-metrics" + + "github.com/gorilla/mux" +) + +type Route struct { + Name string + Method string + Pattern string + HandlerFunc http.HandlerFunc +} + +type Routes []Route + +func NewRouter() *mux.Router { + var handler http.Handler + router := mux.NewRouter().StrictSlash(true) + for _, route := range routes { + handler = route.HandlerFunc + handler = Logger(handler, route.Name) + handler = met.MetricsHandler(handler, "", moduleName) + handler = httpLog.LogRx(handler) + + router. + Methods(route.Method). + Path(route.Pattern). + Name(route.Name). + Handler(handler) + } + + // Path prefix router order is important + // Service Api files + handler = http.StripPrefix("/demo4-ue/api/", http.FileServer(http.Dir("./api/"))) + router. + PathPrefix("/demo4-ue/api/"). + Name("Api"). + Handler(handler) + // User supplied service API files + handler = http.StripPrefix("/demo4-ue/user-api/", http.FileServer(http.Dir("./user-api/"))) + router. + PathPrefix("/demo4-ue/user-api/"). + Name("UserApi"). + Handler(handler) + + return router +} + +var routes = Routes{ + + Route{ + "GetActivityLogs", + strings.ToUpper("Get"), + "/info/logs", + GetActivityLogs, + }, + + Route{ + "GetPlatformInfo", + strings.ToUpper("Get"), + "/info/application", + GetPlatformInfo, + }, + + Route{ + "DaiAppListGET", + strings.ToUpper("Get"), + "/dai/apps", + DaiAppListGET, + }, + + Route{ + "DaiDoPingDELETE", + strings.ToUpper("Delete"), + "/dai/delete/{appcontextid}", + DaiDoPingDELETE, + }, + + Route{ + "DaiDoPingGET", + strings.ToUpper("Get"), + "/dai/doping/{appcontextid}", + DaiDoPingGET, + }, + + Route{ + "DaiDoPingPOST", + strings.ToUpper("Post"), + "/dai/instantiate", + DaiDoPingPOST, + }, + + Route{ + "DaiAppLocationAvailabilityPOST", + strings.ToUpper("Post"), + "/dai/availability/{appcontextid}", + DaiAppLocationAvailabilityPOST, + }, + + Route{ + "ServiceAvailNotificationCallback", + strings.ToUpper("Post"), + "/services/callback/service-availability", + ServiceAvailNotificationCallback, + }, + + Route{ + "AppTerminationNotificationCallback", + strings.ToUpper("Post"), + "/application/termination", + AppTerminationNotificationCallback, + }, + + Route{ + "ApplicationContextDeleteNotificationCallback", + strings.ToUpper("Post"), + "/dai/callback/ApplicationContextDeleteNotification", + ApplicationContextDeleteNotificationCallback, + }, +} diff --git a/examples/demo4-ue/src/demo-server/backend/util/config.go b/examples/demo4-ue/src/demo-server/backend/util/config.go new file mode 100644 index 000000000..d4cc442ae --- /dev/null +++ b/examples/demo4-ue/src/demo-server/backend/util/config.go @@ -0,0 +1,52 @@ +/* + * 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. + */ +package util + +import ( + "github.com/spf13/viper" +) + +type Config struct { + Mode string `mapstructure:"mode"` + SandboxUrl string `mapstructure:"sandbox"` + SandboxName string `mapstructure:"sandboxname"` + NodeName string `mapstructure:"nodename"` + HttpsOnly bool `mapstructure:"https"` + MecPlatform string `mapstructure:"mecplatform"` + AppInstanceId string `mapstructure:"appid"` + Localurl string `mapstructure:"localurl"` + Port string `mapstructure:"port"` + AppName string `mapstructure:"appname"` +} + +func LoadConfig(path string, name string) (config Config, err error) { + viper.SetConfigType("yaml") + viper.AddConfigPath(path) + viper.SetConfigName(name) + viper.AutomaticEnv() + + err = viper.ReadInConfig() + if err != nil { + return config, err + } + + err = viper.Unmarshal(&config) + if err != nil { + return config, err + } + return + +} diff --git a/examples/demo4-ue/src/demo-server/demo4-ue-config.yaml b/examples/demo4-ue/src/demo-server/demo4-ue-config.yaml new file mode 100644 index 000000000..30b3a02f2 --- /dev/null +++ b/examples/demo4-ue/src/demo-server/demo4-ue-config.yaml @@ -0,0 +1,22 @@ +# This file defines the configuration of Demo4 edge application. All fields are required to run demo-4 on MEC Sandbox + +# Set where mec application is running either on MEC Sandbox or AdvantEDGE. Expected fields: sandbox | advantedge +mode: 'sandbox' +# Set url of mec platform. Example field format: http://{MEC_IP_ADDRESS}/{SANDBOX_NAME}/{MEP_NAME}/ +sandbox: 'https://sandbox-mec.etsi.org/sbx7j3qk6y/mep1' +# Set the sandbox name. Example field format: {SANDBOX_NAME} +sandboxname: 'sbx7j3qk6y' +# Set the Terminal Equipment the demo-4 should be attached to +nodename: '10.100.0.01' +# Set if sandbox url uses https. Expected fields: true | false +https: true +# Set the mec platform name demo4-ue will run on. Example field: mep1 +mecplatform: 'mep1' +# Set user-application ID that is generated on MEC Sandbox frontend. Example field format: 7930ba6d-4581-444c-b966-3312517f3a51 +appid: '45720620-7442-46cc-93c6-0c67aceb06a6' +# Set host address of demo4-ue. +localurl: 'http://sandbox-mec.etsi.org' +# Set host port number of demo4-ue. Example field: '8094' +port: '31111' +# Set the application name +appname: 'demo4-ue' \ No newline at end of file diff --git a/examples/demo4-ue/src/demo-server/demo4-ue-scenario.yaml b/examples/demo4-ue/src/demo-server/demo4-ue-scenario.yaml new file mode 100644 index 000000000..cd136a8bc --- /dev/null +++ b/examples/demo4-ue/src/demo-server/demo4-ue-scenario.yaml @@ -0,0 +1,261 @@ +version: 1.9.0 +name: demo4ueapplication +deployment: + netChar: + latency: 50 + latencyVariation: 10 + latencyDistribution: Normal + throughputDl: 1000 + throughputUl: 1000 + connectivity: + model: OPEN + d2d: + d2dMaxDistance: 100 + domains: + - + id: PUBLIC + name: PUBLIC + type: PUBLIC + netChar: + latency: 6 + latencyVariation: 2 + throughputDl: 1000 + throughputUl: 1000 + zones: + - + id: PUBLIC-COMMON + name: PUBLIC-COMMON + type: COMMON + netChar: + latency: 5 + latencyVariation: 1 + throughputDl: 1000 + throughputUl: 1000 + networkLocations: + - + id: PUBLIC-COMMON-DEFAULT + name: PUBLIC-COMMON-DEFAULT + type: DEFAULT + netChar: + latency: 1 + latencyVariation: 1 + throughputDl: 1000 + throughputUl: 1000 + - + id: 8f7ad774-b3f9-4fea-9972-0a2a8185a1db + name: operator-cell1 + type: OPERATOR-CELLULAR + netChar: + latency: 6 + latencyVariation: 2 + throughputDl: 1000 + throughputUl: 1000 + cellularDomainConfig: + mnc: '002' + mcc: '001' + defaultCellId: CAFEDEC + zones: + - + id: operator-cell1-COMMON + name: operator-cell1-COMMON + type: COMMON + netChar: + latency: 5 + latencyVariation: 1 + throughputDl: 1000 + throughputUl: 1000 + networkLocations: + - + id: operator-cell1-COMMON-DEFAULT + name: operator-cell1-COMMON-DEFAULT + type: DEFAULT + netChar: + latency: 1 + latencyVariation: 1 + throughputDl: 1000 + throughputUl: 1000 + - + id: b2076ddf-dd15-46b4-9814-204084ec5805 + name: zone1 + type: ZONE + netChar: + latency: 5 + latencyVariation: 1 + throughputDl: 1000 + throughputUl: 1000 + meta: + display.map.color: '#E21C1C' + networkLocations: + - + id: zone1-DEFAULT + name: zone1-DEFAULT + type: DEFAULT + netChar: + latency: 1 + latencyVariation: 1 + throughputDl: 1000 + throughputUl: 1000 + physicalLocations: + - + id: b60c5f19-3666-4707-9297-6aa83e62ccc0 + name: edge1 + type: EDGE + geoData: + location: + type: Point + coordinates: + - 7.421096 + - 43.73408 + connected: true + dataNetwork: + dnn: edn + processes: + - + id: ce454f4c-16f8-4542-83d8-c8afd45bcfea + name: demo4-ue1 + type: EDGE-APP + image: 'meep-docker-registry:30001/demo4-ue' + environment: MEEP_NODE_NAME=10.10.20.01 + serviceConfig: + name: demo4-ue1 + meSvcName: demo4-ue + ports: + - + protocol: TCP + port: 80 + externalPort: 31111 + netChar: + throughputDl: 1000 + throughputUl: 1000 + netChar: + latencyDistribution: Normal + throughputDl: 1000 + throughputUl: 1000 + - + id: 0c5152b9-954d-48fe-a547-7e53532ae869 + name: poa-5g1 + type: POA-5G + netChar: + latency: 1 + latencyVariation: 1 + throughputDl: 1000 + throughputUl: 1000 + poa5GConfig: + cellId: '1010101' + geoData: + location: + type: Point + coordinates: + - 7.416715 + - 43.733616 + radius: 400 + physicalLocations: + - + id: eb96cba6-c0c2-4113-ae56-cc7097161eef + name: 10.10.20.01 + type: UE + geoData: + location: + type: Point + coordinates: + - 7.420433 + - 43.729942 + path: + type: LineString + coordinates: + - + - 7.420433 + - 43.729942 + - + - 7.420659 + - 43.73036 + - + - 7.420621 + - 43.731045 + - + - 7.420922 + - 43.73129 + - + - 7.421345 + - 43.731373 + - + - 7.42135 + - 43.73168 + - + - 7.421148 + - 43.73173 + - + - 7.420616 + - 43.731964 + - + - 7.419779 + - 43.732197 + - + - 7.419111 + - 43.732353 + - + - 7.418931 + - 43.732315 + - + - 7.418345 + - 43.731964 + - + - 7.418319 + - 43.73186 + - + - 7.418024 + - 43.73179 + - + - 7.41796 + - 43.731728 + - + - 7.417729 + - 43.731743 + - + - 7.417463 + - 43.731632 + - + - 7.417507 + - 43.73148 + - + - 7.417428 + - 43.731407 + - + - 7.417343 + - 43.731396 + - + - 7.417334 + - 43.731133 + - + - 7.417317 + - 43.73053 + - + - 7.417164 + - 43.7304 + - + - 7.417164 + - 43.72998 + - + - 7.417319 + - 43.729916 + - + - 7.419065 + - 43.730103 + eopMode: REVERSE + velocity: 1 + connected: true + wireless: true + wirelessType: 'wifi,5g,4g,other' + dataNetwork: + dnn: "" + ladn: false + ecsp: "" + netChar: + latencyDistribution: Normal + throughputDl: 1000 + throughputUl: 1000 + latency: 0 + latencyVariation: 0 + packetLoss: 0 + macId: DEADBEEF0001 + label: 10.10.20.01 diff --git a/examples/demo4-ue/src/demo-server/entrypoint.sh b/examples/demo4-ue/src/demo-server/entrypoint.sh new file mode 100644 index 000000000..b3eacc4f1 --- /dev/null +++ b/examples/demo4-ue/src/demo-server/entrypoint.sh @@ -0,0 +1,13 @@ +#!/bin/bash +set -e + +echo "mode: advantedge" >app_instance.yaml +echo "sandbox:" >>app_instance.yaml +echo "mecplatform: ${MEEP_MEP_NAME}" >>app_instance.yaml +echo "appid:" ${MEEP_APP_ID} >>app_instance.yaml +echo "localurl: ${MEEP_POD_NAME}" >>app_instance.yaml +echo "port:" >>app_instance.yaml +echo "nodename: ${MEEP_NODE_NAME}" >>app_instance.yaml + +# Start service +exec /demo-server ./app_instance.yaml diff --git a/examples/demo4-ue/src/onboarded-demo/.swagger-codegen-ignore b/examples/demo4-ue/src/onboarded-demo/.swagger-codegen-ignore new file mode 100644 index 000000000..c5fa491b4 --- /dev/null +++ b/examples/demo4-ue/src/onboarded-demo/.swagger-codegen-ignore @@ -0,0 +1,23 @@ +# Swagger Codegen Ignore +# Generated by swagger-codegen https://github.com/swagger-api/swagger-codegen + +# Use this file to prevent files from being overwritten by the generator. +# The patterns follow closely to .gitignore or .dockerignore. + +# As an example, the C# client generator defines ApiClient.cs. +# You can make changes and tell Swagger Codgen to ignore just this file by uncommenting the following line: +#ApiClient.cs + +# You can match any string of characters against a directory, file or extension with a single asterisk (*): +#foo/*/qux +# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux + +# You can recursively match patterns against a directory, file or extension with a double asterisk (**): +#foo/**/qux +# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux + +# You can also negate patterns with an exclamation (!). +# For example, you can ignore all files in a docs folder with the file extension .md: +#docs/*.md +# Then explicitly reverse the ignore rule for a single file: +#!docs/README.md diff --git a/examples/demo4-ue/src/onboarded-demo/.swagger-codegen/VERSION b/examples/demo4-ue/src/onboarded-demo/.swagger-codegen/VERSION new file mode 100644 index 000000000..0667b5ffc --- /dev/null +++ b/examples/demo4-ue/src/onboarded-demo/.swagger-codegen/VERSION @@ -0,0 +1 @@ +3.0.29 \ No newline at end of file diff --git a/examples/demo4-ue/src/onboarded-demo/.travis.yml b/examples/demo4-ue/src/onboarded-demo/.travis.yml new file mode 100644 index 000000000..f5cb2ce9a --- /dev/null +++ b/examples/demo4-ue/src/onboarded-demo/.travis.yml @@ -0,0 +1,8 @@ +language: go + +install: + - go get -d -v . + +script: + - go build -v ./ + diff --git a/examples/demo4-ue/src/onboarded-demo/Dockerfile b/examples/demo4-ue/src/onboarded-demo/Dockerfile new file mode 100644 index 000000000..8b2f27fe8 --- /dev/null +++ b/examples/demo4-ue/src/onboarded-demo/Dockerfile @@ -0,0 +1,27 @@ +# Copyright (c) 2022 InterDigital Communications, Inc +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +FROM debian:9.6-slim + + +# Some ENV variables +ENV SERVICE_NAME = "onboarded-demo4" + +COPY ./onboarded-demo4 /onboarded-demo4 +#COPY ./static /static +COPY entrypoint.sh / + +RUN chmod +x /entrypoint.sh + +ENTRYPOINT ["/entrypoint.sh"] diff --git a/examples/demo4-ue/src/onboarded-demo/README.md b/examples/demo4-ue/src/onboarded-demo/README.md new file mode 100644 index 000000000..85a19e528 --- /dev/null +++ b/examples/demo4-ue/src/onboarded-demo/README.md @@ -0,0 +1,39 @@ +# Go API client for swagger + +Demo 4 is an device application that can be instanciated over the UE Application interface + +## Overview +This API client was generated by the [swagger-codegen](https://github.com/swagger-api/swagger-codegen) project. By using the [swagger-spec](https://github.com/swagger-api/swagger-spec) from a remote server, you can easily generate an API client. + +- API version: 0.0.1 +- Package version: 1.0.0 +- Build package: io.swagger.codegen.v3.generators.go.GoClientCodegen + +## Installation +Put the package under your project folder and add the following in import: +```golang +import "./swagger" +``` + +## Documentation for API Endpoints + +All URIs are relative to *http://10.190.115.162:8093* + +Class | Method | HTTP request | Description +------------ | ------------- | ------------- | ------------- +*FrontendApi* | [**Ping**](docs/FrontendApi.md#ping) | **Get** /ping | Await for ping request and reply winth pong text body +*FrontendApi* | [**Terminate**](docs/FrontendApi.md#terminate) | **Delete** / | Terminate gracefully the application + +## Documentation For Models + + +## Documentation For Authorization + Endpoints do not require authorization. + + +## Author +AdvantEDGE@InterDigital.com +xFlow Research (Pvt.) Inc. +FSCOM + + diff --git a/examples/demo4-ue/src/onboarded-demo/api/swagger.yaml b/examples/demo4-ue/src/onboarded-demo/api/swagger.yaml new file mode 100644 index 000000000..8b506dc60 --- /dev/null +++ b/examples/demo4-ue/src/onboarded-demo/api/swagger.yaml @@ -0,0 +1,56 @@ +openapi: 3.0.2 +info: + title: MEC On-boarded Demo 4 API + description: Demo 4 is an device application that can be instanciated over the UE + Application interface + license: + name: Apache 2.0 + url: http://www.apache.org/licenses/LICENSE-2.0 + version: 0.0.1 +servers: +- url: http://10.190.115.162:8093 +paths: + /ping: + get: + tags: + - frontend + summary: Await for ping request and reply winth pong text body + description: ping then pong! + operationId: ping + responses: + "200": + description: OK + content: + text/plain: + schema: + type: string + example: pong + x-content-type: text/plain + "400": + description: Bad Request + content: + text/plain: + schema: + type: string + example: Not pong + x-content-type: text/plain + /: + delete: + tags: + - frontend + summary: Terminate gracefully the application + description: Request to terminate gracefully the application + operationId: terminate + responses: + "204": + description: No Content + "400": + description: Bad Request + content: + text/plain: + schema: + type: string + example: Failed + x-content-type: text/plain +components: + schemas: {} diff --git a/examples/demo4-ue/src/onboarded-demo/build.sh b/examples/demo4-ue/src/onboarded-demo/build.sh new file mode 100644 index 000000000..e35787816 --- /dev/null +++ b/examples/demo4-ue/src/onboarded-demo/build.sh @@ -0,0 +1,20 @@ +#!/bin/sh + +#set -vx + +# Get full path to script directory +SCRIPT=$(readlink -f "$0") +BASEDIR=$(dirname "$SCRIPT") + +# Create build directory +if [ "$#" -ne 1 ]; then + echo "Missing bin directory" + exit +fi +BINDIR=$1 +mkdir -p $BINDIR + +# Build demo App server +cd $BASEDIR + +go build -o $BINDIR/onboarded-demo4 . diff --git a/examples/demo4-ue/src/onboarded-demo/docs/FrontendApi.md b/examples/demo4-ue/src/onboarded-demo/docs/FrontendApi.md new file mode 100644 index 000000000..131a88b86 --- /dev/null +++ b/examples/demo4-ue/src/onboarded-demo/docs/FrontendApi.md @@ -0,0 +1,57 @@ +# {{classname}} + +All URIs are relative to *http://10.190.115.162:8093* + +Method | HTTP request | Description +------------- | ------------- | ------------- +[**Ping**](FrontendApi.md#Ping) | **Get** /ping | Await for ping request and reply winth pong text body +[**Terminate**](FrontendApi.md#Terminate) | **Delete** / | Terminate gracefully the application + +# **Ping** +> string Ping(ctx, ) +Await for ping request and reply winth pong text body + +ping then pong! + +### Required Parameters +This endpoint does not need any parameter. + +### Return type + +**string** + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: text/plain + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + +# **Terminate** +> Terminate(ctx, ) +Terminate gracefully the application + +Request to terminate gracefully the application + +### Required Parameters +This endpoint does not need any parameter. + +### Return type + + (empty response body) + +### Authorization + +No authorization required + +### HTTP request headers + + - **Content-Type**: Not defined + - **Accept**: text/plain + +[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md) + diff --git a/examples/demo4-ue/src/onboarded-demo/entrypoint.sh b/examples/demo4-ue/src/onboarded-demo/entrypoint.sh new file mode 100644 index 000000000..def0e791c --- /dev/null +++ b/examples/demo4-ue/src/onboarded-demo/entrypoint.sh @@ -0,0 +1,12 @@ +#!/bin/bash +set -e + +echo "mode: advantedge" >app_instance.yaml +echo "sandbox:" >>app_instance.yaml +echo "mecplatform: ${MEEP_MEP_NAME}" >>app_instance.yaml +echo "appid:" ${MEEP_APP_ID} >>app_instance.yaml +echo "localurl: ${MEEP_POD_NAME}" >>app_instance.yaml +echo "port:" >>app_instance.yaml + +# Start service +exec /onboarded-demo4 ./app_instance.yaml diff --git a/examples/demo4-ue/src/onboarded-demo/git_push.sh b/examples/demo4-ue/src/onboarded-demo/git_push.sh new file mode 100644 index 000000000..ae01b182a --- /dev/null +++ b/examples/demo4-ue/src/onboarded-demo/git_push.sh @@ -0,0 +1,52 @@ +#!/bin/sh +# ref: https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/ +# +# Usage example: /bin/sh ./git_push.sh wing328 swagger-petstore-perl "minor update" + +git_user_id=$1 +git_repo_id=$2 +release_note=$3 + +if [ "$git_user_id" = "" ]; then + git_user_id="GIT_USER_ID" + echo "[INFO] No command line input provided. Set \$git_user_id to $git_user_id" +fi + +if [ "$git_repo_id" = "" ]; then + git_repo_id="GIT_REPO_ID" + echo "[INFO] No command line input provided. Set \$git_repo_id to $git_repo_id" +fi + +if [ "$release_note" = "" ]; then + release_note="Minor update" + echo "[INFO] No command line input provided. Set \$release_note to $release_note" +fi + +# Initialize the local directory as a Git repository +git init + +# Adds the files in the local repository and stages them for commit. +git add . + +# Commits the tracked changes and prepares them to be pushed to a remote repository. +git commit -m "$release_note" + +# Sets the new remote +git_remote=`git remote` +if [ "$git_remote" = "" ]; then # git remote not defined + + if [ "$GIT_TOKEN" = "" ]; then + echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git credential in your environment." + git remote add origin https://github.com/${git_user_id}/${git_repo_id}.git + else + git remote add origin https://${git_user_id}:${GIT_TOKEN}@github.com/${git_user_id}/${git_repo_id}.git + fi + +fi + +git pull origin master + +# Pushes (Forces) the changes in the local repository up to the remote repository +echo "Git pushing to https://github.com/${git_user_id}/${git_repo_id}.git" +git push origin master 2>&1 | grep -v 'To https' + diff --git a/examples/demo4-ue/src/onboarded-demo/go.mod b/examples/demo4-ue/src/onboarded-demo/go.mod new file mode 100644 index 000000000..57c01cb5c --- /dev/null +++ b/examples/demo4-ue/src/onboarded-demo/go.mod @@ -0,0 +1,22 @@ +module github.com/InterDigitalInc/AdvantEDGE/example/demo4/src/onboarded-demo + +go 1.13 + +require ( + github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-app-support-client v0.0.0-20211214133749-f203f7ab4f1c + github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-dai-mgr v0.0.0 + github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-logger v0.0.0-20211214133749-f203f7ab4f1c + github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-sandbox-ctrl-client v0.0.0-20211214133749-f203f7ab4f1c + github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-service-mgmt-client v0.0.0-20211214133749-f203f7ab4f1c + github.com/antihax/optional v1.0.0 // indirect + github.com/google/uuid v1.3.0 + github.com/gorilla/mux v1.7.3 +) + +replace ( + github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-app-support-client => ../../../../go-packages/meep-app-support-client + github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-dai-mgr => ../../../../go-packages/meep-dai-mgr + github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-logger => ../../../../go-packages/meep-logger + github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-sandbox-ctrl-client => ../../../../go-packages/meep-sandbox-ctrl-client + github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-service-mgmt-client => ../../../../go-packages/meep-service-mgmt-client +) diff --git a/examples/demo4-ue/src/onboarded-demo/go.sum b/examples/demo4-ue/src/onboarded-demo/go.sum new file mode 100644 index 000000000..03a94bfa5 --- /dev/null +++ b/examples/demo4-ue/src/onboarded-demo/go.sum @@ -0,0 +1,54 @@ +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/InterDigitalInc/AdvantEDGE v1.8.1 h1:2jZJ/Hu6IDweJifEpbOD8PP9pX03AQlZGNnrhv1Die8= +github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-logger v0.0.0-20211214133749-f203f7ab4f1c h1:pNyzqkE702/quz8AGVznklRAwW764WZSwK0izIWlTOY= +github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-logger v0.0.0-20211214133749-f203f7ab4f1c/go.mod h1:Xy2Z6nc9m0DRQRj9g0+/4E6OkDlCkFYySa65JoQ2d8g= +github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-sandbox-ctrl-client v0.0.0-20211214133749-f203f7ab4f1c h1:A63lWl3Tgh0XjVmulBpGON5G3hGfy2jpRoZfwl79RN4= +github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-sandbox-ctrl-client v0.0.0-20211214133749-f203f7ab4f1c/go.mod h1:RlTJLiOIOlQ1IRl/un3Ut1tch5NqxNdIaV4HMuFOdr0= +github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-service-mgmt-client v0.0.0-20211214133749-f203f7ab4f1c h1:4UuaBC5bYlhBR87FgqN7r1rmDxbgcUPWbM+aDWaQFEg= +github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-service-mgmt-client v0.0.0-20211214133749-f203f7ab4f1c/go.mod h1:PBVKB8iRvq7E3VQvmVaqf2LDKP0IZXJwNN7CAJ/tWi8= +github.com/antihax/optional v1.0.0 h1:xK2lYat7ZLaVVcIuj82J8kIro4V6kDe0AUDFboUCwcg= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gorilla/mux v1.7.3 h1:gnP5JzjVOuiZD07fKKToCAOjS0yOpj/qPETTXCCS6hw= +github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/lib/pq v1.10.6 h1:jbk+ZieJ0D7EVGJYpL9QTz7/YW6UHbmdnZWYyK5cdBs= +github.com/lib/pq v1.10.6/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/sirupsen/logrus v1.4.1 h1:GL2rEmy6nsikmW0r8opw9JIRScdMF5hA8cOYLH7In1k= +github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= +github.com/spf13/cobra v1.5.0 h1:X+jTBEBqF0bHN+9cSMgmfuvv2VHJ9ezmFNf9Y/XstYU= +github.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJoUM= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3 h1:0GoQqolDA55aaLxZyTzK/Y2ePZzZTUrRacwib7cNsYQ= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a h1:tImsplftrFpALCYumobsd0K86vlAs/eXGFms2txfJfA= +golang.org/x/oauth2 v0.0.0-20190402181905-9f3314589c9a/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33 h1:I6FyU15t786LL7oL/hn43zqTuEGr4PN7F4XJ1p4E3Y8= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= diff --git a/examples/demo4-ue/src/onboarded-demo/main.go b/examples/demo4-ue/src/onboarded-demo/main.go new file mode 100644 index 000000000..91205b6b1 --- /dev/null +++ b/examples/demo4-ue/src/onboarded-demo/main.go @@ -0,0 +1,71 @@ +/* + * 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. + */ + +package main + +import ( + "context" + "log" + "net/http" + "os" + "os/signal" + + server "github.com/InterDigitalInc/AdvantEDGE/example/demo4/src/onboarded-demo/server" +) + +const ( + port = ":31124" // hardcoded in mepp-dai Chart template +) + +func main() { + err := server.Init() + if err != nil { + log.Fatal("Failed to initalize onboarded-demo4 ", err) + } + + // Channel sync pass channel listen for app termination + server.Run() + + FrontendApiService := server.NewFrontendApiService() + FrontendApiController := server.NewFrontendApiController(FrontendApiService) + + router := server.NewRouter(FrontendApiController) + + log.Printf("Server started on port " + port) + srv := &http.Server{Addr: port, Handler: router} + go func() { + //returns ErrServerClosed on graceful close + log.Printf("Call ListenAndServe") + if err := srv.ListenAndServe(); err != http.ErrServerClosed { + log.Printf("ListenAndServe(): %s", err) + return + } + log.Printf("Terminate goroutine") + }() + + // log.Fatal(http.ListenAndServe(port, router)) + log.Printf("Configure signals") + c := make(chan os.Signal) + signal.Notify(c, os.Interrupt) + sig := <-c + log.Printf("Got %s signal. Aborting...\n", sig) + server.Terminate() + err = srv.Shutdown(context.TODO()) + if err != nil { + log.Printf("Shutdown(): %s", err) + return + } +} diff --git a/examples/demo4-ue/src/onboarded-demo/onboarded-demo-test1.json b/examples/demo4-ue/src/onboarded-demo/onboarded-demo-test1.json new file mode 100644 index 000000000..927f8cbdd --- /dev/null +++ b/examples/demo4-ue/src/onboarded-demo/onboarded-demo-test1.json @@ -0,0 +1,61 @@ +{ + "appList": + [ + { + "appInfoList": + [ + { + "appDId": "appDId1", + "appName": "appName1", + "appProvider": "appProvider1", + "appSoftVersion": "appSoftVersion1", + "appDVersion": "appDVersion1", + "appDescription": "appDescription1", + "appLocation": + [ + { + "area": + { + "coordinates": + [ + [ + [7.43166,43.736156],[7.431723,43.736115],[7.431162,43.735607],[7.430685,43.73518] + ] + ] + }, + "countryCode": "countryCode1" + }, + { + "civicAddressElement": + [ + { + "caType": 2, + "caValue": "Value2" + }, + { + "caType": 20, + "caValue": "Value20" + } + ] + } + ], + "appCharcs": + [ + { + "memory": 2048, + "storage": 2048, + "latency": 2048, + "bandwidth": 2048, + "serviceCont": 1 + } + ], + "cmd": "uptime", + "args":null + } + ], + "vendorSpecificExt": { + "vendorId": "vendorId1" + } + } + ] +} diff --git a/examples/demo4-ue/src/onboarded-demo/onboarded-demo4.json b/examples/demo4-ue/src/onboarded-demo/onboarded-demo4.json new file mode 100644 index 000000000..6df154b95 --- /dev/null +++ b/examples/demo4-ue/src/onboarded-demo/onboarded-demo4.json @@ -0,0 +1,62 @@ +{ + "appList": + [ + { + "appInfoList": + [ + { + "appDId": "onboarded-demo4", + "appName": "onboarded-demo4", + "appProvider": "ETSI", + "appSoftVersion": "v0.1.0", + "appDVersion": "v0.1.0", + "appDescription": "Basic HTTP Ping Pong", + "appLocation": + [ + { + "area": + { + "coordinates": + [ + [ + [7.420433,43.729942],[7.420659,43.73036],[7.420621,43.731045],[7.420922,43.73129] + ], + [ + [7.43166,43.736156],[7.431723,43.736115],[7.431162,43.735607],[7.430685,43.73518] + ] + ] + }, + "civicAddressElement": + [ + { + "caType": 1, + "caValue": "A1" + }, + { + "caType": 2, + "caValue": "A2" + } + ], + "countryCode": "492" + } + ], + "appCharcs": + [ + { + "memory": 1024, + "storage": 1024, + "latency": 1024, + "bandwidth": 1024, + "serviceCont": 0 + } + ], + "cmd": "/onboardedapp/onboarded-demo/onboarded-demo4", + "args":null + } + ], + "vendorSpecificExt": { + "vendorId": "ETSI" + } + } + ] +} diff --git a/examples/demo4-ue/src/onboarded-demo/server/api.go b/examples/demo4-ue/src/onboarded-demo/server/api.go new file mode 100644 index 000000000..1949a73a3 --- /dev/null +++ b/examples/demo4-ue/src/onboarded-demo/server/api.go @@ -0,0 +1,46 @@ +/* + * 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. + * + * MEEP Demo 4 API + * Demo 4 is an edge application that can be used with AdvantEDGE or ETSI MEC Sandbox to demonstrate MEC016 usage + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 0.0.1 + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ +package server + +import ( + "context" + "net/http" +) + +// FrontendApiRouter defines the required methods for binding the api requests to a responses for the FrontendApi +// The FrontendApiRouter implementation should parse necessary information from the http request, +// pass the data to a FrontendApiServicer to perform the required actions, then write the service results to the http response. +type FrontendApiRouter interface { + Ping(http.ResponseWriter, *http.Request) + Terminate(http.ResponseWriter, *http.Request) +} + +// FrontendApiServicer defines the api actions for the FrontendApi service +// This interface intended to stay up to date with the openapi yaml used to generate it, +// while the service implementation can ignored with the .openapi-generator-ignore file +// and updated with the logic required for the API. +type FrontendApiServicer interface { + Ping(context.Context) (interface{}, error) + Terminate(context.Context) (interface{}, error) +} diff --git a/examples/demo4-ue/src/onboarded-demo/server/api_frontend.go b/examples/demo4-ue/src/onboarded-demo/server/api_frontend.go new file mode 100644 index 000000000..527c9b066 --- /dev/null +++ b/examples/demo4-ue/src/onboarded-demo/server/api_frontend.go @@ -0,0 +1,79 @@ +/* + * 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. + * + * MEEP Demo 4 API + * Demo 4 is an edge application that can be used with AdvantEDGE or ETSI MEC Sandbox to demonstrate MEC016 usage + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 0.0.1 + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ +package server + +import ( + "net/http" + "strings" +) + +// A FrontendApiController binds http requests to an api service and writes the service results to the http response +type FrontendApiController struct { + service FrontendApiServicer +} + +// NewFrontendApiController creates a default api controller +func NewFrontendApiController(s FrontendApiServicer) Router { + return &FrontendApiController{service: s} +} + +// Routes returns all of the api route for the FrontendApiController +func (c *FrontendApiController) Routes() Routes { + return Routes{ + { + "Ping", + strings.ToUpper("Get"), + "/ping", + c.Ping, + }, + { + "Terminate", + strings.ToUpper("Delete"), + "/", + c.Terminate, + }, + } +} + +// Ping - Await for ping request and reply winth pong text body +func (c *FrontendApiController) Ping(w http.ResponseWriter, r *http.Request) { + result, err := c.service.Ping(r.Context()) + if err != nil { + w.WriteHeader(500) + return + } + + EncodeJSONResponse(result, nil, w) +} + +// Terminate - Terminate gracefully the application +func (c *FrontendApiController) Terminate(w http.ResponseWriter, r *http.Request) { + result, err := c.service.Terminate(r.Context()) + if err != nil { + w.WriteHeader(500) + return + } + + EncodeJSONResponse(result, nil, w) +} diff --git a/examples/demo4-ue/src/onboarded-demo/server/api_frontend_service.go b/examples/demo4-ue/src/onboarded-demo/server/api_frontend_service.go new file mode 100644 index 000000000..ce09bd148 --- /dev/null +++ b/examples/demo4-ue/src/onboarded-demo/server/api_frontend_service.go @@ -0,0 +1,59 @@ +/* + * 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. + * + * MEEP Demo 4 API + * Demo 4 is an edge application that can be used with AdvantEDGE or ETSI MEC Sandbox to demonstrate MEC016 usage + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 0.0.1 + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ +package server + +import ( + "context" + "syscall" +) + +// FrontendApiService is a service that implents the logic for the FrontendApiServicer +// This service should implement the business logic for every endpoint for the FrontendApi API. +// Include any external packages or services that will be required by this service. +type FrontendApiService struct { +} + +// NewFrontendApiService creates a default api service +func NewFrontendApiService() FrontendApiServicer { + return &FrontendApiService{} +} + +// Ping - Await for ping request and reply winth pong text body +func (s *FrontendApiService) Ping(ctx context.Context) (interface{}, error) { + // TODO - update Ping with the required logic for this service method. + // Add api_frontend_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. + //return nil, errors.New("service method 'Ping' not implemented") + return "pong", nil +} + +// Terminate - Terminate gracefully the application +func (s *FrontendApiService) Terminate(ctx context.Context) (interface{}, error) { + // TODO - update Terminate with the required logic for this service method. + // Add api_frontend_service.go to the .openapi-generator-ignore to avoid overwriting this service implementation when updating open api generation. + //return nil, errors.New("service method 'Terminate' not implemented") + + syscall.Kill(syscall.Getpid(), syscall.SIGINT) + + return nil, nil +} diff --git a/examples/demo4-ue/src/onboarded-demo/server/error.go b/examples/demo4-ue/src/onboarded-demo/server/error.go new file mode 100644 index 000000000..eabf3972b --- /dev/null +++ b/examples/demo4-ue/src/onboarded-demo/server/error.go @@ -0,0 +1,76 @@ +/* + * 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. + * + * MEEP Demo 4 API + * Demo 4 is an edge application that can be used with AdvantEDGE or ETSI MEC Sandbox to demonstrate MEC016 usage + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 0.0.1 + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ +package server + +import ( + "errors" + "fmt" + "net/http" +) + +var ( + // ErrTypeAssertionError is thrown when type an interface does not match the asserted type + ErrTypeAssertionError = errors.New("unable to assert type") +) + +// ParsingError indicates that an error has occurred when parsing request parameters +type ParsingError struct { + Err error +} + +func (e *ParsingError) Unwrap() error { + return e.Err +} + +func (e *ParsingError) Error() string { + return e.Err.Error() +} + +// RequiredError indicates that an error has occurred when parsing request parameters +type RequiredError struct { + Field string +} + +func (e *RequiredError) Error() string { + return fmt.Sprintf("required field '%s' is zero value.", e.Field) +} + +// ErrorHandler defines the required method for handling error. You may implement it and inject this into a controller if +// you would like errors to be handled differently from the DefaultErrorHandler +type ErrorHandler func(w http.ResponseWriter, r *http.Request, err error, result *ImplResponse) + +// DefaultErrorHandler defines the default logic on how to handle errors from the controller. Any errors from parsing +// request params will return a StatusBadRequest. Otherwise, the error code originating from the servicer will be used. +func DefaultErrorHandler(w http.ResponseWriter, r *http.Request, err error, result *ImplResponse) { + if _, ok := err.(*ParsingError); ok { + // Handle parsing errors + EncodeJSONResponse(err.Error(), func(i int) *int { return &i }(http.StatusBadRequest), w) + } else if _, ok := err.(*RequiredError); ok { + // Handle missing required errors + EncodeJSONResponse(err.Error(), func(i int) *int { return &i }(http.StatusUnprocessableEntity), w) + } else { + // Handle all other errors + EncodeJSONResponse(err.Error(), &result.Code, w) + } +} diff --git a/examples/demo4-ue/src/onboarded-demo/server/helpers.go b/examples/demo4-ue/src/onboarded-demo/server/helpers.go new file mode 100644 index 000000000..f4e5e7601 --- /dev/null +++ b/examples/demo4-ue/src/onboarded-demo/server/helpers.go @@ -0,0 +1,68 @@ +/* + * 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. + * + * MEEP Demo 4 API + * Demo 4 is an edge application that can be used with AdvantEDGE or ETSI MEC Sandbox to demonstrate MEC016 usage + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 0.0.1 + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ +package server + +import ( + "reflect" +) + +// Response return a ImplResponse struct filled +func Response(code int, body interface{}) ImplResponse { + return ImplResponse{ + Code: code, + Body: body, + } +} + +// IsZeroValue checks if the val is the zero-ed value. +func IsZeroValue(val interface{}) bool { + return val == nil || reflect.DeepEqual(val, reflect.Zero(reflect.TypeOf(val)).Interface()) +} + +// AssertRecurseInterfaceRequired recursively checks each struct in a slice against the callback. +// This method traverse nested slices in a preorder fashion. +func AssertRecurseInterfaceRequired(obj interface{}, callback func(interface{}) error) error { + return AssertRecurseValueRequired(reflect.ValueOf(obj), callback) +} + +// AssertRecurseValueRequired checks each struct in the nested slice against the callback. +// This method traverse nested slices in a preorder fashion. +func AssertRecurseValueRequired(value reflect.Value, callback func(interface{}) error) error { + switch value.Kind() { + // If it is a struct we check using callback + case reflect.Struct: + if err := callback(value.Interface()); err != nil { + return err + } + + // If it is a slice we continue recursion + case reflect.Slice: + for i := 0; i < value.Len(); i += 1 { + if err := AssertRecurseValueRequired(value.Index(i), callback); err != nil { + return err + } + } + } + return nil +} diff --git a/examples/demo4-ue/src/onboarded-demo/server/impl.go b/examples/demo4-ue/src/onboarded-demo/server/impl.go new file mode 100644 index 000000000..2ef23ecc3 --- /dev/null +++ b/examples/demo4-ue/src/onboarded-demo/server/impl.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. + * + * MEEP Demo 4 API + * Demo 4 is an edge application that can be used with AdvantEDGE or ETSI MEC Sandbox to demonstrate MEC016 usage + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 0.0.1 + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ +package server + +// ImplResponse response defines an error code with the associated body +type ImplResponse struct { + Code int + Body interface{} +} diff --git a/examples/demo4-ue/src/onboarded-demo/server/logger.go b/examples/demo4-ue/src/onboarded-demo/server/logger.go new file mode 100644 index 000000000..3ed73b87a --- /dev/null +++ b/examples/demo4-ue/src/onboarded-demo/server/logger.go @@ -0,0 +1,46 @@ +/* + * 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. + * + * MEEP Demo 4 API + * Demo 4 is an edge application that can be used with AdvantEDGE or ETSI MEC Sandbox to demonstrate MEC016 usage + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 0.0.1 + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ +package server + +import ( + "log" + "net/http" + "time" +) + +func Logger(inner http.Handler, name string) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + start := time.Now() + + inner.ServeHTTP(w, r) + + log.Printf( + "%s %s %s %s", + r.Method, + r.RequestURI, + name, + time.Since(start), + ) + }) +} diff --git a/examples/demo4-ue/src/onboarded-demo/server/onboarded-demo-service.go b/examples/demo4-ue/src/onboarded-demo/server/onboarded-demo-service.go new file mode 100644 index 000000000..90483511b --- /dev/null +++ b/examples/demo4-ue/src/onboarded-demo/server/onboarded-demo-service.go @@ -0,0 +1,309 @@ +/* + * 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. + * + * MEEP Demo 4 API + * Demo 4 is an edge application that can be used with AdvantEDGE or ETSI MEC Sandbox to demonstrate MEC016 usage + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 0.0.1 + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ +package server + +import ( + "context" + "errors" + //"net/http" + "strconv" + "strings" + "sync" + "time" + + asc "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-app-support-client" + tm "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-dai-mgr" + log "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-logger" + sbx "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-sandbox-ctrl-client" + smc "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-service-mgmt-client" + + "github.com/google/uuid" +) + +const ( + amName = "pc" + amNamespace = "postgis-ns" + amDBUser = "postgres" + amDBPwd = "pwd" + amDBHost = "" + amDBPort = "" +) + +const ( // FIXME confoguration file required + environment = "advantedge" + sandboxUrl = "yannsb" + mep = "mep1" + localUrl = "mec-platform.etsi.org" + localPort = ":31124" + mecUrl = "sandbox-mec.etsi.org" + appNameBase = "onboarded-demo4" +) + +// Sandbox controller client +var sandBoxClient *sbx.APIClient +var sbxCtrlUrl string = "http://meep-sandbox-ctrl" +var instanceName string = uuid.New().String() +var appName string = appNameBase + "-" + instanceName[0:32] + +// App-enablement client +var srvMgmtClient *smc.APIClient +var srvMgmtClientPath string +var appSupportClient *asc.APIClient +var appSupportClientPath string + +var appTerminationSent bool +var terminationSubscriptionId string +var terminated bool +var terminateNotification bool +var appEnabled bool +var subscriptions ApplicationInstanceSubscriptions +var mutex sync.Mutex + +// TODO Models +// List of ams subscription unique to device and their id +type ApplicationInstanceSubscriptions struct { + AppTerminationSubscription *ApplicationInstanceAppTerminationSubscription `json:"AppTerminationSubscription,omitempty"` +} + +// This type represents the information that the MEC platform notifies the subscribed application instance about the corresponding application instance termination/stop. +type ApplicationInstanceAppTerminationSubscription struct { + SubId string `json:"subId,omitempty"` +} + +// DaiMgr +var daiMgr *tm.DaiMgr = nil + +func Init() (err error) { + // Setup application support client & service management client + appSupportClientCfg := asc.NewConfiguration() + srvMgmtClientCfg := smc.NewConfiguration() + if environment == "advantedge" { + appSupportClientCfg.BasePath = "http://" + localUrl + "/" + sandboxUrl + "/mec_app_support/v1" + srvMgmtClientCfg.BasePath = "http://" + localUrl + "/" + sandboxUrl + "/mec_service_mgmt/v1" + } else { + appSupportClientCfg.BasePath = mecUrl + "/mec_app_support/v1" + srvMgmtClientCfg.BasePath = mecUrl + "/mec_service_mgmt/v1" + } + log.Info("Init: appSupportClientCfg: ", appSupportClientCfg) + + // Register UE application into sandbox controller + sandBoxClientCfg := sbx.NewConfiguration() + sandBoxClientCfg.BasePath = sbxCtrlUrl + "/sandbox-ctrl/v1" + log.Info("Init: sandBoxClientCfg= ", sandBoxClientCfg) + sandBoxClient = sbx.NewAPIClient(sandBoxClientCfg) + var appInfo = sbx.ApplicationInfo{instanceName, appName, mep, "USER", false} + appInfo, err = setApplicationInfo(appInfo) + if err != nil { + log.Fatal("Failed to set UE application resource ", appInfo) + } + + // Create app enablement client + appSupportClient = asc.NewAPIClient(appSupportClientCfg) + appSupportClientPath = appSupportClientCfg.BasePath + if appSupportClient == nil { + err := errors.New("Failed to create App Enablement App Support REST API client") + log.Error(err.Error()) + return err + } + log.Info("appSupportClient: ", appSupportClient, "/appSupportClientPath: ", appSupportClientPath) + + // Create service management client + srvMgmtClient = smc.NewAPIClient(srvMgmtClientCfg) + srvMgmtClientPath = srvMgmtClientCfg.BasePath + if srvMgmtClient == nil { + err := errors.New("Failed to create App Enablement Service Management REST API client") + log.Error(err.Error()) + return err + } + log.Info("srvMgmtClient: ", srvMgmtClient, "/srvMgmtClientPath: ", srvMgmtClientPath) + + // Create DAI client + cfgDai := tm.DaiCfg{ + Name: amName, + Namespace: amNamespace, + User: amDBUser, + Pwd: amDBPwd, + Host: amDBHost, + Port: amDBPort, + NotifyAppContextDeletion: nil, + } + daiMgr, err := tm.NewDaiMgr(cfgDai) + if err != nil { + log.Error(err.Error()) + return err + } + log.Info("Connected to DAI Manager: ", daiMgr) + + // Wait a few seconds to get all components up. + log.Info("Waiting for Service to start") + time.Sleep(5 * time.Second) + + return nil +} + +func setApplicationInfo(appInfo sbx.ApplicationInfo) (appInfoRes sbx.ApplicationInfo, err error) { + appInfoRes, resp, err := sandBoxClient.ApplicationsApi.ApplicationsPOST(context.TODO(), appInfo) + if err != nil { + log.Error(err.Error()) + return appInfoRes, err + } + log.Debug("setApplicationInfo: Receive confirmation acknowlegement ", resp.Status) + + return appInfoRes, nil +} + +// Channel sync consume channel listen for app termination +func Run() { + err := onboardedDemoRegister() + if err != nil { + log.Fatal(err.Error()) + } + +} + +// Terminate by deleting all resources allocated on MEC platform & mec app +func Terminate() { + + // Only invoke graceful termination if not terminated (triggerd by mec platform) + + if !terminated { + + if appEnabled { + log.Info("De-register " + appName + " Application") + } + + if appTerminationSent { + // Delete app subscriptions + + // Delete service + + // Send Confirm Terminate if received notification + if terminateNotification { + confirmTerminate(instanceName) + terminated = true + } + + log.Debug("Terminate: instanceName= ", instanceName) + _, err := sandBoxClient.ApplicationsApi.ApplicationsAppInstanceIdDELETE(context.TODO(), instanceName) + if err != nil { + log.Info("Failed to delete UE application resource") + } + + } + } +} + +// Client request to notify mec platform of mec app +func sendReadyConfirmation(appInstanceId string) error { + var appReady asc.AppReadyConfirmation + appReady.Indication = "READY" + log.Info(appSupportClientPath) + resp, err := appSupportClient.MecAppSupportApi.ApplicationsConfirmReadyPOST(context.TODO(), appReady, appInstanceId) + if err != nil { + log.Error(err.Error()) + //log.Error("Failed to receive confirmation acknowlegement ", resp.Status) + return err + } + log.Debug("Receive confirmation acknowlegement ", resp.Status) + + return nil +} + +// Client request to sent confirm terminate +func confirmTerminate(appInstanceId string) { + operationAction := asc.TERMINATING_OperationActionType + var terminationBody asc.AppTerminationConfirmation + terminationBody.OperationAction = &operationAction + resp, err := appSupportClient.MecAppSupportApi.ApplicationsConfirmTerminationPOST(context.TODO(), terminationBody, appInstanceId) + status := strconv.Itoa(resp.StatusCode) + if err != nil { + log.Error("Failed to send confirm termination ", err) + } else { + log.Info("Confirm Terminated") + } + log.Debug("confirmTerminate: ", status) +} + +func onboardedDemoRegister() (err error) { + mutex.Lock() + defer mutex.Unlock() + + // Start app registeration + if !appEnabled { + + // Send confirm ready + err := sendReadyConfirmation(instanceName) + if err != nil { + // Add to activity log for error indicator + log.Error(err.Error()) + return err + } + + // Retrieve mec services + // Store discovered service name into app info model + + // Subscribe to app termination + appTerminationReference := "http://" + localUrl + localPort + "/application/termination" + appTerminationId, err := subscribeAppTermination(instanceName, appTerminationReference) + if err == nil { + appTerminationSent = true + } + + // Store app termination subscription id + var appSubscription ApplicationInstanceAppTerminationSubscription + appSubscription.SubId = appTerminationId + subscriptions.AppTerminationSubscription = &appSubscription + + } + + return nil +} + +// Client request to subscribe app-termination notifications +func subscribeAppTermination(appInstanceId string, callBackReference string) (string, error) { + log.Debug("Sending request to mec platform add app terminate subscription api") + var appTerminationBody asc.AppTerminationNotificationSubscription + appTerminationBody.SubscriptionType = "AppTerminationNotificationSubscription" + appTerminationBody.CallbackReference = callBackReference + appTerminationBody.AppInstanceId = appInstanceId + appTerminationResponse, _, err := appSupportClient.MecAppSupportApi.ApplicationsSubscriptionsPOST(context.TODO(), appTerminationBody, appInstanceId) + + if err != nil { + log.Error("Failed to send termination subscription: ", err) + return "", err + } + + hRefLink := appTerminationResponse.Links.Self.Href + + // Find subscription id from response + idPosition := strings.LastIndex(hRefLink, "/") + if idPosition == -1 { + log.Error("Error parsing subscription id for subscription") + } + + terminationSubscriptionId = hRefLink[idPosition+1:] + + log.Debug("subscribeAppTermination: Subscribe to app-termination notification [201]: ", terminationSubscriptionId) + return terminationSubscriptionId, nil +} diff --git a/examples/demo4-ue/src/onboarded-demo/server/routers.go b/examples/demo4-ue/src/onboarded-demo/server/routers.go new file mode 100644 index 000000000..eff1f707b --- /dev/null +++ b/examples/demo4-ue/src/onboarded-demo/server/routers.go @@ -0,0 +1,120 @@ +/* + * 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. + * + * MEEP Demo 4 API + * Demo 4 is an edge application that can be used with AdvantEDGE or ETSI MEC Sandbox to demonstrate MEC016 usage + * + * No description provided (generated by Swagger Codegen https://github.com/swagger-api/swagger-codegen) + * + * API version: 0.0.1 + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ +package server + +import ( + "encoding/json" + "io/ioutil" + "net/http" + "os" + "strconv" + + "github.com/gorilla/mux" +) + +// A Route defines the parameters for an api endpoint +type Route struct { + Name string + Method string + Pattern string + HandlerFunc http.HandlerFunc +} + +// Routes are a collection of defined api endpoints +type Routes []Route + +// Router defines the required methods for retrieving api routes +type Router interface { + Routes() Routes +} + +// NewRouter creates a new router for any number of api routers +func NewRouter(routers ...Router) *mux.Router { + router := mux.NewRouter().StrictSlash(true) + for _, api := range routers { + for _, route := range api.Routes() { + var handler http.Handler + handler = route.HandlerFunc + handler = Logger(handler, route.Name) + + router. + Methods(route.Method). + Path(route.Pattern). + Name(route.Name). + Handler(handler) + } + } + + return router +} + +// EncodeJSONResponse uses the json encoder to write an interface to the http response with an optional status code +func EncodeJSONResponse(i interface{}, status *int, w http.ResponseWriter) error { + w.Header().Set("Content-Type", "application/json; charset=UTF-8") + if status != nil { + w.WriteHeader(*status) + } else { + w.WriteHeader(http.StatusOK) + } + + return json.NewEncoder(w).Encode(i) +} + +// ReadFormFileToTempFile reads file data from a request form and writes it to a temporary file +func ReadFormFileToTempFile(r *http.Request, key string) (*os.File, error) { + r.ParseForm() + formFile, _, err := r.FormFile(key) + if err != nil { + return nil, err + } + + defer formFile.Close() + file, err := ioutil.TempFile("tmp", key) + if err != nil { + return nil, err + } + + defer file.Close() + fileBytes, err := ioutil.ReadAll(formFile) + if err != nil { + return nil, err + } + + file.Write(fileBytes) + return file, nil +} + +// parseInt64Parameter parses a sting parameter to an int64 +func parseInt64Parameter(param string) (int64, error) { + return strconv.ParseInt(param, 10, 64) +} + +// parseInt32Parameter parses a sting parameter to an int32 +func parseInt32Parameter(param string) (int32, error) { + val, err := strconv.ParseInt(param, 10, 32) + if err != nil { + return -1, err + } + return int32(val), nil +} diff --git a/go-apps/meep-vis/api/swagger.yaml b/go-apps/meep-vis/api/swagger.yaml index 9ec5e2f8d..b5493763c 100644 --- a/go-apps/meep-vis/api/swagger.yaml +++ b/go-apps/meep-vis/api/swagger.yaml @@ -6,10 +6,9 @@ info: ISG MEC030 V2XI API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/030/02.02.01_60/gs_MEC030v020201p.pdf)

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

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

**Type & Usage**
Edge Service used by edge applications that want to get - information about radio conditions in the network

**Note**
AdvantEDGE supports - a selected subset of RNI API endpoints (see below) and a subset of subscription - types. +

**Type & Usage**
Edge Service used by edge applications that want to get information about radio conditions + in the network

**Note**
AdvantEDGE supports a selected subset of RNI API endpoints (see below) and + a subset of subscription types." contact: name: InterDigital AdvantEDGE Support email: AdvantEDGE@InterDigital.com @@ -30,7 +29,7 @@ paths: /queries/uu_unicast_provisioning_info: get: tags: - - 'unsupported' + - 'v2xi' summary: 'Used to query provisioning information for V2X communication over Uu unicast.' description: 'Used to query provisioning information for V2X communication over Uu unicast.' operationId: prov_info_uu_unicastGET @@ -163,7 +162,7 @@ paths: /publish_v2x_message: post: tags: - - 'unsupported' + - 'v2xi' summary: 'Used to publish a V2X message.' description: 'Used to publish a V2X message.' operationId: v2x_messagePOST @@ -173,6 +172,11 @@ paths: application/json: schema: $ref: '#/components/schemas/V2xMsgPublication' + example: + msgContent: 'Hello World' + msgEncodeFormat: 'base64' + msgType: 1 + stdOrganization: 'ETSI' responses: '204': $ref: '#/components/responses/204' @@ -192,7 +196,7 @@ paths: /subscriptions: get: tags: - - 'unsupported' + - 'v2xi' summary: 'Request information about the subscriptions for this requestor.' description: 'Request information about the subscriptions for this requestor.' operationId: subGET @@ -210,6 +214,16 @@ paths: application/json: schema: $ref: '#/components/schemas/SubscriptionLinkList' + example: + _links: + self: + href: 'http://meAppServer.example.com/vis/v2/subscriptions' + subscription: + - _links: + self: + href: 'http://meAppServer.example.com/vis/v2/subscriptions/123' + callbackReference: 'http://my.callback.com/vis-v2x-msg/some-id' + subscriptionType: V2xMsgSubscription '400': $ref: '#/components/responses/400' '401': @@ -224,7 +238,7 @@ paths: $ref: '#/components/responses/429' post: tags: - - 'unsupported' + - 'v2xi' summary: ' create a new subscription to VIS notifications.' description: ' create a new subscription to VIS notifications.' operationId: subPOST @@ -238,6 +252,17 @@ paths: - $ref: '#/components/schemas/ProvChgUuMbmsSubscription' - $ref: '#/components/schemas/ProvChgPc5Subscription' - $ref: '#/components/schemas/V2xMsgSubscription' + example: + subscriptionType: V2xMsgSubscription + callbackReference: 'http://my.callback.com/vis-v2x-msg/some-id' + filterCriteria: + stdOrganization: 'ETSI' + msgType: + - 1 + - 2 + expiryDeadline: + seconds: 1977836800 + nanoseconds: 0 responses: '201': description: 'In the returned NotificationSubscription structure, the created subscription is described using the appropriate data type.' @@ -249,6 +274,20 @@ paths: - $ref: '#/components/schemas/ProvChgUuMbmsSubscription' - $ref: '#/components/schemas/ProvChgPc5Subscription' - $ref: '#/components/schemas/V2xMsgSubscription' + example: + subscriptionType: V2xMsgSubscription + callbackReference: 'http://my.callback.com/vis-v2x-msg/some-id' + _links: + self: + href: 'http://meAppServer.example.com/vis/v2/subscriptions/123' + filterCriteria: + stdOrganization: 'ETSI' + msgType: + - 1 + - 2 + expiryDeadline: + seconds: 1977836800 + nanoseconds: 0 '400': $ref: '#/components/responses/400' '401': @@ -299,7 +338,7 @@ paths: get: tags: - - 'unsupported' + - 'v2xi' summary: 'Retrieve information about this subscription.' description: 'Retrieve information about this subscription.' operationId: individualSubscriptionGET @@ -315,6 +354,20 @@ paths: - $ref: '#/components/schemas/ProvChgUuMbmsSubscription' - $ref: '#/components/schemas/ProvChgPc5Subscription' - $ref: '#/components/schemas/V2xMsgSubscription' + example: + subscriptionType: V2xMsgSubscription + callbackReference: 'http://my.callback.com/vis-v2x-msg/some-id' + _links: + self: + href: 'http://meAppServer.example.com/vis/v2/subscriptions/123' + filterCriteria: + stdOrganization: 'ETSI' + msgType: + - 1 + - 2 + expiryDeadline: + seconds: 1977836800 + nanoseconds: 0 '400': $ref: '#/components/responses/400' '401': @@ -330,7 +383,7 @@ paths: put: tags: - - 'unsupported' + - 'v2xi' summary: 'Used to update the existing subscription.' description: 'Used to update the existing subscription.' operationId: individualSubscriptionPUT @@ -344,6 +397,20 @@ paths: - $ref: '#/components/schemas/ProvChgUuMbmsSubscription' - $ref: '#/components/schemas/ProvChgPc5Subscription' - $ref: '#/components/schemas/V2xMsgSubscription' + example: + subscriptionType: V2xMsgSubscription + callbackReference: 'http://my.callback.com/vis-v2x-msg/some-id' + _links: + self: + href: 'http://meAppServer.example.com/vis/v2/subscriptions/123' + filterCriteria: + stdOrganization: 'ETSI' + msgType: + - 1 + - 2 + expiryDeadline: + seconds: 1977836800 + nanoseconds: 0 responses: '200': description: 'A response body containing data type describing the updated subscription is returned' @@ -355,6 +422,21 @@ paths: - $ref: '#/components/schemas/ProvChgUuMbmsSubscription' - $ref: '#/components/schemas/ProvChgPc5Subscription' - $ref: '#/components/schemas/V2xMsgSubscription' + example: + example: + subscriptionType: V2xMsgSubscription + callbackReference: 'http://my.callback.com/vis-v2x-msg/some-id' + _links: + self: + href: 'http://meAppServer.example.com/vis/v2/subscriptions/123' + filterCriteria: + stdOrganization: 'ETSI' + msgType: + - 1 + - 2 + expiryDeadline: + seconds: 1977836800 + nanoseconds: 0 '400': $ref: '#/components/responses/400' '401': @@ -379,7 +461,7 @@ paths: $ref: '#/components/responses/429' delete: tags: - - 'unsupported' + - 'v2xi' summary: 'Used to cancel the existing subscription.' description: 'Used to cancel the existing subscription.' operationId: individualSubscriptionDELETE @@ -1536,7 +1618,7 @@ components: msgType: description: Subscribed V2X message type. Its value is defined by the standardization organization indicated by the attribute stdOrganization. See note 3. items: - type: string + type: integer minItems: 0 type: array x-etsi-mec-cardinality: 0..N diff --git a/go-apps/meep-vis/entrypoint.sh b/go-apps/meep-vis/entrypoint.sh index d1a42fd8e..15537e976 100644 --- a/go-apps/meep-vis/entrypoint.sh +++ b/go-apps/meep-vis/entrypoint.sh @@ -5,6 +5,8 @@ echo "MEEP_HOST_URL: ${MEEP_HOST_URL}" echo "MEEP_SANDBOX_NAME: ${MEEP_SANDBOX_NAME}" echo "MEEP_MEP_NAME: ${MEEP_MEP_NAME}" echo "MEEP_CODECOV: ${MEEP_CODECOV}" +echo "MEEP_BROKER: ${MEEP_BROKER}" # E.g. mqtt://test.mosquito.org:1338 or amqp://guest:guest@localhost:5672 +echo "MEEP_POA_LIST: ${MEEP_POA_LIST}" # E.g. poa-5g1;poa-5g2 if [[ ! -z "${MEEP_MEP_NAME}" ]]; then svcPath="${MEEP_SANDBOX_NAME}/${MEEP_MEP_NAME}" diff --git a/go-apps/meep-vis/go.sum b/go-apps/meep-vis/go.sum index d2b3eaf4a..05b573ec7 100644 --- a/go-apps/meep-vis/go.sum +++ b/go-apps/meep-vis/go.sum @@ -58,6 +58,7 @@ github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:Htrtb github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= +github.com/eclipse/paho.mqtt.golang v1.4.2/go.mod h1:JGt0RsEwEX+Xa/agj90YJ9d9DH2b7upDZMK9HRbFvCA= github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -365,6 +366,7 @@ golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200425230154-ff2c4b7c35a0/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= @@ -382,6 +384,8 @@ golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= diff --git a/go-apps/meep-vis/main_test.go b/go-apps/meep-vis/main_test.go index f12275209..6e642d668 100644 --- a/go-apps/meep-vis/main_test.go +++ b/go-apps/meep-vis/main_test.go @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 ETSI STF 625 + * 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. diff --git a/go-apps/meep-vis/sbi/vis-sbi.go b/go-apps/meep-vis/sbi/vis-sbi.go index 9c24ca781..0be74e967 100644 --- a/go-apps/meep-vis/sbi/vis-sbi.go +++ b/go-apps/meep-vis/sbi/vis-sbi.go @@ -17,6 +17,9 @@ package sbi import ( + "encoding/binary" + "encoding/hex" + "errors" "os" "strconv" "strings" @@ -41,6 +44,8 @@ const postgisPwd = "pwd" type SbiCfg struct { ModuleName string SandboxName string + V2xBroker string + PoaList []string MepName string RedisAddr string InfluxAddr string @@ -48,6 +53,7 @@ type SbiCfg struct { PostgisPort string Locality []string ScenarioNameCb func(string) + V2xNotify func(v2xMessage []byte, v2xType int32, longitude *float32, latitude *float32) CleanUpCb func() } @@ -58,12 +64,15 @@ type VisSbi struct { scenarioName string localityEnabled bool locality map[string]bool + v2xBroker string + poaList []string mqLocal *mq.MsgQueue handlerId int apiMgr *sam.SwaggerApiMgr activeModel *mod.Model trafficMgr *tm.TrafficMgr updateScenarioNameCB func(string) + v2xNotify func(v2xMessage []byte, v2xType int32, longitude *float32, latitude *float32) cleanUpCB func() mutex sync.Mutex predictionModelSupported bool @@ -71,6 +80,43 @@ type VisSbi struct { var sbi *VisSbi +type UuUnicastProvisioningInfoProInfoUuUnicast struct { + LocationInfo *LocationInfo + NeighbourCellInfo []UuUniNeighbourCellInfo + V2xApplicationServer *V2xApplicationServer +} +type UuUnicastProvisioningInfoProInfoUuUnicast_list []UuUnicastProvisioningInfoProInfoUuUnicast +type LocationInfo struct { + Ecgi *Ecgi + GeoArea *LocationInfoGeoArea +} +type UuUniNeighbourCellInfo struct { + Ecgi *Ecgi + //FddInfo *FddInfo + Pci int32 + Plmn *Plmn + //TddInfo *TddInfo +} +type V2xApplicationServer struct { + IpAddress string + UdpPort string +} +type Ecgi struct { + CellId *CellId + Plmn *Plmn +} +type CellId struct { + CellId string +} +type Plmn struct { + Mcc string + Mnc string +} +type LocationInfoGeoArea struct { + Latitude float32 + Longitude float32 +} + // Init - V2XI Service SBI initialization func Init(cfg SbiCfg) (predictionModelSupported bool, err error) { @@ -83,7 +129,10 @@ func Init(cfg SbiCfg) (predictionModelSupported bool, err error) { sbi.sandboxName = cfg.SandboxName sbi.mepName = cfg.MepName sbi.scenarioName = "" + sbi.v2xBroker = cfg.V2xBroker + sbi.poaList = cfg.PoaList sbi.updateScenarioNameCB = cfg.ScenarioNameCb + sbi.v2xNotify = cfg.V2xNotify sbi.cleanUpCB = cfg.CleanUpCb // redisAddr = cfg.RedisAddr // influxAddr = cfg.InfluxAddr @@ -128,7 +177,6 @@ func Init(cfg SbiCfg) (predictionModelSupported bool, err error) { log.Error("Failed to create model: ", err.Error()) return false, err } - // Get prediction model support predictionModelSupportedEnv := strings.TrimSpace(os.Getenv("MEEP_PREDICT_MODEL_SUPPORTED")) if predictionModelSupportedEnv != "" { @@ -139,25 +187,23 @@ func Init(cfg SbiCfg) (predictionModelSupported bool, err error) { } log.Info("MEEP_PREDICT_MODEL_SUPPORTED: ", sbi.predictionModelSupported) - if sbi.predictionModelSupported { - // Connect to VIS Traffic Manager - sbi.trafficMgr, err = tm.NewTrafficMgr(sbi.moduleName, sbi.sandboxName, postgisUser, postgisPwd, cfg.PostgisHost, cfg.PostgisPort) - if sbi.trafficMgr.GridFileExists { - if err != nil { - log.Error("Failed connection to VIS Traffic Manager: ", err) - return false, err - } - log.Info("Connected to VIS Traffic Manager") + // Connect to VIS Traffic Manager + sbi.trafficMgr, err = tm.NewTrafficMgr(sbi.moduleName, sbi.sandboxName, postgisUser, postgisPwd, cfg.PostgisHost, cfg.PostgisPort, cfg.V2xBroker, cfg.PoaList, cfg.V2xNotify) + if sbi.trafficMgr.GridFileExists { + if err != nil { + log.Error("Failed connection to VIS Traffic Manager: ", err) + return false, err + } + log.Info("Connected to VIS Traffic Manager") - // Delete any old tables - _ = sbi.trafficMgr.DeleteTables() + // Delete any old tables + _ = sbi.trafficMgr.DeleteTables() - } else { - // In case grid map file does not exist - log.Error("Failed connection to VIS Traffic Manager as grid map file does not exist") - _ = sbi.trafficMgr.DeleteTrafficMgr() - sbi.predictionModelSupported = false - } + } else { + // In case grid map file does not exist + log.Error("Failed connection to VIS Traffic Manager as grid map file does not exist") + _ = sbi.trafficMgr.DeleteTrafficMgr() + sbi.predictionModelSupported = false } // Initialize service @@ -271,10 +317,18 @@ func processActiveScenarioUpdate() { // Process new scenario var scenarioName = sbi.activeModel.GetScenarioName() if scenarioName != sbi.scenarioName { + log.Info("processActiveScenarioUpdate: Entering in then") // Update scenario name sbi.scenarioName = scenarioName sbi.updateScenarioNameCB(sbi.scenarioName) + err := initializeV2xMessageDistribution() + if err != nil { + log.Error("Failed to initialize V2X message distribution: ", err) + return + } + + log.Info("processActiveScenarioUpdate: sbi.scenarioName: ", sbi.scenarioName) if sbi.predictionModelSupported { // Create new tables err := sbi.trafficMgr.CreateTables() @@ -300,21 +354,118 @@ func processActiveScenarioUpdate() { } log.Info("Populated VIS DB traffic load table") } + + } + +} + +func initializeV2xMessageDistribution() (err error) { + poaNameList := sbi.activeModel.GetNodeNames(mod.NodeTypePoa4G, mod.NodeTypePoa5G) + var validPoaNameList []string + var ecgi_s []string + for _, poaName := range poaNameList { + node := sbi.activeModel.GetNode(poaName) + if node != nil { + nl := node.(*dataModel.NetworkLocation) + if nl.GeoData != nil { + validPoaNameList = append(validPoaNameList, poaName) + // Generate Ecgi according to ETSI GS MEC 030 Clause 6.5.5 Type: Ecgi + mnc := "" // TODO Apply numerical conversion directly, -1 if not initialized + mcc := "" + cellId := "" + ecgi := "" + switch nl.Type_ { + case mod.NodeTypePoa4G, mod.NodeTypePoa5G: + poaParent := sbi.activeModel.GetNodeParent(poaName) + if zone, ok := poaParent.(*dataModel.Zone); ok { + zoneParent := sbi.activeModel.GetNodeParent(zone.Name) + if domain, ok := zoneParent.(*dataModel.Domain); ok { + if domain.CellularDomainConfig != nil { + mnc = domain.CellularDomainConfig.Mnc + mcc = domain.CellularDomainConfig.Mcc + cellId = domain.CellularDomainConfig.DefaultCellId + } + } + } + if nl.Poa4GConfig != nil { + cellId = nl.Poa4GConfig.CellId + } else if nl.Poa5GConfig != nil { + cellId = nl.Poa5GConfig.CellId + } + if len(cellId)%2 != 0 { + cellId = "0" + cellId + } + log.Info("=================> cellId: ", cellId) + log.Info("=================> mnc: ", mnc) + log.Info("=================> mcc: ", mcc) + // Calculate Ecgi + cellId_num, err := strconv.Atoi(cellId) + if err != nil { + // Hexadump, + content, err := hex.DecodeString(cellId) + if err != nil { + log.Error(err.Error()) + return err + } + if len(content) > 4 { + err = errors.New("Invalid cellId format (TS 36.413: E-UTRAN Cell Identity (ECI) and E-UTRAN Cell Global Identification (ECGI)): " + cellId) + log.Error(err.Error()) + return err + } + cellId_num = int(binary.BigEndian.Uint32(content)) + } + log.Info("initializeV2xMessageDistribution: cellId_num= ", cellId_num) + TwentyEigthBits := 0xFFFFFFF // TS 36.413: E-UTRAN Cell Identity (ECI) and E-UTRAN Cell Global Identification (ECGI) + eci := cellId_num & TwentyEigthBits + log.Info("initializeV2xMessageDistribution: eci= ", int(eci)) + mcc_num, err := strconv.Atoi(mcc) + if err != nil { + log.Error(err.Error()) + return err + } + mnc_num, err := strconv.Atoi(mnc) + if err != nil { + log.Error(err.Error()) + return err + } + log.Info("initializeV2xMessageDistribution: mcc_num= ", int(mcc_num)) + log.Info("initializeV2xMessageDistribution: mnc_num= ", int(mnc_num)) + log.Info("initializeV2xMessageDistribution: plmn= ", int64(mcc_num&0xFFFFFF*1000+mnc_num&0xFFFFFF)) + var ecgi_num int64 + ecgi_num = int64((mcc_num&0xFFFFFF*1000+mnc_num&0xFFFFFF)<<28) | int64(eci) + log.Info("initializeV2xMessageDistribution: ecgi_num= ", int(ecgi_num)) + ecgi = strconv.FormatInt(int64(ecgi_num), 10) + log.Info("initializeV2xMessageDistribution: ecgi= ", ecgi) + } // End of 'switch' statement + ecgi_s = append(ecgi_s, ecgi) + } + } + } // End of 'for' statement + log.Info("initializeV2xMessageDistribution: ecgi_s= ", ecgi_s) + err = sbi.trafficMgr.InitializeV2xMessageDistribution(validPoaNameList, ecgi_s) + if err != nil { + log.Error(err.Error()) + return err } + return nil } func populatePoaTable() (err error) { poaNameList := sbi.activeModel.GetNodeNames(mod.NodeTypePoa4G, mod.NodeTypePoa5G) + var validPoaNameList []string var gpsCoordinates [][]float32 for _, poaName := range poaNameList { node := sbi.activeModel.GetNode(poaName) if node != nil { nl := node.(*dataModel.NetworkLocation) - location := nl.GeoData.Location.Coordinates - gpsCoordinates = append(gpsCoordinates, location) + if nl.GeoData != nil { + location := nl.GeoData.Location.Coordinates + validPoaNameList = append(validPoaNameList, poaName) + gpsCoordinates = append(gpsCoordinates, location) + } } - } - err = sbi.trafficMgr.PopulatePoaLoad(poaNameList, gpsCoordinates) + } // End of 'for' statement + err = sbi.trafficMgr.PopulatePoaLoad(validPoaNameList, gpsCoordinates) if err != nil { log.Error(err.Error()) return err @@ -329,3 +480,80 @@ func GetPredictedPowerValues(hour int32, inRsrp int32, inRsrq int32, poaName str } return outRsrp, outRsrq, err } + +func GetInfoUuUnicast(params []string, num_item int) (proInfoUuUnicast UuUnicastProvisioningInfoProInfoUuUnicast_list, err error) { + resp, err := sbi.trafficMgr.GetInfoUuUnicast(params, num_item) + log.Info("GetInfoUuUnicast: resp= ", resp) + proInfoUuUnicast = nil + if err != nil { + log.Error(err.Error()) + } else { + proInfoUuUnicast = make([]UuUnicastProvisioningInfoProInfoUuUnicast, len(resp)) + for i := range resp { + if resp[i].LocationInfo != nil { + proInfoUuUnicast[i].LocationInfo = new(LocationInfo) + if resp[i].LocationInfo.Ecgi != nil { + proInfoUuUnicast[i].LocationInfo.Ecgi = new(Ecgi) + if resp[i].LocationInfo.Ecgi.CellId != nil { + proInfoUuUnicast[i].LocationInfo.Ecgi.CellId = new(CellId) + proInfoUuUnicast[i].LocationInfo.Ecgi.CellId.CellId = resp[i].LocationInfo.Ecgi.CellId.CellId + } + if resp[i].LocationInfo.Ecgi.Plmn != nil { + proInfoUuUnicast[i].LocationInfo.Ecgi.Plmn = new(Plmn) + proInfoUuUnicast[i].LocationInfo.Ecgi.Plmn.Mcc = resp[i].LocationInfo.Ecgi.Plmn.Mcc + proInfoUuUnicast[i].LocationInfo.Ecgi.Plmn.Mnc = resp[i].LocationInfo.Ecgi.Plmn.Mnc + } + } + if resp[i].LocationInfo.GeoArea != nil { + proInfoUuUnicast[i].LocationInfo.GeoArea = new(LocationInfoGeoArea) + proInfoUuUnicast[i].LocationInfo.GeoArea.Latitude = resp[i].LocationInfo.GeoArea.Latitude + proInfoUuUnicast[i].LocationInfo.GeoArea.Longitude = resp[i].LocationInfo.GeoArea.Longitude + } + } + + if resp[i].NeighbourCellInfo != nil { + proInfoUuUnicast[i].NeighbourCellInfo = make([]UuUniNeighbourCellInfo, len(resp[i].NeighbourCellInfo)) + for j := range resp[i].NeighbourCellInfo { + + if resp[i].NeighbourCellInfo[j].Ecgi != nil { + proInfoUuUnicast[i].NeighbourCellInfo[j].Ecgi = new(Ecgi) + if resp[i].NeighbourCellInfo[j].Ecgi.CellId != nil { + proInfoUuUnicast[i].NeighbourCellInfo[j].Ecgi.CellId = new(CellId) + proInfoUuUnicast[i].NeighbourCellInfo[j].Ecgi.CellId.CellId = resp[i].NeighbourCellInfo[j].Ecgi.CellId.CellId + } + if resp[i].NeighbourCellInfo[j].Ecgi.Plmn != nil { + proInfoUuUnicast[i].NeighbourCellInfo[j].Ecgi.Plmn = new(Plmn) + proInfoUuUnicast[i].NeighbourCellInfo[j].Ecgi.Plmn.Mcc = resp[i].NeighbourCellInfo[j].Ecgi.Plmn.Mcc + proInfoUuUnicast[i].NeighbourCellInfo[j].Ecgi.Plmn.Mnc = resp[i].NeighbourCellInfo[j].Ecgi.Plmn.Mnc + } + } + proInfoUuUnicast[i].NeighbourCellInfo[j].Pci = resp[i].NeighbourCellInfo[j].Pci + if resp[i].NeighbourCellInfo[j].Plmn != nil { + proInfoUuUnicast[i].NeighbourCellInfo[j].Plmn = new(Plmn) + proInfoUuUnicast[i].NeighbourCellInfo[j].Plmn.Mcc = resp[i].NeighbourCellInfo[j].Plmn.Mcc + proInfoUuUnicast[i].NeighbourCellInfo[j].Plmn.Mnc = resp[i].NeighbourCellInfo[j].Plmn.Mnc + } + } // End of 'for' statement + } + if resp[i].V2xApplicationServer != nil { + proInfoUuUnicast[i].V2xApplicationServer = new(V2xApplicationServer) + proInfoUuUnicast[i].V2xApplicationServer.IpAddress = resp[i].V2xApplicationServer.IpAddress + proInfoUuUnicast[i].V2xApplicationServer.UdpPort = resp[i].V2xApplicationServer.UdpPort + } + } // End of 'for' statement + } + log.Info("GetInfoUuUnicast: proInfoUuUnicast= ", proInfoUuUnicast) + return proInfoUuUnicast, err +} + +func PublishMessageOnMessageBroker(msgContent string, msgEncodeFormat string, stdOrganization string, msgType *int32) (err error) { + return sbi.trafficMgr.PublishMessageOnMessageBroker(msgContent, msgEncodeFormat, stdOrganization, msgType) +} + +func StartV2xMessageBrokerServer() (err error) { + return sbi.trafficMgr.StartV2xMessageBrokerServer() +} + +func StopV2xMessageBrokerServer() { + sbi.trafficMgr.StopV2xMessageBrokerServer() +} diff --git a/go-apps/meep-vis/server/README.md b/go-apps/meep-vis/server/README.md index 3a15b6ea1..3b8c46ea9 100644 --- a/go-apps/meep-vis/server/README.md +++ b/go-apps/meep-vis/server/README.md @@ -13,7 +13,7 @@ To see how to make this your own, look here: [README](https://github.com/swagger-api/swagger-codegen/blob/master/README.md) - API version: 2.2.1 -- Build date: 2022-12-19T08:32:03.261794-05:00[America/Toronto] +- Build date: 2022-11-04T17:14:22.484925-04:00[America/New_York] ### Running the server diff --git a/go-apps/meep-vis/server/api_unsupported.go b/go-apps/meep-vis/server/api_unsupported.go index 8fcdd0780..b7d091683 100644 --- a/go-apps/meep-vis/server/api_unsupported.go +++ b/go-apps/meep-vis/server/api_unsupported.go @@ -27,18 +27,6 @@ import ( "net/http" ) -func IndividualSubscriptionDELETE(w http.ResponseWriter, r *http.Request) { - notImplemented(w, r) -} - -func IndividualSubscriptionGET(w http.ResponseWriter, r *http.Request) { - notImplemented(w, r) -} - -func IndividualSubscriptionPUT(w http.ResponseWriter, r *http.Request) { - notImplemented(w, r) -} - func ProvInfoGET(w http.ResponseWriter, r *http.Request) { notImplemented(w, r) } @@ -46,19 +34,3 @@ func ProvInfoGET(w http.ResponseWriter, r *http.Request) { func ProvInfoUuMbmsGET(w http.ResponseWriter, r *http.Request) { notImplemented(w, r) } - -func ProvInfoUuUnicastGET(w http.ResponseWriter, r *http.Request) { - notImplemented(w, r) -} - -func SubGET(w http.ResponseWriter, r *http.Request) { - notImplemented(w, r) -} - -func SubPOST(w http.ResponseWriter, r *http.Request) { - notImplemented(w, r) -} - -func V2xMessagePOST(w http.ResponseWriter, r *http.Request) { - notImplemented(w, r) -} diff --git a/go-apps/meep-vis/server/api_v2xi.go b/go-apps/meep-vis/server/api_v2xi.go index ddfde7704..3d3a28e48 100644 --- a/go-apps/meep-vis/server/api_v2xi.go +++ b/go-apps/meep-vis/server/api_v2xi.go @@ -34,3 +34,31 @@ func Mec011AppTerminationPOST(w http.ResponseWriter, r *http.Request) { func PredictedQosPOST(w http.ResponseWriter, r *http.Request) { predictedQosPost(w, r) } + +func SubPOST(w http.ResponseWriter, r *http.Request) { + subscriptionsPost(w, r) +} + +func IndividualSubscriptionDELETE(w http.ResponseWriter, r *http.Request) { + individualSubscriptionDelete(w, r) +} + +func IndividualSubscriptionGET(w http.ResponseWriter, r *http.Request) { + individualSubscriptionGET(w, r) +} + +func IndividualSubscriptionPUT(w http.ResponseWriter, r *http.Request) { + individualSubscriptionPut(w, r) +} + +func ProvInfoUuUnicastGET(w http.ResponseWriter, r *http.Request) { + provInfoUuUnicastGET(w, r) +} + +func SubGET(w http.ResponseWriter, r *http.Request) { + subscriptionsGET(w, r) +} + +func V2xMessagePOST(w http.ResponseWriter, r *http.Request) { + V2xMsgPublicationPOST(w, r) +} diff --git a/go-apps/meep-vis/server/convert.go b/go-apps/meep-vis/server/convert.go index 28a71648b..f5dd9b259 100644 --- a/go-apps/meep-vis/server/convert.go +++ b/go-apps/meep-vis/server/convert.go @@ -39,3 +39,21 @@ func convertProblemDetailstoJson(probdetails *ProblemDetails) string { } return string(jsonInfo) } + +func convertV2xMsgSubscriptionToJson(v2xMsgSubscription *V2xMsgSubscription) string { + jsonInfo, err := json.Marshal(*v2xMsgSubscription) + if err != nil { + log.Error(err.Error()) + return "" + } + return string(jsonInfo) +} + +// func convertV2xMsgPublicationToJson(v2xMsgPublication *V2xMsgPublication) string { +// jsonInfo, err := json.Marshal(*v2xMsgPublication) +// if err != nil { +// log.Error(err.Error()) +// return "" +// } +// return string(jsonInfo) +// } diff --git a/go-apps/meep-vis/server/model_expiry_notification.go b/go-apps/meep-vis/server/model_expiry_notification.go new file mode 100644 index 000000000..ac83887e2 --- /dev/null +++ b/go-apps/meep-vis/server/model_expiry_notification.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 V2X Information Service REST API + * + * V2X Information Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC030 V2XI API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/030/02.02.01_60/gs_MEC030v020201p.pdf)

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

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

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

**Note**
AdvantEDGE supports a selected subset of RNI API endpoints (see below) and a subset of subscription types. + * + * API version: 2.2.1 + * Contact: AdvantEDGE@InterDigital.com + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ +package server + +type ExpiryNotification struct { + Links *ExpiryNotificationLinks `json:"_links"` + + ExpiryDeadline *TimeStamp `json:"expiryDeadline"` + + TimeStamp *TimeStamp `json:"timeStamp,omitempty"` + // Shall be set to \"ExpiryNotification\" + NotificationType string `json:"notificationType"` +} diff --git a/go-apps/meep-vis/server/model_expiry_notification__links.go b/go-apps/meep-vis/server/model_expiry_notification__links.go new file mode 100644 index 000000000..d179574e9 --- /dev/null +++ b/go-apps/meep-vis/server/model_expiry_notification__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 V2X Information Service REST API + * + * V2X Information Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC030 V2XI API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/030/02.02.01_60/gs_MEC030v020201p.pdf)

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

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

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

**Note**
AdvantEDGE supports a selected subset of RNI API endpoints (see below) and a subset of subscription types. + * + * API version: 2.2.1 + * Contact: AdvantEDGE@InterDigital.com + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ +package server + +// List of hyperlinks related to the resource. +type ExpiryNotificationLinks struct { + Subscription *LinkType `json:"subscription"` +} diff --git a/go-apps/meep-vis/server/model_subscription_type.go b/go-apps/meep-vis/server/model_subscription_type.go new file mode 100644 index 000000000..e5350dcda --- /dev/null +++ b/go-apps/meep-vis/server/model_subscription_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 server + +type SubscriptionType string + +// List of SubscriptionType +const ( + PROV_CHG_UU_UNI_SubscriptionType SubscriptionType = "UuUnicastSubscription" + PROV_CHG_UU_MBMS_SubscriptionType SubscriptionType = "UuMbmsSubscription" + PROV_CHG_PC5_SubscriptionType SubscriptionType = "Pc5Subscription" + V2X_MSG_SubscriptionType SubscriptionType = "V2xMsgSubscription" +) diff --git a/go-apps/meep-vis/server/model_v2x_msg_subscription_filter_criteria.go b/go-apps/meep-vis/server/model_v2x_msg_subscription_filter_criteria.go index 90170e8d8..ade1666d8 100644 --- a/go-apps/meep-vis/server/model_v2x_msg_subscription_filter_criteria.go +++ b/go-apps/meep-vis/server/model_v2x_msg_subscription_filter_criteria.go @@ -26,7 +26,7 @@ package server // 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 V2xMsgSubscriptionFilterCriteria struct { // Subscribed V2X message type. Its value is defined by the standardization organization indicated by the attribute stdOrganization. See note 3. - MsgType []string `json:"msgType,omitempty"` + MsgType []MsgType `json:"msgType,omitempty"` // Standardization organization which defines the subscribed V2X message type: ETSI: European Telecommunications Standards Institute. See note 2. StdOrganization string `json:"stdOrganization"` } diff --git a/go-apps/meep-vis/server/subscriptionCommon.go b/go-apps/meep-vis/server/subscriptionCommon.go new file mode 100644 index 000000000..a2fc7e097 --- /dev/null +++ b/go-apps/meep-vis/server/subscriptionCommon.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 V2X Information Service REST API + * + * V2X Information Service is AdvantEDGE's implementation of [ETSI MEC ISG MEC030 V2XI API](http://www.etsi.org/deliver/etsi_gs/MEC/001_099/030/02.02.01_60/gs_MEC030v020201p.pdf)

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

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

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

**Note**
AdvantEDGE supports a selected subset of RNI API endpoints (see below) and a subset of subscription types. + * + * API version: 2.2.1 + * Contact: AdvantEDGE@InterDigital.com + * Generated by: Swagger Codegen (https://github.com/swagger-api/swagger-codegen.git) + */ +package server + +type SubscriptionCommon struct { + Links *Links `json:"_links,omitempty"` + // URI selected by the service consumer, to receive notifications on the subscribed RNIS information. This shall be included in the request and response. + SubscriptionType string `json:"subscriptionType"` + CallbackReference string `json:"callbackReference"` + WebsockNotifConfig *WebsockNotifConfig `json:"websockNotifConfig,omitempty"` + FilterCriteria *V2xMsgSubscriptionFilterCriteria `json:"filterCriteria"` + ExpiryDeadline *TimeStamp `json:"expiryDeadline,omitempty"` +} diff --git a/go-apps/meep-vis/server/vis.go b/go-apps/meep-vis/server/vis.go index 7e37b9835..91721e7cd 100644 --- a/go-apps/meep-vis/server/vis.go +++ b/go-apps/meep-vis/server/vis.go @@ -17,15 +17,20 @@ package server import ( + "bytes" "context" + "encoding/hex" "encoding/json" "errors" "fmt" + "io/ioutil" "net/http" "net/url" "os" + "sort" "strconv" "strings" + "sync" "time" sbi "github.com/InterDigitalInc/AdvantEDGE/go-apps/meep-vis/sbi" @@ -34,10 +39,12 @@ import ( gisClient "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-gis-engine-client" httpLog "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-http-logger" log "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-logger" + met "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-metrics" redis "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-redis" scc "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-sandbox-ctrl-client" smc "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-service-mgmt-client" sm "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-subscriptions" + "github.com/gorilla/mux" ) const moduleName = "meep-vis" @@ -70,6 +77,8 @@ var scopeOfLocality string = defaultScopeOfLocality var consumedLocalOnly bool = defaultConsumedLocalOnly var predictionModelSupported bool = defaultPredictionModelSupported var locality []string +var v2x_broker string +var v2x_poa_list []string var basePath string var baseKey string @@ -94,6 +103,33 @@ var sbxCtrlClient *scc.APIClient var registrationTicker *time.Ticker var subMgr *sm.SubscriptionMgr = nil +const v2xSubscriptionType = "v2xMsgSubscription" +const notifExpiry = "ExpiryNotification" +const V2X_MSG = "V2xMsgSubscription" +const PROV_CHG_UU_UNI = "ProvChgUuUniSubscription" +const PROV_CHG_UU_MBMS = "ProvChgUuMbmsSubscription" +const PROV_CHG_PC5 = "ProvChgPc5Subscription" + +var v2xMsgSubscriptionMap = map[int]*V2xMsgSubscription{} + +// var provChgUuUniSubscriptionMap = map[int]*ProvChgUuUniSubscription{} +var subscriptionExpiryMap = map[int][]int{} + +var mutex sync.Mutex +var expiryTicker *time.Ticker +var nextSubscriptionIdAvailable int + +//var nextV2xMsgPubIdAvailable int = 0 + +const v2xMsgNotifType = "V2xMsgNotification" + +// type msgTypeAndStdOrgCheck struct { +// msgTypeInReq MsgType +// stdOrgInReq string +// subscriptionLinks []LinkType +// callBackReferenceArray []string +// } + func notImplemented(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "application/json; charset=UTF-8") w.WriteHeader(http.StatusNotImplemented) @@ -190,6 +226,40 @@ func sendTerminationConfirmation(appInstanceId string) error { return nil } +func isSubscriptionIdRegisteredV2x(subsIdStr string) bool { + var returnVal bool + subsId, _ := strconv.Atoi(subsIdStr) + mutex.Lock() + defer mutex.Unlock() + + if v2xMsgSubscriptionMap[subsId] != nil { + returnVal = true + } else { + returnVal = false + } + return returnVal +} + +/* +* registerV2x to register new v2xMsgSubscription +* @param {struct} v2xMsgSubscription contains request body send to /subscriptions endpoint +* @param {string} subsIdStr contains an Id to uniquely subscription + */ +func registerV2x(v2xMsgSubscription *V2xMsgSubscription, subsIdStr string) { + subsId, _ := strconv.Atoi(subsIdStr) + mutex.Lock() + defer mutex.Unlock() + + v2xMsgSubscriptionMap[subsId] = v2xMsgSubscription + if v2xMsgSubscription.ExpiryDeadline != nil { + //get current list of subscription meant to expire at this time + intList := subscriptionExpiryMap[int(v2xMsgSubscription.ExpiryDeadline.Seconds)] + intList = append(intList, subsId) + subscriptionExpiryMap[int(v2xMsgSubscription.ExpiryDeadline.Seconds)] = intList + } + log.Info("New registration: ", subsId, " type: ", v2xSubscriptionType) +} + func subscribeAppTermination(appInstanceId string) error { var sub asc.AppTerminationNotificationSubscription sub.SubscriptionType = "AppTerminationNotificationSubscription" @@ -337,6 +407,20 @@ func Init() (err error) { } log.Info("MEEP_LOCALITY: ", locality) + // Get V2X brokers. E.g. mqtt://test.mosquito.org:1338 or amqp://guest:guest@localhost:5672 + v2x_broker := strings.TrimSpace(os.Getenv("MEEP_BROKER")) + log.Info("MEEP_BROKER: ", v2x_broker) + + // E.g. poa-5g1,poa-5g2 + poa_list := strings.TrimSpace(os.Getenv("MEEP_POA_LIST")) + if poa_list != "" { + v2x_poa_list = strings.Split(poa_list, ";") + if len(v2x_poa_list) > 1 { + sort.Strings(v2x_poa_list) // Sorting the PoA list to use search algorithms + } + } + log.Info("MEEP_POA_LIST: ", v2x_poa_list) + // Set base path if mepName == defaultMepName { basePath = "/" + sandboxName + "/" + visBasePath @@ -366,15 +450,27 @@ func Init() (err error) { return err } + reInit() + + expiryTicker = time.NewTicker(time.Second) + go func() { + for range expiryTicker.C { + checkForExpiredSubscriptions() + } + }() + // Initialize SBI sbiCfg := sbi.SbiCfg{ ModuleName: moduleName, SandboxName: sandboxName, + V2xBroker: v2x_broker, + PoaList: v2x_poa_list, RedisAddr: redisAddr, PostgisHost: postgisHost, PostgisPort: postgisPort, Locality: locality, ScenarioNameCb: updateStoreName, + V2xNotify: v2xNotify, CleanUpCb: cleanUp, } if mepName != defaultMepName { @@ -421,6 +517,15 @@ func Init() (err error) { return nil } +// reInit - finds the value already in the DB to repopulate local stored info +func reInit() { + //next available subsId will be overrriden if subscriptions already existed + nextSubscriptionIdAvailable = 1 + + keyName := baseKey + "subscriptions:" + "*" + _ = rc.ForEachJSONEntry(keyName, repopulateV2xMsgSubscriptionMap, nil) +} + // Run - Start VIS func Run() (err error) { // Start MEC Service registration ticker @@ -535,6 +640,9 @@ func cleanUp() { // Flush all service data rc.DBFlush(baseKey) + subscriptionExpiryMap = map[int][]int{} + v2xMsgSubscriptionMap = map[int]*V2xMsgSubscription{} + // Reset metrics store name updateStoreName("") } @@ -692,3 +800,862 @@ func errHandlerProblemDetails(w http.ResponseWriter, error string, code int) { w.WriteHeader(code) fmt.Fprint(w, jsonResponse) } + +// V2xMsgPublicationPOST is to create at V2xMsgPublication /publish_v2x_message endpoint +func V2xMsgPublicationPOST(w http.ResponseWriter, r *http.Request) { + + log.Info("V2xMsgPublicationPOST: ", r) + w.Header().Set("Content-Type", "application/json; charset=UTF-8") + + var v2xMsgPubReq V2xMsgPublication + // Read JSON input stream provided in the Request, and stores it in the bodyBytes as bytes + bodyBytes, _ := ioutil.ReadAll(r.Body) + // Unmarshal function to converts a JSON-formatted string into a V2xMsgPublication struct and store it in v2xMsgPubReq + err := json.Unmarshal(bodyBytes, &v2xMsgPubReq) + if err != nil { + log.Error(err.Error()) + errHandlerProblemDetails(w, err.Error(), http.StatusInternalServerError) + return + } + + // Validating mandatory parameters provided in the request body + if v2xMsgPubReq.StdOrganization == "" { + log.Error("Mandatory StdOrganization parameter should be present") + errHandlerProblemDetails(w, "Mandatory attribute StdOrganization is missing in the request body.", http.StatusBadRequest) + return + } + + if v2xMsgPubReq.MsgType == nil { + log.Error("Mandatory MsgType parameter should be present") + errHandlerProblemDetails(w, "Mandatory attribute MsgType is missing in the request body.", http.StatusBadRequest) + return + } + + if v2xMsgPubReq.MsgEncodeFormat == "" { + log.Error("Mandatory MsgEncodeFormat parameter should be present") + errHandlerProblemDetails(w, "Mandatory attribute MsgEncodeFormat is missing in the request body.", http.StatusBadRequest) + return + } + + if v2xMsgPubReq.MsgContent == "" { + log.Error("Mandatory MsgContent parameter should be present") + errHandlerProblemDetails(w, "Mandatory attribute MsgContent is missing in the request body.", http.StatusBadRequest) + return + } + + if *v2xMsgPubReq.MsgType < 1 || *v2xMsgPubReq.MsgType > 13 { + log.Error("MsgType parameter should be between 1 and 13") + errHandlerProblemDetails(w, "MsgType parameter should be between 1 and 13 in the request body.", http.StatusBadRequest) + return + } + + if len(v2xMsgSubscriptionMap) != 0 { // There are some subscription ongoing, we can publish it + // Publish message on message broker + var msgType *int32 = nil + if v2xMsgPubReq.MsgType != nil { + msgType = new(int32) + *msgType = int32(*v2xMsgPubReq.MsgType) + } + err = sbi.PublishMessageOnMessageBroker(v2xMsgPubReq.MsgContent, v2xMsgPubReq.MsgEncodeFormat, v2xMsgPubReq.StdOrganization, msgType) + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + } + w.WriteHeader(http.StatusNoContent) + } else { // No subscription ongoing, discard it + log.Error("No subscription ongoing, discard it") + errHandlerProblemDetails(w, "No subscription ongoing, discard it.", http.StatusBadRequest) + return + } + +} + +/* +* sendV2xMsgNotification sends notification to the call reference address +* @param {string} notifyUrl contains the call reference address +* @param {struct} notification contains notification body of type V2xMsgNotification + */ +func sendV2xMsgNotification(notifyUrl string, notification V2xMsgNotification) { + startTime := time.Now() + jsonNotif, err := json.Marshal(notification) + if err != nil { + log.Error(err) + return + } + log.Info("sendV2xMsgNotification: jsonNotif: ", string(jsonNotif)) + + resp, err := http.Post(notifyUrl, "application/json", bytes.NewBuffer(jsonNotif)) + log.Info("sendV2xMsgNotification: resp: ", resp) + duration := float64(time.Since(startTime).Microseconds()) / 1000.0 + _ = httpLog.LogNotification(notifyUrl, "POST", "", "", string(jsonNotif), resp, startTime) + if err != nil { + log.Error(err) + met.ObserveNotification(sandboxName, serviceName, v2xMsgNotifType, notifyUrl, nil, duration) + return + } + met.ObserveNotification(sandboxName, serviceName, v2xMsgNotifType, notifyUrl, resp, duration) + defer resp.Body.Close() +} + +// subscriptionsPost is to create subscription at /subscriptions endpoint +func subscriptionsPost(w http.ResponseWriter, r *http.Request) { + + log.Info("subPost") + w.Header().Set("Content-Type", "application/json; charset=UTF-8") + + var subscriptionCommon SubscriptionCommon + // Read JSON input stream provided in the Request, and stores it in the bodyBytes as bytes + bodyBytes, _ := ioutil.ReadAll(r.Body) + // Unmarshal function to converts a JSON-formatted string into a SubscriptionCommon struct and store it in extractSubType + err := json.Unmarshal(bodyBytes, &subscriptionCommon) + if err != nil { + log.Error(err.Error()) + errHandlerProblemDetails(w, err.Error(), http.StatusInternalServerError) + return + } + + // Validating mandatory parameters provided in the request body + if subscriptionCommon.SubscriptionType == "" { + log.Error("Mandatory SubscriptionType parameter should be present") + errHandlerProblemDetails(w, "Mandatory attribute SubscriptionType is missing in the request body.", http.StatusBadRequest) + return + } + + if subscriptionCommon.CallbackReference == "" && subscriptionCommon.WebsockNotifConfig == nil { + log.Error("At least one of CallbackReference and WebsockNotifConfig parameters should be present") + errHandlerProblemDetails(w, "At least one of CallbackReference and WebsockNotifConfig parameters should be present.", http.StatusBadRequest) + return + } + + //extract subscription type + subscriptionType := subscriptionCommon.SubscriptionType + + // subscriptionId will be generated sequentially + newSubsId := nextSubscriptionIdAvailable + nextSubscriptionIdAvailable++ + subsIdStr := strconv.Itoa(newSubsId) + + // create a unique link for every subscription and concatenate subscription to it + link := new(Links) + self := new(LinkType) + self.Href = hostUrl.String() + basePath + "subscriptions/" + subsIdStr + link.Self = self + + var jsonResponse string + + // switch statement is based on provided subscriptionType in the request body + switch subscriptionType { + // if subscription is of type V2xMsgSubscription + case V2X_MSG: + + var v2xSubscription V2xMsgSubscription + + err = json.Unmarshal(bodyBytes, &v2xSubscription) + if err != nil { + log.Error(err.Error()) + errHandlerProblemDetails(w, err.Error(), http.StatusInternalServerError) + return + } + + // Validating mandatory parameters provided in the request body + if v2xSubscription.Links != nil { + log.Error("Links attribute should not be present in request body") + errHandlerProblemDetails(w, "Links attribute should not be present in request body.", http.StatusBadRequest) + return + } + + if v2xSubscription.FilterCriteria == nil { + log.Error("Mandatory FilterCriteria parameter should be present") + errHandlerProblemDetails(w, "Mandatory attribute FilterCriteria is missing in the request body.", http.StatusBadRequest) + return + } + + if v2xSubscription.FilterCriteria != nil && v2xSubscription.FilterCriteria.StdOrganization == "" { + log.Error("Mandatory StdOrganization parameter should be present") + errHandlerProblemDetails(w, "Mandatory attribute StdOrganization is missing in the request body.", http.StatusBadRequest) + return + } + + if v2xSubscription.WebsockNotifConfig != nil { + v2xSubscription.WebsockNotifConfig = subscriptionCommon.WebsockNotifConfig + } + + if v2xSubscription.CallbackReference != "" { + v2xSubscription.CallbackReference = subscriptionCommon.CallbackReference + } + + if !checkMsgTypeValue(v2xSubscription.FilterCriteria.MsgType) { + log.Error("MsgType parameter should be between 1 and 13") + errHandlerProblemDetails(w, "MsgType parameter should be between 1 and 13 in the request body.", http.StatusBadRequest) + return + } + + v2xSubscription.Links = link + + registerV2xSub(&v2xSubscription, subsIdStr) + + // Store subscription key in redis + _ = rc.JSONSetEntry(baseKey+"subscriptions:"+subsIdStr, ".", convertV2xMsgSubscriptionToJson(&v2xSubscription)) + + jsonResponse = convertV2xMsgSubscriptionToJson(&v2xSubscription) + + // if subscription is of type ProvChgUuUniSubscription + case PROV_CHG_UU_UNI: + //TODO + + default: + log.Error("Unsupported subscriptionType") + return + } + + // Prepare & send response + w.WriteHeader(http.StatusCreated) + fmt.Fprint(w, jsonResponse) +} + +func createSubscriptionLinkList(subType string) *SubscriptionLinkList { + + subscriptionLinkList := new(SubscriptionLinkList) + + link := new(SubscriptionLinkListLinks) + self := new(LinkType) + self.Href = hostUrl.String() + basePath + "subscriptions" + + link.Self = self + subscriptionLinkList.Links = link + + //loop through all different types of subscription + + mutex.Lock() + defer mutex.Unlock() + + //loop through v2x_msg map + if subType == "" || subType == "v2x_msg" { + for _, v2xSubscription := range v2xMsgSubscriptionMap { + if v2xSubscription != nil { + var subscription SubscriptionLinkListLinksSubscriptions + subscription.Href = v2xSubscription.Links.Self.Href + subscription.SubscriptionType = V2X_MSG + subscriptionLinkList.Links.Subscriptions = append(subscriptionLinkList.Links.Subscriptions, subscription) + } + } + } + //no other maps to go through + + return subscriptionLinkList +} + +// subscriptionsGET is to retrieve information about all existing subscriptions at /subscriptions endpoint +func subscriptionsGET(w http.ResponseWriter, r *http.Request) { + log.Info("subGet") + w.Header().Set("Content-Type", "application/json; charset=UTF-8") + + // get & validate query param values for subscription_type + u, _ := url.Parse(r.URL.String()) + log.Info("url: ", u.RequestURI()) + q := u.Query() + subType := q.Get("subscription_type") + + validQueryParams := []string{"subscription_type"} + validQueryParamValues := []string{"prov_chg_uu_uni", "prov_chg_uu_mbms", "prov_chg_pc5", "v2x_msg"} + + // look for all query parameters to reject if any invalid ones + found := false + for queryParam, values := range q { + found = false + for _, validQueryParam := range validQueryParams { + if queryParam == validQueryParam { + found = true + break + } + } + if !found { + log.Error("Query param not valid: ", queryParam) + w.WriteHeader(http.StatusBadRequest) + return + } + for _, validQueryParamValue := range validQueryParamValues { + found = false + for _, value := range values { + if value == validQueryParamValue { + found = true + break + } + } + if found { + break + } + } + if !found { + log.Error("Query param not valid: ", queryParam) + w.WriteHeader(http.StatusBadRequest) + return + } + + } + + // get the response against particular subscription type + response := createSubscriptionLinkList(subType) + + // prepare & send response + jsonResponse, err := json.Marshal(response) + if err != nil { + log.Error(err.Error()) + errHandlerProblemDetails(w, err.Error(), http.StatusInternalServerError) + return + } + + // success response code + w.WriteHeader(http.StatusOK) + fmt.Fprint(w, string(jsonResponse)) +} + +// individualSubscriptionGET is to retrive a specific subscriptionsInfo at /subscriptions/{subscriptionId} endpoint +func individualSubscriptionGET(w http.ResponseWriter, r *http.Request) { + log.Info("individualSubGet") + + w.Header().Set("Content-Type", "application/json; charset=UTF-8") + vars := mux.Vars(r) + subsIdStr := vars["subscriptionId"] + + keyName := baseKey + "subscriptions:" + subsIdStr + + // Find subscription entry in Redis DB + v2xMsgJson, err := rc.JSONGetEntry(keyName, ".") + if err != nil { + err = errors.New("subscription not found against the provided subscriptionId") + log.Error(err.Error()) + errHandlerProblemDetails(w, err.Error(), http.StatusNotFound) + return + } + + // Prepare & send v2xMsgSubscription as a response + var v2xMsgSubResp V2xMsgSubscription + err = json.Unmarshal([]byte(v2xMsgJson), &v2xMsgSubResp) + if err != nil { + log.Error(err.Error()) + errHandlerProblemDetails(w, err.Error(), http.StatusInternalServerError) + return + } + jsonResponse := convertV2xMsgSubscriptionToJson(&v2xMsgSubResp) + + w.WriteHeader(http.StatusOK) + fmt.Fprint(w, jsonResponse) +} + +func registerV2xSub(v2xMsgSubscription *V2xMsgSubscription, subId string) { + subsId, _ := strconv.Atoi(subId) + mutex.Lock() + defer mutex.Unlock() + + v2xMsgSubscriptionMap[subsId] = v2xMsgSubscription + if v2xMsgSubscription.ExpiryDeadline != nil { + //get current list of subscription meant to expire at this time + intList := subscriptionExpiryMap[int(v2xMsgSubscription.ExpiryDeadline.Seconds)] + intList = append(intList, subsId) + subscriptionExpiryMap[int(v2xMsgSubscription.ExpiryDeadline.Seconds)] = intList + } + log.Info("New registration: ", subsId, " type: ", v2xSubscriptionType) + + if len(subscriptionExpiryMap) == 1 { // Start V2X message broker server + log.Info("registerV2xSub: StartV2xMessageBrokerServer") + _ = sbi.StartV2xMessageBrokerServer() + } else if len(subscriptionExpiryMap) == 0 { // Stop V2X message broker server + log.Info("registerV2xSub: StopV2xMessageBrokerServer") + sbi.StopV2xMessageBrokerServer() + } +} + +/* + * checkForExpiredSubscriptions delete those subscriptions whose expiryTime is reached + */ +func checkForExpiredSubscriptions() { + + nowTime := int(time.Now().Unix()) + mutex.Lock() + defer mutex.Unlock() + for expiryTime, subsIndexList := range subscriptionExpiryMap { + if expiryTime <= nowTime { + subscriptionExpiryMap[expiryTime] = nil + for _, subsId := range subsIndexList { + cbRef := "" + if v2xMsgSubscriptionMap[subsId] != nil { + cbRef = v2xMsgSubscriptionMap[subsId].CallbackReference + } else { + continue + } + + subsIdStr := strconv.Itoa(subsId) + + var notif ExpiryNotification + + seconds := time.Now().Unix() + var timeStamp TimeStamp + timeStamp.Seconds = int32(seconds) + + var expiryTimeStamp TimeStamp + expiryTimeStamp.Seconds = int32(expiryTime) + + link := new(ExpiryNotificationLinks) + link.Subscription.Href = cbRef + notif.Links = link + + notif.TimeStamp = &timeStamp + notif.ExpiryDeadline = &expiryTimeStamp + sendExpiryNotification(link.Subscription.Href, notif) + _ = delSubscription(baseKey, subsIdStr, true) + } + } + } +} + +/* +* sendExpiryNotification send expiry notification to the the corresponding callback reference address +* @param {string} notifyUrl contains callback reference address of service consumer +* @param {struct} notification struct of type ExpiryNotification + */ +func sendExpiryNotification(notifyUrl string, notification ExpiryNotification) { + startTime := time.Now() + jsonNotif, err := json.Marshal(notification) + if err != nil { + log.Error(err.Error()) + } + + resp, err := http.Post(notifyUrl, "application/json", bytes.NewBuffer(jsonNotif)) + duration := float64(time.Since(startTime).Microseconds()) / 1000.0 + _ = httpLog.LogNotification(notifyUrl, "POST", "", "", string(jsonNotif), resp, startTime) + if err != nil { + log.Error(err) + met.ObserveNotification(sandboxName, serviceName, notifExpiry, notifyUrl, nil, duration) + return + } + met.ObserveNotification(sandboxName, serviceName, notifExpiry, notifyUrl, resp, duration) + defer resp.Body.Close() +} + +/* +* delSubscription delete expired subscriptions from redis DB + */ +func delSubscription(keyPrefix string, subsId string, mutexTaken bool) error { + + err := rc.JSONDelEntry(keyPrefix+":"+subsId, ".") + deregisterv2xMsgSub(subsId, mutexTaken) + + return err +} + +func deregisterv2xMsgSub(subsIdStr string, mutexTaken bool) { + subsId, _ := strconv.Atoi(subsIdStr) + if !mutexTaken { + mutex.Lock() + defer mutex.Unlock() + } + delete(v2xMsgSubscriptionMap, subsId) + log.Info("Deregistration: ", subsId, " type: ", v2xSubscriptionType) + + log.Info("Deregistration: len(v2xMsgSubscriptionMap): ", len(v2xMsgSubscriptionMap)) + if len(v2xMsgSubscriptionMap) == 0 { + sbi.StopV2xMessageBrokerServer() + } +} + +func repopulateV2xMsgSubscriptionMap(key string, jsonInfo string, userData interface{}) error { + + var v2xMsgSubscription V2xMsgSubscription + + // Format response + err := json.Unmarshal([]byte(jsonInfo), &v2xMsgSubscription) + if err != nil { + return err + } + + selfUrl := strings.Split(v2xMsgSubscription.Links.Self.Href, "/") + subsIdStr := selfUrl[len(selfUrl)-1] + subsId, _ := strconv.Atoi(subsIdStr) + + mutex.Lock() + defer mutex.Unlock() + + v2xMsgSubscriptionMap[subsId] = &v2xMsgSubscription + if v2xMsgSubscription.ExpiryDeadline != nil { + intList := subscriptionExpiryMap[int(v2xMsgSubscription.ExpiryDeadline.Seconds)] + intList = append(intList, subsId) + subscriptionExpiryMap[int(v2xMsgSubscription.ExpiryDeadline.Seconds)] = intList + } + + //reinitialisation of next available Id for future subscription request + if subsId >= nextSubscriptionIdAvailable { + nextSubscriptionIdAvailable = subsId + 1 + } + + return nil +} + +// individualSubscriptionPut updates the information about a specific subscriptionInfo at /subscriptions/{subscriptionId} endpoint +func individualSubscriptionPut(w http.ResponseWriter, r *http.Request) { + log.Info("individualSubPut") + + w.Header().Set("Content-Type", "application/json; charset=UTF-8") + vars := mux.Vars(r) + subIdParamStr := vars["subscriptionId"] + + var subscriptionCommon SubscriptionCommon + // read JSON input stream provided in the Request, and stores it in the bodyBytes as bytes + bodyBytes, _ := ioutil.ReadAll(r.Body) + // Unmarshal function to converts a JSON-formatted string into a SubscriptionCommon struct and store it in extractSubType + err := json.Unmarshal(bodyBytes, &subscriptionCommon) + if err != nil { + log.Error(err.Error()) + errHandlerProblemDetails(w, err.Error(), http.StatusInternalServerError) + return + } + // extract common body part + subscriptionType := subscriptionCommon.SubscriptionType + + // validating common mandatory parameters provided in the request body + if subscriptionCommon.SubscriptionType == "" { + log.Error("Mandatory SubscriptionType parameter should be present") + errHandlerProblemDetails(w, "Mandatory attribute SubscriptionType is missing in the request body.", http.StatusBadRequest) + return + } + + if subscriptionCommon.CallbackReference == "" && subscriptionCommon.WebsockNotifConfig == nil { + log.Error("At least one of callbackReference and websockNotifConfig parameters should be present") + errHandlerProblemDetails(w, "Both callbackReference and websockNotifConfig parameters are missing in the request body.", http.StatusBadRequest) + return + } + + if subscriptionCommon.FilterCriteria == nil { + log.Error("Mandatory attribute FilterCriteria parameter should be present") + errHandlerProblemDetails(w, "Mandatory attribute FilterCriteria is missing in the request body.", http.StatusBadRequest) + return + } + + link := subscriptionCommon.Links + if link == nil || link.Self == nil { + log.Error("Mandatory _links parameter should be present") + errHandlerProblemDetails(w, "Mandatory attribute _links is missing in the request body.", http.StatusBadRequest) + return + } + + selfUrl := strings.Split(link.Self.Href, "/") + subsIdStr := selfUrl[len(selfUrl)-1] + + if subsIdStr != subIdParamStr { + log.Error("SubscriptionId in endpoint and in body not matching") + errHandlerProblemDetails(w, "SubscriptionId in endpoint and in body not matching", http.StatusBadRequest) + return + } + + alreadyRegistered := false + var jsonResponse []byte + + // switch statement is based on provided subscriptionType in the request body + switch subscriptionType { + // if subscription is of type V2xMsgSubscription + case V2X_MSG: + var v2xSubscription V2xMsgSubscription + err = json.Unmarshal(bodyBytes, &v2xSubscription) + if err != nil { + log.Error(err.Error()) + errHandlerProblemDetails(w, err.Error(), http.StatusInternalServerError) + return + } + + v2xMsgSubscription, _ := rc.JSONGetEntry(baseKey+"subscriptions:"+subIdParamStr, ".") + + // Validating mandatory parameters specific to V2xMsgSubscription in the request body + if v2xMsgSubscription == "" { + log.Error("subscription not found against the provided subscriptionId") + errHandlerProblemDetails(w, "subscription not found against the provided subscriptionId", http.StatusNotFound) + return + } + + if v2xSubscription.FilterCriteria.StdOrganization == "" { + log.Error("Mandatory StdOrganization parameter should be present") + errHandlerProblemDetails(w, "Mandatory attribute StdOrganization is missing in the request body.", http.StatusBadRequest) + return + } + + if v2xSubscription.WebsockNotifConfig != nil { + v2xSubscription.WebsockNotifConfig = subscriptionCommon.WebsockNotifConfig + } + + if v2xSubscription.CallbackReference != "" { + v2xSubscription.CallbackReference = subscriptionCommon.CallbackReference + } + + if !checkMsgTypeValue(v2xSubscription.FilterCriteria.MsgType) { + log.Error("MsgType parameter should be between 1 and 13") + errHandlerProblemDetails(w, "MsgType parameter should be between 1 and 13 in the request body.", http.StatusBadRequest) + return + } + + // registration + if isSubscriptionIdRegisteredV2x(subsIdStr) { + registerV2x(&v2xSubscription, subsIdStr) + // store subscription key in redis + _ = rc.JSONSetEntry(baseKey+"subscriptions:"+subsIdStr, ".", convertV2xMsgSubscriptionToJson(&v2xSubscription)) + alreadyRegistered = true + jsonResponse, err = json.Marshal(v2xSubscription) + } + + // if subscription is of type ProvChgUuUniSubscription + case PROV_CHG_UU_UNI: + //TODO + + default: + log.Error("Unsupported subscriptionType") + return + } + + if alreadyRegistered { + if err != nil { + log.Error(err.Error()) + errHandlerProblemDetails(w, err.Error(), http.StatusInternalServerError) + return + } + w.WriteHeader(http.StatusOK) + fmt.Fprint(w, string(jsonResponse)) + } else { + w.WriteHeader(http.StatusNotFound) + } +} + +// individualSubscriptionDelete is to delete a specific subscriptionInfo at subscriptions/{subscriptionId} endpoint +func individualSubscriptionDelete(w http.ResponseWriter, r *http.Request) { + log.Info("individualSubDel") + + w.Header().Set("Content-Type", "application/json; charset=UTF-8") + vars := mux.Vars(r) + subIdParamStr := vars["subscriptionId"] + + // Find subscriptionInfo entry in redis DB + _, err := rc.JSONGetEntry(baseKey+"subscriptions:"+subIdParamStr, ".") + if err != nil { + err = errors.New("subscription not found against the provided subscriptionId") + log.Error(err.Error()) + errHandlerProblemDetails(w, err.Error(), http.StatusNotFound) + return + } + + // Delete subscriptionInfo entry from redis DB + err = delSubscription(baseKey+"subscriptions", subIdParamStr, false) + if err != nil { + errHandlerProblemDetails(w, err.Error(), http.StatusInternalServerError) + return + } + + // Send response on successful deletion of subscription resource + w.WriteHeader(http.StatusNoContent) +} + +func provInfoUuUnicastGET(w http.ResponseWriter, r *http.Request) { + w.Header().Set("Content-Type", "application/json; charset=UTF-8") + + // Retrieve query parameters + u, _ := url.Parse(r.URL.String()) + log.Info("url: ", u.RequestURI()) + q := u.Query() + log.Info("infoUuUnicastGET: q= ", q) + validQueryParams := []string{"location_info"} + if !validateQueryParams(q, validQueryParams) { + w.WriteHeader(http.StatusBadRequest) + return + } + + // Get & validate query param values + location_info := q.Get("location_info") + log.Info("infoUuUnicastGET: location_info= ", location_info) + // Extract parameters + params := strings.Split(location_info, ",") + log.Info("infoUuUnicastGET: args= ", params) + + if !validateQueryParamValue(params[0], []string{"ecgi", "latitude"}) { + w.WriteHeader(http.StatusBadRequest) + return + } + // Extract list of items + var i int + for i = 1; i < len(params); i += 1 { + if validateQueryParamValue(params[i], []string{"longitude"}) { + break + } + } // End of 'for' statement + i -= 1 + log.Info("infoUuUnicastGET: i= ", i) + log.Info("infoUuUnicastGET: (len(params)-2)/2= ", (len(params)-2)/2) + if i < 1 || ((params[0] == "latitude") && (i != (len(params)-2)/2)) { + w.WriteHeader(http.StatusBadRequest) + return + } + + // Process the request + log.Info("infoUuUnicastGET: Process the request") + resp, err := sbi.GetInfoUuUnicast(params, i) + if err != nil { + log.Error(err.Error()) + errHandlerProblemDetails(w, err.Error(), http.StatusInternalServerError) + return + } + + // FIXME Add logic + proInfoUuUnicast := make([]UuUnicastProvisioningInfoProInfoUuUnicast, len(resp)) + for i := range resp { + if resp[i].LocationInfo != nil { + proInfoUuUnicast[i].LocationInfo = new(LocationInfo) + if resp[i].LocationInfo.Ecgi != nil { + proInfoUuUnicast[i].LocationInfo.Ecgi = new(Ecgi) + if resp[i].LocationInfo.Ecgi.CellId != nil { + proInfoUuUnicast[i].LocationInfo.Ecgi.CellId = new(CellId) + proInfoUuUnicast[i].LocationInfo.Ecgi.CellId.CellId = resp[i].LocationInfo.Ecgi.CellId.CellId + } + if resp[i].LocationInfo.Ecgi.Plmn != nil { + proInfoUuUnicast[i].LocationInfo.Ecgi.Plmn = new(Plmn) + proInfoUuUnicast[i].LocationInfo.Ecgi.Plmn.Mcc = resp[i].LocationInfo.Ecgi.Plmn.Mcc + proInfoUuUnicast[i].LocationInfo.Ecgi.Plmn.Mnc = resp[i].LocationInfo.Ecgi.Plmn.Mnc + } + } + if resp[i].LocationInfo.GeoArea != nil { + proInfoUuUnicast[i].LocationInfo.GeoArea = new(LocationInfoGeoArea) + proInfoUuUnicast[i].LocationInfo.GeoArea.Latitude = resp[i].LocationInfo.GeoArea.Latitude + proInfoUuUnicast[i].LocationInfo.GeoArea.Longitude = resp[i].LocationInfo.GeoArea.Longitude + } + } + + if resp[i].NeighbourCellInfo != nil { + proInfoUuUnicast[i].NeighbourCellInfo = make([]UuUniNeighbourCellInfo, len(resp[i].NeighbourCellInfo)) + for j := range resp[i].NeighbourCellInfo { + + if resp[i].NeighbourCellInfo[j].Ecgi != nil { + proInfoUuUnicast[i].NeighbourCellInfo[j].Ecgi = new(Ecgi) + if resp[i].NeighbourCellInfo[j].Ecgi.CellId != nil { + proInfoUuUnicast[i].NeighbourCellInfo[j].Ecgi.CellId = new(CellId) + proInfoUuUnicast[i].NeighbourCellInfo[j].Ecgi.CellId.CellId = resp[i].NeighbourCellInfo[j].Ecgi.CellId.CellId + } + if resp[i].NeighbourCellInfo[j].Ecgi.Plmn != nil { + proInfoUuUnicast[i].NeighbourCellInfo[j].Ecgi.Plmn = new(Plmn) + proInfoUuUnicast[i].NeighbourCellInfo[j].Ecgi.Plmn.Mcc = resp[i].NeighbourCellInfo[j].Ecgi.Plmn.Mcc + proInfoUuUnicast[i].NeighbourCellInfo[j].Ecgi.Plmn.Mnc = resp[i].NeighbourCellInfo[j].Ecgi.Plmn.Mnc + } + } + proInfoUuUnicast[i].NeighbourCellInfo[j].FddInfo = nil // FIXME Not supported yet + proInfoUuUnicast[i].NeighbourCellInfo[j].Pci = resp[i].NeighbourCellInfo[j].Pci + if resp[i].NeighbourCellInfo[j].Plmn != nil { + proInfoUuUnicast[i].NeighbourCellInfo[j].Plmn = new(Plmn) + proInfoUuUnicast[i].NeighbourCellInfo[j].Plmn.Mcc = resp[i].NeighbourCellInfo[j].Plmn.Mcc + proInfoUuUnicast[i].NeighbourCellInfo[j].Plmn.Mnc = resp[i].NeighbourCellInfo[j].Plmn.Mnc + } + proInfoUuUnicast[i].NeighbourCellInfo[j].TddInfo = nil // FIXME Not supported yet + } // End of 'for' statement + } + if resp[i].V2xApplicationServer != nil { + proInfoUuUnicast[i].V2xApplicationServer = new(V2xApplicationServer) + proInfoUuUnicast[i].V2xApplicationServer.IpAddress = resp[i].V2xApplicationServer.IpAddress + proInfoUuUnicast[i].V2xApplicationServer.UdpPort = resp[i].V2xApplicationServer.UdpPort + } + } // End of 'for' statement + uuUnicastProvisioningInfo := UuUnicastProvisioningInfo{ + ProInfoUuUnicast: proInfoUuUnicast, + TimeStamp: &TimeStamp{ + Seconds: int32(time.Now().Unix()), + }, + } + log.Info("infoUuUnicastGET: uuUnicastProvisioningInfo: ", uuUnicastProvisioningInfo) + + // Send response + jsonResponse, err := json.Marshal(uuUnicastProvisioningInfo) + if err != nil { + log.Error(err.Error()) + errHandlerProblemDetails(w, err.Error(), http.StatusInternalServerError) + return + } + log.Info("infoUuUnicastGET: Response: ", string(jsonResponse)) + w.WriteHeader(http.StatusOK) + fmt.Fprint(w, string(jsonResponse)) +} + +func checkMsgTypeValue(msgType []MsgType) bool { + for _, msgTypeInt := range msgType { + if msgTypeInt < DENM || msgTypeInt > RTCMEM { + return false + } + } // End of 'for' statement + return true +} + +func validateQueryParams(params url.Values, validParamList []string) bool { + for param := range params { + found := false + for _, validParam := range validParamList { + if param == validParam { + found = true + break + } + } + if !found { + log.Error("validateQueryParams: Invalid query param: ", param) + return false + } + } + return true +} + +func validateQueryParamValue(val string, validValues []string) bool { + for _, validVal := range validValues { + if val == validVal { + return true + } + } + log.Error("validateQueryParamValue: Invalid query param value: ", val) + return false +} + +func v2xNotify(v2xMessage []byte, v2xType int32, longitude *float32, latitude *float32) { + log.Info(">>> v2xNotify: ", v2xMessage) + + msgType := MsgType(v2xType) + v2xMsgNotification := V2xMsgNotification{ + Links: nil, + MsgContent: hex.EncodeToString(v2xMessage), + MsgEncodeFormat: "hexadump", + MsgType: &msgType, + NotificationType: "V2xMsgNotification", + StdOrganization: "v2x_msg", + TimeStamp: &TimeStamp{ + Seconds: int32(time.Now().Unix()), + }, + } + log.Info("v2xNotify: v2xMsgNotification: ", v2xMsgNotification) + + log.Info("v2xNotify: v2xMsgSubscriptionMap: ", v2xMsgSubscriptionMap) + for i, sub := range v2xMsgSubscriptionMap { + log.Info("v2xNotify: i: ", i) + log.Info("v2xNotify: sub", sub) + + if sub.FilterCriteria != nil && findMsgTypeId(sub.FilterCriteria.MsgType, msgType) { + if sub.Links != nil { + v2xMsgNotification.Links = &V2xMsgNotificationLinks{ + Subscription: sub.Links.Self, + } + } + notifyUrl := sub.CallbackReference + log.Info("v2xNotify: v2xMsgNotification: ", v2xMsgNotification) + log.Info("v2xNotify: notifyUrl: ", notifyUrl) + sendV2xMsgNotification(notifyUrl, v2xMsgNotification) + } + } +} + +func findMsgTypeId(list []MsgType, item MsgType) bool { + if len(list) == 0 { + return false + } + + for _, v := range list { + if v == item { + return true + } + } + + return false +} diff --git a/go-apps/meep-vis/server/vis_test.go b/go-apps/meep-vis/server/vis_test.go index 26d14a60e..aa573c021 100644 --- a/go-apps/meep-vis/server/vis_test.go +++ b/go-apps/meep-vis/server/vis_test.go @@ -25,6 +25,7 @@ import ( "net/http" "net/http/httptest" "os" + "strings" "testing" "time" @@ -219,7 +220,20 @@ const testScenario string = ` "poa4GConfig":{ "cellId":"2345678" }, - "physicalLocations":[ + "geoData": { + "location": { + "type": "Point", + "coordinates": [ + 7.423547, + 43.731724 + ] + }, + "radius": 400, + "path": null, + "eopMode": null, + "velocity": null + }, + "physicalLocations":[ { "id":"32a2ced4-a262-49a8-8503-8489a94386a2", "name":"ue1", @@ -314,8 +328,21 @@ const testScenario string = ` }, "poa4GConfig":{ "cellId":"3456789" - } - } + }, + "geoData": { + "location": { + "type": "Point", + "coordinates": [ + 7.423547, + 43.731724 + ] + }, + "radius": 400, + "path": null, + "eopMode": null, + "velocity": null + } + } ] }, { @@ -485,13 +512,17 @@ const testScenario string = ` } ] } -}` +} +` const redisTestAddr = "localhost:30380" const influxTestAddr = "http://localhost:30986" const postgisTestHost = "localhost" const postgisTestPort = "30432" const testScenarioName = "testScenario" +const v2xBrokerTest = "mqtt://test.mosquito.org:1338" // Or amqp://guest:guest@localhost:5672 + +var poaListTest = []string{"zone1-poa-cell1", "zone1-poa-cell2"} var m *mod.Model var mqLocal *mq.MsgQueue @@ -500,22 +531,22 @@ func TestNotImplemented(t *testing.T) { fmt.Println("--- ", t.Name()) log.MeepTextLogInit(t.Name()) - _, err := sendRequest(http.MethodDelete, "/subscriptions/1", nil, nil, nil, http.StatusNotImplemented, IndividualSubscriptionDELETE) - if err != nil { - t.Fatalf("Failed to get expected response") - } + // _, err := sendRequest(http.MethodDelete, "/subscriptions/1", nil, nil, nil, http.StatusNotImplemented, IndividualSubscriptionDELETE) + // if err != nil { + // t.Fatalf("Failed to get expected response") + // } - _, err = sendRequest(http.MethodGet, "/subscriptions/1", nil, nil, nil, http.StatusNotImplemented, IndividualSubscriptionGET) - if err != nil { - t.Fatalf("Failed to get expected response") - } + // _, err = sendRequest(http.MethodGet, "/subscriptions/1", nil, nil, nil, http.StatusNotImplemented, IndividualSubscriptionGET) + // if err != nil { + // t.Fatalf("Failed to get expected response") + // } - _, err = sendRequest(http.MethodPut, "/subscriptions/1", nil, nil, nil, http.StatusNotImplemented, IndividualSubscriptionPUT) - if err != nil { - t.Fatalf("Failed to get expected response") - } + // _, err = sendRequest(http.MethodPut, "/subscriptions/1", nil, nil, nil, http.StatusNotImplemented, IndividualSubscriptionPUT) + // if err != nil { + // t.Fatalf("Failed to get expected response") + // } - _, err = sendRequest(http.MethodGet, "/queries/pc5_provisioning_info", nil, nil, nil, http.StatusNotImplemented, ProvInfoGET) + _, err := sendRequest(http.MethodGet, "/queries/pc5_provisioning_info", nil, nil, nil, http.StatusNotImplemented, ProvInfoGET) if err != nil { t.Fatalf("Failed to get expected response") } @@ -525,26 +556,6 @@ func TestNotImplemented(t *testing.T) { t.Fatalf("Failed to get expected response") } - _, err = sendRequest(http.MethodGet, "/queries/uu_unicast_provisioning_info", nil, nil, nil, http.StatusNotImplemented, ProvInfoUuUnicastGET) - if err != nil { - t.Fatalf("Failed to get expected response") - } - - _, err = sendRequest(http.MethodGet, "/subscriptions", nil, nil, nil, http.StatusNotImplemented, SubGET) - if err != nil { - t.Fatalf("Failed to get expected response") - } - - _, err = sendRequest(http.MethodPost, "/subscriptions", nil, nil, nil, http.StatusNotImplemented, SubPOST) - if err != nil { - t.Fatalf("Failed to get expected response") - } - - _, err = sendRequest(http.MethodPost, "/publish_v2x_message", nil, nil, nil, http.StatusNotImplemented, V2xMessagePOST) - if err != nil { - t.Fatalf("Failed to get expected response") - } - } func TestPredictedQosPost(t *testing.T) { @@ -649,6 +660,622 @@ func TestPredictedQosPost(t *testing.T) { terminateScenario() } +func TestProvInfoUuUnicastGET(t *testing.T) { + fmt.Println("--- ", t.Name()) + log.MeepTextLogInit(t.Name()) + + initializeVars() + + err := Init() + if err != nil { + t.Fatalf("Error initializing test basic procedure") + } + err = Run() + if err != nil { + t.Fatalf("Error running test basic procedure") + } + + fmt.Println("Set a scenario") + initialiseScenario(testScenario) + + time.Sleep(1000 * time.Millisecond) + updateScenario("mobility1") + + /****************************** + * expected response section + ******************************/ + // Initialize the data structure for the GET request + // MEC-030 Clause 6.2.2 + // MEC-030 Clause 7.3.3 + + /****************************** + * expected request section + ******************************/ + + ecgi := Ecgi{ + CellId: &CellId{CellId: "cellid"}, + Plmn: &Plmn{Mcc: "mcc", Mnc: "mnc"}, + } + plmn := Plmn{Mcc: "mcc", Mnc: "mnc"} + uuUniNeighbourCellInfo := make([]UuUniNeighbourCellInfo, 1) + uuUniNeighbourCellInfo[0] = UuUniNeighbourCellInfo{&ecgi, nil, 0, &plmn, nil} + proInfoUuUnicast := make([]UuUnicastProvisioningInfoProInfoUuUnicast, 1) + proInfoUuUnicast[0] = UuUnicastProvisioningInfoProInfoUuUnicast{nil, uuUniNeighbourCellInfo, nil} + uuUnicastProvisioningInfo := UuUnicastProvisioningInfo{ + ProInfoUuUnicast: proInfoUuUnicast, + TimeStamp: &TimeStamp{ + Seconds: int32(time.Now().Unix()), + }, + } + + expected_json_response, err := json.Marshal(uuUnicastProvisioningInfo) + if err != nil { + t.Fatalf(err.Error()) + } + fmt.Println("expected_json_response: ", string(expected_json_response)) + + /****************************** + * request execution section + ******************************/ + rr, err := sendRequest(http.MethodGet, "/queries/uu_unicast_provisioning_info?location_info=ecgi,33139970001614,33139971112725", nil, nil, nil, http.StatusOK, ProvInfoUuUnicastGET) + if err != nil { + t.Fatalf(err.Error()) + } + log.Info("Respone: rr: ", rr) + var resp UuUnicastProvisioningInfo + err = json.Unmarshal([]byte(rr), &resp) + if err != nil { + t.Fatalf("Failed to get expected response") + } + log.Info("Respone: resp: ", resp) + if !validateUuUnicastProvisioningInfo(resp, uuUnicastProvisioningInfo) { + t.Errorf("handler returned unexpected body: got %v want %v", rr, expected_json_response) + } + + _, err = sendRequest(http.MethodGet, "/queries/uu_unicast_provisioning_info?location_info=ecgi", nil, nil, nil, http.StatusBadRequest, ProvInfoUuUnicastGET) + if err != nil { + t.Fatalf(err.Error()) + } + log.Info("sendRequest done") + + rr, err = sendRequest(http.MethodGet, "/queries/uu_unicast_provisioning_info?location_info=latitude,000.000,001.000,longitude,000.000,001.000", nil, nil, nil, http.StatusOK, ProvInfoUuUnicastGET) + if err != nil { + t.Fatalf(err.Error()) + } + log.Info("Respone: rr: ", rr) + err = json.Unmarshal([]byte(rr), &resp) + if err != nil { + t.Fatalf("Failed to get expected response") + } + log.Info("Respone: resp: ", resp) + // TODO Validate with expected response + + _, err = sendRequest(http.MethodGet, "/queries/uu_unicast_provisioning_info?location_info=latitude,000.000,001.000,longitude,000.000", nil, nil, nil, http.StatusBadRequest, ProvInfoUuUnicastGET) + if err != nil { + t.Fatalf(err.Error()) + } + log.Info("sendRequest done") + + _, err = sendRequest(http.MethodGet, "/queries/uu_unicast_provisioning_info?location_info=latitude,000.000,001.000", nil, nil, nil, http.StatusBadRequest, ProvInfoUuUnicastGET) + if err != nil { + t.Fatalf(err.Error()) + } + log.Info("sendRequest done") + + _, err = sendRequest(http.MethodGet, "/queries/uu_unicast_provisioning_info?location_info=longitude,000.000,001.000,latitude,000.000,001.000", nil, nil, nil, http.StatusBadRequest, ProvInfoUuUnicastGET) + if err != nil { + t.Fatalf(err.Error()) + } + log.Info("sendRequest done") + + /****************************** + * back to initial state section + ******************************/ + terminateScenario() +} + +func validateUuUnicastProvisioningInfo(received UuUnicastProvisioningInfo, expected UuUnicastProvisioningInfo) bool { + log.Info("validateUuUnicastProvisioningInfo: received: ", received) + log.Info("validateUuUnicastProvisioningInfo: expected: ", expected) + + log.Info("validateUuUnicastProvisioningInfo: received: ", len(received.ProInfoUuUnicast)) + log.Info("validateUuUnicastProvisioningInfo: expected: ", len(expected.ProInfoUuUnicast)) + if len(received.ProInfoUuUnicast) != len(expected.ProInfoUuUnicast) { + fmt.Println("len(received.ProInfoUuUnicast) mismatch") + return false + } + // TODO + + return true +} + +func testSubscriptionPost(t *testing.T) (string, string) { + + /****************************** + * expected response section + ******************************/ + // Initialize the data structure for the POST request + // MEC-030 Clause 6.3.5 + // MEC-030 Clause 7.8.3.4 + expected_subscriptionType := "V2xMsgSubscription" + expected_callbackReference := "MyCallback" + expected_href := LinkType{Href: "http://meAppServer.example.com/vis/v2/subscriptions/1"} + expected_self := Links{Self: &expected_href} + expected_msgType := []MsgType{DENM, CAM} + expected_filterCriteria := V2xMsgSubscriptionFilterCriteria{StdOrganization: "ETSI", MsgType: expected_msgType} + expected_expiryDeadline := TimeStamp{Seconds: 1977836800, NanoSeconds: 0} + expected_v2xMsgSubscription := V2xMsgSubscription{ + SubscriptionType: expected_subscriptionType, + CallbackReference: expected_callbackReference, + Links: &expected_self, + FilterCriteria: &expected_filterCriteria, + ExpiryDeadline: &expected_expiryDeadline, + RequestTestNotification: false, + WebsockNotifConfig: nil, + } + expectedResponseStr, err := json.Marshal(expected_v2xMsgSubscription) + if err != nil { + t.Fatalf(err.Error()) + } + fmt.Println("expected_v2xMsgSubscription_str: ", string(expectedResponseStr)) + + /****************************** + * request body section + ******************************/ + + subscriptionType := "V2xMsgSubscription" + callbackReference := "MyCallback" + msgType := []MsgType{DENM, CAM} + filterCriteria := V2xMsgSubscriptionFilterCriteria{StdOrganization: "ETSI", MsgType: msgType} + expiryDeadline := TimeStamp{Seconds: 1977836800, NanoSeconds: 0} + requestedV2xMsgSubscription := V2xMsgSubscription{ + SubscriptionType: subscriptionType, + CallbackReference: callbackReference, + FilterCriteria: &filterCriteria, + ExpiryDeadline: &expiryDeadline, + RequestTestNotification: false, + WebsockNotifConfig: nil, + } + body, err := json.Marshal(requestedV2xMsgSubscription) + if err != nil { + t.Fatalf(err.Error()) + } + fmt.Println("body: ", string(body)) + + /****************************** + * request execution section + ******************************/ + + rr, err := sendRequest(http.MethodPost, "/vis/v2/subscriptions", bytes.NewBuffer(body), nil, nil, http.StatusCreated, SubPOST) + if err != nil { + t.Fatalf(err.Error()) + } + log.Info("Request sent") + + var respBody V2xMsgSubscription + err = json.Unmarshal([]byte(rr), &respBody) + if err != nil { + t.Fatalf(err.Error()) + } + + /****************************** + * Comparing responses + ******************************/ + + if expected_v2xMsgSubscription.SubscriptionType != respBody.SubscriptionType { + t.Fatalf("Failed to get expected response") + } + if &expected_v2xMsgSubscription.FilterCriteria != &respBody.FilterCriteria { + t.Fatalf("Failed to get expected response") + } + if expected_v2xMsgSubscription.CallbackReference != respBody.CallbackReference { + t.Fatalf("Failed to get expected response") + } + if *expected_v2xMsgSubscription.ExpiryDeadline != *respBody.ExpiryDeadline { + t.Fatalf("Failed to get expected response") + } + if *expected_v2xMsgSubscription.Links != *respBody.Links { + t.Fatalf("Failed to get expected response") + } + if respBody.WebsockNotifConfig != nil { + t.Fatalf("Failed to get expected response") + } + if respBody.RequestTestNotification != false { + t.Fatalf("Failed to get expected response") + } + + subscriptionId := strings.Split(respBody.Links.Self.Href, "/") + cleanSubscriptionId := subscriptionId[len(subscriptionId)-1] + + return cleanSubscriptionId, string(expectedResponseStr) +} + +func TestSuccessV2XMsgSubscription(t *testing.T) { + fmt.Println("--- ", t.Name()) + log.MeepTextLogInit(t.Name()) + + initializeVars() + + err := Init() + if err != nil { + t.Fatalf("Error initializing test basic procedure") + } + err = Run() + if err != nil { + t.Fatalf("Error running test basic procedure") + } + + fmt.Println("Set a scenario") + initialiseScenario(testScenario) + + time.Sleep(1000 * time.Millisecond) + updateScenario("mobility1") + + // POST + subscriptionId, expectedGetResponse := testSubscriptionPost(t) + + //GET Subscriptions + subscriptionTypeQuery := "v2x_msg" + testSubscriptionsGet(t, subscriptionTypeQuery, expectedGetResponse) + + // GET Individual Subscription + testIndividualSubscriptionGet(t, subscriptionId, expectedGetResponse) + + // PUT + testIndividualSubscriptionPut(t, subscriptionId, true) + + // DELETE + testIndividualSubscriptionDelete(t, subscriptionId, true) + + /****************************** + * back to initial state section + ******************************/ + terminateScenario() + +} + +func TestFailV2XMsgSubscription(t *testing.T) { + fmt.Println("--- ", t.Name()) + log.MeepTextLogInit(t.Name()) + + initializeVars() + + err := Init() + if err != nil { + t.Fatalf("Error initializing test basic procedure") + } + err = Run() + if err != nil { + t.Fatalf("Error running test basic procedure") + } + + fmt.Println("Set a scenario") + initialiseScenario(testScenario) + + time.Sleep(1000 * time.Millisecond) + updateScenario("mobility1") + + // GET + testIndividualSubscriptionGet(t, "invalidSubscriptionId", "") + + // PUT + _ = testIndividualSubscriptionPut(t, "invalidSubscriptionId", false) + + // DELETE + testIndividualSubscriptionDelete(t, "invalidSubscriptionId", false) + + /****************************** + * back to initial state section + ******************************/ + + terminateScenario() +} + +//Generic GET function for any subscription type + +func testSubscriptionsGet(t *testing.T, subscriptionTypeQuery string, expectedResponse string) { + + /****************************** + * expected response section + ******************************/ + //passed as a parameter since a POST had to be sent first + + /****************************** + * request queries section + ******************************/ + + queryParam := make(map[string]string) + queryParam["subscription_type"] = subscriptionTypeQuery + + /****************************** + * request execution section + ******************************/ + + var err error + + if expectedResponse == "" { + _, err = sendRequest(http.MethodGet, "/vis/v2/subscriptions", nil, nil, queryParam, http.StatusNotFound, SubGET) + if err != nil { + t.Fatalf("Failed to get expected response") + } + } else { + rr, err := sendRequest(http.MethodGet, "/vis/v2/subscriptions", nil, nil, queryParam, http.StatusOK, SubGET) + if err != nil { + t.Fatalf("Failed to get expected response") + } + + if rr != expectedResponse { + t.Fatalf("Failed to get expected response") + } + log.Info("Received expected response for GET Subscription method") + } +} + +func testIndividualSubscriptionGet(t *testing.T, subscriptionId string, expectedResponse string) { + + /****************************** + * expected response section + ******************************/ + //passed as a parameter since a POST had to be sent first + + /****************************** + * request vars section + ******************************/ + vars := make(map[string]string) + vars["subscriptionId"] = subscriptionId + + /****************************** + * request execution section + ******************************/ + + var err error + if expectedResponse == "" { + _, err = sendRequest(http.MethodGet, "/vis/v2/subscriptions", nil, vars, nil, http.StatusNotFound, IndividualSubscriptionGET) + if err != nil { + t.Fatalf("Failed to get expected response") + } + } else { + var expectedResp V2xMsgSubscription + err := json.Unmarshal([]byte(expectedResponse), &expectedResp) + if err != nil { + t.Fatalf("Failed to get expected response") + } + + rr, err := sendRequest(http.MethodGet, "/vis/v2/subscriptions", nil, vars, nil, http.StatusOK, IndividualSubscriptionGET) + if err != nil { + t.Fatalf("Failed to get expected response") + } + var respBody V2xMsgSubscription + err = json.Unmarshal([]byte(rr), &respBody) + if err != nil { + t.Fatalf("Failed to get expected response") + } + + if expectedResp.SubscriptionType != respBody.SubscriptionType { + t.Fatalf("Failed to get expected response") + } + if &expectedResp.FilterCriteria != &respBody.FilterCriteria { + t.Fatalf("Failed to get expected response") + } + if expectedResp.CallbackReference != respBody.CallbackReference { + t.Fatalf("Failed to get expected response") + } + if *expectedResp.ExpiryDeadline != *respBody.ExpiryDeadline { + t.Fatalf("Failed to get expected response") + } + if *expectedResp.Links != *respBody.Links { + t.Fatalf("Failed to get expected response") + } + if respBody.WebsockNotifConfig != nil { + t.Fatalf("Failed to get expected response") + } + if respBody.RequestTestNotification != false { + t.Fatalf("Failed to get expected response") + } + } +} + +func testIndividualSubscriptionDelete(t *testing.T, subscriptionId string, expectSuccess bool) { + + /****************************** + * request vars section + ******************************/ + vars := make(map[string]string) + vars["subscriptionId"] = subscriptionId + + /****************************** + * request execution section + ******************************/ + + if expectSuccess { + _, err := sendRequest(http.MethodDelete, "/vis/v2/subscriptions", nil, vars, nil, http.StatusNoContent, IndividualSubscriptionDELETE) + if err != nil { + t.Fatalf("Failed to get expected response") + } + } else { + _, err := sendRequest(http.MethodDelete, "/vis/v2/subscriptions", nil, vars, nil, http.StatusNotFound, IndividualSubscriptionDELETE) + if err != nil { + t.Fatalf("Failed to get expected response") + } + } +} + +func testIndividualSubscriptionPut(t *testing.T, subscriptionId string, expectSuccess bool) string { + /****************************** + * expected response section + ******************************/ + + expected_subscriptionType := "V2xMsgSubscription" + expected_callbackReference := "MyCallback" + expected_href := LinkType{Href: "http://meAppServer.example.com/vis/v2/subscriptions/1"} + expected_self := Links{Self: &expected_href} + expected_msgType := []MsgType{DENM, CAM} + expected_filterCriteria := V2xMsgSubscriptionFilterCriteria{StdOrganization: "ETSI", MsgType: expected_msgType} + expected_expiryDeadline := TimeStamp{Seconds: 1977836800, NanoSeconds: 0} + + expected_v2xMsgSubscription := V2xMsgSubscription{ + SubscriptionType: expected_subscriptionType, + CallbackReference: expected_callbackReference, + Links: &expected_self, + FilterCriteria: &expected_filterCriteria, + ExpiryDeadline: &expected_expiryDeadline, + RequestTestNotification: false, + WebsockNotifConfig: nil, + } + expectedResponseStr, err := json.Marshal(expected_v2xMsgSubscription) + if err != nil { + t.Fatalf(err.Error()) + } + fmt.Println("expectedResponseStr: ", string(expectedResponseStr)) + + /****************************** + * request vars section + ******************************/ + vars := make(map[string]string) + vars["subscriptionId"] = subscriptionId + + /****************************** + * request body section + ******************************/ + + subscriptionType := "V2xMsgSubscription" + callbackReference := "MyCallback" + href := LinkType{Href: "http://meAppServer.example.com/vis/v2/subscriptions/1"} + self := Links{Self: &href} + msgType := []MsgType{DENM, CAM} + filterCriteria := V2xMsgSubscriptionFilterCriteria{StdOrganization: "ETSI", MsgType: msgType} + expiryDeadline := TimeStamp{Seconds: 1977836800, NanoSeconds: 0} + requestedv2xMsgSubscription := V2xMsgSubscription{ + SubscriptionType: subscriptionType, + CallbackReference: callbackReference, + Links: &self, + FilterCriteria: &filterCriteria, + ExpiryDeadline: &expiryDeadline, + RequestTestNotification: false, + WebsockNotifConfig: nil, + } + body, err := json.Marshal(requestedv2xMsgSubscription) + if err != nil { + t.Fatalf(err.Error()) + } + fmt.Println("body: ", string(body)) + + /****************************** + * request queries section + ******************************/ + + /****************************** + * request execution section + ******************************/ + if expectSuccess { + rr, err := sendRequest(http.MethodPut, "/vis/v2/subscriptions", bytes.NewBuffer(body), nil, nil, http.StatusOK, IndividualSubscriptionPUT) + if err != nil { + t.Fatalf("Failed to get expected response") + } + + var respBody V2xMsgSubscription + err = json.Unmarshal([]byte(rr), &respBody) + if err != nil { + t.Fatalf("Failed to get expected response") + } + + if expected_v2xMsgSubscription.SubscriptionType != respBody.SubscriptionType { + t.Fatalf("Failed to get expected response") + } + if &expected_v2xMsgSubscription.FilterCriteria != &respBody.FilterCriteria { + t.Fatalf("Failed to get expected response") + } + if expected_v2xMsgSubscription.CallbackReference != respBody.CallbackReference { + t.Fatalf("Failed to get expected response") + } + if *expected_v2xMsgSubscription.ExpiryDeadline != *respBody.ExpiryDeadline { + t.Fatalf("Failed to get expected response") + } + if *expected_v2xMsgSubscription.Links != *respBody.Links { + t.Fatalf("Failed to get expected response") + } + if respBody.WebsockNotifConfig != nil { + t.Fatalf("Failed to get expected response") + } + if respBody.RequestTestNotification != false { + t.Fatalf("Failed to get expected response") + } + + return string(expectedResponseStr) + } else { + _, err = sendRequest(http.MethodPost, "/vis/v2/subscriptions", bytes.NewBuffer(body), vars, nil, http.StatusNotFound, IndividualSubscriptionPUT) + if err != nil { + t.Fatalf("Failed to get expected response") + } + return "" + } +} + +func TestV2xMsgPublicationPost(t *testing.T) { + fmt.Println("--- ", t.Name()) + log.MeepTextLogInit(t.Name()) + + initializeVars() + + err := Init() + if err != nil { + t.Fatalf("Error initializing test basic procedure") + } + err = Run() + if err != nil { + t.Fatalf("Error running test basic procedure") + } + + fmt.Println("Set a scenario") + initialiseScenario(testScenario) + + time.Sleep(1000 * time.Millisecond) + updateScenario("mobility1") + + /****************************** + * expected response section + ******************************/ + // Initialize the data structure for the POST request + // MEC-030 Clause 6.2.6 + // MEC-030 Clause 7.7.3.4 + + /****************************** + * expected request section + ******************************/ + + stdOrganization := "ETSI" + msgEncodeFormat := "hexadump" + msgType := DENM + msgContent := "031200f101038100400380818c20400100005802001ee600003c0004e548140072066b24d01eb78149084d5571800000" + + testv2xMsgPublication := V2xMsgPublication{ + MsgContent: msgContent, + MsgEncodeFormat: msgEncodeFormat, + MsgType: &msgType, + StdOrganization: stdOrganization, + } + body, err := json.Marshal(testv2xMsgPublication) + if err != nil { + t.Fatalf(err.Error()) + } + fmt.Println("body: ", string(body)) + + /****************************** + * request execution section + ******************************/ + + _, err = sendRequest(http.MethodPost, "/vis/v2/publish_v2x_message", bytes.NewBuffer(body), nil, nil, http.StatusNoContent, V2xMessagePOST) + if err != nil { + t.Fatalf(err.Error()) + } + log.Info("sendRequest done") + + /****************************** + * back to initial state section + ******************************/ + terminateScenario() +} + func initializeVars() { mod.DbAddress = redisTestAddr redisAddr = redisTestAddr @@ -658,6 +1285,10 @@ func initializeVars() { postgisHost = postgisTestHost postgisPort = postgisTestPort os.Setenv("MEEP_SANDBOX_NAME", testScenarioName) + v2x_broker = v2xBrokerTest + os.Setenv("MEEP_BROKER", v2x_broker) + v2x_poa_list = poaListTest + os.Setenv("MEEP_POA_LIST", strings.Join(v2x_poa_list, ";")) } func initialiseScenario(testScenario string) { @@ -672,7 +1303,6 @@ func initialiseScenario(testScenario string) { UpdateCb: nil, DbAddr: redisAddr, } - var err error m, err = mod.NewModel(cfg) if err != nil { diff --git a/go-packages/meep-vis-client/README.md b/go-packages/meep-vis-client/README.md index c36261472..d0b56d956 100644 --- a/go-packages/meep-vis-client/README.md +++ b/go-packages/meep-vis-client/README.md @@ -21,18 +21,17 @@ All URIs are relative to *https://localhost/sandboxname/vis/v2* Class | Method | HTTP request | Description ------------ | ------------- | ------------- | ------------- -*UnsupportedApi* | [**IndividualSubscriptionDELETE**](docs/UnsupportedApi.md#individualsubscriptiondelete) | **Delete** /subscriptions/{subscriptionId} | Used to cancel the existing subscription. -*UnsupportedApi* | [**IndividualSubscriptionGET**](docs/UnsupportedApi.md#individualsubscriptionget) | **Get** /subscriptions/{subscriptionId} | Retrieve information about this subscription. -*UnsupportedApi* | [**IndividualSubscriptionPUT**](docs/UnsupportedApi.md#individualsubscriptionput) | **Put** /subscriptions/{subscriptionId} | Used to update the existing subscription. *UnsupportedApi* | [**ProvInfoGET**](docs/UnsupportedApi.md#provinfoget) | **Get** /queries/pc5_provisioning_info | Query provisioning information for V2X communication over PC5. *UnsupportedApi* | [**ProvInfoUuMbmsGET**](docs/UnsupportedApi.md#provinfouumbmsget) | **Get** /queries/uu_mbms_provisioning_info | retrieve information required for V2X communication over Uu MBMS. -*UnsupportedApi* | [**ProvInfoUuUnicastGET**](docs/UnsupportedApi.md#provinfouuunicastget) | **Get** /queries/uu_unicast_provisioning_info | Used to query provisioning information for V2X communication over Uu unicast. -*UnsupportedApi* | [**SubGET**](docs/UnsupportedApi.md#subget) | **Get** /subscriptions | Request information about the subscriptions for this requestor. -*UnsupportedApi* | [**SubPOST**](docs/UnsupportedApi.md#subpost) | **Post** /subscriptions | create a new subscription to VIS notifications. -*UnsupportedApi* | [**V2xMessagePOST**](docs/UnsupportedApi.md#v2xmessagepost) | **Post** /publish_v2x_message | Used to publish a V2X message. +*V2xiApi* | [**IndividualSubscriptionDELETE**](docs/V2xiApi.md#individualsubscriptiondelete) | **Delete** /subscriptions/{subscriptionId} | Used to cancel the existing subscription. +*V2xiApi* | [**IndividualSubscriptionGET**](docs/V2xiApi.md#individualsubscriptionget) | **Get** /subscriptions/{subscriptionId} | Retrieve information about this subscription. +*V2xiApi* | [**IndividualSubscriptionPUT**](docs/V2xiApi.md#individualsubscriptionput) | **Put** /subscriptions/{subscriptionId} | Used to update the existing subscription. *V2xiApi* | [**Mec011AppTerminationPOST**](docs/V2xiApi.md#mec011appterminationpost) | **Post** /notifications/mec011/appTermination | MEC011 Application Termination notification for self termination *V2xiApi* | [**PredictedQosPOST**](docs/V2xiApi.md#predictedqospost) | **Post** /provide_predicted_qos | Request the predicted QoS correspondent to potential routes of a vehicular UE. - +*V2xiApi* | [**ProvInfoUuUnicastGET**](docs/V2xiApi.md#provinfouuunicastget) | **Get** /queries/uu_unicast_provisioning_info | Used to query provisioning information for V2X communication over Uu unicast. +*V2xiApi* | [**SubGET**](docs/V2xiApi.md#subget) | **Get** /subscriptions | Request information about the subscriptions for this requestor. +*V2xiApi* | [**SubPOST**](docs/V2xiApi.md#subpost) | **Post** /subscriptions | create a new subscription to VIS notifications. +*V2xiApi* | [**V2xMessagePOST**](docs/V2xiApi.md#v2xmessagepost) | **Post** /publish_v2x_message | Used to publish a V2X message. ## Documentation For Models @@ -96,7 +95,6 @@ Class | Method | HTTP request | Description - [V2xServerUsdTmgi](docs/V2xServerUsdTmgi.md) - [WebsockNotifConfig](docs/WebsockNotifConfig.md) - ## Documentation For Authorization Endpoints do not require authorization. @@ -104,4 +102,6 @@ Class | Method | HTTP request | Description ## Author AdvantEDGE@InterDigital.com +xFlow Research (Pvt.) Inc. +FSCOM diff --git a/go-packages/meep-vis-client/api_unsupported.go b/go-packages/meep-vis-client/api_unsupported.go index 6b1fb6c43..8b7072cc3 100644 --- a/go-packages/meep-vis-client/api_unsupported.go +++ b/go-packages/meep-vis-client/api_unsupported.go @@ -26,13 +26,10 @@ package client import ( "context" - "fmt" "io/ioutil" "net/http" "net/url" "strings" - - "github.com/antihax/optional" ) // Linger please @@ -43,141 +40,29 @@ var ( type UnsupportedApiService service /* -UnsupportedApiService Used to cancel the existing subscription. -Used to cancel the existing subscription. - - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - - @param subscriptionId Refers to created subscription, where the VIS API allocates a unique resource name for this subscription -*/ -func (a *UnsupportedApiService) IndividualSubscriptionDELETE(ctx context.Context, subscriptionId string) (*http.Response, error) { - var ( - localVarHttpMethod = strings.ToUpper("Delete") - localVarPostBody interface{} - localVarFileName string - localVarFileBytes []byte - ) - - // create path and map variables - localVarPath := a.client.cfg.BasePath + "/subscriptions/{subscriptionId}" - localVarPath = strings.Replace(localVarPath, "{"+"subscriptionId"+"}", fmt.Sprintf("%v", subscriptionId), -1) - - localVarHeaderParams := make(map[string]string) - localVarQueryParams := url.Values{} - localVarFormParams := url.Values{} - - // to determine the Content-Type header - localVarHttpContentTypes := []string{} - - // set Content-Type header - localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes) - if localVarHttpContentType != "" { - localVarHeaderParams["Content-Type"] = localVarHttpContentType - } - - // to determine the Accept header - localVarHttpHeaderAccepts := []string{"application/json"} - - // set Accept header - localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts) - if localVarHttpHeaderAccept != "" { - localVarHeaderParams["Accept"] = localVarHttpHeaderAccept - } - r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes) - if err != nil { - return nil, err - } - - localVarHttpResponse, err := a.client.callAPI(r) - if err != nil || localVarHttpResponse == nil { - return localVarHttpResponse, err - } - - localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body) - localVarHttpResponse.Body.Close() - if err != nil { - return localVarHttpResponse, err - } - - if localVarHttpResponse.StatusCode >= 300 { - newErr := GenericSwaggerError{ - body: localVarBody, - error: localVarHttpResponse.Status, - } - - if localVarHttpResponse.StatusCode == 401 { - var v ProblemDetails - err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarHttpResponse, newErr - } - newErr.model = v - return localVarHttpResponse, newErr - } - - if localVarHttpResponse.StatusCode == 403 { - var v ProblemDetails - err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarHttpResponse, newErr - } - newErr.model = v - return localVarHttpResponse, newErr - } - - if localVarHttpResponse.StatusCode == 404 { - var v ProblemDetails - err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarHttpResponse, newErr - } - newErr.model = v - return localVarHttpResponse, newErr - } - - if localVarHttpResponse.StatusCode == 429 { - var v ProblemDetails - err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarHttpResponse, newErr - } - newErr.model = v - return localVarHttpResponse, newErr - } - - return localVarHttpResponse, newErr - } - - return localVarHttpResponse, nil -} - -/* -UnsupportedApiService Retrieve information about this subscription. -Retrieve information about this subscription. - - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - - @param subscriptionId Refers to created subscription, where the VIS API allocates a unique resource name for this subscription - -@return SubscriptionsBody +UnsupportedApiService Query provisioning information for V2X communication over PC5. +Query provisioning information for V2X communication over PC5. + * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + * @param locationInfo Comma separated list of locations to identify a cell of a base station or a particular geographical area +@return Pc5ProvisioningInfo */ -func (a *UnsupportedApiService) IndividualSubscriptionGET(ctx context.Context, subscriptionId string) (SubscriptionsBody, *http.Response, error) { +func (a *UnsupportedApiService) ProvInfoGET(ctx context.Context, locationInfo string) (Pc5ProvisioningInfo, *http.Response, error) { var ( localVarHttpMethod = strings.ToUpper("Get") localVarPostBody interface{} localVarFileName string localVarFileBytes []byte - localVarReturnValue SubscriptionsBody + localVarReturnValue Pc5ProvisioningInfo ) // create path and map variables - localVarPath := a.client.cfg.BasePath + "/subscriptions/{subscriptionId}" - localVarPath = strings.Replace(localVarPath, "{"+"subscriptionId"+"}", fmt.Sprintf("%v", subscriptionId), -1) + localVarPath := a.client.cfg.BasePath + "/queries/pc5_provisioning_info" localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} localVarFormParams := url.Values{} + localVarQueryParams.Add("location_info", parameterToString(locationInfo, "")) // to determine the Content-Type header localVarHttpContentTypes := []string{} @@ -224,9 +109,8 @@ func (a *UnsupportedApiService) IndividualSubscriptionGET(ctx context.Context, s body: localVarBody, error: localVarHttpResponse.Status, } - if localVarHttpResponse.StatusCode == 200 { - var v SubscriptionsBody + var v Pc5ProvisioningInfo err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) if err != nil { newErr.error = err.Error() @@ -235,7 +119,6 @@ func (a *UnsupportedApiService) IndividualSubscriptionGET(ctx context.Context, s newErr.model = v return localVarReturnValue, localVarHttpResponse, newErr } - if localVarHttpResponse.StatusCode == 400 { var v ProblemDetails err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) @@ -246,7 +129,6 @@ func (a *UnsupportedApiService) IndividualSubscriptionGET(ctx context.Context, s newErr.model = v return localVarReturnValue, localVarHttpResponse, newErr } - if localVarHttpResponse.StatusCode == 401 { var v ProblemDetails err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) @@ -257,7 +139,6 @@ func (a *UnsupportedApiService) IndividualSubscriptionGET(ctx context.Context, s newErr.model = v return localVarReturnValue, localVarHttpResponse, newErr } - if localVarHttpResponse.StatusCode == 403 { var v ProblemDetails err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) @@ -268,7 +149,6 @@ func (a *UnsupportedApiService) IndividualSubscriptionGET(ctx context.Context, s newErr.model = v return localVarReturnValue, localVarHttpResponse, newErr } - if localVarHttpResponse.StatusCode == 404 { var v ProblemDetails err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) @@ -279,7 +159,6 @@ func (a *UnsupportedApiService) IndividualSubscriptionGET(ctx context.Context, s newErr.model = v return localVarReturnValue, localVarHttpResponse, newErr } - if localVarHttpResponse.StatusCode == 406 { var v ProblemDetails err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) @@ -290,7 +169,6 @@ func (a *UnsupportedApiService) IndividualSubscriptionGET(ctx context.Context, s newErr.model = v return localVarReturnValue, localVarHttpResponse, newErr } - if localVarHttpResponse.StatusCode == 429 { var v ProblemDetails err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) @@ -301,7 +179,6 @@ func (a *UnsupportedApiService) IndividualSubscriptionGET(ctx context.Context, s newErr.model = v return localVarReturnValue, localVarHttpResponse, newErr } - return localVarReturnValue, localVarHttpResponse, newErr } @@ -309,33 +186,31 @@ func (a *UnsupportedApiService) IndividualSubscriptionGET(ctx context.Context, s } /* -UnsupportedApiService Used to update the existing subscription. -Used to update the existing subscription. - - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - - @param body - - @param subscriptionId Refers to created subscription, where the VIS API allocates a unique resource name for this subscription - -@return SubscriptionsSubscriptionIdBody +UnsupportedApiService retrieve information required for V2X communication over Uu MBMS. +retrieve information required for V2X communication over Uu MBMS. + * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + * @param locationInfo omma separated list of locations to identify a cell of a base station or a particular geographical area +@return UuMbmsProvisioningInfo */ -func (a *UnsupportedApiService) IndividualSubscriptionPUT(ctx context.Context, body SubscriptionsSubscriptionIdBody, subscriptionId string) (SubscriptionsSubscriptionIdBody, *http.Response, error) { +func (a *UnsupportedApiService) ProvInfoUuMbmsGET(ctx context.Context, locationInfo string) (UuMbmsProvisioningInfo, *http.Response, error) { var ( - localVarHttpMethod = strings.ToUpper("Put") + localVarHttpMethod = strings.ToUpper("Get") localVarPostBody interface{} localVarFileName string localVarFileBytes []byte - localVarReturnValue SubscriptionsSubscriptionIdBody + localVarReturnValue UuMbmsProvisioningInfo ) // create path and map variables - localVarPath := a.client.cfg.BasePath + "/subscriptions/{subscriptionId}" - localVarPath = strings.Replace(localVarPath, "{"+"subscriptionId"+"}", fmt.Sprintf("%v", subscriptionId), -1) + localVarPath := a.client.cfg.BasePath + "/queries/uu_mbms_provisioning_info" localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} localVarFormParams := url.Values{} + localVarQueryParams.Add("location_info", parameterToString(locationInfo, "")) // to determine the Content-Type header - localVarHttpContentTypes := []string{"application/json"} + localVarHttpContentTypes := []string{} // set Content-Type header localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes) @@ -351,8 +226,6 @@ func (a *UnsupportedApiService) IndividualSubscriptionPUT(ctx context.Context, b if localVarHttpHeaderAccept != "" { localVarHeaderParams["Accept"] = localVarHttpHeaderAccept } - // body params - localVarPostBody = &body r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes) if err != nil { return localVarReturnValue, nil, err @@ -382,9 +255,8 @@ func (a *UnsupportedApiService) IndividualSubscriptionPUT(ctx context.Context, b body: localVarBody, error: localVarHttpResponse.Status, } - if localVarHttpResponse.StatusCode == 200 { - var v SubscriptionsSubscriptionIdBody + var v UuMbmsProvisioningInfo err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) if err != nil { newErr.error = err.Error() @@ -393,7 +265,6 @@ func (a *UnsupportedApiService) IndividualSubscriptionPUT(ctx context.Context, b newErr.model = v return localVarReturnValue, localVarHttpResponse, newErr } - if localVarHttpResponse.StatusCode == 400 { var v ProblemDetails err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) @@ -404,7 +275,6 @@ func (a *UnsupportedApiService) IndividualSubscriptionPUT(ctx context.Context, b newErr.model = v return localVarReturnValue, localVarHttpResponse, newErr } - if localVarHttpResponse.StatusCode == 401 { var v ProblemDetails err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) @@ -415,7 +285,6 @@ func (a *UnsupportedApiService) IndividualSubscriptionPUT(ctx context.Context, b newErr.model = v return localVarReturnValue, localVarHttpResponse, newErr } - if localVarHttpResponse.StatusCode == 403 { var v ProblemDetails err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) @@ -426,7 +295,6 @@ func (a *UnsupportedApiService) IndividualSubscriptionPUT(ctx context.Context, b newErr.model = v return localVarReturnValue, localVarHttpResponse, newErr } - if localVarHttpResponse.StatusCode == 404 { var v ProblemDetails err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) @@ -437,7 +305,6 @@ func (a *UnsupportedApiService) IndividualSubscriptionPUT(ctx context.Context, b newErr.model = v return localVarReturnValue, localVarHttpResponse, newErr } - if localVarHttpResponse.StatusCode == 406 { var v ProblemDetails err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) @@ -448,29 +315,6 @@ func (a *UnsupportedApiService) IndividualSubscriptionPUT(ctx context.Context, b newErr.model = v return localVarReturnValue, localVarHttpResponse, newErr } - - if localVarHttpResponse.StatusCode == 412 { - var v ProblemDetails - err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHttpResponse, newErr - } - newErr.model = v - return localVarReturnValue, localVarHttpResponse, newErr - } - - if localVarHttpResponse.StatusCode == 422 { - var v ProblemDetails - err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHttpResponse, newErr - } - newErr.model = v - return localVarReturnValue, localVarHttpResponse, newErr - } - if localVarHttpResponse.StatusCode == 429 { var v ProblemDetails err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) @@ -481,950 +325,8 @@ func (a *UnsupportedApiService) IndividualSubscriptionPUT(ctx context.Context, b newErr.model = v return localVarReturnValue, localVarHttpResponse, newErr } - return localVarReturnValue, localVarHttpResponse, newErr } return localVarReturnValue, localVarHttpResponse, nil } - -/* -UnsupportedApiService Query provisioning information for V2X communication over PC5. -Query provisioning information for V2X communication over PC5. - - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - - @param locationInfo Comma separated list of locations to identify a cell of a base station or a particular geographical area - -@return Pc5ProvisioningInfo -*/ -func (a *UnsupportedApiService) ProvInfoGET(ctx context.Context, locationInfo string) (Pc5ProvisioningInfo, *http.Response, error) { - var ( - localVarHttpMethod = strings.ToUpper("Get") - localVarPostBody interface{} - localVarFileName string - localVarFileBytes []byte - localVarReturnValue Pc5ProvisioningInfo - ) - - // create path and map variables - localVarPath := a.client.cfg.BasePath + "/queries/pc5_provisioning_info" - - localVarHeaderParams := make(map[string]string) - localVarQueryParams := url.Values{} - localVarFormParams := url.Values{} - - localVarQueryParams.Add("location_info", parameterToString(locationInfo, "")) - // to determine the Content-Type header - localVarHttpContentTypes := []string{} - - // set Content-Type header - localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes) - if localVarHttpContentType != "" { - localVarHeaderParams["Content-Type"] = localVarHttpContentType - } - - // to determine the Accept header - localVarHttpHeaderAccepts := []string{"application/json"} - - // set Accept header - localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts) - if localVarHttpHeaderAccept != "" { - localVarHeaderParams["Accept"] = localVarHttpHeaderAccept - } - r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes) - if err != nil { - return localVarReturnValue, nil, err - } - - localVarHttpResponse, err := a.client.callAPI(r) - if err != nil || localVarHttpResponse == nil { - return localVarReturnValue, localVarHttpResponse, err - } - - localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body) - localVarHttpResponse.Body.Close() - if err != nil { - return localVarReturnValue, localVarHttpResponse, err - } - - if localVarHttpResponse.StatusCode < 300 { - // If we succeed, return the data, otherwise pass on to decode error. - err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) - if err == nil { - return localVarReturnValue, localVarHttpResponse, err - } - } - - if localVarHttpResponse.StatusCode >= 300 { - newErr := GenericSwaggerError{ - body: localVarBody, - error: localVarHttpResponse.Status, - } - - if localVarHttpResponse.StatusCode == 200 { - var v Pc5ProvisioningInfo - err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHttpResponse, newErr - } - newErr.model = v - return localVarReturnValue, localVarHttpResponse, newErr - } - - if localVarHttpResponse.StatusCode == 400 { - var v ProblemDetails - err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHttpResponse, newErr - } - newErr.model = v - return localVarReturnValue, localVarHttpResponse, newErr - } - - if localVarHttpResponse.StatusCode == 401 { - var v ProblemDetails - err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHttpResponse, newErr - } - newErr.model = v - return localVarReturnValue, localVarHttpResponse, newErr - } - - if localVarHttpResponse.StatusCode == 403 { - var v ProblemDetails - err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHttpResponse, newErr - } - newErr.model = v - return localVarReturnValue, localVarHttpResponse, newErr - } - - if localVarHttpResponse.StatusCode == 404 { - var v ProblemDetails - err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHttpResponse, newErr - } - newErr.model = v - return localVarReturnValue, localVarHttpResponse, newErr - } - - if localVarHttpResponse.StatusCode == 406 { - var v ProblemDetails - err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHttpResponse, newErr - } - newErr.model = v - return localVarReturnValue, localVarHttpResponse, newErr - } - - if localVarHttpResponse.StatusCode == 429 { - var v ProblemDetails - err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHttpResponse, newErr - } - newErr.model = v - return localVarReturnValue, localVarHttpResponse, newErr - } - - return localVarReturnValue, localVarHttpResponse, newErr - } - - return localVarReturnValue, localVarHttpResponse, nil -} - -/* -UnsupportedApiService retrieve information required for V2X communication over Uu MBMS. -retrieve information required for V2X communication over Uu MBMS. - - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - - @param locationInfo omma separated list of locations to identify a cell of a base station or a particular geographical area - -@return UuMbmsProvisioningInfo -*/ -func (a *UnsupportedApiService) ProvInfoUuMbmsGET(ctx context.Context, locationInfo string) (UuMbmsProvisioningInfo, *http.Response, error) { - var ( - localVarHttpMethod = strings.ToUpper("Get") - localVarPostBody interface{} - localVarFileName string - localVarFileBytes []byte - localVarReturnValue UuMbmsProvisioningInfo - ) - - // create path and map variables - localVarPath := a.client.cfg.BasePath + "/queries/uu_mbms_provisioning_info" - - localVarHeaderParams := make(map[string]string) - localVarQueryParams := url.Values{} - localVarFormParams := url.Values{} - - localVarQueryParams.Add("location_info", parameterToString(locationInfo, "")) - // to determine the Content-Type header - localVarHttpContentTypes := []string{} - - // set Content-Type header - localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes) - if localVarHttpContentType != "" { - localVarHeaderParams["Content-Type"] = localVarHttpContentType - } - - // to determine the Accept header - localVarHttpHeaderAccepts := []string{"application/json"} - - // set Accept header - localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts) - if localVarHttpHeaderAccept != "" { - localVarHeaderParams["Accept"] = localVarHttpHeaderAccept - } - r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes) - if err != nil { - return localVarReturnValue, nil, err - } - - localVarHttpResponse, err := a.client.callAPI(r) - if err != nil || localVarHttpResponse == nil { - return localVarReturnValue, localVarHttpResponse, err - } - - localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body) - localVarHttpResponse.Body.Close() - if err != nil { - return localVarReturnValue, localVarHttpResponse, err - } - - if localVarHttpResponse.StatusCode < 300 { - // If we succeed, return the data, otherwise pass on to decode error. - err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) - if err == nil { - return localVarReturnValue, localVarHttpResponse, err - } - } - - if localVarHttpResponse.StatusCode >= 300 { - newErr := GenericSwaggerError{ - body: localVarBody, - error: localVarHttpResponse.Status, - } - - if localVarHttpResponse.StatusCode == 200 { - var v UuMbmsProvisioningInfo - err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHttpResponse, newErr - } - newErr.model = v - return localVarReturnValue, localVarHttpResponse, newErr - } - - if localVarHttpResponse.StatusCode == 400 { - var v ProblemDetails - err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHttpResponse, newErr - } - newErr.model = v - return localVarReturnValue, localVarHttpResponse, newErr - } - - if localVarHttpResponse.StatusCode == 401 { - var v ProblemDetails - err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHttpResponse, newErr - } - newErr.model = v - return localVarReturnValue, localVarHttpResponse, newErr - } - - if localVarHttpResponse.StatusCode == 403 { - var v ProblemDetails - err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHttpResponse, newErr - } - newErr.model = v - return localVarReturnValue, localVarHttpResponse, newErr - } - - if localVarHttpResponse.StatusCode == 404 { - var v ProblemDetails - err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHttpResponse, newErr - } - newErr.model = v - return localVarReturnValue, localVarHttpResponse, newErr - } - - if localVarHttpResponse.StatusCode == 406 { - var v ProblemDetails - err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHttpResponse, newErr - } - newErr.model = v - return localVarReturnValue, localVarHttpResponse, newErr - } - - if localVarHttpResponse.StatusCode == 429 { - var v ProblemDetails - err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHttpResponse, newErr - } - newErr.model = v - return localVarReturnValue, localVarHttpResponse, newErr - } - - return localVarReturnValue, localVarHttpResponse, newErr - } - - return localVarReturnValue, localVarHttpResponse, nil -} - -/* -UnsupportedApiService Used to query provisioning information for V2X communication over Uu unicast. -Used to query provisioning information for V2X communication over Uu unicast. - - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - - @param locationInfo Comma separated list of locations to identify a cell of a base station or a particular geographical area - -@return UuUnicastProvisioningInfo -*/ -func (a *UnsupportedApiService) ProvInfoUuUnicastGET(ctx context.Context, locationInfo string) (UuUnicastProvisioningInfo, *http.Response, error) { - var ( - localVarHttpMethod = strings.ToUpper("Get") - localVarPostBody interface{} - localVarFileName string - localVarFileBytes []byte - localVarReturnValue UuUnicastProvisioningInfo - ) - - // create path and map variables - localVarPath := a.client.cfg.BasePath + "/queries/uu_unicast_provisioning_info" - - localVarHeaderParams := make(map[string]string) - localVarQueryParams := url.Values{} - localVarFormParams := url.Values{} - - localVarQueryParams.Add("location_info", parameterToString(locationInfo, "")) - // to determine the Content-Type header - localVarHttpContentTypes := []string{} - - // set Content-Type header - localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes) - if localVarHttpContentType != "" { - localVarHeaderParams["Content-Type"] = localVarHttpContentType - } - - // to determine the Accept header - localVarHttpHeaderAccepts := []string{"application/json"} - - // set Accept header - localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts) - if localVarHttpHeaderAccept != "" { - localVarHeaderParams["Accept"] = localVarHttpHeaderAccept - } - r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes) - if err != nil { - return localVarReturnValue, nil, err - } - - localVarHttpResponse, err := a.client.callAPI(r) - if err != nil || localVarHttpResponse == nil { - return localVarReturnValue, localVarHttpResponse, err - } - - localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body) - localVarHttpResponse.Body.Close() - if err != nil { - return localVarReturnValue, localVarHttpResponse, err - } - - if localVarHttpResponse.StatusCode < 300 { - // If we succeed, return the data, otherwise pass on to decode error. - err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) - if err == nil { - return localVarReturnValue, localVarHttpResponse, err - } - } - - if localVarHttpResponse.StatusCode >= 300 { - newErr := GenericSwaggerError{ - body: localVarBody, - error: localVarHttpResponse.Status, - } - - if localVarHttpResponse.StatusCode == 200 { - var v UuUnicastProvisioningInfo - err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHttpResponse, newErr - } - newErr.model = v - return localVarReturnValue, localVarHttpResponse, newErr - } - - if localVarHttpResponse.StatusCode == 400 { - var v ProblemDetails - err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHttpResponse, newErr - } - newErr.model = v - return localVarReturnValue, localVarHttpResponse, newErr - } - - if localVarHttpResponse.StatusCode == 401 { - var v ProblemDetails - err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHttpResponse, newErr - } - newErr.model = v - return localVarReturnValue, localVarHttpResponse, newErr - } - - if localVarHttpResponse.StatusCode == 403 { - var v ProblemDetails - err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHttpResponse, newErr - } - newErr.model = v - return localVarReturnValue, localVarHttpResponse, newErr - } - - if localVarHttpResponse.StatusCode == 404 { - var v ProblemDetails - err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHttpResponse, newErr - } - newErr.model = v - return localVarReturnValue, localVarHttpResponse, newErr - } - - if localVarHttpResponse.StatusCode == 406 { - var v ProblemDetails - err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHttpResponse, newErr - } - newErr.model = v - return localVarReturnValue, localVarHttpResponse, newErr - } - - if localVarHttpResponse.StatusCode == 429 { - var v ProblemDetails - err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHttpResponse, newErr - } - newErr.model = v - return localVarReturnValue, localVarHttpResponse, newErr - } - - return localVarReturnValue, localVarHttpResponse, newErr - } - - return localVarReturnValue, localVarHttpResponse, nil -} - -/* -UnsupportedApiService Request information about the subscriptions for this requestor. -Request information about the subscriptions for this requestor. - * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - * @param optional nil or *SubGETOpts - Optional Parameters: - * @param "SubscriptionType" (optional.String) - Query parameter to filter on a specific subscription type. Permitted values: prov_chg_uu_uni: provisioning information change for V2X communication over Uuunicast prov_chg_uu_mbms: provisioning information change for V2X communication over Uu MBMS prov_chg_uu_pc5: provisioning information change for V2X communication over PC5. v2x_msg: V2X interoperability message - -@return SubscriptionLinkList -*/ - -type SubGETOpts struct { - SubscriptionType optional.String -} - -func (a *UnsupportedApiService) SubGET(ctx context.Context, localVarOptionals *SubGETOpts) (SubscriptionLinkList, *http.Response, error) { - var ( - localVarHttpMethod = strings.ToUpper("Get") - localVarPostBody interface{} - localVarFileName string - localVarFileBytes []byte - localVarReturnValue SubscriptionLinkList - ) - - // create path and map variables - localVarPath := a.client.cfg.BasePath + "/subscriptions" - - localVarHeaderParams := make(map[string]string) - localVarQueryParams := url.Values{} - localVarFormParams := url.Values{} - - if localVarOptionals != nil && localVarOptionals.SubscriptionType.IsSet() { - localVarQueryParams.Add("subscription_type", parameterToString(localVarOptionals.SubscriptionType.Value(), "")) - } - // to determine the Content-Type header - localVarHttpContentTypes := []string{} - - // set Content-Type header - localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes) - if localVarHttpContentType != "" { - localVarHeaderParams["Content-Type"] = localVarHttpContentType - } - - // to determine the Accept header - localVarHttpHeaderAccepts := []string{"application/json"} - - // set Accept header - localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts) - if localVarHttpHeaderAccept != "" { - localVarHeaderParams["Accept"] = localVarHttpHeaderAccept - } - r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes) - if err != nil { - return localVarReturnValue, nil, err - } - - localVarHttpResponse, err := a.client.callAPI(r) - if err != nil || localVarHttpResponse == nil { - return localVarReturnValue, localVarHttpResponse, err - } - - localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body) - localVarHttpResponse.Body.Close() - if err != nil { - return localVarReturnValue, localVarHttpResponse, err - } - - if localVarHttpResponse.StatusCode < 300 { - // If we succeed, return the data, otherwise pass on to decode error. - err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) - if err == nil { - return localVarReturnValue, localVarHttpResponse, err - } - } - - if localVarHttpResponse.StatusCode >= 300 { - newErr := GenericSwaggerError{ - body: localVarBody, - error: localVarHttpResponse.Status, - } - - if localVarHttpResponse.StatusCode == 200 { - var v SubscriptionLinkList - err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHttpResponse, newErr - } - newErr.model = v - return localVarReturnValue, localVarHttpResponse, newErr - } - - if localVarHttpResponse.StatusCode == 400 { - var v ProblemDetails - err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHttpResponse, newErr - } - newErr.model = v - return localVarReturnValue, localVarHttpResponse, newErr - } - - if localVarHttpResponse.StatusCode == 401 { - var v ProblemDetails - err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHttpResponse, newErr - } - newErr.model = v - return localVarReturnValue, localVarHttpResponse, newErr - } - - if localVarHttpResponse.StatusCode == 403 { - var v ProblemDetails - err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHttpResponse, newErr - } - newErr.model = v - return localVarReturnValue, localVarHttpResponse, newErr - } - - if localVarHttpResponse.StatusCode == 404 { - var v ProblemDetails - err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHttpResponse, newErr - } - newErr.model = v - return localVarReturnValue, localVarHttpResponse, newErr - } - - if localVarHttpResponse.StatusCode == 406 { - var v ProblemDetails - err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHttpResponse, newErr - } - newErr.model = v - return localVarReturnValue, localVarHttpResponse, newErr - } - - if localVarHttpResponse.StatusCode == 429 { - var v ProblemDetails - err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHttpResponse, newErr - } - newErr.model = v - return localVarReturnValue, localVarHttpResponse, newErr - } - - return localVarReturnValue, localVarHttpResponse, newErr - } - - return localVarReturnValue, localVarHttpResponse, nil -} - -/* -UnsupportedApiService create a new subscription to VIS notifications. - - create a new subscription to VIS notifications. - * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - * @param body - -@return SubscriptionsBody -*/ -func (a *UnsupportedApiService) SubPOST(ctx context.Context, body SubscriptionsBody) (SubscriptionsBody, *http.Response, error) { - var ( - localVarHttpMethod = strings.ToUpper("Post") - localVarPostBody interface{} - localVarFileName string - localVarFileBytes []byte - localVarReturnValue SubscriptionsBody - ) - - // create path and map variables - localVarPath := a.client.cfg.BasePath + "/subscriptions" - - localVarHeaderParams := make(map[string]string) - localVarQueryParams := url.Values{} - localVarFormParams := url.Values{} - - // to determine the Content-Type header - localVarHttpContentTypes := []string{"application/json"} - - // set Content-Type header - localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes) - if localVarHttpContentType != "" { - localVarHeaderParams["Content-Type"] = localVarHttpContentType - } - - // to determine the Accept header - localVarHttpHeaderAccepts := []string{"application/json"} - - // set Accept header - localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts) - if localVarHttpHeaderAccept != "" { - localVarHeaderParams["Accept"] = localVarHttpHeaderAccept - } - // body params - localVarPostBody = &body - r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes) - if err != nil { - return localVarReturnValue, nil, err - } - - localVarHttpResponse, err := a.client.callAPI(r) - if err != nil || localVarHttpResponse == nil { - return localVarReturnValue, localVarHttpResponse, err - } - - localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body) - localVarHttpResponse.Body.Close() - if err != nil { - return localVarReturnValue, localVarHttpResponse, err - } - - if localVarHttpResponse.StatusCode < 300 { - // If we succeed, return the data, otherwise pass on to decode error. - err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) - if err == nil { - return localVarReturnValue, localVarHttpResponse, err - } - } - - if localVarHttpResponse.StatusCode >= 300 { - newErr := GenericSwaggerError{ - body: localVarBody, - error: localVarHttpResponse.Status, - } - - if localVarHttpResponse.StatusCode == 201 { - var v SubscriptionsBody - err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHttpResponse, newErr - } - newErr.model = v - return localVarReturnValue, localVarHttpResponse, newErr - } - - if localVarHttpResponse.StatusCode == 400 { - var v ProblemDetails - err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHttpResponse, newErr - } - newErr.model = v - return localVarReturnValue, localVarHttpResponse, newErr - } - - if localVarHttpResponse.StatusCode == 401 { - var v ProblemDetails - err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHttpResponse, newErr - } - newErr.model = v - return localVarReturnValue, localVarHttpResponse, newErr - } - - if localVarHttpResponse.StatusCode == 403 { - var v ProblemDetails - err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHttpResponse, newErr - } - newErr.model = v - return localVarReturnValue, localVarHttpResponse, newErr - } - - if localVarHttpResponse.StatusCode == 404 { - var v ProblemDetails - err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHttpResponse, newErr - } - newErr.model = v - return localVarReturnValue, localVarHttpResponse, newErr - } - - if localVarHttpResponse.StatusCode == 406 { - var v ProblemDetails - err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHttpResponse, newErr - } - newErr.model = v - return localVarReturnValue, localVarHttpResponse, newErr - } - - if localVarHttpResponse.StatusCode == 415 { - var v ProblemDetails - err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHttpResponse, newErr - } - newErr.model = v - return localVarReturnValue, localVarHttpResponse, newErr - } - - if localVarHttpResponse.StatusCode == 422 { - var v ProblemDetails - err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHttpResponse, newErr - } - newErr.model = v - return localVarReturnValue, localVarHttpResponse, newErr - } - - if localVarHttpResponse.StatusCode == 429 { - var v ProblemDetails - err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarReturnValue, localVarHttpResponse, newErr - } - newErr.model = v - return localVarReturnValue, localVarHttpResponse, newErr - } - - return localVarReturnValue, localVarHttpResponse, newErr - } - - return localVarReturnValue, localVarHttpResponse, nil -} - -/* -UnsupportedApiService Used to publish a V2X message. -Used to publish a V2X message. - - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - - @param body -*/ -func (a *UnsupportedApiService) V2xMessagePOST(ctx context.Context, body V2xMsgPublication) (*http.Response, error) { - var ( - localVarHttpMethod = strings.ToUpper("Post") - localVarPostBody interface{} - localVarFileName string - localVarFileBytes []byte - ) - - // create path and map variables - localVarPath := a.client.cfg.BasePath + "/publish_v2x_message" - - localVarHeaderParams := make(map[string]string) - localVarQueryParams := url.Values{} - localVarFormParams := url.Values{} - - // to determine the Content-Type header - localVarHttpContentTypes := []string{"application/json"} - - // set Content-Type header - localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes) - if localVarHttpContentType != "" { - localVarHeaderParams["Content-Type"] = localVarHttpContentType - } - - // to determine the Accept header - localVarHttpHeaderAccepts := []string{"application/json"} - - // set Accept header - localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts) - if localVarHttpHeaderAccept != "" { - localVarHeaderParams["Accept"] = localVarHttpHeaderAccept - } - // body params - localVarPostBody = &body - r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes) - if err != nil { - return nil, err - } - - localVarHttpResponse, err := a.client.callAPI(r) - if err != nil || localVarHttpResponse == nil { - return localVarHttpResponse, err - } - - localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body) - localVarHttpResponse.Body.Close() - if err != nil { - return localVarHttpResponse, err - } - - if localVarHttpResponse.StatusCode >= 300 { - newErr := GenericSwaggerError{ - body: localVarBody, - error: localVarHttpResponse.Status, - } - - if localVarHttpResponse.StatusCode == 400 { - var v ProblemDetails - err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarHttpResponse, newErr - } - newErr.model = v - return localVarHttpResponse, newErr - } - - if localVarHttpResponse.StatusCode == 401 { - var v ProblemDetails - err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarHttpResponse, newErr - } - newErr.model = v - return localVarHttpResponse, newErr - } - - if localVarHttpResponse.StatusCode == 403 { - var v ProblemDetails - err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarHttpResponse, newErr - } - newErr.model = v - return localVarHttpResponse, newErr - } - - if localVarHttpResponse.StatusCode == 404 { - var v ProblemDetails - err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarHttpResponse, newErr - } - newErr.model = v - return localVarHttpResponse, newErr - } - - if localVarHttpResponse.StatusCode == 406 { - var v ProblemDetails - err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarHttpResponse, newErr - } - newErr.model = v - return localVarHttpResponse, newErr - } - - if localVarHttpResponse.StatusCode == 429 { - var v ProblemDetails - err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) - if err != nil { - newErr.error = err.Error() - return localVarHttpResponse, newErr - } - newErr.model = v - return localVarHttpResponse, newErr - } - - return localVarHttpResponse, newErr - } - - return localVarHttpResponse, nil -} diff --git a/go-packages/meep-vis-client/api_v2xi.go b/go-packages/meep-vis-client/api_v2xi.go index 12cda6487..f37f37cea 100644 --- a/go-packages/meep-vis-client/api_v2xi.go +++ b/go-packages/meep-vis-client/api_v2xi.go @@ -26,10 +26,13 @@ package client import ( "context" + "fmt" "io/ioutil" "net/http" "net/url" "strings" + + "github.com/antihax/optional" ) // Linger please @@ -40,28 +43,30 @@ var ( type V2xiApiService service /* -V2xiApiService MEC011 Application Termination notification for self termination -Terminates itself. - - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - - @param body Termination notification details +V2xiApiService Used to cancel the existing subscription. +Used to cancel the existing subscription. + * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + * @param subscriptionId Refers to created subscription, where the VIS API allocates a unique resource name for this subscription + */ -func (a *V2xiApiService) Mec011AppTerminationPOST(ctx context.Context, body AppTerminationNotification) (*http.Response, error) { +func (a *V2xiApiService) IndividualSubscriptionDELETE(ctx context.Context, subscriptionId string) (*http.Response, error) { var ( - localVarHttpMethod = strings.ToUpper("Post") + localVarHttpMethod = strings.ToUpper("Delete") localVarPostBody interface{} localVarFileName string localVarFileBytes []byte ) // create path and map variables - localVarPath := a.client.cfg.BasePath + "/notifications/mec011/appTermination" + localVarPath := a.client.cfg.BasePath + "/subscriptions/{subscriptionId}" + localVarPath = strings.Replace(localVarPath, "{"+"subscriptionId"+"}", fmt.Sprintf("%v", subscriptionId), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} localVarFormParams := url.Values{} // to determine the Content-Type header - localVarHttpContentTypes := []string{"application/json"} + localVarHttpContentTypes := []string{} // set Content-Type header localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes) @@ -70,15 +75,13 @@ func (a *V2xiApiService) Mec011AppTerminationPOST(ctx context.Context, body AppT } // to determine the Accept header - localVarHttpHeaderAccepts := []string{} + localVarHttpHeaderAccepts := []string{"application/json"} // set Accept header localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts) if localVarHttpHeaderAccept != "" { localVarHeaderParams["Accept"] = localVarHttpHeaderAccept } - // body params - localVarPostBody = &body r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes) if err != nil { return nil, err @@ -100,7 +103,46 @@ func (a *V2xiApiService) Mec011AppTerminationPOST(ctx context.Context, body AppT body: localVarBody, error: localVarHttpResponse.Status, } - + if localVarHttpResponse.StatusCode == 401 { + var v ProblemDetails + err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarHttpResponse, newErr + } + newErr.model = v + return localVarHttpResponse, newErr + } + if localVarHttpResponse.StatusCode == 403 { + var v ProblemDetails + err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarHttpResponse, newErr + } + newErr.model = v + return localVarHttpResponse, newErr + } + if localVarHttpResponse.StatusCode == 404 { + var v ProblemDetails + err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarHttpResponse, newErr + } + newErr.model = v + return localVarHttpResponse, newErr + } + if localVarHttpResponse.StatusCode == 429 { + var v ProblemDetails + err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarHttpResponse, newErr + } + newErr.model = v + return localVarHttpResponse, newErr + } return localVarHttpResponse, newErr } @@ -108,24 +150,171 @@ func (a *V2xiApiService) Mec011AppTerminationPOST(ctx context.Context, body AppT } /* -V2xiApiService Request the predicted QoS correspondent to potential routes of a vehicular UE. -Request the predicted QoS correspondent to potential routes of a vehicular UE. - - @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). - - @param body +V2xiApiService Retrieve information about this subscription. +Retrieve information about this subscription. + * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + * @param subscriptionId Refers to created subscription, where the VIS API allocates a unique resource name for this subscription +@return SubscriptionsBody +*/ +func (a *V2xiApiService) IndividualSubscriptionGET(ctx context.Context, subscriptionId string) (SubscriptionsBody, *http.Response, error) { + var ( + localVarHttpMethod = strings.ToUpper("Get") + localVarPostBody interface{} + localVarFileName string + localVarFileBytes []byte + localVarReturnValue SubscriptionsBody + ) -@return PredictedQos + // create path and map variables + localVarPath := a.client.cfg.BasePath + "/subscriptions/{subscriptionId}" + localVarPath = strings.Replace(localVarPath, "{"+"subscriptionId"+"}", fmt.Sprintf("%v", subscriptionId), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + // to determine the Content-Type header + localVarHttpContentTypes := []string{} + + // set Content-Type header + localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes) + if localVarHttpContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHttpContentType + } + + // to determine the Accept header + localVarHttpHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts) + if localVarHttpHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHttpHeaderAccept + } + r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHttpResponse, err := a.client.callAPI(r) + if err != nil || localVarHttpResponse == nil { + return localVarReturnValue, localVarHttpResponse, err + } + + localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body) + localVarHttpResponse.Body.Close() + if err != nil { + return localVarReturnValue, localVarHttpResponse, err + } + + if localVarHttpResponse.StatusCode < 300 { + // If we succeed, return the data, otherwise pass on to decode error. + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err == nil { + return localVarReturnValue, localVarHttpResponse, err + } + } + + if localVarHttpResponse.StatusCode >= 300 { + newErr := GenericSwaggerError{ + body: localVarBody, + error: localVarHttpResponse.Status, + } + if localVarHttpResponse.StatusCode == 200 { + var v SubscriptionsBody + err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHttpResponse, newErr + } + newErr.model = v + return localVarReturnValue, localVarHttpResponse, newErr + } + if localVarHttpResponse.StatusCode == 400 { + var v ProblemDetails + err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHttpResponse, newErr + } + newErr.model = v + return localVarReturnValue, localVarHttpResponse, newErr + } + if localVarHttpResponse.StatusCode == 401 { + var v ProblemDetails + err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHttpResponse, newErr + } + newErr.model = v + return localVarReturnValue, localVarHttpResponse, newErr + } + if localVarHttpResponse.StatusCode == 403 { + var v ProblemDetails + err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHttpResponse, newErr + } + newErr.model = v + return localVarReturnValue, localVarHttpResponse, newErr + } + if localVarHttpResponse.StatusCode == 404 { + var v ProblemDetails + err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHttpResponse, newErr + } + newErr.model = v + return localVarReturnValue, localVarHttpResponse, newErr + } + if localVarHttpResponse.StatusCode == 406 { + var v ProblemDetails + err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHttpResponse, newErr + } + newErr.model = v + return localVarReturnValue, localVarHttpResponse, newErr + } + if localVarHttpResponse.StatusCode == 429 { + var v ProblemDetails + err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHttpResponse, newErr + } + newErr.model = v + return localVarReturnValue, localVarHttpResponse, newErr + } + return localVarReturnValue, localVarHttpResponse, newErr + } + + return localVarReturnValue, localVarHttpResponse, nil +} + +/* +V2xiApiService Used to update the existing subscription. +Used to update the existing subscription. + * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + * @param body + * @param subscriptionId Refers to created subscription, where the VIS API allocates a unique resource name for this subscription +@return SubscriptionsSubscriptionIdBody */ -func (a *V2xiApiService) PredictedQosPOST(ctx context.Context, body PredictedQos) (PredictedQos, *http.Response, error) { +func (a *V2xiApiService) IndividualSubscriptionPUT(ctx context.Context, body SubscriptionsSubscriptionIdBody, subscriptionId string) (SubscriptionsSubscriptionIdBody, *http.Response, error) { var ( - localVarHttpMethod = strings.ToUpper("Post") + localVarHttpMethod = strings.ToUpper("Put") localVarPostBody interface{} localVarFileName string localVarFileBytes []byte - localVarReturnValue PredictedQos + localVarReturnValue SubscriptionsSubscriptionIdBody ) // create path and map variables - localVarPath := a.client.cfg.BasePath + "/provide_predicted_qos" + localVarPath := a.client.cfg.BasePath + "/subscriptions/{subscriptionId}" + localVarPath = strings.Replace(localVarPath, "{"+"subscriptionId"+"}", fmt.Sprintf("%v", subscriptionId), -1) localVarHeaderParams := make(map[string]string) localVarQueryParams := url.Values{} @@ -179,9 +368,8 @@ func (a *V2xiApiService) PredictedQosPOST(ctx context.Context, body PredictedQos body: localVarBody, error: localVarHttpResponse.Status, } - if localVarHttpResponse.StatusCode == 200 { - var v PredictedQos + var v SubscriptionsSubscriptionIdBody err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) if err != nil { newErr.error = err.Error() @@ -190,7 +378,6 @@ func (a *V2xiApiService) PredictedQosPOST(ctx context.Context, body PredictedQos newErr.model = v return localVarReturnValue, localVarHttpResponse, newErr } - if localVarHttpResponse.StatusCode == 400 { var v ProblemDetails err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) @@ -201,7 +388,6 @@ func (a *V2xiApiService) PredictedQosPOST(ctx context.Context, body PredictedQos newErr.model = v return localVarReturnValue, localVarHttpResponse, newErr } - if localVarHttpResponse.StatusCode == 401 { var v ProblemDetails err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) @@ -212,7 +398,6 @@ func (a *V2xiApiService) PredictedQosPOST(ctx context.Context, body PredictedQos newErr.model = v return localVarReturnValue, localVarHttpResponse, newErr } - if localVarHttpResponse.StatusCode == 403 { var v ProblemDetails err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) @@ -223,7 +408,6 @@ func (a *V2xiApiService) PredictedQosPOST(ctx context.Context, body PredictedQos newErr.model = v return localVarReturnValue, localVarHttpResponse, newErr } - if localVarHttpResponse.StatusCode == 404 { var v ProblemDetails err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) @@ -234,9 +418,838 @@ func (a *V2xiApiService) PredictedQosPOST(ctx context.Context, body PredictedQos newErr.model = v return localVarReturnValue, localVarHttpResponse, newErr } - + if localVarHttpResponse.StatusCode == 406 { + var v ProblemDetails + err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHttpResponse, newErr + } + newErr.model = v + return localVarReturnValue, localVarHttpResponse, newErr + } + if localVarHttpResponse.StatusCode == 412 { + var v ProblemDetails + err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHttpResponse, newErr + } + newErr.model = v + return localVarReturnValue, localVarHttpResponse, newErr + } + if localVarHttpResponse.StatusCode == 422 { + var v ProblemDetails + err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHttpResponse, newErr + } + newErr.model = v + return localVarReturnValue, localVarHttpResponse, newErr + } + if localVarHttpResponse.StatusCode == 429 { + var v ProblemDetails + err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHttpResponse, newErr + } + newErr.model = v + return localVarReturnValue, localVarHttpResponse, newErr + } return localVarReturnValue, localVarHttpResponse, newErr } return localVarReturnValue, localVarHttpResponse, nil } + +/* +V2xiApiService MEC011 Application Termination notification for self termination +Terminates itself. + * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + * @param body Termination notification details + +*/ +func (a *V2xiApiService) Mec011AppTerminationPOST(ctx context.Context, body AppTerminationNotification) (*http.Response, error) { + var ( + localVarHttpMethod = strings.ToUpper("Post") + localVarPostBody interface{} + localVarFileName string + localVarFileBytes []byte + ) + + // create path and map variables + localVarPath := a.client.cfg.BasePath + "/notifications/mec011/appTermination" + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + // to determine the Content-Type header + localVarHttpContentTypes := []string{"application/json"} + + // set Content-Type header + localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes) + if localVarHttpContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHttpContentType + } + + // to determine the Accept header + localVarHttpHeaderAccepts := []string{} + + // set Accept header + localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts) + if localVarHttpHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHttpHeaderAccept + } + // body params + localVarPostBody = &body + r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes) + if err != nil { + return nil, err + } + + localVarHttpResponse, err := a.client.callAPI(r) + if err != nil || localVarHttpResponse == nil { + return localVarHttpResponse, err + } + + localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body) + localVarHttpResponse.Body.Close() + if err != nil { + return localVarHttpResponse, err + } + + if localVarHttpResponse.StatusCode >= 300 { + newErr := GenericSwaggerError{ + body: localVarBody, + error: localVarHttpResponse.Status, + } + return localVarHttpResponse, newErr + } + + return localVarHttpResponse, nil +} + +/* +V2xiApiService Request the predicted QoS correspondent to potential routes of a vehicular UE. +Request the predicted QoS correspondent to potential routes of a vehicular UE. + * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + * @param body +@return PredictedQos +*/ +func (a *V2xiApiService) PredictedQosPOST(ctx context.Context, body PredictedQos) (PredictedQos, *http.Response, error) { + var ( + localVarHttpMethod = strings.ToUpper("Post") + localVarPostBody interface{} + localVarFileName string + localVarFileBytes []byte + localVarReturnValue PredictedQos + ) + + // create path and map variables + localVarPath := a.client.cfg.BasePath + "/provide_predicted_qos" + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + // to determine the Content-Type header + localVarHttpContentTypes := []string{"application/json"} + + // set Content-Type header + localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes) + if localVarHttpContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHttpContentType + } + + // to determine the Accept header + localVarHttpHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts) + if localVarHttpHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHttpHeaderAccept + } + // body params + localVarPostBody = &body + r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHttpResponse, err := a.client.callAPI(r) + if err != nil || localVarHttpResponse == nil { + return localVarReturnValue, localVarHttpResponse, err + } + + localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body) + localVarHttpResponse.Body.Close() + if err != nil { + return localVarReturnValue, localVarHttpResponse, err + } + + if localVarHttpResponse.StatusCode < 300 { + // If we succeed, return the data, otherwise pass on to decode error. + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err == nil { + return localVarReturnValue, localVarHttpResponse, err + } + } + + if localVarHttpResponse.StatusCode >= 300 { + newErr := GenericSwaggerError{ + body: localVarBody, + error: localVarHttpResponse.Status, + } + if localVarHttpResponse.StatusCode == 200 { + var v PredictedQos + err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHttpResponse, newErr + } + newErr.model = v + return localVarReturnValue, localVarHttpResponse, newErr + } + if localVarHttpResponse.StatusCode == 400 { + var v ProblemDetails + err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHttpResponse, newErr + } + newErr.model = v + return localVarReturnValue, localVarHttpResponse, newErr + } + if localVarHttpResponse.StatusCode == 401 { + var v ProblemDetails + err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHttpResponse, newErr + } + newErr.model = v + return localVarReturnValue, localVarHttpResponse, newErr + } + if localVarHttpResponse.StatusCode == 403 { + var v ProblemDetails + err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHttpResponse, newErr + } + newErr.model = v + return localVarReturnValue, localVarHttpResponse, newErr + } + if localVarHttpResponse.StatusCode == 404 { + var v ProblemDetails + err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHttpResponse, newErr + } + newErr.model = v + return localVarReturnValue, localVarHttpResponse, newErr + } + return localVarReturnValue, localVarHttpResponse, newErr + } + + return localVarReturnValue, localVarHttpResponse, nil +} + +/* +V2xiApiService Used to query provisioning information for V2X communication over Uu unicast. +Used to query provisioning information for V2X communication over Uu unicast. + * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + * @param locationInfo Comma separated list of locations to identify a cell of a base station or a particular geographical area +@return UuUnicastProvisioningInfo +*/ +func (a *V2xiApiService) ProvInfoUuUnicastGET(ctx context.Context, locationInfo string) (UuUnicastProvisioningInfo, *http.Response, error) { + var ( + localVarHttpMethod = strings.ToUpper("Get") + localVarPostBody interface{} + localVarFileName string + localVarFileBytes []byte + localVarReturnValue UuUnicastProvisioningInfo + ) + + // create path and map variables + localVarPath := a.client.cfg.BasePath + "/queries/uu_unicast_provisioning_info" + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + localVarQueryParams.Add("location_info", parameterToString(locationInfo, "")) + // to determine the Content-Type header + localVarHttpContentTypes := []string{} + + // set Content-Type header + localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes) + if localVarHttpContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHttpContentType + } + + // to determine the Accept header + localVarHttpHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts) + if localVarHttpHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHttpHeaderAccept + } + r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHttpResponse, err := a.client.callAPI(r) + if err != nil || localVarHttpResponse == nil { + return localVarReturnValue, localVarHttpResponse, err + } + + localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body) + localVarHttpResponse.Body.Close() + if err != nil { + return localVarReturnValue, localVarHttpResponse, err + } + + if localVarHttpResponse.StatusCode < 300 { + // If we succeed, return the data, otherwise pass on to decode error. + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err == nil { + return localVarReturnValue, localVarHttpResponse, err + } + } + + if localVarHttpResponse.StatusCode >= 300 { + newErr := GenericSwaggerError{ + body: localVarBody, + error: localVarHttpResponse.Status, + } + if localVarHttpResponse.StatusCode == 200 { + var v UuUnicastProvisioningInfo + err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHttpResponse, newErr + } + newErr.model = v + return localVarReturnValue, localVarHttpResponse, newErr + } + if localVarHttpResponse.StatusCode == 400 { + var v ProblemDetails + err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHttpResponse, newErr + } + newErr.model = v + return localVarReturnValue, localVarHttpResponse, newErr + } + if localVarHttpResponse.StatusCode == 401 { + var v ProblemDetails + err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHttpResponse, newErr + } + newErr.model = v + return localVarReturnValue, localVarHttpResponse, newErr + } + if localVarHttpResponse.StatusCode == 403 { + var v ProblemDetails + err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHttpResponse, newErr + } + newErr.model = v + return localVarReturnValue, localVarHttpResponse, newErr + } + if localVarHttpResponse.StatusCode == 404 { + var v ProblemDetails + err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHttpResponse, newErr + } + newErr.model = v + return localVarReturnValue, localVarHttpResponse, newErr + } + if localVarHttpResponse.StatusCode == 406 { + var v ProblemDetails + err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHttpResponse, newErr + } + newErr.model = v + return localVarReturnValue, localVarHttpResponse, newErr + } + if localVarHttpResponse.StatusCode == 429 { + var v ProblemDetails + err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHttpResponse, newErr + } + newErr.model = v + return localVarReturnValue, localVarHttpResponse, newErr + } + return localVarReturnValue, localVarHttpResponse, newErr + } + + return localVarReturnValue, localVarHttpResponse, nil +} + +/* +V2xiApiService Request information about the subscriptions for this requestor. +Request information about the subscriptions for this requestor. + * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + * @param optional nil or *V2xiApiSubGETOpts - Optional Parameters: + * @param "SubscriptionType" (optional.String) - Query parameter to filter on a specific subscription type. Permitted values: prov_chg_uu_uni: provisioning information change for V2X communication over Uuunicast prov_chg_uu_mbms: provisioning information change for V2X communication over Uu MBMS prov_chg_uu_pc5: provisioning information change for V2X communication over PC5. v2x_msg: V2X interoperability message +@return SubscriptionLinkList +*/ + +type V2xiApiSubGETOpts struct { + SubscriptionType optional.String +} + +func (a *V2xiApiService) SubGET(ctx context.Context, localVarOptionals *V2xiApiSubGETOpts) (SubscriptionLinkList, *http.Response, error) { + var ( + localVarHttpMethod = strings.ToUpper("Get") + localVarPostBody interface{} + localVarFileName string + localVarFileBytes []byte + localVarReturnValue SubscriptionLinkList + ) + + // create path and map variables + localVarPath := a.client.cfg.BasePath + "/subscriptions" + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + if localVarOptionals != nil && localVarOptionals.SubscriptionType.IsSet() { + localVarQueryParams.Add("subscription_type", parameterToString(localVarOptionals.SubscriptionType.Value(), "")) + } + // to determine the Content-Type header + localVarHttpContentTypes := []string{} + + // set Content-Type header + localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes) + if localVarHttpContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHttpContentType + } + + // to determine the Accept header + localVarHttpHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts) + if localVarHttpHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHttpHeaderAccept + } + r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHttpResponse, err := a.client.callAPI(r) + if err != nil || localVarHttpResponse == nil { + return localVarReturnValue, localVarHttpResponse, err + } + + localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body) + localVarHttpResponse.Body.Close() + if err != nil { + return localVarReturnValue, localVarHttpResponse, err + } + + if localVarHttpResponse.StatusCode < 300 { + // If we succeed, return the data, otherwise pass on to decode error. + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err == nil { + return localVarReturnValue, localVarHttpResponse, err + } + } + + if localVarHttpResponse.StatusCode >= 300 { + newErr := GenericSwaggerError{ + body: localVarBody, + error: localVarHttpResponse.Status, + } + if localVarHttpResponse.StatusCode == 200 { + var v SubscriptionLinkList + err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHttpResponse, newErr + } + newErr.model = v + return localVarReturnValue, localVarHttpResponse, newErr + } + if localVarHttpResponse.StatusCode == 400 { + var v ProblemDetails + err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHttpResponse, newErr + } + newErr.model = v + return localVarReturnValue, localVarHttpResponse, newErr + } + if localVarHttpResponse.StatusCode == 401 { + var v ProblemDetails + err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHttpResponse, newErr + } + newErr.model = v + return localVarReturnValue, localVarHttpResponse, newErr + } + if localVarHttpResponse.StatusCode == 403 { + var v ProblemDetails + err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHttpResponse, newErr + } + newErr.model = v + return localVarReturnValue, localVarHttpResponse, newErr + } + if localVarHttpResponse.StatusCode == 404 { + var v ProblemDetails + err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHttpResponse, newErr + } + newErr.model = v + return localVarReturnValue, localVarHttpResponse, newErr + } + if localVarHttpResponse.StatusCode == 406 { + var v ProblemDetails + err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHttpResponse, newErr + } + newErr.model = v + return localVarReturnValue, localVarHttpResponse, newErr + } + if localVarHttpResponse.StatusCode == 429 { + var v ProblemDetails + err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHttpResponse, newErr + } + newErr.model = v + return localVarReturnValue, localVarHttpResponse, newErr + } + return localVarReturnValue, localVarHttpResponse, newErr + } + + return localVarReturnValue, localVarHttpResponse, nil +} + +/* +V2xiApiService create a new subscription to VIS notifications. +create a new subscription to VIS notifications. + * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + * @param body +@return SubscriptionsBody +*/ +func (a *V2xiApiService) SubPOST(ctx context.Context, body SubscriptionsBody) (SubscriptionsBody, *http.Response, error) { + var ( + localVarHttpMethod = strings.ToUpper("Post") + localVarPostBody interface{} + localVarFileName string + localVarFileBytes []byte + localVarReturnValue SubscriptionsBody + ) + + // create path and map variables + localVarPath := a.client.cfg.BasePath + "/subscriptions" + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + // to determine the Content-Type header + localVarHttpContentTypes := []string{"application/json"} + + // set Content-Type header + localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes) + if localVarHttpContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHttpContentType + } + + // to determine the Accept header + localVarHttpHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts) + if localVarHttpHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHttpHeaderAccept + } + // body params + localVarPostBody = &body + r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHttpResponse, err := a.client.callAPI(r) + if err != nil || localVarHttpResponse == nil { + return localVarReturnValue, localVarHttpResponse, err + } + + localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body) + localVarHttpResponse.Body.Close() + if err != nil { + return localVarReturnValue, localVarHttpResponse, err + } + + if localVarHttpResponse.StatusCode < 300 { + // If we succeed, return the data, otherwise pass on to decode error. + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err == nil { + return localVarReturnValue, localVarHttpResponse, err + } + } + + if localVarHttpResponse.StatusCode >= 300 { + newErr := GenericSwaggerError{ + body: localVarBody, + error: localVarHttpResponse.Status, + } + if localVarHttpResponse.StatusCode == 201 { + var v SubscriptionsBody + err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHttpResponse, newErr + } + newErr.model = v + return localVarReturnValue, localVarHttpResponse, newErr + } + if localVarHttpResponse.StatusCode == 400 { + var v ProblemDetails + err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHttpResponse, newErr + } + newErr.model = v + return localVarReturnValue, localVarHttpResponse, newErr + } + if localVarHttpResponse.StatusCode == 401 { + var v ProblemDetails + err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHttpResponse, newErr + } + newErr.model = v + return localVarReturnValue, localVarHttpResponse, newErr + } + if localVarHttpResponse.StatusCode == 403 { + var v ProblemDetails + err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHttpResponse, newErr + } + newErr.model = v + return localVarReturnValue, localVarHttpResponse, newErr + } + if localVarHttpResponse.StatusCode == 404 { + var v ProblemDetails + err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHttpResponse, newErr + } + newErr.model = v + return localVarReturnValue, localVarHttpResponse, newErr + } + if localVarHttpResponse.StatusCode == 406 { + var v ProblemDetails + err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHttpResponse, newErr + } + newErr.model = v + return localVarReturnValue, localVarHttpResponse, newErr + } + if localVarHttpResponse.StatusCode == 415 { + var v ProblemDetails + err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHttpResponse, newErr + } + newErr.model = v + return localVarReturnValue, localVarHttpResponse, newErr + } + if localVarHttpResponse.StatusCode == 422 { + var v ProblemDetails + err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHttpResponse, newErr + } + newErr.model = v + return localVarReturnValue, localVarHttpResponse, newErr + } + if localVarHttpResponse.StatusCode == 429 { + var v ProblemDetails + err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHttpResponse, newErr + } + newErr.model = v + return localVarReturnValue, localVarHttpResponse, newErr + } + return localVarReturnValue, localVarHttpResponse, newErr + } + + return localVarReturnValue, localVarHttpResponse, nil +} + +/* +V2xiApiService Used to publish a V2X message. +Used to publish a V2X message. + * @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + * @param body + +*/ +func (a *V2xiApiService) V2xMessagePOST(ctx context.Context, body V2xMsgPublication) (*http.Response, error) { + var ( + localVarHttpMethod = strings.ToUpper("Post") + localVarPostBody interface{} + localVarFileName string + localVarFileBytes []byte + ) + + // create path and map variables + localVarPath := a.client.cfg.BasePath + "/publish_v2x_message" + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + // to determine the Content-Type header + localVarHttpContentTypes := []string{"application/json"} + + // set Content-Type header + localVarHttpContentType := selectHeaderContentType(localVarHttpContentTypes) + if localVarHttpContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHttpContentType + } + + // to determine the Accept header + localVarHttpHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHttpHeaderAccept := selectHeaderAccept(localVarHttpHeaderAccepts) + if localVarHttpHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHttpHeaderAccept + } + // body params + localVarPostBody = &body + r, err := a.client.prepareRequest(ctx, localVarPath, localVarHttpMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, localVarFileName, localVarFileBytes) + if err != nil { + return nil, err + } + + localVarHttpResponse, err := a.client.callAPI(r) + if err != nil || localVarHttpResponse == nil { + return localVarHttpResponse, err + } + + localVarBody, err := ioutil.ReadAll(localVarHttpResponse.Body) + localVarHttpResponse.Body.Close() + if err != nil { + return localVarHttpResponse, err + } + + if localVarHttpResponse.StatusCode >= 300 { + newErr := GenericSwaggerError{ + body: localVarBody, + error: localVarHttpResponse.Status, + } + if localVarHttpResponse.StatusCode == 400 { + var v ProblemDetails + err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarHttpResponse, newErr + } + newErr.model = v + return localVarHttpResponse, newErr + } + if localVarHttpResponse.StatusCode == 401 { + var v ProblemDetails + err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarHttpResponse, newErr + } + newErr.model = v + return localVarHttpResponse, newErr + } + if localVarHttpResponse.StatusCode == 403 { + var v ProblemDetails + err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarHttpResponse, newErr + } + newErr.model = v + return localVarHttpResponse, newErr + } + if localVarHttpResponse.StatusCode == 404 { + var v ProblemDetails + err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarHttpResponse, newErr + } + newErr.model = v + return localVarHttpResponse, newErr + } + if localVarHttpResponse.StatusCode == 406 { + var v ProblemDetails + err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarHttpResponse, newErr + } + newErr.model = v + return localVarHttpResponse, newErr + } + if localVarHttpResponse.StatusCode == 429 { + var v ProblemDetails + err = a.client.decode(&v, localVarBody, localVarHttpResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarHttpResponse, newErr + } + newErr.model = v + return localVarHttpResponse, newErr + } + return localVarHttpResponse, newErr + } + + return localVarHttpResponse, nil +} diff --git a/go-packages/meep-vis-client/client.go b/go-packages/meep-vis-client/client.go index 18f77696b..c0b062054 100644 --- a/go-packages/meep-vis-client/client.go +++ b/go-packages/meep-vis-client/client.go @@ -199,7 +199,7 @@ func (c *APIClient) prepareRequest( } // add form parameters and file if available. - if len(formParams) > 0 || (len(fileBytes) > 0 && fileName != "") { + if strings.HasPrefix(headerParams["Content-Type"], "multipart/form-data") && len(formParams) > 0 || (len(fileBytes) > 0 && fileName != "") { if body != nil { return nil, errors.New("Cannot specify postBody and multipart form at the same time.") } @@ -238,6 +238,16 @@ func (c *APIClient) prepareRequest( w.Close() } + if strings.HasPrefix(headerParams["Content-Type"], "application/x-www-form-urlencoded") && len(formParams) > 0 { + if body != nil { + return nil, errors.New("Cannot specify postBody and x-www-form-urlencoded form at the same time.") + } + body = &bytes.Buffer{} + body.WriteString(formParams.Encode()) + // Set Content-Length + headerParams["Content-Length"] = fmt.Sprintf("%d", body.Len()) + } + // Setup path and query parameters url, err := url.Parse(path) if err != nil { diff --git a/go-packages/meep-vis-client/model_v2x_msg_subscription_filter_criteria.go b/go-packages/meep-vis-client/model_v2x_msg_subscription_filter_criteria.go index e5baf15c8..9088dcd61 100644 --- a/go-packages/meep-vis-client/model_v2x_msg_subscription_filter_criteria.go +++ b/go-packages/meep-vis-client/model_v2x_msg_subscription_filter_criteria.go @@ -27,7 +27,7 @@ package client // 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 V2xMsgSubscriptionFilterCriteria struct { // Subscribed V2X message type. Its value is defined by the standardization organization indicated by the attribute stdOrganization. See note 3. - MsgType []string `json:"msgType,omitempty"` + MsgType []MsgType `json:"msgType,omitempty"` // Standardization organization which defines the subscribed V2X message type: ETSI: European Telecommunications Standards Institute. See note 2. StdOrganization string `json:"stdOrganization"` } diff --git a/go-packages/meep-vis-traffic-mgr/amqp.go b/go-packages/meep-vis-traffic-mgr/amqp.go new file mode 100644 index 000000000..703233022 --- /dev/null +++ b/go-packages/meep-vis-traffic-mgr/amqp.go @@ -0,0 +1,71 @@ +/* + * 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. + */ + +package vistrafficmgr + +import ( + //"encoding/hex" + "net/url" + //"errors" + + log "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-logger" + //amqp "github.com/hadihammurabi/go-rabbitmq" +) + +type message_broker_amqp struct { + running bool +} + +func (amqp *message_broker_amqp) Init(tm *TrafficMgr) (err error) { + log.Info("message_broker_amqp: Init") + + amqp.running = false + + u, err := url.ParseRequestURI(tm.broker) + if err != nil { + log.Error(err.Error()) + return err + } + log.Info("url:%v\nscheme:%v host:%v Path:%v Port:%s", u, u.Scheme, u.Hostname(), u.Path, u.Port()) + + // TODO + + return nil +} + +func (amqp *message_broker_amqp) Run(tm *TrafficMgr) (err error) { + log.Info("message_broker_amqp: Run") + + // TODO + + return nil +} + +func (amqp *message_broker_amqp) Stop(tm *TrafficMgr) (err error) { + log.Info("message_broker_amqp: Stop") + + // TODO + + return nil +} + +func (amqp *message_broker_amqp) Send(tm *TrafficMgr, msgContent string, msgEncodeFormat string, stdOrganization string, msgType *int32) (err error) { + log.Info("message_broker_amqp: Send") + + // TODO + + return nil +} diff --git a/go-packages/meep-vis-traffic-mgr/go.mod b/go-packages/meep-vis-traffic-mgr/go.mod index be384b25b..aae19721c 100644 --- a/go-packages/meep-vis-traffic-mgr/go.mod +++ b/go-packages/meep-vis-traffic-mgr/go.mod @@ -5,8 +5,10 @@ go 1.16 require ( github.com/BurntSushi/toml v1.2.0 // indirect github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-logger v0.0.0 + github.com/eclipse/paho.mqtt.golang v1.4.2 github.com/lib/pq v1.10.7 github.com/roymx/viper v1.3.3-0.20190416163942-b9a223fc58a3 + ) replace github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-logger => ../../go-packages/meep-logger diff --git a/go-packages/meep-vis-traffic-mgr/go.sum b/go-packages/meep-vis-traffic-mgr/go.sum index 645332803..ba3bc743b 100644 --- a/go-packages/meep-vis-traffic-mgr/go.sum +++ b/go-packages/meep-vis-traffic-mgr/go.sum @@ -6,8 +6,12 @@ github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8Nz github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/eclipse/paho.mqtt.golang v1.4.2 h1:66wOzfUHSSI1zamx7jR6yMEI5EuHnT1G6rNA5PM12m4= +github.com/eclipse/paho.mqtt.golang v1.4.2/go.mod h1:JGt0RsEwEX+Xa/agj90YJ9d9DH2b7upDZMK9HRbFvCA= github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= +github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw= @@ -38,9 +42,17 @@ github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXf github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/net v0.0.0-20200425230154-ff2c4b7c35a0 h1:Jcxah/M+oLZ/R4/z5RzfPzGbPXnVDPkEDtf2JnuxN+U= +golang.org/x/net v0.0.0-20200425230154-ff2c4b7c35a0/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a h1:1n5lsVfiQW3yfsRGu98756EH1YthsFqr/5mxHduZW2A= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= diff --git a/go-packages/meep-vis-traffic-mgr/message_broker_interface.go b/go-packages/meep-vis-traffic-mgr/message_broker_interface.go new file mode 100644 index 000000000..3f6e9fae6 --- /dev/null +++ b/go-packages/meep-vis-traffic-mgr/message_broker_interface.go @@ -0,0 +1,27 @@ +/* + * 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. + */ + +package vistrafficmgr + +type message_broker_interface interface { + Init(tm *TrafficMgr) (err error) + + Run(tm *TrafficMgr) (err error) + + Stop(tm *TrafficMgr) (err error) + + Send(tm *TrafficMgr, msgContent string, msgEncodeFormat string, stdOrganization string, msgType *int32) (err error) +} diff --git a/go-packages/meep-vis-traffic-mgr/mqtt.go b/go-packages/meep-vis-traffic-mgr/mqtt.go new file mode 100644 index 000000000..3a23a789a --- /dev/null +++ b/go-packages/meep-vis-traffic-mgr/mqtt.go @@ -0,0 +1,71 @@ +/* + * 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. + */ + +package vistrafficmgr + +import ( + //"encoding/hex" + "net/url" + //-"errors" + + log "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-logger" + //mqtt "github.com/eclipse/paho.mqtt.golang" +) + +type message_broker_mqtt struct { + running bool +} + +func (mqtt *message_broker_mqtt) Init(tm *TrafficMgr) (err error) { + log.Info("message_broker_mqtt: Init") + + mqtt.running = false + + u, err := url.ParseRequestURI(tm.broker) + if err != nil { + log.Error(err.Error()) + return err + } + log.Info("url:%v\nscheme:%v host:%v Path:%v Port:%s", u, u.Scheme, u.Hostname(), u.Path, u.Port()) + + // TODO + + return nil +} + +func (mqtt *message_broker_mqtt) Run(tm *TrafficMgr) (err error) { + log.Info("message_broker_mqtt: Run") + + // TODO + + return nil +} + +func (mqtt *message_broker_mqtt) Stop(tm *TrafficMgr) (err error) { + log.Info("message_broker_mqtt: Stop") + + // TODO + + return nil +} + +func (mqtt *message_broker_mqtt) Send(tm *TrafficMgr, msgContent string, msgEncodeFormat string, stdOrganization string, msgType *int32) (err error) { + log.Info("message_broker_mqtt: Send") + + // TODO + + return nil +} diff --git a/go-packages/meep-vis-traffic-mgr/simulator.go b/go-packages/meep-vis-traffic-mgr/simulator.go new file mode 100644 index 000000000..85e6fe77a --- /dev/null +++ b/go-packages/meep-vis-traffic-mgr/simulator.go @@ -0,0 +1,269 @@ +/* + * 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. + */ + +package vistrafficmgr + +import ( + "encoding/hex" + //"errors" + "math/rand" + "time" + + log "github.com/InterDigitalInc/AdvantEDGE/go-packages/meep-logger" +) + +type message_broker_simu struct { + running bool + simulatedV2xMessages map[int32][]byte + simulateBrokerTicker *time.Ticker +} + +func (simu *message_broker_simu) Init(tm *TrafficMgr) (err error) { + log.Info("message_broker_simu: Init") + + simu.running = false + const ( + DENM int32 = 1 + CAM int32 = 2 + POI int32 = 3 + SPATEM int32 = 4 + MAPEM int32 = 5 + IVIM int32 = 6 + EV_RSR int32 = 7 + TISTPGTRANSACTION int32 = 8 + SREM int32 = 9 + SSEM int32 = 10 + EVCSN int32 = 11 + SAEM int32 = 12 + RTCMEM int32 = 13 + ) + simu.simulatedV2xMessages = map[int32][]byte{ + CAM: { + 0x03, 0x12, 0x00, 0x05, 0x01, 0x03, 0x81, 0x00, /* ........ */ + 0x40, 0x03, 0x80, 0x65, 0x20, 0x50, 0x02, 0x80, /* @..e P.. */ + 0x00, 0x41, 0x01, 0x00, 0x14, 0x00, 0x04, 0xe5, /* .A...... */ + 0x48, 0x14, 0x00, 0x72, 0x0c, 0x65, 0x09, 0xbf, /* H..r.e.. */ + 0x1e, 0xb7, 0x81, 0xdf, 0x08, 0x4d, 0x55, 0x4e, /* .....MUN */ + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ + 0x07, 0xd1, 0x00, 0x00, 0x02, 0x02, 0x48, 0x14, /* ......H. */ + 0x00, 0x72, 0x09, 0xbf, 0x40, 0x5a, 0x8b, 0x8d, /* .r..@Z.. */ + 0x5b, 0xee, 0x72, 0xe4, 0xe9, 0xc1, 0x90, 0x19, /* [.r..... */ + 0x03, 0x84, 0x39, 0x29, 0xd0, 0x40, 0xe1, 0x1f, /* ..9).@.. */ + 0xc0, 0x00, 0x7e, 0x82, 0x98, 0x8a, 0x83, 0x37, /* ..~....7 */ + 0xfe, 0xeb, 0xff, 0xf6, 0x00, 0x00, 0x00, 0x2b, /* .......+ */ + 0xff, 0xd0, 0xff, 0xef, 0x32, 0xbe, 0x7f, 0xff, /* ....2... */ + 0x60, 0x05, 0x77, 0xff, 0xfd, 0x8b, 0x53, 0xff, /* `.w...S. */ + 0xf8, 0xc0, 0x01, 0x24, 0x00, 0x02, 0x0b, 0xa0, /* ...$.... */ + 0x6a, 0xaf, 0x23, 0x01, 0x02, 0x05, 0x80, 0x05, /* j.#..... */ + 0x01, 0x01, 0x81, 0xa8, 0x43, 0x81, 0x01, 0x01, /* ....C... */ + 0x80, 0x03, 0x00, 0x80, 0x31, 0x63, 0xf3, 0x55, /* ....1c.U */ + 0x36, 0xc8, 0x3e, 0xd0, 0x10, 0x83, 0x00, 0x00, /* 6.>..... */ + 0x00, 0x00, 0x00, 0x22, 0x50, 0x26, 0xe0, 0x84, /* ..."P&.. */ + 0x00, 0x24, 0x01, 0x02, 0x80, 0x01, 0x24, 0x81, /* .$....$. */ + 0x04, 0x03, 0x01, 0xff, 0xfc, 0x80, 0x01, 0x25, /* .......% */ + 0x81, 0x05, 0x04, 0x01, 0xff, 0xff, 0xff, 0x80, /* ........ */ + 0x80, 0x83, 0x46, 0xf7, 0x82, 0xd1, 0x33, 0xdb, /* ..F...3. */ + 0x96, 0xbb, 0xac, 0x7d, 0xdf, 0x85, 0xc0, 0xb2, /* ...}.... */ + 0x33, 0x6c, 0x4a, 0xb8, 0x39, 0x01, 0x1d, 0x67, /* 3lJ.9..g */ + 0xb1, 0x00, 0x48, 0x77, 0x4a, 0x15, 0xbf, 0x7f, /* ..HwJ... */ + 0x45, 0xeb, 0x80, 0x80, 0xd3, 0x74, 0x1a, 0xc0, /* E....t.. */ + 0x58, 0x6d, 0x85, 0xac, 0x63, 0x99, 0xee, 0x3c, /* Xm..c..< */ + 0x60, 0x20, 0xa2, 0x55, 0xe1, 0x88, 0x6d, 0x53, /* ` .U..mS */ + 0xf4, 0x32, 0xf3, 0xea, 0xe9, 0x52, 0x13, 0x31, /* .2...R.1 */ + 0x4c, 0x3d, 0x52, 0x44, 0xd6, 0x5f, 0xf7, 0x08, /* L=RD._.. */ + 0x3c, 0xe7, 0x97, 0xc7, 0x0f, 0xb3, 0x50, 0xc9, /* <.....P. */ + 0xee, 0xf1, 0xd3, 0x95, 0x76, 0x80, 0x9f, 0x8b, /* ....v... */ + 0x6c, 0xb2, 0x31, 0xe6, 0x98, 0xfe, 0xa9, 0xbf, /* l.1..... */ + 0xfc, 0x80, 0xc8, 0x83, 0x80, 0x80, 0x63, 0xca, /* ......c. */ + 0xdc, 0x41, 0xab, 0x68, 0x17, 0x41, 0xf0, 0xd0, /* .A.h.A.. */ + 0xf1, 0xea, 0xab, 0x6e, 0x6c, 0xda, 0xa8, 0x66, /* ...nl..f */ + 0x23, 0x21, 0xb3, 0xb2, 0xc5, 0x76, 0x49, 0xfa, /* #!...vI. */ + 0xe6, 0xc7, 0x1f, 0xcf, 0xa4, 0xc6, 0x74, 0x5d, /* ......t] */ + 0x2d, 0x32, 0x69, 0x72, 0x29, 0xbb, 0xbf, 0xb6, /* -2ir)... */ + 0x22, 0xb6, 0x60, 0xe6, 0xb5, 0xcd, 0x31, 0x9a, /* ".`...1. */ + 0x97, 0xde, 0x0d, 0xdf, 0xf4, 0xb1, 0x8a, 0x0f, /* ........ */ + 0x65, 0xc6, 0x53, 0xf0, 0xd6, 0x5d, + }, + DENM: { + 0x03, 0x12, 0x00, 0xf1, 0x01, 0x03, 0x81, 0x00, /* ........ */ + 0x40, 0x03, 0x80, 0x81, 0x8c, 0x20, 0x40, 0x01, /* @.... @. */ + 0x00, 0x00, 0x58, 0x02, 0x00, 0x1e, 0xe6, 0x00, /* ..X..... */ + 0x00, 0x3c, 0x00, 0x04, 0xe5, 0x48, 0x14, 0x00, /* .<...H.. */ + 0x72, 0x06, 0x6b, 0x24, 0xd0, 0x1e, 0xb7, 0x81, /* r.k$.... */ + 0x49, 0x08, 0x4d, 0x55, 0x71, 0x80, 0x00, 0x00, /* I.MUq... */ + 0x00, 0x1e, 0xb7, 0x8b, 0x7b, 0x08, 0x4d, 0xc1, /* ....{.M. */ + 0x8b, 0x07, 0xd0, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ + 0x00, 0x07, 0xd2, 0x00, 0x00, 0x02, 0x01, 0x71, /* .......q */ + 0xd9, 0x5b, 0x9a, 0xc7, 0xb8, 0xec, 0xad, 0xcd, /* .[...... */ + 0x00, 0x1b, 0x90, 0xc0, 0xc1, 0xb4, 0xe7, 0xa4, /* ........ */ + 0x30, 0x30, 0x36, 0x58, 0x35, 0x45, 0xc7, 0x47, /* 006X5E.G */ + 0xb7, 0x39, 0x79, 0x38, 0xbf, 0xff, 0xff, 0xfe, /* .9y8.... */ + 0x11, 0xdb, 0xba, 0x1f, 0x0b, 0x01, 0xe8, 0x06, /* ........ */ + 0x30, 0xf1, 0xc1, 0x80, 0x25, 0xa7, 0x62, 0x40, /* 0...%.b@ */ + 0xa7, 0xf2, 0xea, 0x02, 0x0b, 0x63, 0x38, 0x7f, /* .....c8. */ + 0x2e, 0xa0, 0x20, 0xb6, 0x33, 0x87, 0xf2, 0xea, /* .. .3... */ + 0x02, 0x0b, 0x63, 0x38, 0x7f, 0x2e, 0xa0, 0x20, /* ..c8... */ + 0xb6, 0x33, 0x87, 0xf2, 0xea, 0x02, 0x0b, 0x63, /* .3.....c */ + 0x38, 0x50, 0x01, 0x25, 0x00, 0x02, 0x0b, 0x89, /* 8P.%.... */ + 0x12, 0x89, 0x6a, 0x0d, 0x1e, 0xb7, 0x81, 0x49, /* ..j....I */ + 0x08, 0x4d, 0x55, 0x71, 0x06, 0xa2, 0x81, 0x01, /* .MUq.... */ + 0x01, 0x80, 0x03, 0x00, 0x80, 0x31, 0x63, 0xf3, /* .....1c. */ + 0x55, 0x36, 0xc8, 0x3e, 0xd0, 0x10, 0x83, 0x00, /* U6.>.... */ + 0x00, 0x00, 0x00, 0x00, 0x22, 0x4e, 0x2c, 0xa0, /* ...."N,. */ + 0x84, 0x00, 0x24, 0x01, 0x02, 0x80, 0x01, 0x24, /* ..$....$ */ + 0x81, 0x04, 0x03, 0x01, 0xff, 0xfc, 0x80, 0x01, /* ........ */ + 0x25, 0x81, 0x05, 0x04, 0x01, 0xff, 0xff, 0xff, /* %....... */ + 0x80, 0x80, 0x83, 0x69, 0x9e, 0x54, 0x31, 0x01, /* ...i.T1. */ + 0x42, 0x10, 0x24, 0xed, 0xf0, 0x50, 0xb6, 0xf1, /* B.$..P.. */ + 0xe3, 0xb7, 0xdd, 0xf7, 0xcc, 0xc6, 0x5c, 0xb3, /* ......\. */ + 0x1b, 0x1f, 0x72, 0xec, 0x5d, 0xad, 0x92, 0x4c, /* ..r.]..L */ + 0x4a, 0x4e, 0x01, 0x80, 0x80, 0x70, 0xee, 0xfd, /* JN...p.. */ + 0x24, 0x44, 0xf4, 0x3f, 0x98, 0x84, 0x78, 0x7d, /* $D.?..x} */ + 0x5d, 0xa5, 0x2e, 0x2e, 0x5a, 0x4b, 0x3a, 0xc7, /* ]...ZK:. */ + 0x1e, 0x87, 0xc2, 0x54, 0xf6, 0xb8, 0xab, 0xef, /* ...T.... */ + 0xef, 0x8a, 0xa2, 0xc0, 0x30, 0xa6, 0x20, 0x1b, /* ....0. . */ + 0x45, 0xc1, 0x09, 0x55, 0x94, 0x31, 0x96, 0x07, /* E..U.1.. */ + 0xfa, 0x05, 0x3b, 0x92, 0xdd, 0xc7, 0x98, 0xf7, /* ..;..... */ + 0x2c, 0xfd, 0xe4, 0x80, 0x0c, 0x97, 0xfa, 0xa3, /* ,....... */ + 0xfc, 0x9c, 0x51, 0xaf, 0xdd, 0x80, 0x80, 0x83, /* ..Q..... */ + 0xc0, 0x3e, 0x25, 0x01, 0x0f, 0xe9, 0x8f, 0x93, /* .>%..... */ + 0x6b, 0x8d, 0x5b, 0xe9, 0x69, 0x5d, 0xf3, 0xa5, /* k.[.i].. */ + 0x33, 0x7e, 0x42, 0xa0, 0x8e, 0xcf, 0xf4, 0x3c, /* 3~B....< */ + 0x93, 0xe1, 0x6e, 0xe0, 0x01, 0x63, 0x97, 0x30, /* ..n..c.0 */ + 0x31, 0x99, 0xe9, 0x61, 0x82, 0x57, 0x86, 0xe7, /* 1..a.W.. */ + 0x15, 0xf0, 0x96, 0xcf, 0x7e, 0x27, 0x55, 0x6a, /* ....~'Uj */ + 0x3a, 0x0a, 0x0d, 0x9f, 0xd9, 0x35, 0xd8, 0x7a, /* :....5.z */ + 0x56, 0x06, 0xcf, 0x81, 0xfe, 0x5e, 0x24, + }, + IVIM: {0xDE, 0x5E}, + MAPEM: { + 0x03, 0x12, 0x00, 0x50, 0x01, 0x03, 0x81, 0x00, /* ...P.... */ + 0x40, 0x03, 0x80, 0x6f, 0x20, 0x40, 0x03, 0x80, /* @..o @.. */ + 0x00, 0x3b, 0x01, 0x00, 0xae, 0xd0, 0x00, 0x00, /* .;...... */ + 0xbc, 0x00, 0x00, 0x13, 0x95, 0x2a, 0x6b, 0x79, /* .....*ky */ + 0x02, 0x86, 0x8e, 0x5e, 0x1e, 0xb7, 0x7e, 0xa0, /* ...^..~. */ + 0x08, 0x4d, 0x51, 0xf0, 0x00, 0x00, 0x00, 0x00, /* .MQ..... */ + 0x1e, 0xb7, 0x7e, 0xb2, 0x08, 0x4d, 0x51, 0xf2, /* ..~..MQ. */ + 0x13, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ + 0x07, 0xd3, 0x00, 0x00, 0x02, 0x05, 0x00, 0x01, /* ........ */ + 0x3d, 0xb0, 0x08, 0x00, 0x00, 0x10, 0x00, 0x10, /* =....... */ + 0xbb, 0x90, 0x22, 0xa2, 0xe1, 0xd0, 0x83, 0x9c, /* .."..... */ + 0xb4, 0x14, 0x10, 0x09, 0x20, 0x50, 0xa0, 0x00, /* .... P.. */ + 0x00, 0x00, 0x00, 0xa1, 0x68, 0x61, 0xa5, 0x1f, /* ....ha.. */ + 0x74, 0xc0, 0x81, 0x43, 0x21, 0x01, 0x42, 0x20, /* t..C!.B */ + 0x00, 0x00, 0x00, 0x00, 0xa3, 0x34, 0xc3, 0x4a, /* .....4.J */ + 0x86, 0xe4, 0x80, 0x40, 0x01, 0x8a, 0x00, 0x02, /* ...@.... */ + 0x0b, 0x79, 0xdd, 0x9c, 0x21, 0x54, 0x80, 0x64, /* .y..!T.d */ + 0xc7, 0x8c, 0x07, 0x98, 0x1e, 0x0d, 0x4a, 0x80, /* ......J. */ + 0x80, 0xda, 0xfb, 0x20, 0x62, 0xda, 0x36, 0xea, /* ... b.6. */ + 0xe3, 0x5a, 0x45, 0x30, 0xfe, 0x5d, 0xc4, 0x60, /* .ZE0.].` */ + 0x01, 0x60, 0xa8, 0xb7, 0xff, 0x34, 0x77, 0xbd, /* .`...4w. */ + 0x79, 0x9f, 0x17, 0x08, 0xd9, 0x1a, 0x72, 0x28, /* y.....r( */ + 0xc7, 0xcd, 0xa2, 0x6c, 0x6e, 0x02, 0xf8, 0x54, /* ...ln..T */ + 0xe0, 0xbc, 0x21, 0xa6, 0x86, 0x71, 0x44, 0x1f, /* ..!..qD. */ + 0xc4, 0xcd, 0xe6, 0x53, 0xe8, 0x19, 0xb2, 0x90, /* ...S.... */ + 0xab, 0x45, 0x04, 0x62, 0xa1, 0xfa, 0xd7, 0x13, /* .E.b.... */ + 0x09, + }, + SPATEM: { + 0x00, 0x04, 0x02, 0x12, 0x00, 0x00, 0x00, 0x00, /* ........ */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0xdd, /* ........ */ + 0x60, 0x30, 0x00, 0x00, 0x00, 0xc2, 0x11, 0x01, /* `0...... */ + 0x80, 0xf8, 0x0f, 0x80, 0xf8, 0x0f, 0x80, 0xf8, /* ........ */ + 0x61, 0xa9, 0x74, 0x07, 0xbb, 0xbb, 0x31, 0x82, /* a.t...1. */ + 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, /* ........ */ + 0x0a, 0x2a, 0x0a, 0x2a, 0x00, 0xc2, 0x77, 0xe8, /* .*.*..w. */ + 0x03, 0x12, 0x00, 0x50, 0x01, 0x03, 0x81, 0x00, /* ...P.... */ + 0x40, 0x03, 0x80, 0x58, 0x20, 0x40, 0x03, 0x80, /* @..X @.. */ + 0x00, 0x24, 0x01, 0x00, 0xae, 0xd2, 0x00, 0x00, /* .$...... */ + 0xbc, 0x00, 0x00, 0x13, 0x95, 0x2a, 0x6b, 0x79, /* .....*ky */ + 0x02, 0x86, 0x91, 0x18, 0x1e, 0xb7, 0x7e, 0xa0, /* ......~. */ + 0x08, 0x4d, 0x51, 0xf0, 0x00, 0x00, 0x00, 0x00, /* .MQ..... */ + 0x1e, 0xb7, 0x7e, 0xb2, 0x08, 0x4d, 0x51, 0xf2, /* ..~..MQ. */ + 0x13, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */ + 0x07, 0xd4, 0x00, 0x00, 0x02, 0x04, 0x00, 0x01, /* ........ */ + 0x3d, 0xb0, 0x00, 0x18, 0x80, 0x00, 0x85, 0xdc, /* =....... */ + 0x81, 0x00, 0x00, 0x1e, 0x77, 0xfb, 0x3e, 0xe0, /* ....w.>. */ + 0x00, 0x32, 0x14, 0x30, 0x46, 0x0f, 0x22, 0xc2, /* .2.0F.". */ + 0x30, 0x78, 0x02, 0xa8, 0x40, 0x01, 0x89, 0x00, /* 0x..@... */ + 0x02, 0x0b, 0x79, 0xdd, 0xa6, 0xc6, 0x8c, 0x80, /* ..y..... */ + 0x64, 0xc7, 0x8c, 0x07, 0x98, 0x1e, 0x0d, 0x4a, /* d......J */ + 0x80, 0x80, 0x64, 0x2a, 0x2c, 0x10, 0x68, 0x74, /* ..d*,.ht */ + 0x22, 0x00, 0xc3, 0xaa, 0xdb, 0x9b, 0x04, 0x02, /* "....... */ + 0x01, 0xb6, 0x41, 0x17, 0x73, 0x5b, 0x54, 0x9a, /* ..A.s[T. */ + 0x9c, 0x0f, 0x02, 0xe4, 0x70, 0x7e, 0xd7, 0x9c, /* ....p~.. */ + 0xc2, 0xf4, 0xab, 0x82, 0x96, 0x52, 0xb5, 0xa2, /* .....R.. */ + 0x91, 0xe4, 0xac, 0x98, 0x83, 0x09, 0x8b, 0xce, /* ........ */ + 0xb5, 0xfd, 0xa4, 0xec, 0x12, 0xba, 0xb0, 0x7c, /* .......| */ + 0xe4, 0x93, 0xcb, 0x7c, 0x20, 0x91, 0xc5, 0xa3, /* ...| ... */ + 0x09, 0x7e, + }, + } + + return nil +} + +func (simu *message_broker_simu) Run(tm *TrafficMgr) (err error) { + log.Info("message_broker_simu: Run: simu.running: ", simu.running) + + simu.simulateBrokerTicker = time.NewTicker(time.Second) + simu.running = true + go func() { + for range simu.simulateBrokerTicker.C { + if !simu.running { + log.Info("message_broker_simu: Run: Exit loop") + break + } + // Generate new V2X message + i := int32(rand.Intn(1)) + 1 + v2xMessage := simu.simulatedV2xMessages[i] + tm.v2x_notify(v2xMessage, i, nil, nil) + } // End of 'for' statement + }() + + return nil +} + +func (simu *message_broker_simu) Stop(tm *TrafficMgr) (err error) { + log.Info("message_broker_simu: Stop: simu.running: ", simu.running) + + if simu.running { + simu.running = false + time.Sleep(2 * time.Second) + simu.simulateBrokerTicker.Stop() + simu.simulateBrokerTicker = nil + } + + return nil +} + +func (simu *message_broker_simu) Send(tm *TrafficMgr, msgContent string, msgEncodeFormat string, stdOrganization string, msgType *int32) (err error) { + log.Info("message_broker_simu: Send") + + if msgEncodeFormat == "hexadump" { + content, err := hex.DecodeString(msgContent) + if err != nil { + log.Error(err.Error()) + return err + } + log.Info("message_broker_simu: Send: Publish content : ", content) + log.Info("message_broker_simu: Send: msgEncodeFormat: ", msgEncodeFormat) + log.Info("message_broker_simu: Send: stdOrganization: ", stdOrganization) + } + + return nil +} diff --git a/go-packages/meep-vis-traffic-mgr/traffic-mgr.go b/go-packages/meep-vis-traffic-mgr/traffic-mgr.go index 7d3f5798d..f0a3c356d 100644 --- a/go-packages/meep-vis-traffic-mgr/traffic-mgr.go +++ b/go-packages/meep-vis-traffic-mgr/traffic-mgr.go @@ -20,6 +20,8 @@ import ( "database/sql" "errors" "math" + "net/url" + "sort" "strconv" "strings" "sync" @@ -38,12 +40,16 @@ type TrafficMgr struct { pwd string host string port string + broker string + poa_list []string + v2x_notify func(v2xMessage []byte, v2xType int32, longitude *float32, latitude *float32) dbName string db *sql.DB connected bool GridFileExists bool mutex sync.Mutex poaLoadMap map[string]*PoaLoads + message_broker message_broker_interface // updateCb func(string, string) } @@ -65,6 +71,47 @@ type GridMapTable struct { grid string } +type UuUnicastProvisioningInfoProInfoUuUnicast struct { + LocationInfo *LocationInfo + NeighbourCellInfo []UuUniNeighbourCellInfo + V2xApplicationServer *V2xApplicationServer +} +type UuUnicastProvisioningInfoProInfoUuUnicast_list []UuUnicastProvisioningInfoProInfoUuUnicast +type LocationInfo struct { + Ecgi *Ecgi + GeoArea *LocationInfoGeoArea +} +type UuUniNeighbourCellInfo struct { + Ecgi *Ecgi + //FddInfo *FddInfo + Pci int32 + Plmn *Plmn + //TddInfo *TddInfo +} +type V2xApplicationServer struct { + IpAddress string + UdpPort string +} +type Ecgi struct { + CellId *CellId + Plmn *Plmn +} +type CellId struct { + CellId string +} +type Plmn struct { + Mcc string + Mnc string +} +type LocationInfoGeoArea struct { + Latitude float32 + Longitude float32 +} + +var brokerRunning bool = false +var cellName2CellId map[string]string = nil +var cellId2CellName map[string]string = nil + // DB Config const ( DbHost = "meep-postgis.default.svc.cluster.local" @@ -185,7 +232,7 @@ func init() { } // NewTrafficMgr - Creates and initializes a new VIS Traffic Manager -func NewTrafficMgr(name, namespace, user, pwd, host, port string) (tm *TrafficMgr, err error) { +func NewTrafficMgr(name string, namespace string, user string, pwd string, host string, port string, broker string, poa_list []string, v2x_notify func(v2xMessage []byte, v2xType int32, longitude *float32, latitude *float32)) (tm *TrafficMgr, err error) { if name == "" { err = errors.New("Missing connector name") return nil, err @@ -203,6 +250,9 @@ func NewTrafficMgr(name, namespace, user, pwd, host, port string) (tm *TrafficMg tm.pwd = pwd tm.host = host tm.port = port + tm.broker = broker + tm.poa_list = poa_list + tm.v2x_notify = v2x_notify tm.poaLoadMap = map[string]*PoaLoads{} // Connect to Postgis DB @@ -315,6 +365,8 @@ func (tm *TrafficMgr) DeleteTrafficMgr() (err error) { // Destroy sandbox database _ = tm.DestroyDb(tm.dbName) + tm.StopV2xMessageBrokerServer() + return nil } @@ -698,6 +750,38 @@ func (tm *TrafficMgr) GetPoaCategory(longitude float32, latitude float32) (categ return category, err } +func (tm *TrafficMgr) InitializeV2xMessageDistribution(poaNameList []string, ecgi_s []string) (err error) { + // Validate input + if poaNameList == nil { + err = errors.New("Missing POA Name List") + return err + } + if ecgi_s == nil { + err = errors.New("Missing ECGIs") + return err + } + + if len(ecgi_s) != 0 { + cellName2CellId = make(map[string]string, len(ecgi_s)) + cellId2CellName = make(map[string]string, len(ecgi_s)) + for i := 0; i < len(ecgi_s); i++ { + if ecgi_s[i] != "" { + idx := sort.Search(len(tm.poa_list), func(j int) bool { return poaNameList[i] <= tm.poa_list[j] }) + if idx < len(tm.poa_list) { + cellName2CellId[poaNameList[i]] = ecgi_s[i] + cellId2CellName[ecgi_s[i]] = poaNameList[i] + } + } + } // End of 'for' statement + log.Info("InitializeV2xMessageDistribution: cellName2CellId: ", cellName2CellId) + log.Info("InitializeV2xMessageDistribution: cellId2CellName: ", cellId2CellName) + } else { + log.Warn("InitializeV2xMessageDistribution: V2X message distribution ECGI list is empty") + } + + return nil +} + // PopulatePoaLoad - Populate the Traffic Load table func (tm *TrafficMgr) PopulatePoaLoad(poaNameList []string, gpsCoordinates [][]float32) (err error) { // Validate input @@ -728,6 +812,7 @@ func (tm *TrafficMgr) PopulatePoaLoad(poaNameList []string, gpsCoordinates [][]f return err } } + return nil } @@ -785,3 +870,126 @@ func findReducedSignalStrength(inRsrp int32, inRsrq int32, users int32, averageL return inRsrp, inRsrq, nil } } + +func (tm *TrafficMgr) GetInfoUuUnicast(params []string, num_item int) (proInfoUuUnicast UuUnicastProvisioningInfoProInfoUuUnicast_list, err error) { + if params[0] == "ecgi" { + //log.Info("GetInfoUuUnicast: Got ecgi") + proInfoUuUnicast = make([]UuUnicastProvisioningInfoProInfoUuUnicast, num_item) + for i := 1; i <= num_item; i++ { + //log.Info("GetInfoUuUnicast: Processing index #", i) + + ecgi_num, err := strconv.Atoi(params[i]) + if err != nil { + log.Error(err.Error()) + return nil, err + } + //log.Info("GetInfoUuUnicast: ecgi_num= ", ecgi_num) + + // Extract Poa CellId according to v2x_msg GS MEC 030 Clause 6.5.5 Type: Ecgi + TwentyEigthBits := 0xFFFFFFF // TS 36.413: E-UTRAN Cell Identity (ECI) and E-UTRAN Cell Global Identification (ECGI) + eci := ecgi_num & TwentyEigthBits + //log.Info("GetInfoUuUnicast: eci= ", int(eci)) + // Extract Poa Plmn according to v2x_msg GS MEC 030 Clause 6.5.4 Type: Plmn + plmn_num := int(ecgi_num >> 28) + //log.Info("GetInfoUuUnicast: plmn= ", plmn_num) + //mcc_num := int((plmn_num / 1000) & 0xFFFFFF) + //mnc_num := int((plmn_num - mcc_num * 1000) & 0xFFFFFF) + mcc_num := int(plmn_num / 1000) + mnc_num := int(plmn_num - mcc_num*1000) + //log.Info("GetInfoUuUnicast: mcc_num= ", mcc_num) + //log.Info("GetInfoUuUnicast: mnc_num= ", mnc_num) + + ecgi := Ecgi{ + CellId: &CellId{CellId: strconv.Itoa(int(eci))}, + Plmn: &Plmn{Mcc: strconv.Itoa(int(mcc_num)), Mnc: strconv.Itoa(int(mnc_num))}, + } + plmn := Plmn{Mcc: strconv.Itoa(int(mcc_num)), Mnc: strconv.Itoa(int(mnc_num))} + uuUniNeighbourCellInfo := make([]UuUniNeighbourCellInfo, 1) + uuUniNeighbourCellInfo[0] = UuUniNeighbourCellInfo{&ecgi, 0, &plmn} + var v2xApplicationServer *V2xApplicationServer = nil + if _, found := cellId2CellName[params[i]]; found { + u, err := url.ParseRequestURI(tm.broker) + if err != nil { + log.Error(err.Error()) + return nil, err + } + log.Info("url:%v\nscheme:%v host:%v Path:%v Port:%s", u, u.Scheme, u.Hostname(), u.Path, u.Port()) + v2xApplicationServer = &V2xApplicationServer{ + IpAddress: u.Hostname(), + UdpPort: u.Port(), + } + } + proInfoUuUnicast[i-1] = UuUnicastProvisioningInfoProInfoUuUnicast{nil, uuUniNeighbourCellInfo, v2xApplicationServer} + } // End of 'for' statement + } else if params[0] == "latitude" { + err = errors.New("GetInfoUuUnicast: Location not supported yet") + log.Error(err.Error()) + return nil, err + } else { + err = errors.New("GetInfoUuUnicast: Invalid parameter: " + params[0]) + log.Error(err.Error()) + return nil, err + } + + log.Info("GetInfoUuUnicast: proInfoUuUnicast= ", proInfoUuUnicast) + return proInfoUuUnicast, nil +} + +func (tm *TrafficMgr) PublishMessageOnMessageBroker(msgContent string, msgEncodeFormat string, stdOrganization string, msgType *int32) (err error) { + if !brokerRunning { + err = errors.New("Message broker mechanism not initialized") + log.Error(err.Error()) + return err + } + return tm.message_broker.Send(tm, msgContent, msgEncodeFormat, stdOrganization, msgType) +} + +func (tm *TrafficMgr) StartV2xMessageBrokerServer() (err error) { + if cellName2CellId == nil || len(cellId2CellName) == 0 { + brokerRunning = false + return + } + + u, err := url.ParseRequestURI(tm.broker) + if err != nil { + err = errors.New("Failed to parse url " + tm.broker) + log.Error(err.Error()) + return err + } + log.Info("url:%v\nscheme:%v host:%v Path:%v Port:%s", u, u.Scheme, u.Hostname(), u.Path, u.Port()) + if u.Scheme == "mqtt" { + // TODO tm.message_broker = &message_broker_mqtt{false} + tm.message_broker = &message_broker_simu{false, map[int32][]byte{}, nil} + } else if u.Scheme == "amqp" { + // TODO tm.message_broker = &message_broker_amqp{false} + tm.message_broker = &message_broker_simu{false, map[int32][]byte{}, nil} + } else { + err = errors.New("Invalid url " + tm.broker) + log.Error(err.Error()) + return err + } + + err = tm.message_broker.Init(tm) + if err != nil { + log.Error(err.Error()) + return err + } + err = tm.message_broker.Run(tm) + if err != nil { + log.Error(err.Error()) + return err + } + + brokerRunning = true + + return nil +} + +func (tm *TrafficMgr) StopV2xMessageBrokerServer() { + log.Info("StopV2xMessageBrokerServer: brokerRunning: ", brokerRunning) + + if brokerRunning { + brokerRunning = false + _ = tm.message_broker.Stop(tm) + } +} diff --git a/go-packages/meep-vis-traffic-mgr/traffic-mgr_test.go b/go-packages/meep-vis-traffic-mgr/traffic-mgr_test.go index 437cb230c..251629992 100644 --- a/go-packages/meep-vis-traffic-mgr/traffic-mgr_test.go +++ b/go-packages/meep-vis-traffic-mgr/traffic-mgr_test.go @@ -324,14 +324,14 @@ func TestPredictQosPerTrafficLoad(t *testing.T) { } // FIXME Are there any invalid Rsrp/Rsrq values? /*_, _, err = tm.PredictQosPerTrafficLoad(14, -1, 0, poaName1) - if err == nil { - t.Fatalf("Should have failed due to invalid inRsrp") - } - // Invalid inRsrq - _, _, err = tm.PredictQosPerTrafficLoad(14, 0, -1, poaName1) - if err == nil { - t.Fatalf("Should have failed due to invalid inRsrq") - }*/ + if err == nil { + t.Fatalf("Should have failed due to invalid inRsrp") + } + // Invalid inRsrq + _, _, err = tm.PredictQosPerTrafficLoad(14, 0, -1, poaName1) + if err == nil { + t.Fatalf("Should have failed due to invalid inRsrq") + }*/ fmt.Println("Invalid checks done") // FIXME Execute the test with proper values for inRsrp1 and inRsrq1