Adding Capif invoker
Issue-ID: NONRTRIC-861
Signed-off-by: ychacon <yennifer.chacon@est.tech>
Change-Id: Idccd804e484fa0131496a8d7362bd242bf282a16
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
+# <replacements_start>
+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
+# <new_replacement>
+
+# 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 @@
+<!--
+ ========================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===================================
+-->
+{{define "base"}}
+ <!DOCTYPE html>
+ <html lang="en">
+ <head>
+ <!-- Required meta tags -->
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+
+ <!-- CSS -->
+ <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
+ <link rel="stylesheet" type="text/css" href="./css/style.css">
+ <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.4/jquery.min.js"></script>
+ <script language="JavaScript" type="text/javascript" src="./js/script.js"></script>
+
+ <title>{{template "title" .}}</title>
+ </head>
+ <body>
+ <main>
+ <div class="container py-4">
+ <header class="d-flex flex-wrap justify-content-center py-3 mb-4 border-bottom text-dark">
+ <div class="col-4 text-center">
+ <a class="text-body-emphasis mb-3 mb-md-0 me-md-auto link-body-emphasis text-decoration-none" href="/">
+ <span class="fs-2">CAPIF Invoker</span>
+ </a>
+ </div>
+ </header>
+ {{template "body" .}}
+ </div>
+ </main>
+ <!-- JS -->
+ <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-kenU1KFdBIe4zVF0s0G1M5b4hcpxyD9F7jL+jjXkk+Q2h455rYXK/7HAuoJl+0I4" crossorigin="anonymous"></script>
+ </body>
+ </html>
+{{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 @@
+<!--
+ ========================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===================================
+-->
+{{define "title"}}
+ CAPIF Invoker | {{index . "name"}}
+{{end}}
+
+{{define "body"}}
+
+{{if .isResponse}}
+<div class="p-5 mb-4 bg-light rounded-3">
+ <div class="container-fluid py-5">
+ <h4 class="card-subtitle mb-3 text-body-secondary">Response from CAPIF core</h4>
+ <div class="callout callout-info">
+ <h5 class="card-subtitle mb-3 text-body-secondary">DiscoveredAPIs - ServiceAPIDescription</h5>
+ <div id="response">
+ </div>
+ </div>
+
+ <div class="btns col-md-12 text-center">
+ <form action="/" method="GET">
+ <input class="btn btn-secondary" formaction="/" type="submit" value="Return to main page">
+ </form>
+ </div>
+ </div>
+ </div>
+ <script>
+ var htmlResponse = "{{.response}}"
+ const strData = JSON.parse(htmlResponse);
+ console.log(strData)
+ let index = 0
+ let out = "";
+ strData.serviceAPIDescriptions.forEach((api) => {
+ out += `
+ <h6>
+ ApiId:
+ <small id="ApiId" class="text-muted">${api.apiId}</small>
+ </h6>
+ <h6>
+ ApiName:
+ <small id="ApiName" class="text-muted">${api.apiName}</small>
+ </h6>
+ <h6>
+ Description:
+ <small id="Description" class="text-muted">${api.description}</small>
+ </h6>
+
+ <h6>AefProfiles:</h6>
+ <div id="responseTable" class="table-responsive">
+ <table class="table accordion">
+ <thead>
+ <tr>
+ <th scope="col">AefId</th>
+ <th scope="col">AefLocation</th>
+ <th scope="col">DomainName</th>
+ <th scope="col">Protocol</th>
+ <th scope="col">SecurityMethods</th>
+ </tr>
+ </thead>
+ <tbody id="data-output">
+ <!-- Prodcuts from javascript file in here. -->
+ ${printAefProfiles(api.aefProfiles, index)}
+ </tbody>
+ </table>
+ </div>
+ `;
+ index++;
+ document.querySelector("#response").innerHTML = out;
+ });
+ </script>
+{{- else}}
+ <div class="p-5 mb-4 bg-light rounded-3">
+ <div class="container-fluid py-5">
+ {{if .isError}}
+ <div class="alert alert-danger" role="alert">
+ {{.response}}
+ </div>
+ {{end}}
+ {{if .isEmpty}}
+ <div class="alert alert-warning" role="alert">
+ {{.response}}
+ </div>
+ {{end}}
+ <h5 class="card-subtitle mb-3 text-body-secondary">CAPIF_Discover_Service_API > Discover_Service_API</h5>
+ <form action="/discovery" method="GET">
+ <div class="mb-3">
+ <label for="apfId" class="form-label">API invoker identifier:</label>
+ <input type="text" class="form-control" id="api-invoker-id" name="api-invoker-id" placeholder="invokerId" required>
+ </div>
+ <div class="mb-3">
+ <label for="apfId" class="form-label">API name:</label>
+ <input type="text" class="form-control" id="api-name" name="api-name" placeholder="apiName it is set as {apiName} part of the URI " >
+ </div>
+ <div class="mb-3">
+ <label for="apfId" class="form-label">API major version the URI:</label>
+ <input type="text" class="form-control" id="api-version" name="api-version" placeholder="apiVersion" >
+ </div>
+ <div class="mb-3">
+ <label for="apfId" class="form-label">Communication type used by the API:</label>
+ <input type="text" class="form-control" id="comm-type" name="comm-type" placeholder="commType e.g. REQUEST_RESPONSE" >
+ </div>
+ <div class="mb-3">
+ <label for="apfId" class="form-label">Protocol:</label>
+ <input type="text" class="form-control" id="protocol" name="protocol" placeholder="protocol" >
+ </div>
+ <div class="mb-3">
+ <label for="apfId" class="form-label">AEF identifer:</label>
+ <input type="text" class="form-control" id="aef-id" name="aef-id" placeholder="aefId" >
+ </div>
+ <div class="mb-3">
+ <label for="apfId" class="form-label">Data formats used by the API:</label>
+ <input type="text" class="form-control" id="data-format" name="data-format" placeholder="dataFormat e.g. serialization protocol JSON used" >
+ </div>
+ <div class="mb-3">
+ <label for="apfId" class="form-label">Api category:</label>
+ <input type="text" class="form-control" id="api-cat" name="api-cat" placeholder="apiCat" >
+ </div>
+ <div class="mb-3">
+ <label for="apfId" class="form-label">Preferred Aef Location:</label>
+ <input type="text" class="form-control" id="preferred-aef-loc" name="preferred-aef-loc" placeholder="preferredAefLoc" >
+ </div>
+ <div class="mb-3">
+ <label for="apfId" class="form-label">Supported Features:</label>
+ <input type="text" class="form-control" id="supported-features" name="supported-features" placeholder="suppFeat" >
+ </div>
+ <div class="btns col-md-12 text-center">
+ <input class="btn btn-primary" type="submit" value="Submit">
+ <input class="btn btn-secondary" formaction="/" type="submit" value="Cancel" formnovalidate>
+ </div>
+ </form>
+ </div>
+ </div>
+{{- 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 @@
+<!--
+ ========================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===================================
+-->
+{{define "title"}}
+ CAPIF Invoker
+{{end}}
+
+{{define "body"}}
+ {{if .isResponse}}
+ <div class="p-5 mb-4 bg-light rounded-3">
+ <div class="container-fluid py-5">
+ <h4 class="card-subtitle mb-3 text-body-secondary">Response from CAPIF core</h4>
+ <div class="callout callout-info">
+ <h5 class="card-subtitle mb-3 text-body-secondary">Access Token Response</h5>
+ <div id="response" class="text-truncate">
+ <h6>
+ Access token:
+ <small id="accessToken" class="text-muted"></small>
+ </h6>
+ <h6>
+ Expires in:
+ <small id="expiresIn" class="text-muted"></small>
+ </h6>
+ <h6>
+ Scope:
+ <small id="scope" class="text-muted"></small>
+ </h6>
+ <h6>
+ Token type:
+ <small id="tokenType" class="text-muted"></small>
+ </h6>
+ </div>
+ </div>
+
+ <div class="btns col-md-12 text-center">
+ <form action="/" method="GET">
+ <input class="btn btn-secondary" formaction="/" type="submit" value="Return to main page">
+ </form>
+ </div>
+ </div>
+ </div>
+ <script>
+ var htmlResponse = "{{.response}}"
+ const strData = JSON.parse(htmlResponse);
+ document.getElementById("accessToken").innerHTML = strData.access_token;
+ document.getElementById("expiresIn").innerHTML = strData.expires_in;
+ document.getElementById("scope").innerHTML = strData.scope;
+ document.getElementById("tokenType").innerHTML = strData.token_type;
+ </script>
+ {{- else}}
+ <div class="p-5 mb-4 bg-light rounded-3">
+ <div class="container-fluid py-5">
+ {{if .isError}}
+ <div class="alert alert-danger" role="alert">
+ {{.response}}
+ </div>
+ {{end}}
+ <h5 class="card-subtitle mb-3 text-body-secondary">CAPIF_Security_API > Obtain_Authorization</h5>
+ <form action="/gettoken" method="POST">
+ <div class="mb-3">
+ <label for="securityId" class="form-label">Security Id:</label>
+ <input type="text" class="form-control" id="securityId" name="securityId" placeholder="securityId" required>
+ </div>
+ <div class="mb-3">
+ <label for="clientId" class="form-label">Client Id:</label>
+ <input type="text" class="form-control" id="clientId" name="clientId" placeholder="clientId" required>
+ </div>
+ <div class="mb-3">
+ <label for="clientSecret" class="form-label">Client Secret:</label>
+ <input type="text" class="form-control" id="clientSecret" name="clientSecret" placeholder="clientSecret" >
+ </div>
+ <div class="mb-3">
+ <label for="scope" class="form-label">Scope:</label>
+ <input type="text" class="form-control" id="scope" name="scope" placeholder="scope" >
+ </div>
+ <div class="btns col-md-12 text-center">
+ <input class="btn btn-primary" type="submit" value="Submit">
+ <input class="btn btn-secondary" formaction="/" type="submit" value="Cancel" formnovalidate>
+ </div>
+ </form>
+ </div>
+ </div>
+ {{- 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 @@
+<!--
+ ========================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===================================
+-->
+{{define "title"}}
+ CAPIF Invoker
+{{end}}
+
+{{define "body"}}
+<div class="bd-example">
+<div class="accordion" id="accordionExample">
+ <div class="accordion-item">
+ <h2 class="accordion-header">
+ <button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#collapseOne" aria-expanded="true" aria-controls="collapseOne">
+ CAPIF_API_Invoker_Management_API
+ </button>
+ </h2>
+ <div id="collapseOne" class="accordion-collapse collapse show" data-bs-parent="#accordionExample">
+ <div class="accordion-body">
+ <ul>
+ <li><a href="/onboardinvoker">Onboard_API_Invoker</a></li>
+ <li><a href="/offboardinvoker">Offboard_API_Invoker</a></li>
+ </ul>
+ </div>
+ </div>
+ </div>
+ <div class="accordion-item">
+ <h2 class="accordion-header">
+ <button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo">
+ CAPIF_Discover_Service_API
+ </button>
+ </h2>
+ <div id="collapseTwo" class="accordion-collapse collapse" data-bs-parent="#accordionExample">
+ <div class="accordion-body">
+ <ul>
+ <li><a href="/discovery">Discover published service APIs and retrieve a collection of APIs according to certain filter criteria.</a></li>
+ </ul>
+ </div>
+ </div>
+ </div>
+ <div class="accordion-item">
+ <h2 class="accordion-header">
+ <button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#collapseThree" aria-expanded="false" aria-controls="collapseThree">
+ CAPIF_Security_API
+ </button>
+ </h2>
+ <div id="collapseThree" class="accordion-collapse collapse" data-bs-parent="#accordionExample">
+ <ul>
+ <li><a href="/securitymethod">Obtain_Security_Method</a></li>
+ <li><a href="/gettoken">Obtain_Authorization</a></li>
+ </ul>
+ </div>
+ </div>
+ </div>
+</div>
+{{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 = `<p class="lead">Resources:</p><ul>`;
+ res.forEach((r) => {
+ out += `<li>
+ <p>
+ <strong>CommType:</strong> ${r.commType}
+ <strong>CustOpName:</strong> ${r.custOpName}
+ <strong>ResourceName:</strong> ${r.resourceName}
+ <strong>Uri:</strong> ${r.uri}
+ <strong>Description:</strong> ${r.description}
+ <strong>Operations:</strong> ${Object.values(checkValue(r.operations))}
+ </p>
+ </li>`;
+ });
+ out += `</ul>`;
+ return out;
+}
+
+function printCustomOperations(custOperations) {
+ let operations = Object.values(checkValue(custOperations));
+ let out = `<p class="lead"> Custom Operations:</p><ul>`;
+ operations.forEach((o) => {
+ out += `<li>
+ <p>
+ <strong>CommType:</strong> ${o.commType}
+ <strong>CustOpName:</strong> ${o.custOpName}
+ <strong>Description:</strong> ${o.description}
+ <strong>Operations:</strong> ${Object.values(checkValue(o.operations))}
+ </p>
+ </li>`;
+ });
+ out += `</ul>`;
+ return out;
+}
+
+function printVersions(versions) {
+ let vers = Object.values(checkValue(versions));
+ let out = `<p class="lead">Versions:</p><ul>`;
+ vers.forEach((v) => {
+ out += `<li>
+ <p>
+ <strong>ApiVersion:</strong> ${v.apiVersion}
+ ${printCustomOperations(v.custOperations)}
+ ${printResources(v.resources)}
+ </p>
+ </li>`;
+ });
+ out += `</ul>`;
+ return out;
+}
+
+function printInterfaceDescription(description) {
+ let interfaceDescriptions = Object.values(checkValue(description));
+ let out = `<p class="lead">Interface Description:</p><ul>`;
+ interfaceDescriptions.forEach((d) => {
+ out += `<li>
+ <p>
+ <strong>Ipv4Addr:</strong> ${d.ipv4Addr}
+ <strong>Ipv6Addr:</strong> ${d.ipv6Addr}
+ <strong>Port:</strong> ${d.port}
+ <strong>SecurityMethods:</strong> ${Object.values(checkValue(d.securityMethods))}
+ </p>
+ </li>`;
+ });
+ out += `</ul>`;
+ return out;
+}
+
+function printAefProfiles(aefProfiles, k){
+ let out = "";
+ let index = 0;
+ aefProfiles.forEach((aef) => {
+ out += `
+ <tr data-bs-toggle="collapse" data-bs-target="#r${k}${index}">
+ <td>${aef.aefId}</td>
+ <td>${aef.aefLocation}</td>
+ <td>${aef.domainName}</td>
+ <td>${aef.protocol}</td>
+ <td>${Object.values(checkValue(aef.securityMethods))}</td>
+ </tr>
+ <tr class="collapse accordion-collapse" id="r${k}${index}" data-bs-parent=".table">
+ <td colspan="5">
+ <div id="demo1">
+ ${printInterfaceDescription(aef.interfaceDescriptions)}
+ ${printVersions(aef.versions)}
+ </div>
+ </td>
+ </tr>
+ `;
+ index++;
+ });
+ return out;
+}
+
+function printSecInfo(secInfo){
+ let out = "";
+ let index = 0;
+ secInfo.forEach((info) => {
+ out += `
+ <tr>
+ <td>${info.aefId}</td>
+ <td>${info.apiId}</td>
+ <td>${Object.values(checkValue(info.prefSecurityMethods))}</td>
+ <td>${info.selSecurityMethod}</td>
+ </tr>
+ `;
+ 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 @@
+<!--
+ ========================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===================================
+-->
+{{define "title"}}
+ CAPIF Invoker | {{index . "name"}}
+{{end}}
+
+{{define "body"}}
+{{if .isResponse}}
+ <div class="p-5 mb-4 bg-light rounded-3">
+ <div class="container-fluid py-5">
+ <h4 class="card-subtitle mb-3 text-body-secondary">Response from CAPIF core</h4>
+ <div class="callout callout-info">
+ <h5 class="card-subtitle mb-3 text-body-secondary">APIInvokerEnrolmentDetails</h5>
+ <div id="response">
+ <h6>
+ Api InvokerId:
+ <small id="apiInvokerId" class="text-muted"></small>
+ </h6>
+ <h6>
+ Api Invoker Information:
+ <small id="apiInvokerInformation" class="text-muted"></small>
+ </h6>
+ <h6>
+ Notification Destination:
+ <small id="notificationDestination" class="text-muted"></small>
+ </h6>
+ <h6>Onboarding Information:</h6>
+ <ul>
+ <li><h6>
+ Api Invoker Certificate:
+ <small id="apiInvokerCertificate" class="text-muted"></small>
+ </h6></li>
+ <li><h6>
+ Api Invoker PublicKey:
+ <small id="apiInvokerPublicKey" class="text-muted"></small>
+ </h6></li>
+ <li><h6>
+ Onboarding Secret:
+ <small id="onboardingSecret" class="text-muted"></small>
+ </h6></li>
+ </ul>
+ <h6>API List:</h6>
+ <div id="responseTable">
+
+ </div>
+ </div>
+ </div>
+
+ <div class="btns col-md-12 text-center">
+ <form action="/" method="GET">
+ <input class="btn btn-secondary" formaction="/" type="submit" value="Return to main page">
+ </form>
+ </div>
+ </div>
+ </div>
+ <script>
+
+ var htmlResponse = "{{.response}}"
+ const strData = JSON.parse(htmlResponse);
+
+ document.getElementById("apiInvokerId").innerHTML = strData.apiInvokerId;
+ document.getElementById("apiInvokerInformation").innerHTML = strData.apiInvokerInformation;
+ document.getElementById("notificationDestination").innerHTML = strData.notificationDestination;
+
+ document.getElementById("apiInvokerCertificate").innerHTML = strData.onboardingInformation['apiInvokerCertificate'];
+ document.getElementById("apiInvokerPublicKey").innerHTML = strData.onboardingInformation['apiInvokerPublicKey'];
+ document.getElementById("onboardingSecret").innerHTML = strData.onboardingInformation['onboardingSecret'];
+
+ var pretty = JSON.stringify(strData.apiList, undefined, 4);
+ document.getElementById("responseTable").innerHTML = pretty;
+
+ </script>
+{{- else}}
+ <div class="p-5 mb-4 bg-light rounded-3">
+ <div class="container-fluid py-5">
+ {{if .isError}}
+ <div class="alert alert-danger" role="alert">
+ {{.response}}
+ </div>
+ {{end}}
+ <h5 class="card-subtitle mb-3 text-body-secondary">CAPIF_API_Invoker_Management_API > Onboard_API_Invoker</h5>
+ <form action="/onboardinvoker" method="POST">
+ <div class="mb-3">
+ <label for="enrolmentDetails" class="form-label">APIInvokerEnrolmentDetails:</label>
+ <textarea id="enrolmentDetails" class="form-control" name="enrolmentDetails" rows="10" cols="60" required></textarea>
+ </div>
+
+ <div class="btns col-md-12 text-center">
+ <input class="btn btn-primary" type="submit" value="Submit">
+ <input class="btn btn-secondary" formaction="/" type="submit" value="Cancel" formnovalidate>
+ </div>
+ </form>
+ </div>
+ </div>
+{{- 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 @@
+<!--
+ ========================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===================================
+-->
+{{define "title"}}
+ CAPIF Invoker
+{{end}}
+
+{{define "body"}}
+ {{if .isResponse}}
+ <div class="p-5 mb-4 bg-light rounded-3">
+ <div class="container-fluid py-5">
+ <h4 class="card-subtitle mb-3 text-body-secondary">Response from CAPIF core</h4>
+ <div class="callout callout-info">
+ <h5 class="card-subtitle mb-3 text-body-secondary">ServiceAPIDescription</h5>
+ <div id="response">
+ <h6>
+ Description:
+ <small id="Description" class="text-muted"></small>
+ </h6>
+ <h6>
+ Notification Destination:
+ <small id="NotificationDestination" class="text-muted"></small>
+ </h6>
+ <h6>
+ Supported Features:
+ <small id="SupportedFeatures" class="text-muted"></small>
+ </h6>
+
+ <h6>Security Information:</h6>
+ <div id="responseTable" class="table-responsive">
+ <table class="table table-striped">
+ <thead>
+ <tr>
+ <th scope="col">AefId</th>
+ <th scope="col">ApiId</th>
+ <th scope="col">PrefSecurityMethods</th>
+ <th scope="col">SelSecurityMethod</th>
+ </tr>
+ </thead>
+ <tbody id="data-output">
+ <!-- Prodcuts from javascript file in here. -->
+ </tbody>
+ </table>
+ </div>
+ </div>
+ </div>
+
+ <div class="btns col-md-12 text-center">
+ <form action="/" method="GET">
+ <input class="btn btn-secondary" formaction="/" type="submit" value="Return to main page">
+ </form>
+ </div>
+ </div>
+ </div>
+ <script>
+ var htmlResponse = "{{.response}}"
+ const strData = JSON.parse(htmlResponse);
+ document.getElementById("Description").innerHTML = strData.description;
+ document.getElementById("NotificationDestination").innerHTML = strData.notificationDestination;
+ document.getElementById("SupportedFeatures").innerHTML = strData.supportedFeatures;
+
+ let secInfo = Object.values(checkValue(strData.securityInfo));
+ document.querySelector("#data-output").innerHTML = printSecInfo(secInfo);
+ </script>
+ {{- else}}
+ <div class="p-5 mb-4 bg-light rounded-3">
+ <div class="container-fluid py-5">
+ {{if .isError}}
+ <div class="alert alert-danger" role="alert">
+ {{.response}}
+ </div>
+ {{end}}
+ <h5 class="card-subtitle mb-3 text-body-secondary">CAPIF_Security_API > Obtain_Security_Method</h5>
+ <form action="/securitymethod" method="POST">
+ <div class="mb-3">
+ <label for="apfId" class="form-label">Api invoker identifier:</label>
+ <input type="text" class="form-control" id="invokerId" name="invokerId" placeholder="invokerId" required>
+ </div>
+ <div class="mb-3">
+ <label for="servSecurity" class="form-label">Service Security:</label>
+ <textarea id="servSecurity" class="form-control" name="servSecurity" rows="10" cols="60"></textarea>
+ </div>
+ <div class="btns col-md-12 text-center">
+ <input class="btn btn-primary" type="submit" value="Submit">
+ <input class="btn btn-secondary" formaction="/" type="submit" value="Cancel" formnovalidate>
+ </div>
+ </form>
+ </div>
+ </div>
+ {{- end}}
+{{end}}
+
+