From b873255143602920b7b0728392fbd8fe304b73d3 Mon Sep 17 00:00:00 2001 From: ychacon Date: Wed, 26 Apr 2023 09:11:45 +0200 Subject: [PATCH] Adding Capif provider Issue-ID: NONRTRIC-861 Signed-off-by: ychacon Change-Id: If80624eccbbafd8c9ae9d14658a3bb5599fdec2f --- provider/Dockerfile | 38 +++++ provider/generate.sh | 156 +++++++++++++++++++++ .../common/generator_settings.yaml | 29 ++++ .../common29122/generator_settings.yaml | 30 ++++ .../common29571/generator_settings.yaml | 27 ++++ .../generator_settings_types.yaml | 28 ++++ .../generator_settings_types.yaml | 29 ++++ provider/handler/common_handler.go | 81 +++++++++++ provider/handler/getapi_handler.go | 80 +++++++++++ provider/handler/home_handler.go | 32 +++++ provider/handler/publishapi_handler.go | 98 +++++++++++++ provider/handler/registration_handler.go | 88 ++++++++++++ .../gentools/commoncollector/commoncollector.go | 119 ++++++++++++++++ .../gentools/commoncollector/definitions.txt | 38 +++++ provider/internal/gentools/enumfixer/enumfixer.go | 117 ++++++++++++++++ .../specificationfixer/specificationfixer.go | 80 +++++++++++ provider/main.go | 89 ++++++++++++ provider/view/base.html | 53 +++++++ provider/view/css/style.css | 41 ++++++ provider/view/getapi.html | 109 ++++++++++++++ provider/view/home.html | 70 +++++++++ provider/view/js/script.js | 121 ++++++++++++++++ provider/view/publishapi.html | 111 +++++++++++++++ provider/view/registration.html | 119 ++++++++++++++++ 24 files changed, 1783 insertions(+) create mode 100644 provider/Dockerfile create mode 100755 provider/generate.sh create mode 100644 provider/gogeneratorspecs/common/generator_settings.yaml create mode 100644 provider/gogeneratorspecs/common29122/generator_settings.yaml create mode 100644 provider/gogeneratorspecs/common29571/generator_settings.yaml create mode 100644 provider/gogeneratorspecs/providermanagementapi/generator_settings_types.yaml create mode 100644 provider/gogeneratorspecs/publishserviceapi/generator_settings_types.yaml create mode 100644 provider/handler/common_handler.go create mode 100644 provider/handler/getapi_handler.go create mode 100644 provider/handler/home_handler.go create mode 100644 provider/handler/publishapi_handler.go create mode 100644 provider/handler/registration_handler.go create mode 100644 provider/internal/gentools/commoncollector/commoncollector.go create mode 100644 provider/internal/gentools/commoncollector/definitions.txt create mode 100644 provider/internal/gentools/enumfixer/enumfixer.go create mode 100644 provider/internal/gentools/specificationfixer/specificationfixer.go create mode 100644 provider/main.go create mode 100644 provider/view/base.html create mode 100644 provider/view/css/style.css create mode 100644 provider/view/getapi.html create mode 100644 provider/view/home.html create mode 100644 provider/view/js/script.js create mode 100644 provider/view/publishapi.html create mode 100644 provider/view/registration.html diff --git a/provider/Dockerfile b/provider/Dockerfile new file mode 100644 index 0000000..bfadfb8 --- /dev/null +++ b/provider/Dockerfile @@ -0,0 +1,38 @@ +#================================================================================== +# 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. +# +# This source code is part of the near-RT RIC (RAN Intelligent Controller) +# platform project (RICP). +#================================================================================== + +## +## Build +## +FROM nexus3.o-ran-sc.org:10001/golang:1.19.2-bullseye AS build +WORKDIR /app +COPY go.mod . +COPY go.sum . +RUN go mod download +COPY . . +RUN go build -o /capifprovider +## +## Deploy +## +FROM gcr.io/distroless/base-debian11 +WORKDIR / +## Copy from "build" stage +COPY --from=build /capifprovider . +USER nonroot:nonroot +ENTRYPOINT ["/capifprovider"] diff --git a/provider/generate.sh b/provider/generate.sh new file mode 100755 index 0000000..36dfe59 --- /dev/null +++ b/provider/generate.sh @@ -0,0 +1,156 @@ +# - +# ========================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 "Cleanup" +rm -rf specs + +echo "Generating mocks." +go generate ./... \ No newline at end of file diff --git a/provider/gogeneratorspecs/common/generator_settings.yaml b/provider/gogeneratorspecs/common/generator_settings.yaml new file mode 100644 index 0000000..af302a1 --- /dev/null +++ b/provider/gogeneratorspecs/common/generator_settings.yaml @@ -0,0 +1,29 @@ +# - +# ========================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/common/common.gen.go +package: common +generate: + - types + - skip-prune + - spec +import-mapping: + TS29571_CommonData.yaml: oransc.org/nonrtric/capifprov/internal/common29571 diff --git a/provider/gogeneratorspecs/common29122/generator_settings.yaml b/provider/gogeneratorspecs/common29122/generator_settings.yaml new file mode 100644 index 0000000..69f77e2 --- /dev/null +++ b/provider/gogeneratorspecs/common29122/generator_settings.yaml @@ -0,0 +1,30 @@ +# - +# ========================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/common29122/common29122.gen.go +package: common29122 +generate: + - types + - skip-prune + - spec +import-mapping: + TS29571_CommonData.yaml: oransc.org/nonrtric/capifprov/internal/common29571 + CommonData.yaml: oransc.org/nonrtric/capifprov/internal/common \ No newline at end of file diff --git a/provider/gogeneratorspecs/common29571/generator_settings.yaml b/provider/gogeneratorspecs/common29571/generator_settings.yaml new file mode 100644 index 0000000..c83b629 --- /dev/null +++ b/provider/gogeneratorspecs/common29571/generator_settings.yaml @@ -0,0 +1,27 @@ +# - +# ========================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/common29571/common29571.gen.go +package: common29571 +generate: + - types + - skip-prune + - spec \ No newline at end of file diff --git a/provider/gogeneratorspecs/providermanagementapi/generator_settings_types.yaml b/provider/gogeneratorspecs/providermanagementapi/generator_settings_types.yaml new file mode 100644 index 0000000..fd9bd0a --- /dev/null +++ b/provider/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/capifprov/internal/common29122 + TS29571_CommonData.yaml: oransc.org/nonrtric/capifprov/internal/common29571 \ No newline at end of file diff --git a/provider/gogeneratorspecs/publishserviceapi/generator_settings_types.yaml b/provider/gogeneratorspecs/publishserviceapi/generator_settings_types.yaml new file mode 100644 index 0000000..1a5f416 --- /dev/null +++ b/provider/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/capifprov/internal/common29122 + TS29571_CommonData.yaml: oransc.org/nonrtric/capifprov/internal/common29571 + CommonData.yaml: oransc.org/nonrtric/capifprov/internal/common \ No newline at end of file diff --git a/provider/handler/common_handler.go b/provider/handler/common_handler.go new file mode 100644 index 0000000..73952ee --- /dev/null +++ b/provider/handler/common_handler.go @@ -0,0 +1,81 @@ +// - +// +// ========================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" + "io" + "net/http" +) + +func makeRequest(method, url string, headers map[string]string, data interface{}) ([]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(bytes.NewReader(jsonBytes)) + } + + // 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/provider/handler/getapi_handler.go b/provider/handler/getapi_handler.go new file mode 100644 index 0000000..01c33e6 --- /dev/null +++ b/provider/handler/getapi_handler.go @@ -0,0 +1,80 @@ +// - +// +// ========================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" + + log "github.com/sirupsen/logrus" + + "github.com/labstack/echo/v4" + "oransc.org/nonrtric/capifprov/internal/publishserviceapi" +) + +func GetApiRequest(server string) echo.HandlerFunc { + return func(c echo.Context) error { + + aefId := c.FormValue("apfId") + if aefId == "" { + return c.Render(http.StatusOK, "getapi.html", map[string]interface{}{ + "isResponse": false, + "isError": false, + }) + } + + //server format: http://localhost:8090 + url := server + "/published-apis/v1/" + aefId + "/service-apis" + log.Infof("[Get API] to %v for aefId: %v", url, aefId) + + headers := map[string]string{ + "Content-Type": "text/plain", + } + resp, err := makeRequest("GET", url, headers, nil) + if err != nil { + log.Errorf("[Get API] %v", fmt.Sprintf("error: %v", err)) + return c.Render(http.StatusBadRequest, "getapi.html", map[string]interface{}{ + "response": fmt.Sprintf("error: %v", err), + "isError": true, + "isResponse": false, + }) + } + log.Infof("[Get API] Response from service: %+v error: %v\n", string(resp), err) + + var resAPIs []publishserviceapi.ServiceAPIDescription + err = json.Unmarshal(resp, &resAPIs) + if err != nil { + log.Error("[Get API] error unmarshaling parameter ServiceAPIDescription as JSON") + return c.Render(http.StatusBadRequest, "getapi.html", map[string]interface{}{ + "isResponse": false, + "isError": true, + "response": "error unmarshaling parameter ServiceAPIDescription as JSON", + }) + } + + bytes, _ := json.Marshal(resAPIs) + log.Infof("[Get API] There are %v ServiceAPIDescription objects available", len(resAPIs)) + return c.Render(http.StatusOK, "getapi.html", map[string]interface{}{ + "isResponse": true, + "response": string(bytes), + }) + } +} diff --git a/provider/handler/home_handler.go b/provider/handler/home_handler.go new file mode 100644 index 0000000..619d624 --- /dev/null +++ b/provider/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/provider/handler/publishapi_handler.go b/provider/handler/publishapi_handler.go new file mode 100644 index 0000000..99e6775 --- /dev/null +++ b/provider/handler/publishapi_handler.go @@ -0,0 +1,98 @@ +// - +// +// ========================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" + + "github.com/labstack/echo/v4" + log "github.com/sirupsen/logrus" + "oransc.org/nonrtric/capifprov/internal/publishserviceapi" +) + +func PublishapiHandler(c echo.Context) error { + return c.Render(http.StatusOK, "publishapi.html", map[string]interface{}{ + "isError": false, + "isResponse": false, + }) +} + +func PublishApiFormHandler(server string) echo.HandlerFunc { + return func(c echo.Context) error { + + apfId := c.FormValue("apfId") + if apfId == "" { + return c.Render(http.StatusBadRequest, "publishapi.html", map[string]interface{}{ + "isError": true, + "isResponse": false, + "response": "field apfId is needed", + }) + } + + //server format: http://localhost:8090 + url := server + "/published-apis/v1/" + apfId + "/service-apis" + + log.Infof("[Publish API] url to capif core %v for aefId: %v", url, apfId) + var apiDescription publishserviceapi.ServiceAPIDescription + + err := json.Unmarshal([]byte(c.FormValue("apiDescription")), &apiDescription) + if err != nil { + log.Error("[Publish API] error unmarshaling parameter ServiceAPIDescription as JSON") + return c.Render(http.StatusBadRequest, "publishapi.html", map[string]interface{}{ + "isResponse": false, + "isError": true, + "response": "error unmarshaling parameter ServiceAPIDescription as JSON", + }) + } + + headers := map[string]string{ + "Content-Type": "application/json", + } + resp, err := makeRequest("POST", url, headers, apiDescription) + if err != nil { + log.Errorf("[Publish API] %v", fmt.Sprintf("error: %v", err)) + return c.Render(http.StatusBadRequest, "publishapi.html", map[string]interface{}{ + "isResponse": false, + "isError": true, + "response": fmt.Sprintf("error: %v", err), + }) + } + + var resAPI publishserviceapi.ServiceAPIDescription + err = json.Unmarshal(resp, &resAPI) + if err != nil { + log.Error("[Publish API] error unmarshaling parameter ServiceAPIDescription as JSON") + return c.Render(http.StatusBadRequest, "publishapi.html", map[string]interface{}{ + "isResponse": false, + "isError": true, + "response": "Error unmarshaling parameter ServiceAPIDescription as JSON", + }) + } + + bytes, _ := json.Marshal(resAPI) + log.Infof("[Publish API] API %v with the id: %v has been register", resAPI.ApiName, *resAPI.ApiId) + return c.Render(http.StatusOK, "publishapi.html", map[string]interface{}{ + "isResponse": true, + "response": string(bytes), + }) + } +} diff --git a/provider/handler/registration_handler.go b/provider/handler/registration_handler.go new file mode 100644 index 0000000..0259999 --- /dev/null +++ b/provider/handler/registration_handler.go @@ -0,0 +1,88 @@ +// - +// +// ========================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" + + "github.com/labstack/echo/v4" + log "github.com/sirupsen/logrus" + "oransc.org/nonrtric/capifprov/internal/providermanagementapi" +) + +func RegistrationHandler(c echo.Context) error { + return c.Render(http.StatusOK, "registration.html", map[string]interface{}{ + "isError": false, + "isResponse": false, + }) +} + +func RegistrationFormHandler(server string) echo.HandlerFunc { + return func(c echo.Context) error { + + url := server + "/api-provider-management/v1/registrations" + log.Infof("[Register provider] url to capif core %v\n", url) + + var newProvider providermanagementapi.APIProviderEnrolmentDetails + err := json.Unmarshal([]byte(c.FormValue("enrolmentDetails")), &newProvider) + if err != nil { + log.Error("[Register provider] error unmarshaling parameter enrolmentDetails as JSON") + return c.Render(http.StatusBadRequest, "registration.html", map[string]interface{}{ + "isResponse": false, + "isError": true, + "response": "Error unmarshaling parameter enrolmentDetails as JSON", + }) + } + + headers := map[string]string{ + "Content-Type": "application/json", + } + resp, err := makeRequest("POST", url, headers, newProvider) + if err != nil { + log.Errorf("[Register provider] %v", fmt.Sprintf("error: %v", err)) + return c.Render(http.StatusBadRequest, "registration.html", map[string]interface{}{ + "isResponse": false, + "isError": true, + "response": fmt.Sprintf("error: %v", err), + }) + } + + var resProvider providermanagementapi.APIProviderEnrolmentDetails + err = json.Unmarshal(resp, &resProvider) + if err != nil { + log.Error("[Register provider] error unmarshaling parameter enrolmentDetails as JSON") + return c.Render(http.StatusBadRequest, "registration.html", map[string]interface{}{ + "isResponse": false, + "isError": true, + "response": "error unmarshaling parameter enrolmentDetails as JSON", + }) + } + + bytes, _ := json.Marshal(resProvider) + log.Infof("[Register provider] Api Provider domain %v has been register\n", resProvider.ApiProvDomId) + return c.Render(http.StatusOK, "registration.html", map[string]interface{}{ + "isResponse": true, + "isError": false, + "response": string(bytes), + }) + } +} diff --git a/provider/internal/gentools/commoncollector/commoncollector.go b/provider/internal/gentools/commoncollector/commoncollector.go new file mode 100644 index 0000000..ab85e0a --- /dev/null +++ b/provider/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/provider/internal/gentools/commoncollector/definitions.txt b/provider/internal/gentools/commoncollector/definitions.txt new file mode 100644 index 0000000..a2f3f25 --- /dev/null +++ b/provider/internal/gentools/commoncollector/definitions.txt @@ -0,0 +1,38 @@ +TS29508_Nsmf_EventExposure.yaml#/components/schemas/NotificationMethod +TS29510_Nnrf_NFManagement.yaml#/components/schemas/Ipv4AddressRange +TS29512_Npcf_SMPolicyControl.yaml#/components/schemas/FlowDirection +TS29514_Npcf_PolicyAuthorization.yaml#/components/schemas/ContentVersion +TS29514_Npcf_PolicyAuthorization.yaml#/components/schemas/EthFlowDescription +TS29514_Npcf_PolicyAuthorization.yaml#/components/schemas/FlowDescription +TS29514_Npcf_PolicyAuthorization.yaml#/components/schemas/TscaiInputContainer +TS29517_Naf_EventExposure.yaml#/components/schemas/AddrFqdn +TS29518_Namf_EventExposure.yaml#/components/schemas/CommunicationFailure +TS29522_TrafficInfluence.yaml#/components/schemas/AfResultInfo +TS29522_TrafficInfluence.yaml#/components/schemas/AfResultStatus +TS29523_Npcf_EventExposure.yaml#/components/schemas/ReportingInformation +TS29554_Npcf_BDTPolicyControl.yaml#/components/schemas/NetworkAreaInfo +TS29572_Nlmf_Location.yaml#/components/schemas/Altitude +TS29572_Nlmf_Location.yaml#/components/schemas/Angle +TS29572_Nlmf_Location.yaml#/components/schemas/CivicAddress +TS29572_Nlmf_Location.yaml#/components/schemas/Confidence +TS29572_Nlmf_Location.yaml#/components/schemas/EllipsoidArc +TS29572_Nlmf_Location.yaml#/components/schemas/GADShape +TS29572_Nlmf_Location.yaml#/components/schemas/GeographicArea +TS29572_Nlmf_Location.yaml#/components/schemas/GeographicalCoordinates +TS29572_Nlmf_Location.yaml#/components/schemas/InnerRadius +TS29572_Nlmf_Location.yaml#/components/schemas/Local2dPointUncertaintyEllipse +TS29572_Nlmf_Location.yaml#/components/schemas/Local3dPointUncertaintyEllipsoid +TS29572_Nlmf_Location.yaml#/components/schemas/LocalOrigin +TS29572_Nlmf_Location.yaml#/components/schemas/Orientation +TS29572_Nlmf_Location.yaml#/components/schemas/Point +TS29572_Nlmf_Location.yaml#/components/schemas/PointAltitude +TS29572_Nlmf_Location.yaml#/components/schemas/PointAltitudeUncertainty +TS29572_Nlmf_Location.yaml#/components/schemas/PointList +TS29572_Nlmf_Location.yaml#/components/schemas/PointUncertaintyCircle +TS29572_Nlmf_Location.yaml#/components/schemas/PointUncertaintyEllipse +TS29572_Nlmf_Location.yaml#/components/schemas/Polygon +TS29572_Nlmf_Location.yaml#/components/schemas/RelativeCartesianLocation +TS29572_Nlmf_Location.yaml#/components/schemas/Uncertainty +TS29572_Nlmf_Location.yaml#/components/schemas/UncertaintyEllipsoid +TS29572_Nlmf_Location.yaml#/components/schemas/SupportedGADShapes +TS29572_Nlmf_Location.yaml#/components/schemas/UncertaintyEllipse \ No newline at end of file diff --git a/provider/internal/gentools/enumfixer/enumfixer.go b/provider/internal/gentools/enumfixer/enumfixer.go new file mode 100644 index 0000000..e722875 --- /dev/null +++ b/provider/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/provider/internal/gentools/specificationfixer/specificationfixer.go b/provider/internal/gentools/specificationfixer/specificationfixer.go new file mode 100644 index 0000000..4257b65 --- /dev/null +++ b/provider/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/provider/main.go b/provider/main.go new file mode 100644 index 0000000..b7661ea --- /dev/null +++ b/provider/main.go @@ -0,0 +1,89 @@ +// - +// ========================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/capifprov/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["registration.html"] = template.Must(template.ParseFiles("view/registration.html", "view/base.html")) + templates["publishapi.html"] = template.Must(template.ParseFiles("view/publishapi.html", "view/base.html")) + templates["getapi.html"] = template.Must(template.ParseFiles("view/getapi.html", "view/base.html")) + + e.Renderer = &TemplateRegistry{ + templates: templates, + } + + // Route => handler + e.GET("/", handler.HomeHandler) + e.POST("/", handler.HomeHandler) + + e.GET("/registration", handler.RegistrationHandler) + e.POST("/registration", handler.RegistrationFormHandler(capifCoreUrl)) + + e.GET("/publishapi", handler.PublishapiHandler) + e.POST("/publishapi", handler.PublishApiFormHandler(capifCoreUrl)) + + e.GET("/getapi", handler.GetApiRequest(capifCoreUrl)) + + // Start the web server + e.Logger.Fatal(e.Start(fmt.Sprintf("0.0.0.0:%d", *port))) +} diff --git a/provider/view/base.html b/provider/view/base.html new file mode 100644 index 0000000..7d6d2b2 --- /dev/null +++ b/provider/view/base.html @@ -0,0 +1,53 @@ + +{{define "base"}} + + + + + + + + + + + + + + {{template "title" .}} + + +
+
+
+ +
+ {{template "body" .}} +
+
+ + + + +{{end}} \ No newline at end of file diff --git a/provider/view/css/style.css b/provider/view/css/style.css new file mode 100644 index 0000000..1654f0c --- /dev/null +++ b/provider/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/provider/view/getapi.html b/provider/view/getapi.html new file mode 100644 index 0000000..9ae04e3 --- /dev/null +++ b/provider/view/getapi.html @@ -0,0 +1,109 @@ + +{{define "title"}} + CAPIF Provider | {{index . "name"}} +{{end}} + +{{define "body"}} + +{{if .isResponse}} +
+
+

Response from CAPIF core

+
+
ServiceAPIDescription
+
+
+
+ +
+
+ +
+
+
+
+ +{{- else}} +
+
+ {{if .isError}} + + {{end}} +
API publishing functions> Get APIs
+
+
+ + +
+
+ + +
+
+
+
+{{- end}} +{{end}} + + diff --git a/provider/view/home.html b/provider/view/home.html new file mode 100644 index 0000000..9d9ff55 --- /dev/null +++ b/provider/view/home.html @@ -0,0 +1,70 @@ + +{{define "title"}} + CAPIF Provider +{{end}} + +{{define "body"}} +
+
+ +
+

+ +

+ +
+
+

+ +

+
+ +
+
+
+
+{{end}} + + diff --git a/provider/view/js/script.js b/provider/view/js/script.js new file mode 100644 index 0000000..2b25652 --- /dev/null +++ b/provider/view/js/script.js @@ -0,0 +1,121 @@ +/* + ========================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){ + 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; +} + + diff --git a/provider/view/publishapi.html b/provider/view/publishapi.html new file mode 100644 index 0000000..3f71ed6 --- /dev/null +++ b/provider/view/publishapi.html @@ -0,0 +1,111 @@ + +{{define "title"}} + CAPIF Provider +{{end}} + +{{define "body"}} + {{if .isResponse}} +
+
+

Response from CAPIF core

+
+
ServiceAPIDescription
+
+
+ ApiId: + +
+
+ ApiName: + +
+
+ Description: + +
+ +
AefProfiles:
+
+ + + + + + + + + + + + + +
AefIdAefLocationDomainNameProtocolSecurityMethods
+
+
+
+ +
+
+ +
+
+
+
+ + {{- else}} +
+
+ {{if .isError}} + + {{end}} +
API publishing functions> Publish API
+
+
+ + +
+
+ + +
+ +
+ + +
+
+
+
+ {{- end}} +{{end}} + + diff --git a/provider/view/registration.html b/provider/view/registration.html new file mode 100644 index 0000000..d0e381d --- /dev/null +++ b/provider/view/registration.html @@ -0,0 +1,119 @@ + +{{define "title"}} + CAPIF Provider | {{index . "name"}} +{{end}} + +{{define "body"}} +{{if .isResponse}} +
+
+

Response from CAPIF core

+
+
APIProviderEnrolmentDetails
+
+
+ ApiProvDomId: + +
+
+ ApiProvDomInfo: + +
+
+ RegSec: + +
+
APIProviderFunctionDetails:
+ +
+ + + + + + + + + + + + +
ApiProvFuncIdApiProvFuncInfoApiProvFuncRoleRegistrationInformation
+
+
+
+ +
+
+ +
+
+
+
+ +{{- else}} +
+
+ {{if .isError}} + + {{end}} +
API management functions> Registrations
+
+
+ + +
+ +
+ + +
+
+
+
+{{- end}} +{{end}} + + -- 2.16.6