From 7178971a7f69da513f153f433b020dd986a393a6 Mon Sep 17 00:00:00 2001 From: ychacon Date: Mon, 15 May 2023 11:07:32 +0200 Subject: [PATCH] Adding Capif invoker Issue-ID: NONRTRIC-861 Signed-off-by: ychacon Change-Id: Idccd804e484fa0131496a8d7362bd242bf282a16 --- invoker/generate.sh | 168 +++++++++++++++++++++ invoker/go.mod | 35 +++++ invoker/go.sum | 98 ++++++++++++ .../common/generator_settings.yaml | 29 ++++ .../common29122/generator_settings.yaml | 30 ++++ .../common29571/generator_settings.yaml | 27 ++++ .../generator_settings_types.yaml | 29 ++++ .../generator_settings_types.yaml | 29 ++++ .../generator_settings_types.yaml | 28 ++++ .../generator_settings_types.yaml | 29 ++++ .../securityapi/generator_settings_types.yaml | 29 ++++ invoker/handler/common_handler.go | 79 ++++++++++ invoker/handler/discovery_handler.go | 99 ++++++++++++ invoker/handler/gettoken_handler.go | 100 ++++++++++++ invoker/handler/home_handler.go | 32 ++++ invoker/handler/offboardinvoker_handler.go | 20 +++ invoker/handler/onboardinvoker_handler.go | 100 ++++++++++++ invoker/handler/securitymethod_handler.go | 109 +++++++++++++ .../gentools/commoncollector/commoncollector.go | 119 +++++++++++++++ invoker/internal/gentools/enumfixer/enumfixer.go | 117 ++++++++++++++ .../specificationfixer/specificationfixer.go | 80 ++++++++++ invoker/main.go | 93 ++++++++++++ invoker/view/base.html | 53 +++++++ invoker/view/css/style.css | 41 +++++ invoker/view/discovery.html | 152 +++++++++++++++++++ invoker/view/gettoken.html | 102 +++++++++++++ invoker/view/home.html | 73 +++++++++ invoker/view/js/script.js | 136 +++++++++++++++++ invoker/view/onboardinvoker.html | 115 ++++++++++++++ invoker/view/securitymethod.html | 109 +++++++++++++ 30 files changed, 2260 insertions(+) create mode 100755 invoker/generate.sh create mode 100644 invoker/go.mod create mode 100644 invoker/go.sum create mode 100644 invoker/gogeneratorspecs/common/generator_settings.yaml create mode 100644 invoker/gogeneratorspecs/common29122/generator_settings.yaml create mode 100644 invoker/gogeneratorspecs/common29571/generator_settings.yaml create mode 100644 invoker/gogeneratorspecs/discoverserviceapi/generator_settings_types.yaml create mode 100644 invoker/gogeneratorspecs/invokermanagementapi/generator_settings_types.yaml create mode 100644 invoker/gogeneratorspecs/providermanagementapi/generator_settings_types.yaml create mode 100644 invoker/gogeneratorspecs/publishserviceapi/generator_settings_types.yaml create mode 100644 invoker/gogeneratorspecs/securityapi/generator_settings_types.yaml create mode 100644 invoker/handler/common_handler.go create mode 100644 invoker/handler/discovery_handler.go create mode 100644 invoker/handler/gettoken_handler.go create mode 100644 invoker/handler/home_handler.go create mode 100644 invoker/handler/offboardinvoker_handler.go create mode 100644 invoker/handler/onboardinvoker_handler.go create mode 100644 invoker/handler/securitymethod_handler.go create mode 100644 invoker/internal/gentools/commoncollector/commoncollector.go create mode 100644 invoker/internal/gentools/enumfixer/enumfixer.go create mode 100644 invoker/internal/gentools/specificationfixer/specificationfixer.go create mode 100644 invoker/main.go create mode 100644 invoker/view/base.html create mode 100644 invoker/view/css/style.css create mode 100644 invoker/view/discovery.html create mode 100644 invoker/view/gettoken.html create mode 100644 invoker/view/home.html create mode 100644 invoker/view/js/script.js create mode 100644 invoker/view/onboardinvoker.html create mode 100644 invoker/view/securitymethod.html diff --git a/invoker/generate.sh b/invoker/generate.sh new file mode 100755 index 0000000..18a4f5b --- /dev/null +++ b/invoker/generate.sh @@ -0,0 +1,168 @@ +# - +# ========================LICENSE_START================================= +# O-RAN-SC +# %% +# Copyright (C) 2023: Nordix Foundation +# %% +# 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. +# ========================LICENSE_END=================================== +# + +cwd=$(pwd) + +mkdir -p specs + +curl https://www.3gpp.org/ftp/Specs/archive/29_series/29.222/29222-h60.zip -o specs/apidef.zip +curl https://www.3gpp.org/ftp/Specs/archive/29_series/29.122/29122-h70.zip -o specs/common29122apidef.zip +curl https://www.3gpp.org/ftp/Specs/archive/29_series/29.508/29508-h80.zip -o specs/common29508apidef.zip +curl https://www.3gpp.org/ftp/Specs/archive/29_series/29.510/29510-h70.zip -o specs/common29510apidef.zip +curl https://www.3gpp.org/ftp/Specs/archive/29_series/29.512/29512-h80.zip -o specs/common29512apidef.zip +curl https://www.3gpp.org/ftp/Specs/archive/29_series/29.514/29514-h60.zip -o specs/common29514apidef.zip +curl https://www.3gpp.org/ftp/Specs/archive/29_series/29.517/29517-h70.zip -o specs/common29517apidef.zip +curl https://www.3gpp.org/ftp/Specs/archive/29_series/29.518/29518-h70.zip -o specs/common29518apidef.zip +curl https://www.3gpp.org/ftp/Specs/archive/29_series/29.522/29522-h70.zip -o specs/common29522apidef.zip +curl https://www.3gpp.org/ftp/Specs/archive/29_series/29.523/29523-h80.zip -o specs/common29523apidef.zip +curl https://www.3gpp.org/ftp/Specs/archive/29_series/29.554/29554-h40.zip -o specs/common29554apidef.zip +curl https://www.3gpp.org/ftp/Specs/archive/29_series/29.571/29571-h70.zip -o specs/common29571apidef.zip +curl https://www.3gpp.org/ftp/Specs/archive/29_series/29.572/29572-h60.zip -o specs/common29572apidef.zip + +cd specs/ + +jar xvf apidef.zip +jar xvf common29122apidef.zip +jar xvf common29508apidef.zip +jar xvf common29510apidef.zip +jar xvf common29512apidef.zip +jar xvf common29514apidef.zip +jar xvf common29517apidef.zip +jar xvf common29518apidef.zip +jar xvf common29522apidef.zip +jar xvf common29523apidef.zip +jar xvf common29554apidef.zip +jar xvf common29571apidef.zip +jar xvf common29572apidef.zip + +# Remove types that are not used by CAPIF that have dependencies to other specifications. +sed -e 'H;x;/^\( *\)\n\1/{s/\n.*//;x;d;}' -e 's/.*//;x;/\CivicAddress/{s/^\( *\).*/ \1/;x;d;}' TS29571_CommonData.yaml >temp.yaml +mv temp.yaml TS29571_CommonData.yaml +sed -e 'H;x;/^\( *\)\n\1/{s/\n.*//;x;d;}' -e 's/.*//;x;/\ExternalMbsServiceArea/{s/^\( *\).*/ \1/;x;d;}' TS29571_CommonData.yaml >temp.yaml +mv temp.yaml TS29571_CommonData.yaml +sed -e 'H;x;/^\( *\)\n\1/{s/\n.*//;x;d;}' -e 's/.*//;x;/\GeographicArea/{s/^\( *\).*/ \1/;x;d;}' TS29571_CommonData.yaml >temp.yaml +mv temp.yaml TS29571_CommonData.yaml +sed -e 'H;x;/^\( *\)\n\1/{s/\n.*//;x;d;}' -e 's/.*//;x;/\GeoServiceArea/{s/^\( *\).*/ \1/;x;d;}' TS29571_CommonData.yaml >temp.yaml +mv temp.yaml TS29571_CommonData.yaml +sed -e 'H;x;/^\( *\)\n\1/{s/\n.*//;x;d;}' -e 's/.*//;x;/\MbsMediaComp/{s/^\( *\).*/ \1/;x;d;}' TS29571_CommonData.yaml >temp.yaml +mv temp.yaml TS29571_CommonData.yaml +sed -e 'H;x;/^\( *\)\n\1/{s/\n.*//;x;d;}' -e 's/.*//;x;/\MbsMediaCompRm/{s/^\( *\).*/ \1/;x;d;}' TS29571_CommonData.yaml >temp.yaml +mv temp.yaml TS29571_CommonData.yaml +sed -e 'H;x;/^\( *\)\n\1/{s/\n.*//;x;d;}' -e 's/.*//;x;/\MbsMediaInfo/{s/^\( *\).*/ \1/;x;d;}' TS29571_CommonData.yaml >temp.yaml +mv temp.yaml TS29571_CommonData.yaml +sed -e 'H;x;/^\( *\)\n\1/{s/\n.*//;x;d;}' -e 's/.*//;x;/\MbsServiceInfo/{s/^\( *\).*/ \1/;x;d;}' TS29571_CommonData.yaml >temp.yaml +mv temp.yaml TS29571_CommonData.yaml +sed -e 'H;x;/^\( *\)\n\1/{s/\n.*//;x;d;}' -e 's/.*//;x;/\MbsSession/{s/^\( *\).*/ \1/;x;d;}' TS29571_CommonData.yaml >temp.yaml +mv temp.yaml TS29571_CommonData.yaml +sed -e 'H;x;/^\( *\)\n\1/{s/\n.*//;x;d;}' -e 's/.*//;x;/\SpatialValidityCond/{s/^\( *\).*/ \1/;x;d;}' TS29571_CommonData.yaml >temp.yaml +mv temp.yaml TS29571_CommonData.yaml + +# Remove attributes that can not be generated easily. +sed '/accessTokenError.*/,+3d' TS29571_CommonData.yaml >temp.yaml +mv temp.yaml TS29571_CommonData.yaml +sed '/accessTokenRequest.*/,+3d' TS29571_CommonData.yaml >temp.yaml +mv temp.yaml TS29571_CommonData.yaml + + +sed '/oneOf.*/,+2d' TS29222_CAPIF_Publish_Service_API.yaml >temp.yaml +mv temp.yaml TS29222_CAPIF_Publish_Service_API.yaml + +# Replace references to external specs that are collected to the common spec by the commoncollector +# +cat TS29122_CommonData.yaml | sed 's/TS29572_Nlmf_Location/CommonData/g' > temp.yaml +mv temp.yaml TS29122_CommonData.yaml +cat TS29122_CommonData.yaml | sed 's/TS29554_Npcf_BDTPolicyControl/CommonData/g' > temp.yaml +mv temp.yaml TS29122_CommonData.yaml +cat TS29122_CommonData.yaml | sed 's/TS29514_Npcf_PolicyAuthorization/CommonData/g' > temp.yaml +mv temp.yaml TS29122_CommonData.yaml +cat TS29571_CommonData.yaml | sed 's/TS29514_Npcf_PolicyAuthorization/CommonData/g' > temp.yaml +mv temp.yaml TS29571_CommonData.yaml +cat TS29571_CommonData.yaml | sed 's/TS29572_Nlmf_Location/CommonData/g' > temp.yaml +mv temp.yaml TS29571_CommonData.yaml +cat TS29222_CAPIF_Publish_Service_API.yaml | sed 's/TS29572_Nlmf_Location/CommonData/g' > temp.yaml +mv temp.yaml TS29222_CAPIF_Publish_Service_API.yaml +# + +# This spec has references to itself that need to be removed +cat TS29571_CommonData.yaml | sed 's/TS29571_CommonData.yaml//g' > temp.yaml +mv temp.yaml TS29571_CommonData.yaml + +cd $cwd + +echo "Fixing enums" +cd internal/gentools/enumfixer +go build . +./enumfixer -apidir=../../../specs + +cd $cwd +echo "Gathering common references" +cd internal/gentools/commoncollector +go build . +./commoncollector -apidir=../../../specs + +cd $cwd +echo "Fixing misc in specifications" +cd internal/gentools/specificationfixer +go build . +./specificationfixer -apidir=../../../specs + +cd $cwd + +go install github.com/deepmap/oapi-codegen/cmd/oapi-codegen@v1.10.1 +PATH=$PATH:~/go/bin + +echo "Generating TS29122_CommonData" +mkdir -p internal/common29122 +oapi-codegen --config gogeneratorspecs/common29122/generator_settings.yaml specs/TS29122_CommonData.yaml + +echo "Generating aggregated CommonData" +mkdir -p internal/common +oapi-codegen --config gogeneratorspecs/common/generator_settings.yaml specs/CommonData.yaml + +echo "Generating TS29571_CommonData" +mkdir -p internal/common29571 +oapi-codegen --config gogeneratorspecs/common29571/generator_settings.yaml specs/TS29571_CommonData.yaml + + +echo "Generating TS29222_CAPIF_API_Provider_Management_API" +mkdir -p internal/providermanagementapi +oapi-codegen --config gogeneratorspecs/providermanagementapi/generator_settings_types.yaml specs/TS29222_CAPIF_API_Provider_Management_API.yaml + +echo "Generating TS29222_CAPIF_Publish_Service_API" +mkdir -p internal/publishserviceapi +oapi-codegen --config gogeneratorspecs/publishserviceapi/generator_settings_types.yaml specs/TS29222_CAPIF_Publish_Service_API.yaml + +echo "Generating TS29222_CAPIF_API_Invoker_Management_API" +mkdir -p internal/invokermanagementapi +oapi-codegen --config gogeneratorspecs/invokermanagementapi/generator_settings_types.yaml specs/TS29222_CAPIF_API_Invoker_Management_API.yaml + +echo "Generating TS29222_CAPIF_Discover_Service_API" +mkdir -p internal/discoverserviceapi +oapi-codegen --config gogeneratorspecs/discoverserviceapi/generator_settings_types.yaml specs/TS29222_CAPIF_Discover_Service_API.yaml + +echo "Generating TS29222_CAPIF_Security_API" +mkdir -p internal/securityapi +oapi-codegen --config gogeneratorspecs/securityapi/generator_settings_types.yaml specs/TS29222_CAPIF_Security_API.yaml + +echo "Cleanup" +rm -rf specs + +echo "Generating mocks." +go generate ./... \ No newline at end of file diff --git a/invoker/go.mod b/invoker/go.mod new file mode 100644 index 0000000..b38e295 --- /dev/null +++ b/invoker/go.mod @@ -0,0 +1,35 @@ +module oransc.org/nonrtric/capifinvoker + +go 1.19 + +require ( + github.com/deepmap/oapi-codegen v1.12.4 + github.com/getkin/kin-openapi v0.116.0 + github.com/labstack/echo/v4 v4.10.2 + github.com/sirupsen/logrus v1.9.0 +) + +require ( + github.com/go-openapi/jsonpointer v0.19.5 // indirect + github.com/go-openapi/swag v0.21.1 // indirect + github.com/google/uuid v1.3.0 // indirect + github.com/invopop/yaml v0.1.0 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/mailru/easyjson v0.7.7 // indirect + github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect + github.com/perimeterx/marshmallow v1.1.4 // indirect + gopkg.in/yaml.v2 v2.4.0 + gopkg.in/yaml.v3 v3.0.1 // indirect +) + +require ( + github.com/labstack/gommon v0.4.0 + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.17 // indirect + github.com/valyala/bytebufferpool v1.0.0 // indirect + github.com/valyala/fasttemplate v1.2.2 // indirect + golang.org/x/crypto v0.6.0 // indirect + golang.org/x/net v0.7.0 // indirect + golang.org/x/sys v0.5.0 // indirect + golang.org/x/text v0.7.0 // indirect +) diff --git a/invoker/go.sum b/invoker/go.sum new file mode 100644 index 0000000..cc5ae0e --- /dev/null +++ b/invoker/go.sum @@ -0,0 +1,98 @@ +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 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/deepmap/oapi-codegen v1.12.4 h1:pPmn6qI9MuOtCz82WY2Xaw46EQjgvxednXXrP7g5Q2s= +github.com/deepmap/oapi-codegen v1.12.4/go.mod h1:3lgHGMu6myQ2vqbbTXH2H1o4eXFTGnFiDaOaKKl5yas= +github.com/getkin/kin-openapi v0.116.0 h1:o986hwgMzR972JzOG5j6+WTwWqllZLs1EJKMKCivs2E= +github.com/getkin/kin-openapi v0.116.0/go.mod h1:l5e9PaFUo9fyLJCPGQeXI2ML8c3P8BHOEV2VaAVf/pc= +github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY= +github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-openapi/swag v0.21.1 h1:wm0rhTb5z7qpJRHBdPOMuY4QjVUMbF6/kwoYeRAOrKU= +github.com/go-openapi/swag v0.21.1/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= +github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM= +github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= +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.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/invopop/yaml v0.1.0 h1:YW3WGUoJEXYfzWBjn00zIlrw7brGVD0fUKRYDPAPhrc= +github.com/invopop/yaml v0.1.0/go.mod h1:2XuRLgs/ouIrW3XNzuNj7J3Nvu/Dig5MXvbCEdiBN3Q= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +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 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/labstack/echo/v4 v4.10.2 h1:n1jAhnq/elIFTHr1EYpiYtyKgx4RW9ccVgkqByZaN2M= +github.com/labstack/echo/v4 v4.10.2/go.mod h1:OEyqf2//K1DFdE57vw2DRgWY0M7s65IVQO2FzvI4J5k= +github.com/labstack/gommon v0.4.0 h1:y7cvthEAEbU0yHOf4axH8ZG2NH8knB9iNSoTO8dyIk8= +github.com/labstack/gommon v0.4.0/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM= +github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= +github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= +github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/perimeterx/marshmallow v1.1.4 h1:pZLDH9RjlLGGorbXhcaQLhfuV0pFMNfPO55FuFkxqLw= +github.com/perimeterx/marshmallow v1.1.4/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= +github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +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/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/ugorji/go v1.2.7 h1:qYhyWUUd6WbiM+C6JZAUkIJt/1WrjzNHY9+KCIjVqTo= +github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M= +github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= +github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= +github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= +github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo= +github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= +golang.org/x/crypto v0.6.0 h1:qfktjS5LUO+fFKeJXZ+ikTRijMmljikvG68fpMMruSc= +golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= +golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/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-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +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-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +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-20200615113413-eeeca48fe776/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/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/invoker/gogeneratorspecs/common/generator_settings.yaml b/invoker/gogeneratorspecs/common/generator_settings.yaml new file mode 100644 index 0000000..298e588 --- /dev/null +++ b/invoker/gogeneratorspecs/common/generator_settings.yaml @@ -0,0 +1,29 @@ +# - +# ========================LICENSE_START================================= +# O-RAN-SC +# %% +# Copyright (C) 2023: Nordix Foundation +# %% +# 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. +# ========================LICENSE_END=================================== +# + +output: + internal/common/common.gen.go +package: common +generate: + - types + - skip-prune + - spec +import-mapping: + TS29571_CommonData.yaml: oransc.org/nonrtric/capifinvoker/internal/common29571 diff --git a/invoker/gogeneratorspecs/common29122/generator_settings.yaml b/invoker/gogeneratorspecs/common29122/generator_settings.yaml new file mode 100644 index 0000000..7470a73 --- /dev/null +++ b/invoker/gogeneratorspecs/common29122/generator_settings.yaml @@ -0,0 +1,30 @@ +# - +# ========================LICENSE_START================================= +# O-RAN-SC +# %% +# Copyright (C) 2022: Nordix Foundation +# %% +# 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. +# ========================LICENSE_END=================================== +# + +output: + internal/common29122/common29122.gen.go +package: common29122 +generate: + - types + - skip-prune + - spec +import-mapping: + TS29571_CommonData.yaml: oransc.org/nonrtric/capifinvoker/internal/common29571 + CommonData.yaml: oransc.org/nonrtric/capifinvoker/internal/common \ No newline at end of file diff --git a/invoker/gogeneratorspecs/common29571/generator_settings.yaml b/invoker/gogeneratorspecs/common29571/generator_settings.yaml new file mode 100644 index 0000000..8401e8d --- /dev/null +++ b/invoker/gogeneratorspecs/common29571/generator_settings.yaml @@ -0,0 +1,27 @@ +# - +# ========================LICENSE_START================================= +# O-RAN-SC +# %% +# Copyright (C) 2022: Nordix Foundation +# %% +# 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. +# ========================LICENSE_END=================================== +# + +output: + internal/common29571/common29571.gen.go +package: common29571 +generate: + - types + - skip-prune + - spec \ No newline at end of file diff --git a/invoker/gogeneratorspecs/discoverserviceapi/generator_settings_types.yaml b/invoker/gogeneratorspecs/discoverserviceapi/generator_settings_types.yaml new file mode 100644 index 0000000..1c61f4a --- /dev/null +++ b/invoker/gogeneratorspecs/discoverserviceapi/generator_settings_types.yaml @@ -0,0 +1,29 @@ +# - +# ========================LICENSE_START================================= +# O-RAN-SC +# %% +# Copyright (C) 2023: Nordix Foundation +# %% +# 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. +# ========================LICENSE_END=================================== +# + +output: + internal/discoverserviceapi/discoverserviceapi-types.gen.go +package: discoverserviceapi +generate: + - types +import-mapping: + TS29122_CommonData.yaml: oransc.org/nonrtric/capifinvoker/internal/common29122 + TS29571_CommonData.yaml: oransc.org/nonrtric/capifinvoker/internal/common29571 + TS29222_CAPIF_Publish_Service_API.yaml: oransc.org/nonrtric/capifinvoker/internal/publishserviceapi \ No newline at end of file diff --git a/invoker/gogeneratorspecs/invokermanagementapi/generator_settings_types.yaml b/invoker/gogeneratorspecs/invokermanagementapi/generator_settings_types.yaml new file mode 100644 index 0000000..4f994fd --- /dev/null +++ b/invoker/gogeneratorspecs/invokermanagementapi/generator_settings_types.yaml @@ -0,0 +1,29 @@ +# - +# ========================LICENSE_START================================= +# O-RAN-SC +# %% +# Copyright (C) 2023: Nordix Foundation +# %% +# 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. +# ========================LICENSE_END=================================== +# + +output: + internal/invokermanagementapi/invokermanagementapi-types.gen.go +package: invokermanagementapi +generate: + - types +import-mapping: + TS29122_CommonData.yaml: oransc.org/nonrtric/capifinvoker/internal/common29122 + TS29571_CommonData.yaml: oransc.org/nonrtric/capifinvoker/internal/common29571 + TS29222_CAPIF_Publish_Service_API.yaml: oransc.org/nonrtric/capifinvoker/internal/publishserviceapi \ No newline at end of file diff --git a/invoker/gogeneratorspecs/providermanagementapi/generator_settings_types.yaml b/invoker/gogeneratorspecs/providermanagementapi/generator_settings_types.yaml new file mode 100644 index 0000000..f1fae3a --- /dev/null +++ b/invoker/gogeneratorspecs/providermanagementapi/generator_settings_types.yaml @@ -0,0 +1,28 @@ +# - +# ========================LICENSE_START================================= +# O-RAN-SC +# %% +# Copyright (C) 2023: Nordix Foundation +# %% +# 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. +# ========================LICENSE_END=================================== +# + +output: + internal/providermanagementapi/providermanagementapi-types.gen.go +package: providermanagementapi +generate: + - types +import-mapping: + TS29122_CommonData.yaml: oransc.org/nonrtric/capifinvoker/internal/common29122 + TS29571_CommonData.yaml: oransc.org/nonrtric/capifinvoker/internal/common29571 \ No newline at end of file diff --git a/invoker/gogeneratorspecs/publishserviceapi/generator_settings_types.yaml b/invoker/gogeneratorspecs/publishserviceapi/generator_settings_types.yaml new file mode 100644 index 0000000..2a05fb8 --- /dev/null +++ b/invoker/gogeneratorspecs/publishserviceapi/generator_settings_types.yaml @@ -0,0 +1,29 @@ +# - +# ========================LICENSE_START================================= +# O-RAN-SC +# %% +# Copyright (C) 2023: Nordix Foundation +# %% +# 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. +# ========================LICENSE_END=================================== +# + +output: + internal/publishserviceapi/publishserviceapi-types.gen.go +package: publishserviceapi +generate: + - types +import-mapping: + TS29122_CommonData.yaml: oransc.org/nonrtric/capifinvoker/internal/common29122 + TS29571_CommonData.yaml: oransc.org/nonrtric/capifinvoker/internal/common29571 + CommonData.yaml: oransc.org/nonrtric/capifinvoker/internal/common \ No newline at end of file diff --git a/invoker/gogeneratorspecs/securityapi/generator_settings_types.yaml b/invoker/gogeneratorspecs/securityapi/generator_settings_types.yaml new file mode 100644 index 0000000..5c1a873 --- /dev/null +++ b/invoker/gogeneratorspecs/securityapi/generator_settings_types.yaml @@ -0,0 +1,29 @@ +# - +# ========================LICENSE_START================================= +# O-RAN-SC +# %% +# Copyright (C) 2023: Nordix Foundation +# %% +# 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. +# ========================LICENSE_END=================================== +# + +output: + internal/securityapi/securityapi-types.gen.go +package: securityapi +generate: + - types +import-mapping: + TS29122_CommonData.yaml: oransc.org/nonrtric/capifinvoker/internal/common29122 + TS29571_CommonData.yaml: oransc.org/nonrtric/capifinvoker/internal/common29571 + TS29222_CAPIF_Publish_Service_API.yaml: oransc.org/nonrtric/capifinvoker/internal/publishserviceapi \ No newline at end of file diff --git a/invoker/handler/common_handler.go b/invoker/handler/common_handler.go new file mode 100644 index 0000000..081fa94 --- /dev/null +++ b/invoker/handler/common_handler.go @@ -0,0 +1,79 @@ +// - +// +// ========================LICENSE_START================================= +// O-RAN-SC +// %% +// Copyright (C) 2023: Nordix Foundation +// %% +// 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. +// ========================LICENSE_END=================================== +package handler + +import ( + "fmt" + "io" + "net/http" +) + +func makeRequest(method, url string, headers map[string]string, data io.Reader) ([]byte, error) { + client := &http.Client{} + + // Create a new HTTP request with the specified method and URL + req, err := http.NewRequest(method, url, nil) + if err != nil { + return nil, err + } + + // Set any headers specified in the headers map + for k, v := range headers { + req.Header.Set(k, v) + } + + // If there is data to send, marshal it to JSON and set it as the request body + if data != nil { + /*jsonBytes, err := json.Marshal(data) + if err != nil { + return nil, err + }*/ + req.Body = io.NopCloser(data) + } + + // Send the request and get the response + if resp, err := client.Do(req); err == nil { + if isResponseSuccess(resp.StatusCode) { + defer resp.Body.Close() + + // Read the response body + respBody, err := io.ReadAll(resp.Body) + if err != nil { + return nil, err + } + return respBody, nil + } else { + return nil, getRequestError(resp) + } + } else { + return nil, err + } +} + +func isResponseSuccess(statusCode int) bool { + return statusCode >= http.StatusOK && statusCode <= 299 +} + +func getRequestError(response *http.Response) error { + defer response.Body.Close() + responseData, _ := io.ReadAll(response.Body) + + return fmt.Errorf("message: %v code: %v", string(responseData), response.StatusCode) +} diff --git a/invoker/handler/discovery_handler.go b/invoker/handler/discovery_handler.go new file mode 100644 index 0000000..f15ddc5 --- /dev/null +++ b/invoker/handler/discovery_handler.go @@ -0,0 +1,99 @@ +// - +// +// ========================LICENSE_START================================= +// O-RAN-SC +// %% +// Copyright (C) 2023: Nordix Foundation +// %% +// 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. +// ========================LICENSE_END=================================== +package handler + +import ( + "encoding/json" + "fmt" + "net/http" + "net/url" + + "github.com/labstack/echo/v4" + log "github.com/sirupsen/logrus" + "oransc.org/nonrtric/capifinvoker/internal/discoverserviceapi" +) + +func DiscoverAPIs(server string) echo.HandlerFunc { + return func(c echo.Context) error { + + invokerId := c.FormValue("api-invoker-id") + if invokerId == "" { + return c.Render(http.StatusOK, "discovery.html", map[string]interface{}{ + "isResponse": false, + "isError": false, + }) + } + + //server format: http://localhost:8090 + urlStr, _ := url.Parse(server + "/service-apis/v1/allServiceAPIs") + log.Infof("[Discovery API] apis to %v for invokerId: %v", urlStr, invokerId) + + //TODO check how to remove empty parameters + c.Request().ParseForm() + params := c.Request().Form + for key, val := range params { + if len(val) == 0 || val[0] == "" { + params.Del(key) + } + } + urlStr.RawQuery = params.Encode() + + headers := map[string]string{ + "Content-Type": "text/plain", + } + resp, err := makeRequest("GET", urlStr.String(), headers, nil) + if err != nil { + log.Errorf("[Discovery API] %v", fmt.Sprintf("error: %v", err)) + return c.Render(http.StatusBadRequest, "discovery.html", map[string]interface{}{ + "response": fmt.Sprintf("error: %v", err), + "isError": true, + "isResponse": false, + }) + } + log.Infof("[Discovery API] Response from service: %+v error: %v\n", string(resp), err) + + var resAPIs discoverserviceapi.DiscoveredAPIs + err = json.Unmarshal(resp, &resAPIs) + if err != nil { + log.Error("[Discovery API] error unmarshaling parameter DiscoveredAPIs as JSON") + return c.Render(http.StatusBadRequest, "discovery.html", map[string]interface{}{ + "isResponse": false, + "isError": true, + "response": "error unmarshaling parameter []DiscoveredAPIs as JSON", + }) + } + + if len(*resAPIs.ServiceAPIDescriptions) == 0 { + log.Info("[Discovery API] There are no APIs availables for the specified parameters.") + return c.Render(http.StatusOK, "discovery.html", map[string]interface{}{ + "isResponse": false, + "isError": false, + "isEmpty": true, + "response": "There are no APIs availables for the specified parameters.", + }) + } + + bytes, _ := json.Marshal(resAPIs) + return c.Render(http.StatusOK, "discovery.html", map[string]interface{}{ + "isResponse": true, + "response": string(bytes), + }) + } +} diff --git a/invoker/handler/gettoken_handler.go b/invoker/handler/gettoken_handler.go new file mode 100644 index 0000000..625840f --- /dev/null +++ b/invoker/handler/gettoken_handler.go @@ -0,0 +1,100 @@ +// - +// +// ========================LICENSE_START================================= +// O-RAN-SC +// %% +// Copyright (C) 2023: Nordix Foundation +// %% +// 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. +// ========================LICENSE_END=================================== +package handler + +import ( + "encoding/json" + "fmt" + "net/http" + "net/url" + "strconv" + "strings" + + "github.com/labstack/echo/v4" + log "github.com/sirupsen/logrus" + "oransc.org/nonrtric/capifinvoker/internal/securityapi" +) + +func GetTokenHandler(c echo.Context) error { + log.Info("[Security API] in get token handler") + return c.Render(http.StatusOK, "gettoken.html", map[string]interface{}{ + "isError": false, + "isResponse": false, + }) +} + +func ObtainToken(server string) echo.HandlerFunc { + return func(c echo.Context) error { + log.Info("[Security API] in ObtainToken") + securityId := c.FormValue("securityId") + if securityId == "" { + log.Error("[Security API] field securityId is needed") + return c.Render(http.StatusBadRequest, "gettoken.html", map[string]interface{}{ + "isError": true, + "isResponse": false, + "response": "field securityId is needed", + }) + } + + //server format: http://localhost:8090 + urlStr := server + "/capif-security/v1/securities/" + securityId + "/token" + + log.Infof("[Security API] url to capif core %v for securityId: %v", urlStr, securityId) + + data := url.Values{} + data.Set("client_id", c.FormValue("clientId")) + data.Set("client_secret", c.FormValue("clientSecret")) + data.Set("grant_type", "client_credentials") + data.Set("scope", c.FormValue("scope")) + + headers := map[string]string{ + "Content-Type": "application/x-www-form-urlencoded", + "Content-Length": strconv.Itoa(len(data.Encode())), + } + resp, err := makeRequest("POST", urlStr, headers, strings.NewReader(data.Encode())) + if err != nil { + log.Errorf("[Security API] %v", fmt.Sprintf("error: %v", err)) + return c.Render(http.StatusBadRequest, "gettoken.html", map[string]interface{}{ + "isResponse": false, + "isError": true, + "response": fmt.Sprintf("error: %v", err), + }) + } + + var resToken securityapi.AccessTokenRsp + if err = json.Unmarshal(resp, &resToken); err != nil { + log.Error("[Security API] error unmarshaling parameter AccessTokenRsp as JSON") + return c.Render(http.StatusBadRequest, "gettoken.html", map[string]interface{}{ + "isResponse": false, + "isError": true, + "response": "Error unmarshaling parameter AccessTokenRsp as JSON", + }) + } + + // Return the rendered response HTML + bytes, _ := json.Marshal(resToken) + log.Infof("[Security API] jwt token fetch AccessTokenRsp is %v\n", resToken) + return c.Render(http.StatusOK, "gettoken.html", map[string]interface{}{ + "isResponse": true, + "isError": false, + "response": string(bytes), + }) + } +} diff --git a/invoker/handler/home_handler.go b/invoker/handler/home_handler.go new file mode 100644 index 0000000..619d624 --- /dev/null +++ b/invoker/handler/home_handler.go @@ -0,0 +1,32 @@ +// - +// +// ========================LICENSE_START================================= +// O-RAN-SC +// %% +// Copyright (C) 2023: Nordix Foundation +// %% +// 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. +// ========================LICENSE_END=================================== +package handler + +import ( + "net/http" + + "github.com/labstack/echo/v4" +) + +func HomeHandler(c echo.Context) error { + return c.Render(http.StatusOK, "home.html", map[string]interface{}{ + "name": "HOME", + }) +} diff --git a/invoker/handler/offboardinvoker_handler.go b/invoker/handler/offboardinvoker_handler.go new file mode 100644 index 0000000..ad153a4 --- /dev/null +++ b/invoker/handler/offboardinvoker_handler.go @@ -0,0 +1,20 @@ +// - +// +// ========================LICENSE_START================================= +// O-RAN-SC +// %% +// Copyright (C) 2023: Nordix Foundation +// %% +// 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. +// ========================LICENSE_END=================================== +package handler diff --git a/invoker/handler/onboardinvoker_handler.go b/invoker/handler/onboardinvoker_handler.go new file mode 100644 index 0000000..5001c9c --- /dev/null +++ b/invoker/handler/onboardinvoker_handler.go @@ -0,0 +1,100 @@ +// - +// +// ========================LICENSE_START================================= +// O-RAN-SC +// %% +// Copyright (C) 2023: Nordix Foundation +// %% +// 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. +// ========================LICENSE_END=================================== +package handler + +import ( + "bytes" + "encoding/json" + "fmt" + "net/http" + + "github.com/labstack/echo/v4" + log "github.com/sirupsen/logrus" + invokerapi "oransc.org/nonrtric/capifinvoker/internal/invokermanagementapi" +) + +func OnboardingInvokerHandler(c echo.Context) error { + return c.Render(http.StatusOK, "onboardinvoker.html", map[string]interface{}{ + "isError": false, + "isResponse": false, + }) +} + +func OnboardInvoker(server string) echo.HandlerFunc { + return func(c echo.Context) error { + + url := server + "/api-invoker-management/v1/onboardedInvokers" + log.Infof("[Register invoker] url to capif core %v\n", url) + + var newInvoker invokerapi.APIInvokerEnrolmentDetails + fmt.Printf("Getting enrolment details from UI:: %+v", c.FormValue("enrolmentDetails")) + err := json.Unmarshal([]byte(c.FormValue("enrolmentDetails")), &newInvoker) + if err != nil { + fmt.Printf("error: %+v", err) + log.Error("[Register invoker] error unmarshaling parameter enrolmentDetails as JSON") + return c.Render(http.StatusBadRequest, "onboardinvoker.html", map[string]interface{}{ + "isResponse": false, + "isError": true, + "response": "Error unmarshaling parameter enrolmentDetails as JSON", + }) + } + + headers := map[string]string{ + "Content-Type": "application/json", + } + jsonBytes, err := json.Marshal(newInvoker) + if err != nil { + return c.Render(http.StatusBadRequest, "onboardinvoker.html", map[string]interface{}{ + "isResponse": false, + "isError": true, + "response": "Error marshaling parameter enrolmentDetails before doing request", + }) + } + + resp, err := makeRequest("POST", url, headers, bytes.NewReader(jsonBytes)) + if err != nil { + log.Errorf("[Register invoker] %v", fmt.Sprintf("error: %v", err)) + return c.Render(http.StatusBadRequest, "onboardinvoker.html", map[string]interface{}{ + "isResponse": false, + "isError": true, + "response": fmt.Sprintf("error: %v", err), + }) + } + + var resInvoker invokerapi.APIInvokerEnrolmentDetails + err = json.Unmarshal(resp, &resInvoker) + if err != nil { + log.Error("[Register invoker] error unmarshaling response enrolmentDetails as JSON") + return c.Render(http.StatusBadRequest, "onboardinvoker.html", map[string]interface{}{ + "isResponse": false, + "isError": true, + "response": "error unmarshaling parameter enrolmentDetails as JSON", + }) + } + + bytes, _ := json.Marshal(resInvoker) + log.Infof("[Register invoker] new invoker register with id %v\n", *resInvoker.ApiInvokerId) + return c.Render(http.StatusOK, "onboardinvoker.html", map[string]interface{}{ + "isResponse": true, + "isError": false, + "response": string(bytes), + }) + } +} diff --git a/invoker/handler/securitymethod_handler.go b/invoker/handler/securitymethod_handler.go new file mode 100644 index 0000000..7aa4f1b --- /dev/null +++ b/invoker/handler/securitymethod_handler.go @@ -0,0 +1,109 @@ +// - +// +// ========================LICENSE_START================================= +// O-RAN-SC +// %% +// Copyright (C) 2023: Nordix Foundation +// %% +// 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. +// ========================LICENSE_END=================================== +package handler + +import ( + "bytes" + "encoding/json" + "fmt" + "net/http" + + "github.com/labstack/echo/v4" + log "github.com/sirupsen/logrus" + "oransc.org/nonrtric/capifinvoker/internal/securityapi" +) + +func SecurityMethodHandler(c echo.Context) error { + log.Info("[Security API] in security method handler") + return c.Render(http.StatusOK, "securitymethod.html", map[string]interface{}{ + "isError": false, + "isResponse": false, + }) +} + +func ObtainSecurityMethod(server string) echo.HandlerFunc { + return func(c echo.Context) error { + log.Info("[Security API] in ObtainSecurityMethod") + invokerId := c.FormValue("invokerId") + if invokerId == "" { + log.Error("[Security API] field invokerId is needed") + return c.Render(http.StatusBadRequest, "securitymethod.html", map[string]interface{}{ + "isError": true, + "isResponse": false, + "response": "field invokerId is needed", + }) + } + + //server format: http://localhost:8090 + url := server + "/capif-security/v1/trustedInvokers/" + invokerId + + log.Infof("[Security API] url to capif core %v for invokerId: %v", url, invokerId) + var servSecurity securityapi.ServiceSecurity + + err := json.Unmarshal([]byte(c.FormValue("servSecurity")), &servSecurity) + if err != nil { + log.Error("[Security API] error unmarshaling parameter ServiceSecurity as JSON") + return c.Render(http.StatusBadRequest, "securitymethod.html", map[string]interface{}{ + "isResponse": false, + "isError": true, + "response": "error unmarshaling parameter ServiceSecurity as JSON", + }) + } + + headers := map[string]string{ + "Content-Type": "application/json", + } + jsonBytes, err := json.Marshal(servSecurity) + if err != nil { + return c.Render(http.StatusBadRequest, "securitymethod.html", map[string]interface{}{ + "isResponse": false, + "isError": true, + "response": "Error marshaling parameter ServiceSecurity before doing request", + }) + } + resp, err := makeRequest("PUT", url, headers, bytes.NewReader(jsonBytes)) + if err != nil { + log.Errorf("[Security API] %v", fmt.Sprintf("error: %v", err)) + return c.Render(http.StatusBadRequest, "securitymethod.html", map[string]interface{}{ + "isResponse": false, + "isError": true, + "response": fmt.Sprintf("error: %v", err), + }) + } + + var resAPI securityapi.ServiceSecurity + err = json.Unmarshal(resp, &resAPI) + if err != nil { + log.Error("[Security API] error unmarshaling parameter ServiceSecurity as JSON") + return c.Render(http.StatusBadRequest, "securitymethod.html", map[string]interface{}{ + "isResponse": false, + "isError": true, + "response": "Error unmarshaling parameter ServiceSecurity as JSON", + }) + } + + // Return the rendered response HTML + bytes, _ := json.Marshal(resAPI) + return c.Render(http.StatusOK, "securitymethod.html", map[string]interface{}{ + "isResponse": true, + "response": string(bytes), + }) + } +} diff --git a/invoker/internal/gentools/commoncollector/commoncollector.go b/invoker/internal/gentools/commoncollector/commoncollector.go new file mode 100644 index 0000000..ab85e0a --- /dev/null +++ b/invoker/internal/gentools/commoncollector/commoncollector.go @@ -0,0 +1,119 @@ +// - +// ========================LICENSE_START================================= +// O-RAN-SC +// %% +// Copyright (C) 2022: Nordix Foundation +// %% +// 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. +// ========================LICENSE_END=================================== +// + +package main + +import ( + "bufio" + "flag" + "io/ioutil" + "log" + "os" + "strings" + + "gopkg.in/yaml.v2" +) + +var apiDir *string +var common = map[interface{}]interface{}{ + "openapi": "3.0.0", + "info": map[interface{}]interface{}{ + "title": "Common", + "version": "1.0.0", + }, + "components": map[interface{}]interface{}{ + "schemas": map[interface{}]interface{}{}, + }, +} + +func main() { + apiDir = flag.String("apidir", "", "Directory containing API definitions to fix") + flag.Parse() + + file, err := os.Open("definitions.txt") + if err != nil { + log.Fatalf("Error opening file: %v", err) + } + defer func(file *os.File) { + _ = file.Close() + }(file) + + scanner := bufio.NewScanner(file) + components := common["components"] + cMap := components.(map[interface{}]interface{}) + schemas := cMap["schemas"].(map[interface{}]interface{}) + for scanner.Scan() { + name, data := getDependency(scanner.Text()) + if name == "EthFlowDescription" { + changeToLocalReference("fDir", "FlowDirection", data) + } + if name == "ReportingInformation" { + changeToLocalReference("notifMethod", "NotificationMethod", data) + } + if name == "RelativeCartesianLocation" { + properties := data["properties"].(map[interface{}]interface{}) + delete(properties, true) + data["required"] = remove(data["required"].([]interface{}), 1) + } + schemas[name] = data + } + + if err := scanner.Err(); err != nil { + log.Fatal(err) + } + + modCommon, err := yaml.Marshal(common) + if err != nil { + log.Fatalf("Marshal: #%v ", err) + } + err = ioutil.WriteFile(*apiDir+"/"+"CommonData.yaml", modCommon, 0644) + if err != nil { + log.Fatalf("Error writing yamlFile. #%v ", err) + } +} + +func changeToLocalReference(attrname, refName string, data map[interface{}]interface{}) { + properties := data["properties"].(map[interface{}]interface{}) + ref := properties[attrname].(map[interface{}]interface{}) + ref["$ref"] = "#/components/schemas/" + refName +} + +func getDependency(s string) (string, map[interface{}]interface{}) { + info := strings.Split(s, "#") + yamlFile, err := ioutil.ReadFile(*apiDir + "/" + info[0]) + if err != nil { + log.Fatalf("Error reading yamlFile. #%v ", err) + } + m := make(map[string]interface{}) + err = yaml.Unmarshal(yamlFile, m) + if err != nil { + log.Fatalf("Unmarshal: %v", err) + } + components := m["components"] + cMap := components.(map[interface{}]interface{}) + schemas := cMap["schemas"].(map[interface{}]interface{}) + component := strings.Split(info[1], "/") + dep := schemas[component[3]].(map[interface{}]interface{}) + return component[3], dep +} + +func remove(slice []interface{}, s int) []interface{} { + return append(slice[:s], slice[s+1:]...) +} diff --git a/invoker/internal/gentools/enumfixer/enumfixer.go b/invoker/internal/gentools/enumfixer/enumfixer.go new file mode 100644 index 0000000..e722875 --- /dev/null +++ b/invoker/internal/gentools/enumfixer/enumfixer.go @@ -0,0 +1,117 @@ +// - +// ========================LICENSE_START================================= +// O-RAN-SC +// %% +// Copyright (C) 2022: Nordix Foundation +// %% +// 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. +// ========================LICENSE_END=================================== +// + +package main + +import ( + "flag" + "fmt" + "io/ioutil" + "log" + "os" + "path/filepath" + "reflect" + "strconv" + "strings" + + "gopkg.in/yaml.v2" +) + +type Enum struct { + Enum []string `yaml:"enum"` + Type string `yaml:"type"` + Description string `yaml:"description"` +} + +func main() { + var apiDir = flag.String("apidir", "", "Directory containing API definitions to fix") + flag.Parse() + err := filepath.Walk(*apiDir, fixEnums) + if err != nil { + fmt.Println(err) + } +} + +func fixEnums(path string, info os.FileInfo, _ error) error { + if !info.IsDir() && strings.HasSuffix(info.Name(), ".yaml") { + yamlFile, err := ioutil.ReadFile(path) + if err != nil { + log.Printf("yamlFile. Get err #%v ", err) + } + m := make(map[string]interface{}) + err = yaml.Unmarshal(yamlFile, m) + if err != nil { + log.Fatalf("Unmarshal: %v", err) + } + components := m["components"] + if components != nil { + cMap := components.(map[interface{}]interface{}) + if _, ok := cMap["schemas"].(map[interface{}]interface{}); ok { + schemas := cMap["schemas"].(map[interface{}]interface{}) + for typeName, typeDef := range schemas { + tDMap := typeDef.(map[interface{}]interface{}) + anyOf, ok := tDMap["anyOf"] + if ok { + aOSlice := anyOf.([]interface{}) + correctEnum := Enum{} + mapInterface := aOSlice[0].(map[interface{}]interface{}) + enumInterface := mapInterface["enum"] + if enumInterface != nil { + is := enumInterface.([]interface{}) + var enumVals []string + for i := 0; i < len(is); i++ { + if reflect.TypeOf(is[i]).Kind() == reflect.String { + enumVals = append(enumVals, is[i].(string)) + + } else if reflect.TypeOf(is[1]).Kind() == reflect.Int { + enumVals = append(enumVals, strconv.Itoa(is[i].(int))) + } + } + correctEnum.Enum = enumVals + correctEnum.Type = "string" + description := tDMap["description"] + if description != nil { + correctEnum.Description = description.(string) + } else { + if aOSlice[1] != nil { + mapInterface = aOSlice[1].(map[interface{}]interface{}) + description := mapInterface["description"] + if description != nil { + correctEnum.Description = description.(string) + } + } + } + schemas[typeName] = correctEnum + } + } + } + modM, err := yaml.Marshal(m) + if err != nil { + log.Printf("yamlFile. Get err #%v ", err) + } + err = ioutil.WriteFile(path, modM, 0644) + if err != nil { + log.Printf("yamlFile. Get err #%v ", err) + } + } + } + } + return nil +} diff --git a/invoker/internal/gentools/specificationfixer/specificationfixer.go b/invoker/internal/gentools/specificationfixer/specificationfixer.go new file mode 100644 index 0000000..4257b65 --- /dev/null +++ b/invoker/internal/gentools/specificationfixer/specificationfixer.go @@ -0,0 +1,80 @@ +// - +// ========================LICENSE_START================================= +// O-RAN-SC +// %% +// Copyright (C) 2022: Nordix Foundation +// %% +// 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. +// ========================LICENSE_END=================================== +// + +package main + +import ( + "flag" + "io/ioutil" + "log" + + "gopkg.in/yaml.v2" +) + +var apiDir *string + +func main() { + apiDir = flag.String("apidir", "", "Directory containing API definitions to fix") + flag.Parse() + + m := getData("TS29571_CommonData.yaml") + components := m["components"] + cMap := components.(map[interface{}]interface{}) + schemas := cMap["schemas"].(map[interface{}]interface{}) + snssaiExtensionData := schemas["SnssaiExtension"].(map[interface{}]interface{}) + props := snssaiExtensionData["properties"].(map[interface{}]interface{}) + wildcardSdData := props["wildcardSd"].(map[interface{}]interface{}) + delete(wildcardSdData, "enum") + + writeFile("TS29571_CommonData.yaml", m) + + m = getData("TS29222_CAPIF_Security_API.yaml") + components = m["components"] + cMap = components.(map[interface{}]interface{}) + schemas = cMap["schemas"].(map[interface{}]interface{}) + accessTokenReq := schemas["AccessTokenReq"].(map[interface{}]interface{}) + accessTokenReq["type"] = "object" + + writeFile("TS29222_CAPIF_Security_API.yaml", m) +} + +func getData(filename string) map[string]interface{} { + yamlFile, err := ioutil.ReadFile(*apiDir + "/" + filename) + if err != nil { + log.Fatalf("Error reading yamlFile. #%v ", err) + } + m := make(map[string]interface{}) + err = yaml.Unmarshal(yamlFile, m) + if err != nil { + log.Fatalf("Unmarshal: %v", err) + } + return m +} + +func writeFile(filename string, data map[string]interface{}) { + modCommon, err := yaml.Marshal(data) + if err != nil { + log.Fatalf("Marshal: #%v ", err) + } + err = ioutil.WriteFile(*apiDir+"/"+filename, modCommon, 0644) + if err != nil { + log.Fatalf("Error writing yamlFile. #%v ", err) + } +} diff --git a/invoker/main.go b/invoker/main.go new file mode 100644 index 0000000..e8dd6cf --- /dev/null +++ b/invoker/main.go @@ -0,0 +1,93 @@ +// - +// ========================LICENSE_START================================= +// O-RAN-SC +// %% +// Copyright (C) 2023: Nordix Foundation +// %% +// 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. +// ========================LICENSE_END=================================== +// + +package main + +import ( + "errors" + "flag" + "fmt" + "html/template" + "io" + + log "github.com/sirupsen/logrus" + + "github.com/labstack/echo/v4" + "oransc.org/nonrtric/capifinvoker/handler" +) + +type TemplateRegistry struct { + templates map[string]*template.Template +} + +func (t *TemplateRegistry) Render(w io.Writer, name string, data interface{}, c echo.Context) error { + tmpl, ok := t.templates[name] + if !ok { + err := errors.New("Template not found -> " + name) + return err + } + return tmpl.ExecuteTemplate(w, "base", data) +} + +func main() { + + // Echo instance + e := echo.New() + e.Static("/", "view") + var capifCoreUrl string + flag.StringVar(&capifCoreUrl, "capifCoreUrl", "http://localhost:8090", "Url for CAPIF core") + var logLevelStr = flag.String("loglevel", "Info", "Log level") + var port = flag.Int("port", 9090, "Port for CAPIF Provider") + + flag.Parse() + + if loglevel, err := log.ParseLevel(*logLevelStr); err == nil { + log.SetLevel(loglevel) + } + + templates := make(map[string]*template.Template) + templates["home.html"] = template.Must(template.ParseFiles("view/home.html", "view/base.html")) + templates["discovery.html"] = template.Must(template.ParseFiles("view/discovery.html", "view/base.html")) + templates["onboardinvoker.html"] = template.Must(template.ParseFiles("view/onboardinvoker.html", "view/base.html")) + templates["securitymethod.html"] = template.Must(template.ParseFiles("view/securitymethod.html", "view/base.html")) + templates["gettoken.html"] = template.Must(template.ParseFiles("view/gettoken.html", "view/base.html")) + + e.Renderer = &TemplateRegistry{ + templates: templates, + } + + // Route => handler + e.GET("/", handler.HomeHandler) + e.POST("/", handler.HomeHandler) + + e.GET("/discovery", handler.DiscoverAPIs(capifCoreUrl)) + + e.GET("/onboardinvoker", handler.OnboardingInvokerHandler) + e.POST("/onboardinvoker", handler.OnboardInvoker(capifCoreUrl)) + + e.GET("/securitymethod", handler.SecurityMethodHandler) + e.POST("/securitymethod", handler.ObtainSecurityMethod(capifCoreUrl)) + + e.GET("/gettoken", handler.GetTokenHandler) + e.POST("/gettoken", handler.ObtainToken(capifCoreUrl)) + + // Start the web server + e.Logger.Fatal(e.Start(fmt.Sprintf("0.0.0.0:%d", *port))) +} diff --git a/invoker/view/base.html b/invoker/view/base.html new file mode 100644 index 0000000..da912e6 --- /dev/null +++ b/invoker/view/base.html @@ -0,0 +1,53 @@ + +{{define "base"}} + + + + + + + + + + + + + + {{template "title" .}} + + +
+
+
+ +
+ {{template "body" .}} +
+
+ + + + +{{end}} \ No newline at end of file diff --git a/invoker/view/css/style.css b/invoker/view/css/style.css new file mode 100644 index 0000000..1654f0c --- /dev/null +++ b/invoker/view/css/style.css @@ -0,0 +1,41 @@ +/* + ========================LICENSE_START================================= + O-RAN-SC + %% + Copyright (C) 2023: Nordix Foundation + %% + 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. + ========================LICENSE_END=================================== +*/ +.callout { + padding: 20px; + margin: 20px 0; + border: 1px solid #eee; + border-left-width: 5px; + border-radius: 3px; +} + +.bs-callout { + margin-top: -5px; +} +.callout-info { + border-left-color: #5bc0de; +} + +.callout-info h4 { + color: #5bc0de; +} + +.hiddenRow { + padding: 0 !important; +} \ No newline at end of file diff --git a/invoker/view/discovery.html b/invoker/view/discovery.html new file mode 100644 index 0000000..b582baa --- /dev/null +++ b/invoker/view/discovery.html @@ -0,0 +1,152 @@ + +{{define "title"}} + CAPIF Invoker | {{index . "name"}} +{{end}} + +{{define "body"}} + +{{if .isResponse}} +
+
+

Response from CAPIF core

+
+
DiscoveredAPIs - ServiceAPIDescription
+
+
+
+ +
+
+ +
+
+
+
+ +{{- else}} +
+
+ {{if .isError}} + + {{end}} + {{if .isEmpty}} + + {{end}} +
CAPIF_Discover_Service_API > Discover_Service_API
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+
+{{- end}} +{{end}} + + diff --git a/invoker/view/gettoken.html b/invoker/view/gettoken.html new file mode 100644 index 0000000..fbe64ce --- /dev/null +++ b/invoker/view/gettoken.html @@ -0,0 +1,102 @@ + +{{define "title"}} + CAPIF Invoker +{{end}} + +{{define "body"}} + {{if .isResponse}} +
+
+

Response from CAPIF core

+
+
Access Token Response
+
+
+ Access token: + +
+
+ Expires in: + +
+
+ Scope: + +
+
+ Token type: + +
+
+
+ +
+
+ +
+
+
+
+ + {{- else}} +
+
+ {{if .isError}} + + {{end}} +
CAPIF_Security_API > Obtain_Authorization
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+
+ {{- end}} +{{end}} + + diff --git a/invoker/view/home.html b/invoker/view/home.html new file mode 100644 index 0000000..59239d3 --- /dev/null +++ b/invoker/view/home.html @@ -0,0 +1,73 @@ + +{{define "title"}} + CAPIF Invoker +{{end}} + +{{define "body"}} +
+
+
+

+ +

+ +
+ +
+

+ +

+ +
+
+
+{{end}} + + diff --git a/invoker/view/js/script.js b/invoker/view/js/script.js new file mode 100644 index 0000000..e7ca85d --- /dev/null +++ b/invoker/view/js/script.js @@ -0,0 +1,136 @@ +/* + ========================LICENSE_START================================= + O-RAN-SC + %% + Copyright (C) 2023: Nordix Foundation + %% + 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. + ========================LICENSE_END=================================== +*/ +const isObject = (value) => typeof value === "object" && value !== null + +function checkValue(value){ + return (isObject(value) ? value : ""); +} + +function printResources(resources) { + let res = Object.values(checkValue(resources)); + let out = `

Resources:

    `; + res.forEach((r) => { + out += `
  • +

    + CommType: ${r.commType} + CustOpName: ${r.custOpName} + ResourceName: ${r.resourceName} + Uri: ${r.uri} + Description: ${r.description} + Operations: ${Object.values(checkValue(r.operations))} +

    +
  • `; + }); + out += `
`; + return out; +} + +function printCustomOperations(custOperations) { + let operations = Object.values(checkValue(custOperations)); + let out = `

Custom Operations:

    `; + operations.forEach((o) => { + out += `
  • +

    + CommType: ${o.commType} + CustOpName: ${o.custOpName} + Description: ${o.description} + Operations: ${Object.values(checkValue(o.operations))} +

    +
  • `; + }); + out += `
`; + return out; +} + +function printVersions(versions) { + let vers = Object.values(checkValue(versions)); + let out = `

Versions:

    `; + vers.forEach((v) => { + out += `
  • +

    + ApiVersion: ${v.apiVersion} + ${printCustomOperations(v.custOperations)} + ${printResources(v.resources)} +

    +
  • `; + }); + out += `
`; + return out; +} + +function printInterfaceDescription(description) { + let interfaceDescriptions = Object.values(checkValue(description)); + let out = `

Interface Description:

    `; + interfaceDescriptions.forEach((d) => { + out += `
  • +

    + Ipv4Addr: ${d.ipv4Addr} + Ipv6Addr: ${d.ipv6Addr} + Port: ${d.port} + SecurityMethods: ${Object.values(checkValue(d.securityMethods))} +

    +
  • `; + }); + out += `
`; + return out; +} + +function printAefProfiles(aefProfiles, k){ + let out = ""; + let index = 0; + aefProfiles.forEach((aef) => { + out += ` + + ${aef.aefId} + ${aef.aefLocation} + ${aef.domainName} + ${aef.protocol} + ${Object.values(checkValue(aef.securityMethods))} + + + +
+ ${printInterfaceDescription(aef.interfaceDescriptions)} + ${printVersions(aef.versions)} +
+ + + `; + index++; + }); + return out; +} + +function printSecInfo(secInfo){ + let out = ""; + let index = 0; + secInfo.forEach((info) => { + out += ` + + ${info.aefId} + ${info.apiId} + ${Object.values(checkValue(info.prefSecurityMethods))} + ${info.selSecurityMethod} + + `; + index++; + }); + return out; +} diff --git a/invoker/view/onboardinvoker.html b/invoker/view/onboardinvoker.html new file mode 100644 index 0000000..89179ef --- /dev/null +++ b/invoker/view/onboardinvoker.html @@ -0,0 +1,115 @@ + +{{define "title"}} + CAPIF Invoker | {{index . "name"}} +{{end}} + +{{define "body"}} +{{if .isResponse}} +
+
+

Response from CAPIF core

+
+
APIInvokerEnrolmentDetails
+
+
+ Api InvokerId: + +
+
+ Api Invoker Information: + +
+
+ Notification Destination: + +
+
Onboarding Information:
+
    +
  • + Api Invoker Certificate: + +
  • +
  • + Api Invoker PublicKey: + +
  • +
  • + Onboarding Secret: + +
  • +
+
API List:
+
+ +
+
+
+ +
+
+ +
+
+
+
+ +{{- else}} +
+
+ {{if .isError}} + + {{end}} +
CAPIF_API_Invoker_Management_API > Onboard_API_Invoker
+
+
+ + +
+ +
+ + +
+
+
+
+{{- end}} +{{end}} + + diff --git a/invoker/view/securitymethod.html b/invoker/view/securitymethod.html new file mode 100644 index 0000000..3518488 --- /dev/null +++ b/invoker/view/securitymethod.html @@ -0,0 +1,109 @@ + +{{define "title"}} + CAPIF Invoker +{{end}} + +{{define "body"}} + {{if .isResponse}} +
+
+

Response from CAPIF core

+
+
ServiceAPIDescription
+
+
+ Description: + +
+
+ Notification Destination: + +
+
+ Supported Features: + +
+ +
Security Information:
+
+ + + + + + + + + + + + +
AefIdApiIdPrefSecurityMethodsSelSecurityMethod
+
+
+
+ +
+
+ +
+
+
+
+ + {{- else}} +
+
+ {{if .isError}} + + {{end}} +
CAPIF_Security_API > Obtain_Security_Method
+
+
+ + +
+
+ + +
+
+ + +
+
+
+
+ {{- end}} +{{end}} + + -- 2.16.6